Attached is a patch to Maven't <ant> task that allows references and
properties to be exported from a child Ant build into the parent build.

So just like the <ant> task as inheritAll="true|false" and
inheritRefs="true|false" there is now a similar exportRefs="true|false" and
exportAll="true|false". Note that a reference or property is only exported
if the reference/property does not exist in the parent build - so this
operation is safe and doesn't overwrite anything defined in the projects
build.xml.


What this means is that using this special version of <ant> we can call the
Maven builds (such as for the 'maven:compile' target), then use the
generated Maven classpath in the outer build (i.e. the build.xml of your
project). So if you want to run some test programs or sample programs in
your project as an Ant task you can let Maven create the classpath for you
and you can just reference it in your build.xml.

Here's an example of it in action; in the Jelly build I'm patching the
"maven:compile" target to export the Maven created classes directory
(property) and classpath (reference) so that I can then run Java code that
Maven has just build. e.g.

<!-- patch the maven:compile to use the maven-ant task -->
<target name="maven:compile">
    <taskdef
        name="maven-ant"
        classname="org.apache.maven.ant.Ant">
        <classpath>
            <pathelement location="${lib.repo}/maven.jar"/>
        </classpath>
    </taskdef>

    <maven-ant
        antfile="${maven.home}/plugins/core/build.xml"
        target="compile"
        exportRefs="true"
        exportAll="true"/>
</target>

Then later on I declare a local 'compile' target to create a classpath I can
use to run java code that Maven has just built...

<target name="compile" depends="maven:compile, maven:jar-resources">
    <path id="test.classpath">
        <!-- these are created inside the Maven builds -->
        <pathelement path="${maven.build.dest}"/>
        <path refid="maven.dependency.classpath"/>
    </path>
</target>

Then I can run things like this...

<target name="hello.world" depends="compile">
    <java classname="org.apache.foo.Bar" fork="yes">
        <classpath refid="test.classpath"/>
    </java>
</target>


James
Index: src/java/org/apache/maven/ant/Ant.java
===================================================================
RCS file: /home/cvs/jakarta-turbine-maven/src/java/org/apache/maven/ant/Ant.java,v
retrieving revision 1.2
diff -u -r1.2 Ant.java
--- src/java/org/apache/maven/ant/Ant.java      22 Apr 2002 00:15:04 -0000      1.2
+++ src/java/org/apache/maven/ant/Ant.java      23 May 2002 21:59:34 -0000
@@ -121,6 +121,12 @@
     /** should we inherit references from the parent ? */
     private boolean inheritRefs = false;
 
+    /** should we export all properties to the parent ? */
+    private boolean exportAll = false;
+    
+    /** should we export references to the parent ? */
+    private boolean exportRefs = false;
+    
     /** the properties to pass to the new project */
     private Vector properties = new Vector();
 
@@ -154,6 +160,27 @@
     }
 
     /**
+     * If true, all properties defined in the child Project
+     * are exported to the parent Project so long as they are not
+     * already defined. No properties will be overwritten.
+     * If false, properties are not exported to the parent project
+     */
+    public void setExportAll(boolean value) {
+        exportAll = value;
+    }
+
+    /**
+     * If true, all references will be exported from the child Project
+     * into the parent Project after the child project has been executed
+     * providing they don't already exist in the parent Project.
+     * No references will ever be overwritten.
+     * If false, references are not exported to the parent project
+     */
+    public void setExportRefs(boolean value) {
+        exportRefs = value;
+    }
+
+    /**
      * Creates a Project instance for the project to call.
      */
     public void init()
@@ -403,6 +430,9 @@
             }
 
             newProject.executeTarget(target);
+            
+            exportProperties();
+            exportReferences();
         }
         finally
         {
@@ -451,14 +481,13 @@
         Hashtable thisReferences = (Hashtable) project.getReferences().clone();
         Hashtable newReferences = newProject.getReferences();
         Enumeration e;
-        if (references.size() > 0)
+        if (references.size() > 0) 
         {
             for (e = references.elements(); e.hasMoreElements(); ) 
             {
                 Reference ref = (Reference) e.nextElement();
                 String refid = ref.getRefId();
-                if (refid == null) 
-                {
+                if (refid == null) {
                     throw new BuildException("the refid attribute is required"
                                              + " for reference elements");
                 }
@@ -482,12 +511,12 @@
 
         // Now add all references that are not defined in the
         // subproject, if inheritRefs is true
-        if (inheritRefs)
+        if (inheritRefs) 
         {
-            for (e = thisReferences.keys(); e.hasMoreElements(); )
+            for (e = thisReferences.keys(); e.hasMoreElements(); ) 
             {
                 String key = (String) e.nextElement();
-                if (newReferences.containsKey(key))
+                if (newReferences.containsKey(key)) 
                 {
                     continue;
                 }
@@ -509,8 +538,25 @@
         //Object orig = project.getReference(oldKey);
         // Changed this to make it work with ant 1.4
         Object orig = project.getReferences().get(oldKey);
-        Class c = orig.getClass();
+        
+        copyReference(orig, newKey, newProject);
+    }
+
+    /**
+     * Try to clone the given reference .
+     *
+     * <p>If we cannot clone it, lets reuse the existing 
+     * reference and keep our fingers crossed.</p>
+     * 
+     * @param orig is the reference to be cloned
+     * @param key is the key for the newly created reference
+     * @param aProject is the project to add the new reference to
+     * @return a new cloned reference, ready for adding to a different project
+     */
+    private void copyReference(Object orig, String key, Project aProject)
+    {
         Object copy = orig;
+        Class c = orig.getClass();
         try
         {
             Method cloneM = c.getMethod("clone", new Class[0]);
@@ -527,7 +573,7 @@
 
         if (copy instanceof ProjectComponent)
         {
-            ((ProjectComponent) copy).setProject(newProject);
+            ((ProjectComponent) copy).setProject(aProject);
         }
         else
         {
@@ -537,7 +583,7 @@
                     c.getMethod("setProject", new Class[] {Project.class});
                 if (setProjectM != null)
                 {
-                    setProjectM.invoke(copy, new Object[] {newProject});
+                    setProjectM.invoke(copy, new Object[] {aProject});
                 }
             }
             catch (NoSuchMethodException e)
@@ -548,11 +594,68 @@
             catch (Exception e2)
             {
                 String msg = "Error setting new project instance for "
-                    + "reference with id " + oldKey;
+                    + "reference with new id " + key;
                 throw new BuildException(msg, e2, location);
             }
         }
-        newProject.addReference(newKey, copy);
+        aProject.addReference(key, copy);
+    }
+
+    /**
+     * Export any references defined in the child project to the parent
+     * Project providing that they don't already exist in the parent
+     * project.
+     */
+    private void exportReferences() throws BuildException {
+        if (exportRefs) {
+            Hashtable thisReferences = (Hashtable) project.getReferences().clone();
+            Hashtable newReferences = newProject.getReferences();
+            
+            for (Enumeration e = newReferences.keys(); e.hasMoreElements(); )
+            {
+                String refid = (String) e.nextElement();
+                if (refid != null)
+                {
+                    // do not overwrite any existing references
+                    if (!thisReferences.containsKey(refid)) 
+                    {
+                        Object reference = newReferences.get(refid);
+                        
+                        log("exporting reference for id: " + refid, 
+Project.MSG_VERBOSE);
+                        
+                        copyReference(reference, refid, project);
+                    }
+                }
+            }
+        }
+    }
+    
+
+    /**
+     * Export any properties defined in the child project to the parent
+     * Project providing that they don't already exist in the parent
+     * project.
+     */
+    private void exportProperties() throws BuildException {
+        if (exportAll) {
+            Hashtable thisProperties = (Hashtable) project.getProperties().clone();
+            Hashtable newProperties = newProject.getProperties();
+            
+            for (Enumeration e = newProperties.keys(); e.hasMoreElements(); )
+            {
+                String key = (String) e.nextElement();
+                if (key != null)
+                {
+                    // do not overwrite any existing properties
+                    if (!thisProperties.containsKey(key)) 
+                    {
+                        log("exporting property for key: " + key, 
+Project.MSG_VERBOSE);
+                        
+                        project.setProperty(key, newProject.getProperty(key));
+                    }
+                }
+            }
+        }
     }
 
     /**

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to