Home » apache-ant-1.7.1-src » org.apache.tools » ant » [javadoc | source]
    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one or more
    3    *  contributor license agreements.  See the NOTICE file distributed with
    4    *  this work for additional information regarding copyright ownership.
    5    *  The ASF licenses this file to You under the Apache License, Version 2.0
    6    *  (the "License"); you may not use this file except in compliance with
    7    *  the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    *  Unless required by applicable law or agreed to in writing, software
   12    *  distributed under the License is distributed on an "AS IS" BASIS,
   13    *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    *  See the License for the specific language governing permissions and
   15    *  limitations under the License.
   16    *
   17    */
   18   
   19   package org.apache.tools.ant;
   20   
   21   import java.util.ArrayList;
   22   import java.util.Collections;
   23   import java.util.Enumeration;
   24   import java.util.Hashtable;
   25   import java.util.Iterator;
   26   import java.util.List;
   27   import java.util.StringTokenizer;
   28   
   29   import org.apache.tools.ant.util.CollectionUtils;
   30   
   31   /**
   32    * Class to implement a target object with required parameters.
   33    *
   34    */
   35   public class Target implements TaskContainer {
   36   
   37       /** Name of this target. */
   38       private String name;
   39       /** The "if" condition to test on execution. */
   40       private String ifCondition = "";
   41       /** The "unless" condition to test on execution. */
   42       private String unlessCondition = "";
   43       /** List of targets this target is dependent on. */
   44       private List dependencies = null;
   45       /** Children of this target (tasks and data types). */
   46       private List children = new ArrayList();
   47       /** Since Ant 1.6.2 */
   48       private Location location = Location.UNKNOWN_LOCATION;
   49   
   50       /** Project this target belongs to. */
   51       private Project project;
   52   
   53       /** Description of this target, if any. */
   54       private String description = null;
   55   
   56       /** Default constructor. */
   57       public Target() {
   58           //empty
   59       }
   60   
   61       /**
   62        * Cloning constructor.
   63        * @param other the Target to clone.
   64        */
   65       public Target(Target other) {
   66           this.name = other.name;
   67           this.ifCondition = other.ifCondition;
   68           this.unlessCondition = other.unlessCondition;
   69           this.dependencies = other.dependencies;
   70           this.location = other.location;
   71           this.project = other.project;
   72           this.description = other.description;
   73           // The children are added to after this cloning
   74           this.children = other.children;
   75       }
   76   
   77       /**
   78        * Sets the project this target belongs to.
   79        *
   80        * @param project The project this target belongs to.
   81        *                Must not be <code>null</code>.
   82        */
   83       public void setProject(Project project) {
   84           this.project = project;
   85       }
   86   
   87       /**
   88        * Returns the project this target belongs to.
   89        *
   90        * @return The project this target belongs to, or <code>null</code> if
   91        *         the project has not been set yet.
   92        */
   93       public Project getProject() {
   94           return project;
   95       }
   96   
   97       /**
   98        * Sets the location of this target's definition.
   99        *
  100        * @param location   <code>Location</code>
  101        * @since 1.6.2
  102        */
  103       public void setLocation(Location location) {
  104           this.location = location;
  105       }
  106   
  107       /**
  108        * Get the location of this target's definition.
  109        *
  110        * @return <code>Location</code>
  111        * @since 1.6.2
  112        */
  113       public Location getLocation() {
  114           return location;
  115       }
  116   
  117       /**
  118        * Sets the list of targets this target is dependent on.
  119        * The targets themselves are not resolved at this time.
  120        *
  121        * @param depS A comma-separated list of targets this target
  122        *             depends on. Must not be <code>null</code>.
  123        */
  124       public void setDepends(String depS) {
  125           if (depS.length() > 0) {
  126               StringTokenizer tok =
  127                   new StringTokenizer(depS, ",", true);
  128               while (tok.hasMoreTokens()) {
  129                   String token = tok.nextToken().trim();
  130   
  131                   // Make sure the dependency is not empty string
  132                   if ("".equals(token) || ",".equals(token)) {
  133                       throw new BuildException("Syntax Error: depends "
  134                           + "attribute of target \"" + getName()
  135                           + "\" has an empty string as dependency.");
  136                   }
  137   
  138                   addDependency(token);
  139   
  140                   // Make sure that depends attribute does not
  141                   // end in a ,
  142                   if (tok.hasMoreTokens()) {
  143                       token = tok.nextToken();
  144                       if (!tok.hasMoreTokens() || !",".equals(token)) {
  145                           throw new BuildException("Syntax Error: Depend "
  146                               + "attribute for target \"" + getName()
  147                               + "\" ends with a , character");
  148                       }
  149                   }
  150               }
  151           }
  152       }
  153   
  154       /**
  155        * Sets the name of this target.
  156        *
  157        * @param name The name of this target. Should not be <code>null</code>.
  158        */
  159       public void setName(String name) {
  160           this.name = name;
  161       }
  162   
  163       /**
  164        * Returns the name of this target.
  165        *
  166        * @return the name of this target, or <code>null</code> if the
  167        *         name has not been set yet.
  168        */
  169       public String getName() {
  170           return name;
  171       }
  172   
  173       /**
  174        * Adds a task to this target.
  175        *
  176        * @param task The task to be added. Must not be <code>null</code>.
  177        */
  178       public void addTask(Task task) {
  179           children.add(task);
  180       }
  181   
  182       /**
  183        * Adds the wrapper for a data type element to this target.
  184        *
  185        * @param r The wrapper for the data type element to be added.
  186        *          Must not be <code>null</code>.
  187        */
  188       public void addDataType(RuntimeConfigurable r) {
  189           children.add(r);
  190       }
  191   
  192       /**
  193        * Returns the current set of tasks to be executed by this target.
  194        *
  195        * @return an array of the tasks currently within this target
  196        */
  197       public Task[] getTasks() {
  198           List tasks = new ArrayList(children.size());
  199           Iterator it = children.iterator();
  200           while (it.hasNext()) {
  201               Object o = it.next();
  202               if (o instanceof Task) {
  203                   tasks.add(o);
  204               }
  205           }
  206   
  207           return (Task[]) tasks.toArray(new Task[tasks.size()]);
  208       }
  209   
  210       /**
  211        * Adds a dependency to this target.
  212        *
  213        * @param dependency The name of a target this target is dependent on.
  214        *                   Must not be <code>null</code>.
  215        */
  216       public void addDependency(String dependency) {
  217           if (dependencies == null) {
  218               dependencies = new ArrayList(2);
  219           }
  220           dependencies.add(dependency);
  221       }
  222   
  223       /**
  224        * Returns an enumeration of the dependencies of this target.
  225        *
  226        * @return an enumeration of the dependencies of this target
  227        */
  228       public Enumeration getDependencies() {
  229           return (dependencies != null ? Collections.enumeration(dependencies)
  230                                        : new CollectionUtils.EmptyEnumeration());
  231       }
  232   
  233       /**
  234        * Does this target depend on the named target?
  235        * @param other the other named target.
  236        * @return true if the target does depend on the named target
  237        * @since Ant 1.6
  238        */
  239       public boolean dependsOn(String other) {
  240           Project p = getProject();
  241           Hashtable t = (p == null) ? null : p.getTargets();
  242           return (p != null
  243                   && p.topoSort(getName(), t, false).contains(t.get(other)));
  244       }
  245   
  246       /**
  247        * Sets the "if" condition to test on execution. This is the
  248        * name of a property to test for existence - if the property
  249        * is not set, the task will not execute. The property goes
  250        * through property substitution once before testing, so if
  251        * property <code>foo</code> has value <code>bar</code>, setting
  252        * the "if" condition to <code>${foo}_x</code> will mean that the
  253        * task will only execute if property <code>bar_x</code> is set.
  254        *
  255        * @param property The property condition to test on execution.
  256        *                 May be <code>null</code>, in which case
  257        *                 no "if" test is performed.
  258        */
  259       public void setIf(String property) {
  260           ifCondition = (property == null) ? "" : property;
  261       }
  262   
  263       /**
  264        * Returns the "if" property condition of this target.
  265        *
  266        * @return the "if" property condition or <code>null</code> if no
  267        *         "if" condition had been defined.
  268        * @since 1.6.2
  269        */
  270       public String getIf() {
  271           return ("".equals(ifCondition) ? null : ifCondition);
  272       }
  273   
  274       /**
  275        * Sets the "unless" condition to test on execution. This is the
  276        * name of a property to test for existence - if the property
  277        * is set, the task will not execute. The property goes
  278        * through property substitution once before testing, so if
  279        * property <code>foo</code> has value <code>bar</code>, setting
  280        * the "unless" condition to <code>${foo}_x</code> will mean that the
  281        * task will only execute if property <code>bar_x</code> isn't set.
  282        *
  283        * @param property The property condition to test on execution.
  284        *                 May be <code>null</code>, in which case
  285        *                 no "unless" test is performed.
  286        */
  287       public void setUnless(String property) {
  288           unlessCondition = (property == null) ? "" : property;
  289       }
  290   
  291       /**
  292        * Returns the "unless" property condition of this target.
  293        *
  294        * @return the "unless" property condition or <code>null</code>
  295        *         if no "unless" condition had been defined.
  296        * @since 1.6.2
  297        */
  298       public String getUnless() {
  299           return ("".equals(unlessCondition) ? null : unlessCondition);
  300       }
  301   
  302       /**
  303        * Sets the description of this target.
  304        *
  305        * @param description The description for this target.
  306        *                    May be <code>null</code>, indicating that no
  307        *                    description is available.
  308        */
  309       public void setDescription(String description) {
  310           this.description = description;
  311       }
  312   
  313       /**
  314        * Returns the description of this target.
  315        *
  316        * @return the description of this target, or <code>null</code> if no
  317        *         description is available.
  318        */
  319       public String getDescription() {
  320           return description;
  321       }
  322   
  323       /**
  324        * Returns the name of this target.
  325        *
  326        * @return the name of this target, or <code>null</code> if the
  327        *         name has not been set yet.
  328        */
  329       public String toString() {
  330           return name;
  331       }
  332   
  333       /**
  334        * Executes the target if the "if" and "unless" conditions are
  335        * satisfied. Dependency checking should be done before calling this
  336        * method, as it does no checking of its own. If either the "if"
  337        * or "unless" test prevents this target from being executed, a verbose
  338        * message is logged giving the reason. It is recommended that clients
  339        * of this class call performTasks rather than this method so that
  340        * appropriate build events are fired.
  341        *
  342        * @exception BuildException if any of the tasks fail or if a data type
  343        *                           configuration fails.
  344        *
  345        * @see #performTasks()
  346        * @see #setIf(String)
  347        * @see #setUnless(String)
  348        */
  349       public void execute() throws BuildException {
  350           if (testIfCondition() && testUnlessCondition()) {
  351               for (int taskPosition = 0;
  352                    taskPosition < children.size();
  353                    ++taskPosition) {
  354                   Object o = children.get(taskPosition);
  355                   if (o instanceof Task) {
  356                       Task task = (Task) o;
  357                       task.perform();
  358                   } else {
  359                       RuntimeConfigurable r = (RuntimeConfigurable) o;
  360                       r.maybeConfigure(project);
  361                   }
  362               }
  363           } else if (!testIfCondition()) {
  364               project.log(this, "Skipped because property '"
  365                           + project.replaceProperties(ifCondition)
  366                           + "' not set.", Project.MSG_VERBOSE);
  367           } else {
  368               project.log(this, "Skipped because property '"
  369                           + project.replaceProperties(unlessCondition)
  370                           + "' set.", Project.MSG_VERBOSE);
  371           }
  372       }
  373   
  374       /**
  375        * Performs the tasks within this target (if the conditions are met),
  376        * firing target started/target finished messages around a call to
  377        * execute.
  378        *
  379        * @see #execute()
  380        */
  381       public final void performTasks() {
  382           RuntimeException thrown = null;
  383           project.fireTargetStarted(this);
  384           try {
  385               execute();
  386           } catch (RuntimeException exc) {
  387               thrown = exc;
  388               throw exc;
  389           } finally {
  390               project.fireTargetFinished(this, thrown);
  391           }
  392       }
  393   
  394       /**
  395        * Replaces all occurrences of the given task in the list
  396        * of children with the replacement data type wrapper.
  397        *
  398        * @param el The task to replace.
  399        *           Must not be <code>null</code>.
  400        * @param o  The data type wrapper to replace <code>el</code> with.
  401        */
  402       void replaceChild(Task el, RuntimeConfigurable o) {
  403           int index;
  404           while ((index = children.indexOf(el)) >= 0) {
  405               children.set(index, o);
  406           }
  407       }
  408   
  409       /**
  410        * Replaces all occurrences of the given task in the list
  411        * of children with the replacement task.
  412        *
  413        * @param el The task to replace.
  414        *           Must not be <code>null</code>.
  415        * @param o  The task to replace <code>el</code> with.
  416        */
  417       void replaceChild(Task el, Task o) {
  418           int index;
  419           while ((index = children.indexOf(el)) >= 0) {
  420               children.set(index, o);
  421           }
  422       }
  423   
  424       /**
  425        * Tests whether or not the "if" condition is satisfied.
  426        *
  427        * @return whether or not the "if" condition is satisfied. If no
  428        *         condition (or an empty condition) has been set,
  429        *         <code>true</code> is returned.
  430        *
  431        * @see #setIf(String)
  432        */
  433       private boolean testIfCondition() {
  434           if ("".equals(ifCondition)) {
  435               return true;
  436           }
  437   
  438           String test = project.replaceProperties(ifCondition);
  439           return project.getProperty(test) != null;
  440       }
  441   
  442       /**
  443        * Tests whether or not the "unless" condition is satisfied.
  444        *
  445        * @return whether or not the "unless" condition is satisfied. If no
  446        *         condition (or an empty condition) has been set,
  447        *         <code>true</code> is returned.
  448        *
  449        * @see #setUnless(String)
  450        */
  451       private boolean testUnlessCondition() {
  452           if ("".equals(unlessCondition)) {
  453               return true;
  454           }
  455           String test = project.replaceProperties(unlessCondition);
  456           return project.getProperty(test) == null;
  457       }
  458   }

Save This Page
Home » apache-ant-1.7.1-src » org.apache.tools » ant » [javadoc | source]