conor 02/02/08 05:04:46
Modified: proposal/mutant build.xml
proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib
AntLibrary.java
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution
ComponentManager.java CoreEventService.java
ExecutionContext.java ExecutionManager.java
ImportInfo.java TaskContext.java
proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant
Ant1Factory.java Project.java
proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system
Ant.java AntCall.java
proposal/mutant/src/java/common/org/apache/ant/common/event
BuildEvent.java
proposal/mutant/src/java/common/org/apache/ant/common/service
ComponentService.java
Added: proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib
ComponentLibrary.java DynamicLibrary.java
proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution
CoreDataService.java CoreExecService.java
CoreFileService.java Frame.java
proposal/mutant/src/java/common/org/apache/ant/common/service
ExecService.java
Removed: proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution
ExecutionDataService.java ExecutionFileService.java
ExecutionFrame.java
Log:
Improved support for taskdef
Renamed a few classes
Revision Changes Path
1.11 +1 -1 jakarta-ant/proposal/mutant/build.xml
Index: build.xml
===================================================================
RCS file: /home/cvs/jakarta-ant/proposal/mutant/build.xml,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -w -u -r1.10 -r1.11
--- build.xml 5 Feb 2002 11:59:28 -0000 1.10
+++ build.xml 8 Feb 2002 13:04:45 -0000 1.11
@@ -158,7 +158,7 @@
<path id="checkstyle.path">
<fileset dir="${checkstyle.bin}"/>
</path>
- <taskdef name="checkstyle" reverseloader="true"
+ <taskdef name="checkstyle"
classname="com.puppycrawl.tools.checkstyle.CheckStyleTask">
<classpath refid="checkstyle.path"/>
</taskdef>
1.5 +21 -30
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java
Index: AntLibrary.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibrary.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -w -u -r1.4 -r1.5
--- AntLibrary.java 7 Feb 2002 14:42:36 -0000 1.4
+++ AntLibrary.java 8 Feb 2002 13:04:45 -0000 1.5
@@ -55,10 +55,10 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.util.ExecutionException;
@@ -68,12 +68,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 14 January 2002
*/
-public class AntLibrary {
-
- /** constant indicating a taskdef definition */
- public final static int TASKDEF = 1;
- /** constant indicating a typedef definition */
- public final static int TYPEDEF = 2;
+public class AntLibrary implements ComponentLibrary {
/** A counter for generating unique ids */
private static int implicitLibCount = 0;
@@ -129,25 +124,6 @@
}
/**
- * Create an Ant library to wrap around an existing class
- *
- * @param componentName the name of the component to be wrapped
- * @param componentClass the class to be wrapped
- * @param defType the type of definition being defined
- */
- public AntLibrary(int defType, String componentName, Class
componentClass) {
- this.libraryId = "_internal" + (implicitLibCount++);
- this.definitions = new HashMap();
- AntLibDefinition definition = new AntLibDefinition(defType,
- componentName, componentClass.getName());
- this.definitions.put(componentName, definition);
- this.isolated = false;
- this.factoryClassName = null;
- this.definitionURL = null;
- loader = componentClass.getClassLoader();
- }
-
- /**
* Sets the Library which this library extends
*
* @param extendsLibrary The new ExtendsLibrary value
@@ -191,10 +167,21 @@
/**
* Gets the definitions (taskdefs and typedefs) of the AntLibrary
*
- * @return the definitions map
+ * @return an iterator over the definition names
+ */
+ public Iterator getDefinitionNames() {
+ return definitions.keySet().iterator();
+ }
+
+ /**
+ * Get the definition of a particular component
+ *
+ * @param definitionName the name of the component within the library
+ * @return an AntLibDefinition instance with information about the
+ * component's definition
*/
- public Map getDefinitions() {
- return definitions;
+ public AntLibDefinition getDefinition(String definitionName) {
+ return (AntLibDefinition)definitions.get(definitionName);
}
/**
@@ -220,11 +207,14 @@
* Gat an instance of a factory object for creating objects in this
* library.
*
+ * @param context the context to use for the factory creation if
+ * required
* @return an instance of the factory, or null if this library does not
* support a factory
* @exception ExecutionException if the factory cannot be created
*/
- public AntLibFactory getFactory() throws ExecutionException {
+ public AntLibFactory getFactory(AntContext context)
+ throws ExecutionException {
try {
AntLibFactory libFactory = null;
if (factoryClassName != null) {
@@ -232,6 +222,7 @@
true, getClassLoader());
libFactory
= (AntLibFactory)factoryClass.newInstance();
+ libFactory.init(context);
}
return libFactory;
} catch (ClassNotFoundException e) {
1.1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/ComponentLibrary.java
Index: ComponentLibrary.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.antlib;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.util.ExecutionException;
/**
* A Component Library supplies components to the Ant core.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 8 February 2002
*/
public interface ComponentLibrary {
/** constant indicating a taskdef definition */
final static int TASKDEF = 1;
/** constant indicating a typedef definition */
final static int TYPEDEF = 2;
/**
* Gets the ClassLoader of the AntLibrary
*
* @return The ClassLoader value
*/
ClassLoader getClassLoader();
/**
* Gat an instance of a factory object for creating objects in this
* library.
*
* @param context the context to use for the factory creation if
* required
* @return an instance of the factory, or null if this library does not
* support a factory
* @exception ExecutionException if the factory cannot be created
*/
AntLibFactory getFactory(AntContext context) throws ExecutionException;
/**
* Gets the libraryId of the AntLibrary
*
* @return the libraryId value
*/
String getLibraryId();
/**
* Get the definition of a particular component
*
* @param definitionName the name of the component within the library
* @return an AntLibDefinition instance with information about the
* component's definition
*/
AntLibDefinition getDefinition(String definitionName);
}
1.1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/DynamicLibrary.java
Index: DynamicLibrary.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.antlib;
import java.util.HashMap;
import java.util.Map;
import org.apache.ant.common.antlib.AntContext;
import org.apache.ant.common.antlib.AntLibFactory;
/**
* A dynamic library is created at runtime to hold newly defined components.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 8 February 2002
*/
public class DynamicLibrary implements ComponentLibrary {
/** The name profix for naming dynamic libraries */
public final static String DYNAMIC_LIB_PREFIX = "_internal";
/** A static field used to uniquely name dynamic libraries */
private static int dynamicIdCounter = 0;
/**
* the factory this dynamic library will use to create instances of its
* components
*/
private AntLibFactory factory;
/**
* the classloader that will be used to create new instances of the
* library's components
*/
private ClassLoader loader;
/** the library's unique id */
private String libraryId;
/**
* the component definitions of this library. This map contains
* AntLibDefinition instances indexed on the definition names.
*/
private Map definitions = new HashMap();
/**
* Constructor for the DynamicLibrary object
*
* @param factory the factory to use to create instances. May be null
* @param loader the loader to use to load the instance classes
*/
public DynamicLibrary(AntLibFactory factory, ClassLoader loader) {
int dynamicId = 0;
synchronized (DynamicLibrary.class) {
dynamicId = dynamicIdCounter++;
}
this.libraryId = DYNAMIC_LIB_PREFIX + dynamicId;
this.loader = loader;
this.factory = factory;
}
/**
* Gets the ClassLoader of the AntLibrary
*
* @return The ClassLoader value
*/
public ClassLoader getClassLoader() {
return loader;
}
/**
* Gat an instance of a factory object for creating objects in this
* library.
*
* @param context the context to use for the factory creation if
* required
* @return an instance of the factory, or null if this library does not
* support a factory
*/
public AntLibFactory getFactory(AntContext context) {
return factory;
}
/**
* Gets the libraryId of the AntLibrary
*
* @return the libraryId value
*/
public String getLibraryId() {
return libraryId;
}
/**
* Get the definition of a particular component
*
* @param definitionName the name of the component within the library
* @return an AntLibDefinition instance with information about the
* component's definition
*/
public AntLibDefinition getDefinition(String definitionName) {
return (AntLibDefinition)definitions.get(definitionName);
}
/**
* Add a new component definition to this library
*
* @param componentType the type of the component
* @param componentName the name of the component
* @param componentClassName the component's class
*/
public void addComponent(int componentType, String componentName,
String componentClassName) {
AntLibDefinition newDefinition
= new AntLibDefinition(componentType, componentName,
componentClassName);
definitions.put(componentName, newDefinition);
}
}
1.3 +75 -99
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java
Index: ComponentManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -u -r1.2 -r1.3
--- ComponentManager.java 7 Feb 2002 14:42:37 -0000 1.2
+++ ComponentManager.java 8 Feb 2002 13:04:45 -0000 1.3
@@ -52,24 +52,20 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
-import java.io.File;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.antlib.AntLibDefinition;
import org.apache.ant.antcore.antlib.AntLibManager;
import org.apache.ant.antcore.antlib.AntLibrary;
-import org.apache.ant.antcore.modelparser.XMLProjectParser;
-import org.apache.ant.antcore.xml.XMLParseException;
+import org.apache.ant.antcore.antlib.ComponentLibrary;
+import org.apache.ant.antcore.antlib.DynamicLibrary;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.antlib.Converter;
import org.apache.ant.common.antlib.StandardLibFactory;
-import org.apache.ant.common.model.Project;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.util.ExecutionException;
-import org.apache.ant.init.InitUtils;
/**
* The instance of the ComponentServices made available by the core to the
@@ -83,16 +79,16 @@
public final static String ANT_LIB_PREFIX = "ant.";
/**
- * Type converters for this executionFrame. Converters are used when
- * configuring Tasks to handle special type conversions.
+ * Type converters for this frame. Converters are used when configuring
+ * Tasks to handle special type conversions.
*/
private Map converters = new HashMap();
/** The factory objects for each library, indexed by the library Id */
private Map libFactories = new HashMap();
- /** The ExecutionFrame this service instance is working for */
- private ExecutionFrame frame;
+ /** The Frame this service instance is working for */
+ private Frame frame;
/** The library manager instance used to configure libraries. */
private AntLibManager libManager;
@@ -102,20 +98,25 @@
* manager
*/
private Map antLibraries;
+
+ /** dynamic libraries which have been defined */
+ private Map dynamicLibraries;
+
/** The definitions which have been imported into this frame. */
private Map definitions = new HashMap();
/**
* Constructor
*
- * @param executionFrame the frame containing this context
+ * @param frame the frame containing this context
* @param allowRemoteLibs true if remote libraries can be loaded though
* this service.
*/
- protected ComponentManager(ExecutionFrame executionFrame,
+ protected ComponentManager(Frame frame,
boolean allowRemoteLibs) {
- this.frame = executionFrame;
+ this.frame = frame;
libManager = new AntLibManager(allowRemoteLibs);
+ dynamicLibraries = new HashMap();
}
/**
@@ -149,77 +150,37 @@
}
/**
- * Run a sub-build.
- *
- * @param antFile the file containing the XML description of the model
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- public void runBuild(File antFile, Map properties, List targets)
- throws ExecutionException {
- try {
- // Parse the build file into a project
- XMLProjectParser parser = new XMLProjectParser();
- Project project
- = parser.parseBuildFile(InitUtils.getFileURL(antFile));
- runBuild(project, properties, targets);
- } catch (MalformedURLException e) {
- throw new ExecutionException(e);
- } catch (XMLParseException e) {
- throw new ExecutionException(e);
- }
- }
-
- /**
- * Run a sub-build.
- *
- * @param model the project model to be used for the build
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- public void runBuild(Project model, Map properties, List targets)
- throws ExecutionException {
- ExecutionFrame newFrame = frame.createFrame(model);
- newFrame.setInitialProperties(properties);
- newFrame.runBuild(targets);
- }
-
- /**
- * Run a sub-build using the current frame's project model
- *
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- public void callTarget(Map properties, List targets)
- throws ExecutionException {
- runBuild(frame.getProject(), properties, targets);
- }
-
- /**
* Experimental - define a new task
*
* @param taskName the name by which this task will be referred
- * @param taskClass the class of the task
+ * @param factory the library factory object to create the task
+ * instances
+ * @param loader the class loader to use to create the particular tasks
+ * @param className the name of the class implementing the task
* @exception ExecutionException if the task cannot be defined
*/
- public void taskdef(String taskName, Class taskClass)
+ public void taskdef(AntLibFactory factory, ClassLoader loader,
+ String taskName, String className)
throws ExecutionException {
- defineComponent(AntLibrary.TASKDEF, taskName, taskClass);
+ defineComponent(factory, loader, ComponentLibrary.TASKDEF,
+ taskName, className);
}
/**
* Experimental - define a new type
*
* @param typeName the name by which this type will be referred
- * @param typeClass the class of the type
+ * @param factory the library factory object to create the type
+ * instances
+ * @param loader the class loader to use to create the particular types
+ * @param className the name of the class implementing the type
* @exception ExecutionException if the type cannot be defined
*/
- public void typedef(String typeName, Class typeClass)
+ public void typedef(AntLibFactory factory, ClassLoader loader,
+ String typeName, String className)
throws ExecutionException {
- defineComponent(AntLibrary.TYPEDEF, typeName, typeClass);
+ defineComponent(factory, loader, ComponentLibrary.TYPEDEF,
+ typeName, className);
}
/**
@@ -233,6 +194,7 @@
*/
protected void setStandardLibraries(Map standardLibs)
throws ExecutionException {
+
antLibraries = new HashMap(standardLibs);
// go through the libraries and import all standard ant libraries
@@ -256,33 +218,26 @@
}
/**
- * Get the collection of Ant Libraries defined for this frame
- *
- * @return a map of Ant Libraries indexed by thier library Id
- */
- protected Map getAntLibraries() {
- return antLibraries;
- }
-
- /**
- * Gets the factory object for the given library
+ * Get the collection of Ant Libraries defined for this frame Gets the
+ * factory object for the given library
*
- * @param antLibrary the library for which the factory is required
+ * @param componentLibrary the compnent library for which a factory
+ * objetc is required
* @return the library's factory object
- * @exception ExecutionException if the factory cannot be initialised
+ * @exception ExecutionException if the factory cannot be created
*/
- protected AntLibFactory getLibFactory(AntLibrary antLibrary)
+ protected AntLibFactory getLibFactory(ComponentLibrary componentLibrary)
throws ExecutionException {
- String libraryId = antLibrary.getLibraryId();
+ String libraryId = componentLibrary.getLibraryId();
if (libFactories.containsKey(libraryId)) {
return (AntLibFactory)libFactories.get(libraryId);
}
- AntLibFactory libFactory = antLibrary.getFactory();
+ AntLibFactory libFactory
+ = componentLibrary.getFactory(new ExecutionContext(frame));
if (libFactory == null) {
libFactory = new StandardLibFactory();
}
libFactories.put(libraryId, libFactory);
- libFactory.init(new ExecutionContext(frame));
return libFactory;
}
@@ -309,32 +264,53 @@
throw new ExecutionException("Unable to import library " +
libraryId
+ " as it has not been loaded");
}
- Map libDefs = library.getDefinitions();
- for (Iterator i = libDefs.keySet().iterator(); i.hasNext(); ) {
+ for (Iterator i = library.getDefinitionNames(); i.hasNext(); ) {
String defName = (String)i.next();
- AntLibDefinition libdef
- = (AntLibDefinition)libDefs.get(defName);
- definitions.put(defName, new ImportInfo(library, libdef));
+ importLibraryDef(library, defName, null);
}
addLibraryConverters(library);
}
/**
- * Experimental - define a new component
+ * Import a single component from the given library
+ *
+ * @param library the library which provides the component
+ * @param defName the name of the component in the library
+ * @param alias the name to be used for the component in build files. If
+ * this is null, the component's name within its library is used.
+ */
+ protected void importLibraryDef(ComponentLibrary library, String defName,
+ String alias) {
+ String label = alias;
+ if (label == null) {
+ label = defName;
+ }
+
+ AntLibDefinition libDef = library.getDefinition(defName);
+ definitions.put(label, new ImportInfo(library, libDef));
+ }
+
+ /**
+ * Define a new component
*
* @param componentName the name this component will take
- * @param componentClass the component's class
* @param defType the type of component being defined
+ * @param factory the library factory object to create the component
+ * instances
+ * @param loader the class loader to use to create the particular
+ * components
+ * @param className the name of the class implementing the component
* @exception ExecutionException if the component cannot be defined
*/
- private void defineComponent(int defType, String componentName,
- Class componentClass)
+ private void defineComponent(AntLibFactory factory, ClassLoader loader,
+ int defType, String componentName,
+ String className)
throws ExecutionException {
- AntLibrary wrapperLibrary
- = new AntLibrary(defType, componentName, componentClass);
- String libraryId = wrapperLibrary.getLibraryId();
- antLibraries.put(libraryId, wrapperLibrary);
- importLibrary(libraryId);
+ DynamicLibrary dynamicLibrary
+ = new DynamicLibrary(factory, loader);
+ dynamicLibrary.addComponent(defType, componentName, className);
+ dynamicLibraries.put(dynamicLibrary.getLibraryId(), dynamicLibrary);
+ importLibraryDef(dynamicLibrary, componentName, null);
}
/**
1.2 +3 -3
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreEventService.java
Index: CoreEventService.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreEventService.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -u -r1.1 -r1.2
--- CoreEventService.java 7 Feb 2002 14:42:37 -0000 1.1
+++ CoreEventService.java 8 Feb 2002 13:04:45 -0000 1.2
@@ -63,15 +63,15 @@
* @created 7 February 2002
*/
public class CoreEventService implements EventService {
- /** The ExecutionFrame this service instance is working for */
- private ExecutionFrame frame;
+ /** The Frame this service instance is working for */
+ private Frame frame;
/**
* Constructor
*
* @param frame the frame for which this instance is providing service
*/
- public CoreEventService(ExecutionFrame frame) {
+ public CoreEventService(Frame frame) {
this.frame = frame;
}
1.5 +3 -3
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java
Index: ExecutionContext.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionContext.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -w -u -r1.4 -r1.5
--- ExecutionContext.java 6 Feb 2002 10:15:04 -0000 1.4
+++ ExecutionContext.java 8 Feb 2002 13:04:45 -0000 1.5
@@ -65,8 +65,8 @@
* @created 20 January 2002
*/
public class ExecutionContext implements AntContext {
- /** The ExecutionFrame containing this context */
- private ExecutionFrame frame;
+ /** The Frame containing this context */
+ private Frame frame;
/** the event support instance used to manage build events */
private BuildEventSupport eventSupport;
@@ -79,7 +79,7 @@
*
* @param frame the frame containing this context
*/
- public ExecutionContext(ExecutionFrame frame) {
+ public ExecutionContext(Frame frame) {
this.frame = frame;
this.eventSupport = frame.getEventSupport();
}
1.6 +3 -3
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java
Index: ExecutionManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ExecutionManager.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -u -r1.5 -r1.6
--- ExecutionManager.java 6 Feb 2002 10:15:04 -0000 1.5
+++ ExecutionManager.java 8 Feb 2002 13:04:45 -0000 1.6
@@ -70,7 +70,7 @@
/**
* The ExecutionManager is used to manage the execution of a build. The
* Execution manager is responsible for loading the Ant task libraries,
- * creating ExecutionFrames for each project that is part of the build and
+ * creating Frames for each project that is part of the build and
* then executing the tasks within those Execution Frames.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
@@ -84,7 +84,7 @@
private BuildEventSupport eventSupport = new BuildEventSupport();
/** The Execution Frame for the top level project being executed */
- private ExecutionFrame mainFrame;
+ private Frame mainFrame;
/**
* The configuration to be used in this execution of Ant. It is formed
@@ -136,7 +136,7 @@
addConfigLibPaths();
- mainFrame = new ExecutionFrame(antLibraries, initConfig, config);
+ mainFrame = new Frame(antLibraries, initConfig, config);
} catch (MalformedURLException e) {
throw new ExecutionException("Unable to load Ant libraries", e);
}
1.2 +6 -5
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java
Index: ImportInfo.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ImportInfo.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -u -r1.1 -r1.2
--- ImportInfo.java 5 Feb 2002 11:49:04 -0000 1.1
+++ ImportInfo.java 8 Feb 2002 13:04:45 -0000 1.2
@@ -54,7 +54,7 @@
package org.apache.ant.antcore.execution;
import org.apache.ant.antcore.antlib.AntLibDefinition;
-import org.apache.ant.antcore.antlib.AntLibrary;
+import org.apache.ant.antcore.antlib.ComponentLibrary;
/**
* This class is used to maintain information about imports
@@ -63,8 +63,8 @@
* @created 16 January 2002
*/
public class ImportInfo {
- /** the ant library from which the import is made */
- private AntLibrary library;
+ /** the component library from which the import is made */
+ private ComponentLibrary library;
/** the library definition information */
private AntLibDefinition libDefinition;
@@ -74,7 +74,8 @@
* @param library The library from which the import was made
* @param libDefinition the library definition information
*/
- public ImportInfo(AntLibrary library, AntLibDefinition libDefinition) {
+ public ImportInfo(ComponentLibrary library,
+ AntLibDefinition libDefinition) {
this.library = library;
this.libDefinition = libDefinition;
}
@@ -93,7 +94,7 @@
*
* @return the library from which the import was made
*/
- public AntLibrary getAntLibrary() {
+ public ComponentLibrary getComponentLibrary() {
return library;
}
1.4 +1 -1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java
Index: TaskContext.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/TaskContext.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -u -r1.3 -r1.4
--- TaskContext.java 5 Feb 2002 11:49:04 -0000 1.3
+++ TaskContext.java 8 Feb 2002 13:04:45 -0000 1.4
@@ -78,7 +78,7 @@
*
* @param frame the frame containing this context
*/
- public TaskContext(ExecutionFrame frame) {
+ public TaskContext(Frame frame) {
super(frame);
}
1.1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreDataService.java
Index: CoreDataService.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.PropertyUtils;
/**
* This is the core's implementation of the DataService service interface.
* It gives Ant libraries access to property values maintained in the
* Frame.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 31 January 2002
*/
public class CoreDataService implements DataService {
/** The Frame this service instance is working for */
private Frame frame;
/** all properties to be unset without throwing an exception */
private boolean allowUnsetProperties;
/**
* Constructor
*
* @param frame the frame containing this context
* @param allowUnsetProperties true if the reference to an unset
* property should not throw an exception
*/
public CoreDataService(Frame frame,
boolean allowUnsetProperties) {
this.frame = frame;
this.allowUnsetProperties = allowUnsetProperties;
}
/**
* Set a data value. If an existing data value exists, associated with
* the given name, the value will not be changed
*
* @param valueName the name of the data value
* @param value the value to be associated with the name
* @exception ExecutionException if the value cannot be set
*/
public void setDataValue(String valueName, Object value)
throws ExecutionException {
frame.setDataValue(valueName, value, false);
}
/**
* Set a data value which can be overwritten
*
* @param valueName the name of the data value
* @param value the value to be associated with the name
* @exception ExecutionException if the value cannot be set
*/
public void setMutableDataValue(String valueName, Object value)
throws ExecutionException {
frame.setDataValue(valueName, value, true);
}
/**
* Get a data value
*
* @param valueName the name of the data value
* @return the current object associated with the name or null if no
* value is currently associated with the name
* @exception ExecutionException if the value cannot be retrieved.
*/
public Object getDataValue(String valueName) throws ExecutionException {
return frame.getDataValue(valueName);
}
/**
* Indicate if a data value has been set
*
* @param name the name of the data value - may contain reference
* delimiters
* @return true if the value exists
* @exception ExecutionException if the containing frame for the value
* does not exist
*/
public boolean isDataValueSet(String name) throws ExecutionException {
return frame.isDataValueSet(name);
}
/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full
* name.
*/
public Map getAllProperties() {
return frame.getAllProperties();
}
/**
* Replace ${} style constructions in the given value with the string
* value of the corresponding data values in the frame
*
* @param value the string to be scanned for property references.
* @return the string with all property references replaced
* @exception ExecutionException if any of the properties do not exist
*/
public String replacePropertyRefs(String value)
throws ExecutionException {
if (value == null) {
return null;
}
List fragments = new ArrayList();
List propertyRefs = new ArrayList();
PropertyUtils.parsePropertyString(value, fragments, propertyRefs);
StringBuffer sb = new StringBuffer();
Iterator i = fragments.iterator();
Iterator j = propertyRefs.iterator();
while (i.hasNext()) {
String fragment = (String)i.next();
if (fragment == null) {
String propertyName = (String)j.next();
if (!isDataValueSet(propertyName)) {
if (!allowUnsetProperties) {
throw new ExecutionException("Property \""
+ propertyName + "\" has not been set");
}
fragment = "${" + propertyName + "}";
} else {
fragment = getDataValue(propertyName).toString();
}
}
sb.append(fragment);
}
return sb.toString();
}
/**
* Replace ${} style constructions in the given value with the string
* value of the objects in the given map. Any values which are not found
* are left unchanged.
*
* @param value the string to be scanned for property references.
* @param replacementValues the collection of replacement values
* @return the string with all property references replaced
* @exception ExecutionException if any of the properties do not exist
*/
public String replacePropertyRefs(String value, Map replacementValues)
throws ExecutionException {
if (value == null) {
return null;
}
List fragments = new ArrayList();
List propertyRefs = new ArrayList();
PropertyUtils.parsePropertyString(value, fragments, propertyRefs);
StringBuffer sb = new StringBuffer();
Iterator i = fragments.iterator();
Iterator j = propertyRefs.iterator();
while (i.hasNext()) {
String fragment = (String)i.next();
if (fragment == null) {
String propertyName = (String)j.next();
if (!replacementValues.containsKey(propertyName)) {
fragment = "${" + propertyName + "}";
} else {
fragment
= replacementValues.get(propertyName).toString();
}
}
sb.append(fragment);
}
return sb.toString();
}
}
1.1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java
Index: CoreExecService.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import java.io.File;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map;
import org.apache.ant.antcore.modelparser.XMLProjectParser;
import org.apache.ant.antcore.xml.XMLParseException;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.init.InitUtils;
/**
*This is the core's implementation of the Execution Service.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 8 February 2002
*/
public class CoreExecService implements ExecService {
/** The Frame this service instance is working for */
private Frame frame;
/**
* Constructor
*
* @param frame the frame containing this context
*/
protected CoreExecService(Frame frame) {
this.frame = frame;
}
/**
* Run a sub-build.
*
* @param antFile the file containing the XML description of the model
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
public void runBuild(File antFile, Map properties, List targets)
throws ExecutionException {
try {
// Parse the build file into a project
XMLProjectParser parser = new XMLProjectParser();
Project project
= parser.parseBuildFile(InitUtils.getFileURL(antFile));
runBuild(project, properties, targets);
} catch (MalformedURLException e) {
throw new ExecutionException(e);
} catch (XMLParseException e) {
throw new ExecutionException(e);
}
}
/**
* Run a sub-build.
*
* @param model the project model to be used for the build
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
public void runBuild(Project model, Map properties, List targets)
throws ExecutionException {
Frame newFrame = frame.createFrame(model);
newFrame.setInitialProperties(properties);
newFrame.runBuild(targets);
}
/**
* Run a sub-build using the current frame's project model
*
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
public void callTarget(Map properties, List targets)
throws ExecutionException {
runBuild(frame.getProject(), properties, targets);
}
}
1.1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreFileService.java
Index: CoreFileService.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import java.io.File;
import org.apache.ant.common.service.FileService;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
/**
* The core's implementation of the File Service. The File Service is used
* by Ant Library components to perform operations on the local file system
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 27 January 2002
*/
public class CoreFileService implements FileService {
/** The Frame this service instance is working for */
private Frame frame;
/** General file utilities */
private FileUtils fileUtils = new FileUtils();
/**
* Constructor
*
* @param frame the frame containing this context
*/
public CoreFileService(Frame frame) {
this.frame = frame;
}
/**
* Resolve a file according to the base directory of the project
* associated with this context
*
* @param fileName the file name to be resolved.
* @return the file resolved to the project's base dir
* @exception ExecutionException if the file cannot be resolved.
*/
public File resolveFile(String fileName) throws ExecutionException {
File base = frame.getBaseDir();
return fileUtils.resolveFile(fileUtils.normalize(base.getPath()),
fileName);
}
}
1.1
jakarta-ant/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java
Index: Frame.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.antcore.execution;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.ant.antcore.antlib.AntLibrary;
import org.apache.ant.antcore.antlib.ComponentLibrary;
import org.apache.ant.antcore.config.AntConfig;
import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.antlib.ExecutionComponent;
import org.apache.ant.common.antlib.Task;
import org.apache.ant.common.antlib.TaskContainer;
import org.apache.ant.common.event.BuildListener;
import org.apache.ant.common.model.BuildElement;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.model.Target;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.FileService;
import org.apache.ant.common.service.EventService;
import org.apache.ant.common.service.MagicProperties;
import org.apache.ant.common.util.AntException;
import org.apache.ant.common.util.ConfigException;
import org.apache.ant.common.util.ExecutionException;
import org.apache.ant.common.util.FileUtils;
import org.apache.ant.common.util.MessageLevel;
import org.apache.ant.init.InitConfig;
import org.apache.ant.common.service.ExecService;
/**
* An Frame maintains the state of a project during an execution.
* The Frame contains the data values set by Ant tasks as they are
* executed, including task definitions, property values, etc.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 14 January 2002
*/
public class Frame {
/** The Ant aspect used to identify Ant metadata */
public final static String ANT_ASPECT = "ant";
/** the base dir of the project */
private File baseDir;
/** The Project that this execution frame is processing */
private Project project = null;
/** The referenced frames corresponding to the referenced projects */
private Map referencedFrames = new HashMap();
/** Reflector objects used to configure Tasks from the Task models. */
private Map reflectors = new HashMap();
/**
* The context of this execution. This contains all data object's
* created by tasks that have been executed
*/
private Map dataValues = new HashMap();
/**
* Ant's initialization configuration with information on the location
* of Ant and its libraries.
*/
private InitConfig initConfig;
/**
* These are the standard libraries from which taskdefs, typedefs, etc
* may be imported.
*/
private Map standardLibs;
/** BuildEvent support used to fire events and manage listeners */
private BuildEventSupport eventSupport = new BuildEventSupport();
/**
* The services map is a map of service interface classes to instances
* which provide the service.
*/
private Map services = new HashMap();
/**
* The configuration to be used in this execution of Ant. It is formed
* from the system, user and any runtime configs.
*/
private AntConfig config;
/**
* The Data Service instance used by the frame for data management
*/
private DataService dataService;
/** The execution file service instance */
private FileService fileService;
/**
* the Component Manager used to manage the importing of library
* components from the Ant libraries
*/
private ComponentManager componentManager;
/**
* Create an Execution Frame for the given project
*
* @param standardLibs The libraries of tasks and types available to
* this frame
* @param config the user config to use for this execution of Ant
* @param initConfig Ant's initialisation config
* @exception ExecutionException if a component of the library cannot be
* imported
*/
protected Frame(Map standardLibs, InitConfig initConfig,
AntConfig config) throws ExecutionException {
this.standardLibs = standardLibs;
this.config = config;
this.initConfig = initConfig;
}
/**
* Set the context loader of the current thread and returns the existing
* classloader
*
* @param newLoader the new context loader
* @return the old context loader
*/
private static ClassLoader setContextLoader(ClassLoader newLoader) {
Thread thread = Thread.currentThread();
ClassLoader currentLoader = thread.getContextClassLoader();
thread.setContextClassLoader(newLoader);
return currentLoader;
}
/**
* Sets the Project of the Frame
*
* @param project The new Project value
* @exception ExecutionException if any required sub-frames cannot be
* created and configured
*/
protected void setProject(Project project) throws ExecutionException {
this.project = project;
referencedFrames = new HashMap();
for (Iterator i = project.getReferencedProjectNames(); i.hasNext(); )
{
String referenceName = (String)i.next();
Project referencedProject
= project.getReferencedProject(referenceName);
Frame referencedFrame = createFrame(referencedProject);
referencedFrames.put(referenceName, referencedFrame);
}
configureServices();
componentManager.setStandardLibraries(standardLibs);
setMagicProperties();
}
/**
* Set a value in this frame or any of its imported frames.
*
* @param name the name of the value
* @param value the actual value
* @param mutable if true, existing values can be changed
* @exception ExecutionException if the value name is invalid
*/
protected void setDataValue(String name, Object value, boolean mutable)
throws ExecutionException {
Frame frame = getContainingFrame(name);
if (frame == this) {
if (dataValues.containsKey(name) && !mutable) {
log("Ignoring oveeride for data value " + name,
MessageLevel.MSG_VERBOSE);
} else {
dataValues.put(name, value);
}
} else {
frame.setDataValue(getNameInFrame(name), value, mutable);
}
}
/**
* Set the initial properties to be used when the frame starts execution
*
* @param properties a Map of named properties which may in fact be any
* object
* @exception ExecutionException if the properties cannot be set
*/
protected void setInitialProperties(Map properties)
throws ExecutionException {
if (properties != null) {
addProperties(properties);
}
// add in system properties
addProperties(System.getProperties());
}
/**
* Set the values of various magic properties
*
* @exception ExecutionException if the properties cannot be set
*/
protected void setMagicProperties() throws ExecutionException {
// set up various magic properties
setDataValue(MagicProperties.ANT_HOME,
initConfig.getAntHome().toString(), true);
}
/**
* Gets the project model this frame is working with
*
* @return the project model
*/
protected Project getProject() {
return project;
}
/**
* Get all the properties from the frame and any references frames. This
* is an expensive operation since it must clone all of the property
* stores in all frames
*
* @return a Map containing the frames properties indexed by their full
* name.
*/
protected Map getAllProperties() {
Map allProperties = new HashMap(dataValues);
Iterator i = referencedFrames.keySet().iterator();
while (i.hasNext()) {
String refName = (String)i.next();
Frame refFrame = getReferencedFrame(refName);
Map refProperties = refFrame.getAllProperties();
Iterator j = refProperties.keySet().iterator();
while (j.hasNext()) {
String name = (String)j.next();
Object value = refProperties.get(name);
allProperties.put(refName + Project.REF_DELIMITER + name,
value);
}
}
return allProperties;
}
/**
* Get the Ant initialization configuration for this frame.
*
* @return Ant's initialization configuration
*/
protected InitConfig getInitConfig() {
return initConfig;
}
/**
* Get the config instance being used by this frame.
*
* @return the config associated with this frame.
*/
protected AntConfig getConfig() {
return config;
}
/**
* Get the core's implementation of the given service interface.
*
* @param serviceInterfaceClass the service interface for which an
* implementation is require
* @return the core's implementation of the service interface
* @exception ExecutionException if the core does not provide an
* implementatin of the requested interface
*/
protected Object getCoreService(Class serviceInterfaceClass)
throws ExecutionException {
Object service = services.get(serviceInterfaceClass);
if (service == null) {
throw new ExecutionException("No service of interface class "
+ serviceInterfaceClass);
}
return service;
}
/**
* Get the EventSupport instance for this frame. This tracks the build
* listeners on this frame
*
* @return the EventSupport instance
*/
protected BuildEventSupport getEventSupport() {
return eventSupport;
}
/**
* Gets the baseDir of the Frame
*
* @return the baseDir value
*/
protected File getBaseDir() {
return baseDir;
}
/**
* Get a referenced frame by its reference name
*
* @param referenceName the name under which the frame was imported.
* @return the Frame asscociated with the given reference name
* or null if there is no such project.
*/
protected Frame getReferencedFrame(String referenceName) {
return (Frame)referencedFrames.get(referenceName);
}
/**
* Get the frames representing referenced projects.
*
* @return an iterator which returns the referenced ExeuctionFrames..
*/
protected Iterator getReferencedFrames() {
return referencedFrames.values().iterator();
}
/**
* Get the name of an object in its frame
*
* @param fullname The name of the object
* @return the name of the object within its containing frame
*/
protected String getNameInFrame(String fullname) {
int index = fullname.lastIndexOf(Project.REF_DELIMITER);
if (index == -1) {
return fullname;
}
return fullname.substring(index + Project.REF_DELIMITER.length());
}
/**
* Get a value from this frame or any imported frame
*
* @param name the name of the data value - may contain reference
* delimiters
* @return the data value fetched from the appropriate frame
* @exception ExecutionException if the value is not defined
*/
protected Object getDataValue(String name) throws ExecutionException {
Frame frame = getContainingFrame(name);
if (frame == this) {
return dataValues.get(name);
} else {
return frame.getDataValue(getNameInFrame(name));
}
}
/**
* Indicate if a data value has been set
*
* @param name the name of the data value - may contain reference
* delimiters
* @return true if the value exists
* @exception ExecutionException if the containing frame for the value
* does not exist
*/
protected boolean isDataValueSet(String name) throws ExecutionException {
Frame frame = getContainingFrame(name);
if (frame == this) {
return dataValues.containsKey(name);
} else {
return frame.isDataValueSet(getNameInFrame(name));
}
}
/**
* Add a collection of properties to this frame
*
* @param properties the collection of property values, indexed by their
* names
* @exception ExecutionException if the frame cannot be created.
*/
protected void addProperties(Map properties) throws ExecutionException {
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) {
String name = (String)i.next();
Object value = properties.get(name);
setDataValue(name, value, false);
}
}
/**
* Create a new frame for a given project
*
* @param project the project model the frame will deal with
* @return an Frame ready to build the project
* @exception ExecutionException if the frame cannot be created.
*/
protected Frame createFrame(Project project)
throws ExecutionException {
Frame newFrame
= new Frame(standardLibs, initConfig, config);
newFrame.setProject(project);
for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) {
BuildListener listener = (BuildListener)j.next();
newFrame.addBuildListener(listener);
}
return newFrame;
}
/**
* Log a message as a build event
*
* @param message the message to be logged
* @param level the priority level of the message
*/
protected void log(String message, int level) {
eventSupport.fireMessageLogged(project, message, level);
}
/**
* Add a build listener to this execution frame
*
* @param listener the listener to be added to the frame
*/
protected void addBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame referencedFrame = (Frame)i.next();
referencedFrame.addBuildListener(listener);
}
eventSupport.addBuildListener(listener);
}
/**
* Remove a build listener from the execution
*
* @param listener the listener to be removed
*/
protected void removeBuildListener(BuildListener listener) {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame subFrame = (Frame)i.next();
subFrame.removeBuildListener(listener);
}
eventSupport.removeBuildListener(listener);
}
/**
* Run the given list of targets
*
* @param targets a list of target names which are to be evaluated
* @exception ExecutionException if there is a problem in the build
*/
protected void runBuild(List targets) throws ExecutionException {
determineBaseDirs();
initialize();
if (targets.isEmpty()) {
// we just execute the default target if any
String defaultTarget = project.getDefaultTarget();
if (defaultTarget != null) {
log("Executing default target: " + defaultTarget,
MessageLevel.MSG_DEBUG);
executeTarget(defaultTarget);
}
} else {
for (Iterator i = targets.iterator(); i.hasNext(); ) {
String targetName = (String)i.next();
log("Executing target: " + targetName,
MessageLevel.MSG_DEBUG);
executeTarget(targetName);
}
}
}
/**
* Execute the tasks of a target in this frame with the given name
*
* @param targetName the name of the target whose tasks will be
* evaluated
* @exception ExecutionException if there is a problem executing the
* tasks of the target
*/
protected void executeTarget(String targetName) throws ExecutionException
{
// to execute a target we must determine its dependencies and
// execute them in order.
try {
// firstly build a list of fully qualified target names to
execute.
List dependencyOrder = project.getTargetDependencies(targetName);
for (Iterator i = dependencyOrder.iterator(); i.hasNext(); ) {
String fullTargetName = (String)i.next();
Frame frame = getContainingFrame(fullTargetName);
String localTargetName = getNameInFrame(fullTargetName);
frame.executeTargetTasks(localTargetName);
}
} catch (ConfigException e) {
throw new ExecutionException(e);
}
}
/**
* Run the tasks returned by the given iterator
*
* @param taskIterator the iterator giving the tasks to execute
* @exception ExecutionException if there is execution problem while
* executing tasks
*/
protected void executeTasks(Iterator taskIterator)
throws ExecutionException {
while (taskIterator.hasNext()) {
Throwable failureCause = null;
BuildElement model = (BuildElement)taskIterator.next();
// what sort of element is this.
ImportInfo importInfo
= componentManager.getDefinition(model.getType());
if (importInfo == null) {
throw new ExecutionException("There is no definition for the
<"
+ model.getType() + "> element", model.getLocation());
}
try {
if (importInfo.getDefinitionType() == AntLibrary.TASKDEF) {
TaskContext taskContext = configureTask(model);
eventSupport.fireTaskStarted(model);
ClassLoader currentLoader
= setContextLoader(taskContext.getLoader());
taskContext.execute();
setContextLoader(currentLoader);
taskContext.destroy();
} else {
// typedef
String typeId = model.getAspectValue(ANT_ASPECT, "id");
Object typeInstance = configureType(model.getType(),
model);
if (typeId != null) {
setDataValue(typeId, typeInstance, true);
}
}
} catch (AntException te) {
ExecutionException e
= new ExecutionException(te, te.getLocation());
e.setLocation(model.getLocation(), false);
failureCause = e;
throw e;
} catch (RuntimeException e) {
ExecutionException ee =
new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e, model.getLocation());
failureCause = ee;
throw ee;
} finally {
eventSupport.fireTaskFinished(model, failureCause);
}
}
}
/**
* Execute the given target's tasks. The target must be local to this
* frame's project
*
* @param targetName the name of the target within this frame that is to
* be executed.
* @exception ExecutionException if there is a problem executing tasks
*/
protected void executeTargetTasks(String targetName)
throws ExecutionException {
Throwable failureCause = null;
Target target = project.getTarget(targetName);
String ifCondition = target.getIfCondition();
String unlessCondition = target.getUnlessCondition();
if (ifCondition != null) {
ifCondition = dataService.replacePropertyRefs(ifCondition.trim());
if (!isDataValueSet(ifCondition)) {
return;
}
}
if (unlessCondition != null) {
unlessCondition
= dataService.replacePropertyRefs(unlessCondition.trim());
if (isDataValueSet(unlessCondition)) {
return;
}
}
try {
Iterator taskIterator = target.getTasks();
eventSupport.fireTargetStarted(target);
executeTasks(taskIterator);
} catch (ExecutionException e) {
e.setLocation(target.getLocation(), false);
failureCause = e;
throw e;
} catch (RuntimeException e) {
ExecutionException ee =
new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e, target.getLocation());
failureCause = ee;
throw ee;
} finally {
eventSupport.fireTargetFinished(target, failureCause);
}
}
/**
* Initialize the frame by executing the project level tasks if any
*
* @exception ExecutionException if the top level tasks of the frame
* failed
*/
protected void initialize() throws ExecutionException {
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame referencedFrame = (Frame)i.next();
referencedFrame.initialize();
}
Iterator taskIterator = project.getTasks();
executeTasks(taskIterator);
}
/**
* Gets the reflector for the given class
*
* @param c the class for which the reflector is desired
* @return the reflector
*/
private Reflector getReflector(Class c) {
if (reflectors.containsKey(c)) {
return (Reflector)reflectors.get(c);
}
ClassIntrospector introspector
= new ClassIntrospector(c, componentManager.getConverters());
Reflector reflector = introspector.getReflector();
reflectors.put(c, reflector);
return reflector;
}
/**
* Get the execution frame which contains, directly, the named target
* where the name is relative to this frame
*
* @param targetName The name of the target
* @return the execution frame for the project that contains the given
* target
*/
private Frame getContainingFrame(String targetName) {
int index = targetName.lastIndexOf(Project.REF_DELIMITER);
if (index == -1) {
return this;
}
Frame currentFrame = this;
String relativeName = targetName.substring(0, index);
StringTokenizer tokenizer
= new StringTokenizer(relativeName, Project.REF_DELIMITER);
while (tokenizer.hasMoreTokens()) {
String refName = tokenizer.nextToken();
currentFrame = currentFrame.getReferencedFrame(refName);
if (currentFrame == null) {
return null;
}
}
return currentFrame;
}
/**
* Determine the base directory for each frame in the frame hierarchy
*
* @exception ExecutionException if the base directories cannot be
* determined
*/
private void determineBaseDirs() throws ExecutionException {
if (isDataValueSet(MagicProperties.BASEDIR)) {
baseDir
= new File(getDataValue(MagicProperties.BASEDIR).toString());
} else {
URL projectURL = project.getSourceURL();
if (projectURL.getProtocol().equals("file")) {
File projectFile = new File(projectURL.getFile());
File projectFileParent = projectFile.getParentFile();
String base = project.getBase();
if (base == null) {
baseDir = projectFileParent;
} else {
FileUtils fileUtils = new FileUtils();
baseDir = fileUtils.resolveFile(projectFileParent, base);
}
} else {
baseDir = new File(".");
}
}
setDataValue(MagicProperties.BASEDIR, baseDir.getAbsolutePath(),
true);
for (Iterator i = getReferencedFrames(); i.hasNext(); ) {
Frame refFrame = (Frame)i.next();
refFrame.determineBaseDirs();
}
}
/**
* Configure the services that the frame makes available to its library
* components
*/
private void configureServices() {
// create services and make them available in our services map
fileService = new CoreFileService(this);
componentManager
= new ComponentManager(this, config.isRemoteLibAllowed());
dataService = new CoreDataService(this,
config.isUnsetPropertiesAllowed());
services.put(FileService.class, fileService);
services.put(ComponentService.class, componentManager);
services.put(DataService.class, dataService);
services.put(EventService.class, new CoreEventService(this));
services.put(ExecService.class, new CoreExecService(this));
}
/**
* Configure an element according to the given model.
*
* @param element the object to be configured
* @param model the BuildElement describing the object in the build file
* @param factory Ant Library factory associated with the element being
* configured
* @exception ExecutionException if the element cannot be configured
*/
private void configureElement(AntLibFactory factory, Object element,
BuildElement model)
throws ExecutionException {
Reflector reflector = getReflector(element.getClass());
// start by setting the attributes of this element
for (Iterator i = model.getAttributeNames(); i.hasNext(); ) {
String attributeName = (String)i.next();
String attributeValue = model.getAttributeValue(attributeName);
if (!reflector.supportsAttribute(attributeName)) {
throw new ExecutionException(model.getType()
+ " does not support the \"" + attributeName
+ "\" attribute", model.getLocation());
}
reflector.setAttribute(element, attributeName,
dataService.replacePropertyRefs(attributeValue));
}
String modelText = model.getText().trim();
if (modelText.length() != 0) {
if (!reflector.supportsText()) {
throw new ExecutionException(model.getType()
+ " does not support content", model.getLocation());
}
reflector.addText(element,
dataService.replacePropertyRefs(modelText));
}
// now do the nested elements
for (Iterator i = model.getNestedElements(); i.hasNext(); ) {
BuildElement nestedElementModel = (BuildElement)i.next();
String nestedElementName = nestedElementModel.getType();
ImportInfo info =
componentManager.getDefinition(nestedElementName);
if (element instanceof TaskContainer
&& info != null
&& info.getDefinitionType() == AntLibrary.TASKDEF
&& !reflector.supportsNestedElement(nestedElementName)) {
// it is a nested task
TaskContext nestedContext
= configureTask(nestedElementModel);
TaskContainer container = (TaskContainer)element;
// XXX what should we be adding - need to understand container
// method of executing tasks
container.addTask(nestedContext.getTask());
} else {
if (reflector.supportsNestedAdder(nestedElementName)) {
addNestedElement(factory, reflector, element,
nestedElementModel);
} else if
(reflector.supportsNestedCreator(nestedElementName)) {
createNestedElement(factory, reflector, element,
nestedElementModel);
} else {
throw new ExecutionException(model.getType()
+ " does not support the \"" + nestedElementName
+ "\" nested element",
nestedElementModel.getLocation());
}
}
}
}
/**
* Create a nested element for the given object according to the model.
*
* @param reflector the reflector instance of the container object
* @param element the container object for which a nested element is
* required.
* @param model the build model for the nestd element
* @param factory Ant Library factory associated with the element
* creating the nested element
* @exception ExecutionException if the nested element cannot be
* created.
*/
private void createNestedElement(AntLibFactory factory, Reflector
reflector,
Object element, BuildElement model)
throws ExecutionException {
log("The use of create methods is deprecated - class: "
+ element.getClass().getName(), MessageLevel.MSG_INFO);
String nestedElementName = model.getType();
try {
Object nestedElement
= reflector.createElement(element, nestedElementName);
factory.registerCreatedElement(nestedElement);
if (nestedElement instanceof ExecutionComponent) {
ExecutionComponent component
= (ExecutionComponent)nestedElement;
ExecutionContext context
= new ExecutionContext(this);
context.setModelElement(model);
component.init(context);
configureElement(factory, nestedElement, model);
component.validateComponent();
} else {
configureElement(factory, nestedElement, model);
}
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
throw e;
} catch (RuntimeException e) {
throw new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e, model.getLocation());
}
}
/**
* Create and add a nested element
*
* @param reflector The reflector instance for the container element
* @param element the container element in which the nested element will
* be created
* @param model the model of the nested element
* @param factory Ant Library factory associated with the element to
* which the attribute is to be added.
* @exception ExecutionException if the nested element cannot be created
*/
private void addNestedElement(AntLibFactory factory, Reflector reflector,
Object element, BuildElement model)
throws ExecutionException {
String nestedElementName = model.getType();
Class nestedType = reflector.getType(nestedElementName);
// is there a polymorph indicator - look in Ant aspects
String typeName = model.getAspectValue(ANT_ASPECT, "type");
String refId = model.getAspectValue(ANT_ASPECT, "refid");
if (refId != null && typeName != null) {
throw new ExecutionException("Only one of " + ANT_ASPECT
+ ":type and " + ANT_ASPECT
+ ":refid may be specified at a time", model.getLocation());
}
Object typeInstance = null;
if (typeName != null) {
// the build file has specified the actual type of the element.
// we need to look up that type and use it
typeInstance = configureType(typeName, model);
} else if (refId != null) {
// We have a reference to an existing instance. Need to check if
// it is compatible with the type expected by the nested element's
// adder method
typeInstance = getDataValue(refId);
if (model.getAttributeNames().hasNext() ||
model.getNestedElements().hasNext() ||
model.getText().length() != 0) {
throw new ExecutionException("Element <" + nestedElementName
+ "> is defined by reference and hence may not specify "
+ "any attributes, nested elements or content",
model.getLocation());
}
if (typeInstance == null) {
throw new ExecutionException("The given ant:refid value '"
+ refId + "' is not defined", model.getLocation());
}
} else {
// We need to create an instance of the class expected by the
nested
// element's adder method if that is possible
if (nestedType.isInterface()) {
throw new ExecutionException("No element can be created for "
+ "nested element <" + nestedElementName + ">. Please "
+ "provide a value by reference or specify the value
type",
model.getLocation());
}
typeInstance = createTypeInstance(nestedType, factory, model);
}
// is the typeInstance compatible with the type expected
// by the element's add method
if (!nestedType.isInstance(typeInstance)) {
if (refId != null) {
throw new ExecutionException("The value specified by refId "
+ refId + " is not compatible with the <"
+ nestedElementName + "> nested element",
model.getLocation());
} else if (typeName != null) {
throw new ExecutionException("The type "
+ typeName + " is not compatible with the <"
+ nestedElementName + "> nested element",
model.getLocation());
}
}
reflector.addElement(element, nestedElementName, typeInstance);
}
/**
* Create a Task and configure it according to the given model.
*
* @param model the model for the task from the build file
* @return an execution context for managing the task
* @exception ExecutionException if there is a problem configuring the
* task
*/
private TaskContext configureTask(BuildElement model)
throws ExecutionException {
String taskType = model.getType();
ImportInfo taskDefInfo = componentManager.getDefinition(taskType);
if (taskDefInfo == null
|| taskDefInfo.getDefinitionType() != AntLibrary.TASKDEF) {
throw new ExecutionException("There is no defintion for a "
+ "task of type <" + taskType + ">", model.getLocation());
}
String className = taskDefInfo.getClassName();
ComponentLibrary componentLibrary
= taskDefInfo.getComponentLibrary();
try {
ClassLoader taskClassLoader = componentLibrary.getClassLoader();
Class elementClass
= Class.forName(className, true, taskClassLoader);
AntLibFactory libFactory
= componentManager.getLibFactory(componentLibrary);
Object element = libFactory.createTaskInstance(elementClass);
Task task = null;
if (element instanceof Task) {
// create a Task context for the Task
task = (Task)element;
} else {
task = new TaskAdapter(taskType, element);
}
// set the context loader while configuring the element
ClassLoader currentLoader = setContextLoader(taskClassLoader);
TaskContext taskContext = new TaskContext(this);
taskContext.init(taskClassLoader, task, model);
configureElement(libFactory, element, model);
task.validateComponent();
setContextLoader(currentLoader);
return taskContext;
} catch (ClassNotFoundException e) {
throw new ExecutionException("Class " + className
+ " for task <" + taskType + "> was not found", e,
model.getLocation());
} catch (NoClassDefFoundError e) {
throw new ExecutionException("Could not load a dependent class ("
+ e.getMessage() + ") for task " + taskType,
e, model.getLocation());
} catch (InstantiationException e) {
throw new ExecutionException("Unable to instantiate task class "
+ className + " for task <" + taskType + ">",
e, model.getLocation());
} catch (IllegalAccessException e) {
throw new ExecutionException("Unable to access task class "
+ className + " for task <" + taskType + ">",
e, model.getLocation());
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
throw e;
} catch (RuntimeException e) {
throw new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e, model.getLocation());
}
}
/**
* Configure a type instance from the given build model. The name given
* may not match the name in the model type value. This allows the
* caller to provide a polymorphic type for the type model
*
* @param typeName the name of the type which should be created
* @param model the model describing the type
* @return an instance of the type, configured from the model
* @exception ExecutionException if the type could not be created
*/
private Object configureType(String typeName, BuildElement model)
throws ExecutionException {
ImportInfo typeDefInfo = componentManager.getDefinition(typeName);
if (typeDefInfo == null
|| typeDefInfo.getDefinitionType() != AntLibrary.TYPEDEF) {
throw new ExecutionException("There is no defintion for a "
+ "type <" + typeName + ">", model.getLocation());
}
String className = typeDefInfo.getClassName();
ComponentLibrary componentLibrary
= typeDefInfo.getComponentLibrary();
try {
ClassLoader typeClassLoader = componentLibrary.getClassLoader();
Class typeClass
= Class.forName(className, true, typeClassLoader);
ClassLoader currentLoader = setContextLoader(typeClassLoader);
AntLibFactory libFactory
= componentManager.getLibFactory(componentLibrary);
Object typeInstance
= createTypeInstance(typeClass, libFactory, model);
setContextLoader(currentLoader);
return typeInstance;
} catch (ClassNotFoundException e) {
throw new ExecutionException("Class " + className
+ " for type <" + typeName + "> was not found", e,
model.getLocation());
} catch (NoClassDefFoundError e) {
throw new ExecutionException("Could not load a dependent class ("
+ e.getMessage() + ") for type " + typeName);
}
}
/**
* Create an instance of a type given its required class
*
* @param typeClass the class from which the instance should be created
* @param model the model describing the required configuration of the
* instance
* @param libFactory the factory object of the typeClass's Ant library
* @return an instance of the given class appropriately configured
* @exception ExecutionException if there is a problem creating the type
* instance
*/
private Object createTypeInstance(Class typeClass, AntLibFactory
libFactory,
BuildElement model)
throws ExecutionException {
try {
Object typeInstance = libFactory.createTypeInstance(typeClass);
if (typeInstance instanceof ExecutionComponent) {
ExecutionComponent component =
(ExecutionComponent)typeInstance;
ExecutionContext context
= new ExecutionContext(this);
context.setModelElement(model);
component.init(context);
configureElement(libFactory, typeInstance, model);
component.validateComponent();
} else {
configureElement(libFactory, typeInstance, model);
}
return typeInstance;
} catch (InstantiationException e) {
throw new ExecutionException("Unable to instantiate type class "
+ typeClass.getName() + " for type <" + model.getType() +
">",
e, model.getLocation());
} catch (IllegalAccessException e) {
throw new ExecutionException("Unable to access type class "
+ typeClass.getName() + " for type <" + model.getType() +
">",
e, model.getLocation());
} catch (ExecutionException e) {
e.setLocation(model.getLocation(), false);
throw e;
} catch (RuntimeException e) {
throw new ExecutionException(e.getClass().getName() + ": "
+ e.getMessage(), e, model.getLocation());
}
}
}
1.6 +5 -1
jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java
Index: Ant1Factory.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Ant1Factory.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -u -r1.5 -r1.6
--- Ant1Factory.java 7 Feb 2002 14:42:37 -0000 1.5
+++ Ant1Factory.java 8 Feb 2002 13:04:46 -0000 1.6
@@ -82,13 +82,17 @@
* @exception ExecutionException if the factory cannot be initialised.
*/
public void init(AntContext context) throws ExecutionException {
+ if (project != null) {
+ return;
+ }
+
this.context = context;
// set the system classpath. In Ant2, the system classpath will not
// in general, have any useful information. For Ant1 compatability
// we set it now to include the Ant1 facade classes
System.setProperty("java.class.path", getAnt1Classpath());
- project = new Project();
+ project = new Project(this);
project.init(context);
EventService eventService =
1.6 +18 -4
jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java
Index: Project.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -w -u -r1.5 -r1.6
--- Project.java 7 Feb 2002 14:42:37 -0000 1.5
+++ Project.java 8 Feb 2002 13:04:46 -0000 1.6
@@ -63,6 +63,7 @@
import java.util.Stack;
import java.util.Vector;
import org.apache.ant.common.antlib.AntContext;
+import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.service.ComponentService;
import org.apache.ant.common.service.DataService;
import org.apache.ant.common.service.FileService;
@@ -116,6 +117,10 @@
/** The java version detected that Ant is running on */
private static String javaVersion;
+ /** the factory which created this project instance. This is used to
+ define new types and tasks */
+ private AntLibFactory factory;
+
/** Collection of Ant1 type definitions */
private Hashtable dataClassDefinitions = new Hashtable();
/** Collection of Ant1 task definitions */
@@ -175,8 +180,13 @@
}
}
- /** Create the project */
- public Project() {
+ /**
+ * Create the project
+ *
+ * @param factory the factory object creating this project
+ */
+ public Project(AntLibFactory factory) {
+ this.factory = factory;
fileUtils = FileUtils.newFileUtils();
}
@@ -468,6 +478,8 @@
* @param event target finished event
*/
public void targetFinished(org.apache.ant.common.event.BuildEvent event)
{
+ org.apache.ant.common.model.Target realTarget =
+ (org.apache.ant.common.model.Target)event.getModelElement();
Target currentTarget = (Target)targetStack.pop();
fireTargetFinished(currentTarget, event.getCause());
currentTarget = null;
@@ -818,7 +830,8 @@
public void addTaskDefinition(String taskName, Class taskClass)
throws BuildException {
try {
- componentService.taskdef(taskName, taskClass);
+ componentService.taskdef(factory, taskClass.getClassLoader(),
+ taskName, taskClass.getName());
taskClassDefinitions.put(taskName, taskClass);
} catch (ExecutionException e) {
throw new BuildException(e);
@@ -833,7 +846,8 @@
*/
public void addDataTypeDefinition(String typeName, Class typeClass) {
try {
- componentService.typedef(typeName, typeClass);
+ componentService.typedef(factory, typeClass.getClassLoader(),
+ typeName, typeClass.getName());
dataClassDefinitions.put(typeName, typeClass);
} catch (ExecutionException e) {
throw new BuildException(e);
1.3 +4 -4
jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java
Index: Ant.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/Ant.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -u -r1.2 -r1.3
--- Ant.java 7 Feb 2002 09:59:59 -0000 1.2
+++ Ant.java 8 Feb 2002 13:04:46 -0000 1.3
@@ -53,7 +53,7 @@
*/
package org.apache.ant.antlib.system;
import java.io.File;
-import org.apache.ant.common.service.ComponentService;
+import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
/**
@@ -113,10 +113,10 @@
}
}
- ComponentService componentService
- = (ComponentService)getCoreService(ComponentService.class);
+ ExecService execService
+ = (ExecService)getCoreService(ExecService.class);
- componentService.runBuild(antFile, getProperties(), getTargets());
+ execService.runBuild(antFile, getProperties(), getTargets());
}
}
1.2 +5 -5
jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java
Index: AntCall.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/antlibs/system/code/org/apache/ant/antlib/system/AntCall.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -u -r1.1 -r1.2
--- AntCall.java 5 Feb 2002 11:49:06 -0000 1.1
+++ AntCall.java 8 Feb 2002 13:04:46 -0000 1.2
@@ -52,7 +52,7 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.antlib.system;
-import org.apache.ant.common.service.ComponentService;
+import org.apache.ant.common.service.ExecService;
import org.apache.ant.common.util.ExecutionException;
/**
@@ -68,10 +68,10 @@
* @exception ExecutionException if the build fails
*/
public void execute() throws ExecutionException {
- ComponentService componentService
- = (ComponentService)getCoreService(ComponentService.class);
+ ExecService execService
+ = (ExecService)getCoreService(ExecService.class);
- componentService.callTarget(getProperties(), getTargets());
+ execService.callTarget(getProperties(), getTargets());
}
/**
1.3 +1 -1
jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java
Index: BuildEvent.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/event/BuildEvent.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -w -u -r1.2 -r1.3
--- BuildEvent.java 5 Feb 2002 11:49:06 -0000 1.2
+++ BuildEvent.java 8 Feb 2002 13:04:46 -0000 1.3
@@ -58,7 +58,7 @@
/**
* A BuildEvent indicates the occurence of a significant event in the build.
- * All build events come from an ExecutionFrame or an ExecutionManager.
+ * All build events come from an Frame or an ExecutionManager.
* There are a number of different types of event and they will generally be
* associated with some build element from the build model.
*
1.4 +12 -41
jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java
Index: ComponentService.java
===================================================================
RCS file:
/home/cvs/jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -w -u -r1.3 -r1.4
--- ComponentService.java 7 Feb 2002 14:42:37 -0000 1.3
+++ ComponentService.java 8 Feb 2002 13:04:46 -0000 1.4
@@ -52,10 +52,7 @@
* <http://www.apache.org/>.
*/
package org.apache.ant.common.service;
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import org.apache.ant.common.model.Project;
+import org.apache.ant.common.antlib.AntLibFactory;
import org.apache.ant.common.util.ExecutionException;
/**
@@ -86,55 +83,29 @@
throws ExecutionException;
/**
- * Run a sub-build.
- *
- * @param antFile the file containing the XML description of the model
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- void runBuild(File antFile, Map properties, List targets)
- throws ExecutionException;
-
- /**
- * Run a sub-build.
- *
- * @param model the project model to be used for the build
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- void runBuild(Project model, Map properties, List targets)
- throws ExecutionException;
-
- /**
- * Run a sub-build using the current frame's project model
- *
- * @param targets A list of targets to be run
- * @param properties the initiali properties to be used in the build
- * @exception ExecutionException if the subbuild cannot be run
- */
- void callTarget(Map properties, List targets)
- throws ExecutionException;
-
- /**
* Experimental - define a new type
*
* @param typeName the name by which this type will be referred
- * @param typeClass the class of the type
+ * @param factory the library factory object to create the type instances
+ * @param loader the class loader to use to create the particular types
+ * @param className the name of the class implementing the type
* @exception ExecutionException if the type cannot be defined
*/
- void typedef(String typeName, Class typeClass)
+ void typedef(AntLibFactory factory, ClassLoader loader,
+ String typeName, String className)
throws ExecutionException;
/**
* Experimental - define a new task
*
* @param taskName the name by which this task will be referred
- * @param taskClass the class of the task
+ * @param factory the library factory object to create the task instances
+ * @param loader the class loader to use to create the particular tasks
+ * @param className the name of the class implementing the task
* @exception ExecutionException if the task cannot be defined
*/
- void taskdef(String taskName, Class taskClass)
+ void taskdef(AntLibFactory factory, ClassLoader loader,
+ String taskName, String className)
throws ExecutionException;
}
1.1
jakarta-ant/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java
Index: ExecService.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Ant", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.ant.common.service;
import java.io.File;
import java.util.List;
import java.util.Map;
import org.apache.ant.common.model.Project;
import org.apache.ant.common.util.ExecutionException;
/**
* The ExecService provides executiuon services to tasks
*
* @author <a href="mailto:[EMAIL PROTECTED]">Conor MacNeill</a>
* @created 8 February 2002
*/
public interface ExecService {
/**
* Run a sub-build.
*
* @param antFile the file containing the XML description of the model
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
void runBuild(File antFile, Map properties, List targets)
throws ExecutionException;
/**
* Run a sub-build.
*
* @param model the project model to be used for the build
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
void runBuild(Project model, Map properties, List targets)
throws ExecutionException;
/**
* Run a sub-build using the current frame's project model
*
* @param targets A list of targets to be run
* @param properties the initiali properties to be used in the build
* @exception ExecutionException if the subbuild cannot be run
*/
void callTarget(Map properties, List targets)
throws ExecutionException;
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>