|
- /*
- * 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 apache@apache.org.
- *
- * 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;
-
- import java.util.Enumeration;
- import java.util.Vector;
- import java.util.StringTokenizer;
-
- /**
- * Class to implement a target object with required parameters.
- *
- * @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
- */
- public class Target implements TaskContainer {
-
- /** Name of this target. */
- private String name;
- /** The "if" condition to test on execution. */
- private String ifCondition = "";
- /** The "unless" condition to test on execution. */
- private String unlessCondition = "";
- /** List of targets this target is dependent on. */
- private Vector dependencies = new Vector(2);
- /** Children of this target (tasks and data types). */
- private Vector children = new Vector(5);
- /** Project this target belongs to. */
- private Project project;
- /** Description of this target, if any. */
- private String description = null;
-
- /** Sole constructor. */
- public Target() {
- }
-
- /**
- * Sets the project this target belongs to.
- *
- * @param project The project this target belongs to.
- * Must not be <code>null</code>.
- */
- public void setProject(Project project) {
- this.project = project;
- }
-
- /**
- * Returns the project this target belongs to.
- *
- * @return The project this target belongs to, or <code>null</code> if
- * the project has not been set yet.
- */
- public Project getProject() {
- return project;
- }
-
- /**
- * Sets the list of targets this target is dependent on.
- * The targets themselves are not resolved at this time.
- *
- * @param depS A comma-separated list of targets this target
- * depends on. Must not be <code>null</code>.
- */
- public void setDepends(String depS) {
- if (depS.length() > 0) {
- StringTokenizer tok =
- new StringTokenizer(depS, ",", true);
- while (tok.hasMoreTokens()) {
- String token = tok.nextToken().trim();
-
- // Make sure the dependency is not empty string
- if (token.equals("") || token.equals(",")) {
- throw new BuildException("Syntax Error: Depend "
- + "attribute for target \"" + getName()
- + "\" has an empty string for dependency.");
- }
-
- addDependency(token);
-
- // Make sure that depends attribute does not
- // end in a ,
- if (tok.hasMoreTokens()) {
- token = tok.nextToken();
- if (!tok.hasMoreTokens() || !token.equals(",")) {
- throw new BuildException("Syntax Error: Depend "
- + "attribute for target \"" + getName()
- + "\" ends with a , character");
- }
- }
- }
- }
- }
-
- /**
- * Sets the name of this target.
- *
- * @param name The name of this target. Should not be <code>null</code>.
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * Returns the name of this target.
- *
- * @return the name of this target, or <code>null</code> if the
- * name has not been set yet.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Adds a task to this target.
- *
- * @param task The task to be added. Must not be <code>null</code>.
- */
- public void addTask(Task task) {
- children.addElement(task);
- }
-
- /**
- * Adds the wrapper for a data type element to this target.
- *
- * @param r The wrapper for the data type element to be added.
- * Must not be <code>null</code>.
- */
- public void addDataType(RuntimeConfigurable r) {
- children.addElement(r);
- }
-
- /**
- * Returns the current set of tasks to be executed by this target.
- *
- * @return an array of the tasks currently within this target
- */
- public Task[] getTasks() {
- Vector tasks = new Vector(children.size());
- Enumeration enum = children.elements();
- while (enum.hasMoreElements()) {
- Object o = enum.nextElement();
- if (o instanceof Task) {
- tasks.addElement(o);
- }
- }
-
- Task[] retval = new Task[tasks.size()];
- tasks.copyInto(retval);
- return retval;
- }
-
- /**
- * Adds a dependency to this target.
- *
- * @param dependency The name of a target this target is dependent on.
- * Must not be <code>null</code>.
- */
- public void addDependency(String dependency) {
- dependencies.addElement(dependency);
- }
-
- /**
- * Returns an enumeration of the dependencies of this target.
- *
- * @return an enumeration of the dependencies of this target
- */
- public Enumeration getDependencies() {
- return dependencies.elements();
- }
-
- /**
- * Sets the "if" condition to test on execution. This is the
- * name of a property to test for existence - if the property
- * is not set, the task will not execute. The property goes
- * through property substitution once before testing, so if
- * property <code>foo</code> has value <code>bar</code>, setting
- * the "if" condition to <code>${foo}_x</code> will mean that the
- * task will only execute if property <code>bar_x</code> is set.
- *
- * @param property The property condition to test on execution.
- * May be <code>null</code>, in which case
- * no "if" test is performed.
- */
- public void setIf(String property) {
- this.ifCondition = (property == null) ? "" : property;
- }
-
- /**
- * Sets the "unless" condition to test on execution. This is the
- * name of a property to test for existence - if the property
- * is set, the task will not execute. The property goes
- * through property substitution once before testing, so if
- * property <code>foo</code> has value <code>bar</code>, setting
- * the "unless" condition to <code>${foo}_x</code> will mean that the
- * task will only execute if property <code>bar_x</code> isn't set.
- *
- * @param property The property condition to test on execution.
- * May be <code>null</code>, in which case
- * no "unless" test is performed.
- */
- public void setUnless(String property) {
- this.unlessCondition = (property == null) ? "" : property;
- }
-
- /**
- * Sets the description of this target.
- *
- * @param description The description for this target.
- * May be <code>null</code>, indicating that no
- * description is available.
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- * Returns the description of this target.
- *
- * @return the description of this target, or <code>null</code> if no
- * description is available.
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * Returns the name of this target.
- *
- * @return the name of this target, or <code>null</code> if the
- * name has not been set yet.
- */
- public String toString() {
- return name;
- }
-
- /**
- * Executes the target if the "if" and "unless" conditions are
- * satisfied. Dependency checking should be done before calling this
- * method, as it does no checking of its own. If either the "if"
- * or "unless" test prevents this target from being executed, a verbose
- * message is logged giving the reason. It is recommended that clients
- * of this class call performTasks rather than this method so that
- * appropriate build events are fired.
- *
- * @exception BuildException if any of the tasks fail or if a data type
- * configuration fails.
- *
- * @see #performTasks()
- * @see #setIf(String)
- * @see #setUnless(String)
- */
- public void execute() throws BuildException {
- if (testIfCondition() && testUnlessCondition()) {
- Enumeration enum = children.elements();
- while (enum.hasMoreElements()) {
- Object o = enum.nextElement();
- if (o instanceof Task) {
- Task task = (Task) o;
- task.perform();
- } else {
- RuntimeConfigurable r = (RuntimeConfigurable) o;
- r.maybeConfigure(project);
- }
- }
- } else if (!testIfCondition()) {
- project.log(this, "Skipped because property '" + this.ifCondition
- + "' not set.", Project.MSG_VERBOSE);
- } else {
- project.log(this, "Skipped because property '"
- + this.unlessCondition + "' set.", Project.MSG_VERBOSE);
- }
- }
-
- /**
- * Performs the tasks within this target (if the conditions are met),
- * firing target started/target finished messages around a call to
- * execute.
- *
- * @see #execute()
- */
- public final void performTasks() {
- try {
- project.fireTargetStarted(this);
- execute();
- project.fireTargetFinished(this, null);
- } catch (RuntimeException exc) {
- project.fireTargetFinished(this, exc);
- throw exc;
- }
- }
-
- /**
- * Replaces all occurrences of the given task in the list
- * of children with the replacement data type wrapper.
- *
- * @param el The task to replace.
- * Must not be <code>null</code>.
- * @param o The data type wrapper to replace <code>el</code> with.
- */
- void replaceChild(Task el, RuntimeConfigurable o) {
- int index;
- while ((index = children.indexOf(el)) >= 0) {
- children.setElementAt(o, index);
- }
- }
-
- /**
- * Replaces all occurrences of the given task in the list
- * of children with the replacement task.
- *
- * @param el The task to replace.
- * Must not be <code>null</code>.
- * @param o The task to replace <code>el</code> with.
- */
- void replaceChild(Task el, Task o) {
- int index;
- while ((index = children.indexOf(el)) >= 0) {
- children.setElementAt(o, index);
- }
- }
-
- /**
- * Tests whether or not the "if" condition is satisfied.
- *
- * @return whether or not the "if" condition is satisfied. If no
- * condition (or an empty condition) has been set,
- * <code>true</code> is returned.
- *
- * @see #setIf(String)
- */
- private boolean testIfCondition() {
- if ("".equals(ifCondition)) {
- return true;
- }
-
- String test = project.replaceProperties(ifCondition);
- return project.getProperty(test) != null;
- }
-
- /**
- * Tests whether or not the "unless" condition is satisfied.
- *
- * @return whether or not the "unless" condition is satisfied. If no
- * condition (or an empty condition) has been set,
- * <code>true</code> is returned.
- *
- * @see #setUnless(String)
- */
- private boolean testUnlessCondition() {
- if ("".equals(unlessCondition)) {
- return true;
- }
- String test = project.replaceProperties(unlessCondition);
- return project.getProperty(test) == null;
- }
- }
|