jvanzyl     02/04/19 07:51:31

  Added:       src/java/org/apache/maven/ant Ant.java CallTarget.java
  Log:
  Adding a couple ant sources and back ported them to work with 1.4. The start
  of the extension mechanism which is pretty much impossible with ant 1.4.
  
  Revision  Changes    Path
  1.1                  jakarta-turbine-maven/src/java/org/apache/maven/ant/Ant.java
  
  Index: Ant.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  //package org.apache.tools.ant.taskdefs;
  package org.apache.maven.ant;
  
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.ProjectComponent;
  import org.apache.tools.ant.BuildListener;
  import org.apache.tools.ant.DefaultLogger;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.ProjectHelper;
  import org.apache.tools.ant.taskdefs.Property;
  import org.apache.tools.ant.util.FileUtils;
  import java.io.File;
  import java.io.PrintStream;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.lang.reflect.Method;
  import java.util.Vector;
  import java.util.Hashtable;
  import java.util.Enumeration;
  
  /**
   * Call Ant in a sub-project.
   *
   *  <pre>
   *  &lt;target name=&quot;foo&quot; depends=&quot;init&quot;&gt;
   *    &lt;ant antfile=&quot;build.xml&quot; target=&quot;bar&quot; &gt;
   *      &lt;property name=&quot;property1&quot; value=&quot;aaaaa&quot; /&gt;
   *      &lt;property name=&quot;foo&quot; value=&quot;baz&quot; /&gt;
   *    &lt;/ant&gt;</SPAN>
   *  &lt;/target&gt;</SPAN>
   *
   *  &lt;target name=&quot;bar&quot; depends=&quot;init&quot;&gt;
   *    &lt;echo message=&quot;prop is ${property1} ${foo}&quot; /&gt;
   *  &lt;/target&gt;
   * </pre>
   *
   *
   * @author [EMAIL PROTECTED]
   *
   * @since Ant 1.1
   *
   * @ant.task category="control"
   */
  public class Ant extends Task {
  
      /** the basedir where is executed the build file */
      private File dir = null;
  
      /** 
       * the build.xml file (can be absolute) in this case dir will be
       * ignored 
       */
      private String antFile = null;
  
      /** the target to call if any */
      private String target = null;
  
      /** the output */
      private String output  = null;
  
      /** should we inherit properties from the parent ? */
      private boolean inheritAll = true;
  
      /** should we inherit references from the parent ? */
      private boolean inheritRefs = false;
  
      /** the properties to pass to the new project */
      private Vector properties = new Vector();
  
      /** the references to pass to the new project */
      private Vector references = new Vector();
  
      /** the temporary project created to run the build file */
      private Project newProject;
  
      /** The stream to which output is to be written. */
      private PrintStream out = null;
  
      /**
       * If true, inherit all properties from parent Project
       * If false, inherit only userProperties and those defined
       * inside the ant call itself
       */
      public void setInheritAll(boolean value) {
          inheritAll = value;
      }
  
      /**
       * If true, inherit all references from parent Project
       * If false, inherit only those defined
       * inside the ant call itself
       */
      public void setInheritRefs(boolean value) {
          inheritRefs = value;
      }
  
      /**
       * Creates a Project instance for the project to call.
       */
      public void init() {
          newProject = new Project();
          newProject.setJavaVersionProperty();
          newProject.addTaskDefinition("property",
                                       (Class) project.getTaskDefinitions()
                                               .get("property"));
      }
  
      /**
       * Called in execute or createProperty if newProject is null.
       *
       * <p>This can happen if the same instance of this task is run
       * twice as newProject is set to null at the end of execute (to
       * save memory and help the GC).</p>
       *
       * <p>Sets all properties that have been defined as nested
       * property elements.</p>
       */
      private void reinit() {
          init();
          final int count = properties.size();
          for (int i = 0; i < count; i++) {
              Property p = (Property) properties.elementAt(i);
              Property newP = (Property) newProject.createTask("property");
              newP.setName(p.getName());
              if (p.getValue() != null) {
                  newP.setValue(p.getValue());
              }
              if (p.getFile() != null) {
                  newP.setFile(p.getFile());
              }
              if (p.getResource() != null) {
                  newP.setResource(p.getResource());
              }
              properties.setElementAt(newP, i);
          }
      }
  
      /**
       * Attaches the build listeners of the current project to the new
       * project, configures a possible logfile, transfers task and
       * data-type definitions, transfers properties (either all or just
       * the ones specified as user properties to the current project,
       * depending on inheritall).
       */
      private void initializeProject() {
          Vector listeners = project.getBuildListeners();
          final int count = listeners.size();
          for (int i = 0; i < count; i++) {
              newProject.addBuildListener((BuildListener) listeners.elementAt(i));
          }
  
          if (output != null) {
              File outfile = null;
              if (dir != null) {
                  outfile = FileUtils.newFileUtils().resolveFile(dir, output);
              } else {
                  outfile = getProject().resolveFile(output);
              }
              try {
                  out = new PrintStream(new FileOutputStream(outfile));
                  DefaultLogger logger = new DefaultLogger();
                  logger.setMessageOutputLevel(Project.MSG_INFO);
                  logger.setOutputPrintStream(out);
                  logger.setErrorPrintStream(out);
                  newProject.addBuildListener(logger);
              } catch (IOException ex) {
                  log("Ant: Can't set output to " + output);
              }
          }
  
          Hashtable taskdefs = project.getTaskDefinitions();
          Enumeration et = taskdefs.keys();
          while (et.hasMoreElements()) {
              String taskName = (String) et.nextElement();
              if (taskName.equals("property")) {
                  // we have already added this taskdef in #init
                  continue;
              }
              Class taskClass = (Class) taskdefs.get(taskName);
              newProject.addTaskDefinition(taskName, taskClass);
          }
  
          Hashtable typedefs = project.getDataTypeDefinitions();
          Enumeration e = typedefs.keys();
          while (e.hasMoreElements()) {
              String typeName = (String) e.nextElement();
              Class typeClass = (Class) typedefs.get(typeName);
              newProject.addDataTypeDefinition(typeName, typeClass);
          }
  
          // set user-defined or all properties from calling project
          Hashtable prop1;
          if (inheritAll) {
             prop1 = project.getProperties();
          } else {
             prop1 = project.getUserProperties();
  
             // set Java built-in properties separately,
             // b/c we won't inherit them.
             newProject.setSystemProperties();
          }
  
          e = prop1.keys();
          while (e.hasMoreElements()) {
              String arg = (String) e.nextElement();
              if ("basedir".equals(arg) || "ant.file".equals(arg)) {
                  // basedir and ant.file get special treatment in execute()
                  continue;
              }
  
              String value = (String) prop1.get(arg);
              if (inheritAll){
                 newProject.setProperty(arg, value);
              } else {
                 newProject.setUserProperty(arg, value);
              }
          }
      }
  
      /**
       * Pass output sent to System.out to the new project.
       *
       * @since Ant 1.5
       */
      protected void handleOutput(String line) {
          if (newProject != null) {
              newProject.demuxOutput(line, false);
          } else {
              super.handleOutput(line);
          }
      }
  
      /**
       * Pass output sent to System.err to the new project.
       *
       * @since Ant 1.5
       */
      protected void handleErrorOutput(String line) {
          if (newProject != null) {
              newProject.demuxOutput(line, true);
          } else {
              super.handleErrorOutput(line);
          }
      }
  
      /**
       * Do the execution.
       */
      public void execute() throws BuildException {
          File savedDir = dir;
          String savedAntFile = antFile;
          String savedTarget = target;
          try {
              if (newProject == null) {
                  reinit();
              }
  
              if ((dir == null) && (inheritAll)) {
                  dir = project.getBaseDir();
              }
  
              initializeProject();
  
              if (dir != null) {
                  newProject.setBaseDir(dir);
                  newProject.setUserProperty("basedir" , dir.getAbsolutePath());
              } else {
                  dir = project.getBaseDir();
              }
  
              overrideProperties();
  
              if (antFile == null) {
                  antFile = "build.xml";
              }
  
              File file = FileUtils.newFileUtils().resolveFile(dir, antFile);
              antFile = file.getAbsolutePath();
  
              log("calling target " + (target != null ? target : "[default]")
                      + " in build file " +  antFile.toString(),
                      Project.MSG_VERBOSE);
              newProject.setUserProperty("ant.file" , antFile);
              ProjectHelper.configureProject(newProject, new File(antFile));
  
              if (target == null) {
                  target = newProject.getDefaultTarget();
              }
  
              addReferences();
  
              // Are we trying to call the target in which we are defined?
              if (newProject.getBaseDir().equals(project.getBaseDir()) &&
                  
newProject.getProperty("ant.file").equals(project.getProperty("ant.file")) &&
                  getOwningTarget() != null &&
                  target.equals(this.getOwningTarget().getName())) {
  
                  throw new BuildException("ant task calling its own parent " 
                      + "target");
              }
  
              newProject.executeTarget(target);
          } finally {
              // help the gc
              newProject = null;
              if (output != null && out != null) {
                  try {
                      out.close();
                  } catch (final Exception e) {
                      //ignore
                  }
              }
              dir = savedDir;
              antFile = savedAntFile;
              target = savedTarget;
          }
      }
  
      /**
       * Override the properties in the new project with the one
       * explicitly defined as nested elements here.
       */
      private void overrideProperties() throws BuildException {
          Enumeration e = properties.elements();
          while (e.hasMoreElements()) {
              Property p = (Property) e.nextElement();
              p.setProject(newProject);
              p.execute();
          }
      }
  
      /**
       * Add the references explicitly defined as nested elements to the
       * new project.  Also copy over all references that don't override
       * existing references in the new project if inheritrefs has been
       * requested.
       */
      private void addReferences() throws BuildException {
          Hashtable thisReferences = (Hashtable) project.getReferences().clone();
          Hashtable newReferences = newProject.getReferences();
          Enumeration e;
          if (references.size() > 0) {
              for (e = references.elements(); e.hasMoreElements();) {
                  Reference ref = (Reference) e.nextElement();
                  String refid = ref.getRefId();
                  if (refid == null) {
                      throw new BuildException("the refid attribute is required"
                                               + " for reference elements");
                  }
                  if (!thisReferences.containsKey(refid)) {
                      log("Parent project doesn't contain any reference '"
                          + refid + "'",
                          Project.MSG_WARN);
                      continue;
                  }
  
                  thisReferences.remove(refid);
                  String toRefid = ref.getToRefid();
                  if (toRefid == null) {
                      toRefid = refid;
                  }
                  copyReference(refid, toRefid);
              }
          }
  
          // Now add all references that are not defined in the
          // subproject, if inheritRefs is true
          if (inheritRefs) {
              for (e = thisReferences.keys(); e.hasMoreElements();) {
                  String key = (String) e.nextElement();
                  if (newReferences.containsKey(key)) {
                      continue;
                  }
                  copyReference(key, key);
              }
          }
      }
  
      /**
       * Try to clone and reconfigure the object referenced by oldkey in
       * the parent project and add it to the new project with the key
       * newkey.
       *
       * <p>If we cannot clone it, copy the referenced object itself and
       * keep our fingers crossed.</p>
       */
      private void copyReference(String oldKey, String newKey) {
          //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();
          Object copy = orig;
          try {
              Method cloneM = c.getMethod("clone", new Class[0]);
              if (cloneM != null) {
                  copy = cloneM.invoke(orig, new Object[0]);
              }
          } catch (Exception e) {
              // not Clonable
          }
  
  
          if (copy instanceof ProjectComponent) {
              ((ProjectComponent) copy).setProject(newProject);
          } else {
              try {
                  Method setProjectM =
                      c.getMethod("setProject", new Class[] {Project.class});
                  if (setProjectM != null) {
                      setProjectM.invoke(copy, new Object[] {newProject});
                  }
              } catch (NoSuchMethodException e) {
                  // ignore this if the class being referenced does not have
                  // a set project method.
              } catch (Exception e2) {
                  String msg = "Error setting new project instance for "
                      + "reference with id " + oldKey;
                  throw new BuildException(msg, e2, location);
              }
          }
          newProject.addReference(newKey, copy);
      }
  
      /**
       * Set the dir attribute.
       */
      public void setDir(File d) {
          this.dir = d;
      }
  
      /**
       * set the build file, it can be either absolute or relative.
       * If it is absolute, <tt>dir</tt> will be ignored, if it is
       * relative it will be resolved relative to <tt>dir</tt>.
       */
      public void setAntfile(String s) {
          // @note: it is a string and not a file to handle relative/absolute
          // otherwise a relative file will be resolved based on the current
          // basedir.
          this.antFile = s;
      }
  
      /**
       * set the target to execute. If none is defined it will
       * execute the default target of the build file
       */
      public void setTarget(String s) {
          this.target = s;
      }
  
      /**
       * Set the name of a log file.  This will be resolved relative to
       * the dir attribute if specified, relative to the current
       * project's basedir otherwise.
       */
      public void setOutput(String s) {
          this.output = s;
      }
  
      /** create a property to pass to the new project as a 'user property' */
      public Property createProperty() {
          if (newProject == null) {
              reinit();
          }
          //Property p = new Property(true);
          // Make 1.5 <ant> work with 1.4 base. jvz.
          Property p = new Property();
          p.setUserProperty(true);
          
          p.setProject(newProject);
          p.setTaskName("property");
          properties.addElement(p);
          return p;
      }
  
      /**
       * create a reference element that identifies a data type that
       * should be carried over to the new project.
       */
      public void addReference(Reference r) {
          references.addElement(r);
      }
  
      /**
       * Helper class that implements the nested &lt;reference&gt;
       * element of &lt;ant&gt; and &lt;antcall&gt;.
       */
      public static class Reference
          extends org.apache.tools.ant.types.Reference {
  
          /** Creates a reference to be configured by Ant */
          public Reference() {
              super();
          }
  
          private String targetid = null;
  
          /**
           * Set the id that this reference to be stored under in the
           * new project.
           *
           * @param targetid the id under which this reference will be passed to 
           *        the new project */ 
          public void setToRefid(String targetid) {
              this.targetid = targetid; 
          }
  
          /**
           * Get the id under which this reference will be stored in the new
           * project
           *
           * @return the id of the reference in the new project.
           */
          public String getToRefid() { 
              return targetid; 
          }
      }
  }
  
  
  
  1.1                  
jakarta-turbine-maven/src/java/org/apache/maven/ant/CallTarget.java
  
  Index: CallTarget.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  //package org.apache.tools.ant.taskdefs;
  package org.apache.maven.ant;
  
  import org.apache.tools.ant.Task;
  import org.apache.tools.ant.BuildException;
  import org.apache.tools.ant.taskdefs.Property;
  
  /**
   * Call another target in the same project.
   *
   *  <pre>
   *    &lt;target name="foo"&gt;
   *      &lt;antcall target="bar"&gt;
   *        &lt;param name="property1" value="aaaaa" /&gt;
   *        &lt;param name="foo" value="baz" /&gt;
   *       &lt;/antcall&gt;
   *    &lt;/target&gt;
   *
   *    &lt;target name="bar" depends="init"&gt;
   *      &lt;echo message="prop is ${property1} ${foo}" /&gt;
   *    &lt;/target&gt;
   * </pre>
   *
   * <p>This only works as expected if neither property1 nor foo are
   * defined in the project itself.
   *
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Stefan Bodewig</a> 
   *
   * @since Ant 1.2
   *
   * @ant.task name="antcall" category="control"
   */
  public class CallTarget extends Task {
  
      private Ant callee;
      private String subTarget;
      // must match the default value of Ant#inheritAll
      private boolean inheritAll = true;
      // must match the default value of Ant#inheritRefs
      private boolean inheritRefs = false;
  
      /**
       * If true, inherit all properties from parent Project
       * If false, inherit only userProperties and those defined
       * inside the antcall call itself
       **/
      public void setInheritAll(boolean inherit) {
         inheritAll = inherit;
      }
  
      /**
       * set the inherit refs flag
       * @param inheritRefs new value
       */
      public void setInheritRefs(boolean inheritRefs) {
          this.inheritRefs = inheritRefs;
      }
  
      /**
       * init this task by creating new instance of the ant task and
       * configuring it's by calling its own init method.
       */
      public void init() {
          callee = (Ant) getProject().createTask("ant");
          callee.setOwningTarget(getOwningTarget());
          callee.setTaskName(getTaskName());
          callee.setLocation(getLocation());
          callee.init();
      }
  
      /**
       * hand off the work to the ant task of ours, after setting it up
       * @throws BuildException on validation failure or if the target didn't
       * execute
       */
      public void execute() throws BuildException {
          if (callee == null) {
              init();
          }
          
          if (subTarget == null) {
              throw new BuildException("Attribute target is required.", 
                                       location);
          }
          
          callee.setDir(getProject().getBaseDir());
          callee.setAntfile(getProject().getProperty("ant.file"));
          callee.setTarget(subTarget);
          callee.setInheritAll(inheritAll);
          callee.setInheritRefs(inheritRefs);
          callee.execute();
      }
  
      /**
       * Create a nested param element.
       */
      public Property createParam() {
          if (callee == null) {
              init();
          }
          return callee.createProperty();
      }
  
      /** 
       * create a reference element that identifies a data type that
       * should be carried over to the new project.
       *
       * @since Ant 1.5
       */
      public void addReference(Ant.Reference r) {
          if (callee == null) {
              init();
          }
          callee.addReference(r);
      }
  
      /**
       * Sets the target attribute, required.
       */
      public void setTarget(String target) {
          subTarget = target;
      }
  
      /**
       * Pass output sent to System.out to the new project.
       *
       * @since Ant 1.5
       */
      protected void handleOutput(String line) {
          if (callee != null) {
              callee.handleOutput(line);
          } else {
              super.handleOutput(line);
          }
      }
      
      /**
       * Pass output sent to System.err to the new project.
       *
       * @since Ant 1.5
       */
      protected void handleErrorOutput(String line) {
          if (callee != null) {
              callee.handleErrorOutput(line);
          } else {
              super.handleErrorOutput(line);
          }
      }
      
  }
  
  
  


Reply via email to