Author: bentmann
Date: Mon May 31 16:16:22 2010
New Revision: 949790
URL: http://svn.apache.org/viewvc?rev=949790&view=rev
Log:
o Extended plugin to support expressions like
"project/dependencies/*/artifactId" to iterate collections
Modified:
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/EvalMojo.java
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/ExpressionUtil.java
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/test/java/org/apache/maven/plugin/coreit/ExpressionUtilTest.java
Modified:
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/EvalMojo.java
URL:
http://svn.apache.org/viewvc/maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/EvalMojo.java?rev=949790&r1=949789&r2=949790&view=diff
==============================================================================
---
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/EvalMojo.java
(original)
+++
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/EvalMojo.java
Mon May 31 16:16:22 2010
@@ -26,6 +26,7 @@ import org.apache.maven.plugin.MojoFailu
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
@@ -51,7 +52,7 @@ import java.util.Properties;
* </pre>
*
* Expressions that reference non-existing objects or use invalid
collection/array indices silently resolve to
- * <code>null</code>.
+ * <code>null</code>. For collections and arrays, the special index "*" can be
used to iterate all elements.
*
* @goal eval
* @phase initialize
@@ -176,8 +177,13 @@ public class EvalMojo
for ( int i = 0; i < expressions.length; i++ )
{
- Object value = ExpressionUtil.evaluate( expressions[i],
contexts );
- PropertyUtil.store( expressionProperties,
expressions[i].replace( '/', '.' ), value );
+ Map values = ExpressionUtil.evaluate( expressions[i], contexts
);
+ for ( Iterator it = values.keySet().iterator(); it.hasNext(); )
+ {
+ Object key = it.next();
+ Object value = values.get( key );
+ PropertyUtil.store( expressionProperties,
key.toString().replace( '/', '.' ), value );
+ }
}
}
Modified:
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/ExpressionUtil.java
URL:
http://svn.apache.org/viewvc/maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/ExpressionUtil.java?rev=949790&r1=949789&r2=949790&view=diff
==============================================================================
---
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/ExpressionUtil.java
(original)
+++
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/main/java/org/apache/maven/plugin/coreit/ExpressionUtil.java
Mon May 31 16:16:22 2010
@@ -24,6 +24,9 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -48,65 +51,56 @@ class ExpressionUtil
* Evaluates the specified expression. Expressions are composed of
segments which are separated by a forward slash
* ('/'). Each segment specifies a (public) bean property of the current
object and drives the evaluation further
* down the object graph. For lists, arrays and maps segments can
additionally specify the index/key of an element.
- * The initial segment denotes the root object and the parameter
<code>contexts</code> is used to specify which
- * root objects are available. For instance, if <code>contexts</code> maps
the token "project" to a Maven project
+ * The initial segment denotes the root object and the parameter
<code>contexts</code> is used to specify which root
+ * objects are available. For instance, if <code>contexts</code> maps the
token "project" to a Maven project
* instance, the expression "project/build/resources/0/directory"
specifies the first resource directory of the
* project.
*
* @param expression The expression to evaluate, may be <code>null</code>.
- * @param contexts The possible root objects for the expression
evaluation, indexed by their identifying token, must
- * not be <code>null</code>.
- * @return The value of the expression or <code>null</code> if the
expression could not be evaluated.
+ * @param context The object to start expression evaluation at, must not
be <code>null</code>.
+ * @return The values of the evaluation, indexed by expression, or an
empty map if the segments could not be
+ * evaluated.
*/
- public static Object evaluate( String expression, Map contexts )
+ public static Map evaluate( String expression, Object context )
{
- Object value = null;
+ Map values = Collections.EMPTY_MAP;
if ( expression != null && expression.length() > 0 )
{
List segments = Arrays.asList( expression.split( "/", 0 ) );
- if ( !segments.isEmpty() )
- {
- Object context = contexts.get( segments.get( 0 ) );
- if ( context != null )
- {
- value = evaluate( context, segments.subList( 1,
segments.size() ) );
- }
- }
+ values = evaluate( "", segments, context );
}
- return value;
+ return values;
}
/**
* Evaluates the given expression segments against the specified object.
*
- * @param context The object to evaluate the segments against, may be
<code>null</code>.
+ * @param prefix The expression prefix that led to the current context,
must not be <code>null</code>.
* @param segments The expression segments to evaluate, must not be
<code>null</code>.
- * @return The value of the evaluation or <code>null</code> if the
segments could not be evaluated.
+ * @param context The object to evaluate the segments against, may be
<code>null</code>.
+ * @return The values of the evaluation, indexed by expression, or an
empty map if the segments could not be
+ * evaluated.
*/
- private static Object evaluate( Object context, List segments )
+ private static Map evaluate( String prefix, List segments, Object context )
{
- Object value = null;
+ Map values = Collections.EMPTY_MAP;
if ( segments.isEmpty() )
{
- value = context;
+ values = Collections.singletonMap( prefix, context );
}
else if ( context != null )
{
- Object target = null;
+ Map targets = Collections.EMPTY_MAP;
String segment = (String) segments.get( 0 );
- if ( segment.length() <= 0 )
- {
- value = context;
- }
- else if ( context.getClass().isArray() && Character.isDigit(
segment.charAt( 0 ) ) )
+ if ( context.getClass().isArray() && Character.isDigit(
segment.charAt( 0 ) ) )
{
try
{
int index = Integer.parseInt( segment );
- target = Array.get( context, index );
+ targets = Collections.singletonMap( segment, Array.get(
context, index ) );
}
catch ( RuntimeException e )
{
@@ -118,21 +112,51 @@ class ExpressionUtil
try
{
int index = Integer.parseInt( segment );
- target = ( (List) context ).get( index );
+ targets = Collections.singletonMap( segment, ( (List)
context ).get( index ) );
}
catch ( RuntimeException e )
{
// invalid index, just ignore
}
}
+ else if ( ( context instanceof Collection ) && "*".equals( segment
) )
+ {
+ targets = new LinkedHashMap();
+ int index = 0;
+ for ( Iterator it = ( (Collection) context ).iterator();
it.hasNext(); index++ )
+ {
+ targets.put( Integer.toString( index ), it.next() );
+ }
+ }
+ else if ( context.getClass().isArray() && "*".equals( segment ) )
+ {
+ targets = new LinkedHashMap();
+ for ( int index = 0, n = Array.getLength( context ); index <
n; index++ )
+ {
+ targets.put( Integer.toString( index ), Array.get(
context, index ) );
+ }
+ }
else
{
- target = getProperty( context, segment );
+ targets = Collections.singletonMap( segment, getProperty(
context, segment ) );
+ }
+
+ values = new LinkedHashMap();
+ for ( Iterator it = targets.keySet().iterator(); it.hasNext(); )
+ {
+ Object key = it.next();
+ Object target = targets.get( key );
+ values.putAll( evaluate( concat( prefix, String.valueOf( key )
),
+ segments.subList( 1, segments.size()
), target ) );
}
- value = evaluate( target, segments.subList( 1, segments.size() ) );
}
- return value;
+ return values;
+ }
+
+ private static String concat( String prefix, String segment )
+ {
+ return ( prefix == null || prefix.length() <= 0 ) ? segment : ( prefix
+ '/' + segment );
}
/**
Modified:
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/test/java/org/apache/maven/plugin/coreit/ExpressionUtilTest.java
URL:
http://svn.apache.org/viewvc/maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/test/java/org/apache/maven/plugin/coreit/ExpressionUtilTest.java?rev=949790&r1=949789&r2=949790&view=diff
==============================================================================
---
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/test/java/org/apache/maven/plugin/coreit/ExpressionUtilTest.java
(original)
+++
maven/core-integration-testing/trunk/core-it-support/core-it-plugins/maven-it-plugin-expression/src/test/java/org/apache/maven/plugin/coreit/ExpressionUtilTest.java
Mon May 31 16:16:22 2010
@@ -47,35 +47,48 @@ public class ExpressionUtilTest
contexts.put( "map", map );
contexts.put( "bean", bean );
- assertSame( array, ExpressionUtil.evaluate( "array", contexts ) );
- assertSame( array, ExpressionUtil.evaluate( "array/", contexts ) );
- assertSame( list, ExpressionUtil.evaluate( "list", contexts ) );
- assertSame( map, ExpressionUtil.evaluate( "map", contexts ) );
- assertSame( bean, ExpressionUtil.evaluate( "bean", contexts ) );
- assertNull( ExpressionUtil.evaluate( "no-root", contexts ) );
-
- assertEquals( new Integer( 3 ), ExpressionUtil.evaluate(
"array/length", contexts ) );
- assertEquals( "three", ExpressionUtil.evaluate( "array/2", contexts )
);
- assertEquals( new Integer( 5 ), ExpressionUtil.evaluate(
"array/2/length", contexts ) );
- assertNull( ExpressionUtil.evaluate( "array/invalid", contexts ) );
- assertNull( ExpressionUtil.evaluate( "array/-1", contexts ) );
- assertNull( ExpressionUtil.evaluate( "array/999", contexts ) );
-
- assertEquals( new Integer( 3 ), ExpressionUtil.evaluate( "list/size",
contexts ) );
- assertEquals( "-2", ExpressionUtil.evaluate( "list/2", contexts ) );
- assertNull( ExpressionUtil.evaluate( "list/invalid", contexts ) );
- assertNull( ExpressionUtil.evaluate( "list/-1", contexts ) );
- assertNull( ExpressionUtil.evaluate( "list/999", contexts ) );
-
- assertEquals( new Integer( 1 ), ExpressionUtil.evaluate( "map/size",
contexts ) );
- assertEquals( "value", ExpressionUtil.evaluate( "map/some.key",
contexts ) );
- assertNull( ExpressionUtil.evaluate( "map/invalid", contexts ) );
-
- assertEquals( "field", ExpressionUtil.evaluate( "bean/field", contexts
) );
- assertNull( ExpressionUtil.evaluate( "bean/invalid", contexts ) );
- assertEquals( "prop", ExpressionUtil.evaluate( "bean/bean/prop",
contexts ) );
- assertEquals( "flag", ExpressionUtil.evaluate( "bean/bean/flag",
contexts ) );
- assertEquals( "arg", ExpressionUtil.evaluate( "bean/bean/arg",
contexts ) );
+ assertSame( array, evaluate( "array", contexts ) );
+ assertSame( array, ExpressionUtil.evaluate( "array/", contexts ).get(
"array" ) );
+ assertSame( list, evaluate( "list", contexts ) );
+ assertSame( map, evaluate( "map", contexts ) );
+ assertSame( bean, evaluate( "bean", contexts ) );
+ assertNull( evaluate( "no-root", contexts ) );
+
+ assertEquals( new Integer( 3 ), evaluate( "array/length", contexts ) );
+ assertEquals( "three", evaluate( "array/2", contexts ) );
+ assertEquals( new Integer( 5 ), evaluate( "array/2/length", contexts )
);
+ assertNull( evaluate( "array/invalid", contexts ) );
+ assertNull( evaluate( "array/-1", contexts ) );
+ assertNull( evaluate( "array/999", contexts ) );
+ assertEquals( 3, ExpressionUtil.evaluate( "array/*", contexts ).size()
);
+ assertEquals( "one", ExpressionUtil.evaluate( "array/*", contexts
).get( "array/0" ) );
+ assertEquals( "two", ExpressionUtil.evaluate( "array/*", contexts
).get( "array/1" ) );
+ assertEquals( "three", ExpressionUtil.evaluate( "array/*", contexts
).get( "array/2" ) );
+
+ assertEquals( new Integer( 3 ), evaluate( "list/size", contexts ) );
+ assertEquals( "-2", evaluate( "list/2", contexts ) );
+ assertNull( evaluate( "list/invalid", contexts ) );
+ assertNull( evaluate( "list/-1", contexts ) );
+ assertNull( evaluate( "list/999", contexts ) );
+ assertEquals( 3, ExpressionUtil.evaluate( "list/*", contexts ).size()
);
+ assertEquals( "0", ExpressionUtil.evaluate( "list/*", contexts ).get(
"list/0" ) );
+ assertEquals( "-1", ExpressionUtil.evaluate( "list/*", contexts ).get(
"list/1" ) );
+ assertEquals( "-2", ExpressionUtil.evaluate( "list/*", contexts ).get(
"list/2" ) );
+
+ assertEquals( new Integer( 1 ), evaluate( "map/size", contexts ) );
+ assertEquals( "value", evaluate( "map/some.key", contexts ) );
+ assertNull( evaluate( "map/invalid", contexts ) );
+
+ assertEquals( "field", evaluate( "bean/field", contexts ) );
+ assertNull( evaluate( "bean/invalid", contexts ) );
+ assertEquals( "prop", evaluate( "bean/bean/prop", contexts ) );
+ assertEquals( "flag", evaluate( "bean/bean/flag", contexts ) );
+ assertEquals( "arg", evaluate( "bean/bean/arg", contexts ) );
+ }
+
+ private static Object evaluate( String expression, Object context )
+ {
+ return ExpressionUtil.evaluate( expression, context ).get( expression
);
}
public void testGetProperty()