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()


Reply via email to