/* * 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