Index: src/test/java/org/codehaus/plexus/util/introspection/ReflectionValueExtractorTest.java =================================================================== --- src/test/java/org/codehaus/plexus/util/introspection/ReflectionValueExtractorTest.java (revision 6542) +++ src/test/java/org/codehaus/plexus/util/introspection/ReflectionValueExtractorTest.java (working copy) @@ -36,6 +36,11 @@ { super.setUp(); + Dependency dependency1 = new Dependency(); + dependency1.setArtifactId("dep1"); + Dependency dependency2 = new Dependency(); + dependency2.setArtifactId("dep2"); + project = new Project(); project.setModelVersion( "4.0.0" ); project.setGroupId( "org.apache.maven" ); @@ -44,8 +49,8 @@ project.setVersion( "2.0-SNAPSHOT" ); project.setScm( new Scm() ); project.getScm().setConnection( "scm-connection" ); - project.addDependency( new Dependency() ); - project.addDependency( new Dependency() ); + project.addDependency( dependency1 ); + project.addDependency( dependency2 ); project.setBuild( new Build() ); } @@ -83,6 +88,20 @@ Assert.assertEquals( 2, dependencies.size() ); // ---------------------------------------------------------------------- + // Dependencies - using index notation + // ---------------------------------------------------------------------- + + Dependency dependency = (Dependency)ReflectionValueExtractor.evaluate( "project.dependencies.0", project ); + + Assert.assertNotNull( dependency ); + + Assert.assertTrue( "dep1".equals(dependency.getArtifactId()) ); + + String artifactId = (String)ReflectionValueExtractor.evaluate( "project.dependencies.1.artifactId", project ); + + Assert.assertTrue( "dep2".equals(artifactId) ); + + // ---------------------------------------------------------------------- // Build // ---------------------------------------------------------------------- @@ -95,6 +114,8 @@ throws Exception { Assert.assertNull( ReflectionValueExtractor.evaluate( "project.foo", project ) ); + Assert.assertNull( ReflectionValueExtractor.evaluate( "project.dependencies.10", project ) ); + Assert.assertNull( ReflectionValueExtractor.evaluate( "project.dependencies.0.foo", project ) ); } public static class Project @@ -203,7 +224,17 @@ public static class Dependency { - + private String artifactId; + + public String getArtifactId() + { + return artifactId; + } + + public void setArtifactId(String id) + { + artifactId = id; + } } public static class Scm Index: src/main/java/org/codehaus/plexus/util/introspection/ReflectionValueExtractor.java =================================================================== --- src/main/java/org/codehaus/plexus/util/introspection/ReflectionValueExtractor.java (revision 6542) +++ src/main/java/org/codehaus/plexus/util/introspection/ReflectionValueExtractor.java (working copy) @@ -16,6 +16,7 @@ * limitations under the License. */ +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; @@ -55,10 +56,17 @@ public static Object evaluate( String expression, Object root, boolean trimRootToken ) throws Exception { + Class[] localArgs; + Object[] localParams; + String methodName; + String methodBase; + Method method; + Integer index; + // if the root token refers to the supplied root object parameter, remove it. - if ( trimRootToken ) + if (trimRootToken) { - expression = expression.substring( expression.indexOf( '.' ) + 1 ); + expression = expression.substring(expression.indexOf('.') + 1); } Object value = root; @@ -68,39 +76,75 @@ // MavenProject instance. // ---------------------------------------------------------------------- - StringTokenizer parser = new StringTokenizer( expression, "." ); + StringTokenizer parser = new StringTokenizer(expression, "."); - while ( parser.hasMoreTokens() ) + while (parser.hasMoreTokens()) { - String token = parser.nextToken(); + // default to parameterless & null + localArgs = args; + localParams = params; + methodBase = null; + methodName = null; + method = null; + index = null; - if ( value == null ) + // if we have nothing, stop now + if (value == null) { return null; } + + String token = parser.nextToken(); - classMap = getClassMap( value.getClass() ); + classMap = getClassMap(value.getClass()); - String methodBase = StringUtils.capitalizeFirstLetter( token ); - - String methodName = "get" + methodBase; + try + { + // did we pass an integer as a property? If so, could be a list index + index = Integer.valueOf(token); + localArgs = new Class[1]; + localArgs[0] = Integer.TYPE; + localParams = new Object[1]; + localParams[0] = index; - Method method = classMap.findMethod( methodName, args ); - - if ( method == null ) + // use get method on List interface + method = classMap.findMethod("get", localParams); + } + catch (NumberFormatException e) { - // perhaps this is a boolean property?? - methodName = "is" + methodBase; - - method = classMap.findMethod( methodName, args ); + methodBase = StringUtils.capitalizeFirstLetter(token); + methodName = "get" + methodBase; + + method = classMap.findMethod(methodName, localArgs); + + if (method == null) + { + // perhaps this is a boolean property?? + methodName = "is" + methodBase; + + method = classMap.findMethod(methodName, localArgs); + } } - if ( method == null ) + // couldn't find the method required + if (method == null) { return null; } - value = method.invoke( value, params ); + // might have issues on index out of bounds. + try + { + value = method.invoke(value, localParams); + } + catch (InvocationTargetException e) + { + // catch array index issues gracefully, otherwise release + if (e.getCause() instanceof IndexOutOfBoundsException) + return null; + else + throw e; + } } return value;