From 043365afe42f0cd64929a2e7834f1d8b5bb7a138 Mon Sep 17 00:00:00 2001 From: Peter Donald Date: Mon, 18 Dec 2000 05:59:51 +0000 Subject: [PATCH] A new proposal to shake the tree that unifies everything to a task. Submitted By: "James Cook" git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268364 13f79535-47bb-0310-9956-ffa450edef68 --- proposal/frantic/build.bat | 55 +++ .../src/org/apache/ant/AntException.java | 65 +++ .../apache/ant/engine/AntEngineListener.java | 72 ++++ .../src/org/apache/ant/engine/AntEvent.java | 80 ++++ .../ant/engine/DefaultEngineListener.java | 166 ++++++++ .../ant/engine/HierarchicalHashtable.java | 62 +++ .../src/org/apache/ant/engine/TaskEngine.java | 124 ++++++ .../org/apache/ant/engine/TaskEngineImpl.java | 397 ++++++++++++++++++ .../src/org/apache/ant/tasks/BaseTask.java | 189 +++++++++ .../src/org/apache/ant/tasks/Task.java | 179 ++++++++ .../org/apache/ant/tasks/build/Project.java | 113 +++++ .../org/apache/ant/tasks/build/Target.java | 123 ++++++ .../org/apache/ant/tasks/util/Property.java | 97 +++++ .../apache/ant/tasks/util/PropertyDump.java | 81 ++++ .../src/org/apache/ant/test/SimpleTest.java | 146 +++++++ 15 files changed, 1949 insertions(+) create mode 100755 proposal/frantic/build.bat create mode 100644 proposal/frantic/src/org/apache/ant/AntException.java create mode 100644 proposal/frantic/src/org/apache/ant/engine/AntEngineListener.java create mode 100644 proposal/frantic/src/org/apache/ant/engine/AntEvent.java create mode 100644 proposal/frantic/src/org/apache/ant/engine/DefaultEngineListener.java create mode 100644 proposal/frantic/src/org/apache/ant/engine/HierarchicalHashtable.java create mode 100644 proposal/frantic/src/org/apache/ant/engine/TaskEngine.java create mode 100644 proposal/frantic/src/org/apache/ant/engine/TaskEngineImpl.java create mode 100644 proposal/frantic/src/org/apache/ant/tasks/BaseTask.java create mode 100644 proposal/frantic/src/org/apache/ant/tasks/Task.java create mode 100644 proposal/frantic/src/org/apache/ant/tasks/build/Project.java create mode 100644 proposal/frantic/src/org/apache/ant/tasks/build/Target.java create mode 100644 proposal/frantic/src/org/apache/ant/tasks/util/Property.java create mode 100644 proposal/frantic/src/org/apache/ant/tasks/util/PropertyDump.java create mode 100644 proposal/frantic/src/org/apache/ant/test/SimpleTest.java diff --git a/proposal/frantic/build.bat b/proposal/frantic/build.bat new file mode 100755 index 000000000..da96ae4cc --- /dev/null +++ b/proposal/frantic/build.bat @@ -0,0 +1,55 @@ +@echo off +rem -------------------------------------------------------------------------- +rem build.bat - Build Script for Frantic (lifted from Tomcat...thx guys) +rem +rem Environment Variable Prerequisites: +rem +rem JAVA_HOME Must point at your Java Development Kit [REQUIRED] +rem +rem --------------------------------------------------------------------------- + + +rem ----- Save Environment Variables ------------------------------------------ + +set _CLASSPATH=%CLASSPATH% +set _CLASSES=%CLASSES% + +rem ----- Verify and Set Required Environment Variables ----------------------- + +if not "%JAVA_HOME%" == "" goto gotJavaHome +echo You must set JAVA_HOME to point at your Java Development Kit installation +goto cleanup +:gotJavaHome + +rem ----- Set Up The Runtime Classpath ---------------------------------------- + +if not "%CLASSPATH%" == "" set CLASSPATH=%CLASSPATH%; +set CLASSPATH=%CLASSPATH%;./src + +rem ----- Execute The Requested Build ----------------------------------------- + +if not exist dist mkdir dist +if not exist dist\lib mkdir dist\lib +if not exist dist\lib\classes mkdir dist\lib\classes +if not exist dist\doc mkdir dist\doc +if not exist dist\doc\api mkdir dist\doc\api + +set CLASSES=dist\lib\classes + +%JAVA_HOME%\bin\javac -d %CLASSES% src/org/apache/ant/test/*.java +%JAVA_HOME%\bin\jar cvf dist\lib\frantic.jar -C dist\lib\classes . + +xcopy website\*.html dist\doc /s /y +xcopy website\*.gif dist\doc /s /y + +%JAVA_HOME%\bin\javadoc -protected -sourcepath src -d dist\doc\api -author org.apache.ant org.apache.ant.engine org.apache.ant.tasks org.apache.ant.tasks.build org.apache.ant.tasks.util + +rem ----- Restore Environment Variables --------------------------------------- +:cleanup +set CLASSPATH=%_CLASSPATH% +set CLASSES=%_CLASSES% +set _CLASSPATH= +set _CLASSES= + +:finish + diff --git a/proposal/frantic/src/org/apache/ant/AntException.java b/proposal/frantic/src/org/apache/ant/AntException.java new file mode 100644 index 000000000..17763b14d --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/AntException.java @@ -0,0 +1,65 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant; + +public class AntException extends Exception { + + public AntException() { + super(); + } + + public AntException(String message) { + super(message); + } +} diff --git a/proposal/frantic/src/org/apache/ant/engine/AntEngineListener.java b/proposal/frantic/src/org/apache/ant/engine/AntEngineListener.java new file mode 100644 index 000000000..7839d6469 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/engine/AntEngineListener.java @@ -0,0 +1,72 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.engine; + + +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.tasks.Task; + +public interface AntEngineListener extends EventListener { + + void engineStart(AntEvent e); + void engineFinish(AntEvent e); + + void taskStart(AntEvent e); + void taskExecute(AntEvent e); + void taskFinish(AntEvent e); + void taskMessage(AntEvent e, String message); + void taskException(AntEvent e, AntException exception); + +} diff --git a/proposal/frantic/src/org/apache/ant/engine/AntEvent.java b/proposal/frantic/src/org/apache/ant/engine/AntEvent.java new file mode 100644 index 000000000..f14d1f7a5 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/engine/AntEvent.java @@ -0,0 +1,80 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.engine; + + +import java.util.EventObject; +import org.apache.ant.tasks.Task; + +public class AntEvent extends EventObject { + + Task task; + + public AntEvent(Object source) { + this(source, null); + } + + public AntEvent(Object source, Task task) { + super(source); + this.task = task; + } + + public Task getTask() { + return task; + } + + public void setTask(Task task) { + this.task = task; + } +} diff --git a/proposal/frantic/src/org/apache/ant/engine/DefaultEngineListener.java b/proposal/frantic/src/org/apache/ant/engine/DefaultEngineListener.java new file mode 100644 index 000000000..6ccda435b --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/engine/DefaultEngineListener.java @@ -0,0 +1,166 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.engine; + + +import java.io.*; +import java.text.*; +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.tasks.Task; + +public class DefaultEngineListener implements AntEngineListener { + + protected PrintStream outputStream; + protected long startTime; + + protected StringBuffer sb = new StringBuffer(); + protected int indentSpaces = 4; + protected boolean indent = true; + protected int curIndent = 0; + + protected SimpleDateFormat timestamp = new SimpleDateFormat("HH:mm:ss:SSS"); + + public DefaultEngineListener() { + this(System.out); + } + + public DefaultEngineListener(PrintStream outputStream) { + this.outputStream = outputStream; + } + + public void setIndentSpaces(int spaces) { + this.indentSpaces = spaces; + } + + public int getIndentSpaces() { + return indentSpaces; + } + + public void setIndent(boolean on) { + this.indent = on; + } + + public boolean isIndent() { + return indent; + } + + protected String padLeft(String s, int length) { + sb.setLength(0); + sb.append(s); + while (sb.length() < length) { + sb.insert(0, ' '); + } + return sb.toString(); + } + + protected void output(String message) { + if (!indent) { + outputStream.println(message); + return; + } + + // shouldn't happen, but let's be on the safe side + if (curIndent < 0) { + curIndent = 0; + } + + outputStream.println( + padLeft(message, message.length() + (indentSpaces * curIndent))); + } + + //////////////////////////////////////////////////////////////////////////// + // AntEngineListener Implementation // + //////////////////////////////////////////////////////////////////////////// + + public void engineStart(AntEvent e) { + Date now = new Date(); + output("Engine Started: " + timestamp.format(now)); + startTime = now.getTime(); + } + + public void engineFinish(AntEvent e) { + Date now = new Date(); + long elapsed = System.currentTimeMillis() - startTime; + + output("Engine Finished: " + timestamp.format(now)); + output("Elapsed Time: " + (elapsed / 1000F) + " seconds"); + } + + public void taskStart(AntEvent e) { + output("Task Started: " + e.getTask().getFullyQualifiedName()); + curIndent++; + } + + public void taskExecute(AntEvent e){ + output("Task Execution: " + e.getTask().getFullyQualifiedName()); + } + + public void taskFinish(AntEvent e){ + curIndent--; + output("Task Finished: " + e.getTask().getFullyQualifiedName()); + } + + public void taskMessage(AntEvent e, String message){ + curIndent++; + output("Task Message: " + e.getTask().getFullyQualifiedName() + ": " + + message); + curIndent--; + } + + public void taskException(AntEvent e, AntException exception){ + output("Task Exception: " + e.getTask().getFullyQualifiedName() + ": " + + exception.getMessage()); + } +} diff --git a/proposal/frantic/src/org/apache/ant/engine/HierarchicalHashtable.java b/proposal/frantic/src/org/apache/ant/engine/HierarchicalHashtable.java new file mode 100644 index 000000000..5876af3b5 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/engine/HierarchicalHashtable.java @@ -0,0 +1,62 @@ +package org.apache.ant.engine; + +import java.util.*; + +public class HierarchicalHashtable extends Hashtable { + + private HierarchicalHashtable parent; + + public HierarchicalHashtable() { + this(null); + } + + public HierarchicalHashtable(HierarchicalHashtable parent) { + super(); + this.parent = parent; + } + + public HierarchicalHashtable getParent() { + return parent; + } + + public void setParent(HierarchicalHashtable parent) { + this.parent = parent; + } + + public List getPropertyNames() { + ArrayList list = new ArrayList(); + + Enumeration e = keys(); + while (e.hasMoreElements()) { + list.add(e.nextElement()); + } + + if (getParent() != null) { + list.addAll(getParent().getPropertyNames()); + } + + return list; + } + + public Object getPropertyValue(String name) { + Object value = get(name); + if (value == null && getParent() != null) { + return getParent().getPropertyValue(name); + } + return value; + } + + public void setPropertyValue(String name, Object value) { + put(name, value); + } + + public void removePropertyValue(String name) { + Object value = get(name); + if (value == null && getParent() != null) { + getParent().removePropertyValue(name); + } + if (value != null) { + remove(name); + } + } +} diff --git a/proposal/frantic/src/org/apache/ant/engine/TaskEngine.java b/proposal/frantic/src/org/apache/ant/engine/TaskEngine.java new file mode 100644 index 000000000..6e35fceb2 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/engine/TaskEngine.java @@ -0,0 +1,124 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.engine; + + +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.tasks.Task; + +/** + * The TaskEngine interface defines the methods that a TaskEngine are required + * to implement. This interface is also passed to each Task in order for them to + * get access to some utility functions like inserting a new Task during a run, + * or forcing the execution path of Tasks to be modified. + */ +public interface TaskEngine { + + void addAntEngineListener(AntEngineListener listener); + + void removeAntEngineListener(AntEngineListener listener); + + void execute(Task task) throws AntException; + + void execute(Task root, Task task) throws AntException; + + void message(Task task, String message); + + Task getNextExecuteTask(); + + /** + * Returns a list of all property names that the current task stack is aware + * of. This is a recursive list of all property names. + */ + List getPropertyNames(); + + /** + * May be called to obtain property values that have been defined. Property + * values are maintained in a hierarchical manner as each task is executed. + * When a property is requested, if the current execution level does not + * contain the property, the execution parent is then queried. This + * continues until there is no where else to go! + *

+ * Maybe this should be a Hashtable implementation and be able to return + * Object? Is that a little overkill considering these values will usually + * be Strings? Perhaps someone will have a farfetched idea of storing a + * Task in a property? + */ + Object getPropertyValue(String name); + + /** + * Adds the name-value pair to this execution stack property list. If the + * property is declared in parent tasks, I don't really see a reason for not + * adding it again to this execution list. This would achieve a nice scoped + * parameter list that is dictated by nesting levels. + *

+ * This is against the current Ant (1.2) specification, but I'm not sure why + * that restriction was there. It would be simple to implement here if it + * again required. + */ + void setPropertyValue(String name, Object value); + + /** + * Removes the given property from the property list. I haven't thought too + * much about the rules behind this method. My current thinking is that the + * property is removed no matter what level of the execution stack the + * property was defined in. I think this should be good in most cases. If it + * ever surfaces that the property should just be unavailable for this stack + * level (and other's below it), then the implementation can be modified to + * keep a list of these "unavailable" properties. + */ + void removePropertyValue(String name); + +} diff --git a/proposal/frantic/src/org/apache/ant/engine/TaskEngineImpl.java b/proposal/frantic/src/org/apache/ant/engine/TaskEngineImpl.java new file mode 100644 index 000000000..d1f574953 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/engine/TaskEngineImpl.java @@ -0,0 +1,397 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.engine; + + +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.tasks.Task; + +/** + * The engine that actually invokes each Task. In addition to specifying a Task + * to execute, it may be desirable to specify the root Task that will define + * an execution cycle. + */ +public class TaskEngineImpl implements TaskEngine { + + /** + * Analagous to a call stack, but with Tasks. + */ + protected Stack taskStack = new Stack();; + + /** + * As the task stack is built, a mirror representation will also be + * contructed that will hold property values. + */ + protected Stack propertyStack = new Stack(); + + /** + * Keeps track of AntEngineListeners. We don't have to use Vector because we + * take care of synchronization on the add, remove, and iteration operations. + */ + protected ArrayList listenerList = new ArrayList(); + + private int engineLevel = 0; + + /** + * Constructor is private so it cannot be instantiated. Users of this class + * will get an instance by using the getTaskEngine() method. This will allow + * us to have a simple Factory implementation. We may use a Singleton + * implementation, or a collection pool. The choice is up to us. + */ + private TaskEngineImpl() { + super(); + } + + /** + * Return a usable instance of a TaskEngine to the requestor. Nothing + * sophisticated yet, simple doles out a new instance each time. + */ + public static TaskEngine getTaskEngine() { + return new TaskEngineImpl(); + } + + /** + * Walk the list of Tasks backwards until the root is reached. Keep track of + * the Tasks along the way in a Stack. Return null if the root Task is not a + * parent of the provided Task. + */ + protected Stack getTaskStack(Task root, Task task) { + Stack stack = new Stack(); + while (task != null) { + stack.push(task); + if (task == root) { + return stack; + } + task = task.getParent(); + } + return null; + } + + /** + * Returns the next Task to be executed from the taskStack. The task is not + * removed from the Stack. + */ + public Task getNextExecuteTask() { + try { + return (Task)taskStack.peek(); + } catch (EmptyStackException esx) { + return null; + } + } + + /** + * If no root is specified, we will assume that the user wants to execute + * the Task with no root. This is accomplished by using the Task parameter + * as its own root. + */ + public void execute(Task task) throws AntException { + execute(task, task); + } + + /** + * This is the workhorse, however it has been made to be very simple. Given + * the ability to specify a path between root and the target Task, we build + * a trail of Tasks to connect the two. Next we execute each Task on the way + * between the two Tasks. Once we arrive at the Task to execute, we execute + * all of its chlidren. + */ + public void execute(Task root, Task task) throws AntException { + fireEngineStart(); + try { + taskStack = getTaskStack(root, task);; + if (taskStack == null) { + throw new AntException( + "The execution root Task is not an ancestor of the execution Task."); + } + + // Pop thru the stack and execute each Task we come across. + while (!taskStack.isEmpty()) { + executeTask(taskStack); + } + } finally { + fireEngineFinish(); + } + } + + /** + * A recursive routine that allows all Tasks in the stack to be executed. At + * the same time, the stack may grow to include new Tasks. + */ + protected void executeTask(Stack taskStack) throws AntException { + Task task = (Task)taskStack.pop(); + + fireTaskStart(task); + try { + // Add a new property holder for this task to the property stack. Note + // that the parent of the new holder is the current stack head. + if (task.isPropertyContainer()) { + if (propertyStack.isEmpty()) { + propertyStack.push(new HierarchicalHashtable()); + } else { + propertyStack.push(new HierarchicalHashtable( + (HierarchicalHashtable)propertyStack.peek())); + } + + } + + // Allow Task to do whatever it may need to do before touching its + // children. + task.init(this); + + // Iterate the Task's children and execute any priority Tasks. + Task[] tasks = task.getChildren(); + for (int i = 0, c = tasks.length; i < c; i++) { + if (tasks[i].getExecutionMode() == Task.EXECUTION_MODE_PRIORITY) { + taskStack.push(tasks[i]); + executeTask(taskStack); + } + } + + // Allow the Task to validate. + task.validate(); + + // Finally, execute the Task. + fireTaskExecute(task); + task.execute(this); + + // We can discard the no londer needed property holder. + if (task.isPropertyContainer()) { + propertyStack.pop(); + } + + } catch (AntException ax) { + fireTaskException(task, ax); + } finally { + fireTaskFinish(task); + } + } + + /** + * Causes an AntEvent to be generated and fired to all listeners. + */ + public void message(Task task, String message) { + fireTaskMessage(task, message); + } + + //////////////////////////////////////////////////////////////////////////// + // Listener Support // + //////////////////////////////////////////////////////////////////////////// + + public synchronized void addAntEngineListener(AntEngineListener listener) { + if (!listenerList.contains(listener)) { + listenerList.add(listener); + } + } + + public synchronized void removeAntEngineListener(AntEngineListener listener) { + if (listenerList.contains(listener)) { + listenerList.remove(listener); + } + } + + protected synchronized void fireEngineStart() { + if (engineLevel++ > 0) return; + AntEvent e = new AntEvent(this); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).engineStart(e); + } + + } + + protected synchronized void fireEngineFinish() { + if (--engineLevel > 0) return; + AntEvent e = new AntEvent(this); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).engineFinish(e); + } + + } + + protected synchronized void fireTaskStart(Task task) { + AntEvent e = new AntEvent(this, task); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).taskStart(e); + } + + } + + protected synchronized void fireTaskExecute(Task task) { + AntEvent e = new AntEvent(this, task); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).taskExecute(e); + } + + } + + protected synchronized void fireTaskFinish(Task task) { + AntEvent e = new AntEvent(this, task); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).taskFinish(e); + } + + } + + protected synchronized void fireTaskMessage(Task task, String message) { + AntEvent e = new AntEvent(this, task); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).taskMessage(e, message); + } + + } + + protected synchronized void fireTaskException(Task task, AntException exception) { + AntEvent e = new AntEvent(this, task); + for (int i = 0; i < listenerList.size(); i++) { + ((AntEngineListener)listenerList.get(i)).taskException(e, exception); + } + + } + + //////////////////////////////////////////////////////////////////////////// + // Property Support Methods // + //////////////////////////////////////////////////////////////////////////// + + /** + * This is the routine that will perform key substitution. Phrase will come + * in as "src/${someparam}" and be converted to the appropriate "normalized" + * string. I suppose while I'm doing this we should support phrases with + * nested keys, such as "src/${build${token}}". Also, we should properly + * handle cases where ${someparam} will evaluate to ${anotherparam}. + *

+ * One thing that will be different from the Ant 1.2 mechanismoccurs when a + * parameter value is not found. The substitution routine inserts it back in + * the phrase unchanged. I have opted to insert a zero-length string + * instead. + *

+ * I should add a switch to the engine that will give the user the ability + * to throw an exception if a key is not found. Pretty easy, except this + * method is a strange place for an AntException to be thrown. Perhaps I + * should use a RuntimeException instead... + *

+ * A brief rundown on the logic here: + * I check for the first instances of a key prefix. + * If none found we return the phrase as is. + * If key prefix is found get location of next key prefix and suffix. + * If suffix is found first, we have found a key. + * If there is no suffix, we return the phrase. + */ + static final String KEY_PREFIX = "${"; + static final String KEY_SUFFIX = "}"; + protected String substitute(String phrase) { + StringBuffer sb = new StringBuffer(phrase); + int startPoint = 0; + while (startPoint >= 0 && startPoint < phrase.length()) { + int pre1 = startPoint + phrase.substring(startPoint).indexOf(KEY_PREFIX); + if (pre1 < 0) break; + int suf1 = phrase.substring(pre1 + KEY_PREFIX.length()).indexOf(KEY_SUFFIX); + if (suf1 < 0) break; + suf1 = suf1 + pre1 + KEY_PREFIX.length(); + int pre2 = phrase.substring(pre1 + KEY_PREFIX.length()).indexOf(KEY_PREFIX); + if (pre2 < 0) { + pre2 = phrase.length() + 1; + } else { + pre2 = pre2 + pre1 + KEY_PREFIX.length(); + } + + if (suf1 < pre2) { + // we have found a token + String key = sb.substring(pre1 + KEY_PREFIX.length(), suf1); + sb.delete(pre1, suf1 + 1); + Object value = getPropertyValueNoSubstitution(key); + if (value != null) { + sb.insert(pre1, value.toString()); + } + return substitute(sb.toString()); + } + startPoint = pre2; + } + return sb.toString(); + } + + public List getPropertyNames() { + if (propertyStack.isEmpty()) return new ArrayList(); + HierarchicalHashtable hash = (HierarchicalHashtable)propertyStack.peek(); + return hash.getPropertyNames(); + } + + public Object getPropertyValue(String name) { + if (propertyStack.isEmpty()) return null; + HierarchicalHashtable hash = (HierarchicalHashtable)propertyStack.peek(); + Object result = hash.getPropertyValue(name); + if (result instanceof String) { + return substitute((String)result); + } else { + return result; + } + } + + protected Object getPropertyValueNoSubstitution(String name) { + if (propertyStack.isEmpty()) return null; + HierarchicalHashtable hash = (HierarchicalHashtable)propertyStack.peek(); + return hash.getPropertyValue(name); + } + + public void setPropertyValue(String name, Object value) { + if (propertyStack.isEmpty()) return; + HierarchicalHashtable hash = (HierarchicalHashtable)propertyStack.peek(); + hash.setPropertyValue(name, value); + } + + public void removePropertyValue(String name) { + if (propertyStack.isEmpty()) return; + HierarchicalHashtable hash = (HierarchicalHashtable)propertyStack.peek(); + hash.remove(name); + } +} diff --git a/proposal/frantic/src/org/apache/ant/tasks/BaseTask.java b/proposal/frantic/src/org/apache/ant/tasks/BaseTask.java new file mode 100644 index 000000000..3cf4a2af7 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/tasks/BaseTask.java @@ -0,0 +1,189 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.tasks; + + + +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.engine.TaskEngine; +import org.apache.ant.tasks.Task; + +public abstract class BaseTask implements Task { + + protected Task parent; + protected ArrayList children = new ArrayList(); + protected String taskName; + protected Properties properties = new Properties(); + + public BaseTask() { + super(); + } + + public void init(TaskEngine engine) throws AntException { + } + + public void execute(TaskEngine engine) throws AntException { + } + +// abstract public String getTaskTag(); + + public void validate() throws AntException {} + + public String getFullyQualifiedName() { + if (getParent() == null) return Task.NAME_SEPARATOR + taskName; + return getParent().getFullyQualifiedName() + Task.NAME_SEPARATOR + taskName; + } + + public int hashCode() { + return getFullyQualifiedName().hashCode(); + } + + public String getTaskName() { + return taskName; + } + + public void setTaskName(String taskName) { + this.taskName = taskName; + } + + public int getExecutionMode() { + return Task.EXECUTION_MODE_PRIORITY; + } + + public String getAttributeValue(String name) { + /**@todo: Implement this org.apache.ant.Task method*/ + throw new java.lang.UnsupportedOperationException("Method getAttributeValue() not yet implemented."); + } + + public Task getParent() { + return parent; + } + + /** + * We have to trust the developers to not screw up the hierarchy by changing + * the parent of a Task when it is a child of another. + */ + public void setParent(Task parent) { + this.parent = parent; + } + + public Task[] getChildren() { + return (Task[])children.toArray(new Task[children.size()]); + } + + public void addChild(Task task) { + children.add(task); + task.setParent(this); + } + + public void removeChild(Task task) { + children.remove(task); + } + + public Task getRootTask() { + if (getParent() != null) { + return getParent().getRootTask(); + } + return this; + } + + protected Task getTaskByName(String taskName) { + Task[] tasks = getChildren(); + for (int i = 0, c = tasks.length; i < c; i++) { + if (tasks[i].getTaskName().equals(taskName)) { + return tasks[i]; + } + } + return null; + } + + public Task getTask(String taskPath) { + taskPath = taskPath.trim(); + int slashPos = taskPath.indexOf("/"); + + // starts with '/' + if (slashPos == 0) { + return getRootTask().getTask(taskPath.substring(slashPos + 1)); + } else + + // starts with '../' + if (taskPath.startsWith("../") || taskPath.equals("..")) { + return getParent().getTask(taskPath.substring(3)); + } else + + // starts with './' + if (taskPath.startsWith("./") || taskPath.equals(".")) { + return getTask(taskPath.substring(2)); + } else + + // starts with 'some_level/' + if (slashPos > 0) { + String levelName = taskPath.substring(0, slashPos); + return getTaskByName(levelName).getTask(taskPath.substring(slashPos + 1)); + } + + // there are no more directories; what remains is the name of the task + if (slashPos < 0) { + if (taskPath.length() == 0) return this; + return getTaskByName(taskPath); + } + return null; + } + + public boolean isPropertyContainer() { + return false; + } + +} diff --git a/proposal/frantic/src/org/apache/ant/tasks/Task.java b/proposal/frantic/src/org/apache/ant/tasks/Task.java new file mode 100644 index 000000000..4c96c7a47 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/tasks/Task.java @@ -0,0 +1,179 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.tasks; + + +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.engine.TaskEngine; + +/** + * Task is the core interface for all structures that will be processed by the + * TaskEngine. + */ +public interface Task { + + public static final int EXECUTION_MODE_IMPLICIT = 0; + public static final int EXECUTION_MODE_EXPLICIT = 1; + public static final int EXECUTION_MODE_PRIORITY = 2; + + public static final char NAME_SEPARATOR = '/'; + + /** + * Causes the existing Task implementation to execute. + */ + void execute(TaskEngine engine) throws AntException; + + /** + * Called when the Task first gets "noticed" by the TaskEngine. + */ + void init(TaskEngine engine) throws AntException; + + /** + * Each Task should have the ability to validate its state. This would be + * invoked by the TaskEngine prior to commencing an execution cycle. + */ + void validate() throws AntException; + + /** + * Just a simple name used to identify a Task. This name is only sufficient + * for simple debugging and GUI output. It does not uniquely identify a + * Task. + * + * @see #getFullyQualifiedName + */ + String getTaskName(); + + /** + * Although this method seems to tie the concept of XML "tags", it is not + * necessarily so. The tag name will serve as a general description of the + * type of tag represented by this class instance. It is primarily used by + * Tasks with sub-Tasks that are not assigned to a specific class + * implementation. + * + * @see org.apache.ant.tasks.UnknownTask + */ +// String getTaskTag(); + + /** + * A mechanism for locating a task relative to the current task. This + * navigation sceme will mimic a typical OS system. '..' will move back + * a level in the Task tree. If taskPath begins with '/' then the root node + * will be used as a starting point. + *

+ * Returns null of no task is found at this location. + */ + Task getTask(String taskPath); + + /** + * Proceed backwards through the nodes until we come across the first Task + * in the tree. This is the root Task. + */ + Task getRootTask(); + + /** + * The "fully-qualified" name of a Task is the Task's name, prepended by its + * parent's name, prepended by its parent's name, etc. This method may be + * used by the Task's hashCode() method to calculate a hash that will + * uniquely identify a Task. + */ + String getFullyQualifiedName(); + + /** + * Determines whether this Task is executed whenever its parent is executed, + * or if its execution must be specifically requested. + *

+ *
EXECUTION_MODE_EXPLICIT
+ *
Requires interaction by the TaskEngine in order to execute.
+ *
EXECUTION_MODE_IMPLICIT
+ *
This Task is automatically executed when its parent is + * executed.
+ *
EXECUTION_MODE_PRIORITY
+ *
These Tasks are executed prior to its parent's execution
+ *

+ * The default mode should probably be EXECUTION_MODE_IMPLICIT. In the + * build domain of Ant, every Task below a Task will normally be executed. + * The major exception to this is the Target. When a Project Task is + * executed, all Target Tasks do not automatically fire, however all + * Property Tasks do execute. + */ + int getExecutionMode(); + + /** + * Determines whether a Task is suitable for holding property values. + */ + boolean isPropertyContainer(); + + /** + * Each Task will hold its attributes in some manner. This method will allow + * the Task implementation to return the value of its attribute. + */ + String getAttributeValue(String name); + + /** + * Returns this Task's parent Task. If this Task is the root Task, then this + * method will return null. + */ + Task getParent(); + + /** + * Sets the Task's parent. + */ + void setParent(Task parent); + + /** + * Returns the an array of Task objects that are subordinate to this Task. + */ + Task[] getChildren(); +} diff --git a/proposal/frantic/src/org/apache/ant/tasks/build/Project.java b/proposal/frantic/src/org/apache/ant/tasks/build/Project.java new file mode 100644 index 000000000..bb2890422 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/tasks/build/Project.java @@ -0,0 +1,113 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.tasks.build; + + +import org.apache.ant.AntException; +import org.apache.ant.engine.TaskEngine; +import org.apache.ant.tasks.BaseTask; +import org.apache.ant.tasks.Task; + +public class Project extends BaseTask { + + private String def; + private String basedir; + + public Project() { + super(); + } + + public String getDefault() { + return def; + } + + public void setDefault(String newDefault) { + def = newDefault; + } + + public void setBasedir(String newBasedir) { + basedir = newBasedir; + } + + public String getBasedir() { + return basedir; + } + + //////////////////////////////////////////////////////////////////////////// + // BaseTask Implementation // + //////////////////////////////////////////////////////////////////////////// + + public void init(TaskEngine engine) throws AntException { + } + + /** + * Here is where we check and see if there are any Targets specified. We do + * this by peeking into the known taskStack and checking to see if a Target + * is next to be executed. If not, we add our default Target to the list. + */ + public void execute(TaskEngine engine) throws AntException { + // see if it is necessary to invoke the default task + Task task = engine.getNextExecuteTask(); + if (task == null && getDefault() != null) { + Task defaultTask = getTask(getDefault()); + if (defaultTask != null) { + engine.execute(defaultTask); + } + } + } + + public boolean isPropertyContainer() { + return true; + } +} diff --git a/proposal/frantic/src/org/apache/ant/tasks/build/Target.java b/proposal/frantic/src/org/apache/ant/tasks/build/Target.java new file mode 100644 index 000000000..c9e3dc6c9 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/tasks/build/Target.java @@ -0,0 +1,123 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.tasks.build; + + + +import org.apache.ant.AntException; +import org.apache.ant.engine.TaskEngine; +import org.apache.ant.tasks.BaseTask; +import org.apache.ant.tasks.Task; + +public class Target extends BaseTask { + + private String depends; + private String ifCond; + private String unlessCond; + + public Target() { + super(); + } + + public String getIf() { + return ifCond; + } + + public void setIf(String condition) { + this.ifCond = condition; + } + + public String getUnless() { + return unlessCond; + } + + public void setUnless(String condition) { + this.unlessCond = condition; + } + + public void setDepends(String newDepends) { + this.depends = newDepends; + } + + public String getDepends() { + return depends; + } + + //////////////////////////////////////////////////////////////////////////// + // BaseTask Implementation // + //////////////////////////////////////////////////////////////////////////// + + public int getExecutionMode() { + return Task.EXECUTION_MODE_EXPLICIT; + } + + /** + * Note that dependencies are executed before the task at hand. + */ + public void execute(TaskEngine engine) throws AntException { + if (getDepends() != null && getDepends().length() > 0) { + Task dependencyTask = getTask(getDepends()); + if (dependencyTask == null) { + throw new AntException( + "Cannot find dependency, " + getDepends() + " from Task."); + } + + engine.execute(dependencyTask); + } + } + + public boolean isPropertyContainer() { + return true; + } +} diff --git a/proposal/frantic/src/org/apache/ant/tasks/util/Property.java b/proposal/frantic/src/org/apache/ant/tasks/util/Property.java new file mode 100644 index 000000000..559c83798 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/tasks/util/Property.java @@ -0,0 +1,97 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.tasks.util; + + + +import org.apache.ant.AntException; +import org.apache.ant.engine.TaskEngine; +import org.apache.ant.tasks.BaseTask; + +public class Property extends BaseTask { + + private String value; + private String name; + + public Property() { + super(); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + //////////////////////////////////////////////////////////////////////////// + // BaseTask Implementation // + //////////////////////////////////////////////////////////////////////////// + + public void execute(TaskEngine engine) throws AntException { + if (getParent() == null) { + throw new AntException("A Property Task must have a parent Task."); + } + engine.setPropertyValue(getName(), getValue()); + } +} diff --git a/proposal/frantic/src/org/apache/ant/tasks/util/PropertyDump.java b/proposal/frantic/src/org/apache/ant/tasks/util/PropertyDump.java new file mode 100644 index 000000000..66c3dd7d3 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/tasks/util/PropertyDump.java @@ -0,0 +1,81 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.tasks.util; + + + +import java.util.*; +import org.apache.ant.AntException; +import org.apache.ant.engine.TaskEngine; +import org.apache.ant.tasks.BaseTask; + +public class PropertyDump extends BaseTask { + + public PropertyDump() { + super(); + } + + //////////////////////////////////////////////////////////////////////////// + // BaseTask Implementation // + //////////////////////////////////////////////////////////////////////////// + + public void execute(TaskEngine engine) throws AntException { + List propNames = engine.getPropertyNames(); + for (Iterator i = propNames.iterator(); i.hasNext();) { + String name = (String)i.next(); + String value = engine.getPropertyValue(name).toString(); + engine.message(this, name + " = " + value); + } + } +} diff --git a/proposal/frantic/src/org/apache/ant/test/SimpleTest.java b/proposal/frantic/src/org/apache/ant/test/SimpleTest.java new file mode 100644 index 000000000..3abe5c440 --- /dev/null +++ b/proposal/frantic/src/org/apache/ant/test/SimpleTest.java @@ -0,0 +1,146 @@ +/* + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.ant.test; + + + + +import org.apache.ant.AntException; +import org.apache.ant.engine.DefaultEngineListener; +import org.apache.ant.engine.TaskEngine; +import org.apache.ant.engine.TaskEngineImpl; +import org.apache.ant.tasks.Task; +import org.apache.ant.tasks.build.Project; +import org.apache.ant.tasks.build.Target; +import org.apache.ant.tasks.util.Property; +import org.apache.ant.tasks.util.PropertyDump; + +public class SimpleTest { + + Task target; + + public SimpleTest() { + try { + Task rootTask = buildProject(); + TaskEngine engine = TaskEngineImpl.getTaskEngine(); + engine.addAntEngineListener(new DefaultEngineListener()); + engine.execute(rootTask, target); + } catch (AntException ax) { + ax.printStackTrace(System.err); + } + } + + protected Task buildProject() { + Project project = new Project(); + project.setTaskName("project"); + project.setBasedir("somedir"); + project.setDefault("build"); + + Property property1 = new Property(); + property1.setTaskName("prop1"); + property1.setName("basedir"); + property1.setValue("/org/apache"); + project.addChild(property1); + + Property property2 = new Property(); + property2.setTaskName("prop2"); + property2.setName("dir1"); + property2.setValue("${basedir}/ant"); + project.addChild(property2); + + Target target1 = new Target(); + target1.setTaskName("clean"); + project.addChild(target1); + + PropertyDump pd = new PropertyDump(); + pd.setTaskName("dump"); + target1.addChild(pd); + + Target target2 = new Target(); + target2.setTaskName("prepare"); + target2.setDepends("../clean"); + project.addChild(target2); + + Property property3 = new Property(); + property3.setTaskName("prop3"); + property3.setName("dir2"); + property3.setValue("${dir1}/tasks"); + target2.addChild(property3); + + Target target3 = new Target(); + target3.setTaskName("build"); + target3.setDepends("../prepare"); + project.addChild(target3); + + Property property4 = new Property(); + property4.setTaskName("prop4"); + property4.setName("dir3"); + property4.setValue("r2}"); + target3.addChild(property4); + + Property property5 = new Property(); + property5.setTaskName("prop5"); + property5.setName("dir4"); + property5.setValue("${di${dir3}"); + target3.addChild(property5); + + target = target2; + + return project; + } + + public static void main(String[] args) { + SimpleTest simpleTest1 = new SimpleTest(); + } +}