|
|
@@ -1,55 +1,55 @@ |
|
|
|
/* |
|
|
|
* The Apache Software License, Version 1.1 |
|
|
|
* The Apache Software License, Version 1.1 |
|
|
|
* |
|
|
|
* Copyright (c) 2002 The Apache Software Foundation. All rights |
|
|
|
* reserved. |
|
|
|
* 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: |
|
|
|
* 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. |
|
|
|
* 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. |
|
|
|
* 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. |
|
|
|
* 3. The end-user documentation included with the redistribution, if |
|
|
|
* any, must include the following acknowlegement: |
|
|
|
* "This product includes software developed by the |
|
|
|
* Apache Software Foundation (http://www.apache.org/)." |
|
|
|
* Alternately, this acknowlegement may appear in the software itself, |
|
|
|
* if and wherever such third-party acknowlegements normally appear. |
|
|
|
* |
|
|
|
* 4. The names "The Jakarta Project", "Ant", and "Apache Software |
|
|
|
* Foundation" must not be used to endorse or promote products derived |
|
|
|
* from this software without prior written permission. For written |
|
|
|
* permission, please contact apache@apache.org. |
|
|
|
* 4. The names "The Jakarta Project", "Ant", and "Apache Software |
|
|
|
* Foundation" must not be used to endorse or promote products derived |
|
|
|
* from this software without prior written permission. For written |
|
|
|
* permission, please contact apache@apache.org. |
|
|
|
* |
|
|
|
* 5. Products derived from this software may not be called "Apache" |
|
|
|
* nor may "Apache" appear in their names without prior written |
|
|
|
* permission of the Apache Group. |
|
|
|
* 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 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/>. |
|
|
|
* 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; |
|
|
@@ -84,10 +84,10 @@ import org.apache.ant.init.InitConfig; |
|
|
|
* contains the data values set by Ant tasks as they are executed, including |
|
|
|
* task definitions, property values, etc. |
|
|
|
* |
|
|
|
* @author Conor MacNeill |
|
|
|
* @created 14 January 2002 |
|
|
|
* @author Conor MacNeill |
|
|
|
* @created 14 January 2002 |
|
|
|
*/ |
|
|
|
public class Frame { |
|
|
|
public class Frame implements DemuxOutputReceiver { |
|
|
|
/** the base dir of the project */ |
|
|
|
private File baseDir; |
|
|
|
|
|
|
@@ -98,20 +98,20 @@ public class Frame { |
|
|
|
private Map referencedFrames = new HashMap(); |
|
|
|
|
|
|
|
/** |
|
|
|
* The context of this execution. This contains all data object's |
|
|
|
* created by tasks that have been executed |
|
|
|
* 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. |
|
|
|
* 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. |
|
|
|
* These are the standard libraries from which taskdefs, typedefs, etc may |
|
|
|
* be imported. |
|
|
|
*/ |
|
|
|
private Map standardLibs; |
|
|
|
|
|
|
@@ -144,17 +144,19 @@ public class Frame { |
|
|
|
*/ |
|
|
|
private ComponentManager componentManager; |
|
|
|
|
|
|
|
/** The core's execution Service */ |
|
|
|
/** The core's execution Service */ |
|
|
|
private CoreExecService execService; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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, |
|
|
@@ -164,23 +166,27 @@ public class Frame { |
|
|
|
this.initConfig = initConfig; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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 { |
|
|
|
return dataService.replacePropertyRefs(value); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Sets the Project of the Frame |
|
|
|
* |
|
|
|
* @param project The new Project value |
|
|
|
* @exception ExecutionException if any required sub-frames cannot be |
|
|
|
* @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 { |
|
|
@@ -192,6 +198,7 @@ public class Frame { |
|
|
|
Project referencedProject |
|
|
|
= project.getReferencedProject(referenceName); |
|
|
|
Frame referencedFrame = createFrame(referencedProject); |
|
|
|
|
|
|
|
referencedFrames.put(referenceName, referencedFrame); |
|
|
|
} |
|
|
|
|
|
|
@@ -200,10 +207,11 @@ public class Frame { |
|
|
|
setMagicProperties(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* get the name of the project associated with this frame. |
|
|
|
* |
|
|
|
* @return the project's name |
|
|
|
* @return the project's name |
|
|
|
*/ |
|
|
|
public String getProjectName() { |
|
|
|
if (project != null) { |
|
|
@@ -211,18 +219,20 @@ public class Frame { |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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 == null) { |
|
|
|
throw new ExecutionException("There is no project corresponding " |
|
|
|
+ "to the name \"" + name + "\""); |
|
|
@@ -239,12 +249,13 @@ public class Frame { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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 { |
|
|
@@ -256,16 +267,19 @@ public class Frame { |
|
|
|
addProperties(System.getProperties()); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Set the values of various magic properties |
|
|
|
* |
|
|
|
* @exception ExecutionException if the properties cannot be set |
|
|
|
* @exception ExecutionException if the properties cannot be set |
|
|
|
*/ |
|
|
|
protected void setMagicProperties() throws ExecutionException { |
|
|
|
URL antHomeURL = initConfig.getAntHome(); |
|
|
|
String antHomeString = null; |
|
|
|
|
|
|
|
if (antHomeURL.getProtocol().equals("file")) { |
|
|
|
File antHome = new File(antHomeURL.getFile()); |
|
|
|
|
|
|
|
antHomeString = antHome.getAbsolutePath(); |
|
|
|
} else { |
|
|
|
antHomeString = antHomeURL.toString(); |
|
|
@@ -273,20 +287,22 @@ public class Frame { |
|
|
|
setDataValue(MagicProperties.ANT_HOME, antHomeString, true); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Get a definition from a referenced frame |
|
|
|
* |
|
|
|
* @param definitionName the name of the definition relative to this |
|
|
|
* frame |
|
|
|
* @return the appropriate import info object from the referenced |
|
|
|
* frame's imports |
|
|
|
* @exception ExecutionException if the referenced definition cannot be |
|
|
|
* @param definitionName the name of the definition relative to |
|
|
|
* this frame |
|
|
|
* @return the appropriate import info object from |
|
|
|
* the referenced frame's imports |
|
|
|
* @exception ExecutionException if the referenced definition cannot be |
|
|
|
* found |
|
|
|
*/ |
|
|
|
protected ImportInfo getReferencedDefinition(String definitionName) |
|
|
|
throws ExecutionException { |
|
|
|
Frame containingFrame = getContainingFrame(definitionName); |
|
|
|
String localName = getNameInFrame(definitionName); |
|
|
|
|
|
|
|
if (containingFrame == null) { |
|
|
|
throw new ExecutionException("There is no project corresponding " |
|
|
|
+ "to the name \"" + definitionName + "\""); |
|
|
@@ -298,10 +314,11 @@ public class Frame { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Gets the project model this frame is working with |
|
|
|
* |
|
|
|
* @return the project model |
|
|
|
* @return the project model |
|
|
|
*/ |
|
|
|
protected Project getProject() { |
|
|
|
return project; |
|
|
@@ -313,20 +330,23 @@ public class Frame { |
|
|
|
* 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 |
|
|
|
* @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); |
|
|
|
} |
|
|
@@ -335,10 +355,11 @@ public class Frame { |
|
|
|
return allProperties; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Get the Ant initialization configuration for this frame. |
|
|
|
* |
|
|
|
* @return Ant's initialization configuration |
|
|
|
* @return Ant's initialization configuration |
|
|
|
*/ |
|
|
|
protected InitConfig getInitConfig() { |
|
|
|
return initConfig; |
|
|
@@ -348,24 +369,27 @@ public class Frame { |
|
|
|
/** |
|
|
|
* Get the config instance being used by this frame. |
|
|
|
* |
|
|
|
* @return the config associated with 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 |
|
|
|
* @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 |
|
|
|
* @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); |
|
|
@@ -373,69 +397,78 @@ public class Frame { |
|
|
|
return service; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Get the EventSupport instance for this frame. This tracks the build |
|
|
|
* listeners on this frame |
|
|
|
* |
|
|
|
* @return the EventSupport instance |
|
|
|
* @return the EventSupport instance |
|
|
|
*/ |
|
|
|
protected BuildEventSupport getEventSupport() { |
|
|
|
return eventSupport; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Gets the baseDir of the Frame |
|
|
|
* |
|
|
|
* @return the baseDir value |
|
|
|
* @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. |
|
|
|
* @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.. |
|
|
|
* @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 |
|
|
|
* @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 |
|
|
|
* @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 == null) { |
|
|
|
throw new ExecutionException("There is no project corresponding " |
|
|
|
+ "to the name \"" + name + "\""); |
|
|
@@ -447,17 +480,19 @@ public class Frame { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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 == null) { |
|
|
|
throw new ExecutionException("There is no project corresponding " |
|
|
|
+ "to the name \"" + name + "\""); |
|
|
@@ -474,12 +509,13 @@ public class Frame { |
|
|
|
* Get the execution frame which contains, directly, the named element |
|
|
|
* where the name is relative to this frame |
|
|
|
* |
|
|
|
* @param elementName The name of the element |
|
|
|
* @return the execution frame for the project that contains the given |
|
|
|
* target |
|
|
|
* @param elementName The name of the element |
|
|
|
* @return the execution frame for the project that contains |
|
|
|
* the given target |
|
|
|
*/ |
|
|
|
protected Frame getContainingFrame(String elementName) { |
|
|
|
int index = elementName.lastIndexOf(Project.REF_DELIMITER); |
|
|
|
|
|
|
|
if (index == -1) { |
|
|
|
return this; |
|
|
|
} |
|
|
@@ -488,8 +524,10 @@ public class Frame { |
|
|
|
String relativeName = elementName.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; |
|
|
@@ -499,81 +537,94 @@ public class Frame { |
|
|
|
return currentFrame; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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. |
|
|
|
* @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. |
|
|
|
* @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 |
|
|
|
* @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 |
|
|
|
* @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 |
|
|
|
* @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 |
|
|
|
* @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(); |
|
|
@@ -582,6 +633,7 @@ public class Frame { |
|
|
|
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); |
|
|
@@ -590,18 +642,20 @@ public class Frame { |
|
|
|
} 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 |
|
|
|
* @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 { |
|
|
@@ -611,10 +665,12 @@ public class Frame { |
|
|
|
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) { |
|
|
@@ -622,25 +678,29 @@ public class Frame { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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()) { |
|
|
|
BuildElement model = (BuildElement) taskIterator.next(); |
|
|
|
|
|
|
|
// what sort of element is this. |
|
|
|
try { |
|
|
|
Object component = componentManager.createComponent(model); |
|
|
|
|
|
|
|
if (component instanceof Task) { |
|
|
|
execService.executeTask((Task) component); |
|
|
|
} else { |
|
|
|
String typeId |
|
|
|
= model.getAspectValue(Constants.ANT_ASPECT, "id"); |
|
|
|
|
|
|
|
if (typeId != null) { |
|
|
|
setDataValue(typeId, component, true); |
|
|
|
} |
|
|
@@ -648,25 +708,28 @@ public class Frame { |
|
|
|
} catch (AntException te) { |
|
|
|
ExecutionException e |
|
|
|
= new ExecutionException(te, te.getLocation()); |
|
|
|
|
|
|
|
e.setLocation(model.getLocation(), false); |
|
|
|
throw e; |
|
|
|
} catch (RuntimeException e) { |
|
|
|
ExecutionException ee = |
|
|
|
new ExecutionException(e.getClass().getName() + ": " |
|
|
|
+ e.getMessage(), e, model.getLocation()); |
|
|
|
|
|
|
|
throw ee; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 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 |
|
|
|
* @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 { |
|
|
@@ -692,6 +755,7 @@ public class Frame { |
|
|
|
|
|
|
|
try { |
|
|
|
Iterator taskIterator = target.getTasks(); |
|
|
|
|
|
|
|
eventSupport.fireTargetStarted(target); |
|
|
|
executeTasks(taskIterator); |
|
|
|
} catch (ExecutionException e) { |
|
|
@@ -702,6 +766,7 @@ public class Frame { |
|
|
|
ExecutionException ee = |
|
|
|
new ExecutionException(e.getClass().getName() + ": " |
|
|
|
+ e.getMessage(), e, target.getLocation()); |
|
|
|
|
|
|
|
failureCause = ee; |
|
|
|
throw ee; |
|
|
|
} finally { |
|
|
@@ -713,22 +778,26 @@ public class Frame { |
|
|
|
/** |
|
|
|
* Initialize the frame by executing the project level tasks if any |
|
|
|
* |
|
|
|
* @exception ExecutionException if the top level tasks of the frame |
|
|
|
* @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); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Determine the base directory for each frame in the frame hierarchy |
|
|
|
* |
|
|
|
* @exception ExecutionException if the base directories cannot be |
|
|
|
* @exception ExecutionException if the base directories cannot be |
|
|
|
* determined |
|
|
|
*/ |
|
|
|
private void determineBaseDirs() throws ExecutionException { |
|
|
@@ -737,14 +806,17 @@ public class Frame { |
|
|
|
= 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 = FileUtils.newFileUtils(); |
|
|
|
|
|
|
|
baseDir = fileUtils.resolveFile(projectFileParent, base); |
|
|
|
} |
|
|
|
} else { |
|
|
@@ -755,10 +827,12 @@ public class Frame { |
|
|
|
|
|
|
|
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 |
|
|
@@ -778,5 +852,19 @@ public class Frame { |
|
|
|
services.put(EventService.class, new CoreEventService(this)); |
|
|
|
services.put(ExecService.class, execService); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Handle the content from a single thread. This method will be called by |
|
|
|
* the thread producing the content. The content is broken up into |
|
|
|
* separate lines |
|
|
|
* |
|
|
|
* @param line the content produce by the current thread. |
|
|
|
* @param isErr true if this content is from the thread's error stream. |
|
|
|
*/ |
|
|
|
public void threadOutput(String line, boolean isErr) { |
|
|
|
eventSupport.threadOutput(line, isErr); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|