Migrating the debugger to use Build Listeners instead of patching the ant. Also, added functionality to break on attempts to modify property values. Also added a facility to add break points at runtime.
git-svn-id: https://svn.apache.org/repos/asf/incubator/easyant/tasks/trunk@1135952 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/Auditor.java b/command-line-debugger/src/main/org/apache/ant/debugger/Auditor.java
new file mode 100644
index 0000000..3c9487b
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/Auditor.java
@@ -0,0 +1,49 @@
+package org.apache.ant.debugger;
+
+import java.util.List;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Audits all calls to change property values
+ *
+ * Right now only properties are audited: We can try to figure a way to audit
+ * other data-types if it adds any value.
+ */
+public interface Auditor {
+
+ /**
+ * Marks a property to be tracked for attempted changes.
+ *
+ * @param property
+ */
+ public void addPropertyForAudits(String property, Project project);
+
+ /**
+ * Audits change to a property by name <code>property</code>.
+ *
+ * @param property
+ * @param value
+ * @param project
+ */
+ public void auditPropertyChange(String property, Object value,
+ Project project);
+
+ /**
+ * Returns all records for the key.
+ *
+ * @param key
+ * @return
+ */
+ public List getAuditsForProperty(String key);
+
+ /**
+ * Provide a hook for debuggers to attach to this auditor so that it may be
+ * able to pass back the control to the Debugger in case of a Property
+ * Breakpoint.
+ *
+ * @param debugger
+ */
+ public void setPrompt(DebugPrompt debugger);
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugCommandSet.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugCommandSet.java
new file mode 100644
index 0000000..e9f60b0
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugCommandSet.java
@@ -0,0 +1,100 @@
+package org.apache.ant.debugger;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Handles all debug support functionality.
+ */
+public class DebugCommandSet {
+
+ protected Project project;
+
+ protected Map commandSupport = new HashMap();
+
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ /**
+ * Initialize all debug commands here - preferrably read from a properties
+ * file.
+ */
+ public void init(Map commands) {
+ if (commands != null)
+ commandSupport.putAll(commands);
+ Properties props = new Properties();
+ try {
+ InputStream is = DebugCommandSet.class.getClassLoader()
+ .getResourceAsStream(
+ "org/apache/ant/debugger/debug-support.properties");
+ props.load(is);
+ Enumeration en = props.keys();
+ while (en.hasMoreElements()) {
+ String key = (String) en.nextElement();
+ String className = props.getProperty(key);
+ Class commandClass;
+ try {
+ commandClass = Class.forName(className);
+ Object command = commandClass.newInstance();
+ if (command instanceof DebugSupport)
+ commandSupport.put(key, command);
+ else
+ project
+ .log(
+ "Command Class: "
+ + className
+ + " does not implement DebugSupport. Ignoring.",
+ Project.MSG_WARN);
+ } catch (ClassNotFoundException e) {
+ project.log("Could not find class: " + className,
+ Project.MSG_WARN);
+ } catch (InstantiationException e) {
+ project.log("Could not instantiate class: " + className,
+ Project.MSG_WARN);
+ } catch (IllegalAccessException e) {
+ project.log("Illegal Access while instantiating class: "
+ + className, Project.MSG_WARN);
+ }
+ }
+ } catch (IOException ioe) {
+ // if the resource could not be located, then initialize with what
+ // is known
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ public void handleCommand(String command) {
+ if (command == null || command.trim().length() == 0) {
+ project.log("Invalid command. Use /? for more information.");
+ }
+ command = command.trim();
+ if (command.equals("/?")) {
+ printUsage();
+ return;
+ }
+
+ String[] tokens = command.split(" ");
+ DebugSupport selected = (DebugSupport) commandSupport.get(tokens[0]);
+ if (selected != null) {
+ selected.execute(project, tokens);
+ } else {
+ printUsage();
+ }
+ }
+
+ protected void printUsage() {
+ // log all help stuff here
+ project
+ .log("You may use one of the following commands: locate, inspect, return");
+ project
+ .log("Type the command followed by /? for more information. Eg. inspect /?");
+ }
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugPrompt.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugPrompt.java
new file mode 100644
index 0000000..046af54
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugPrompt.java
@@ -0,0 +1,46 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.input.DefaultInputHandler;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.apache.tools.ant.util.StringUtils;
+
+public class DebugPrompt {
+
+ protected Project project = null;
+
+ protected DebugCommandSet commandHandler;
+
+ public DebugPrompt(Project project, DebugCommandSet commandHandler) {
+ this.project = project;
+ this.commandHandler = commandHandler;
+ }
+
+ public void prompt(String message) {
+ InputRequest ir = new InputRequest("Debugger> ");
+ InputHandler ih = new DefaultInputHandler();
+ String command = null;
+ project.log(StringUtils.LINE_SEP
+ + "-------- Ant Command Line Debugger --------"
+ + StringUtils.LINE_SEP + StringUtils.LINE_SEP);
+
+ // print a friendly message to allow the user to understand why this
+ // breakpoint occurred
+ project.log(message);
+ project.log("");
+ // keep accepting inputs, until the user enters the return command
+ do {
+ ih.handleInput(ir);
+ command = ir.getInput();
+ commandHandler.handleCommand(command);
+ project.log(""); // log a new line
+ } while (!"return".equals(command));
+
+ // resume build execution on this
+ project.log(StringUtils.LINE_SEP
+ + "--------- Resuming Ant Execution ----------"
+ + StringUtils.LINE_SEP);
+ }
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugSupport.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugSupport.java
new file mode 100644
index 0000000..1e26146
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugSupport.java
@@ -0,0 +1,33 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * An interface for supporting debug commands.
+ */
+public interface DebugSupport {
+
+ /**
+ * Check if this command is supported.
+ *
+ * @param command
+ * @return
+ */
+ public boolean commandSupported(String command);
+
+ /**
+ * Main execution body of the class. Pass all command parameters.
+ *
+ * @param project
+ * @param params
+ */
+ public void execute(Project project, String[] params);
+
+ /**
+ * Prints usage of the command.
+ *
+ * @param project
+ */
+ public void printUsage(Project project);
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DebugUtils.java b/command-line-debugger/src/main/org/apache/ant/debugger/DebugUtils.java
new file mode 100644
index 0000000..db1e052
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DebugUtils.java
@@ -0,0 +1,34 @@
+package org.apache.ant.debugger;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.Target;
+import org.apache.tools.ant.Task;
+
+public class DebugUtils {
+
+ public static List searchTask(Class expectedTaskClass, Project project) {
+ List result = new ArrayList();
+ for (Iterator iterator = project.getTargets().values().iterator(); iterator
+ .hasNext();) {
+ Target t = (Target) iterator.next();
+ for (int i = 0; i < t.getTasks().length; i++) {
+ Task task = t.getTasks()[i];
+ Class taskClass = ComponentHelper.getComponentHelper(project)
+ .getComponentClass(task.getTaskType());
+ // will need to see in what cases it could return a null type
+ // perhaps failing when the task is using a custom antlib
+ // defined task
+ if (taskClass != null && taskClass.equals(expectedTaskClass)) {
+ result.add(task);
+ }
+ }
+ }
+ return result;
+ }
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/DefaultAuditor.java b/command-line-debugger/src/main/org/apache/ant/debugger/DefaultAuditor.java
new file mode 100644
index 0000000..0438a33
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/DefaultAuditor.java
@@ -0,0 +1,98 @@
+package org.apache.ant.debugger;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+
+/**
+ * Default implementation of {@link Auditor}. At the same time, this class also
+ * acts as a Debug command permitting the recorded audits to be available on
+ * user commands.
+ * <p />
+ * Optionally, this class allows a {@link DebugPrompt} instance to attach itself to
+ * this auditor, so that if change to a certain property is attempted, then the
+ * debugger may be chosen to be transferred the control to.
+ */
+public class DefaultAuditor implements Auditor, DebugSupport {
+
+ protected Map propertyaudits = new HashMap();
+
+ protected DebugPrompt prompt = null;
+
+ public void setPrompt(DebugPrompt prompt) {
+ this.prompt = prompt;
+ }
+
+ public void addPropertyForAudits(String property, Project project) {
+ // the list in the value will keep track of all attempted changes to
+ // this property
+ project.log("Adding Property: " + property + " to be audited.",
+ Project.MSG_DEBUG);
+ propertyaudits.put(property, new LinkedList());
+ }
+
+ public void auditPropertyChange(String property, Object value,
+ Project project) {
+ List audits = (List) propertyaudits.get(property);
+ if (audits != null) {
+ project.log("Adding Attempted Change record for Property: "
+ + property, Project.MSG_DEBUG);
+ // if any target executes while currentTarget = null, it indicates
+ // the property
+ // transition happened outside the scope of any target, directly
+ // inside the build file
+ PropertyHelper helper = PropertyHelper.getPropertyHelper(project);
+ StringBuffer sb = new StringBuffer();
+ sb.append("Property [").append(property).append(
+ "] change attempted from [");
+ sb.append(helper.getProperty(property)).append("] to [");
+ sb.append(value).append("]");
+ String message = sb.toString();
+ audits.add(message);
+
+ // if there is a debugger attached to this instance, pass the
+ // control to the debugger
+ if (prompt != null)
+ prompt.prompt(message);
+ }
+
+ }
+
+ public List getAuditsForProperty(String key) {
+ return (List) propertyaudits.get(key);
+ }
+
+ public boolean commandSupported(String command) {
+ return "trace".equals(command);
+ }
+
+ public void execute(Project project, String[] params) {
+ if (params.length != 2) {
+ printUsage(project);
+ }
+
+ String property = params[1];
+
+ List changes = getAuditsForProperty(property);
+ if (changes != null) {
+ project.log("Found " + changes.size()
+ + " Attempted Changes to Property: " + property);
+ Iterator it = changes.iterator();
+ while (it.hasNext()) {
+ project.log(" - " + (String) it.next());
+ }
+ } else {
+ project.log(" - No records found for Property: " + property);
+ }
+ }
+
+ public void printUsage(Project project) {
+ project.log("Some HelpFul Message here");
+ }
+
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/Inspector.java b/command-line-debugger/src/main/org/apache/ant/debugger/Inspector.java
new file mode 100644
index 0000000..319ec1e
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/Inspector.java
@@ -0,0 +1,60 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.PropertyHelper;
+import org.apache.tools.ant.taskdefs.PathConvert;
+import org.apache.tools.ant.types.ResourceCollection;
+import org.apache.tools.ant.util.StringUtils;
+
+/**
+ * Inspects the current value of a property, path or some reference.
+ */
+public class Inspector implements DebugSupport {
+
+ public boolean commandSupported(String command) {
+ return "inspect".equalsIgnoreCase(command);
+ }
+
+ public void execute(Project project, String[] params) {
+ if (params.length < 3 || "/?".equals(params[1])) {
+ printUsage(project);
+ }
+
+ if ("property".equalsIgnoreCase(params[1])) {
+ // show all matches for a property
+ Object value = PropertyHelper.getProperty(project, params[2]);
+ if (value != null) {
+ project.log("Detected a property by name [" + params[1]
+ + "]. Current value: " + value);
+ } else {
+ project.log("Found no such property.");
+ }
+ } else if ("path".equalsIgnoreCase(params[1])) {
+ // look optional component
+ // the remaining part of the string could be:
+ // id=<someid> or refid=<somerefid>
+ Object ref = project.getReference(params[2]);
+ if (ref instanceof ResourceCollection) {
+ if (ref != null) {
+ PathConvert path = (PathConvert) project
+ .createTask("pathconvert");
+ path.setProject(project);
+ path.setPathSep(StringUtils.LINE_SEP + " - ");
+ path.add((ResourceCollection) ref);
+ path.execute();
+ } else {
+ project.log("No path-reference found for " + params[2]);
+ }
+ } else {
+ project.log("No path found for reference id: " + params[2]);
+ }
+ }
+
+ }
+
+ public void printUsage(Project project) {
+ project.log("Incorrect Parameters");
+ project.log("Usage: inspect property some.property");
+ project.log(" inspect path path.id");
+ }
+}
\ No newline at end of file
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/NoOp.java b/command-line-debugger/src/main/org/apache/ant/debugger/NoOp.java
new file mode 100644
index 0000000..9bfeced
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/NoOp.java
@@ -0,0 +1,21 @@
+package org.apache.ant.debugger;
+
+import org.apache.tools.ant.Project;
+
+/**
+ * Used to implement commands that should not be handled by {@link DebugSupport}
+ * at all. Example, the 'return' command
+ */
+public final class NoOp implements DebugSupport {
+
+ public boolean commandSupported(String command) {
+ return "return".equalsIgnoreCase(command);
+ }
+
+ public void execute(Project project, String[] params) {
+ // do nothing
+ }
+
+ public void printUsage(Project project) {
+ };
+}
diff --git a/command-line-debugger/src/main/org/apache/ant/debugger/debug-support.properties b/command-line-debugger/src/main/org/apache/ant/debugger/debug-support.properties
new file mode 100644
index 0000000..e388e71
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/ant/debugger/debug-support.properties
@@ -0,0 +1,3 @@
+inspect=org.apache.ant.debugger.Inspector
+locate=org.apache.tools.ant.Locator
+return=org.apache.ant.debugger.NoOp
\ No newline at end of file
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/DebugTask.java b/command-line-debugger/src/main/org/apache/tools/ant/DebugTask.java
deleted file mode 100644
index 6049b1b..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/DebugTask.java
+++ /dev/null
@@ -1,329 +0,0 @@
-package org.apache.tools.ant;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.ComponentHelper;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.Target;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.input.DefaultInputHandler;
-import org.apache.tools.ant.input.InputHandler;
-import org.apache.tools.ant.input.InputRequest;
-import org.apache.tools.ant.taskdefs.PathConvert;
-import org.apache.tools.ant.taskdefs.Property;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Reference;
-import org.apache.tools.ant.types.ResourceCollection;
-import org.apache.tools.ant.util.StringUtils;
-
-/**
- * A stand alone debug task that plugs into the build through projecthelper
- * class by injecting a dependency at the end of a target. This is a POC and
- * does not yet work for Extension-Points.
- */
-public class DebugTask extends Task {
- /**
- * Debugger prompt
- */
- public static final String PROMPT = "DEBUGGER> ";
-
- /**
- * Standard target name for the internal debugger
- */
- public static final String DEBUG_TARGET_NAME = "-internal-debugger";
-
- /*
- * A static final debug target that is injected as a dependency. We may need
- * to have more than one such target if we are to allow multiple
- * break-points in the build.
- */
- private static final Target debugTarget = new Target();
-
- /*
- * Set of all commands that can be interpreted at runtime.
- */
- private static Set supportedCommands = new HashSet();
-
- static {
- // add any more commands to be supported here
- // if need be, this can be considered to be
- // moved to a separate properties file
- supportedCommands.add("locate");
- supportedCommands.add("inspect");
- supportedCommands.add("return");
- }
-
- public void execute() throws BuildException {
- // expect input here
- InputRequest ir = new InputRequest(PROMPT);
- InputHandler ih = new DefaultInputHandler();
- String command = null;
- getProject().log(
- StringUtils.LINE_SEP
- + "-------- Ant Command Line Debugger --------"
- + StringUtils.LINE_SEP + StringUtils.LINE_SEP);
-
- // keep accepting inputs, until the user enters the return command
- do {
- ih.handleInput(ir);
- command = ir.getInput();
- handleCommand(command);
- getProject().log(""); // log a new line
- } while (!"return".equals(command));
-
- // resume build execution on this
- getProject().log(
- StringUtils.LINE_SEP
- + "--------- Resuming Ant Execution ----------"
- + StringUtils.LINE_SEP);
- }
-
- /**
- * Static method to create a runtime-debug target. For purposes of Command
- * Line Debugger (CLD), the target returned by this method, and identified
- * by DEBUG_TARGET_NAME must be added at the end of the dependency list of
- * the target where the break point exists.
- *
- * @param project
- * @return
- */
- public static Target createDebugTarget(Project project) {
- // see what is the best value for the Location to assume?
- // Location loc = new Location(??);
-
- debugTarget.setProject(project);
- debugTarget.setName(DEBUG_TARGET_NAME);
- project.addTarget(debugTarget);
- // create an instance of debug task and attach it to this project
- Task debugtask = project.createTask("debug");
- debugtask.setProject(project);
- debugtask.setTaskName("Debugger");
- debugTarget.addTask(debugtask);
- return debugTarget;
- }
-
- /*
- * Interprets user input and decides if the command is supported or should
- * be rejected.
- */
- protected void handleCommand(String command) {
- if (command == null || command.trim().length() == 0) {
- getProject().log("Invalid command. Use /? for more information.");
- }
- command = command.trim();
- if (command.equals("/?")) {
- printUsage();
- return;
- }
-
- String[] tokens = command.split(" ");
- if (!supportedCommands.contains(tokens[0])) {
- printUsage();
- return;
- }
-
- DebugSupport[] debuggers = new DebugSupport[] { new NoOp(),
- new Inspector(), new Locator() };
- DebugSupport selected = null;
- for (int j = 0; j < debuggers.length; j++) {
- if (debuggers[j].commandSupported(tokens[0]))
- selected = debuggers[j];
- }
- selected.execute(getProject(), tokens);
- }
-
- protected void printUsage() {
- // log all help stuff here
- getProject()
- .log(
- "You may use one of the following commands: locate, inspect, return");
- getProject()
- .log(
- "Type the command followed by /? for more information. Eg. inspect /?");
- }
-
- protected static List searchTask(Class expectedTaskClass, Project project) {
- List result = new ArrayList();
- for (Iterator iterator = project.getTargets().values().iterator(); iterator
- .hasNext();) {
- Target t = (Target) iterator.next();
- for (int i = 0; i < t.getTasks().length; i++) {
- Task task = t.getTasks()[i];
- Class taskClass = ComponentHelper.getComponentHelper(project)
- .getComponentClass(task.getTaskType());
- // will need to see in what cases it could return a null type
- // perhaps failing when the task is using a custom antlib
- // defined task
- if (taskClass != null && taskClass.equals(expectedTaskClass)) {
- result.add(task);
- }
- }
- }
- return result;
- }
-
- /**
- * An interface for supporting debug commands.
- */
- public static interface DebugSupport {
-
- /**
- * Check if this command is supported.
- *
- * @param command
- * @return
- */
- public boolean commandSupported(String command);
-
- /**
- * Main execution body of the class. Pass all command parameters.
- *
- * @param project
- * @param params
- */
- public void execute(Project project, String[] params);
-
- /**
- * Prints usage of the command.
- *
- * @param project
- */
- public void printUsage(Project project);
-
- }
-
- /**
- * Used to implement commands that should not be handled by
- * {@link DebugSupport} at all. Example, the 'return' command
- */
- public static final class NoOp implements DebugSupport {
-
- public boolean commandSupported(String command) {
- return "return".equalsIgnoreCase(command);
- }
-
- public void execute(Project project, String[] params) {
- // do nothing
- }
-
- public void printUsage(Project project) {
- };
- }
-
- /**
- * Locates properties / paths in static build sources
- */
- public static final class Locator implements DebugSupport {
-
- public boolean commandSupported(String command) {
- return "locate".equalsIgnoreCase(command);
- }
-
- public void execute(Project project, String[] params) {
- // the command syntax is 'locate property some.property'
- // or 'locate path some.path
- if (params.length != 3 || "/?".equals(params[1])) {
- printUsage(project);
- return;
- }
-
- List matches = null;
- String key = null;
- if ("property".equalsIgnoreCase(params[1])) {
- // locate and publish the property
- matches = DebugTask.searchTask(Property.class, project);
- key = "name";
- } else if ("path".equalsIgnoreCase(params[1])) {
- // locate and publish the path
- matches = DebugTask.searchTask(Path.class, project);
- key = "id";
- } else {
- // see if any other component may be supported
- project.log("Unexpected component: " + params[1]);
- project.log("Supported components are property, path.");
- return;
- }
-
- // probably accept some kind of a query from end user and select the
- // target object based on the query
- for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
- Task task = (Task) iterator.next();
- // display attributes
- Map attributeMap = task.getWrapper().getAttributeMap();
- if (!params[2].equals(attributeMap.get(key))) {
- continue;
- }
- String value = (String) attributeMap.get("value");
- project.log("Detected a property by name [" + params[2]
- + "]. Build file value: " + value);
- // and their respected location
- project.log("Located at: " + task.getLocation().toString());
- }
- }
-
- public void printUsage(Project project) {
- project.log("Incorrect Parameters");
- project.log("Usage: locate property/path propertyname/pathname");
- }
- }
-
- /**
- * Inspects the current value of a property, path or some reference.
- */
- public static final class Inspector implements DebugSupport {
-
- public boolean commandSupported(String command) {
- return "inspect".equalsIgnoreCase(command);
- }
-
- public void execute(Project project, String[] params) {
- if (params.length < 3 || "/?".equals(params[1])) {
- printUsage(project);
- }
-
- if ("property".equalsIgnoreCase(params[1])) {
- // show all matches for a property
- Object value = PropertyHelper.getProperty(project, params[2]);
- if (value != null) {
- project.log("Detected a property by name [" + params[1]
- + "]. Current value: " + value);
- } else {
- project.log("Found no such property.");
- }
- } else if ("path".equalsIgnoreCase(params[1])) {
- // look optional component
- // the remaining part of the string could be:
- // id=<someid> or refid=<somerefid>
- Object ref = project.getReference(params[2]);
- if (ref instanceof ResourceCollection) {
- if (ref != null) {
- PathConvert path = (PathConvert) project
- .createTask("pathconvert");
- path.setProject(project);
- path.setPathSep(StringUtils.LINE_SEP + " - ");
- path.add((ResourceCollection) ref);
- path.execute();
- } else {
- project.log("No path-reference found for " + params[2]);
- }
- } else {
- project.log("No path found for reference id: " + params[2]);
- }
- }
-
- }
-
- public void printUsage(Project project) {
- project.log("Incorrect Parameters");
- project.log("Usage: inspect property some.property");
- project.log(" inspect path path.id");
- }
- }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/Locator.java b/command-line-debugger/src/main/org/apache/tools/ant/Locator.java
new file mode 100644
index 0000000..98202e7
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/tools/ant/Locator.java
@@ -0,0 +1,75 @@
+package org.apache.tools.ant;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.ant.debugger.DebugSupport;
+import org.apache.ant.debugger.DebugUtils;
+
+import org.apache.tools.ant.taskdefs.Property;
+import org.apache.tools.ant.types.Path;
+
+/**
+ * Locates properties / paths in static build sources
+ */
+public class Locator implements DebugSupport {
+
+ public boolean commandSupported(String command) {
+ return "locate".equalsIgnoreCase(command);
+ }
+
+ public void execute(Project project, String[] params) {
+ // the command syntax is 'locate property some.property'
+ // or 'locate path some.path
+ if (params.length != 3 || "/?".equals(params[1])) {
+ printUsage(project);
+ return;
+ }
+
+ List matches = null;
+ String key = null;
+ if ("property".equalsIgnoreCase(params[1])) {
+ // locate and publish the property
+ matches = DebugUtils.searchTask(Property.class, project);
+ key = "name";
+ } else if ("path".equalsIgnoreCase(params[1])) {
+ // locate and publish the path
+ matches = DebugUtils.searchTask(Path.class, project);
+ key = "id";
+ } else {
+ // see if any other component may be supported
+ project.log("Unexpected component: " + params[1]);
+ project.log("Supported components are property, path.");
+ return;
+ }
+
+ boolean found = false;
+
+ // probably accept some kind of a query from end user and select the
+ // target object based on the query
+ for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
+ Task task = (Task) iterator.next();
+ // display attributes
+ Map attributeMap = task.getWrapper().getAttributeMap();
+ if (!params[2].equals(attributeMap.get(key))) {
+ continue;
+ }
+ found = true;
+ String value = (String) attributeMap.get("value");
+ project.log("Detected a property by name [" + params[2]
+ + "]. Build file value: " + value);
+ // and their respected location
+ project.log("Located at: " + task.getLocation().toString());
+ }
+
+ if (!found) {
+ project.log("No property by name [" + params[2] + "] found.");
+ }
+ }
+
+ public void printUsage(Project project) {
+ project.log("Incorrect Parameters");
+ project.log("Usage: locate property/path propertyname/pathname");
+ }
+}
\ No newline at end of file
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/Main.java b/command-line-debugger/src/main/org/apache/tools/ant/Main.java
deleted file mode 100644
index d85ddf9..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/Main.java
+++ /dev/null
@@ -1,1235 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- *
- */
-
-package org.apache.tools.ant;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Vector;
-
-import org.apache.tools.ant.input.DefaultInputHandler;
-import org.apache.tools.ant.input.InputHandler;
-import org.apache.tools.ant.launch.AntMain;
-import org.apache.tools.ant.property.ResolvePropertyMap;
-import org.apache.tools.ant.util.ClasspathUtils;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.ProxySetup;
-
-
-/**
- * Command line entry point into Ant. This class is entered via the
- * canonical `public static void main` entry point and reads the
- * command line arguments. It then assembles and executes an Ant
- * project.
- * <p>
- * If you integrating Ant into some other tool, this is not the class
- * to use as an entry point. Please see the source code of this
- * class to see how it manipulates the Ant project classes.
- *
- */
-public class Main implements AntMain {
-
- /**
- * A Set of args are are handled by the launcher and should
- * not be seen by Main.
- */
- private static final Set LAUNCH_COMMANDS = new HashSet();
- static {
- LAUNCH_COMMANDS.add("-lib");
- LAUNCH_COMMANDS.add("-cp");
- LAUNCH_COMMANDS.add("-noclasspath");
- LAUNCH_COMMANDS.add("--noclasspath");
- LAUNCH_COMMANDS.add("-nouserlib");
- LAUNCH_COMMANDS.add("-main");
- }
-
- /** The default build file name. {@value} */
- public static final String DEFAULT_BUILD_FILENAME = "build.xml";
-
- /** Our current message output status. Follows Project.MSG_XXX. */
- private int msgOutputLevel = Project.MSG_INFO;
-
- /** File that we are using for configuration. */
- private File buildFile; /* null */
-
- /** Stream to use for logging. */
- private static PrintStream out = System.out;
-
- /** Stream that we are using for logging error messages. */
- private static PrintStream err = System.err;
-
- /** The build targets. */
- private Vector targets = new Vector();
-
- /** Set of properties that can be used by tasks. */
- private Properties definedProps = new Properties();
-
- /** Names of classes to add as listeners to project. */
- private Vector listeners = new Vector(1);
-
- /** File names of property files to load on startup. */
- private Vector propertyFiles = new Vector(1);
-
- /** Indicates whether this build is to support interactive input */
- private boolean allowInput = true;
-
- /** keep going mode */
- private boolean keepGoingMode = false;
-
- /**
- * The Ant logger class. There may be only one logger. It will have
- * the right to use the 'out' PrintStream. The class must implements the
- * BuildLogger interface.
- */
- private String loggerClassname = null;
-
- /**
- * The Ant InputHandler class. There may be only one input
- * handler.
- */
- private String inputHandlerClassname = null;
-
- /**
- * Whether or not output to the log is to be unadorned.
- */
- private boolean emacsMode = false;
-
- /**
- * Whether or not this instance has successfully been
- * constructed and is ready to run.
- */
- private boolean readyToRun = false;
-
- /**
- * Whether or not we should only parse and display the project help
- * information.
- */
- private boolean projectHelp = false;
-
- /**
- * Whether or not a logfile is being used. This is used to
- * check if the output streams must be closed.
- */
- private static boolean isLogFileUsed = false;
-
- /**
- * optional thread priority
- */
- private Integer threadPriority = null;
-
- /**
- * proxy flag: default is false
- */
- private boolean proxy = false;
-
- /**
- * Target at which to break execution sequence
- */
- private String breakAt = null;
-
- /**
- * Prints the message of the Throwable if it (the message) is not
- * <code>null</code>.
- *
- * @param t Throwable to print the message of.
- * Must not be <code>null</code>.
- */
- private static void printMessage(Throwable t) {
- String message = t.getMessage();
- if (message != null) {
- System.err.println(message);
- }
- }
-
- /**
- * Creates a new instance of this class using the
- * arguments specified, gives it any extra user properties which have been
- * specified, and then runs the build using the classloader provided.
- *
- * @param args Command line arguments. Must not be <code>null</code>.
- * @param additionalUserProperties Any extra properties to use in this
- * build. May be <code>null</code>, which is the equivalent to
- * passing in an empty set of properties.
- * @param coreLoader Classloader used for core classes. May be
- * <code>null</code> in which case the system classloader is used.
- */
- public static void start(String[] args, Properties additionalUserProperties,
- ClassLoader coreLoader) {
- Main m = new Main();
- m.startAnt(args, additionalUserProperties, coreLoader);
- }
-
- /**
- * Start Ant
- * @param args command line args
- * @param additionalUserProperties properties to set beyond those that
- * may be specified on the args list
- * @param coreLoader - not used
- *
- * @since Ant 1.6
- */
- public void startAnt(String[] args, Properties additionalUserProperties,
- ClassLoader coreLoader) {
-
- try {
- processArgs(args);
- } catch (Throwable exc) {
- handleLogfile();
- printMessage(exc);
- exit(1);
- return;
- }
-
- if (additionalUserProperties != null) {
- for (Enumeration e = additionalUserProperties.keys();
- e.hasMoreElements();) {
- String key = (String) e.nextElement();
- String property = additionalUserProperties.getProperty(key);
- definedProps.put(key, property);
- }
- }
-
- // expect the worst
- int exitCode = 1;
- try {
- try {
- runBuild(coreLoader);
- exitCode = 0;
- } catch (ExitStatusException ese) {
- exitCode = ese.getStatus();
- if (exitCode != 0) {
- throw ese;
- }
- }
- } catch (BuildException be) {
- if (err != System.err) {
- printMessage(be);
- }
- } catch (Throwable exc) {
- exc.printStackTrace();
- printMessage(exc);
- } finally {
- handleLogfile();
- }
- exit(exitCode);
- }
-
- /**
- * This operation is expected to call {@link System#exit(int)}, which
- * is what the base version does.
- * However, it is possible to do something else.
- * @param exitCode code to exit with
- */
- protected void exit(int exitCode) {
- System.exit(exitCode);
- }
-
- /**
- * Close logfiles, if we have been writing to them.
- *
- * @since Ant 1.6
- */
- private static void handleLogfile() {
- if (isLogFileUsed) {
- FileUtils.close(out);
- FileUtils.close(err);
- }
- }
-
- /**
- * Command line entry point. This method kicks off the building
- * of a project object and executes a build using either a given
- * target or the default target.
- *
- * @param args Command line arguments. Must not be <code>null</code>.
- */
- public static void main(String[] args) {
- start(args, null, null);
- }
-
- /**
- * Constructor used when creating Main for later arg processing
- * and startup
- */
- public Main() {
- }
-
- /**
- * Sole constructor, which parses and deals with command line
- * arguments.
- *
- * @param args Command line arguments. Must not be <code>null</code>.
- *
- * @exception BuildException if the specified build file doesn't exist
- * or is a directory.
- *
- * @deprecated since 1.6.x
- */
- protected Main(String[] args) throws BuildException {
- processArgs(args);
- }
-
- /**
- * Process command line arguments.
- * When ant is started from Launcher, launcher-only arguments do not get
- * passed through to this routine.
- *
- * @param args the command line arguments.
- *
- * @since Ant 1.6
- */
- private void processArgs(String[] args) {
- String searchForThis = null;
- boolean searchForFile = false;
- PrintStream logTo = null;
-
- // cycle through given args
-
- boolean justPrintUsage = false;
- boolean justPrintVersion = false;
- boolean justPrintDiagnostics = false;
-
- for (int i = 0; i < args.length; i++) {
- String arg = args[i];
-
- if (arg.equals("-help") || arg.equals("-h")) {
- justPrintUsage = true;
- } else if (arg.equals("-version")) {
- justPrintVersion = true;
- } else if (arg.equals("-diagnostics")) {
- justPrintDiagnostics = true;
- } else if (arg.equals("-quiet") || arg.equals("-q")) {
- msgOutputLevel = Project.MSG_WARN;
- } else if (arg.equals("-verbose") || arg.equals("-v")) {
- msgOutputLevel = Project.MSG_VERBOSE;
- } else if (arg.equals("-debug") || arg.equals("-d")) {
- msgOutputLevel = Project.MSG_DEBUG;
- } else if (arg.equals("-noinput")) {
- allowInput = false;
- } else if (arg.equals("-logfile") || arg.equals("-l")) {
- try {
- File logFile = new File(args[i + 1]);
- i++;
- logTo = new PrintStream(new FileOutputStream(logFile));
- isLogFileUsed = true;
- } catch (IOException ioe) {
- String msg = "Cannot write on the specified log file. "
- + "Make sure the path exists and you have write "
- + "permissions.";
- throw new BuildException(msg);
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- String msg = "You must specify a log file when "
- + "using the -log argument";
- throw new BuildException(msg);
- }
- } else if (arg.equals("-buildfile") || arg.equals("-file")
- || arg.equals("-f")) {
- i = handleArgBuildFile(args, i);
- } else if (arg.equals("-listener")) {
- i = handleArgListener(args, i);
- } else if (arg.startsWith("-D")) {
- i = handleArgDefine(args, i);
- } else if (arg.equals("-logger")) {
- i = handleArgLogger(args, i);
- } else if (arg.equals("-inputhandler")) {
- i = handleArgInputHandler(args, i);
- } else if (arg.equals("-emacs") || arg.equals("-e")) {
- emacsMode = true;
- } else if (arg.equals("-projecthelp") || arg.equals("-p")) {
- // set the flag to display the targets and quit
- projectHelp = true;
- } else if (arg.equals("-find") || arg.equals("-s")) {
- searchForFile = true;
- // eat up next arg if present, default to build.xml
- if (i < args.length - 1) {
- searchForThis = args[++i];
- }
- } else if (arg.startsWith("-propertyfile")) {
- i = handleArgPropertyFile(args, i);
- } else if (arg.equals("-k") || arg.equals("-keep-going")) {
- keepGoingMode = true;
- } else if (arg.equals("-nice")) {
- i = handleArgNice(args, i);
- } else if (LAUNCH_COMMANDS.contains(arg)) {
- //catch script/ant mismatch with a meaningful message
- //we could ignore it, but there are likely to be other
- //version problems, so we stamp down on the configuration now
- String msg = "Ant's Main method is being handed "
- + "an option " + arg + " that is only for the launcher class."
- + "\nThis can be caused by a version mismatch between "
- + "the ant script/.bat file and Ant itself.";
- throw new BuildException(msg);
- } else if (arg.equals("-autoproxy")) {
- proxy = true;
- } else if (arg.equals("-breakAt")) {
- breakAt = args[++i];
- } else if (arg.startsWith("-")) {
- // we don't have any more args to recognize!
- String msg = "Unknown argument: " + arg;
- System.err.println(msg);
- printUsage();
- throw new BuildException("");
- } else {
- // if it's no other arg, it may be the target
- targets.addElement(arg);
- }
- }
-
- if (msgOutputLevel >= Project.MSG_VERBOSE || justPrintVersion) {
- printVersion(msgOutputLevel);
- }
-
- if (justPrintUsage || justPrintVersion || justPrintDiagnostics) {
- if (justPrintUsage) {
- printUsage();
- }
- if (justPrintDiagnostics) {
- Diagnostics.doReport(System.out, msgOutputLevel);
- }
- return;
- }
-
- // if buildFile was not specified on the command line,
- if (buildFile == null) {
- // but -find then search for it
- if (searchForFile) {
- if (searchForThis != null) {
- buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
- if (buildFile == null) {
- throw new BuildException("Could not locate a build file!");
- }
- } else {
- // no search file specified: so search an existing default file
- Iterator it = ProjectHelperRepository.getInstance().getHelpers();
- do {
- ProjectHelper helper = (ProjectHelper) it.next();
- searchForThis = helper.getDefaultBuildFile();
- if (msgOutputLevel >= Project.MSG_VERBOSE) {
- System.out.println("Searching the default build file: " + searchForThis);
- }
- buildFile = findBuildFile(System.getProperty("user.dir"), searchForThis);
- } while (buildFile == null && it.hasNext());
- if (buildFile == null) {
- throw new BuildException("Could not locate a build file!");
- }
- }
- } else {
- // no build file specified: so search an existing default file
- Iterator it = ProjectHelperRepository.getInstance().getHelpers();
- do {
- ProjectHelper helper = (ProjectHelper) it.next();
- buildFile = new File(helper.getDefaultBuildFile());
- if (msgOutputLevel >= Project.MSG_VERBOSE) {
- System.out.println("Trying the default build file: " + buildFile);
- }
- } while (!buildFile.exists() && it.hasNext());
- }
- }
-
- // make sure buildfile exists
- if (!buildFile.exists()) {
- System.out.println("Buildfile: " + buildFile + " does not exist!");
- throw new BuildException("Build failed");
- }
-
- // make sure it's not a directory (this falls into the ultra
- // paranoid lets check everything category
-
- if (buildFile.isDirectory()) {
- System.out.println("What? Buildfile: " + buildFile + " is a dir!");
- throw new BuildException("Build failed");
- }
-
- // Normalize buildFile for re-import detection
- buildFile =
- FileUtils.getFileUtils().normalize(buildFile.getAbsolutePath());
-
- // Load the property files specified by -propertyfile
- loadPropertyFiles();
-
- if (msgOutputLevel >= Project.MSG_INFO) {
- System.out.println("Buildfile: " + buildFile);
- }
-
- if (logTo != null) {
- out = logTo;
- err = logTo;
- System.setOut(out);
- System.setErr(err);
- }
- readyToRun = true;
- }
-
- // --------------------------------------------------------
- // Methods for handling the command line arguments
- // --------------------------------------------------------
-
- /** Handle the -buildfile, -file, -f argument */
- private int handleArgBuildFile(String[] args, int pos) {
- try {
- buildFile = new File(
- args[++pos].replace('/', File.separatorChar));
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- throw new BuildException(
- "You must specify a buildfile when using the -buildfile argument");
- }
- return pos;
- }
-
- /** Handle -listener argument */
- private int handleArgListener(String[] args, int pos) {
- try {
- listeners.addElement(args[pos + 1]);
- pos++;
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- String msg = "You must specify a classname when "
- + "using the -listener argument";
- throw new BuildException(msg);
- }
- return pos;
- }
-
- /** Handler -D argument */
- private int handleArgDefine(String[] args, int argPos) {
- /* Interestingly enough, we get to here when a user
- * uses -Dname=value. However, in some cases, the OS
- * goes ahead and parses this out to args
- * {"-Dname", "value"}
- * so instead of parsing on "=", we just make the "-D"
- * characters go away and skip one argument forward.
- *
- * I don't know how to predict when the JDK is going
- * to help or not, so we simply look for the equals sign.
- */
- String arg = args[argPos];
- String name = arg.substring(2, arg.length());
- String value = null;
- int posEq = name.indexOf("=");
- if (posEq > 0) {
- value = name.substring(posEq + 1);
- name = name.substring(0, posEq);
- } else if (argPos < args.length - 1) {
- value = args[++argPos];
- } else {
- throw new BuildException("Missing value for property "
- + name);
- }
- definedProps.put(name, value);
- return argPos;
- }
-
- /** Handle the -logger argument. */
- private int handleArgLogger(String[] args, int pos) {
- if (loggerClassname != null) {
- throw new BuildException(
- "Only one logger class may be specified.");
- }
- try {
- loggerClassname = args[++pos];
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- throw new BuildException(
- "You must specify a classname when using the -logger argument");
- }
- return pos;
- }
-
- /** Handle the -inputhandler argument. */
- private int handleArgInputHandler(String[] args, int pos) {
- if (inputHandlerClassname != null) {
- throw new BuildException("Only one input handler class may "
- + "be specified.");
- }
- try {
- inputHandlerClassname = args[++pos];
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- throw new BuildException("You must specify a classname when"
- + " using the -inputhandler"
- + " argument");
- }
- return pos;
- }
-
- /** Handle the -propertyfile argument. */
- private int handleArgPropertyFile(String[] args, int pos) {
- try {
- propertyFiles.addElement(args[++pos]);
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- String msg = "You must specify a property filename when "
- + "using the -propertyfile argument";
- throw new BuildException(msg);
- }
- return pos;
- }
-
- /** Handle the -nice argument. */
- private int handleArgNice(String[] args, int pos) {
- try {
- threadPriority = Integer.decode(args[++pos]);
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- throw new BuildException(
- "You must supply a niceness value (1-10)"
- + " after the -nice option");
- } catch (NumberFormatException e) {
- throw new BuildException("Unrecognized niceness value: "
- + args[pos]);
- }
-
- if (threadPriority.intValue() < Thread.MIN_PRIORITY
- || threadPriority.intValue() > Thread.MAX_PRIORITY) {
- throw new BuildException(
- "Niceness value is out of the range 1-10");
- }
- return pos;
- }
-
- // --------------------------------------------------------
- // other methods
- // --------------------------------------------------------
-
- /** Load the property files specified by -propertyfile */
- private void loadPropertyFiles() {
- for (int propertyFileIndex = 0;
- propertyFileIndex < propertyFiles.size();
- propertyFileIndex++) {
- String filename
- = (String) propertyFiles.elementAt(propertyFileIndex);
- Properties props = new Properties();
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(filename);
- props.load(fis);
- } catch (IOException e) {
- System.out.println("Could not load property file "
- + filename + ": " + e.getMessage());
- } finally {
- FileUtils.close(fis);
- }
-
- // ensure that -D properties take precedence
- Enumeration propertyNames = props.propertyNames();
- while (propertyNames.hasMoreElements()) {
- String name = (String) propertyNames.nextElement();
- if (definedProps.getProperty(name) == null) {
- definedProps.put(name, props.getProperty(name));
- }
- }
- }
- }
-
- /**
- * Helper to get the parent file for a given file.
- * <p>
- * Added to simulate File.getParentFile() from JDK 1.2.
- * @deprecated since 1.6.x
- *
- * @param file File to find parent of. Must not be <code>null</code>.
- * @return Parent file or null if none
- */
- private File getParentFile(File file) {
- File parent = file.getParentFile();
-
- if (parent != null && msgOutputLevel >= Project.MSG_VERBOSE) {
- System.out.println("Searching in " + parent.getAbsolutePath());
- }
-
- return parent;
- }
-
- /**
- * Search parent directories for the build file.
- * <p>
- * Takes the given target as a suffix to append to each
- * parent directory in search of a build file. Once the
- * root of the file-system has been reached <code>null</code>
- * is returned.
- *
- * @param start Leaf directory of search.
- * Must not be <code>null</code>.
- * @param suffix Suffix filename to look for in parents.
- * Must not be <code>null</code>.
- *
- * @return A handle to the build file if one is found, <code>null</code> if not
- */
- private File findBuildFile(String start, String suffix) {
- if (msgOutputLevel >= Project.MSG_INFO) {
- System.out.println("Searching for " + suffix + " ...");
- }
-
- File parent = new File(new File(start).getAbsolutePath());
- File file = new File(parent, suffix);
-
- // check if the target file exists in the current directory
- while (!file.exists()) {
- // change to parent directory
- parent = getParentFile(parent);
-
- // if parent is null, then we are at the root of the fs,
- // complain that we can't find the build file.
- if (parent == null) {
- return null;
- }
-
- // refresh our file handle
- file = new File(parent, suffix);
- }
-
- return file;
- }
-
- /**
- * Executes the build. If the constructor for this instance failed
- * (e.g. returned after issuing a warning), this method returns
- * immediately.
- *
- * @param coreLoader The classloader to use to find core classes.
- * May be <code>null</code>, in which case the
- * system classloader is used.
- *
- * @exception BuildException if the build fails
- */
- private void runBuild(ClassLoader coreLoader) throws BuildException {
-
- if (!readyToRun) {
- return;
- }
-
- final Project project = new Project();
- project.setCoreLoader(coreLoader);
-
- Throwable error = null;
-
- try {
- addBuildListeners(project);
- addInputHandler(project);
-
- PrintStream savedErr = System.err;
- PrintStream savedOut = System.out;
- InputStream savedIn = System.in;
-
- // use a system manager that prevents from System.exit()
- SecurityManager oldsm = null;
- oldsm = System.getSecurityManager();
-
- //SecurityManager can not be installed here for backwards
- //compatibility reasons (PD). Needs to be loaded prior to
- //ant class if we are going to implement it.
- //System.setSecurityManager(new NoExitSecurityManager());
- try {
- if (allowInput) {
- project.setDefaultInputStream(System.in);
- }
- System.setIn(new DemuxInputStream(project));
- System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
- System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
-
-
- if (!projectHelp) {
- project.fireBuildStarted();
- }
-
- // set the thread priorities
- if (threadPriority != null) {
- try {
- project.log("Setting Ant's thread priority to "
- + threadPriority, Project.MSG_VERBOSE);
- Thread.currentThread().setPriority(threadPriority.intValue());
- } catch (SecurityException swallowed) {
- //we cannot set the priority here.
- project.log("A security manager refused to set the -nice value");
- }
- }
-
-
-
- project.init();
- project.setBreakAt(breakAt);
- // resolve properties
- PropertyHelper propertyHelper
- = (PropertyHelper) PropertyHelper.getPropertyHelper(project);
- HashMap props = new HashMap(definedProps);
- new ResolvePropertyMap(project, propertyHelper,
- propertyHelper.getExpanders())
- .resolveAllProperties(props, null, false);
-
- // set user-define properties
- for (Iterator e = props.entrySet().iterator(); e.hasNext(); ) {
- Map.Entry ent = (Map.Entry) e.next();
- String arg = (String) ent.getKey();
- Object value = ent.getValue();
- project.setUserProperty(arg, String.valueOf(value));
- }
-
- project.setUserProperty(MagicNames.ANT_FILE,
- buildFile.getAbsolutePath());
- project.setUserProperty(MagicNames.ANT_FILE_TYPE,
- MagicNames.ANT_FILE_TYPE_FILE);
-
- project.setKeepGoingMode(keepGoingMode);
- if (proxy) {
- //proxy setup if enabled
- ProxySetup proxySetup = new ProxySetup(project);
- proxySetup.enableProxies();
- }
-
- ProjectHelper.configureProject(project, buildFile);
-
- if (projectHelp) {
- printDescription(project);
- printTargets(project, msgOutputLevel > Project.MSG_INFO,
- msgOutputLevel > Project.MSG_VERBOSE);
- return;
- }
-
- // make sure that we have a target to execute
- if (targets.size() == 0) {
- if (project.getDefaultTarget() != null) {
- targets.addElement(project.getDefaultTarget());
- }
- }
-
- project.executeTargets(targets);
- } finally {
- // put back the original security manager
- //The following will never eval to true. (PD)
- if (oldsm != null) {
- System.setSecurityManager(oldsm);
- }
-
- System.setOut(savedOut);
- System.setErr(savedErr);
- System.setIn(savedIn);
- }
- } catch (RuntimeException exc) {
- error = exc;
- throw exc;
- } catch (Error e) {
- error = e;
- throw e;
- } finally {
- if (!projectHelp) {
- try {
- project.fireBuildFinished(error);
- } catch (Throwable t) {
- // yes, I know it is bad style to catch Throwable,
- // but if we don't, we lose valuable information
- System.err.println("Caught an exception while logging the"
- + " end of the build. Exception was:");
- t.printStackTrace();
- if (error != null) {
- System.err.println("There has been an error prior to"
- + " that:");
- error.printStackTrace();
- }
- throw new BuildException(t);
- }
- } else if (error != null) {
- project.log(error.toString(), Project.MSG_ERR);
- }
- }
- }
-
- /**
- * Adds the listeners specified in the command line arguments,
- * along with the default listener, to the specified project.
- *
- * @param project The project to add listeners to.
- * Must not be <code>null</code>.
- */
- protected void addBuildListeners(Project project) {
-
- // Add the default listener
- project.addBuildListener(createLogger());
-
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- String className = (String) listeners.elementAt(i);
- BuildListener listener =
- (BuildListener) ClasspathUtils.newInstance(className,
- Main.class.getClassLoader(), BuildListener.class);
- project.setProjectReference(listener);
-
- project.addBuildListener(listener);
- }
- }
-
- /**
- * Creates the InputHandler and adds it to the project.
- *
- * @param project the project instance.
- *
- * @exception BuildException if a specified InputHandler
- * implementation could not be loaded.
- */
- private void addInputHandler(Project project) throws BuildException {
- InputHandler handler = null;
- if (inputHandlerClassname == null) {
- handler = new DefaultInputHandler();
- } else {
- handler = (InputHandler) ClasspathUtils.newInstance(
- inputHandlerClassname, Main.class.getClassLoader(),
- InputHandler.class);
- project.setProjectReference(handler);
- }
- project.setInputHandler(handler);
- }
-
- // XXX: (Jon Skeet) Any reason for writing a message and then using a bare
- // RuntimeException rather than just using a BuildException here? Is it
- // in case the message could end up being written to no loggers (as the
- // loggers could have failed to be created due to this failure)?
- /**
- * Creates the default build logger for sending build events to the ant
- * log.
- *
- * @return the logger instance for this build.
- */
- private BuildLogger createLogger() {
- BuildLogger logger = null;
- if (loggerClassname != null) {
- try {
- logger = (BuildLogger) ClasspathUtils.newInstance(
- loggerClassname, Main.class.getClassLoader(),
- BuildLogger.class);
- } catch (BuildException e) {
- System.err.println("The specified logger class "
- + loggerClassname
- + " could not be used because " + e.getMessage());
- throw new RuntimeException();
- }
- } else {
- logger = new DefaultLogger();
- }
-
- logger.setMessageOutputLevel(msgOutputLevel);
- logger.setOutputPrintStream(out);
- logger.setErrorPrintStream(err);
- logger.setEmacsMode(emacsMode);
-
- return logger;
- }
-
- /**
- * Prints the usage information for this class to <code>System.out</code>.
- */
- private static void printUsage() {
- String lSep = System.getProperty("line.separator");
- StringBuffer msg = new StringBuffer();
- msg.append("ant [options] [target [target2 [target3] ...]]" + lSep);
- msg.append("Options: " + lSep);
- msg.append(" -help, -h print this message" + lSep);
- msg.append(" -projecthelp, -p print project help information" + lSep);
- msg.append(" -version print the version information and exit" + lSep);
- msg.append(" -diagnostics print information that might be helpful to" + lSep);
- msg.append(" diagnose or report problems." + lSep);
- msg.append(" -quiet, -q be extra quiet" + lSep);
- msg.append(" -verbose, -v be extra verbose" + lSep);
- msg.append(" -debug, -d print debugging information" + lSep);
- msg.append(" -emacs, -e produce logging information without adornments"
- + lSep);
- msg.append(" -lib <path> specifies a path to search for jars and classes"
- + lSep);
- msg.append(" -logfile <file> use given file for log" + lSep);
- msg.append(" -l <file> ''" + lSep);
- msg.append(" -logger <classname> the class which is to perform logging" + lSep);
- msg.append(" -listener <classname> add an instance of class as a project listener"
- + lSep);
- msg.append(" -noinput do not allow interactive input" + lSep);
- msg.append(" -buildfile <file> use given buildfile" + lSep);
- msg.append(" -file <file> ''" + lSep);
- msg.append(" -f <file> ''" + lSep);
- msg.append(" -D<property>=<value> use value for given property" + lSep);
- msg.append(" -keep-going, -k execute all targets that do not depend" + lSep);
- msg.append(" on failed target(s)" + lSep);
- msg.append(" -propertyfile <name> load all properties from file with -D" + lSep);
- msg.append(" properties taking precedence" + lSep);
- msg.append(" -inputhandler <class> the class which will handle input requests" + lSep);
- msg.append(" -find <file> (s)earch for buildfile towards the root of" + lSep);
- msg.append(" -s <file> the filesystem and use it" + lSep);
- msg.append(" -nice number A niceness value for the main thread:" + lSep
- + " 1 (lowest) to 10 (highest); 5 is the default"
- + lSep);
- msg.append(" -nouserlib Run ant without using the jar files from" + lSep
- + " ${user.home}/.ant/lib" + lSep);
- msg.append(" -noclasspath Run ant without using CLASSPATH" + lSep);
- msg.append(" -autoproxy Java1.5+: use the OS proxy settings"
- + lSep);
- msg.append(" -main <class> override Ant's normal entry point");
- System.out.println(msg.toString());
- }
-
- /**
- * Prints the Ant version information to <code>System.out</code>.
- *
- * @exception BuildException if the version information is unavailable
- */
- private static void printVersion(int logLevel) throws BuildException {
- System.out.println(getAntVersion());
- }
-
- /**
- * Cache of the Ant version information when it has been loaded.
- */
- private static String antVersion = null;
-
- /**
- * Returns the Ant version information, if available. Once the information
- * has been loaded once, it's cached and returned from the cache on future
- * calls.
- *
- * @return the Ant version information as a String
- * (always non-<code>null</code>)
- *
- * @exception BuildException if the version information is unavailable
- */
- public static synchronized String getAntVersion() throws BuildException {
- if (antVersion == null) {
- try {
- Properties props = new Properties();
- InputStream in =
- Main.class.getResourceAsStream("/org/apache/tools/ant/version.txt");
- props.load(in);
- in.close();
-
- StringBuffer msg = new StringBuffer();
- msg.append("Apache Ant(TM) version ");
- msg.append(props.getProperty("VERSION"));
- msg.append(" compiled on ");
- msg.append(props.getProperty("DATE"));
- antVersion = msg.toString();
- } catch (IOException ioe) {
- throw new BuildException("Could not load the version information:"
- + ioe.getMessage());
- } catch (NullPointerException npe) {
- throw new BuildException("Could not load the version information.");
- }
- }
- return antVersion;
- }
-
- /**
- * Prints the description of a project (if there is one) to
- * <code>System.out</code>.
- *
- * @param project The project to display a description of.
- * Must not be <code>null</code>.
- */
- private static void printDescription(Project project) {
- if (project.getDescription() != null) {
- project.log(project.getDescription());
- }
- }
-
- /**
- * Targets in imported files with a project name
- * and not overloaded by the main build file will
- * be in the target map twice. This method
- * removes the duplicate target.
- * @param targets the targets to filter.
- * @return the filtered targets.
- */
- private static Map removeDuplicateTargets(Map targets) {
- Map locationMap = new HashMap();
- for (Iterator i = targets.entrySet().iterator(); i.hasNext();) {
- Map.Entry entry = (Map.Entry) i.next();
- String name = (String) entry.getKey();
- Target target = (Target) entry.getValue();
- Target otherTarget =
- (Target) locationMap.get(target.getLocation());
- // Place this entry in the location map if
- // a) location is not in the map
- // b) location is in map, but it's name is longer
- // (an imported target will have a name. prefix)
- if (otherTarget == null
- || otherTarget.getName().length() > name.length()) {
- locationMap.put(
- target.getLocation(), target); // Smallest name wins
- }
- }
- Map ret = new HashMap();
- for (Iterator i = locationMap.values().iterator(); i.hasNext();) {
- Target target = (Target) i.next();
- ret.put(target.getName(), target);
- }
- return ret;
- }
-
- /**
- * Prints a list of all targets in the specified project to
- * <code>System.out</code>, optionally including subtargets.
- *
- * @param project The project to display a description of.
- * Must not be <code>null</code>.
- * @param printSubTargets Whether or not subtarget names should also be
- * printed.
- */
- private static void printTargets(Project project, boolean printSubTargets,
- boolean printDependencies) {
- // find the target with the longest name
- int maxLength = 0;
- Map ptargets = removeDuplicateTargets(project.getTargets());
- String targetName;
- String targetDescription;
- Target currentTarget;
- // split the targets in top-level and sub-targets depending
- // on the presence of a description
- Vector topNames = new Vector();
- Vector topDescriptions = new Vector();
- Vector/*<Enumeration<String>>*/ topDependencies = new Vector();
- Vector subNames = new Vector();
- Vector/*<Enumeration<String>>*/ subDependencies = new Vector();
-
- for (Iterator i = ptargets.values().iterator(); i.hasNext();) {
- currentTarget = (Target) i.next();
- targetName = currentTarget.getName();
- if (targetName.equals("")) {
- continue;
- }
- targetDescription = currentTarget.getDescription();
- // maintain a sorted list of targets
- if (targetDescription == null) {
- int pos = findTargetPosition(subNames, targetName);
- subNames.insertElementAt(targetName, pos);
- if (printDependencies) {
- subDependencies.insertElementAt(currentTarget.getDependencies(), pos);
- }
- } else {
- int pos = findTargetPosition(topNames, targetName);
- topNames.insertElementAt(targetName, pos);
- topDescriptions.insertElementAt(targetDescription, pos);
- if (targetName.length() > maxLength) {
- maxLength = targetName.length();
- }
- if (printDependencies) {
- topDependencies.insertElementAt(currentTarget.getDependencies(), pos);
- }
- }
- }
-
- printTargets(project, topNames, topDescriptions, topDependencies,
- "Main targets:", maxLength);
- //if there were no main targets, we list all subtargets
- //as it means nothing has a description
- if (topNames.size() == 0) {
- printSubTargets = true;
- }
- if (printSubTargets) {
- printTargets(project, subNames, null, subDependencies, "Other targets:", 0);
- }
-
- String defaultTarget = project.getDefaultTarget();
- if (defaultTarget != null && !"".equals(defaultTarget)) {
- // shouldn't need to check but...
- project.log("Default target: " + defaultTarget);
- }
- }
-
- /**
- * Searches for the correct place to insert a name into a list so as
- * to keep the list sorted alphabetically.
- *
- * @param names The current list of names. Must not be <code>null</code>.
- * @param name The name to find a place for.
- * Must not be <code>null</code>.
- *
- * @return the correct place in the list for the given name
- */
- private static int findTargetPosition(Vector names, String name) {
- final int size = names.size();
- int res = size;
- for (int i = 0; i < size && res == size; i++) {
- if (name.compareTo((String) names.elementAt(i)) < 0) {
- res = i;
- }
- }
- return res;
- }
-
- /**
- * Writes a formatted list of target names to <code>System.out</code>
- * with an optional description.
- *
- *
- * @param project the project instance.
- * @param names The names to be printed.
- * Must not be <code>null</code>.
- * @param descriptions The associated target descriptions.
- * May be <code>null</code>, in which case
- * no descriptions are displayed.
- * If non-<code>null</code>, this should have
- * as many elements as <code>names</code>.
- * @param topDependencies The list of dependencies for each target.
- * The dependencies are listed as a non null
- * enumeration of String.
- * @param heading The heading to display.
- * Should not be <code>null</code>.
- * @param maxlen The maximum length of the names of the targets.
- * If descriptions are given, they are padded to this
- * position so they line up (so long as the names really
- * <i>are</i> shorter than this).
- */
- private static void printTargets(Project project, Vector names,
- Vector descriptions, Vector dependencies,
- String heading,
- int maxlen) {
- // now, start printing the targets and their descriptions
- String lSep = System.getProperty("line.separator");
- // got a bit annoyed that I couldn't find a pad function
- String spaces = " ";
- while (spaces.length() <= maxlen) {
- spaces += spaces;
- }
- StringBuffer msg = new StringBuffer();
- msg.append(heading + lSep + lSep);
- final int size = names.size();
- for (int i = 0; i < size; i++) {
- msg.append(" ");
- msg.append(names.elementAt(i));
- if (descriptions != null) {
- msg.append(
- spaces.substring(0, maxlen - ((String) names.elementAt(i)).length() + 2));
- msg.append(descriptions.elementAt(i));
- }
- msg.append(lSep);
- if (!dependencies.isEmpty()) {
- Enumeration deps = (Enumeration) dependencies.elementAt(i);
- if (deps.hasMoreElements()) {
- msg.append(" depends on: ");
- while (deps.hasMoreElements()) {
- msg.append(deps.nextElement());
- if (deps.hasMoreElements()) {
- msg.append(", ");
- }
- }
- msg.append(lSep);
- }
- }
- }
- project.log(msg.toString(), Project.MSG_WARN);
- }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/Project.java b/command-line-debugger/src/main/org/apache/tools/ant/Project.java
deleted file mode 100644
index ddaee39..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/Project.java
+++ /dev/null
@@ -1,2489 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- *
- */
-package org.apache.tools.ant;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.EOFException;
-import java.io.InputStream;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Properties;
-import java.util.Stack;
-import java.util.Vector;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import org.apache.tools.ant.input.DefaultInputHandler;
-import org.apache.tools.ant.input.InputHandler;
-import org.apache.tools.ant.helper.DefaultExecutor;
-import org.apache.tools.ant.types.FilterSet;
-import org.apache.tools.ant.types.FilterSetCollection;
-import org.apache.tools.ant.types.Description;
-import org.apache.tools.ant.types.Path;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.ResourceFactory;
-import org.apache.tools.ant.types.resources.FileResource;
-import org.apache.tools.ant.util.CollectionUtils;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.JavaEnvUtils;
-import org.apache.tools.ant.util.StringUtils;
-import org.apache.tools.ant.util.VectorSet;
-
-/**
- * Central representation of an Ant project. This class defines an
- * Ant project with all of its targets, tasks and various other
- * properties. It also provides the mechanism to kick off a build using
- * a particular target name.
- * <p>
- * This class also encapsulates methods which allow files to be referred
- * to using abstract path names which are translated to native system
- * file paths at runtime.
- *
- */
-public class Project implements ResourceFactory {
- /** Message priority of "error". */
- public static final int MSG_ERR = 0;
- /** Message priority of "warning". */
- public static final int MSG_WARN = 1;
- /** Message priority of "information". */
- public static final int MSG_INFO = 2;
- /** Message priority of "verbose". */
- public static final int MSG_VERBOSE = 3;
- /** Message priority of "debug". */
- public static final int MSG_DEBUG = 4;
-
- /**
- * Constant for the "visiting" state, used when
- * traversing a DFS of target dependencies.
- */
- private static final String VISITING = "VISITING";
- /**
- * Constant for the "visited" state, used when
- * traversing a DFS of target dependencies.
- */
- private static final String VISITED = "VISITED";
-
- /**
- * Version constant for Java 1.0 .
- *
- * @deprecated since 1.5.x.
- * Use {@link JavaEnvUtils#JAVA_1_0} instead.
- */
- public static final String JAVA_1_0 = JavaEnvUtils.JAVA_1_0;
- /**
- * Version constant for Java 1.1 .
- *
- * @deprecated since 1.5.x.
- * Use {@link JavaEnvUtils#JAVA_1_1} instead.
- */
- public static final String JAVA_1_1 = JavaEnvUtils.JAVA_1_1;
- /**
- * Version constant for Java 1.2 .
- *
- * @deprecated since 1.5.x.
- * Use {@link JavaEnvUtils#JAVA_1_2} instead.
- */
- public static final String JAVA_1_2 = JavaEnvUtils.JAVA_1_2;
- /**
- * Version constant for Java 1.3 .
- *
- * @deprecated since 1.5.x.
- * Use {@link JavaEnvUtils#JAVA_1_3} instead.
- */
- public static final String JAVA_1_3 = JavaEnvUtils.JAVA_1_3;
- /**
- * Version constant for Java 1.4 .
- *
- * @deprecated since 1.5.x.
- * Use {@link JavaEnvUtils#JAVA_1_4} instead.
- */
- public static final String JAVA_1_4 = JavaEnvUtils.JAVA_1_4;
-
- /** Default filter start token. */
- public static final String TOKEN_START = FilterSet.DEFAULT_TOKEN_START;
- /** Default filter end token. */
- public static final String TOKEN_END = FilterSet.DEFAULT_TOKEN_END;
-
- /** Instance of a utility class to use for file operations. */
- private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
- /** Name of this project. */
- private String name;
- /** Description for this project (if any). */
- private String description;
-
-
- /** Map of references within the project (paths etc) (String to Object). */
- private Hashtable references = new AntRefTable();
-
- /** Map of id references - used for indicating broken build files */
- private HashMap idReferences = new HashMap();
-
- /** the parent project for old id resolution (if inheritreferences is set) */
- private Project parentIdProject = null;
-
- /** Name of the project's default target. */
- private String defaultTarget;
-
- /** Map from target names to targets (String to Target). */
- private Hashtable targets = new Hashtable();
- /** Set of global filters. */
- private FilterSet globalFilterSet = new FilterSet();
- {
- // Initialize the globalFileSet's project
- globalFilterSet.setProject(this);
- }
-
- /**
- * Wrapper around globalFilterSet. This collection only ever
- * contains one FilterSet, but the wrapper is needed in order to
- * make it easier to use the FileUtils interface.
- */
- private FilterSetCollection globalFilters
- = new FilterSetCollection(globalFilterSet);
-
- /** Project base directory. */
- private File baseDir;
-
- /** lock object used when adding/removing listeners */
- private final Object listenersLock = new Object();
-
- /** List of listeners to notify of build events. */
- private volatile BuildListener[] listeners = new BuildListener[0];
-
- /** for each thread, record whether it is currently executing
- messageLogged */
- private final ThreadLocal isLoggingMessage = new ThreadLocal() {
- protected Object initialValue() {
- return Boolean.FALSE;
- }
- };
-
- /**
- * The Ant core classloader--may be <code>null</code> if using
- * parent classloader.
- */
- private ClassLoader coreLoader = null;
-
- /** Records the latest task to be executed on a thread. */
- private final Map/*<Thread,Task>*/ threadTasks =
- Collections.synchronizedMap(new WeakHashMap());
-
- /** Records the latest task to be executed on a thread group. */
- private final Map/*<ThreadGroup,Task>*/ threadGroupTasks
- = Collections.synchronizedMap(new WeakHashMap());
-
- /**
- * Called to handle any input requests.
- */
- private InputHandler inputHandler = null;
-
- /**
- * The default input stream used to read any input.
- */
- private InputStream defaultInputStream = null;
-
- /**
- * Keep going flag.
- */
- private boolean keepGoingMode = false;
-
- /**
- * Contains the target to break the execution at.
- */
- protected String breakAt;
-
- public void setBreakAt(String breakAt) {
- this.breakAt = breakAt;
- }
-
- public String getBreakAt() {
- return breakAt;
- }
-
- /**
- * Set the input handler.
- *
- * @param handler the InputHandler instance to use for gathering input.
- */
- public void setInputHandler(InputHandler handler) {
- inputHandler = handler;
- }
-
- /**
- * Set the default System input stream. Normally this stream is set to
- * System.in. This inputStream is used when no task input redirection is
- * being performed.
- *
- * @param defaultInputStream the default input stream to use when input
- * is requested.
- * @since Ant 1.6
- */
- public void setDefaultInputStream(InputStream defaultInputStream) {
- this.defaultInputStream = defaultInputStream;
- }
-
- /**
- * Get this project's input stream.
- *
- * @return the InputStream instance in use by this Project instance to
- * read input.
- */
- public InputStream getDefaultInputStream() {
- return defaultInputStream;
- }
-
- /**
- * Retrieve the current input handler.
- *
- * @return the InputHandler instance currently in place for the project
- * instance.
- */
- public InputHandler getInputHandler() {
- return inputHandler;
- }
-
- /**
- * Create a new Ant project.
- */
- public Project() {
- inputHandler = new DefaultInputHandler();
- }
-
- /**
- * Create and initialize a subproject. By default the subproject will be of
- * the same type as its parent. If a no-arg constructor is unavailable, the
- * <code>Project</code> class will be used.
- * @return a Project instance configured as a subproject of this Project.
- * @since Ant 1.7
- */
- public Project createSubProject() {
- Project subProject = null;
- try {
- subProject = (Project) (getClass().newInstance());
- } catch (Exception e) {
- subProject = new Project();
- }
- initSubProject(subProject);
- return subProject;
- }
-
- /**
- * Initialize a subproject.
- * @param subProject the subproject to initialize.
- */
- public void initSubProject(Project subProject) {
- ComponentHelper.getComponentHelper(subProject)
- .initSubProject(ComponentHelper.getComponentHelper(this));
- subProject.setDefaultInputStream(getDefaultInputStream());
- subProject.setKeepGoingMode(this.isKeepGoingMode());
- subProject.setExecutor(getExecutor().getSubProjectExecutor());
- }
-
- /**
- * Initialise the project.
- *
- * This involves setting the default task definitions and loading the
- * system properties.
- *
- * @exception BuildException if the default task list cannot be loaded.
- */
- public void init() throws BuildException {
- initProperties();
-
- ComponentHelper.getComponentHelper(this).initDefaultDefinitions();
- }
-
- /**
- * Initializes the properties.
- * @exception BuildException if an vital property could not be set.
- * @since Ant 1.7
- */
- public void initProperties() throws BuildException {
- setJavaVersionProperty();
- setSystemProperties();
- setPropertyInternal(MagicNames.ANT_VERSION, Main.getAntVersion());
- setAntLib();
- }
-
- /**
- * Set a property to the location of ant.jar.
- * Use the locator to find the location of the Project.class, and
- * if this is not null, set the property {@link MagicNames#ANT_LIB}
- * to the result
- */
- private void setAntLib() {
- File antlib = org.apache.tools.ant.launch.Locator.getClassSource(
- Project.class);
- if (antlib != null) {
- setPropertyInternal(MagicNames.ANT_LIB, antlib.getAbsolutePath());
- }
- }
- /**
- * Factory method to create a class loader for loading classes from
- * a given path.
- *
- * @param path the path from which classes are to be loaded.
- *
- * @return an appropriate classloader.
- */
- public AntClassLoader createClassLoader(Path path) {
- return AntClassLoader
- .newAntClassLoader(getClass().getClassLoader(), this, path, true);
- }
-
- /**
- * Factory method to create a class loader for loading classes from
- * a given path.
- *
- * @param parent the parent classloader for the new loader.
- * @param path the path from which classes are to be loaded.
- *
- * @return an appropriate classloader.
- */
- public AntClassLoader createClassLoader(
- ClassLoader parent, Path path) {
- return AntClassLoader.newAntClassLoader(parent, this, path, true);
- }
-
- /**
- * Set the core classloader for the project. If a <code>null</code>
- * classloader is specified, the parent classloader should be used.
- *
- * @param coreLoader The classloader to use for the project.
- * May be <code>null</code>.
- */
- public void setCoreLoader(ClassLoader coreLoader) {
- this.coreLoader = coreLoader;
- }
-
- /**
- * Return the core classloader to use for this project.
- * This may be <code>null</code>, indicating that
- * the parent classloader should be used.
- *
- * @return the core classloader to use for this project.
- *
- */
- public ClassLoader getCoreLoader() {
- return coreLoader;
- }
-
- /**
- * Add a build listener to the list. This listener will
- * be notified of build events for this project.
- *
- * @param listener The listener to add to the list.
- * Must not be <code>null</code>.
- */
- public void addBuildListener(BuildListener listener) {
- synchronized (listenersLock) {
- // If the listeners already has this listener, do nothing
- for (int i = 0; i < listeners.length; i++) {
- if (listeners[i] == listener) {
- return;
- }
- }
- // copy on write semantics
- BuildListener[] newListeners =
- new BuildListener[listeners.length + 1];
- System.arraycopy(listeners, 0, newListeners, 0, listeners.length);
- newListeners[listeners.length] = listener;
- listeners = newListeners;
- }
- }
-
- /**
- * Remove a build listener from the list. This listener
- * will no longer be notified of build events for this project.
- *
- * @param listener The listener to remove from the list.
- * Should not be <code>null</code>.
- */
- public void removeBuildListener(BuildListener listener) {
- synchronized (listenersLock) {
- // copy on write semantics
- for (int i = 0; i < listeners.length; i++) {
- if (listeners[i] == listener) {
- BuildListener[] newListeners =
- new BuildListener[listeners.length - 1];
- System.arraycopy(listeners, 0, newListeners, 0, i);
- System.arraycopy(listeners, i + 1, newListeners, i,
- listeners.length - i - 1);
- listeners = newListeners;
- break;
- }
- }
- }
- }
-
- /**
- * Return a copy of the list of build listeners for the project.
- *
- * @return a list of build listeners for the project
- */
- public Vector getBuildListeners() {
- synchronized (listenersLock) {
- Vector r = new Vector(listeners.length);
- for (int i = 0; i < listeners.length; i++) {
- r.add(listeners[i]);
- }
- return r;
- }
- }
-
- /**
- * Write a message to the log with the default log level
- * of MSG_INFO .
- * @param message The text to log. Should not be <code>null</code>.
- */
-
- public void log(String message) {
- log(message, MSG_INFO);
- }
-
- /**
- * Write a project level message to the log with the given log level.
- * @param message The text to log. Should not be <code>null</code>.
- * @param msgLevel The log priority level to use.
- */
- public void log(String message, int msgLevel) {
- log(message, null, msgLevel);
- }
-
- /**
- * Write a project level message to the log with the given log level.
- * @param message The text to log. Should not be <code>null</code>.
- * @param throwable The exception causing this log, may be <code>null</code>.
- * @param msgLevel The log priority level to use.
- * @since 1.7
- */
- public void log(String message, Throwable throwable, int msgLevel) {
- fireMessageLogged(this, message, throwable, msgLevel);
- }
-
- /**
- * Write a task level message to the log with the given log level.
- * @param task The task to use in the log. Must not be <code>null</code>.
- * @param message The text to log. Should not be <code>null</code>.
- * @param msgLevel The log priority level to use.
- */
- public void log(Task task, String message, int msgLevel) {
- fireMessageLogged(task, message, null, msgLevel);
- }
-
- /**
- * Write a task level message to the log with the given log level.
- * @param task The task to use in the log. Must not be <code>null</code>.
- * @param message The text to log. Should not be <code>null</code>.
- * @param throwable The exception causing this log, may be <code>null</code>.
- * @param msgLevel The log priority level to use.
- * @since 1.7
- */
- public void log(Task task, String message, Throwable throwable, int msgLevel) {
- fireMessageLogged(task, message, throwable, msgLevel);
- }
-
- /**
- * Write a target level message to the log with the given log level.
- * @param target The target to use in the log.
- * Must not be <code>null</code>.
- * @param message The text to log. Should not be <code>null</code>.
- * @param msgLevel The log priority level to use.
- */
- public void log(Target target, String message, int msgLevel) {
- log(target, message, null, msgLevel);
- }
-
- /**
- * Write a target level message to the log with the given log level.
- * @param target The target to use in the log.
- * Must not be <code>null</code>.
- * @param message The text to log. Should not be <code>null</code>.
- * @param throwable The exception causing this log, may be <code>null</code>.
- * @param msgLevel The log priority level to use.
- * @since 1.7
- */
- public void log(Target target, String message, Throwable throwable,
- int msgLevel) {
- fireMessageLogged(target, message, throwable, msgLevel);
- }
-
- /**
- * Return the set of global filters.
- *
- * @return the set of global filters.
- */
- public FilterSet getGlobalFilterSet() {
- return globalFilterSet;
- }
-
- /**
- * Set a property. Any existing property of the same name
- * is overwritten, unless it is a user property.
- * @param name The name of property to set.
- * Must not be <code>null</code>.
- * @param value The new value of the property.
- * Must not be <code>null</code>.
- */
- public void setProperty(String name, String value) {
- PropertyHelper.getPropertyHelper(this).setProperty(name, value, true);
- }
-
- /**
- * Set a property if no value currently exists. If the property
- * exists already, a message is logged and the method returns with
- * no other effect.
- *
- * @param name The name of property to set.
- * Must not be <code>null</code>.
- * @param value The new value of the property.
- * Must not be <code>null</code>.
- * @since 1.5
- */
- public void setNewProperty(String name, String value) {
- PropertyHelper.getPropertyHelper(this).setNewProperty(name, value);
- }
-
- /**
- * Set a user property, which cannot be overwritten by
- * set/unset property calls. Any previous value is overwritten.
- * @param name The name of property to set.
- * Must not be <code>null</code>.
- * @param value The new value of the property.
- * Must not be <code>null</code>.
- * @see #setProperty(String,String)
- */
- public void setUserProperty(String name, String value) {
- PropertyHelper.getPropertyHelper(this).setUserProperty(name, value);
- }
-
- /**
- * Set a user property, which cannot be overwritten by set/unset
- * property calls. Any previous value is overwritten. Also marks
- * these properties as properties that have not come from the
- * command line.
- *
- * @param name The name of property to set.
- * Must not be <code>null</code>.
- * @param value The new value of the property.
- * Must not be <code>null</code>.
- * @see #setProperty(String,String)
- */
- public void setInheritedProperty(String name, String value) {
- PropertyHelper.getPropertyHelper(this).setInheritedProperty(name, value);
- }
-
- /**
- * Set a property unless it is already defined as a user property
- * (in which case the method returns silently).
- *
- * @param name The name of the property.
- * Must not be <code>null</code>.
- * @param value The property value. Must not be <code>null</code>.
- */
- private void setPropertyInternal(String name, String value) {
- PropertyHelper.getPropertyHelper(this).setProperty(name, value, false);
- }
-
- /**
- * Return the value of a property, if it is set.
- *
- * @param propertyName The name of the property.
- * May be <code>null</code>, in which case
- * the return value is also <code>null</code>.
- * @return the property value, or <code>null</code> for no match
- * or if a <code>null</code> name is provided.
- */
- public String getProperty(String propertyName) {
- Object value = PropertyHelper.getPropertyHelper(this).getProperty(propertyName);
- return value == null ? null : String.valueOf(value);
- }
-
- /**
- * Replace ${} style constructions in the given value with the
- * string value of the corresponding data types.
- *
- * @param value The string to be scanned for property references.
- * May be <code>null</code>.
- *
- * @return the given string with embedded property names replaced
- * by values, or <code>null</code> if the given string is
- * <code>null</code>.
- *
- * @exception BuildException if the given value has an unclosed
- * property name, e.g. <code>${xxx</code>.
- */
- public String replaceProperties(String value) throws BuildException {
- return PropertyHelper.getPropertyHelper(this).replaceProperties(null, value, null);
- }
-
- /**
- * Return the value of a user property, if it is set.
- *
- * @param propertyName The name of the property.
- * May be <code>null</code>, in which case
- * the return value is also <code>null</code>.
- * @return the property value, or <code>null</code> for no match
- * or if a <code>null</code> name is provided.
- */
- public String getUserProperty(String propertyName) {
- return (String) PropertyHelper.getPropertyHelper(this).getUserProperty(propertyName);
- }
-
- /**
- * Return a copy of the properties table.
- * @return a hashtable containing all properties
- * (including user properties).
- */
- public Hashtable getProperties() {
- return PropertyHelper.getPropertyHelper(this).getProperties();
- }
-
- /**
- * Return a copy of the user property hashtable.
- * @return a hashtable containing just the user properties.
- */
- public Hashtable getUserProperties() {
- return PropertyHelper.getPropertyHelper(this).getUserProperties();
- }
-
- /**
- * Return a copy of the inherited property hashtable.
- * @return a hashtable containing just the inherited properties.
- * @since Ant 1.8.0
- */
- public Hashtable getInheritedProperties() {
- return PropertyHelper.getPropertyHelper(this).getInheritedProperties();
- }
-
- /**
- * Copy all user properties that have been set on the command
- * line or a GUI tool from this instance to the Project instance
- * given as the argument.
- *
- * <p>To copy all "user" properties, you will also have to call
- * {@link #copyInheritedProperties copyInheritedProperties}.</p>
- *
- * @param other the project to copy the properties to. Must not be null.
- *
- * @since Ant 1.5
- */
- public void copyUserProperties(Project other) {
- PropertyHelper.getPropertyHelper(this).copyUserProperties(other);
- }
-
- /**
- * Copy all user properties that have not been set on the
- * command line or a GUI tool from this instance to the Project
- * instance given as the argument.
- *
- * <p>To copy all "user" properties, you will also have to call
- * {@link #copyUserProperties copyUserProperties}.</p>
- *
- * @param other the project to copy the properties to. Must not be null.
- *
- * @since Ant 1.5
- */
- public void copyInheritedProperties(Project other) {
- PropertyHelper.getPropertyHelper(this).copyInheritedProperties(other);
- }
-
- /**
- * Set the default target of the project.
- *
- * @param defaultTarget The name of the default target for this project.
- * May be <code>null</code>, indicating that there is
- * no default target.
- *
- * @deprecated since 1.5.x.
- * Use setDefault.
- * @see #setDefault(String)
- */
- public void setDefaultTarget(String defaultTarget) {
- setDefault(defaultTarget);
- }
-
- /**
- * Return the name of the default target of the project.
- * @return name of the default target or
- * <code>null</code> if no default has been set.
- */
- public String getDefaultTarget() {
- return defaultTarget;
- }
-
- /**
- * Set the default target of the project.
- *
- * @param defaultTarget The name of the default target for this project.
- * May be <code>null</code>, indicating that there is
- * no default target.
- */
- public void setDefault(String defaultTarget) {
- if (defaultTarget != null) {
- setUserProperty(MagicNames.PROJECT_DEFAULT_TARGET, defaultTarget);
- }
- this.defaultTarget = defaultTarget;
- }
-
- /**
- * Set the name of the project, also setting the user
- * property <code>ant.project.name</code>.
- *
- * @param name The name of the project.
- * Must not be <code>null</code>.
- */
- public void setName(String name) {
- setUserProperty(MagicNames.PROJECT_NAME, name);
- this.name = name;
- }
-
- /**
- * Return the project name, if one has been set.
- *
- * @return the project name, or <code>null</code> if it hasn't been set.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Set the project description.
- *
- * @param description The description of the project.
- * May be <code>null</code>.
- */
- public void setDescription(String description) {
- this.description = description;
- }
-
- /**
- * Return the project description, if one has been set.
- *
- * @return the project description, or <code>null</code> if it hasn't
- * been set.
- */
- public String getDescription() {
- if (description == null) {
- description = Description.getDescription(this);
- }
- return description;
- }
-
- /**
- * Add a filter to the set of global filters.
- *
- * @param token The token to filter.
- * Must not be <code>null</code>.
- * @param value The replacement value.
- * Must not be <code>null</code>.
- * @deprecated since 1.4.x.
- * Use getGlobalFilterSet().addFilter(token,value)
- *
- * @see #getGlobalFilterSet()
- * @see FilterSet#addFilter(String,String)
- */
- public void addFilter(String token, String value) {
- if (token == null) {
- return;
- }
- globalFilterSet.addFilter(new FilterSet.Filter(token, value));
- }
-
- /**
- * Return a hashtable of global filters, mapping tokens to values.
- *
- * @return a hashtable of global filters, mapping tokens to values
- * (String to String).
- *
- * @deprecated since 1.4.x
- * Use getGlobalFilterSet().getFilterHash().
- *
- * @see #getGlobalFilterSet()
- * @see FilterSet#getFilterHash()
- */
- public Hashtable getFilters() {
- // we need to build the hashtable dynamically
- return globalFilterSet.getFilterHash();
- }
-
- /**
- * Set the base directory for the project, checking that
- * the given filename exists and is a directory.
- *
- * @param baseD The project base directory.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the directory if invalid.
- */
- public void setBasedir(String baseD) throws BuildException {
- setBaseDir(new File(baseD));
- }
-
- /**
- * Set the base directory for the project, checking that
- * the given file exists and is a directory.
- *
- * @param baseDir The project base directory.
- * Must not be <code>null</code>.
- * @exception BuildException if the specified file doesn't exist or
- * isn't a directory.
- */
- public void setBaseDir(File baseDir) throws BuildException {
- baseDir = FILE_UTILS.normalize(baseDir.getAbsolutePath());
- if (!baseDir.exists()) {
- throw new BuildException("Basedir " + baseDir.getAbsolutePath()
- + " does not exist");
- }
- if (!baseDir.isDirectory()) {
- throw new BuildException("Basedir " + baseDir.getAbsolutePath()
- + " is not a directory");
- }
- this.baseDir = baseDir;
- setPropertyInternal(MagicNames.PROJECT_BASEDIR, this.baseDir.getPath());
- String msg = "Project base dir set to: " + this.baseDir;
- log(msg, MSG_VERBOSE);
- }
-
- /**
- * Return the base directory of the project as a file object.
- *
- * @return the project base directory, or <code>null</code> if the
- * base directory has not been successfully set to a valid value.
- */
- public File getBaseDir() {
- if (baseDir == null) {
- try {
- setBasedir(".");
- } catch (BuildException ex) {
- ex.printStackTrace();
- }
- }
- return baseDir;
- }
-
- /**
- * Set "keep-going" mode. In this mode Ant will try to execute
- * as many targets as possible. All targets that do not depend
- * on failed target(s) will be executed. If the keepGoing settor/getter
- * methods are used in conjunction with the <code>ant.executor.class</code>
- * property, they will have no effect.
- * @param keepGoingMode "keep-going" mode
- * @since Ant 1.6
- */
- public void setKeepGoingMode(boolean keepGoingMode) {
- this.keepGoingMode = keepGoingMode;
- }
-
- /**
- * Return the keep-going mode. If the keepGoing settor/getter
- * methods are used in conjunction with the <code>ant.executor.class</code>
- * property, they will have no effect.
- * @return "keep-going" mode
- * @since Ant 1.6
- */
- public boolean isKeepGoingMode() {
- return this.keepGoingMode;
- }
-
- /**
- * Return the version of Java this class is running under.
- * @return the version of Java as a String, e.g. "1.1" .
- * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion
- * @deprecated since 1.5.x.
- * Use org.apache.tools.ant.util.JavaEnvUtils instead.
- */
- public static String getJavaVersion() {
- return JavaEnvUtils.getJavaVersion();
- }
-
- /**
- * Set the <code>ant.java.version</code> property and tests for
- * unsupported JVM versions. If the version is supported,
- * verbose log messages are generated to record the Java version
- * and operating system name.
- *
- * @exception BuildException if this Java version is not supported.
- *
- * @see org.apache.tools.ant.util.JavaEnvUtils#getJavaVersion
- */
- public void setJavaVersionProperty() throws BuildException {
- String javaVersion = JavaEnvUtils.getJavaVersion();
- setPropertyInternal(MagicNames.ANT_JAVA_VERSION, javaVersion);
-
- // sanity check
- if (!JavaEnvUtils.isAtLeastJavaVersion(JavaEnvUtils.JAVA_1_4)) {
- throw new BuildException("Ant cannot work on Java prior to 1.4");
- }
- log("Detected Java version: " + javaVersion + " in: "
- + System.getProperty("java.home"), MSG_VERBOSE);
-
- log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE);
- }
-
- /**
- * Add all system properties which aren't already defined as
- * user properties to the project properties.
- */
- public void setSystemProperties() {
- Properties systemP = System.getProperties();
- Enumeration e = systemP.propertyNames();
- while (e.hasMoreElements()) {
- String propertyName = (String) e.nextElement();
- String value = systemP.getProperty(propertyName);
- if (value != null) {
- this.setPropertyInternal(propertyName, value);
- }
- }
- }
-
- /**
- * Add a new task definition to the project.
- * Attempting to override an existing definition with an
- * equivalent one (i.e. with the same classname) results in
- * a verbose log message. Attempting to override an existing definition
- * with a different one results in a warning log message and
- * invalidates any tasks which have already been created with the
- * old definition.
- *
- * @param taskName The name of the task to add.
- * Must not be <code>null</code>.
- * @param taskClass The full name of the class implementing the task.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the class is unsuitable for being an Ant
- * task. An error level message is logged before
- * this exception is thrown.
- *
- * @see #checkTaskClass(Class)
- */
- public void addTaskDefinition(String taskName, Class taskClass)
- throws BuildException {
- ComponentHelper.getComponentHelper(this).addTaskDefinition(taskName,
- taskClass);
- }
-
- /**
- * Check whether or not a class is suitable for serving as Ant task.
- * Ant task implementation classes must be public, concrete, and have
- * a no-arg constructor.
- *
- * @param taskClass The class to be checked.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the class is unsuitable for being an Ant
- * task. An error level message is logged before
- * this exception is thrown.
- */
- public void checkTaskClass(final Class taskClass) throws BuildException {
- ComponentHelper.getComponentHelper(this).checkTaskClass(taskClass);
-
- if (!Modifier.isPublic(taskClass.getModifiers())) {
- final String message = taskClass + " is not public";
- log(message, Project.MSG_ERR);
- throw new BuildException(message);
- }
- if (Modifier.isAbstract(taskClass.getModifiers())) {
- final String message = taskClass + " is abstract";
- log(message, Project.MSG_ERR);
- throw new BuildException(message);
- }
- try {
- taskClass.getConstructor((Class[]) null);
- // don't have to check for public, since
- // getConstructor finds public constructors only.
- } catch (NoSuchMethodException e) {
- final String message = "No public no-arg constructor in "
- + taskClass;
- log(message, Project.MSG_ERR);
- throw new BuildException(message);
- } catch (LinkageError e) {
- String message = "Could not load " + taskClass + ": " + e;
- log(message, Project.MSG_ERR);
- throw new BuildException(message, e);
- }
- if (!Task.class.isAssignableFrom(taskClass)) {
- TaskAdapter.checkTaskClass(taskClass, this);
- }
- }
-
- /**
- * Return the current task definition hashtable. The returned hashtable is
- * "live" and so should not be modified.
- *
- * @return a map of from task name to implementing class
- * (String to Class).
- */
- public Hashtable getTaskDefinitions() {
- return ComponentHelper.getComponentHelper(this).getTaskDefinitions();
- }
-
- /**
- * Return the current task definition map. The returned map is a
- * copy of the "live" definitions.
- *
- * @return a map of from task name to implementing class
- * (String to Class).
- *
- * @since Ant 1.8.1
- */
- public Map getCopyOfTaskDefinitions() {
- return new HashMap(getTaskDefinitions());
- }
-
- /**
- * Add a new datatype definition.
- * Attempting to override an existing definition with an
- * equivalent one (i.e. with the same classname) results in
- * a verbose log message. Attempting to override an existing definition
- * with a different one results in a warning log message, but the
- * definition is changed.
- *
- * @param typeName The name of the datatype.
- * Must not be <code>null</code>.
- * @param typeClass The full name of the class implementing the datatype.
- * Must not be <code>null</code>.
- */
- public void addDataTypeDefinition(String typeName, Class typeClass) {
- ComponentHelper.getComponentHelper(this).addDataTypeDefinition(typeName,
- typeClass);
- }
-
- /**
- * Return the current datatype definition hashtable. The returned
- * hashtable is "live" and so should not be modified.
- *
- * @return a map of from datatype name to implementing class
- * (String to Class).
- */
- public Hashtable getDataTypeDefinitions() {
- return ComponentHelper.getComponentHelper(this).getDataTypeDefinitions();
- }
-
- /**
- * Return the current datatype definition map. The returned
- * map is a copy pf the "live" definitions.
- *
- * @return a map of from datatype name to implementing class
- * (String to Class).
- *
- * @since Ant 1.8.1
- */
- public Map getCopyOfDataTypeDefinitions() {
- return new HashMap(getDataTypeDefinitions());
- }
-
- /**
- * Add a <em>new</em> target to the project.
- *
- * @param target The target to be added to the project.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the target already exists in the project
- *
- * @see Project#addOrReplaceTarget(Target)
- */
- public void addTarget(Target target) throws BuildException {
- addTarget(target.getName(), target);
- }
-
- /**
- * Add a <em>new</em> target to the project.
- *
- * @param targetName The name to use for the target.
- * Must not be <code>null</code>.
- * @param target The target to be added to the project.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the target already exists in the project.
- *
- * @see Project#addOrReplaceTarget(String, Target)
- */
- public void addTarget(String targetName, Target target)
- throws BuildException {
- if (targets.get(targetName) != null) {
- throw new BuildException("Duplicate target: `" + targetName + "'");
- }
- addOrReplaceTarget(targetName, target);
- }
-
- /**
- * Add a target to the project, or replaces one with the same
- * name.
- *
- * @param target The target to be added or replaced in the project.
- * Must not be <code>null</code>.
- */
- public void addOrReplaceTarget(Target target) {
- addOrReplaceTarget(target.getName(), target);
- }
-
- /**
- * Add a target to the project, or replaces one with the same
- * name.
- *
- * @param targetName The name to use for the target.
- * Must not be <code>null</code>.
- * @param target The target to be added or replaced in the project.
- * Must not be <code>null</code>.
- */
- public void addOrReplaceTarget(String targetName, Target target) {
- String msg = " +Target: " + targetName;
- log(msg, MSG_DEBUG);
- target.setProject(this);
- targets.put(targetName, target);
- }
-
- /**
- * Return the hashtable of targets. The returned hashtable
- * is "live" and so should not be modified.
- * @return a map from name to target (String to Target).
- */
- public Hashtable getTargets() {
- return targets;
- }
-
- /**
- * Return the map of targets. The returned map
- * is a copy of the "live" targets.
- * @return a map from name to target (String to Target).
- * @since Ant 1.8.1
- */
- public Map getCopyOfTargets() {
- return new HashMap(targets);
- }
-
- /**
- * Create a new instance of a task, adding it to a list of
- * created tasks for later invalidation. This causes all tasks
- * to be remembered until the containing project is removed
- * @param taskType The name of the task to create an instance of.
- * Must not be <code>null</code>.
- *
- * @return an instance of the specified task, or <code>null</code> if
- * the task name is not recognised.
- *
- * @exception BuildException if the task name is recognised but task
- * creation fails.
- */
- public Task createTask(String taskType) throws BuildException {
- return ComponentHelper.getComponentHelper(this).createTask(taskType);
- }
-
- /**
- * Create a new instance of a data type.
- *
- * @param typeName The name of the data type to create an instance of.
- * Must not be <code>null</code>.
- *
- * @return an instance of the specified data type, or <code>null</code> if
- * the data type name is not recognised.
- *
- * @exception BuildException if the data type name is recognised but
- * instance creation fails.
- */
- public Object createDataType(String typeName) throws BuildException {
- return ComponentHelper.getComponentHelper(this).createDataType(typeName);
- }
-
- /**
- * Set the Executor instance for this Project.
- * @param e the Executor to use.
- */
- public void setExecutor(Executor e) {
- addReference(MagicNames.ANT_EXECUTOR_REFERENCE, e);
- }
-
- /**
- * Get this Project's Executor (setting it if necessary).
- * @return an Executor instance.
- */
- public Executor getExecutor() {
- Object o = getReference(MagicNames.ANT_EXECUTOR_REFERENCE);
- if (o == null) {
- String classname = getProperty(MagicNames.ANT_EXECUTOR_CLASSNAME);
- if (classname == null) {
- classname = DefaultExecutor.class.getName();
- }
- log("Attempting to create object of type " + classname, MSG_DEBUG);
- try {
- o = Class.forName(classname, true, coreLoader).newInstance();
- } catch (ClassNotFoundException seaEnEfEx) {
- //try the current classloader
- try {
- o = Class.forName(classname).newInstance();
- } catch (Exception ex) {
- log(ex.toString(), MSG_ERR);
- }
- } catch (Exception ex) {
- log(ex.toString(), MSG_ERR);
- }
- if (o == null) {
- throw new BuildException(
- "Unable to obtain a Target Executor instance.");
- }
- setExecutor((Executor) o);
- }
- return (Executor) o;
- }
-
- /**
- * Execute the specified sequence of targets, and the targets
- * they depend on.
- *
- * @param names A vector of target name strings to execute.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the build failed.
- */
- public void executeTargets(Vector names) throws BuildException {
- setUserProperty(MagicNames.PROJECT_INVOKED_TARGETS,
- CollectionUtils.flattenToString(names));
- getExecutor().executeTargets(this,
- (String[]) (names.toArray(new String[names.size()])));
- }
-
- /**
- * Demultiplex output so that each task receives the appropriate
- * messages. If the current thread is not currently executing a task,
- * the message is logged directly.
- *
- * @param output Message to handle. Should not be <code>null</code>.
- * @param isWarning Whether the text represents an warning (<code>true</code>)
- * or information (<code>false</code>).
- */
- public void demuxOutput(String output, boolean isWarning) {
- Task task = getThreadTask(Thread.currentThread());
- if (task == null) {
- log(output, isWarning ? MSG_WARN : MSG_INFO);
- } else {
- if (isWarning) {
- task.handleErrorOutput(output);
- } else {
- task.handleOutput(output);
- }
- }
- }
-
- /**
- * Read data from the default input stream. If no default has been
- * specified, System.in is used.
- *
- * @param buffer the buffer into which data is to be read.
- * @param offset the offset into the buffer at which data is stored.
- * @param length the amount of data to read.
- *
- * @return the number of bytes read.
- *
- * @exception IOException if the data cannot be read.
- * @since Ant 1.6
- */
- public int defaultInput(byte[] buffer, int offset, int length)
- throws IOException {
- if (defaultInputStream != null) {
- System.out.flush();
- return defaultInputStream.read(buffer, offset, length);
- } else {
- throw new EOFException("No input provided for project");
- }
- }
-
- /**
- * Demux an input request to the correct task.
- *
- * @param buffer the buffer into which data is to be read.
- * @param offset the offset into the buffer at which data is stored.
- * @param length the amount of data to read.
- *
- * @return the number of bytes read.
- *
- * @exception IOException if the data cannot be read.
- * @since Ant 1.6
- */
- public int demuxInput(byte[] buffer, int offset, int length)
- throws IOException {
- Task task = getThreadTask(Thread.currentThread());
- if (task == null) {
- return defaultInput(buffer, offset, length);
- } else {
- return task.handleInput(buffer, offset, length);
- }
- }
-
- /**
- * Demultiplex flush operations so that each task receives the appropriate
- * messages. If the current thread is not currently executing a task,
- * the message is logged directly.
- *
- * @since Ant 1.5.2
- *
- * @param output Message to handle. Should not be <code>null</code>.
- * @param isError Whether the text represents an error (<code>true</code>)
- * or information (<code>false</code>).
- */
- public void demuxFlush(String output, boolean isError) {
- Task task = getThreadTask(Thread.currentThread());
- if (task == null) {
- fireMessageLogged(this, output, isError ? MSG_ERR : MSG_INFO);
- } else {
- if (isError) {
- task.handleErrorFlush(output);
- } else {
- task.handleFlush(output);
- }
- }
- }
-
- /**
- * Execute the specified target and any targets it depends on.
- *
- * @param targetName The name of the target to execute.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if the build failed.
- */
- public void executeTarget(String targetName) throws BuildException {
-
- // sanity check ourselves, if we've been asked to build nothing
- // then we should complain
-
- if (targetName == null) {
- String msg = "No target specified";
- throw new BuildException(msg);
- }
-
- // Sort and run the dependency tree.
- // Sorting checks if all the targets (and dependencies)
- // exist, and if there is any cycle in the dependency
- // graph.
- executeSortedTargets(topoSort(targetName, targets, false));
- }
-
- /**
- * Execute a <code>Vector</code> of sorted targets.
- * @param sortedTargets the aforementioned <code>Vector</code>.
- * @throws BuildException on error.
- */
- public void executeSortedTargets(Vector sortedTargets)
- throws BuildException {
- Set succeededTargets = new HashSet();
- BuildException buildException = null; // first build exception
- for (Enumeration iter = sortedTargets.elements();
- iter.hasMoreElements();) {
- Target curtarget = (Target) iter.nextElement();
- boolean canExecute = true;
- for (Enumeration depIter = curtarget.getDependencies();
- depIter.hasMoreElements();) {
- String dependencyName = ((String) depIter.nextElement());
- if (!succeededTargets.contains(dependencyName)) {
- canExecute = false;
- log(curtarget,
- "Cannot execute '" + curtarget.getName() + "' - '"
- + dependencyName + "' failed or was not executed.",
- MSG_ERR);
- break;
- }
- }
- if (canExecute) {
- Throwable thrownException = null;
- try {
- curtarget.performTasks();
- succeededTargets.add(curtarget.getName());
- } catch (RuntimeException ex) {
- if (!(keepGoingMode)) {
- throw ex; // throw further
- }
- thrownException = ex;
- } catch (Throwable ex) {
- if (!(keepGoingMode)) {
- throw new BuildException(ex);
- }
- thrownException = ex;
- }
- if (thrownException != null) {
- if (thrownException instanceof BuildException) {
- log(curtarget,
- "Target '" + curtarget.getName()
- + "' failed with message '"
- + thrownException.getMessage() + "'.", MSG_ERR);
- // only the first build exception is reported
- if (buildException == null) {
- buildException = (BuildException) thrownException;
- }
- } else {
- log(curtarget,
- "Target '" + curtarget.getName()
- + "' failed with message '"
- + thrownException.getMessage() + "'.", MSG_ERR);
- thrownException.printStackTrace(System.err);
- if (buildException == null) {
- buildException =
- new BuildException(thrownException);
- }
- }
- }
- }
- }
- if (buildException != null) {
- throw buildException;
- }
- }
-
- /**
- * Return the canonical form of a filename.
- * <p>
- * If the specified file name is relative it is resolved
- * with respect to the given root directory.
- *
- * @param fileName The name of the file to resolve.
- * Must not be <code>null</code>.
- *
- * @param rootDir The directory respective to which relative file names
- * are resolved. May be <code>null</code>, in which case
- * the current directory is used.
- *
- * @return the resolved File.
- *
- * @deprecated since 1.4.x
- */
- public File resolveFile(String fileName, File rootDir) {
- return FILE_UTILS.resolveFile(rootDir, fileName);
- }
-
- /**
- * Return the canonical form of a filename.
- * <p>
- * If the specified file name is relative it is resolved
- * with respect to the project's base directory.
- *
- * @param fileName The name of the file to resolve.
- * Must not be <code>null</code>.
- *
- * @return the resolved File.
- *
- */
- public File resolveFile(String fileName) {
- return FILE_UTILS.resolveFile(baseDir, fileName);
- }
-
- /**
- * Translate a path into its native (platform specific) format.
- * <p>
- * This method uses PathTokenizer to separate the input path
- * into its components. This handles DOS style paths in a relatively
- * sensible way. The file separators are then converted to their platform
- * specific versions.
- *
- * @param toProcess The path to be translated.
- * May be <code>null</code>.
- *
- * @return the native version of the specified path or
- * an empty string if the path is <code>null</code> or empty.
- *
- * @deprecated since 1.7
- * Use FileUtils.translatePath instead.
- *
- * @see PathTokenizer
- */
- public static String translatePath(String toProcess) {
- return FileUtils.translatePath(toProcess);
- }
-
- /**
- * Convenience method to copy a file from a source to a destination.
- * No filtering is performed.
- *
- * @param sourceFile Name of file to copy from.
- * Must not be <code>null</code>.
- * @param destFile Name of file to copy to.
- * Must not be <code>null</code>.
- *
- * @exception IOException if the copying fails.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(String sourceFile, String destFile)
- throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile);
- }
-
- /**
- * Convenience method to copy a file from a source to a destination
- * specifying if token filtering should be used.
- *
- * @param sourceFile Name of file to copy from.
- * Must not be <code>null</code>.
- * @param destFile Name of file to copy to.
- * Must not be <code>null</code>.
- * @param filtering Whether or not token filtering should be used during
- * the copy.
- *
- * @exception IOException if the copying fails.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(String sourceFile, String destFile, boolean filtering)
- throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile,
- filtering ? globalFilters : null);
- }
-
- /**
- * Convenience method to copy a file from a source to a
- * destination specifying if token filtering should be used and if
- * source files may overwrite newer destination files.
- *
- * @param sourceFile Name of file to copy from.
- * Must not be <code>null</code>.
- * @param destFile Name of file to copy to.
- * Must not be <code>null</code>.
- * @param filtering Whether or not token filtering should be used during
- * the copy.
- * @param overwrite Whether or not the destination file should be
- * overwritten if it already exists.
- *
- * @exception IOException if the copying fails.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(String sourceFile, String destFile, boolean filtering,
- boolean overwrite) throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile,
- filtering ? globalFilters : null, overwrite);
- }
-
- /**
- * Convenience method to copy a file from a source to a
- * destination specifying if token filtering should be used, if
- * source files may overwrite newer destination files, and if the
- * last modified time of the resulting file should be set to
- * that of the source file.
- *
- * @param sourceFile Name of file to copy from.
- * Must not be <code>null</code>.
- * @param destFile Name of file to copy to.
- * Must not be <code>null</code>.
- * @param filtering Whether or not token filtering should be used during
- * the copy.
- * @param overwrite Whether or not the destination file should be
- * overwritten if it already exists.
- * @param preserveLastModified Whether or not the last modified time of
- * the resulting file should be set to that
- * of the source file.
- *
- * @exception IOException if the copying fails.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(String sourceFile, String destFile, boolean filtering,
- boolean overwrite, boolean preserveLastModified)
- throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile,
- filtering ? globalFilters : null, overwrite, preserveLastModified);
- }
-
- /**
- * Convenience method to copy a file from a source to a destination.
- * No filtering is performed.
- *
- * @param sourceFile File to copy from.
- * Must not be <code>null</code>.
- * @param destFile File to copy to.
- * Must not be <code>null</code>.
- *
- * @exception IOException if the copying fails.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(File sourceFile, File destFile) throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile);
- }
-
- /**
- * Convenience method to copy a file from a source to a destination
- * specifying if token filtering should be used.
- *
- * @param sourceFile File to copy from.
- * Must not be <code>null</code>.
- * @param destFile File to copy to.
- * Must not be <code>null</code>.
- * @param filtering Whether or not token filtering should be used during
- * the copy.
- *
- * @exception IOException if the copying fails.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(File sourceFile, File destFile, boolean filtering)
- throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile,
- filtering ? globalFilters : null);
- }
-
- /**
- * Convenience method to copy a file from a source to a
- * destination specifying if token filtering should be used and if
- * source files may overwrite newer destination files.
- *
- * @param sourceFile File to copy from.
- * Must not be <code>null</code>.
- * @param destFile File to copy to.
- * Must not be <code>null</code>.
- * @param filtering Whether or not token filtering should be used during
- * the copy.
- * @param overwrite Whether or not the destination file should be
- * overwritten if it already exists.
- *
- * @exception IOException if the file cannot be copied.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(File sourceFile, File destFile, boolean filtering,
- boolean overwrite) throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile,
- filtering ? globalFilters : null, overwrite);
- }
-
- /**
- * Convenience method to copy a file from a source to a
- * destination specifying if token filtering should be used, if
- * source files may overwrite newer destination files, and if the
- * last modified time of the resulting file should be set to
- * that of the source file.
- *
- * @param sourceFile File to copy from.
- * Must not be <code>null</code>.
- * @param destFile File to copy to.
- * Must not be <code>null</code>.
- * @param filtering Whether or not token filtering should be used during
- * the copy.
- * @param overwrite Whether or not the destination file should be
- * overwritten if it already exists.
- * @param preserveLastModified Whether or not the last modified time of
- * the resulting file should be set to that
- * of the source file.
- *
- * @exception IOException if the file cannot be copied.
- *
- * @deprecated since 1.4.x
- */
- public void copyFile(File sourceFile, File destFile, boolean filtering,
- boolean overwrite, boolean preserveLastModified)
- throws IOException {
- FILE_UTILS.copyFile(sourceFile, destFile,
- filtering ? globalFilters : null, overwrite, preserveLastModified);
- }
-
- /**
- * Call File.setLastModified(long time) on Java above 1.1, and logs
- * a warning on Java 1.1.
- *
- * @param file The file to set the last modified time on.
- * Must not be <code>null</code>.
- *
- * @param time the required modification time.
- *
- * @deprecated since 1.4.x
- *
- * @exception BuildException if the last modified time cannot be set
- * despite running on a platform with a version
- * above 1.1.
- */
- public void setFileLastModified(File file, long time)
- throws BuildException {
- FILE_UTILS.setFileLastModified(file, time);
- log("Setting modification time for " + file, MSG_VERBOSE);
- }
-
- /**
- * Return the boolean equivalent of a string, which is considered
- * <code>true</code> if either <code>"on"</code>, <code>"true"</code>,
- * or <code>"yes"</code> is found, ignoring case.
- *
- * @param s The string to convert to a boolean value.
- *
- * @return <code>true</code> if the given string is <code>"on"</code>,
- * <code>"true"</code> or <code>"yes"</code>, or
- * <code>false</code> otherwise.
- */
- public static boolean toBoolean(String s) {
- return ("on".equalsIgnoreCase(s)
- || "true".equalsIgnoreCase(s)
- || "yes".equalsIgnoreCase(s));
- }
-
- /**
- * Get the Project instance associated with the specified object.
- * @param o the object to query.
- * @return Project instance, if any.
- * @since Ant 1.7.1
- */
- public static Project getProject(Object o) {
- if (o instanceof ProjectComponent) {
- return ((ProjectComponent) o).getProject();
- }
- try {
- Method m = o.getClass().getMethod("getProject", (Class[]) null);
- if (Project.class == m.getReturnType()) {
- return (Project) m.invoke(o, (Object[]) null);
- }
- } catch (Exception e) {
- //too bad
- }
- return null;
- }
-
- /**
- * Topologically sort a set of targets. Equivalent to calling
- * <code>topoSort(new String[] {root}, targets, true)</code>.
- *
- * @param root The name of the root target. The sort is created in such
- * a way that the sequence of Targets up to the root
- * target is the minimum possible such sequence.
- * Must not be <code>null</code>.
- * @param targetTable A Hashtable mapping names to Targets.
- * Must not be <code>null</code>.
- * @return a Vector of ALL Target objects in sorted order.
- * @exception BuildException if there is a cyclic dependency among the
- * targets, or if a named target does not exist.
- */
- public final Vector topoSort(String root, Hashtable targetTable)
- throws BuildException {
- return topoSort(new String[] {root}, targetTable, true);
- }
-
- /**
- * Topologically sort a set of targets. Equivalent to calling
- * <code>topoSort(new String[] {root}, targets, returnAll)</code>.
- *
- * @param root The name of the root target. The sort is created in such
- * a way that the sequence of Targets up to the root
- * target is the minimum possible such sequence.
- * Must not be <code>null</code>.
- * @param targetTable A Hashtable mapping names to Targets.
- * Must not be <code>null</code>.
- * @param returnAll <code>boolean</code> indicating whether to return all
- * targets, or the execution sequence only.
- * @return a Vector of Target objects in sorted order.
- * @exception BuildException if there is a cyclic dependency among the
- * targets, or if a named target does not exist.
- * @since Ant 1.6.3
- */
- public final Vector topoSort(String root, Hashtable targetTable,
- boolean returnAll) throws BuildException {
- return topoSort(new String[] {root}, targetTable, returnAll);
- }
-
- /**
- * Topologically sort a set of targets.
- *
- * @param root <code>String[]</code> containing the names of the root targets.
- * The sort is created in such a way that the ordered sequence of
- * Targets is the minimum possible such sequence to the specified
- * root targets.
- * Must not be <code>null</code>.
- * @param targetTable A map of names to targets (String to Target).
- * Must not be <code>null</code>.
- * @param returnAll <code>boolean</code> indicating whether to return all
- * targets, or the execution sequence only.
- * @return a Vector of Target objects in sorted order.
- * @exception BuildException if there is a cyclic dependency among the
- * targets, or if a named target does not exist.
- * @since Ant 1.6.3
- */
- public final Vector topoSort(String[] root, Hashtable targetTable,
- boolean returnAll) throws BuildException {
- Vector ret = new VectorSet();
- Hashtable state = new Hashtable();
- Stack visiting = new Stack();
-
- // We first run a DFS based sort using each root as a starting node.
- // This creates the minimum sequence of Targets to the root node(s).
- // We then do a sort on any remaining unVISITED targets.
- // This is unnecessary for doing our build, but it catches
- // circular dependencies or missing Targets on the entire
- // dependency tree, not just on the Targets that depend on the
- // build Target.
-
- for (int i = 0; i < root.length; i++) {
- String st = (String) (state.get(root[i]));
- if (st == null) {
- tsort(root[i], targetTable, state, visiting, ret);
- } else if (st == VISITING) {
- throw new RuntimeException("Unexpected node in visiting state: "
- + root[i]);
- }
- }
- StringBuffer buf = new StringBuffer("Build sequence for target(s)");
-
- for (int j = 0; j < root.length; j++) {
- buf.append((j == 0) ? " `" : ", `").append(root[j]).append('\'');
- }
- buf.append(" is " + ret);
- log(buf.toString(), MSG_VERBOSE);
-
- Vector complete = (returnAll) ? ret : new Vector(ret);
- for (Enumeration en = targetTable.keys(); en.hasMoreElements();) {
- String curTarget = (String) en.nextElement();
- String st = (String) state.get(curTarget);
- if (st == null) {
- tsort(curTarget, targetTable, state, visiting, complete);
- } else if (st == VISITING) {
- throw new RuntimeException("Unexpected node in visiting state: "
- + curTarget);
- }
- }
- log("Complete build sequence is " + complete, MSG_VERBOSE);
- return ret;
- }
-
- /**
- * Perform a single step in a recursive depth-first-search traversal of
- * the target dependency tree.
- * <p>
- * The current target is first set to the "visiting" state, and
- * pushed onto the "visiting" stack.
- * <p>
- * An exception is then thrown if any child of the current node is in the
- * visiting state, as that implies a circular dependency. The exception
- * contains details of the cycle, using elements of the "visiting"
- * stack.
- * <p>
- * If any child has not already been "visited", this method is
- * called recursively on it.
- * <p>
- * The current target is then added to the ordered list of targets. Note
- * that this is performed after the children have been visited in order
- * to get the correct order. The current target is set to the
- * "visited" state.
- * <p>
- * By the time this method returns, the ordered list contains the sequence
- * of targets up to and including the current target.
- *
- * @param root The current target to inspect.
- * Must not be <code>null</code>.
- * @param targetTable A mapping from names to targets (String to Target).
- * Must not be <code>null</code>.
- * @param state A mapping from target names to states (String to String).
- * The states in question are "VISITING" and
- * "VISITED". Must not be <code>null</code>.
- * @param visiting A stack of targets which are currently being visited.
- * Must not be <code>null</code>.
- * @param ret The list to add target names to. This will end up
- * containing the complete list of dependencies in
- * dependency order.
- * Must not be <code>null</code>.
- *
- * @exception BuildException if a non-existent target is specified or if
- * a circular dependency is detected.
- */
- private void tsort(String root, Hashtable targetTable,
- Hashtable state, Stack visiting,
- Vector ret)
- throws BuildException {
- state.put(root, VISITING);
- visiting.push(root);
-
- Target target = (Target) targetTable.get(root);
-
- // Make sure we exist
- if (target == null) {
- StringBuffer sb = new StringBuffer("Target \"");
- sb.append(root);
- sb.append("\" does not exist in the project \"");
- sb.append(name);
- sb.append("\". ");
- visiting.pop();
- if (!visiting.empty()) {
- String parent = (String) visiting.peek();
- sb.append("It is used from target \"");
- sb.append(parent);
- sb.append("\".");
- }
- throw new BuildException(new String(sb));
- }
- for (Enumeration en = target.getDependencies(); en.hasMoreElements();) {
- String cur = (String) en.nextElement();
- String m = (String) state.get(cur);
- if (m == null) {
- // Not been visited
- tsort(cur, targetTable, state, visiting, ret);
- } else if (m == VISITING) {
- // Currently visiting this node, so have a cycle
- throw makeCircularException(cur, visiting);
- }
- }
- String p = (String) visiting.pop();
- if (root != p) {
- throw new RuntimeException("Unexpected internal error: expected to "
- + "pop " + root + " but got " + p);
- }
- state.put(root, VISITED);
- ret.addElement(target);
- }
-
- /**
- * Build an appropriate exception detailing a specified circular
- * dependency.
- *
- * @param end The dependency to stop at. Must not be <code>null</code>.
- * @param stk A stack of dependencies. Must not be <code>null</code>.
- *
- * @return a BuildException detailing the specified circular dependency.
- */
- private static BuildException makeCircularException(String end, Stack stk) {
- StringBuffer sb = new StringBuffer("Circular dependency: ");
- sb.append(end);
- String c;
- do {
- c = (String) stk.pop();
- sb.append(" <- ");
- sb.append(c);
- } while (!c.equals(end));
- return new BuildException(new String(sb));
- }
-
- /**
- * Inherit the id references.
- * @param parent the parent project of this project.
- */
- public void inheritIDReferences(Project parent) {
- parentIdProject = parent;
- }
-
- /**
- * Add an id reference.
- * Used for broken build files.
- * @param id the id to set.
- * @param value the value to set it to (Unknown element in this case.
- */
- public void addIdReference(String id, Object value) {
- idReferences.put(id, value);
- }
-
- /**
- * Add a reference to the project.
- *
- * @param referenceName The name of the reference. Must not be <code>null</code>.
- * @param value The value of the reference.
- */
- public void addReference(String referenceName, Object value) {
- Object old = ((AntRefTable) references).getReal(referenceName);
- if (old == value) {
- // no warning, this is not changing anything
- return;
- }
- if (old != null && !(old instanceof UnknownElement)) {
- log("Overriding previous definition of reference to " + referenceName,
- MSG_VERBOSE);
- }
- log("Adding reference: " + referenceName, MSG_DEBUG);
- references.put(referenceName, value);
- }
-
- /**
- * Return a map of the references in the project (String to Object).
- * The returned hashtable is "live" and so must not be modified.
- *
- * @return a map of the references in the project (String to Object).
- */
- public Hashtable getReferences() {
- return references;
- }
-
- /**
- * Does the project know this reference?
- *
- * @since Ant 1.8.0
- */
- public boolean hasReference(String key) {
- return references.containsKey(key);
- }
-
- /**
- * Return a map of the references in the project (String to
- * Object). The returned hashtable is a copy of the
- * "live" references.
- *
- * @return a map of the references in the project (String to Object).
- *
- * @since Ant 1.8.1
- */
- public Map getCopyOfReferences() {
- return new HashMap(references);
- }
-
- /**
- * Look up a reference by its key (ID).
- *
- * @param key The key for the desired reference.
- * Must not be <code>null</code>.
- *
- * @return the reference with the specified ID, or <code>null</code> if
- * there is no such reference in the project.
- */
- public Object getReference(String key) {
- Object ret = references.get(key);
- if (ret != null) {
- return ret;
- }
- if (!key.equals(MagicNames.REFID_PROPERTY_HELPER)) {
- try {
- if (PropertyHelper.getPropertyHelper(this).containsProperties(key)) {
- log("Unresolvable reference " + key
- + " might be a misuse of property expansion syntax.", MSG_WARN);
- }
- } catch (Exception e) {
- //ignore
- }
- }
- return ret;
- }
-
- /**
- * Return a description of the type of the given element, with
- * special handling for instances of tasks and data types.
- * <p>
- * This is useful for logging purposes.
- *
- * @param element The element to describe.
- * Must not be <code>null</code>.
- *
- * @return a description of the element type.
- *
- * @since 1.95, Ant 1.5
- */
- public String getElementName(Object element) {
- return ComponentHelper.getComponentHelper(this).getElementName(element);
- }
-
- /**
- * Send a "build started" event
- * to the build listeners for this project.
- */
- public void fireBuildStarted() {
- BuildEvent event = new BuildEvent(this);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].buildStarted(event);
- }
- }
-
- /**
- * Send a "build finished" event to the build listeners
- * for this project.
- * @param exception an exception indicating a reason for a build
- * failure. May be <code>null</code>, indicating
- * a successful build.
- */
- public void fireBuildFinished(Throwable exception) {
- BuildEvent event = new BuildEvent(this);
- event.setException(exception);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].buildFinished(event);
- }
- // Inform IH to clear the cache
- IntrospectionHelper.clearCache();
- }
-
- /**
- * Send a "subbuild started" event to the build listeners for
- * this project.
- *
- * @since Ant 1.6.2
- */
- public void fireSubBuildStarted() {
- BuildEvent event = new BuildEvent(this);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- if (currListeners[i] instanceof SubBuildListener) {
- ((SubBuildListener) currListeners[i]).subBuildStarted(event);
- }
- }
- }
-
- /**
- * Send a "subbuild finished" event to the build listeners for
- * this project.
- * @param exception an exception indicating a reason for a build
- * failure. May be <code>null</code>, indicating
- * a successful build.
- *
- * @since Ant 1.6.2
- */
- public void fireSubBuildFinished(Throwable exception) {
- BuildEvent event = new BuildEvent(this);
- event.setException(exception);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- if (currListeners[i] instanceof SubBuildListener) {
- ((SubBuildListener) currListeners[i]).subBuildFinished(event);
- }
- }
- }
-
- /**
- * Send a "target started" event to the build listeners
- * for this project.
- *
- * @param target The target which is starting to build.
- * Must not be <code>null</code>.
- */
- protected void fireTargetStarted(Target target) {
- BuildEvent event = new BuildEvent(target);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].targetStarted(event);
- }
-
- }
-
- /**
- * Send a "target finished" event to the build listeners
- * for this project.
- *
- * @param target The target which has finished building.
- * Must not be <code>null</code>.
- * @param exception an exception indicating a reason for a build
- * failure. May be <code>null</code>, indicating
- * a successful build.
- */
- protected void fireTargetFinished(Target target, Throwable exception) {
- BuildEvent event = new BuildEvent(target);
- event.setException(exception);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].targetFinished(event);
- }
-
- }
-
- /**
- * Send a "task started" event to the build listeners
- * for this project.
- *
- * @param task The target which is starting to execute.
- * Must not be <code>null</code>.
- */
- protected void fireTaskStarted(Task task) {
- // register this as the current task on the current thread.
- registerThreadTask(Thread.currentThread(), task);
- BuildEvent event = new BuildEvent(task);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].taskStarted(event);
- }
- }
-
- /**
- * Send a "task finished" event to the build listeners for this
- * project.
- *
- * @param task The task which has finished executing.
- * Must not be <code>null</code>.
- * @param exception an exception indicating a reason for a build
- * failure. May be <code>null</code>, indicating
- * a successful build.
- */
- protected void fireTaskFinished(Task task, Throwable exception) {
- registerThreadTask(Thread.currentThread(), null);
- System.out.flush();
- System.err.flush();
- BuildEvent event = new BuildEvent(task);
- event.setException(exception);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].taskFinished(event);
- }
-
- }
-
- /**
- * Send a "message logged" event to the build listeners
- * for this project.
- *
- * @param event The event to send. This should be built up with the
- * appropriate task/target/project by the caller, so that
- * this method can set the message and priority, then send
- * the event. Must not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param priority The priority of the message.
- */
- private void fireMessageLoggedEvent(BuildEvent event, String message,
- int priority) {
-
- if (message == null) {
- message = String.valueOf(message);
- }
- if (message.endsWith(StringUtils.LINE_SEP)) {
- int endIndex = message.length() - StringUtils.LINE_SEP.length();
- event.setMessage(message.substring(0, endIndex), priority);
- } else {
- event.setMessage(message, priority);
- }
- if (isLoggingMessage.get() != Boolean.FALSE) {
- /*
- * One of the Listeners has attempted to access
- * System.err or System.out.
- *
- * We used to throw an exception in this case, but
- * sometimes Listeners can't prevent it(like our own
- * Log4jListener which invokes getLogger() which in
- * turn wants to write to the console).
- *
- * @see http://marc.theaimsgroup.com/?t=110538624200006&r=1&w=2
- *
- * We now (Ant 1.6.3 and later) simply swallow the message.
- */
- return;
- }
- try {
- isLoggingMessage.set(Boolean.TRUE);
- BuildListener[] currListeners = listeners;
- for (int i = 0; i < currListeners.length; i++) {
- currListeners[i].messageLogged(event);
- }
- } finally {
- isLoggingMessage.set(Boolean.FALSE);
- }
- }
-
- /**
- * Send a "message logged" project level event
- * to the build listeners for this project.
- *
- * @param project The project generating the event.
- * Should not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param priority The priority of the message.
- */
- protected void fireMessageLogged(Project project, String message,
- int priority) {
- fireMessageLogged(project, message, null, priority);
- }
-
- /**
- * Send a "message logged" project level event
- * to the build listeners for this project.
- *
- * @param project The project generating the event.
- * Should not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param throwable The exception that caused this message. May be <code>null</code>.
- * @param priority The priority of the message.
- * @since 1.7
- */
- protected void fireMessageLogged(Project project, String message,
- Throwable throwable, int priority) {
- BuildEvent event = new BuildEvent(project);
- event.setException(throwable);
- fireMessageLoggedEvent(event, message, priority);
- }
-
- /**
- * Send a "message logged" target level event
- * to the build listeners for this project.
- *
- * @param target The target generating the event.
- * Must not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param priority The priority of the message.
- */
- protected void fireMessageLogged(Target target, String message,
- int priority) {
- fireMessageLogged(target, message, null, priority);
- }
-
- /**
- * Send a "message logged" target level event
- * to the build listeners for this project.
- *
- * @param target The target generating the event.
- * Must not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param throwable The exception that caused this message. May be <code>null</code>.
- * @param priority The priority of the message.
- * @since 1.7
- */
- protected void fireMessageLogged(Target target, String message,
- Throwable throwable, int priority) {
- BuildEvent event = new BuildEvent(target);
- event.setException(throwable);
- fireMessageLoggedEvent(event, message, priority);
- }
-
- /**
- * Send a "message logged" task level event
- * to the build listeners for this project.
- *
- * @param task The task generating the event.
- * Must not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param priority The priority of the message.
- */
- protected void fireMessageLogged(Task task, String message, int priority) {
- fireMessageLogged(task, message, null, priority);
- }
-
- /**
- * Send a "message logged" task level event
- * to the build listeners for this project.
- *
- * @param task The task generating the event.
- * Must not be <code>null</code>.
- * @param message The message to send. Should not be <code>null</code>.
- * @param throwable The exception that caused this message. May be <code>null</code>.
- * @param priority The priority of the message.
- * @since 1.7
- */
- protected void fireMessageLogged(Task task, String message,
- Throwable throwable, int priority) {
- BuildEvent event = new BuildEvent(task);
- event.setException(throwable);
- fireMessageLoggedEvent(event, message, priority);
- }
-
- /**
- * Register a task as the current task for a thread.
- * If the task is null, the thread's entry is removed.
- *
- * @param thread the thread on which the task is registered.
- * @param task the task to be registered.
- * @since Ant 1.5
- */
- public void registerThreadTask(Thread thread, Task task) {
- synchronized(threadTasks) {
- if (task != null) {
- threadTasks.put(thread, task);
- threadGroupTasks.put(thread.getThreadGroup(), task);
- } else {
- threadTasks.remove(thread);
- threadGroupTasks.remove(thread.getThreadGroup());
- }
- }
- }
-
- /**
- * Get the current task associated with a thread, if any.
- *
- * @param thread the thread for which the task is required.
- * @return the task which is currently registered for the given thread or
- * null if no task is registered.
- */
- public Task getThreadTask(Thread thread) {
- synchronized(threadTasks) {
- Task task = (Task) threadTasks.get(thread);
- if (task == null) {
- ThreadGroup group = thread.getThreadGroup();
- while (task == null && group != null) {
- task = (Task) threadGroupTasks.get(group);
- group = group.getParent();
- }
- }
- return task;
- }
- }
-
-
- // Should move to a separate public class - and have API to add
- // listeners, etc.
- private static class AntRefTable extends Hashtable {
-
- AntRefTable() {
- super();
- }
-
- /** Returns the unmodified original object.
- * This method should be called internally to
- * get the "real" object.
- * The normal get method will do the replacement
- * of UnknownElement (this is similar with the JDNI
- * refs behavior).
- */
- private Object getReal(Object key) {
- return super.get(key);
- }
-
- /** Get method for the reference table.
- * It can be used to hook dynamic references and to modify
- * some references on the fly--for example for delayed
- * evaluation.
- *
- * It is important to make sure that the processing that is
- * done inside is not calling get indirectly.
- *
- * @param key lookup key.
- * @return mapped value.
- */
- public Object get(Object key) {
- //System.out.println("AntRefTable.get " + key);
- Object o = getReal(key);
- if (o instanceof UnknownElement) {
- // Make sure that
- UnknownElement ue = (UnknownElement) o;
- ue.maybeConfigure();
- o = ue.getRealThing();
- }
- return o;
- }
- }
-
- /**
- * Set a reference to this Project on the parameterized object.
- * Need to set the project before other set/add elements
- * are called.
- * @param obj the object to invoke setProject(this) on.
- */
- public final void setProjectReference(final Object obj) {
- if (obj instanceof ProjectComponent) {
- ((ProjectComponent) obj).setProject(this);
- return;
- }
- try {
- Method method =
- obj.getClass().getMethod(
- "setProject", new Class[] {Project.class});
- if (method != null) {
- method.invoke(obj, new Object[] {this});
- }
- } catch (Throwable e) {
- // ignore this if the object does not have
- // a set project method or the method
- // is private/protected.
- }
- }
-
- /**
- * Resolve the file relative to the project's basedir and return it as a
- * FileResource.
- * @param name the name of the file to resolve.
- * @return the file resource.
- * @since Ant 1.7
- */
- public Resource getResource(String name) {
- return new FileResource(getBaseDir(), name);
- }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/PropertyDebugHelper.java b/command-line-debugger/src/main/org/apache/tools/ant/PropertyDebugHelper.java
new file mode 100644
index 0000000..42cb17c
--- /dev/null
+++ b/command-line-debugger/src/main/org/apache/tools/ant/PropertyDebugHelper.java
@@ -0,0 +1,57 @@
+package org.apache.tools.ant;
+
+import org.apache.ant.debugger.Auditor;
+
+/**
+ * Derives almost everything from parent {@link PropertyHelper}. Only difference
+ * being, that it allows an {@link Auditor} instance to attach to itself, which
+ * is informed about attempted property changes, which auditor can then choose
+ * to record them, and probably present them to the end user as needed.
+ * <p />
+ */
+public class PropertyDebugHelper extends PropertyHelper {
+
+ protected Auditor auditor;
+
+ protected Project project;
+
+ public void setAuditor(Auditor auditor) {
+ this.auditor = auditor;
+ }
+
+ public void setProject(Project project) {
+ this.project = project;
+ }
+
+ /*
+ * Implement a callback mechanism here for all these methods that will allow
+ * the control to pass back to the listener
+ */
+
+ public boolean setProperty(String name, Object value, boolean verbose) {
+ project.log("Auditing change to property: " + name, Project.MSG_DEBUG);
+ auditor.auditPropertyChange(name, value, project);
+ // call back can take control before the actual property change is
+ // invoked?
+ return super.setProperty(name, value, verbose);
+ }
+
+ public void setNewProperty(String name, Object value) {
+ project.log("Auditing change to property: " + name, Project.MSG_DEBUG);
+ auditor.auditPropertyChange(name, value, project);
+ super.setNewProperty(name, value);
+ }
+
+ public void setUserProperty(String name, Object value) {
+ project.log("Auditing change to property: " + name, Project.MSG_DEBUG);
+ auditor.auditPropertyChange(name, value, project);
+ super.setUserProperty(name, value);
+ }
+
+ public void setInheritedProperty(String name, Object value) {
+ project.log("Auditing change to property: " + name);
+ auditor.auditPropertyChange(name, value, project);
+ super.setInheritedProperty(name, value);
+ }
+
+}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/command-line-debugger/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
deleted file mode 100644
index 2876598..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- *
- */
-package org.apache.tools.ant.helper;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.ExtensionPoint;
-import org.apache.tools.ant.Location;
-import org.apache.tools.ant.MagicNames;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.ProjectHelper;
-import org.apache.tools.ant.RuntimeConfigurable;
-import org.apache.tools.ant.Target;
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.UnknownElement;
-import org.apache.tools.ant.DebugTask;
-import org.apache.tools.ant.types.Resource;
-import org.apache.tools.ant.types.resources.FileProvider;
-import org.apache.tools.ant.types.resources.URLProvider;
-import org.apache.tools.ant.util.FileUtils;
-import org.apache.tools.ant.util.JAXPUtils;
-import org.apache.tools.zip.ZipFile;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Stack;
-
-/**
- * Sax2 based project reader
- *
- */
-public class ProjectHelper2 extends ProjectHelper {
-
- /** Reference holding the (ordered) target Vector */
- public static final String REFID_TARGETS = "ant.targets";
-
- /* Stateless */
-
- // singletons - since all state is in the context
- private static AntHandler elementHandler = new ElementHandler();
- private static AntHandler targetHandler = new TargetHandler();
- private static AntHandler mainHandler = new MainHandler();
- private static AntHandler projectHandler = new ProjectHandler();
-
- /** Specific to ProjectHelper2 so not a true Ant "magic name:" */
- private static final String REFID_CONTEXT = "ant.parsing.context";
-
- /**
- * helper for path -> URI and URI -> path conversions.
- */
- private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
-
- /**
- * Whether this instance of ProjectHelper can parse an Antlib
- * descriptor given by the URL and return its content as an
- * UnknownElement ready to be turned into an Antlib task.
- *
- * <p>This implementation returns true.</p>
- *
- * @since Ant 1.8.0
- */
- public boolean canParseAntlibDescriptor(Resource resource) {
- return true;
- }
-
- /**
- * Parse the given URL as an antlib descriptor and return the
- * content as something that can be turned into an Antlib task.
- *
- * <p>simply delegates to {@link #parseUnknownElement
- * parseUnknownElement} if the resource provides an URL and throws
- * an exception otherwise.</p>
- *
- * @since Ant 1.8.0
- */
- public UnknownElement parseAntlibDescriptor(Project containingProject,
- Resource resource) {
- URLProvider up = (URLProvider) resource.as(URLProvider.class);
- if (up == null) {
- throw new BuildException("Unsupported resource type: " + resource);
- }
- return parseUnknownElement(containingProject, up.getURL());
- }
-
- /**
- * Parse an unknown element from a url
- *
- * @param project the current project
- * @param source the url containing the task
- * @return a configured task
- * @exception BuildException if an error occurs
- */
- public UnknownElement parseUnknownElement(Project project, URL source)
- throws BuildException {
- Target dummyTarget = new Target();
- dummyTarget.setProject(project);
-
- AntXMLContext context = new AntXMLContext(project);
- context.addTarget(dummyTarget);
- context.setImplicitTarget(dummyTarget);
-
- parse(context.getProject(), source, new RootHandler(context, elementHandler));
- Task[] tasks = dummyTarget.getTasks();
- if (tasks.length != 1) {
- throw new BuildException("No tasks defined");
- }
- return (UnknownElement) tasks[0];
- }
-
- /**
- * Parse a source xml input.
- *
- * @param project the current project
- * @param source the xml source
- * @exception BuildException if an error occurs
- */
- public void parse(Project project, Object source) throws BuildException {
- getImportStack().addElement(source);
- AntXMLContext context = null;
- context = (AntXMLContext) project.getReference(REFID_CONTEXT);
- if (context == null) {
- context = new AntXMLContext(project);
- project.addReference(REFID_CONTEXT, context);
- project.addReference(REFID_TARGETS, context.getTargets());
- }
- if (getImportStack().size() > 1) {
- // we are in an imported file.
- context.setIgnoreProjectTag(true);
- Target currentTarget = context.getCurrentTarget();
- Target currentImplicit = context.getImplicitTarget();
- Map currentTargets = context.getCurrentTargets();
- try {
- Target newCurrent = new Target();
- newCurrent.setProject(project);
- newCurrent.setName("");
- context.setCurrentTarget(newCurrent);
- context.setCurrentTargets(new HashMap());
- context.setImplicitTarget(newCurrent);
- parse(project, source, new RootHandler(context, mainHandler));
- newCurrent.execute();
- } finally {
- context.setCurrentTarget(currentTarget);
- context.setImplicitTarget(currentImplicit);
- context.setCurrentTargets(currentTargets);
- }
- } else {
- // top level file
- context.setCurrentTargets(new HashMap());
- parse(project, source, new RootHandler(context, mainHandler));
- // Execute the top-level target
- context.getImplicitTarget().execute();
-
- // resolve extensionOf attributes
- for (Iterator i = getExtensionStack().iterator(); i.hasNext(); ) {
- String[] extensionInfo = (String[]) i.next();
- String tgName = extensionInfo[0];
- String name = extensionInfo[1];
- OnMissingExtensionPoint missingBehaviour = OnMissingExtensionPoint
- .valueOf(extensionInfo[2]);
- Hashtable projectTargets = project.getTargets();
- if (!projectTargets.containsKey(tgName)) {
- String message = "can't add target " + name
- + " to extension-point " + tgName
- + " because the extension-point is unknown.";
- if (missingBehaviour == OnMissingExtensionPoint.FAIL) {
- throw new BuildException(message);
- } else if (missingBehaviour == OnMissingExtensionPoint.WARN) {
- Target target = (Target) projectTargets.get(name);
- context.getProject().log(target,
- "Warning: " + message,
- Project.MSG_WARN);
- }
- } else {
- Target t = (Target) projectTargets.get(tgName);
- if (!(t instanceof ExtensionPoint)) {
- throw new BuildException("referenced target "
- + tgName
- + " is not an extension-point");
- }
- t.addDependency(name);
- }
- }
- }
- }
-
- /**
- * Parses the project file, configuring the project as it goes.
- *
- * @param project the current project
- * @param source the xml source
- * @param handler the root handler to use (contains the current context)
- * @exception BuildException if the configuration is invalid or cannot
- * be read
- */
- public void parse(Project project, Object source, RootHandler handler) throws BuildException {
-
- AntXMLContext context = handler.context;
-
- File buildFile = null;
- URL url = null;
- String buildFileName = null;
-
- if (source instanceof File) {
- buildFile = (File) source;
- } else if (source instanceof URL) {
- url = (URL) source;
- } else if (source instanceof Resource) {
- FileProvider fp =
- (FileProvider) ((Resource) source).as(FileProvider.class);
- if (fp != null) {
- buildFile = fp.getFile();
- } else {
- URLProvider up =
- (URLProvider) ((Resource) source).as(URLProvider.class);
- if (up != null) {
- url = up.getURL();
- }
- }
- }
- if (buildFile != null) {
- buildFile = FILE_UTILS.normalize(buildFile.getAbsolutePath());
- context.setBuildFile(buildFile);
- buildFileName = buildFile.toString();
- } else if (url != null) {
- try {
- context.setBuildFile((File) null);
- context.setBuildFile(url);
- } catch (java.net.MalformedURLException ex) {
- throw new BuildException(ex);
- }
- buildFileName = url.toString();
- } else {
- throw new BuildException("Source " + source.getClass().getName()
- + " not supported by this plugin");
- }
- InputStream inputStream = null;
- InputSource inputSource = null;
- ZipFile zf = null;
-
- try {
- /**
- * SAX 2 style parser used to parse the given file.
- */
- XMLReader parser = JAXPUtils.getNamespaceXMLReader();
-
- String uri = null;
- if (buildFile != null) {
- uri = FILE_UTILS.toURI(buildFile.getAbsolutePath());
- inputStream = new FileInputStream(buildFile);
- } else {
- uri = url.toString();
- int pling = -1;
- if (uri.startsWith("jar:file")
- && (pling = uri.indexOf("!/")) > -1) {
- zf = new ZipFile(org.apache.tools.ant.launch.Locator
- .fromJarURI(uri), "UTF-8");
- inputStream =
- zf.getInputStream(zf.getEntry(uri.substring(pling + 1)));
- } else {
- inputStream = url.openStream();
- }
- }
-
- inputSource = new InputSource(inputStream);
- if (uri != null) {
- inputSource.setSystemId(uri);
- }
- project.log("parsing buildfile " + buildFileName + " with URI = "
- + uri + (zf != null ? " from a zip file" : ""),
- Project.MSG_VERBOSE);
-
- DefaultHandler hb = handler;
-
- parser.setContentHandler(hb);
- parser.setEntityResolver(hb);
- parser.setErrorHandler(hb);
- parser.setDTDHandler(hb);
- parser.parse(inputSource);
- } catch (SAXParseException exc) {
- Location location = new Location(exc.getSystemId(), exc.getLineNumber(), exc
- .getColumnNumber());
-
- Throwable t = exc.getException();
- if (t instanceof BuildException) {
- BuildException be = (BuildException) t;
- if (be.getLocation() == Location.UNKNOWN_LOCATION) {
- be.setLocation(location);
- }
- throw be;
- }
- throw new BuildException(exc.getMessage(), t == null ? exc : t, location);
- } catch (SAXException exc) {
- Throwable t = exc.getException();
- if (t instanceof BuildException) {
- throw (BuildException) t;
- }
- throw new BuildException(exc.getMessage(), t == null ? exc : t);
- } catch (FileNotFoundException exc) {
- throw new BuildException(exc);
- } catch (UnsupportedEncodingException exc) {
- throw new BuildException("Encoding of project file " + buildFileName + " is invalid.",
- exc);
- } catch (IOException exc) {
- throw new BuildException("Error reading project file " + buildFileName + ": "
- + exc.getMessage(), exc);
- } finally {
- FileUtils.close(inputStream);
- ZipFile.closeQuietly(zf);
- }
- }
-
- /**
- * Returns main handler
- * @return main handler
- */
- protected static AntHandler getMainHandler() {
- return mainHandler;
- }
-
- /**
- * Sets main handler
- * @param handler new main handler
- */
- protected static void setMainHandler(AntHandler handler) {
- mainHandler = handler;
- }
-
- /**
- * Returns project handler
- * @return project handler
- */
- protected static AntHandler getProjectHandler() {
- return projectHandler;
- }
-
- /**
- * Sets project handler
- * @param handler new project handler
- */
- protected static void setProjectHandler(AntHandler handler) {
- projectHandler = handler;
- }
-
- /**
- * Returns target handler
- * @return target handler
- */
- protected static AntHandler getTargetHandler() {
- return targetHandler;
- }
-
- /**
- * Sets target handler
- * @param handler new target handler
- */
- protected static void setTargetHandler(AntHandler handler) {
- targetHandler = handler;
- }
-
- /**
- * Returns element handler
- * @return element handler
- */
- protected static AntHandler getElementHandler() {
- return elementHandler;
- }
-
- /**
- * Sets element handler
- * @param handler new element handler
- */
- protected static void setElementHandler(AntHandler handler) {
- elementHandler = handler;
- }
-
- /**
- * The common superclass for all SAX event handlers used to parse
- * the configuration file.
- *
- * The context will hold all state information. At each time
- * there is one active handler for the current element. It can
- * use onStartChild() to set an alternate handler for the child.
- */
- public static class AntHandler {
- /**
- * Handles the start of an element. This base implementation does
- * nothing.
- *
- * @param uri the namespace URI for the tag
- * @param tag The name of the element being started.
- * Will not be <code>null</code>.
- * @param qname The qualified name of the element.
- * @param attrs Attributes of the element being started.
- * Will not be <code>null</code>.
- * @param context The context that this element is in.
- *
- * @exception SAXParseException if this method is not overridden, or in
- * case of error in an overridden version
- */
- public void onStartElement(String uri, String tag, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- }
-
- /**
- * Handles the start of an element. This base implementation just
- * throws an exception - you must override this method if you expect
- * child elements.
- *
- * @param uri The namespace uri for this element.
- * @param tag The name of the element being started.
- * Will not be <code>null</code>.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element being started.
- * Will not be <code>null</code>.
- * @param context The current context.
- * @return a handler (in the derived classes)
- *
- * @exception SAXParseException if this method is not overridden, or in
- * case of error in an overridden version
- */
- public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- throw new SAXParseException("Unexpected element \"" + qname + " \"", context
- .getLocator());
- }
-
- /**
- * Handle the end of a element.
- *
- * @param uri the namespace uri of the element
- * @param tag the tag of the element
- * @param qname the qualified name of the element
- * @param context the current context
- * @exception SAXParseException if an error occurs
- */
- public void onEndChild(String uri, String tag, String qname, AntXMLContext context)
- throws SAXParseException {
- }
-
- /**
- * This method is called when this element and all elements nested into it have been
- * handled. I.e., this happens at the </end_tag_of_the_element>.
- * @param uri the namespace uri for this element
- * @param tag the element name
- * @param context the current context
- */
- public void onEndElement(String uri, String tag, AntXMLContext context) {
- }
-
- /**
- * Handles text within an element. This base implementation just
- * throws an exception, you must override it if you expect content.
- *
- * @param buf A character array of the text within the element.
- * Will not be <code>null</code>.
- * @param start The start element in the array.
- * @param count The number of characters to read from the array.
- * @param context The current context.
- *
- * @exception SAXParseException if this method is not overridden, or in
- * case of error in an overridden version
- */
- public void characters(char[] buf, int start, int count, AntXMLContext context)
- throws SAXParseException {
- String s = new String(buf, start, count).trim();
-
- if (s.length() > 0) {
- throw new SAXParseException("Unexpected text \"" + s + "\"", context.getLocator());
- }
- }
-
- /**
- * Will be called every time a namespace is reached.
- * It'll verify if the ns was processed, and if not load the task definitions.
- * @param uri The namespace uri.
- */
- protected void checkNamespace(String uri) {
- }
- }
-
- /**
- * Handler for ant processing. Uses a stack of AntHandlers to
- * implement each element ( the original parser used a recursive behavior,
- * with the implicit execution stack )
- */
- public static class RootHandler extends DefaultHandler {
- private Stack antHandlers = new Stack();
- private AntHandler currentHandler = null;
- private AntXMLContext context;
-
- /**
- * Creates a new RootHandler instance.
- *
- * @param context The context for the handler.
- * @param rootHandler The handler for the root element.
- */
- public RootHandler(AntXMLContext context, AntHandler rootHandler) {
- currentHandler = rootHandler;
- antHandlers.push(currentHandler);
- this.context = context;
- }
-
- /**
- * Returns the current ant handler object.
- * @return the current ant handler.
- */
- public AntHandler getCurrentAntHandler() {
- return currentHandler;
- }
-
- /**
- * Resolves file: URIs relative to the build file.
- *
- * @param publicId The public identifier, or <code>null</code>
- * if none is available. Ignored in this
- * implementation.
- * @param systemId The system identifier provided in the XML
- * document. Will not be <code>null</code>.
- * @return an inputsource for this identifier
- */
- public InputSource resolveEntity(String publicId, String systemId) {
-
- context.getProject().log("resolving systemId: " + systemId, Project.MSG_VERBOSE);
-
- if (systemId.startsWith("file:")) {
- String path = FILE_UTILS.fromURI(systemId);
-
- File file = new File(path);
- if (!file.isAbsolute()) {
- file = FILE_UTILS.resolveFile(context.getBuildFileParent(), path);
- context.getProject().log(
- "Warning: '" + systemId + "' in " + context.getBuildFile()
- + " should be expressed simply as '" + path.replace('\\', '/')
- + "' for compliance with other XML tools", Project.MSG_WARN);
- }
- context.getProject().log("file=" + file, Project.MSG_DEBUG);
- try {
- InputSource inputSource = new InputSource(new FileInputStream(file));
- inputSource.setSystemId(FILE_UTILS.toURI(file.getAbsolutePath()));
- return inputSource;
- } catch (FileNotFoundException fne) {
- context.getProject().log(file.getAbsolutePath() + " could not be found",
- Project.MSG_WARN);
- }
-
- }
- // use default if not file or file not found
- context.getProject().log("could not resolve systemId", Project.MSG_DEBUG);
- return null;
- }
-
- /**
- * Handles the start of a project element. A project handler is created
- * and initialised with the element name and attributes.
- *
- * @param uri The namespace uri for this element.
- * @param tag The name of the element being started.
- * Will not be <code>null</code>.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element being started.
- * Will not be <code>null</code>.
- *
- * @exception org.xml.sax.SAXParseException if the tag given is not
- * <code>"project"</code>
- */
- public void startElement(String uri, String tag, String qname, Attributes attrs)
- throws SAXParseException {
- AntHandler next = currentHandler.onStartChild(uri, tag, qname, attrs, context);
- antHandlers.push(currentHandler);
- currentHandler = next;
- currentHandler.onStartElement(uri, tag, qname, attrs, context);
- }
-
- /**
- * Sets the locator in the project helper for future reference.
- *
- * @param locator The locator used by the parser.
- * Will not be <code>null</code>.
- */
- public void setDocumentLocator(Locator locator) {
- context.setLocator(locator);
- }
-
- /**
- * Handles the end of an element. Any required clean-up is performed
- * by the onEndElement() method and then the original handler is restored to the parser.
- *
- * @param uri The namespace URI for this element.
- * @param name The name of the element which is ending.
- * Will not be <code>null</code>.
- * @param qName The qualified name for this element.
- *
- * @exception SAXException in case of error (not thrown in this implementation)
- */
- public void endElement(String uri, String name, String qName) throws SAXException {
- currentHandler.onEndElement(uri, name, context);
- AntHandler prev = (AntHandler) antHandlers.pop();
- currentHandler = prev;
- if (currentHandler != null) {
- currentHandler.onEndChild(uri, name, qName, context);
- }
- }
-
- /**
- * Handle text within an element, calls currentHandler.characters.
- *
- * @param buf A character array of the test.
- * @param start The start offset in the array.
- * @param count The number of characters to read.
- * @exception SAXParseException if an error occurs
- */
- public void characters(char[] buf, int start, int count) throws SAXParseException {
- currentHandler.characters(buf, start, count, context);
- }
-
- /**
- * Start a namespace prefix to uri mapping
- *
- * @param prefix the namespace prefix
- * @param uri the namespace uri
- */
- public void startPrefixMapping(String prefix, String uri) {
- context.startPrefixMapping(prefix, uri);
- }
-
- /**
- * End a namepace prefix to uri mapping
- *
- * @param prefix the prefix that is not mapped anymore
- */
- public void endPrefixMapping(String prefix) {
- context.endPrefixMapping(prefix);
- }
- }
-
- /**
- * The main handler - it handles the <project> tag.
- *
- * @see org.apache.tools.ant.helper.ProjectHelper2.AntHandler
- */
- public static class MainHandler extends AntHandler {
-
- /**
- * Handle the project tag
- *
- * @param uri The namespace uri.
- * @param name The element tag.
- * @param qname The element qualified name.
- * @param attrs The attributes of the element.
- * @param context The current context.
- * @return The project handler that handles subelements of project
- * @exception SAXParseException if the qualified name is not "project".
- */
- public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- if (name.equals("project")
- && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
- return ProjectHelper2.projectHandler;
- }
- if (name.equals(qname)) {
- throw new SAXParseException("Unexpected element \"{" + uri
- + "}" + name + "\" {" + ANT_CORE_URI + "}" + name, context.getLocator());
- }
- throw new SAXParseException("Unexpected element \"" + qname
- + "\" " + name, context.getLocator());
- }
- }
-
- /**
- * Handler for the top level "project" element.
- */
- public static class ProjectHandler extends AntHandler {
-
- /**
- * Initialisation routine called after handler creation
- * with the element name and attributes. The attributes which
- * this handler can deal with are: <code>"default"</code>,
- * <code>"name"</code>, <code>"id"</code> and <code>"basedir"</code>.
- *
- * @param uri The namespace URI for this element.
- * @param tag Name of the element which caused this handler
- * to be created. Should not be <code>null</code>.
- * Ignored in this implementation.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element which caused this
- * handler to be created. Must not be <code>null</code>.
- * @param context The current context.
- *
- * @exception SAXParseException if an unexpected attribute is
- * encountered or if the <code>"default"</code> attribute
- * is missing.
- */
- public void onStartElement(String uri, String tag, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- String baseDir = null;
- boolean nameAttributeSet = false;
-
- Project project = context.getProject();
- // Set the location of the implicit target associated with the project tag
- context.getImplicitTarget().setLocation(new Location(context.getLocator()));
-
- /** XXX I really don't like this - the XML processor is still
- * too 'involved' in the processing. A better solution (IMO)
- * would be to create UE for Project and Target too, and
- * then process the tree and have Project/Target deal with
- * its attributes ( similar with Description ).
- *
- * If we eventually switch to ( or add support for ) DOM,
- * things will work smoothly - UE can be avoided almost completely
- * ( it could still be created on demand, for backward compatibility )
- */
-
- for (int i = 0; i < attrs.getLength(); i++) {
- String attrUri = attrs.getURI(i);
- if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
- continue; // Ignore attributes from unknown uris
- }
- String key = attrs.getLocalName(i);
- String value = attrs.getValue(i);
-
- if (key.equals("default")) {
- if (value != null && !value.equals("")) {
- if (!context.isIgnoringProjectTag()) {
- project.setDefault(value);
- }
- }
- } else if (key.equals("name")) {
- if (value != null) {
- context.setCurrentProjectName(value);
- nameAttributeSet = true;
- if (!context.isIgnoringProjectTag()) {
- project.setName(value);
- project.addReference(value, project);
- } else if (isInIncludeMode()) {
- if (!"".equals(value)
- && (getCurrentTargetPrefix() == null
- || getCurrentTargetPrefix().length() == 0)
- ) {
- // help nested include tasks
- setCurrentTargetPrefix(value);
- }
- }
- }
- } else if (key.equals("id")) {
- if (value != null) {
- // What's the difference between id and name ?
- if (!context.isIgnoringProjectTag()) {
- project.addReference(value, project);
- }
- }
- } else if (key.equals("basedir")) {
- if (!context.isIgnoringProjectTag()) {
- baseDir = value;
- }
- } else {
- // XXX ignore attributes in a different NS ( maybe store them ? )
- throw new SAXParseException("Unexpected attribute \"" + attrs.getQName(i)
- + "\"", context.getLocator());
- }
- }
-
- // XXX Move to Project ( so it is shared by all helpers )
- String antFileProp =
- MagicNames.ANT_FILE + "." + context.getCurrentProjectName();
- String dup = project.getProperty(antFileProp);
- String typeProp =
- MagicNames.ANT_FILE_TYPE + "." + context.getCurrentProjectName();
- String dupType = project.getProperty(typeProp);
- if (dup != null && nameAttributeSet) {
- Object dupFile = null;
- Object contextFile = null;
- if (MagicNames.ANT_FILE_TYPE_URL.equals(dupType)) {
- try {
- dupFile = new URL(dup);
- } catch (java.net.MalformedURLException mue) {
- throw new BuildException("failed to parse "
- + dup + " as URL while looking"
- + " at a duplicate project"
- + " name.", mue);
- }
- contextFile = context.getBuildFileURL();
- } else {
- dupFile = new File(dup);
- contextFile = context.getBuildFile();
- }
-
- if (context.isIgnoringProjectTag() && !dupFile.equals(contextFile)) {
- project.log("Duplicated project name in import. Project "
- + context.getCurrentProjectName() + " defined first in " + dup
- + " and again in " + contextFile, Project.MSG_WARN);
- }
- }
- if (nameAttributeSet) {
- if (context.getBuildFile() != null) {
- project.setUserProperty(antFileProp,
- context.getBuildFile().toString());
- project.setUserProperty(typeProp,
- MagicNames.ANT_FILE_TYPE_FILE);
- } else if (context.getBuildFileURL() != null) {
- project.setUserProperty(antFileProp,
- context.getBuildFileURL().toString());
- project.setUserProperty(typeProp,
- MagicNames.ANT_FILE_TYPE_URL);
- }
- }
- if (context.isIgnoringProjectTag()) {
- // no further processing
- return;
- }
- // set explicitly before starting ?
- if (project.getProperty("basedir") != null) {
- project.setBasedir(project.getProperty("basedir"));
- } else {
- // Default for baseDir is the location of the build file.
- if (baseDir == null) {
- project.setBasedir(context.getBuildFileParent().getAbsolutePath());
- } else {
- // check whether the user has specified an absolute path
- if ((new File(baseDir)).isAbsolute()) {
- project.setBasedir(baseDir);
- } else {
- project.setBaseDir(FILE_UTILS.resolveFile(context.getBuildFileParent(),
- baseDir));
- }
- }
- }
- project.addTarget("", context.getImplicitTarget());
- context.setCurrentTarget(context.getImplicitTarget());
- }
-
- /**
- * Handles the start of a top-level element within the project. An
- * appropriate handler is created and initialised with the details
- * of the element.
- *
- * @param uri The namespace URI for this element.
- * @param name The name of the element being started.
- * Will not be <code>null</code>.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element being started.
- * Will not be <code>null</code>.
- * @param context The context for this element.
- * @return a target or an element handler.
- *
- * @exception org.xml.sax.SAXParseException if the tag given is not
- * <code>"taskdef"</code>, <code>"typedef"</code>,
- * <code>"property"</code>, <code>"target"</code>,
- * <code>"extension-point"</code>
- * or a data type definition
- */
- public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- return (name.equals("target") || name.equals("extension-point"))
- && (uri.equals("") || uri.equals(ANT_CORE_URI))
- ? ProjectHelper2.targetHandler : ProjectHelper2.elementHandler;
- }
- }
-
- /**
- * Handler for "target" and "extension-point" elements.
- */
- public static class TargetHandler extends AntHandler {
-
- /**
- * Initialisation routine called after handler creation
- * with the element name and attributes. The attributes which
- * this handler can deal with are: <code>"name"</code>,
- * <code>"depends"</code>, <code>"if"</code>,
- * <code>"unless"</code>, <code>"id"</code> and
- * <code>"description"</code>.
- *
- * @param uri The namespace URI for this element.
- * @param tag Name of the element which caused this handler
- * to be created. Should not be <code>null</code>.
- * Ignored in this implementation.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element which caused this
- * handler to be created. Must not be <code>null</code>.
- * @param context The current context.
- *
- * @exception SAXParseException if an unexpected attribute is encountered
- * or if the <code>"name"</code> attribute is missing.
- */
- public void onStartElement(String uri, String tag, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- String name = null;
- String depends = "";
- String extensionPoint = null;
- OnMissingExtensionPoint extensionPointMissing = null;
-
- Project project = context.getProject();
- Target target = "target".equals(tag)
- ? new Target() : new ExtensionPoint();
- target.setProject(project);
- target.setLocation(new Location(context.getLocator()));
- context.addTarget(target);
- boolean isTarget = false;
- if(!(target instanceof ExtensionPoint)) {
- isTarget = true;
- }
-
- for (int i = 0; i < attrs.getLength(); i++) {
- String attrUri = attrs.getURI(i);
- if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
- continue; // Ignore attributes from unknown uris
- }
- String key = attrs.getLocalName(i);
- String value = attrs.getValue(i);
-
- if (key.equals("name")) {
- name = value;
- if ("".equals(name)) {
- throw new BuildException("name attribute must " + "not be empty");
- }
- } else if (key.equals("depends")) {
- depends = value;
- } else if (key.equals("if")) {
- target.setIf(value);
- } else if (key.equals("unless")) {
- target.setUnless(value);
- } else if (key.equals("id")) {
- if (value != null && !value.equals("")) {
- context.getProject().addReference(value, target);
- }
- } else if (key.equals("description")) {
- target.setDescription(value);
- } else if (key.equals("extensionOf")) {
- extensionPoint = value;
- } else if (key.equals("onMissingExtensionPoint")) {
- try {
- extensionPointMissing = OnMissingExtensionPoint.valueOf(value);
- } catch (IllegalArgumentException e) {
- throw new BuildException("Invalid onMissingExtensionPoint " + value);
- }
- } else {
- throw new SAXParseException("Unexpected attribute \"" + key + "\"", context
- .getLocator());
- }
- }
-
- if (name == null) {
- throw new SAXParseException("target element appears without a name attribute",
- context.getLocator());
- }
-
- String prefix = null;
- boolean isInIncludeMode =
- context.isIgnoringProjectTag() && isInIncludeMode();
- String sep = getCurrentPrefixSeparator();
-
- if (isInIncludeMode) {
- prefix = getTargetPrefix(context);
- if (prefix == null) {
- throw new BuildException("can't include build file "
- + context.getBuildFileURL()
- + ", no as attribute has been given"
- + " and the project tag doesn't"
- + " specify a name attribute");
- }
- name = prefix + sep + name;
- }
-
- // Check if this target is in the current build file
- if (context.getCurrentTargets().get(name) != null) {
- throw new BuildException("Duplicate target '" + name + "'",
- target.getLocation());
- }
- Hashtable projectTargets = project.getTargets();
- boolean usedTarget = false;
- // If the name has not already been defined define it
- if (projectTargets.containsKey(name)) {
- project.log("Already defined in main or a previous import, ignore " + name,
- Project.MSG_VERBOSE);
- } else {
- target.setName(name);
- context.getCurrentTargets().put(name, target);
- project.addOrReplaceTarget(name, target);
- usedTarget = true;
- }
-
- if (depends.length() > 0) {
- if (!isInIncludeMode) {
- target.setDepends(depends);
- } else {
- for (Iterator iter =
- Target.parseDepends(depends, name, "depends")
- .iterator();
- iter.hasNext(); ) {
- target.addDependency(prefix + sep + iter.next());
- }
- }
- }
-
- if(isTarget && name.equals(project.getBreakAt())) {
- // If the current element is a target and it is the same one as specified
- // for Ant to suspend execution at, then add an internal dependency on
- // the Debug Target
- DebugTask.createDebugTarget(project);
-
- // add this dependency to the end of the dependency list so that this target
- // executes immediately ahead of the -breakAt target
- target.addDependency(DebugTask.DEBUG_TARGET_NAME);
- }
-
- if (!isInIncludeMode && context.isIgnoringProjectTag()
- && (prefix = getTargetPrefix(context)) != null) {
- // In an imported file (and not completely
- // ignoring the project tag or having a preconfigured prefix)
- String newName = prefix + sep + name;
- Target newTarget = usedTarget ? new Target(target) : target;
- newTarget.setName(newName);
- context.getCurrentTargets().put(newName, newTarget);
- project.addOrReplaceTarget(newName, newTarget);
- }
- if (extensionPointMissing != null && extensionPoint == null) {
- throw new BuildException("onMissingExtensionPoint attribute cannot " +
- "be specified unless extensionOf is specified",
- target.getLocation());
-
- }
- if (extensionPoint != null) {
- ProjectHelper helper =
- (ProjectHelper) context.getProject().
- getReference(ProjectHelper.PROJECTHELPER_REFERENCE);
- for (Iterator iter =
- Target.parseDepends(extensionPoint, name, "extensionOf")
- .iterator();
- iter.hasNext(); ) {
- String tgName = (String) iter.next();
- if (isInIncludeMode()) {
- tgName = prefix + sep + tgName;
- }
- if (extensionPointMissing == null) {
- extensionPointMissing = OnMissingExtensionPoint.FAIL;
- }
- // defer extensionpoint resolution until the full
- // import stack has been processed
- helper.getExtensionStack().add(new String[] {
- tgName, name, extensionPointMissing.name() });
- }
- }
- }
-
- private String getTargetPrefix(AntXMLContext context) {
- String configuredValue = getCurrentTargetPrefix();
- if (configuredValue != null && configuredValue.length() == 0) {
- configuredValue = null;
- }
- if (configuredValue != null) {
- return configuredValue;
- }
-
- String projectName = context.getCurrentProjectName();
- if ("".equals(projectName)) {
- projectName = null;
- }
-
- return projectName;
- }
-
- /**
- * Handles the start of an element within a target.
- *
- * @param uri The namespace URI for this element.
- * @param name The name of the element being started.
- * Will not be <code>null</code>.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element being started.
- * Will not be <code>null</code>.
- * @param context The current context.
- * @return an element handler.
- *
- * @exception SAXParseException if an error occurs when initialising
- * the appropriate child handler
- */
- public AntHandler onStartChild(String uri, String name, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- return ProjectHelper2.elementHandler;
- }
-
- /**
- * Handle the end of the project, sets the current target of the
- * context to be the implicit target.
- *
- * @param uri The namespace URI of the element.
- * @param tag The name of the element.
- * @param context The current context.
- */
- public void onEndElement(String uri, String tag, AntXMLContext context) {
- context.setCurrentTarget(context.getImplicitTarget());
- }
- }
-
- /**
- * Handler for all project elements ( tasks, data types )
- */
- public static class ElementHandler extends AntHandler {
-
- /**
- * Constructor.
- */
- public ElementHandler() {
- }
-
- /**
- * Initialisation routine called after handler creation
- * with the element name and attributes. This configures
- * the element with its attributes and sets it up with
- * its parent container (if any). Nested elements are then
- * added later as the parser encounters them.
- *
- * @param uri The namespace URI for this element.
- * @param tag Name of the element which caused this handler
- * to be created. Must not be <code>null</code>.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element which caused this
- * handler to be created. Must not be <code>null</code>.
- * @param context The current context.
- *
- * @exception SAXParseException in case of error (not thrown in
- * this implementation)
- */
- public void onStartElement(String uri, String tag, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- RuntimeConfigurable parentWrapper = context.currentWrapper();
- Object parent = null;
-
- if (parentWrapper != null) {
- parent = parentWrapper.getProxy();
- }
-
- /* UnknownElement is used for tasks and data types - with
- delayed eval */
- UnknownElement task = new UnknownElement(tag);
- task.setProject(context.getProject());
- task.setNamespace(uri);
- task.setQName(qname);
- task.setTaskType(ProjectHelper.genComponentName(task.getNamespace(), tag));
- task.setTaskName(qname);
-
- Location location = new Location(context.getLocator().getSystemId(), context
- .getLocator().getLineNumber(), context.getLocator().getColumnNumber());
- task.setLocation(location);
- task.setOwningTarget(context.getCurrentTarget());
-
- if (parent != null) {
- // Nested element
- ((UnknownElement) parent).addChild(task);
- } else {
- // Task included in a target ( including the default one ).
- context.getCurrentTarget().addTask(task);
- }
-
- context.configureId(task, attrs);
-
- // container.addTask(task);
- // This is a nop in UE: task.init();
-
- RuntimeConfigurable wrapper = new RuntimeConfigurable(task, task.getTaskName());
-
- for (int i = 0; i < attrs.getLength(); i++) {
- String name = attrs.getLocalName(i);
- String attrUri = attrs.getURI(i);
- if (attrUri != null && !attrUri.equals("") && !attrUri.equals(uri)) {
- name = attrUri + ":" + attrs.getQName(i);
- }
- String value = attrs.getValue(i);
- // PR: Hack for ant-type value
- // an ant-type is a component name which can
- // be namespaced, need to extract the name
- // and convert from qualified name to uri/name
- if (ANT_TYPE.equals(name)
- || (ANT_CORE_URI.equals(attrUri)
- && ANT_TYPE.equals(attrs.getLocalName(i)))) {
- name = ANT_TYPE;
- int index = value.indexOf(":");
- if (index >= 0) {
- String prefix = value.substring(0, index);
- String mappedUri = context.getPrefixMapping(prefix);
- if (mappedUri == null) {
- throw new BuildException("Unable to find XML NS prefix \"" + prefix
- + "\"");
- }
- value = ProjectHelper.genComponentName(mappedUri, value
- .substring(index + 1));
- }
- }
- wrapper.setAttribute(name, value);
- }
- if (parentWrapper != null) {
- parentWrapper.addChild(wrapper);
- }
- context.pushWrapper(wrapper);
- }
-
- /**
- * Adds text to the task, using the wrapper
- *
- * @param buf A character array of the text within the element.
- * Will not be <code>null</code>.
- * @param start The start element in the array.
- * @param count The number of characters to read from the array.
- * @param context The current context.
- *
- * @exception SAXParseException if the element doesn't support text
- *
- * @see ProjectHelper#addText(Project,java.lang.Object,char[],int,int)
- */
- public void characters(char[] buf, int start, int count,
- AntXMLContext context) throws SAXParseException {
- RuntimeConfigurable wrapper = context.currentWrapper();
- wrapper.addText(buf, start, count);
- }
-
- /**
- * Handles the start of an element within a target. Task containers
- * will always use another task handler, and all other tasks
- * will always use a nested element handler.
- *
- * @param uri The namespace URI for this element.
- * @param tag The name of the element being started.
- * Will not be <code>null</code>.
- * @param qname The qualified name for this element.
- * @param attrs Attributes of the element being started.
- * Will not be <code>null</code>.
- * @param context The current context.
- * @return The handler for elements.
- *
- * @exception SAXParseException if an error occurs when initialising
- * the appropriate child handler
- */
- public AntHandler onStartChild(String uri, String tag, String qname, Attributes attrs,
- AntXMLContext context) throws SAXParseException {
- return ProjectHelper2.elementHandler;
- }
-
- /**
- * Handles the end of the element. This pops the wrapper from
- * the context.
- *
- * @param uri The namespace URI for the element.
- * @param tag The name of the element.
- * @param context The current context.
- */
- public void onEndElement(String uri, String tag, AntXMLContext context) {
- context.popWrapper();
- }
- }
-}
diff --git a/command-line-debugger/src/main/org/apache/tools/ant/taskdefs/defaults.properties b/command-line-debugger/src/main/org/apache/tools/ant/taskdefs/defaults.properties
deleted file mode 100644
index 435a1a2..0000000
--- a/command-line-debugger/src/main/org/apache/tools/ant/taskdefs/defaults.properties
+++ /dev/null
@@ -1,233 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements. See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You 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.
-#
-# standard ant tasks
-ant=org.apache.tools.ant.taskdefs.Ant
-antcall=org.apache.tools.ant.taskdefs.CallTarget
-antstructure=org.apache.tools.ant.taskdefs.AntStructure
-antversion=org.apache.tools.ant.taskdefs.condition.AntVersion
-apply=org.apache.tools.ant.taskdefs.Transform
-apt=org.apache.tools.ant.taskdefs.Apt
-augment=org.apache.tools.ant.taskdefs.AugmentReference
-available=org.apache.tools.ant.taskdefs.Available
-basename=org.apache.tools.ant.taskdefs.Basename
-bindtargets=org.apache.tools.ant.taskdefs.BindTargets
-buildnumber=org.apache.tools.ant.taskdefs.BuildNumber
-bunzip2=org.apache.tools.ant.taskdefs.BUnzip2
-bzip2=org.apache.tools.ant.taskdefs.BZip2
-checksum=org.apache.tools.ant.taskdefs.Checksum
-chmod=org.apache.tools.ant.taskdefs.Chmod
-classloader=org.apache.tools.ant.taskdefs.Classloader
-componentdef=org.apache.tools.ant.taskdefs.Componentdef
-concat=org.apache.tools.ant.taskdefs.Concat
-condition=org.apache.tools.ant.taskdefs.ConditionTask
-copy=org.apache.tools.ant.taskdefs.Copy
-cvs=org.apache.tools.ant.taskdefs.Cvs
-cvschangelog=org.apache.tools.ant.taskdefs.cvslib.ChangeLogTask
-cvspass=org.apache.tools.ant.taskdefs.CVSPass
-cvstagdiff=org.apache.tools.ant.taskdefs.cvslib.CvsTagDiff
-cvsversion=org.apache.tools.ant.taskdefs.cvslib.CvsVersion
-defaultexcludes=org.apache.tools.ant.taskdefs.DefaultExcludes
-delete=org.apache.tools.ant.taskdefs.Delete
-dependset=org.apache.tools.ant.taskdefs.DependSet
-diagnostics=org.apache.tools.ant.taskdefs.DiagnosticsTask
-dirname=org.apache.tools.ant.taskdefs.Dirname
-ear=org.apache.tools.ant.taskdefs.Ear
-echo=org.apache.tools.ant.taskdefs.Echo
-echoproperties=org.apache.tools.ant.taskdefs.optional.EchoProperties
-echoxml=org.apache.tools.ant.taskdefs.EchoXML
-exec=org.apache.tools.ant.taskdefs.ExecTask
-fail=org.apache.tools.ant.taskdefs.Exit
-filter=org.apache.tools.ant.taskdefs.Filter
-fixcrlf=org.apache.tools.ant.taskdefs.FixCRLF
-#funtest=org.apache.tools.ant.taskdefs.optional.testing.Funtest
-genkey=org.apache.tools.ant.taskdefs.GenerateKey
-get=org.apache.tools.ant.taskdefs.Get
-gunzip=org.apache.tools.ant.taskdefs.GUnzip
-gzip=org.apache.tools.ant.taskdefs.GZip
-hostinfo=org.apache.tools.ant.taskdefs.HostInfo
-import=org.apache.tools.ant.taskdefs.ImportTask
-include=org.apache.tools.ant.taskdefs.ImportTask
-input=org.apache.tools.ant.taskdefs.Input
-jar=org.apache.tools.ant.taskdefs.Jar
-java=org.apache.tools.ant.taskdefs.Java
-javac=org.apache.tools.ant.taskdefs.Javac
-javadoc=org.apache.tools.ant.taskdefs.Javadoc
-length=org.apache.tools.ant.taskdefs.Length
-loadfile=org.apache.tools.ant.taskdefs.LoadFile
-loadproperties=org.apache.tools.ant.taskdefs.LoadProperties
-loadresource=org.apache.tools.ant.taskdefs.LoadResource
-local=org.apache.tools.ant.taskdefs.Local
-macrodef=org.apache.tools.ant.taskdefs.MacroDef
-mail=org.apache.tools.ant.taskdefs.email.EmailTask
-makeurl=org.apache.tools.ant.taskdefs.MakeUrl
-manifest=org.apache.tools.ant.taskdefs.ManifestTask
-manifestclasspath=org.apache.tools.ant.taskdefs.ManifestClassPath
-mkdir=org.apache.tools.ant.taskdefs.Mkdir
-move=org.apache.tools.ant.taskdefs.Move
-nice=org.apache.tools.ant.taskdefs.Nice
-parallel=org.apache.tools.ant.taskdefs.Parallel
-patch=org.apache.tools.ant.taskdefs.Patch
-pathconvert=org.apache.tools.ant.taskdefs.PathConvert
-presetdef=org.apache.tools.ant.taskdefs.PreSetDef
-projecthelper=org.apache.tools.ant.taskdefs.ProjectHelperTask
-property=org.apache.tools.ant.taskdefs.Property
-propertyhelper=org.apache.tools.ant.taskdefs.PropertyHelperTask
-record=org.apache.tools.ant.taskdefs.Recorder
-replace=org.apache.tools.ant.taskdefs.Replace
-resourcecount=org.apache.tools.ant.taskdefs.ResourceCount
-retry=org.apache.tools.ant.taskdefs.Retry
-rmic=org.apache.tools.ant.taskdefs.Rmic
-sequential=org.apache.tools.ant.taskdefs.Sequential
-signjar=org.apache.tools.ant.taskdefs.SignJar
-sleep=org.apache.tools.ant.taskdefs.Sleep
-sql=org.apache.tools.ant.taskdefs.SQLExec
-subant=org.apache.tools.ant.taskdefs.SubAnt
-sync=org.apache.tools.ant.taskdefs.Sync
-tar=org.apache.tools.ant.taskdefs.Tar
-taskdef=org.apache.tools.ant.taskdefs.Taskdef
-tempfile=org.apache.tools.ant.taskdefs.TempFile
-touch=org.apache.tools.ant.taskdefs.Touch
-tstamp=org.apache.tools.ant.taskdefs.Tstamp
-truncate=org.apache.tools.ant.taskdefs.Truncate
-typedef=org.apache.tools.ant.taskdefs.Typedef
-unjar=org.apache.tools.ant.taskdefs.Expand
-untar=org.apache.tools.ant.taskdefs.Untar
-unwar=org.apache.tools.ant.taskdefs.Expand
-unzip=org.apache.tools.ant.taskdefs.Expand
-uptodate=org.apache.tools.ant.taskdefs.UpToDate
-waitfor=org.apache.tools.ant.taskdefs.WaitFor
-war=org.apache.tools.ant.taskdefs.War
-whichresource=org.apache.tools.ant.taskdefs.WhichResource
-xmlproperty=org.apache.tools.ant.taskdefs.XmlProperty
-xslt=org.apache.tools.ant.taskdefs.XSLTProcess
-zip=org.apache.tools.ant.taskdefs.Zip
-
-# optional tasks
-antlr=org.apache.tools.ant.taskdefs.optional.ANTLR
-attrib=org.apache.tools.ant.taskdefs.optional.windows.Attrib
-blgenclient=org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient
-cab=org.apache.tools.ant.taskdefs.optional.Cab
-cccheckin=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin
-cccheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout
-cclock=org.apache.tools.ant.taskdefs.optional.clearcase.CCLock
-ccmcheckin=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin
-ccmcheckintask=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault
-ccmcheckout=org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout
-ccmcreatetask=org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask
-ccmkattr=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkattr
-ccmkbl=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkbl
-ccmkdir=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkdir
-ccmkelem=org.apache.tools.ant.taskdefs.optional.clearcase.CCMkelem
-ccmklabel=org.apache.tools.ant.taskdefs.optional.clearcase.CCMklabel
-ccmklbtype=org.apache.tools.ant.taskdefs.optional.clearcase.CCMklbtype
-ccmreconfigure=org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure
-ccrmtype=org.apache.tools.ant.taskdefs.optional.clearcase.CCRmtype
-ccuncheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout
-ccunlock=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnlock
-ccupdate=org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate
-chgrp=org.apache.tools.ant.taskdefs.optional.unix.Chgrp
-chown=org.apache.tools.ant.taskdefs.optional.unix.Chown
-ddcreator=org.apache.tools.ant.taskdefs.optional.ejb.DDCreator
-depend=org.apache.tools.ant.taskdefs.optional.depend.Depend
-ejbc=org.apache.tools.ant.taskdefs.optional.ejb.Ejbc
-ejbjar=org.apache.tools.ant.taskdefs.optional.ejb.EjbJar
-ftp=org.apache.tools.ant.taskdefs.optional.net.FTP
-image=org.apache.tools.ant.taskdefs.optional.image.Image
-iplanet-ejbc=org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask
-jarlib-available=org.apache.tools.ant.taskdefs.optional.extension.JarLibAvailableTask
-jarlib-display=org.apache.tools.ant.taskdefs.optional.extension.JarLibDisplayTask
-jarlib-manifest=org.apache.tools.ant.taskdefs.optional.extension.JarLibManifestTask
-jarlib-resolve=org.apache.tools.ant.taskdefs.optional.extension.JarLibResolveTask
-javacc=org.apache.tools.ant.taskdefs.optional.javacc.JavaCC
-javah=org.apache.tools.ant.taskdefs.optional.Javah
-jdepend=org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask
-jjdoc=org.apache.tools.ant.taskdefs.optional.javacc.JJDoc
-jjtree=org.apache.tools.ant.taskdefs.optional.javacc.JJTree
-junit=org.apache.tools.ant.taskdefs.optional.junit.JUnitTask
-junitreport=org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator
-native2ascii=org.apache.tools.ant.taskdefs.optional.Native2Ascii
-netrexxc=org.apache.tools.ant.taskdefs.optional.NetRexxC
-p4add=org.apache.tools.ant.taskdefs.optional.perforce.P4Add
-p4change=org.apache.tools.ant.taskdefs.optional.perforce.P4Change
-p4counter=org.apache.tools.ant.taskdefs.optional.perforce.P4Counter
-p4delete=org.apache.tools.ant.taskdefs.optional.perforce.P4Delete
-p4edit=org.apache.tools.ant.taskdefs.optional.perforce.P4Edit
-p4fstat=org.apache.tools.ant.taskdefs.optional.perforce.P4Fstat
-p4have=org.apache.tools.ant.taskdefs.optional.perforce.P4Have
-p4integrate=org.apache.tools.ant.taskdefs.optional.perforce.P4Integrate
-p4label=org.apache.tools.ant.taskdefs.optional.perforce.P4Label
-p4labelsync=org.apache.tools.ant.taskdefs.optional.perforce.P4Labelsync
-p4reopen=org.apache.tools.ant.taskdefs.optional.perforce.P4Reopen
-p4resolve=org.apache.tools.ant.taskdefs.optional.perforce.P4Resolve
-p4revert=org.apache.tools.ant.taskdefs.optional.perforce.P4Revert
-p4submit=org.apache.tools.ant.taskdefs.optional.perforce.P4Submit
-p4sync=org.apache.tools.ant.taskdefs.optional.perforce.P4Sync
-propertyfile=org.apache.tools.ant.taskdefs.optional.PropertyFile
-pvcs=org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs
-replaceregexp=org.apache.tools.ant.taskdefs.optional.ReplaceRegExp
-rexec=org.apache.tools.ant.taskdefs.optional.net.RExecTask
-rpm=org.apache.tools.ant.taskdefs.optional.Rpm
-schemavalidate=org.apache.tools.ant.taskdefs.optional.SchemaValidate
-scp=org.apache.tools.ant.taskdefs.optional.ssh.Scp
-script=org.apache.tools.ant.taskdefs.optional.Script
-scriptdef=org.apache.tools.ant.taskdefs.optional.script.ScriptDef
-serverdeploy=org.apache.tools.ant.taskdefs.optional.j2ee.ServerDeploy
-setproxy=org.apache.tools.ant.taskdefs.optional.net.SetProxy
-soscheckin=org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin
-soscheckout=org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout
-sosget=org.apache.tools.ant.taskdefs.optional.sos.SOSGet
-soslabel=org.apache.tools.ant.taskdefs.optional.sos.SOSLabel
-sound=org.apache.tools.ant.taskdefs.optional.sound.SoundTask
-splash=org.apache.tools.ant.taskdefs.optional.splash.SplashTask
-sshexec=org.apache.tools.ant.taskdefs.optional.ssh.SSHExec
-sshsession=org.apache.tools.ant.taskdefs.optional.ssh.SSHSession
-stcheckin=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckin
-stcheckout=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckout
-stlabel=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamLabel
-stlist=org.apache.tools.ant.taskdefs.optional.starteam.StarTeamList
-symlink=org.apache.tools.ant.taskdefs.optional.unix.Symlink
-telnet=org.apache.tools.ant.taskdefs.optional.net.TelnetTask
-translate=org.apache.tools.ant.taskdefs.optional.i18n.Translate
-verifyjar=org.apache.tools.ant.taskdefs.VerifyJar
-vssadd=org.apache.tools.ant.taskdefs.optional.vss.MSVSSADD
-vsscheckin=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN
-vsscheckout=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT
-vsscp=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCP
-vsscreate=org.apache.tools.ant.taskdefs.optional.vss.MSVSSCREATE
-vssget=org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET
-vsshistory=org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY
-vsslabel=org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL
-wljspc=org.apache.tools.ant.taskdefs.optional.jsp.WLJspc
-wlrun=org.apache.tools.ant.taskdefs.optional.ejb.WLRun
-wlstop=org.apache.tools.ant.taskdefs.optional.ejb.WLStop
-xmlvalidate=org.apache.tools.ant.taskdefs.optional.XMLValidateTask
-
-
-# deprecated ant tasks (kept for back compatibility)
-copydir=org.apache.tools.ant.taskdefs.Copydir
-copyfile=org.apache.tools.ant.taskdefs.Copyfile
-copypath=org.apache.tools.ant.taskdefs.CopyPath
-deltree=org.apache.tools.ant.taskdefs.Deltree
-execon=org.apache.tools.ant.taskdefs.ExecuteOn
-javadoc2=org.apache.tools.ant.taskdefs.Javadoc
-jlink=org.apache.tools.ant.taskdefs.optional.jlink.JlinkTask
-jspc=org.apache.tools.ant.taskdefs.optional.jsp.JspC
-mimemail=org.apache.tools.ant.taskdefs.optional.net.MimeMail
-rename=org.apache.tools.ant.taskdefs.Rename
-renameext=org.apache.tools.ant.taskdefs.optional.RenameExtensions
-starteam=org.apache.tools.ant.taskdefs.optional.scm.AntStarTeamCheckOut
-style=org.apache.tools.ant.taskdefs.XSLTProcess
-debug=org.apache.tools.ant.DebugTask
\ No newline at end of file