/* * Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import org.apache.tools.ant.taskdefs.*; import java.io.IOException; import org.apache.tools.ant.Task; import org.apache.tools.ant.Target; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.types.PropertySet; /** * Call another target in the same project. * *
 *    <target name="foo">
 *      <antcall target="bar">
 *        <param name="property1" value="aaaaa" />
 *        <param name="foo" value="baz" />
 *       </antcall>
 *    </target>
 *
 *    <target name="bar" depends="init">
 *      <echo message="prop is ${property1} ${foo}" />
 *    </target>
 * 
* *

This only works as expected if neither property1 nor foo are * defined in the project itself. * * * @since Ant 1.2 * * @ant.task name="antcall" category="control" */ public class TreeCallTarget extends Task { private Ant callee; // must match the default value of Ant#inheritAll private boolean inheritAll = true; // must match the default value of Ant#inheritRefs private boolean inheritRefs = false; private boolean targetSet = false; private String theTarget = null; private String address = null; /** * If true, pass all properties to the new Ant project. * Defaults to true. * @param inherit boolean flag. */ public void setInheritAll(boolean inherit) { inheritAll = inherit; } /** * If true, pass all references to the new Ant project. * Defaults to false. * @param inheritRefs boolean flag. */ public void setInheritRefs(boolean inheritRefs) { this.inheritRefs = inheritRefs; } /** * Initialize this task by creating new instance of the ant task and * configuring it 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(); } /** * Delegate the work to the ant task instance, after setting it up. * @throws BuildEximport org.apache.tools.ant.Task;ception on validation failure or if the target didn't * execute. */ public void execute() throws BuildException { if (callee == null) { init(); } if (!targetSet) { throw new BuildException( "Attribute target or at least one nested target is required.", getLocation()); } //figure out what the address of this instance should be String callingAddress = this.getOwningTarget().getAddress(); int subAddress = this.getOwningTarget().getNextSubAddress(); this.getOwningTarget().incrementNextSubAddress(); if ( callingAddress == null ) { address = "" + subAddress; } else { address = callingAddress + "." + subAddress; } //check that the target should be run given address,resume.mode, rusume.from and resume.to String resumeFrom = this.getProject().getProperty("resume.from"); String resumeDescend = this.getProject().getProperty("resume.descend"); String resumeTo = this.getProject().getProperty("resume.to"); //given resumeFrom, might we execute? boolean shouldExecOnFrom = resumeFrom == null || isDescendantOf(resumeFrom,address) || isAfter(address,resumeFrom); //given resumeDescend, might we execute? boolean shouldExecuteOnDescend = resumeDescend == null || isDescendantOf(address,resumeDescend); //given resumeTo, might we execute? boolean shouldExecOnTo = resumeTo == null || !isAfter(address,resumeTo); //check that all are true boolean execute = shouldExecOnFrom && shouldExecuteOnDescend && shouldExecOnTo; if ( execute ) { callee.setAntfile(getProject().getProperty("ant.file")); callee.setInheritAll(inheritAll); callee.setInheritRefs(inheritRefs); Target calleeTarget = (Target)callee.getProject().getTargets().get(theTarget); calleeTarget.setAddress(address); if( false ) { throw new BuildException( "\n theTarget " + theTarget + "\n calleeTarget: " + calleeTarget + "\n address: " + calleeTarget.getAddress(), getLocation() ); } callee.execute(theTarget,address); } } /** * Create a new Property to pass to the invoked target(s). * @return a Property object. */ public Property createParam() { if (callee == null) { init(); } return callee.createProperty(); } /** * Reference element identifying a data type to carry * over to the invoked target. * @param r the specified Ant.Reference. * @since Ant 1.5 */ public void addReference(Ant.Reference r) { if (callee == null) { init(); } callee.addReference(r); } /** * Set of properties to pass to the new project. * @param ps the PropertySet to pass. * @since Ant 1.6 */ public void addPropertyset(PropertySet ps) { if (callee == null) { init(); } callee.addPropertyset(ps); } /** * Set target to execute. * @param target the name of the target to execute. */ public void setTarget(String target) { if (callee == null) { init(); } callee.setTarget(target); theTarget = target; targetSet = true; } /** * Add a target to the list of targets to invoke. * @param t Ant.TargetElement representing the target. * @since Ant 1.6.3 */ public void addConfiguredTarget(Ant.TargetElement t) { if (callee == null) { init(); } callee.addConfiguredTarget(t); targetSet = true; } /** * @see Task#handleOutput(String) * * @since Ant 1.5 */ public void handleOutput(String output) { if (callee != null) { callee.handleOutput(output); } else { super.handleOutput(output); } } /** * @see Task#handleInput(byte[], int, int) * * @since Ant 1.6 */ public int handleInput(byte[] buffer, int offset, int length) throws IOException { if (callee != null) { return callee.handleInput(buffer, offset, length); } else { return super.handleInput(buffer, offset, length); } } /** * @see Task#handleFlush(String) * * @since Ant 1.5.2 */ public void handleFlush(String output) { if (callee != null) { callee.handleFlush(output); } else { super.handleFlush(output); } } /** * @see Task#handleErrorOutput(String) * * @since Ant 1.5 */ public void handleErrorOutput(String output) { if (callee != null) { callee.handleErrorOutput(output); } else { super.handleErrorOutput(output); } } /** * @see Task#handleErrorFlush(String) * * @since Ant 1.5.2 */ public void handleErrorFlush(String output) { if (callee != null) { callee.handleErrorFlush(output); } else { super.handleErrorFlush(output); } } /* --- node address relations --- */ public static boolean isAfter(String x, String y) { System.out.println( "x: " + x ); System.out.println( "y: " + y ); if ( x.equals("") || y.equals("") ) { throw new BuildException("Error - x or y not specified !!"); } //check that both are in the form int.int.int //break into chambers String[] xs = x.split("\\."); String[] ys = y.split("\\."); //figure out n int n = ys.length; //step through, making sure x values are higher than or equal to y values for ( int i=0; i yValue ) { System.out.println("x is after y"); return true; } } // if execution reaches here, first n places are equal System.out.println("x is after y"); return true; } public static boolean isDescendantOf(String x, String y) { System.out.println( "x: " + x ); System.out.println( "y: " + y ); if ( x.equals("") || y.equals("") ) { throw new BuildException("Error - x or y not specified !!"); } //check that both are in the form int.int.int //break into chambers String[] xs = x.split("\\."); String[] ys = y.split("\\."); //make sure x is at least as deep as y if ( xs.length < ys.length ) { System.out.println("x not descendant of y"); return false; } //figure out n int n = ys.length; //step through, making sure x values are equal to y values for ( int i=0; i