/** * Copyright (C) 2006-2017 INRIA and contributors * Spoon - http://spoon.gforge.inria.fr/ * * This software is governed by the CeCILL-C License under French law and * abiding by the rules of distribution of free software. You can use, modify * and/or redistribute the software under the terms of the CeCILL-C license as * circulated by CEA, CNRS and INRIA at http://www.cecill.info. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-C license and that you accept its terms. */ package spoon.reflect.path; import spoon.reflect.path.impl.CtNamedPathElement; import spoon.reflect.path.impl.CtPathElement; import spoon.reflect.path.impl.CtPathImpl; import spoon.reflect.path.impl.CtRolePathElement; import spoon.reflect.path.impl.CtTypedNameElement; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Created by nicolas on 27/08/2015. */ public class CtPathStringBuilder { private final Pattern pathPattern = Pattern.compile("([/.#])([^/.#\\[]+)(\\[([^/.#]*)\\])?"); private final Pattern argumentPattern = Pattern.compile("(\\w+)=([^=\\]]+)"); private Class load(String name) throws CtPathException { // try without name try { return Class.forName(name); } catch (ClassNotFoundException ex) { } // search in spoon.reflect.declaration try { return Class.forName("spoon.reflect.declaration." + name); } catch (ClassNotFoundException ex) { } // search in try { return Class.forName("spoon.reflect.code." + name); } catch (ClassNotFoundException ex) { throw new CtPathException( String.format("Unable to locate element with name $s in Spoon model", name)); } } /** * Build path from a string representation. * * for example: * new CtPathBuilder().fromString(".spoon.test.path.Foo.foo#statement[index=0]") * Match the first statement of method foo from class spoon.test.path.Foo. * * Some specials characters * . : match with the given name * # : match with a CtPathRole * / : match with a element type (for example, to match all classes, use /CtClass */ public CtPath fromString(String pathStr) throws CtPathException { Matcher matcher = pathPattern.matcher(pathStr); CtPathImpl path = new CtPathImpl(); while (matcher.find()) { String kind = matcher.group(1); CtPathElement pathElement = null; if (CtNamedPathElement.STRING.equals(kind)) { pathElement = new CtNamedPathElement(matcher.group(2)); } else if (CtTypedNameElement.STRING.equals(kind)) { pathElement = new CtTypedNameElement(load(matcher.group(2))); } else if (CtRolePathElement.STRING.equals(kind)) { pathElement = new CtRolePathElement(CtPathRole.fromName(matcher.group(2))); } String args = matcher.group(4); if (args != null) { for (String arg : args.split(";")) { Matcher argmatcher = argumentPattern.matcher(arg); if (argmatcher.matches()) { pathElement.addArgument(argmatcher.group(1), argmatcher.group(2)); } } } path.addLast(pathElement); } return path; } }