git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271149 13f79535-47bb-0310-9956-ffa450edef68master
@@ -52,8 +52,7 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.antlib; | package org.apache.ant.antcore.antlib; | ||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.common.util.ConfigException; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; | ||||
@@ -60,11 +60,11 @@ import java.util.ArrayList; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.apache.ant.antcore.util.CircularDependencyChecker; | |||||
import org.apache.ant.antcore.util.CircularDependencyException; | |||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.antcore.xml.ParseContext; | import org.apache.ant.antcore.xml.ParseContext; | ||||
import org.apache.ant.antcore.xml.XMLParseException; | import org.apache.ant.antcore.xml.XMLParseException; | ||||
import org.apache.ant.common.util.CircularDependencyChecker; | |||||
import org.apache.ant.common.util.CircularDependencyException; | |||||
import org.apache.ant.common.util.ExecutionException; | |||||
import org.apache.ant.init.InitConfig; | import org.apache.ant.init.InitConfig; | ||||
import org.apache.ant.init.InitUtils; | import org.apache.ant.init.InitUtils; | ||||
import org.apache.ant.init.LoaderUtils; | import org.apache.ant.init.LoaderUtils; | ||||
@@ -102,10 +102,10 @@ public class AntLibManager { | |||||
* @param libURL the URL from which Ant libraries are to be loaded | * @param libURL the URL from which Ant libraries are to be loaded | ||||
* @exception MalformedURLException if the URL for the individual | * @exception MalformedURLException if the URL for the individual | ||||
* library components cannot be formed | * library components cannot be formed | ||||
* @exception ConfigException if the library specs cannot be parsed | |||||
* @exception ExecutionException if the library specs cannot be parsed | |||||
*/ | */ | ||||
public void addAntLibraries(Map librarySpecs, URL libURL) | public void addAntLibraries(Map librarySpecs, URL libURL) | ||||
throws MalformedURLException, ConfigException { | |||||
throws MalformedURLException, ExecutionException { | |||||
URL[] libURLs = LoaderUtils.getLocationURLs(libURL, libURL.toString(), | URL[] libURLs = LoaderUtils.getLocationURLs(libURL, libURL.toString(), | ||||
ANTLIB_EXTENSIONS); | ANTLIB_EXTENSIONS); | ||||
@@ -122,7 +122,7 @@ public class AntLibManager { | |||||
if (antLibrarySpec != null) { | if (antLibrarySpec != null) { | ||||
String libraryId = antLibrarySpec.getLibraryId(); | String libraryId = antLibrarySpec.getLibraryId(); | ||||
if (librarySpecs.containsKey(libraryId)) { | if (librarySpecs.containsKey(libraryId)) { | ||||
throw new ConfigException("Found more than one " | |||||
throw new ExecutionException("Found more than one " | |||||
+ "copy of library with id = " + libraryId + | + "copy of library with id = " + libraryId + | ||||
" (" + libURLs[i] + ")"); | " (" + libURLs[i] + ")"); | ||||
} | } | ||||
@@ -134,7 +134,7 @@ public class AntLibManager { | |||||
// ignore file not found exceptions - means the | // ignore file not found exceptions - means the | ||||
// jar does not provide META-INF/antlib.xml | // jar does not provide META-INF/antlib.xml | ||||
if (!(t instanceof FileNotFoundException)) { | if (!(t instanceof FileNotFoundException)) { | ||||
throw new ConfigException("Unable to parse Ant library " | |||||
throw new ExecutionException("Unable to parse Ant library " | |||||
+ libURLs[i], e); | + libURLs[i], e); | ||||
} | } | ||||
} | } | ||||
@@ -149,12 +149,12 @@ public class AntLibManager { | |||||
* @param librarySpecs the loaded specifications of the Ant libraries | * @param librarySpecs the loaded specifications of the Ant libraries | ||||
* @param initConfig the Ant initialization configuration | * @param initConfig the Ant initialization configuration | ||||
* @param libraries the collection of libraries already configured | * @param libraries the collection of libraries already configured | ||||
* @exception ConfigException if a library cannot be configured from the | |||||
* given specification | |||||
* @exception ExecutionException if a library cannot be configured from | |||||
* the given specification | |||||
*/ | */ | ||||
public void configLibraries(InitConfig initConfig, Map librarySpecs, | public void configLibraries(InitConfig initConfig, Map librarySpecs, | ||||
Map libraries) | Map libraries) | ||||
throws ConfigException { | |||||
throws ExecutionException { | |||||
// check if any already defined | // check if any already defined | ||||
for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext(); ) { | for (Iterator i = librarySpecs.keySet().iterator(); i.hasNext(); ) { | ||||
@@ -162,7 +162,7 @@ public class AntLibManager { | |||||
if (libraries.containsKey(libraryId)) { | if (libraries.containsKey(libraryId)) { | ||||
AntLibrary currentVersion | AntLibrary currentVersion | ||||
= (AntLibrary)libraries.get(libraryId); | = (AntLibrary)libraries.get(libraryId); | ||||
throw new ConfigException("Ant Library \"" + libraryId | |||||
throw new ExecutionException("Ant Library \"" + libraryId | |||||
+ "\" is already loaded from " | + "\" is already loaded from " | ||||
+ currentVersion.getDefinitionURL()); | + currentVersion.getDefinitionURL()); | ||||
} | } | ||||
@@ -185,12 +185,12 @@ public class AntLibManager { | |||||
* @param libLocationString URL or file where libraries can be found | * @param libLocationString URL or file where libraries can be found | ||||
* @param librarySpecs A collection of library specs which will be | * @param librarySpecs A collection of library specs which will be | ||||
* populated with the libraries found | * populated with the libraries found | ||||
* @exception ConfigException if the libraries cannot be loaded | |||||
* @exception ExecutionException if the libraries cannot be loaded | |||||
* @exception MalformedURLException if the library's location cannot be | * @exception MalformedURLException if the library's location cannot be | ||||
* formed | * formed | ||||
*/ | */ | ||||
public void loadLib(Map librarySpecs, String libLocationString) | public void loadLib(Map librarySpecs, String libLocationString) | ||||
throws ConfigException, MalformedURLException { | |||||
throws ExecutionException, MalformedURLException { | |||||
File libLocation = new File(libLocationString); | File libLocation = new File(libLocationString); | ||||
if (!libLocation.exists()) { | if (!libLocation.exists()) { | ||||
@@ -198,7 +198,7 @@ public class AntLibManager { | |||||
URL libLocationURL = new URL(libLocationString); | URL libLocationURL = new URL(libLocationString); | ||||
if (!libLocationURL.getProtocol().equals("file") | if (!libLocationURL.getProtocol().equals("file") | ||||
&& !remoteAllowed) { | && !remoteAllowed) { | ||||
throw new ConfigException("The config library " | |||||
throw new ExecutionException("The config library " | |||||
+ "location \"" + libLocationString | + "location \"" + libLocationString | ||||
+ "\" cannot be used because config does " | + "\" cannot be used because config does " | ||||
+ "not allow remote libraries"); | + "not allow remote libraries"); | ||||
@@ -223,13 +223,13 @@ public class AntLibManager { | |||||
* dependencies. | * dependencies. | ||||
* @param libraries the collection of libraries which have already been | * @param libraries the collection of libraries which have already been | ||||
* configured | * configured | ||||
* @exception ConfigException if the library cannot be configured. | |||||
* @exception ExecutionException if the library cannot be configured. | |||||
*/ | */ | ||||
private void configLibrary(InitConfig initConfig, Map librarySpecs, | private void configLibrary(InitConfig initConfig, Map librarySpecs, | ||||
String libraryId, | String libraryId, | ||||
CircularDependencyChecker configuring, | CircularDependencyChecker configuring, | ||||
Map libraries) | Map libraries) | ||||
throws ConfigException { | |||||
throws ExecutionException { | |||||
try { | try { | ||||
configuring.visitNode(libraryId); | configuring.visitNode(libraryId); | ||||
@@ -240,7 +240,7 @@ public class AntLibManager { | |||||
if (extendsId != null) { | if (extendsId != null) { | ||||
if (!libraries.containsKey(extendsId)) { | if (!libraries.containsKey(extendsId)) { | ||||
if (!librarySpecs.containsKey(extendsId)) { | if (!librarySpecs.containsKey(extendsId)) { | ||||
throw new ConfigException("Could not find library, " | |||||
throw new ExecutionException("Could not find library, " | |||||
+ extendsId + ", upon which library " | + extendsId + ", upon which library " | ||||
+ libraryId + " depends"); | + libraryId + " depends"); | ||||
} | } | ||||
@@ -284,7 +284,7 @@ public class AntLibManager { | |||||
libraries.put(libraryId, antLibrary); | libraries.put(libraryId, antLibrary); | ||||
configuring.leaveNode(libraryId); | configuring.leaveNode(libraryId); | ||||
} catch (CircularDependencyException e) { | } catch (CircularDependencyException e) { | ||||
throw new ConfigException(e); | |||||
throw new ExecutionException(e); | |||||
} | } | ||||
} | } | ||||
@@ -57,7 +57,7 @@ import java.util.ArrayList; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.common.util.ConfigException; | |||||
/** | /** | ||||
* This class represents the specification of an Ant library. It is merely | * This class represents the specification of an Ant library. It is merely | ||||
@@ -60,7 +60,7 @@ import java.util.HashMap; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.common.util.ConfigException; | |||||
import org.apache.ant.common.util.PathTokenizer; | import org.apache.ant.common.util.PathTokenizer; | ||||
import org.apache.ant.init.InitUtils; | import org.apache.ant.init.InitUtils; | ||||
@@ -52,7 +52,7 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.config; | package org.apache.ant.antcore.config; | ||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.common.util.ConfigException; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; | ||||
@@ -56,7 +56,7 @@ import java.util.ArrayList; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import org.apache.ant.antcore.model.ModelElement; | |||||
import org.apache.ant.common.model.ModelElement; | |||||
import org.apache.ant.common.event.BuildListener; | import org.apache.ant.common.event.BuildListener; | ||||
import org.apache.ant.common.event.BuildEvent; | import org.apache.ant.common.event.BuildEvent; | ||||
@@ -101,19 +101,6 @@ public class BuildEventSupport { | |||||
listeners.remove(listener); | listeners.remove(listener); | ||||
} | } | ||||
/** | |||||
* Forward the given event to the subscibed listeners | |||||
* | |||||
* @param event the event to be forwarded to the listeners | |||||
*/ | |||||
public void forwardEvent(BuildEvent event) { | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.processBuildEvent(event); | |||||
} | |||||
} | |||||
/** | /** | ||||
* Fire a build started event | * Fire a build started event | ||||
* | * | ||||
@@ -121,7 +108,10 @@ public class BuildEventSupport { | |||||
*/ | */ | ||||
public void fireBuildStarted(ModelElement element) { | public void fireBuildStarted(ModelElement element) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_STARTED); | BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_STARTED); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.buildStarted(event); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -134,7 +124,10 @@ public class BuildEventSupport { | |||||
Throwable cause) { | Throwable cause) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_FINISHED, | BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_FINISHED, | ||||
cause); | cause); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.buildFinished(event); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -144,7 +137,10 @@ public class BuildEventSupport { | |||||
*/ | */ | ||||
public void fireTargetStarted(ModelElement element) { | public void fireTargetStarted(ModelElement element) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_STARTED); | BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_STARTED); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.targetStarted(event); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -157,7 +153,10 @@ public class BuildEventSupport { | |||||
Throwable cause) { | Throwable cause) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_FINISHED, | BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_FINISHED, | ||||
cause); | cause); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.targetFinished(event); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -167,7 +166,10 @@ public class BuildEventSupport { | |||||
*/ | */ | ||||
public void fireTaskStarted(ModelElement element) { | public void fireTaskStarted(ModelElement element) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.TASK_STARTED); | BuildEvent event = new BuildEvent(element, BuildEvent.TASK_STARTED); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.taskStarted(event); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -180,7 +182,10 @@ public class BuildEventSupport { | |||||
Throwable cause) { | Throwable cause) { | ||||
BuildEvent event = new BuildEvent(element, BuildEvent.TASK_FINISHED, | BuildEvent event = new BuildEvent(element, BuildEvent.TASK_FINISHED, | ||||
cause); | cause); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.taskFinished(event); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
@@ -193,7 +198,10 @@ public class BuildEventSupport { | |||||
public void fireMessageLogged(ModelElement element, | public void fireMessageLogged(ModelElement element, | ||||
String message, int priority) { | String message, int priority) { | ||||
BuildEvent event = new BuildEvent(element, message, priority); | BuildEvent event = new BuildEvent(element, message, priority); | ||||
forwardEvent(event); | |||||
for (Iterator i = listeners.iterator(); i.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)i.next(); | |||||
listener.messageLogged(event); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -95,7 +95,16 @@ public class ClassIntrospector { | |||||
&& !args[0].isArray()) { | && !args[0].isArray()) { | ||||
reflector.addAttributeMethod(m, getPropertyName(name, "set"), | reflector.addAttributeMethod(m, getPropertyName(name, "set"), | ||||
converters); | converters); | ||||
} else if (name.startsWith("add") | |||||
} else if (name.startsWith("addConfigured") | |||||
&& name.length() > 13 | |||||
&& returnType.equals(Void.TYPE) | |||||
&& args.length == 1 | |||||
&& !args[0].equals(String.class) | |||||
&& !args[0].isArray() | |||||
&& !args[0].isPrimitive()) { | |||||
reflector.addElementMethod(m, | |||||
getPropertyName(name, "addConfigured")); | |||||
} else if (name.startsWith("add") | |||||
&& name.length() > 3 | && name.length() > 3 | ||||
&& returnType.equals(Void.TYPE) | && returnType.equals(Void.TYPE) | ||||
&& args.length == 1 | && args.length == 1 | ||||
@@ -103,7 +112,7 @@ public class ClassIntrospector { | |||||
&& !args[0].isArray() | && !args[0].isArray() | ||||
&& !args[0].isPrimitive()) { | && !args[0].isPrimitive()) { | ||||
reflector.addElementMethod(m, getPropertyName(name, "add")); | reflector.addElementMethod(m, getPropertyName(name, "add")); | ||||
} else if (name.startsWith("create") | |||||
} else if (name.startsWith("create") | |||||
&& name.length() > 6 | && name.length() > 6 | ||||
&& !returnType.isArray() | && !returnType.isArray() | ||||
&& !returnType.isPrimitive() | && !returnType.isPrimitive() | ||||
@@ -0,0 +1,358 @@ | |||||
/* | |||||
* 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 apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <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.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 | |||||
* ant libraries. | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 27 January 2002 | |||||
*/ | |||||
public class ComponentManager implements ComponentService { | |||||
/** The prefix for library ids that are automatically imported */ | |||||
public final static String ANT_LIB_PREFIX = "ant."; | |||||
/** | |||||
* Type converters for this executionFrame. 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 library manager instance used to configure libraries. */ | |||||
private AntLibManager libManager; | |||||
/** | |||||
* These are AntLibraries which have been loaded into this component | |||||
* manager | |||||
*/ | |||||
private Map antLibraries; | |||||
/** The definitions which have been imported into this frame. */ | |||||
private Map definitions = new HashMap(); | |||||
/** | |||||
* Constructor | |||||
* | |||||
* @param executionFrame the frame containing this context | |||||
* @param allowRemoteLibs true if remote libraries can be loaded though | |||||
* this service. | |||||
*/ | |||||
protected ComponentManager(ExecutionFrame executionFrame, | |||||
boolean allowRemoteLibs) { | |||||
this.frame = executionFrame; | |||||
libManager = new AntLibManager(allowRemoteLibs); | |||||
} | |||||
/** | |||||
* Load a library or set of libraries from a location making them | |||||
* available for use | |||||
* | |||||
* @param libLocation the file or URL of the library location | |||||
* @param importAll if true all tasks are imported as the library is | |||||
* loaded | |||||
* @exception ExecutionException if the library cannot be loaded | |||||
*/ | |||||
public void loadLib(String libLocation, boolean importAll) | |||||
throws ExecutionException { | |||||
try { | |||||
Map librarySpecs = new HashMap(); | |||||
libManager.loadLib(librarySpecs, libLocation); | |||||
libManager.configLibraries(frame.getInitConfig(), librarySpecs, | |||||
antLibraries); | |||||
if (importAll) { | |||||
Iterator i = librarySpecs.keySet().iterator(); | |||||
while (i.hasNext()) { | |||||
String libraryId = (String)i.next(); | |||||
importLibrary(libraryId); | |||||
} | |||||
} | |||||
} catch (MalformedURLException e) { | |||||
throw new ExecutionException("Unable to load libraries from " | |||||
+ libLocation, e); | |||||
} | |||||
} | |||||
/** | |||||
* 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); | |||||
} | |||||
/** | |||||
* Set the standard libraries (i.e. those which are independent of the | |||||
* build files) to be used in this component manager | |||||
* | |||||
* @param standardLibs A collection of AntLibrary objects indexed by | |||||
* their libraryId | |||||
* @exception ExecutionException if the components cannot be imported | |||||
* form the libraries fro which such importing is automatic. | |||||
*/ | |||||
protected void setStandardLibraries(Map standardLibs) | |||||
throws ExecutionException { | |||||
antLibraries = new HashMap(standardLibs); | |||||
// go through the libraries and import all standard ant libraries | |||||
for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) { | |||||
String libraryId = (String)i.next(); | |||||
if (libraryId.startsWith(ANT_LIB_PREFIX)) { | |||||
// standard library - import whole library | |||||
importLibrary(libraryId); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* Get the collection ov converters currently configured | |||||
* | |||||
* @return A map of converter instances indexed on the class they can | |||||
* convert | |||||
*/ | |||||
protected Map getConverters() { | |||||
return converters; | |||||
} | |||||
/** | |||||
* 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 | |||||
* | |||||
* @param antLibrary the library for which the factory is required | |||||
* @return the library's factory object | |||||
* @exception ExecutionException if the factory cannot be initialised | |||||
*/ | |||||
protected AntLibFactory getLibFactory(AntLibrary antLibrary) | |||||
throws ExecutionException { | |||||
String libraryId = antLibrary.getLibraryId(); | |||||
if (libFactories.containsKey(libraryId)) { | |||||
return (AntLibFactory)libFactories.get(libraryId); | |||||
} | |||||
AntLibFactory libFactory = antLibrary.getFactory(); | |||||
if (libFactory == null) { | |||||
libFactory = new StandardLibFactory(); | |||||
} | |||||
libFactories.put(libraryId, libFactory); | |||||
libFactory.init(new ExecutionContext(frame)); | |||||
return libFactory; | |||||
} | |||||
/** | |||||
* Get an imported definition from the component manager | |||||
* | |||||
* @param name the name under which the component has been imported | |||||
* @return the ImportInfo object detailing the import's library and | |||||
* other details | |||||
*/ | |||||
protected ImportInfo getDefinition(String name) { | |||||
return (ImportInfo)definitions.get(name); | |||||
} | |||||
/** | |||||
* Import a complete library into this frame | |||||
* | |||||
* @param libraryId The id of the library to be imported | |||||
* @exception ExecutionException if the library cannot be imported | |||||
*/ | |||||
protected void importLibrary(String libraryId) throws ExecutionException { | |||||
AntLibrary library = (AntLibrary)antLibraries.get(libraryId); | |||||
if (library == null) { | |||||
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(); ) { | |||||
String defName = (String)i.next(); | |||||
AntLibDefinition libdef | |||||
= (AntLibDefinition)libDefs.get(defName); | |||||
definitions.put(defName, new ImportInfo(library, libdef)); | |||||
} | |||||
addLibraryConverters(library); | |||||
} | |||||
/** | |||||
* Add the converters from the given library to those managed by this | |||||
* frame. | |||||
* | |||||
* @param library the library from which the converters are required | |||||
* @exception ExecutionException if a converter defined in the library | |||||
* cannot be instantiated | |||||
*/ | |||||
private void addLibraryConverters(AntLibrary library) | |||||
throws ExecutionException { | |||||
if (!library.hasConverters()) { | |||||
return; | |||||
} | |||||
String className = null; | |||||
try { | |||||
AntLibFactory libFactory = getLibFactory(library); | |||||
ClassLoader converterLoader = library.getClassLoader(); | |||||
for (Iterator i = library.getConverterClassNames(); i.hasNext(); ) { | |||||
className = (String)i.next(); | |||||
Class converterClass | |||||
= Class.forName(className, true, converterLoader); | |||||
if (!Converter.class.isAssignableFrom(converterClass)) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() + "\" the converter class " | |||||
+ converterClass.getName() | |||||
+ " does not implement the Converter interface"); | |||||
} | |||||
Converter converter | |||||
= libFactory.createConverter(converterClass); | |||||
ExecutionContext context | |||||
= new ExecutionContext(frame); | |||||
converter.init(context); | |||||
Class[] converterTypes = converter.getTypes(); | |||||
for (int j = 0; j < converterTypes.length; ++j) { | |||||
converters.put(converterTypes[j], converter); | |||||
} | |||||
} | |||||
} catch (ClassNotFoundException e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() + "\" converter class " | |||||
+ className + " was not found", e); | |||||
} catch (NoClassDefFoundError e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() | |||||
+ "\" could not load a dependent class (" | |||||
+ e.getMessage() + ") for converter " + className); | |||||
} catch (InstantiationException e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() | |||||
+ "\" unable to instantiate converter class " | |||||
+ className, e); | |||||
} catch (IllegalAccessException e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() | |||||
+ "\" unable to access converter class " | |||||
+ className, e); | |||||
} | |||||
} | |||||
} | |||||
@@ -53,11 +53,10 @@ | |||||
*/ | */ | ||||
package org.apache.ant.antcore.execution; | package org.apache.ant.antcore.execution; | ||||
import java.io.File; | import java.io.File; | ||||
import org.apache.ant.antcore.model.ModelElement; | |||||
import org.apache.ant.common.antlib.AntContext; | import org.apache.ant.common.antlib.AntContext; | ||||
import org.apache.ant.common.model.ModelElement; | |||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
import org.apache.ant.common.util.FileUtils; | import org.apache.ant.common.util.FileUtils; | ||||
import org.apache.ant.common.util.Location; | |||||
/** | /** | ||||
* This is the core's implementation of the AntContext for all core objects. | * This is the core's implementation of the AntContext for all core objects. | ||||
@@ -83,13 +82,10 @@ public class ExecutionContext implements AntContext { | |||||
* Initilaise this context's environment | * Initilaise this context's environment | ||||
* | * | ||||
* @param frame the frame containing this context | * @param frame the frame containing this context | ||||
* @param eventSupport the event support instance used to send build | |||||
* events | |||||
*/ | */ | ||||
public ExecutionContext(ExecutionFrame frame, | |||||
BuildEventSupport eventSupport) { | |||||
public ExecutionContext(ExecutionFrame frame) { | |||||
this.frame = frame; | this.frame = frame; | ||||
this.eventSupport = eventSupport; | |||||
this.eventSupport = frame.getEventSupport(); | |||||
} | } | ||||
/** | /** | ||||
@@ -116,15 +112,17 @@ public class ExecutionContext implements AntContext { | |||||
} | } | ||||
/** | /** | ||||
* Get the build fiel location with which this context is associated | |||||
* Get the model element associated with this context. If the context is | |||||
* not associated with any particular model element, the project model | |||||
* is returned. | |||||
* | * | ||||
* @return the associated location object. | |||||
* @return the model element. | |||||
*/ | */ | ||||
public Location getLocation() { | |||||
if (modelElement != null) { | |||||
return modelElement.getLocation(); | |||||
public ModelElement getModelElement() { | |||||
if (modelElement == null) { | |||||
return frame.getProject(); | |||||
} | } | ||||
return Location.UNKNOWN_LOCATION; | |||||
return modelElement; | |||||
} | } | ||||
/** | /** | ||||
@@ -131,6 +131,18 @@ public class ExecutionDataService implements DataService { | |||||
return frame.isDataValueSet(name); | 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 | * Replace ${} style constructions in the given value with the string | ||||
* value of the corresponding data values in the frame | * value of the corresponding data values in the frame | ||||
@@ -157,8 +169,8 @@ public class ExecutionDataService implements DataService { | |||||
if (fragment == null) { | if (fragment == null) { | ||||
String propertyName = (String)j.next(); | String propertyName = (String)j.next(); | ||||
if (!isDataValueSet(propertyName)) { | if (!isDataValueSet(propertyName)) { | ||||
throw new ExecutionException("Property " + propertyName | |||||
+ " has not been set"); | |||||
throw new ExecutionException("Property \"" + propertyName | |||||
+ "\" has not been set"); | |||||
} | } | ||||
fragment = getDataValue(propertyName).toString(); | fragment = getDataValue(propertyName).toString(); | ||||
} | } | ||||
@@ -207,16 +219,5 @@ public class ExecutionDataService implements DataService { | |||||
return sb.toString(); | return sb.toString(); | ||||
} | } | ||||
/** | |||||
* 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(); | |||||
} | |||||
} | } | ||||
@@ -59,25 +59,23 @@ import java.util.Iterator; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import org.apache.ant.antcore.antlib.AntLibDefinition; | |||||
import org.apache.ant.antcore.antlib.AntLibrary; | import org.apache.ant.antcore.antlib.AntLibrary; | ||||
import org.apache.ant.antcore.config.AntConfig; | import org.apache.ant.antcore.config.AntConfig; | ||||
import org.apache.ant.antcore.model.BuildElement; | |||||
import org.apache.ant.antcore.model.Project; | |||||
import org.apache.ant.antcore.model.Target; | |||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.common.antlib.AntLibFactory; | import org.apache.ant.common.antlib.AntLibFactory; | ||||
import org.apache.ant.common.antlib.Converter; | |||||
import org.apache.ant.common.antlib.ExecutionComponent; | import org.apache.ant.common.antlib.ExecutionComponent; | ||||
import org.apache.ant.common.antlib.StandardLibFactory; | |||||
import org.apache.ant.common.antlib.Task; | import org.apache.ant.common.antlib.Task; | ||||
import org.apache.ant.common.antlib.TaskContainer; | import org.apache.ant.common.antlib.TaskContainer; | ||||
import org.apache.ant.common.event.BuildListener; | 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.ComponentService; | ||||
import org.apache.ant.common.service.DataService; | import org.apache.ant.common.service.DataService; | ||||
import org.apache.ant.common.service.FileService; | import org.apache.ant.common.service.FileService; | ||||
import org.apache.ant.common.util.AntException; | 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.ExecutionException; | ||||
import org.apache.ant.common.util.FileUtils; | |||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; | ||||
import org.apache.ant.common.util.MessageLevel; | import org.apache.ant.common.util.MessageLevel; | ||||
import org.apache.ant.init.InitConfig; | import org.apache.ant.init.InitConfig; | ||||
@@ -91,74 +89,18 @@ import org.apache.ant.init.InitConfig; | |||||
* @created 14 January 2002 | * @created 14 January 2002 | ||||
*/ | */ | ||||
public class ExecutionFrame { | public class ExecutionFrame { | ||||
/** | |||||
* This class is used to maintain information about imports | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 16 January 2002 | |||||
*/ | |||||
private static class ImportInfo { | |||||
/** the ant library from which the import is made */ | |||||
private AntLibrary library; | |||||
/** the library definition information */ | |||||
private AntLibDefinition libDefinition; | |||||
/** | |||||
* ImportInfo records what has been imported from an Ant Library | |||||
* | |||||
* @param library The library from which the import was made | |||||
* @param libDefinition the library definition information | |||||
*/ | |||||
public ImportInfo(AntLibrary library, AntLibDefinition libDefinition) { | |||||
this.library = library; | |||||
this.libDefinition = libDefinition; | |||||
} | |||||
/** | |||||
* Get the classname that has been imported | |||||
* | |||||
* @return the classname that was imported. | |||||
*/ | |||||
public String getClassName() { | |||||
return libDefinition.getClassName(); | |||||
} | |||||
/** | |||||
* Get the library from which the import was made | |||||
* | |||||
* @return the library from which the import was made | |||||
*/ | |||||
public AntLibrary getAntLibrary() { | |||||
return library; | |||||
} | |||||
/** | |||||
* Get the type of the definition that was imported | |||||
* | |||||
* @return the type of definition | |||||
*/ | |||||
public int getDefinitionType() { | |||||
return libDefinition.getDefinitionType(); | |||||
} | |||||
} | |||||
/** A magic property which sets the execution base directory */ | |||||
public final static String BASEDIR_PROP = "basedir"; | |||||
/** The Ant aspect used to identify Ant metadata */ | /** The Ant aspect used to identify Ant metadata */ | ||||
public final static String ANT_ASPECT = "ant"; | public final static String ANT_ASPECT = "ant"; | ||||
/** The prefix for library ids that are automatically imported */ | |||||
public final static String ANT_LIB_PREFIX = "ant."; | |||||
/** the base dir of the project */ | /** the base dir of the project */ | ||||
private File baseDir; | private File baseDir; | ||||
/** The Project that this execution frame is processing */ | /** The Project that this execution frame is processing */ | ||||
private Project project = null; | private Project project = null; | ||||
/** The factory objects for each library, indexed by the library Id */ | |||||
private Map libFactories = new HashMap(); | |||||
/** The referenced frames corresponding to the referenced projects */ | /** The referenced frames corresponding to the referenced projects */ | ||||
private Map referencedFrames = new HashMap(); | private Map referencedFrames = new HashMap(); | ||||
@@ -183,24 +125,9 @@ public class ExecutionFrame { | |||||
*/ | */ | ||||
private Map standardLibs; | private Map standardLibs; | ||||
/** | |||||
* These are AntLibraries which have been loaded in this | |||||
* ExecutionFrame's build file. | |||||
*/ | |||||
private Map antLibraries; | |||||
/** The definitions which have been imported into this frame. */ | |||||
private Map definitions = new HashMap(); | |||||
/** BuildEvent support used to fire events and manage listeners */ | /** BuildEvent support used to fire events and manage listeners */ | ||||
private BuildEventSupport eventSupport = new BuildEventSupport(); | private BuildEventSupport eventSupport = new BuildEventSupport(); | ||||
/** | |||||
* Type converters for this executionFrame. Converters are used when | |||||
* configuring Tasks to handle special type conversions. | |||||
*/ | |||||
private Map converters = new HashMap(); | |||||
/** | /** | ||||
* The services map is a map of service interface classes to instances | * The services map is a map of service interface classes to instances | ||||
* which provide the service. | * which provide the service. | ||||
@@ -218,6 +145,15 @@ public class ExecutionFrame { | |||||
*/ | */ | ||||
private DataService dataService; | 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 | * Create an Execution Frame for the given project | ||||
* | * | ||||
@@ -225,32 +161,17 @@ public class ExecutionFrame { | |||||
* this frame | * this frame | ||||
* @param config the user config to use for this execution of Ant | * @param config the user config to use for this execution of Ant | ||||
* @param initConfig Ant's initialisation config | * @param initConfig Ant's initialisation config | ||||
* @exception ConfigException if a component of the library cannot be | |||||
* @exception ExecutionException if a component of the library cannot be | |||||
* imported | * imported | ||||
*/ | */ | ||||
protected ExecutionFrame(Map standardLibs, InitConfig initConfig, | protected ExecutionFrame(Map standardLibs, InitConfig initConfig, | ||||
AntConfig config) throws ConfigException { | |||||
AntConfig config) throws ExecutionException { | |||||
this.standardLibs = standardLibs; | this.standardLibs = standardLibs; | ||||
this.config = config; | this.config = config; | ||||
this.initConfig = initConfig; | this.initConfig = initConfig; | ||||
configureServices(); | configureServices(); | ||||
antLibraries = new HashMap(standardLibs); | |||||
try { | |||||
// go through the libraries and import all standard ant libraries | |||||
for (Iterator i = antLibraries.keySet().iterator(); i.hasNext(); ) { | |||||
String libraryId = (String)i.next(); | |||||
if (libraryId.startsWith(ANT_LIB_PREFIX)) { | |||||
// standard library - import whole library | |||||
importLibrary(libraryId); | |||||
} | |||||
} | |||||
} catch (ExecutionException e) { | |||||
throw new ConfigException(e); | |||||
} | |||||
componentManager.setStandardLibraries(standardLibs); | |||||
} | } | ||||
/** | /** | ||||
@@ -267,88 +188,24 @@ public class ExecutionFrame { | |||||
return currentLoader; | return currentLoader; | ||||
} | } | ||||
/** | |||||
* Gets the project model this frame is working with | |||||
* | |||||
* @return the project model | |||||
*/ | |||||
public 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. | |||||
*/ | |||||
public Map getAllProperties() { | |||||
Map allProperties = new HashMap(dataValues); | |||||
Iterator i = referencedFrames.keySet().iterator(); | |||||
while (i.hasNext()) { | |||||
String refName = (String)i.next(); | |||||
ExecutionFrame 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; | |||||
} | |||||
/** | |||||
* Log a message as a build event | |||||
* | |||||
* @param message the message to be logged | |||||
* @param level the priority level of the message | |||||
*/ | |||||
public void log(String message, int level) { | |||||
eventSupport.fireMessageLogged(project, message, level); | |||||
} | |||||
/** | /** | ||||
* Sets the Project of the ExecutionFrame | * Sets the Project of the ExecutionFrame | ||||
* | * | ||||
* @param project The new Project value | * @param project The new Project value | ||||
* @exception ConfigException if any required sub-frames cannot be | |||||
* @exception ExecutionException if any required sub-frames cannot be | |||||
* created and configured | * created and configured | ||||
*/ | */ | ||||
protected void setProject(Project project) throws ConfigException { | |||||
protected void setProject(Project project) throws ExecutionException { | |||||
this.project = project; | this.project = project; | ||||
URL projectURL = project.getSourceURL(); | |||||
if (projectURL.getProtocol().equals("file")) { | |||||
File projectFile = new File(projectURL.getFile()); | |||||
String base = project.getBase(); | |||||
if (base == null) { | |||||
base = "."; | |||||
} | |||||
baseDir = new File(projectFile.getParentFile(), base); | |||||
} else { | |||||
baseDir = new File("."); | |||||
} | |||||
referencedFrames = new HashMap(); | referencedFrames = new HashMap(); | ||||
for (Iterator i = project.getReferencedProjectNames(); i.hasNext(); ) { | for (Iterator i = project.getReferencedProjectNames(); i.hasNext(); ) { | ||||
String referenceName = (String)i.next(); | String referenceName = (String)i.next(); | ||||
Project referencedProject | Project referencedProject | ||||
= project.getReferencedProject(referenceName); | = project.getReferencedProject(referenceName); | ||||
ExecutionFrame referencedFrame | |||||
= new ExecutionFrame(standardLibs, initConfig, config); | |||||
referencedFrame.setProject(referencedProject); | |||||
ExecutionFrame referencedFrame = createFrame(referencedProject); | |||||
referencedFrames.put(referenceName, referencedFrame); | referencedFrames.put(referenceName, referencedFrame); | ||||
for (Iterator j = eventSupport.getListeners(); j.hasNext(); ) { | |||||
BuildListener listener = (BuildListener)j.next(); | |||||
referencedFrame.addBuildListener(listener); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -376,12 +233,59 @@ public class ExecutionFrame { | |||||
} | } | ||||
/** | /** | ||||
* Get the collection of Ant Libraries defined for this 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 | |||||
*/ | |||||
protected void setInitialProperties(Map properties) | |||||
throws ExecutionException { | |||||
if (properties == null) { | |||||
return; | |||||
} | |||||
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) { | |||||
String name = (String)i.next(); | |||||
Object value = properties.get(name); | |||||
setDataValue(name, value, false); | |||||
} | |||||
} | |||||
/** | |||||
* 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 of Ant Libraries indexed by thier library Id | |||||
* @return a Map containing the frames properties indexed by their full | |||||
* name. | |||||
*/ | */ | ||||
protected Map getAntLibraries() { | |||||
return antLibraries; | |||||
protected Map getAllProperties() { | |||||
Map allProperties = new HashMap(dataValues); | |||||
Iterator i = referencedFrames.keySet().iterator(); | |||||
while (i.hasNext()) { | |||||
String refName = (String)i.next(); | |||||
ExecutionFrame 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; | |||||
} | } | ||||
/** | /** | ||||
@@ -422,6 +326,16 @@ public class ExecutionFrame { | |||||
return service; | 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 ExecutionFrame | * Gets the baseDir of the ExecutionFrame | ||||
* | * | ||||
@@ -500,6 +414,35 @@ public class ExecutionFrame { | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Create a new frame for a given project | |||||
* | |||||
* @param project the project model the frame will deal with | |||||
* @return an ExecutionFrame ready to build the project | |||||
* @exception ExecutionException if the frame cannot be created. | |||||
*/ | |||||
protected ExecutionFrame createFrame(Project project) | |||||
throws ExecutionException { | |||||
ExecutionFrame newFrame | |||||
= new ExecutionFrame(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 | * Add a build listener to this execution frame | ||||
* | * | ||||
@@ -533,9 +476,9 @@ public class ExecutionFrame { | |||||
* @exception ExecutionException if there is a problem in the build | * @exception ExecutionException if there is a problem in the build | ||||
*/ | */ | ||||
protected void runBuild(List targets) throws ExecutionException { | protected void runBuild(List targets) throws ExecutionException { | ||||
System.out.println("Initilizing frame"); | |||||
determineBaseDirs(); | |||||
initialize(); | initialize(); | ||||
log("Initialized", MessageLevel.MSG_DEBUG); | |||||
if (targets.isEmpty()) { | if (targets.isEmpty()) { | ||||
// we just execute the default target if any | // we just execute the default target if any | ||||
String defaultTarget = project.getDefaultTarget(); | String defaultTarget = project.getDefaultTarget(); | ||||
@@ -565,8 +508,8 @@ public class ExecutionFrame { | |||||
// to execute a target we must determine its dependencies and | // to execute a target we must determine its dependencies and | ||||
// execute them in order. | // execute them in order. | ||||
// firstly build a list of fully qualified target names to execute. | |||||
try { | try { | ||||
// firstly build a list of fully qualified target names to execute. | |||||
List dependencyOrder = project.getTargetDependencies(targetName); | List dependencyOrder = project.getTargetDependencies(targetName); | ||||
for (Iterator i = dependencyOrder.iterator(); i.hasNext(); ) { | for (Iterator i = dependencyOrder.iterator(); i.hasNext(); ) { | ||||
String fullTargetName = (String)i.next(); | String fullTargetName = (String)i.next(); | ||||
@@ -577,6 +520,7 @@ public class ExecutionFrame { | |||||
} catch (ConfigException e) { | } catch (ConfigException e) { | ||||
throw new ExecutionException(e); | throw new ExecutionException(e); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
@@ -593,7 +537,7 @@ public class ExecutionFrame { | |||||
BuildElement model = (BuildElement)taskIterator.next(); | BuildElement model = (BuildElement)taskIterator.next(); | ||||
// what sort of element is this. | // what sort of element is this. | ||||
ImportInfo importInfo | ImportInfo importInfo | ||||
= (ImportInfo)definitions.get(model.getType()); | |||||
= componentManager.getDefinition(model.getType()); | |||||
if (importInfo == null) { | if (importInfo == null) { | ||||
throw new ExecutionException("There is no definition for the <" | throw new ExecutionException("There is no definition for the <" | ||||
+ model.getType() + "> element", model.getLocation()); | + model.getType() + "> element", model.getLocation()); | ||||
@@ -620,10 +564,7 @@ public class ExecutionFrame { | |||||
} catch (AntException te) { | } catch (AntException te) { | ||||
ExecutionException e | ExecutionException e | ||||
= new ExecutionException(te, te.getLocation()); | = new ExecutionException(te, te.getLocation()); | ||||
if (e.getLocation() == null | |||||
|| e.getLocation() == Location.UNKNOWN_LOCATION) { | |||||
e.setLocation(model.getLocation()); | |||||
} | |||||
e.setLocation(model.getLocation(), false); | |||||
failureCause = e; | failureCause = e; | ||||
throw e; | throw e; | ||||
} catch (RuntimeException e) { | } catch (RuntimeException e) { | ||||
@@ -653,12 +594,7 @@ public class ExecutionFrame { | |||||
eventSupport.fireTargetStarted(target); | eventSupport.fireTargetStarted(target); | ||||
executeTasks(taskIterator); | executeTasks(taskIterator); | ||||
} catch (ExecutionException e) { | } catch (ExecutionException e) { | ||||
System.out.println("Exception location is " + e.getLocation()); | |||||
if (e.getLocation() == null | |||||
|| e.getLocation() == Location.UNKNOWN_LOCATION) { | |||||
e.setLocation(target.getLocation()); | |||||
} | |||||
System.out.println("Exception location is now " + e.getLocation()); | |||||
e.setLocation(target.getLocation(), false); | |||||
failureCause = e; | failureCause = e; | ||||
throw e; | throw e; | ||||
} catch (RuntimeException e) { | } catch (RuntimeException e) { | ||||
@@ -686,28 +622,6 @@ public class ExecutionFrame { | |||||
} | } | ||||
/** | |||||
* Import a complete library into this frame | |||||
* | |||||
* @param libraryId The id of the library to be imported | |||||
* @exception ExecutionException if the library cannot be imported | |||||
*/ | |||||
protected void importLibrary(String libraryId) throws ExecutionException { | |||||
AntLibrary library = (AntLibrary)antLibraries.get(libraryId); | |||||
if (library == null) { | |||||
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(); ) { | |||||
String defName = (String)i.next(); | |||||
AntLibDefinition libdef | |||||
= (AntLibDefinition)libDefs.get(defName); | |||||
definitions.put(defName, new ImportInfo(library, libdef)); | |||||
} | |||||
addLibraryConverters(library); | |||||
} | |||||
/** | /** | ||||
* Gets the reflector for the given class | * Gets the reflector for the given class | ||||
* | * | ||||
@@ -718,7 +632,8 @@ public class ExecutionFrame { | |||||
if (reflectors.containsKey(c)) { | if (reflectors.containsKey(c)) { | ||||
return (Reflector)reflectors.get(c); | return (Reflector)reflectors.get(c); | ||||
} | } | ||||
ClassIntrospector introspector = new ClassIntrospector(c, converters); | |||||
ClassIntrospector introspector | |||||
= new ClassIntrospector(c, componentManager.getConverters()); | |||||
Reflector reflector = introspector.getReflector(); | Reflector reflector = introspector.getReflector(); | ||||
reflectors.put(c, reflector); | reflectors.put(c, reflector); | ||||
return reflector; | return reflector; | ||||
@@ -755,27 +670,36 @@ public class ExecutionFrame { | |||||
} | } | ||||
/** | /** | ||||
* Gets the factory object for the given library | |||||
* Determine the base directory for each frame in the frame hierarchy | |||||
* | * | ||||
* @param antLibrary the library for which the factory instance is | |||||
* required. | |||||
* @return the library;s factory object | |||||
* @exception ExecutionException the factory object for the library | |||||
* cannot be created. | |||||
* @exception ExecutionException if the base directories cannot be | |||||
* determined | |||||
*/ | */ | ||||
private AntLibFactory getLibFactory(AntLibrary antLibrary) | |||||
throws ExecutionException { | |||||
String libraryId = antLibrary.getLibraryId(); | |||||
if (libFactories.containsKey(libraryId)) { | |||||
return (AntLibFactory)libFactories.get(libraryId); | |||||
private void determineBaseDirs() throws ExecutionException { | |||||
if (isDataValueSet(BASEDIR_PROP)) { | |||||
baseDir = new File(getDataValue(BASEDIR_PROP).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(BASEDIR_PROP, baseDir.getPath(), true); | |||||
} | } | ||||
AntLibFactory libFactory = antLibrary.getFactory(); | |||||
if (libFactory == null) { | |||||
libFactory = new StandardLibFactory(); | |||||
for (Iterator i = getReferencedFrames(); i.hasNext(); ) { | |||||
ExecutionFrame refFrame = (ExecutionFrame)i.next(); | |||||
refFrame.determineBaseDirs(); | |||||
} | } | ||||
libFactories.put(libraryId, libFactory); | |||||
libFactory.init(new ExecutionContext(this, eventSupport)); | |||||
return libFactory; | |||||
} | } | ||||
/** | /** | ||||
@@ -784,71 +708,14 @@ public class ExecutionFrame { | |||||
*/ | */ | ||||
private void configureServices() { | private void configureServices() { | ||||
// create services and make them available in our services map | // create services and make them available in our services map | ||||
services.put(FileService.class, new ExecutionFileService(this)); | |||||
services.put(ComponentService.class, | |||||
new ExecutionComponentService(this, config.isRemoteLibAllowed())); | |||||
fileService = new ExecutionFileService(this); | |||||
componentManager | |||||
= new ComponentManager(this, config.isRemoteLibAllowed()); | |||||
dataService = new ExecutionDataService(this); | dataService = new ExecutionDataService(this); | ||||
services.put(DataService.class, dataService); | |||||
} | |||||
/** | |||||
* Add the converters from the given library to those managed by this | |||||
* frame. | |||||
* | |||||
* @param library the library from which the converters are required | |||||
* @exception ExecutionException if a converter defined in the library | |||||
* cannot be instantiated | |||||
*/ | |||||
private void addLibraryConverters(AntLibrary library) | |||||
throws ExecutionException { | |||||
if (!library.hasConverters()) { | |||||
return; | |||||
} | |||||
String className = null; | |||||
try { | |||||
AntLibFactory libFactory = getLibFactory(library); | |||||
ClassLoader converterLoader = library.getClassLoader(); | |||||
for (Iterator i = library.getConverterClassNames(); i.hasNext(); ) { | |||||
className = (String)i.next(); | |||||
Class converterClass | |||||
= Class.forName(className, true, converterLoader); | |||||
if (!Converter.class.isAssignableFrom(converterClass)) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() + "\" the converter class " | |||||
+ converterClass.getName() | |||||
+ " does not implement the Converter interface"); | |||||
} | |||||
Converter converter | |||||
= libFactory.createConverter(converterClass); | |||||
ExecutionContext context | |||||
= new ExecutionContext(this, eventSupport); | |||||
converter.init(context); | |||||
Class[] converterTypes = converter.getTypes(); | |||||
for (int j = 0; j < converterTypes.length; ++j) { | |||||
converters.put(converterTypes[j], converter); | |||||
} | |||||
} | |||||
} catch (ClassNotFoundException e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() + "\" converter class " | |||||
+ className + " was not found", e); | |||||
} catch (NoClassDefFoundError e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() | |||||
+ "\" could not load a dependent class (" | |||||
+ e.getMessage() + ") for converter " + className); | |||||
} catch (InstantiationException e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() | |||||
+ "\" unable to instantiate converter class " | |||||
+ className, e); | |||||
} catch (IllegalAccessException e) { | |||||
throw new ExecutionException("In Ant library \"" | |||||
+ library.getLibraryId() | |||||
+ "\" unable to access converter class " | |||||
+ className, e); | |||||
} | |||||
services.put(FileService.class, fileService); | |||||
services.put(ComponentService.class, componentManager); | |||||
services.put(DataService.class, dataService); | |||||
} | } | ||||
/** | /** | ||||
@@ -890,7 +757,7 @@ public class ExecutionFrame { | |||||
BuildElement nestedElementModel = (BuildElement)i.next(); | BuildElement nestedElementModel = (BuildElement)i.next(); | ||||
String nestedElementName = nestedElementModel.getType(); | String nestedElementName = nestedElementModel.getType(); | ||||
ImportInfo info = (ImportInfo)definitions.get(nestedElementName); | |||||
ImportInfo info = componentManager.getDefinition(nestedElementName); | |||||
if (element instanceof TaskContainer | if (element instanceof TaskContainer | ||||
&& info != null | && info != null | ||||
&& info.getDefinitionType() == AntLibrary.TASKDEF | && info.getDefinitionType() == AntLibrary.TASKDEF | ||||
@@ -937,18 +804,21 @@ public class ExecutionFrame { | |||||
String nestedElementName = model.getType(); | String nestedElementName = model.getType(); | ||||
Object nestedElement | Object nestedElement | ||||
= reflector.createElement(element, nestedElementName); | = reflector.createElement(element, nestedElementName); | ||||
if (nestedElement instanceof ExecutionComponent) { | |||||
ExecutionComponent component = (ExecutionComponent)nestedElement; | |||||
ExecutionContext context | |||||
= new ExecutionContext(this, eventSupport); | |||||
context.setModelElement(model); | |||||
component.init(context); | |||||
} | |||||
try { | try { | ||||
configureElement(nestedElement, model); | |||||
if (nestedElement instanceof ExecutionComponent) { | |||||
ExecutionComponent component | |||||
= (ExecutionComponent)nestedElement; | |||||
ExecutionContext context | |||||
= new ExecutionContext(this); | |||||
context.setModelElement(model); | |||||
component.init(context); | |||||
configureElement(nestedElement, model); | |||||
component.validateComponent(); | |||||
} else { | |||||
configureElement(nestedElement, model); | |||||
} | |||||
} catch (ExecutionException e) { | } catch (ExecutionException e) { | ||||
e.setLocation(model.getLocation()); | |||||
e.setLocation(model.getLocation(), false); | |||||
throw e; | throw e; | ||||
} | } | ||||
} | } | ||||
@@ -1045,7 +915,7 @@ public class ExecutionFrame { | |||||
throws ExecutionException { | throws ExecutionException { | ||||
String taskType = model.getType(); | String taskType = model.getType(); | ||||
ImportInfo taskDefInfo = (ImportInfo)definitions.get(taskType); | |||||
ImportInfo taskDefInfo = componentManager.getDefinition(taskType); | |||||
if (taskDefInfo == null | if (taskDefInfo == null | ||||
|| taskDefInfo.getDefinitionType() != AntLibrary.TASKDEF) { | || taskDefInfo.getDefinitionType() != AntLibrary.TASKDEF) { | ||||
throw new ExecutionException("There is no defintion for a " | throw new ExecutionException("There is no defintion for a " | ||||
@@ -1059,7 +929,8 @@ public class ExecutionFrame { | |||||
ClassLoader taskClassLoader = antLibrary.getClassLoader(); | ClassLoader taskClassLoader = antLibrary.getClassLoader(); | ||||
Class elementClass | Class elementClass | ||||
= Class.forName(className, true, taskClassLoader); | = Class.forName(className, true, taskClassLoader); | ||||
AntLibFactory libFactory = getLibFactory(antLibrary); | |||||
AntLibFactory libFactory | |||||
= componentManager.getLibFactory(antLibrary); | |||||
Object element = libFactory.createTaskInstance(elementClass); | Object element = libFactory.createTaskInstance(elementClass); | ||||
Task task = null; | Task task = null; | ||||
@@ -1072,9 +943,10 @@ public class ExecutionFrame { | |||||
// set the context loader while configuring the element | // set the context loader while configuring the element | ||||
ClassLoader currentLoader = setContextLoader(taskClassLoader); | ClassLoader currentLoader = setContextLoader(taskClassLoader); | ||||
TaskContext taskContext = new TaskContext(this, eventSupport); | |||||
TaskContext taskContext = new TaskContext(this); | |||||
taskContext.init(taskClassLoader, task, model); | taskContext.init(taskClassLoader, task, model); | ||||
configureElement(element, model); | configureElement(element, model); | ||||
task.validateComponent(); | |||||
setContextLoader(currentLoader); | setContextLoader(currentLoader); | ||||
return taskContext; | return taskContext; | ||||
} catch (ClassNotFoundException e) { | } catch (ClassNotFoundException e) { | ||||
@@ -1094,7 +966,7 @@ public class ExecutionFrame { | |||||
+ className + " for task <" + taskType + ">", | + className + " for task <" + taskType + ">", | ||||
e, model.getLocation()); | e, model.getLocation()); | ||||
} catch (ExecutionException e) { | } catch (ExecutionException e) { | ||||
e.setLocation(model.getLocation()); | |||||
e.setLocation(model.getLocation(), false); | |||||
throw e; | throw e; | ||||
} | } | ||||
} | } | ||||
@@ -1112,7 +984,7 @@ public class ExecutionFrame { | |||||
*/ | */ | ||||
private Object configureType(String typeName, BuildElement model) | private Object configureType(String typeName, BuildElement model) | ||||
throws ExecutionException { | throws ExecutionException { | ||||
ImportInfo typeDefInfo = (ImportInfo)definitions.get(typeName); | |||||
ImportInfo typeDefInfo = componentManager.getDefinition(typeName); | |||||
if (typeDefInfo == null | if (typeDefInfo == null | ||||
|| typeDefInfo.getDefinitionType() != AntLibrary.TYPEDEF) { | || typeDefInfo.getDefinitionType() != AntLibrary.TYPEDEF) { | ||||
throw new ExecutionException("There is no defintion for a " | throw new ExecutionException("There is no defintion for a " | ||||
@@ -1128,7 +1000,8 @@ public class ExecutionFrame { | |||||
= Class.forName(className, true, typeClassLoader); | = Class.forName(className, true, typeClassLoader); | ||||
ClassLoader currentLoader = setContextLoader(typeClassLoader); | ClassLoader currentLoader = setContextLoader(typeClassLoader); | ||||
AntLibFactory libFactory = getLibFactory(antLibrary); | |||||
AntLibFactory libFactory | |||||
= componentManager.getLibFactory(antLibrary); | |||||
Object typeInstance | Object typeInstance | ||||
= createTypeInstance(typeClass, libFactory, model); | = createTypeInstance(typeClass, libFactory, model); | ||||
setContextLoader(currentLoader); | setContextLoader(currentLoader); | ||||
@@ -1169,12 +1042,14 @@ public class ExecutionFrame { | |||||
if (typeInstance instanceof ExecutionComponent) { | if (typeInstance instanceof ExecutionComponent) { | ||||
ExecutionComponent component = (ExecutionComponent)typeInstance; | ExecutionComponent component = (ExecutionComponent)typeInstance; | ||||
ExecutionContext context | ExecutionContext context | ||||
= new ExecutionContext(this, eventSupport); | |||||
= new ExecutionContext(this); | |||||
context.setModelElement(model); | context.setModelElement(model); | ||||
component.init(context); | component.init(context); | ||||
configureElement(typeInstance, model); | |||||
component.validateComponent(); | |||||
} else { | |||||
configureElement(typeInstance, model); | |||||
} | } | ||||
configureElement(typeInstance, model); | |||||
return typeInstance; | return typeInstance; | ||||
} catch (InstantiationException e) { | } catch (InstantiationException e) { | ||||
throw new ExecutionException("Unable to instantiate type class " | throw new ExecutionException("Unable to instantiate type class " | ||||
@@ -1185,10 +1060,9 @@ public class ExecutionFrame { | |||||
+ typeClass.getName() + " for type <" + model.getType() + ">", | + typeClass.getName() + " for type <" + model.getType() + ">", | ||||
e, model.getLocation()); | e, model.getLocation()); | ||||
} catch (ExecutionException e) { | } catch (ExecutionException e) { | ||||
e.setLocation(model.getLocation()); | |||||
e.setLocation(model.getLocation(), false); | |||||
throw e; | throw e; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
@@ -61,10 +61,10 @@ import java.util.Map; | |||||
import org.apache.ant.antcore.antlib.AntLibManager; | import org.apache.ant.antcore.antlib.AntLibManager; | ||||
import org.apache.ant.antcore.antlib.AntLibrary; | import org.apache.ant.antcore.antlib.AntLibrary; | ||||
import org.apache.ant.antcore.config.AntConfig; | import org.apache.ant.antcore.config.AntConfig; | ||||
import org.apache.ant.antcore.model.Project; | |||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.common.event.BuildListener; | import org.apache.ant.common.event.BuildListener; | ||||
import org.apache.ant.common.model.Project; | |||||
import org.apache.ant.common.util.AntException; | import org.apache.ant.common.util.AntException; | ||||
import org.apache.ant.common.util.ExecutionException; | |||||
import org.apache.ant.init.InitConfig; | import org.apache.ant.init.InitConfig; | ||||
/** | /** | ||||
@@ -105,11 +105,11 @@ public class ExecutionManager { | |||||
* | * | ||||
* @param initConfig Ant's configuration - classloaders etc | * @param initConfig Ant's configuration - classloaders etc | ||||
* @param config The user config to use - may be null | * @param config The user config to use - may be null | ||||
* @exception ConfigException if there is a problem with one of Ant's | |||||
* @exception ExecutionException if there is a problem with one of Ant's | |||||
* tasks | * tasks | ||||
*/ | */ | ||||
public ExecutionManager(InitConfig initConfig, AntConfig config) | public ExecutionManager(InitConfig initConfig, AntConfig config) | ||||
throws ConfigException { | |||||
throws ExecutionException { | |||||
this.config = config; | this.config = config; | ||||
this.initConfig = initConfig; | this.initConfig = initConfig; | ||||
@@ -140,7 +140,7 @@ public class ExecutionManager { | |||||
mainFrame = new ExecutionFrame(antLibraries, initConfig, config); | mainFrame = new ExecutionFrame(antLibraries, initConfig, config); | ||||
} catch (MalformedURLException e) { | } catch (MalformedURLException e) { | ||||
throw new ConfigException("Unable to load Ant libraries", e); | |||||
throw new ExecutionException("Unable to load Ant libraries", e); | |||||
} | } | ||||
} | } | ||||
@@ -149,13 +149,17 @@ public class ExecutionManager { | |||||
* | * | ||||
* @param project the project model to be used for the build | * @param project the project model to be used for the build | ||||
* @param targets a list of target names to be executed. | * @param targets a list of target names to be executed. | ||||
* @param commandProperties the properties defined by the front end to | |||||
* control the build | |||||
*/ | */ | ||||
public void runBuild(Project project, List targets) { | |||||
public void runBuild(Project project, List targets, Map commandProperties) { | |||||
Throwable buildFailureCause = null; | Throwable buildFailureCause = null; | ||||
try { | try { | ||||
// start by validating the project we have been given. | // start by validating the project we have been given. | ||||
project.validate(null); | |||||
project.validate(); | |||||
mainFrame.setProject(project); | mainFrame.setProject(project); | ||||
mainFrame.setInitialProperties(commandProperties); | |||||
eventSupport.fireBuildStarted(project); | eventSupport.fireBuildStarted(project); | ||||
mainFrame.runBuild(targets); | mainFrame.runBuild(targets); | ||||
@@ -193,10 +197,10 @@ public class ExecutionManager { | |||||
* Add the library paths from the AntConfig instance to the Ant | * Add the library paths from the AntConfig instance to the Ant | ||||
* Libraries. | * Libraries. | ||||
* | * | ||||
* @exception ConfigException if remote libraries are not allowed. | |||||
* @exception ExecutionException if remote libraries are not allowed. | |||||
*/ | */ | ||||
private void addConfigLibPaths() | private void addConfigLibPaths() | ||||
throws ConfigException { | |||||
throws ExecutionException { | |||||
if (config == null) { | if (config == null) { | ||||
return; | return; | ||||
} | } | ||||
@@ -212,7 +216,7 @@ public class ExecutionManager { | |||||
URL pathElementURL = (URL)j.next(); | URL pathElementURL = (URL)j.next(); | ||||
if (!pathElementURL.getProtocol().equals("file") | if (!pathElementURL.getProtocol().equals("file") | ||||
&& !config.isRemoteLibAllowed()) { | && !config.isRemoteLibAllowed()) { | ||||
throw new ConfigException("Remote libpaths are not" | |||||
throw new ExecutionException("Remote libpaths are not" | |||||
+ " allowed: " + pathElementURL); | + " allowed: " + pathElementURL); | ||||
} | } | ||||
antLib.addLibraryURL(pathElementURL); | antLib.addLibraryURL(pathElementURL); | ||||
@@ -0,0 +1,110 @@ | |||||
/* | |||||
* 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 apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.ant.antcore.execution; | |||||
import org.apache.ant.antcore.antlib.AntLibDefinition; | |||||
import org.apache.ant.antcore.antlib.AntLibrary; | |||||
/** | |||||
* This class is used to maintain information about imports | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 16 January 2002 | |||||
*/ | |||||
public class ImportInfo { | |||||
/** the ant library from which the import is made */ | |||||
private AntLibrary library; | |||||
/** the library definition information */ | |||||
private AntLibDefinition libDefinition; | |||||
/** | |||||
* ImportInfo records what has been imported from an Ant Library | |||||
* | |||||
* @param library The library from which the import was made | |||||
* @param libDefinition the library definition information | |||||
*/ | |||||
public ImportInfo(AntLibrary library, AntLibDefinition libDefinition) { | |||||
this.library = library; | |||||
this.libDefinition = libDefinition; | |||||
} | |||||
/** | |||||
* Get the classname that has been imported | |||||
* | |||||
* @return the classname that was imported. | |||||
*/ | |||||
public String getClassName() { | |||||
return libDefinition.getClassName(); | |||||
} | |||||
/** | |||||
* Get the library from which the import was made | |||||
* | |||||
* @return the library from which the import was made | |||||
*/ | |||||
public AntLibrary getAntLibrary() { | |||||
return library; | |||||
} | |||||
/** | |||||
* Get the type of the definition that was imported | |||||
* | |||||
* @return the type of definition | |||||
*/ | |||||
public int getDefinitionType() { | |||||
return libDefinition.getDefinitionType(); | |||||
} | |||||
} | |||||
@@ -52,8 +52,8 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.execution; | package org.apache.ant.antcore.execution; | ||||
import org.apache.ant.antcore.model.ModelElement; | |||||
import org.apache.ant.common.antlib.Task; | import org.apache.ant.common.antlib.Task; | ||||
import org.apache.ant.common.model.ModelElement; | |||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
/** | /** | ||||
* This is the core's implementation of the AntContext for Tasks. | * This is the core's implementation of the AntContext for Tasks. | ||||
@@ -77,12 +77,9 @@ public class TaskContext extends ExecutionContext { | |||||
* Initilaise this context's environment | * Initilaise this context's environment | ||||
* | * | ||||
* @param frame the frame containing this context | * @param frame the frame containing this context | ||||
* @param eventSupport the event support instance used to send build | |||||
* events | |||||
*/ | */ | ||||
public TaskContext(ExecutionFrame frame, | |||||
BuildEventSupport eventSupport) { | |||||
super(frame, eventSupport); | |||||
public TaskContext(ExecutionFrame frame) { | |||||
super(frame); | |||||
} | } | ||||
/** | /** | ||||
@@ -109,7 +106,7 @@ public class TaskContext extends ExecutionContext { | |||||
* @param task the task to be manager | * @param task the task to be manager | ||||
* @param loader the classloader | * @param loader the classloader | ||||
* @param modelElement the model element associated with this context | * @param modelElement the model element associated with this context | ||||
* @exception ExecutionException if the task cannot be initialized | |||||
* @exception ExecutionException if the task cannot be initialized | |||||
*/ | */ | ||||
public void init(ClassLoader loader, Task task, ModelElement modelElement) | public void init(ClassLoader loader, Task task, ModelElement modelElement) | ||||
throws ExecutionException { | throws ExecutionException { | ||||
@@ -122,7 +119,8 @@ public class TaskContext extends ExecutionContext { | |||||
/** | /** | ||||
* execute this context's task | * execute this context's task | ||||
* | * | ||||
* @exception ExecutionException if there is a problem executing the task | |||||
* @exception ExecutionException if there is a problem executing the | |||||
* task | |||||
*/ | */ | ||||
public void execute() throws ExecutionException { | public void execute() throws ExecutionException { | ||||
task.execute(); | task.execute(); | ||||
@@ -51,10 +51,10 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
package org.apache.ant.antcore.modelparser; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import org.apache.ant.antcore.model.BuildElement; | |||||
import org.apache.ant.common.model.BuildElement; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; |
@@ -51,11 +51,11 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
package org.apache.ant.antcore.modelparser; | |||||
import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
import java.net.URL; | import java.net.URL; | ||||
import org.apache.ant.antcore.model.Project; | |||||
import org.apache.ant.common.model.Project; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.apache.ant.antcore.xml.XMLParseException; | import org.apache.ant.antcore.xml.XMLParseException; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; |
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
package org.apache.ant.antcore.modelparser; | |||||
/** | /** | ||||
* A NoProjectReadException is used to indicate that a project was not read | * A NoProjectReadException is used to indicate that a project was not read |
@@ -51,9 +51,9 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
import org.apache.ant.antcore.model.ModelException; | |||||
import org.apache.ant.antcore.model.Project; | |||||
package org.apache.ant.antcore.modelparser; | |||||
import org.apache.ant.common.model.ModelException; | |||||
import org.apache.ant.common.model.Project; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; |
@@ -51,11 +51,11 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
package org.apache.ant.antcore.modelparser; | |||||
import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
import java.net.URL; | import java.net.URL; | ||||
import org.apache.ant.antcore.model.Project; | |||||
import org.apache.ant.common.model.Project; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.apache.ant.antcore.xml.XMLParseException; | import org.apache.ant.antcore.xml.XMLParseException; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; | ||||
@@ -129,14 +129,14 @@ public class RefHandler extends ElementHandler { | |||||
referencedProject = referencedProjectHandler.getProject(); | referencedProject = referencedProjectHandler.getProject(); | ||||
} catch (XMLParseException e) { | } catch (XMLParseException e) { | ||||
throw new SAXParseException("Error parsing referenced project " | throw new SAXParseException("Error parsing referenced project " | ||||
+ projectSystemId + ": " + e.getMessage(), getLocator()); | |||||
+ projectSystemId + ": " + e.getMessage(), getLocator(), e); | |||||
} catch (NoProjectReadException e) { | } catch (NoProjectReadException e) { | ||||
throw new SAXParseException("No project found in the reference: " | throw new SAXParseException("No project found in the reference: " | ||||
+ projectSystemId, getLocator()); | |||||
+ projectSystemId, getLocator(), e); | |||||
} catch (MalformedURLException e) { | } catch (MalformedURLException e) { | ||||
throw new SAXParseException("Unable to reference project " | throw new SAXParseException("Unable to reference project " | ||||
+ projectSystemId + ": " + e.getMessage(), | + projectSystemId + ": " + e.getMessage(), | ||||
getLocator()); | |||||
getLocator(), e); | |||||
} | } | ||||
} | } | ||||
@@ -51,10 +51,10 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
package org.apache.ant.antcore.modelparser; | |||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import org.apache.ant.antcore.model.Target; | |||||
import org.apache.ant.common.model.Target; | |||||
import org.apache.ant.antcore.xml.ElementHandler; | import org.apache.ant.antcore.xml.ElementHandler; | ||||
import org.xml.sax.Attributes; | import org.xml.sax.Attributes; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; | ||||
@@ -75,6 +75,12 @@ public class TargetHandler extends ElementHandler { | |||||
/** The depends attribute name */ | /** The depends attribute name */ | ||||
public final static String DESC_ATTR = "description"; | public final static String DESC_ATTR = "description"; | ||||
/** The if attribute name */ | |||||
public final static String IF_ATTR = "if"; | |||||
/** The unless attribute name */ | |||||
public final static String UNLESS_ATTR = "unless"; | |||||
/** The target being configured. */ | /** The target being configured. */ | ||||
private Target target; | private Target target; | ||||
@@ -105,7 +111,7 @@ public class TargetHandler extends ElementHandler { | |||||
if (depends != null) { | if (depends != null) { | ||||
StringTokenizer tokenizer = new StringTokenizer(depends, ","); | StringTokenizer tokenizer = new StringTokenizer(depends, ","); | ||||
while (tokenizer.hasMoreTokens()) { | while (tokenizer.hasMoreTokens()) { | ||||
String dependency = tokenizer.nextToken(); | |||||
String dependency = tokenizer.nextToken().trim(); | |||||
target.addDependency(dependency); | target.addDependency(dependency); | ||||
} | } | ||||
} | } | ||||
@@ -143,9 +149,11 @@ public class TargetHandler extends ElementHandler { | |||||
protected void validateAttribute(String attributeName, | protected void validateAttribute(String attributeName, | ||||
String attributeValue) | String attributeValue) | ||||
throws SAXParseException { | throws SAXParseException { | ||||
if (!attributeName.equals(NAME_ATTR) && | |||||
!attributeName.equals(DEPENDS_ATTR) && | |||||
!attributeName.equals(DESC_ATTR)) { | |||||
if (!attributeName.equals(NAME_ATTR) | |||||
&& !attributeName.equals(DEPENDS_ATTR) | |||||
&& !attributeName.equals(DESC_ATTR) | |||||
&& !attributeName.equals(IF_ATTR) | |||||
&& !attributeName.equals(UNLESS_ATTR)) { | |||||
throwInvalidAttribute(attributeName); | throwInvalidAttribute(attributeName); | ||||
} | } | ||||
} | } |
@@ -51,11 +51,11 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model.xmlparser; | |||||
package org.apache.ant.antcore.modelparser; | |||||
import java.net.URL; | import java.net.URL; | ||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; | ||||
import org.apache.ant.antcore.model.Project; | |||||
import org.apache.ant.common.model.Project; | |||||
import org.apache.ant.antcore.xml.ParseContext; | import org.apache.ant.antcore.xml.ParseContext; | ||||
import org.apache.ant.antcore.xml.XMLParseException; | import org.apache.ant.antcore.xml.XMLParseException; | ||||
@@ -59,8 +59,9 @@ import javax.xml.parsers.ParserConfigurationException; | |||||
import javax.xml.parsers.SAXParser; | import javax.xml.parsers.SAXParser; | ||||
import javax.xml.parsers.SAXParserFactory; | import javax.xml.parsers.SAXParserFactory; | ||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; | ||||
import org.apache.ant.antcore.util.CircularDependencyChecker; | |||||
import org.apache.ant.antcore.util.CircularDependencyException; | |||||
import org.apache.ant.common.util.CircularDependencyChecker; | |||||
import org.apache.ant.common.util.CircularDependencyException; | |||||
import org.apache.ant.common.util.AntException; | |||||
import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||
import org.xml.sax.SAXParseException; | import org.xml.sax.SAXParseException; | ||||
import org.xml.sax.XMLReader; | import org.xml.sax.XMLReader; | ||||
@@ -128,7 +129,11 @@ public class ParseContext { | |||||
Location location = new Location(e.getSystemId(), | Location location = new Location(e.getSystemId(), | ||||
e.getLineNumber(), e.getColumnNumber()); | e.getLineNumber(), e.getColumnNumber()); | ||||
if (e.getException() != null) { | if (e.getException() != null) { | ||||
throw new XMLParseException(e.getException(), location); | |||||
Throwable nestedException = e.getException(); | |||||
if (nestedException instanceof AntException) { | |||||
location = ((AntException)nestedException).getLocation(); | |||||
} | |||||
throw new XMLParseException(nestedException, location); | |||||
} else { | } else { | ||||
throw new XMLParseException(e, location); | throw new XMLParseException(e, location); | ||||
} | } | ||||
@@ -4,20 +4,149 @@ | |||||
<factory classname="org.apache.tools.ant.Ant1Factory"/> | <factory classname="org.apache.tools.ant.Ant1Factory"/> | ||||
<taskdef name="echo" classname="org.apache.tools.ant.taskdefs.Echo"/> | |||||
<taskdef name="property" classname="org.apache.tools.ant.taskdefs.Property"/> | |||||
<typedef name="patternset" classname="org.apache.tools.ant.types.PatternSet"/> | |||||
<typedef name="fileset" classname="org.apache.tools.ant.types.FileSet"/> | |||||
<typedef name="path" classname="org.apache.tools.ant.types.Path"/> | |||||
<converter classname="org.apache.tools.ant.Ant1Converter"/> | |||||
<taskdef name="ant" classname="org.apache.tools.ant.taskdefs.Ant"/> | |||||
<taskdef name="antcall" classname="org.apache.tools.ant.taskdefs.CallTarget"/> | |||||
<taskdef name="antlr" classname="org.apache.tools.ant.taskdefs.optional.ANTLR"/> | |||||
<taskdef name="antstructure" classname="org.apache.tools.ant.taskdefs.AntStructure"/> | |||||
<taskdef name="apply" classname="org.apache.tools.ant.taskdefs.Transform"/> | |||||
<taskdef name="available" classname="org.apache.tools.ant.taskdefs.Available"/> | <taskdef name="available" classname="org.apache.tools.ant.taskdefs.Available"/> | ||||
<taskdef name="blgenclient" classname="org.apache.tools.ant.taskdefs.optional.ejb.BorlandGenerateClient"/> | |||||
<taskdef name="bunzip2" classname="org.apache.tools.ant.taskdefs.BUnzip2"/> | |||||
<taskdef name="bzip2" classname="org.apache.tools.ant.taskdefs.BZip2"/> | |||||
<taskdef name="cab" classname="org.apache.tools.ant.taskdefs.optional.Cab"/> | |||||
<taskdef name="cccheckin" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin"/> | |||||
<taskdef name="cccheckout" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout"/> | |||||
<taskdef name="ccmcheckin" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckin"/> | |||||
<taskdef name="ccmcheckintask" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckinDefault"/> | |||||
<taskdef name="ccmcheckout" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCheckout"/> | |||||
<taskdef name="ccmcreatetask" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMCreateTask"/> | |||||
<taskdef name="ccmreconfigure" classname="org.apache.tools.ant.taskdefs.optional.ccm.CCMReconfigure"/> | |||||
<taskdef name="ccuncheckout" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout"/> | |||||
<taskdef name="ccupdate" classname="org.apache.tools.ant.taskdefs.optional.clearcase.CCUpdate"/> | |||||
<taskdef name="checksum" classname="org.apache.tools.ant.taskdefs.Checksum"/> | |||||
<taskdef name="chmod" classname="org.apache.tools.ant.taskdefs.Chmod"/> | |||||
<taskdef name="condition" classname="org.apache.tools.ant.taskdefs.ConditionTask"/> | <taskdef name="condition" classname="org.apache.tools.ant.taskdefs.ConditionTask"/> | ||||
<taskdef name="javac" classname="org.apache.tools.ant.taskdefs.Javac"/> | |||||
<taskdef name="mkdir" classname="org.apache.tools.ant.taskdefs.Mkdir"/> | |||||
<taskdef name="copy" classname="org.apache.tools.ant.taskdefs.Copy"/> | <taskdef name="copy" classname="org.apache.tools.ant.taskdefs.Copy"/> | ||||
<taskdef name="csc" classname="org.apache.tools.ant.taskdefs.optional.dotnet.CSharp"/> | |||||
<taskdef name="cvs" classname="org.apache.tools.ant.taskdefs.Cvs"/> | |||||
<taskdef name="cvspass" classname="org.apache.tools.ant.taskdefs.CVSPass"/> | |||||
<taskdef name="ddcreator" classname="org.apache.tools.ant.taskdefs.optional.ejb.DDCreator"/> | |||||
<taskdef name="delete" classname="org.apache.tools.ant.taskdefs.Delete"/> | |||||
<taskdef name="depend" classname="org.apache.tools.ant.taskdefs.optional.depend.Depend"/> | <taskdef name="depend" classname="org.apache.tools.ant.taskdefs.optional.depend.Depend"/> | ||||
<taskdef name="dependset" classname="org.apache.tools.ant.taskdefs.DependSet"/> | |||||
<taskdef name="ear" classname="org.apache.tools.ant.taskdefs.Ear"/> | |||||
<taskdef name="echo" classname="org.apache.tools.ant.taskdefs.Echo"/> | |||||
<taskdef name="ejbc" classname="org.apache.tools.ant.taskdefs.optional.ejb.Ejbc"/> | |||||
<taskdef name="ejbjar" classname="org.apache.tools.ant.taskdefs.optional.ejb.EjbJar"/> | |||||
<taskdef name="exec" classname="org.apache.tools.ant.taskdefs.ExecTask"/> | |||||
<taskdef name="execon" classname="org.apache.tools.ant.taskdefs.ExecuteOn"/> | |||||
<taskdef name="fail" classname="org.apache.tools.ant.taskdefs.Exit"/> | |||||
<taskdef name="filter" classname="org.apache.tools.ant.taskdefs.Filter"/> | |||||
<taskdef name="fixcrlf" classname="org.apache.tools.ant.taskdefs.FixCRLF"/> | |||||
<taskdef name="ftp" classname="org.apache.tools.ant.taskdefs.optional.net.FTP"/> | |||||
<taskdef name="genkey" classname="org.apache.tools.ant.taskdefs.GenerateKey"/> | |||||
<taskdef name="get" classname="org.apache.tools.ant.taskdefs.Get"/> | |||||
<taskdef name="gunzip" classname="org.apache.tools.ant.taskdefs.GUnzip"/> | |||||
<taskdef name="gzip" classname="org.apache.tools.ant.taskdefs.GZip"/> | |||||
<taskdef name="icontract" classname="org.apache.tools.ant.taskdefs.optional.IContract"/> | |||||
<taskdef name="ilasm" classname="org.apache.tools.ant.taskdefs.optional.dotnet.Ilasm"/> | |||||
<taskdef name="input" classname="org.apache.tools.ant.taskdefs.Input"/> | |||||
<taskdef name="iplanet-ejbc" classname="org.apache.tools.ant.taskdefs.optional.ejb.IPlanetEjbcTask"/> | |||||
<taskdef name="jar" classname="org.apache.tools.ant.taskdefs.Jar"/> | <taskdef name="jar" classname="org.apache.tools.ant.taskdefs.Jar"/> | ||||
<taskdef name="delete" classname="org.apache.tools.ant.taskdefs.Delete"/> | |||||
<taskdef name="java" classname="org.apache.tools.ant.taskdefs.Java"/> | |||||
<taskdef name="javac" classname="org.apache.tools.ant.taskdefs.Javac"/> | |||||
<taskdef name="javacc" classname="org.apache.tools.ant.taskdefs.optional.javacc.JavaCC"/> | |||||
<taskdef name="javadoc" classname="org.apache.tools.ant.taskdefs.Javadoc"/> | |||||
<taskdef name="javah" classname="org.apache.tools.ant.taskdefs.optional.Javah"/> | |||||
<taskdef name="jdepend" classname="org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask"/> | |||||
<taskdef name="jjtree" classname="org.apache.tools.ant.taskdefs.optional.javacc.JJTree"/> | |||||
<taskdef name="jlink" classname="org.apache.tools.ant.taskdefs.optional.jlink.JlinkTask"/> | |||||
<taskdef name="jpcoverage" classname="org.apache.tools.ant.taskdefs.optional.sitraka.Coverage"/> | |||||
<taskdef name="jpcovmerge" classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovMerge"/> | |||||
<taskdef name="jpcovreport" classname="org.apache.tools.ant.taskdefs.optional.sitraka.CovReport"/> | |||||
<taskdef name="jspc" classname="org.apache.tools.ant.taskdefs.optional.jsp.JspC"/> | |||||
<taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask"/> | |||||
<taskdef name="junitreport" classname="org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator"/> | |||||
<taskdef name="loadfile" classname="org.apache.tools.ant.taskdefs.LoadFile"/> | |||||
<taskdef name="mail" classname="org.apache.tools.ant.taskdefs.SendEmail"/> | |||||
<taskdef name="manifest" classname="org.apache.tools.ant.taskdefs.Manifest"/> | |||||
<taskdef name="maudit" classname="org.apache.tools.ant.taskdefs.optional.metamata.MAudit"/> | |||||
<taskdef name="mimemail" classname="org.apache.tools.ant.taskdefs.optional.net.MimeMail"/> | |||||
<taskdef name="mkdir" classname="org.apache.tools.ant.taskdefs.Mkdir"/> | |||||
<taskdef name="mmetrics" classname="org.apache.tools.ant.taskdefs.optional.metamata.MMetrics"/> | |||||
<taskdef name="move" classname="org.apache.tools.ant.taskdefs.Move"/> | |||||
<taskdef name="mparse" classname="org.apache.tools.ant.taskdefs.optional.metamata.MParse"/> | |||||
<taskdef name="native2ascii" classname="org.apache.tools.ant.taskdefs.optional.Native2Ascii"/> | |||||
<taskdef name="netrexxc" classname="org.apache.tools.ant.taskdefs.optional.NetRexxC"/> | |||||
<taskdef name="p4add" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Add"/> | |||||
<taskdef name="p4change" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Change"/> | |||||
<taskdef name="p4counter" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Counter"/> | |||||
<taskdef name="p4edit" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Edit"/> | |||||
<taskdef name="p4have" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Have"/> | |||||
<taskdef name="p4label" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Label"/> | |||||
<taskdef name="p4submit" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Submit"/> | |||||
<taskdef name="p4sync" classname="org.apache.tools.ant.taskdefs.optional.perforce.P4Sync"/> | |||||
<taskdef name="parallel" classname="org.apache.tools.ant.taskdefs.Parallel"/> | |||||
<taskdef name="patch" classname="org.apache.tools.ant.taskdefs.Patch"/> | |||||
<taskdef name="pathconvert" classname="org.apache.tools.ant.taskdefs.PathConvert"/> | |||||
<taskdef name="property" classname="org.apache.tools.ant.taskdefs.Property"/> | |||||
<taskdef name="propertyfile" classname="org.apache.tools.ant.taskdefs.optional.PropertyFile"/> | |||||
<taskdef name="pvcs" classname="org.apache.tools.ant.taskdefs.optional.pvcs.Pvcs"/> | |||||
<taskdef name="record" classname="org.apache.tools.ant.taskdefs.Recorder"/> | |||||
<taskdef name="renameext" classname="org.apache.tools.ant.taskdefs.optional.RenameExtensions"/> | |||||
<taskdef name="replace" classname="org.apache.tools.ant.taskdefs.Replace"/> | |||||
<taskdef name="replaceregexp" classname="org.apache.tools.ant.taskdefs.optional.ReplaceRegExp"/> | |||||
<taskdef name="rmic" classname="org.apache.tools.ant.taskdefs.Rmic"/> | |||||
<taskdef name="rpm" classname="org.apache.tools.ant.taskdefs.optional.Rpm"/> | |||||
<taskdef name="script" classname="org.apache.tools.ant.taskdefs.optional.Script"/> | |||||
<taskdef name="sequential" classname="org.apache.tools.ant.taskdefs.Sequential"/> | |||||
<taskdef name="signjar" classname="org.apache.tools.ant.taskdefs.SignJar"/> | |||||
<taskdef name="sleep" classname="org.apache.tools.ant.taskdefs.Sleep"/> | |||||
<taskdef name="soscheckin" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckin"/> | |||||
<taskdef name="soscheckout" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSCheckout"/> | |||||
<taskdef name="sosget" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSGet"/> | |||||
<taskdef name="soslabel" classname="org.apache.tools.ant.taskdefs.optional.sos.SOSLabel"/> | |||||
<taskdef name="sound" classname="org.apache.tools.ant.taskdefs.optional.sound.SoundTask"/> | |||||
<taskdef name="sql" classname="org.apache.tools.ant.taskdefs.SQLExec"/> | |||||
<taskdef name="stcheckin" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckin"/> | |||||
<taskdef name="stcheckout" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamCheckout"/> | |||||
<taskdef name="stlabel" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamLabel"/> | |||||
<taskdef name="stlist" classname="org.apache.tools.ant.taskdefs.optional.starteam.StarTeamList"/> | |||||
<taskdef name="style" classname="org.apache.tools.ant.taskdefs.XSLTProcess"/> | |||||
<taskdef name="stylebook" classname="org.apache.tools.ant.taskdefs.optional.StyleBook"/> | |||||
<taskdef name="tar" classname="org.apache.tools.ant.taskdefs.Tar"/> | |||||
<taskdef name="taskdef" classname="org.apache.tools.ant.taskdefs.Taskdef"/> | |||||
<taskdef name="telnet" classname="org.apache.tools.ant.taskdefs.optional.net.TelnetTask"/> | |||||
<taskdef name="test" classname="org.apache.tools.ant.taskdefs.optional.Test"/> | |||||
<taskdef name="touch" classname="org.apache.tools.ant.taskdefs.Touch"/> | |||||
<taskdef name="translate" classname="org.apache.tools.ant.taskdefs.optional.i18n.Translate"/> | |||||
<taskdef name="tstamp" classname="org.apache.tools.ant.taskdefs.Tstamp"/> | |||||
<taskdef name="typedef" classname="org.apache.tools.ant.taskdefs.Typedef"/> | |||||
<taskdef name="unjar" classname="org.apache.tools.ant.taskdefs.Expand"/> | |||||
<taskdef name="untar" classname="org.apache.tools.ant.taskdefs.Untar"/> | |||||
<taskdef name="unwar" classname="org.apache.tools.ant.taskdefs.Expand"/> | |||||
<taskdef name="unzip" classname="org.apache.tools.ant.taskdefs.Expand"/> | |||||
<taskdef name="uptodate" classname="org.apache.tools.ant.taskdefs.UpToDate"/> | |||||
<taskdef name="vajexport" classname="org.apache.tools.ant.taskdefs.optional.ide.VAJExport"/> | |||||
<taskdef name="vajimport" classname="org.apache.tools.ant.taskdefs.optional.ide.VAJImport"/> | |||||
<taskdef name="vajload" classname="org.apache.tools.ant.taskdefs.optional.ide.VAJLoadProjects"/> | |||||
<taskdef name="vsscheckin" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKIN"/> | |||||
<taskdef name="vsscheckout" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSCHECKOUT"/> | |||||
<taskdef name="vssget" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSGET"/> | |||||
<taskdef name="vsshistory" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSHISTORY"/> | |||||
<taskdef name="vsslabel" classname="org.apache.tools.ant.taskdefs.optional.vss.MSVSSLABEL"/> | |||||
<taskdef name="waitfor" classname="org.apache.tools.ant.taskdefs.WaitFor"/> | |||||
<taskdef name="war" classname="org.apache.tools.ant.taskdefs.War"/> | |||||
<taskdef name="wljspc" classname="org.apache.tools.ant.taskdefs.optional.jsp.WLJspc"/> | |||||
<taskdef name="wlrun" classname="org.apache.tools.ant.taskdefs.optional.ejb.WLRun"/> | |||||
<taskdef name="wlstop" classname="org.apache.tools.ant.taskdefs.optional.ejb.WLStop"/> | |||||
<taskdef name="xmlvalidate" classname="org.apache.tools.ant.taskdefs.optional.XMLValidateTask"/> | |||||
<taskdef name="zip" classname="org.apache.tools.ant.taskdefs.Zip"/> | |||||
<converter classname="org.apache.tools.ant.Ant1Converter"/> | |||||
<typedef name="patternset" classname="org.apache.tools.ant.types.PatternSet"/> | |||||
<typedef name="fileset" classname="org.apache.tools.ant.types.FileSet"/> | |||||
<typedef name="path" classname="org.apache.tools.ant.types.Path"/> | |||||
</antlib> | </antlib> |
@@ -136,7 +136,7 @@ public class AntClassLoader extends URLClassLoader | |||||
/** | /** | ||||
* Initialize the given class | * Initialize the given class | ||||
* | * | ||||
* @param theClass XXX Description of Parameter | |||||
* @param theClass the class to be initialised | |||||
*/ | */ | ||||
public static void initializeClass(Class theClass) { | public static void initializeClass(Class theClass) { | ||||
// do nothing in Ant2 | // do nothing in Ant2 | ||||
@@ -188,14 +188,6 @@ public class AntClassLoader extends URLClassLoader | |||||
public void cleanup() { | public void cleanup() { | ||||
} | } | ||||
/** | |||||
* New build listener interface | |||||
* | |||||
* @param be the build event to be processed | |||||
*/ | |||||
public void processBuildEvent(BuildEvent be) { | |||||
} | |||||
/** | /** | ||||
* Force a class to be loaded by this loader | * Force a class to be loaded by this loader | ||||
* | * | ||||
@@ -219,7 +211,64 @@ public class AntClassLoader extends URLClassLoader | |||||
} | } | ||||
/** | /** | ||||
* Add a path tot his loader | |||||
* build started event | |||||
* | |||||
* @param event build started event | |||||
*/ | |||||
public void buildStarted(BuildEvent event) { | |||||
} | |||||
/** | |||||
* build finished event | |||||
* | |||||
* @param event build finished event | |||||
*/ | |||||
public void buildFinished(BuildEvent event) { | |||||
cleanup(); | |||||
} | |||||
/** | |||||
* target started event. | |||||
* | |||||
* @param event target started event. | |||||
*/ | |||||
public void targetStarted(BuildEvent event) { | |||||
} | |||||
/** | |||||
* target finished event | |||||
* | |||||
* @param event target finished event | |||||
*/ | |||||
public void targetFinished(BuildEvent event) { | |||||
} | |||||
/** | |||||
* task started event | |||||
* | |||||
* @param event task started event | |||||
*/ | |||||
public void taskStarted(BuildEvent event) { | |||||
} | |||||
/** | |||||
* task finished event | |||||
* | |||||
* @param event task finished event | |||||
*/ | |||||
public void taskFinished(BuildEvent event) { | |||||
} | |||||
/** | |||||
* message logged event | |||||
* | |||||
* @param event message logged event | |||||
*/ | |||||
public void messageLogged(BuildEvent event) { | |||||
} | |||||
/** | |||||
* Add a path to this loader | |||||
* | * | ||||
* @param path the path to be added to this loader | * @param path the path to be added to this loader | ||||
*/ | */ | ||||
@@ -66,7 +66,7 @@ public class BuildEvent extends org.apache.ant.common.event.BuildEvent { | |||||
* @param task the task that emitted the event. | * @param task the task that emitted the event. | ||||
*/ | */ | ||||
public BuildEvent(Task task) { | public BuildEvent(Task task) { | ||||
super(task, MESSAGE); | |||||
super(task.getContext().getModelElement(), MESSAGE); | |||||
} | } | ||||
} | } | ||||
@@ -629,7 +629,7 @@ public class Project { | |||||
public Hashtable getProperties() { | public Hashtable getProperties() { | ||||
Map properties = dataService.getAllProperties(); | Map properties = dataService.getAllProperties(); | ||||
Hashtable result = new Hashtable(); | Hashtable result = new Hashtable(); | ||||
for (Iterator i = properties.keySet().iterator(); i.hasNext();) { | |||||
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) { | |||||
String name = (String)i.next(); | String name = (String)i.next(); | ||||
Object value = properties.get(name); | Object value = properties.get(name); | ||||
if (value instanceof String) { | if (value instanceof String) { | ||||
@@ -655,7 +655,7 @@ public class Project { | |||||
public Hashtable getReferences() { | public Hashtable getReferences() { | ||||
Map properties = dataService.getAllProperties(); | Map properties = dataService.getAllProperties(); | ||||
Hashtable result = new Hashtable(); | Hashtable result = new Hashtable(); | ||||
for (Iterator i = properties.keySet().iterator(); i.hasNext();) { | |||||
for (Iterator i = properties.keySet().iterator(); i.hasNext(); ) { | |||||
String name = (String)i.next(); | String name = (String)i.next(); | ||||
Object value = properties.get(name); | Object value = properties.get(name); | ||||
if (!(value instanceof String)) { | if (!(value instanceof String)) { | ||||
@@ -117,7 +117,7 @@ public abstract class ProjectComponent { | |||||
public void init(AntContext context) throws ExecutionException { | public void init(AntContext context) throws ExecutionException { | ||||
this.context = context; | this.context = context; | ||||
org.apache.ant.common.util.Location contextLocation | org.apache.ant.common.util.Location contextLocation | ||||
= context.getLocation(); | |||||
= context.getModelElement().getLocation(); | |||||
if (contextLocation | if (contextLocation | ||||
== org.apache.ant.common.util.Location.UNKNOWN_LOCATION) { | == org.apache.ant.common.util.Location.UNKNOWN_LOCATION) { | ||||
@@ -153,5 +153,14 @@ public abstract class ProjectComponent { | |||||
context.log(message, Project.MSG_INFO); | context.log(message, Project.MSG_INFO); | ||||
} | } | ||||
/** | |||||
* Get the context associated with this component | |||||
* | |||||
* @return the AntContext | |||||
*/ | |||||
protected AntContext getContext() { | |||||
return context; | |||||
} | |||||
} | } | ||||
@@ -121,12 +121,18 @@ public abstract class Task extends ProjectComponent | |||||
/** | /** | ||||
* Gets the description of the Task | * Gets the description of the Task | ||||
* | * | ||||
* @return the task's description | |||||
* @return the task's description | |||||
*/ | */ | ||||
public String getDescription() { | public String getDescription() { | ||||
return description; | return description; | ||||
} | } | ||||
/** Validate this component */ | |||||
public void validateComponent() { | |||||
// no default validation for Ant1 tasks | |||||
} | |||||
/** | /** | ||||
* Handle output captured for this task | * Handle output captured for this task | ||||
* | * | ||||
@@ -153,6 +159,5 @@ public abstract class Task extends ProjectComponent | |||||
void setTaskType(String type) { | void setTaskType(String type) { | ||||
this.taskType = type; | this.taskType = type; | ||||
} | } | ||||
} | } | ||||
@@ -132,6 +132,12 @@ public abstract class DataType extends ProjectComponent | |||||
return ref != null; | return ref != null; | ||||
} | } | ||||
/** Validate this component */ | |||||
public void validateComponent() { | |||||
// no default validation for Ant1 types | |||||
} | |||||
/** | /** | ||||
* Performs the check for circular references and returns the referenced | * Performs the check for circular references and returns the referenced | ||||
* object. | * object. | ||||
@@ -7,6 +7,9 @@ | |||||
<taskdef name="typedef" classname="org.apache.ant.antlib.system.TypeDef"/> | <taskdef name="typedef" classname="org.apache.ant.antlib.system.TypeDef"/> | ||||
<taskdef name="loadlib" classname="org.apache.ant.antlib.system.LoadLib"/> | <taskdef name="loadlib" classname="org.apache.ant.antlib.system.LoadLib"/> | ||||
<taskdef name="ant" classname="org.apache.ant.antlib.system.Ant"/> | |||||
<taskdef name="antcall" classname="org.apache.ant.antlib.system.AntCall"/> | |||||
<converter classname="org.apache.ant.antlib.system.FileConverter"/> | <converter classname="org.apache.ant.antlib.system.FileConverter"/> | ||||
<converter classname="org.apache.ant.antlib.system.URLConverter"/> | <converter classname="org.apache.ant.antlib.system.URLConverter"/> | ||||
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/> | <converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/> | ||||
@@ -51,73 +51,69 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.execution; | |||||
import java.net.MalformedURLException; | |||||
import java.util.HashMap; | |||||
import java.util.Iterator; | |||||
import java.util.Map; | |||||
import org.apache.ant.antcore.antlib.AntLibManager; | |||||
import org.apache.ant.antcore.util.ConfigException; | |||||
package org.apache.ant.antlib.system; | |||||
import java.io.File; | |||||
import org.apache.ant.common.service.ComponentService; | import org.apache.ant.common.service.ComponentService; | ||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
/** | /** | ||||
* The instance of the ComponentServices made available by the core to the | |||||
* ant libraries. | |||||
* The Ant task - used to execute a different build file | |||||
* | * | ||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | ||||
* @created 27 January 2002 | |||||
* @created 4 February 2002 | |||||
*/ | */ | ||||
public class ExecutionComponentService implements ComponentService { | |||||
/** The ExecutionFrame this service instance is working for */ | |||||
private ExecutionFrame frame; | |||||
public class Ant extends AntBase { | |||||
/** The ant file to be run */ | |||||
private File antFile; | |||||
/** the base directory to use for the run */ | |||||
private File baseDir; | |||||
/** File to capture any output */ | |||||
private File outputFile; | |||||
/** The library manager instance used to configure libraries. */ | |||||
private AntLibManager libManager; | |||||
/** | |||||
* sets the file containing the XML representation model to build | |||||
* | |||||
* @param antFile the file to build | |||||
*/ | |||||
public void setAntFile(File antFile) { | |||||
this.antFile = antFile; | |||||
} | |||||
/** | /** | ||||
* Constructor | |||||
* Set the base directory for the execution of the build | |||||
* | * | ||||
* @param executionFrame the frame containing this context | |||||
* @param allowRemoteLibs true if remote libraries can be loaded though | |||||
* this service. | |||||
* @param baseDir the base directory for the build | |||||
*/ | */ | ||||
public ExecutionComponentService(ExecutionFrame executionFrame, | |||||
boolean allowRemoteLibs) { | |||||
this.frame = executionFrame; | |||||
libManager = new AntLibManager(allowRemoteLibs); | |||||
public void setBaseDir(File baseDir) { | |||||
this.baseDir = baseDir; | |||||
} | } | ||||
/** | /** | ||||
* Load a library or set of libraries from a location making them | |||||
* available for use | |||||
* The output file for capturing the build output | |||||
* | * | ||||
* @param libLocation the file or URL of the library location | |||||
* @param importAll if true all tasks are imported as the library is | |||||
* loaded | |||||
* @exception ExecutionException if the library cannot be loaded | |||||
* @param outputFile the output file for capturing the build output | |||||
*/ | */ | ||||
public void loadLib(String libLocation, boolean importAll) | |||||
throws ExecutionException { | |||||
try { | |||||
Map librarySpecs = new HashMap(); | |||||
libManager.loadLib(librarySpecs, libLocation); | |||||
libManager.configLibraries(frame.getInitConfig(), librarySpecs, | |||||
frame.getAntLibraries()); | |||||
public void setOutput(File outputFile) { | |||||
this.outputFile = outputFile; | |||||
} | |||||
if (importAll) { | |||||
Iterator i = librarySpecs.keySet().iterator(); | |||||
while (i.hasNext()) { | |||||
String libraryId = (String)i.next(); | |||||
frame.importLibrary(libraryId); | |||||
} | |||||
} | |||||
} catch (MalformedURLException e) { | |||||
throw new ExecutionException("Unable to load libraries from " | |||||
+ libLocation, e); | |||||
} catch (ConfigException e) { | |||||
throw new ExecutionException(e); | |||||
/** | |||||
* Run the sub-build | |||||
* | |||||
* @exception ExecutionException if the build can't be run | |||||
*/ | |||||
public void execute() throws ExecutionException { | |||||
if (baseDir == null) { | |||||
baseDir = getContext().getBaseDir(); | |||||
} | |||||
if (antFile == null) { | |||||
antFile = new File(baseDir, "build.ant"); | |||||
} | } | ||||
ComponentService componentService | |||||
= (ComponentService)getCoreService(ComponentService.class); | |||||
componentService.runBuild(antFile, getProperties(), getTargets()); | |||||
} | } | ||||
} | } | ||||
@@ -0,0 +1,293 @@ | |||||
/* | |||||
* 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 apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.ant.antlib.system; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import org.apache.ant.common.antlib.AbstractTask; | |||||
import org.apache.ant.common.antlib.AntContext; | |||||
import org.apache.ant.common.antlib.AbstractComponent; | |||||
import org.apache.ant.common.service.DataService; | |||||
import org.apache.ant.common.util.ExecutionException; | |||||
/** | |||||
* Common Base class for the Ant and AntCall tasks | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 4 February 2002 | |||||
*/ | |||||
public abstract class AntBase extends AbstractTask { | |||||
/** | |||||
* Simple Property value storing class | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 5 February 2002 | |||||
*/ | |||||
public static class Property extends AbstractComponent { | |||||
/** The property name */ | |||||
private String name; | |||||
/** The property value*/ | |||||
private String value; | |||||
/** | |||||
* Sets the name of the Property | |||||
* | |||||
* @param name the new name value | |||||
*/ | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
/** | |||||
* Sets the value of the Property | |||||
* | |||||
* @param value the new value value | |||||
*/ | |||||
public void setValue(String value) { | |||||
this.value = value; | |||||
} | |||||
/** | |||||
* Gets the name of the Property | |||||
* | |||||
* @return the name value | |||||
*/ | |||||
public String getName() { | |||||
return name; | |||||
} | |||||
/** | |||||
* Gets the value of the Property | |||||
* | |||||
* @return the value value | |||||
*/ | |||||
public String getValue() { | |||||
return value; | |||||
} | |||||
public void validateComponent() throws ExecutionException { | |||||
if (name == null) { | |||||
throw new ExecutionException("\"name\" attribute of <property> must be supplied"); | |||||
} | |||||
if (value == null) { | |||||
throw new ExecutionException("\"value\" attribute of <property> must be supplied"); | |||||
} | |||||
} | |||||
} | |||||
/** | |||||
* A simple class to store information about references being passed | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 5 February 2002 | |||||
*/ | |||||
public static class Reference extends AbstractComponent { | |||||
/** The id of the reference to be passed */ | |||||
private String refId; | |||||
/** The id to be used in the sub-build for this reference */ | |||||
private String toId; | |||||
/** | |||||
* Sets the refId of the Reference | |||||
* | |||||
* @param refId the new refId value | |||||
*/ | |||||
public void setRefId(String refId) { | |||||
this.refId = refId; | |||||
} | |||||
/** | |||||
* Sets the toId of the Reference | |||||
* | |||||
* @param toId the new toId value | |||||
*/ | |||||
public void setToId(String toId) { | |||||
this.toId = toId; | |||||
} | |||||
/** | |||||
* Gets the refId of the Reference | |||||
* | |||||
* @return the refId value | |||||
*/ | |||||
public String getRefId() { | |||||
return refId; | |||||
} | |||||
/** | |||||
* Gets the toId of the Reference | |||||
* | |||||
* @return the toId value | |||||
*/ | |||||
public String getToId() { | |||||
return toId; | |||||
} | |||||
public void validateComponent() throws ExecutionException { | |||||
if (refId == null) { | |||||
throw new ExecutionException("\"refid\" attribute of <reference> must be supplied"); | |||||
} | |||||
} | |||||
} | |||||
/** The name of the target to be evaluated in the sub-build */ | |||||
private String targetName; | |||||
/** flag which indicates if all current properties should be passed to the subbuild */ | |||||
private boolean inheritAll = true; | |||||
/** flag which indicates if all current references should be passed to the subbuild */ | |||||
private boolean inheritRefs = false; | |||||
/** The properties which will be passed to the sub-build */ | |||||
private Map properties = new HashMap(); | |||||
/** The core's data service for manipulating the properties */ | |||||
private DataService dataService; | |||||
/** | |||||
* Sets the target to be executed in the subbuild | |||||
* | |||||
* @param targetName the name of the target to build | |||||
*/ | |||||
public void setTarget(String targetName) { | |||||
this.targetName = targetName; | |||||
} | |||||
/** | |||||
* Indicate if all properties should be passed | |||||
* | |||||
* @param inheritAll true if all properties should be passed | |||||
*/ | |||||
public void setInheritAll(boolean inheritAll) { | |||||
this.inheritAll = inheritAll; | |||||
} | |||||
/** | |||||
* Indicate if all references are to be passed to the subbuild | |||||
* | |||||
* @param inheritRefs true if the sub-build should be given all the current references | |||||
*/ | |||||
public void setInheritRefs(boolean inheritRefs) { | |||||
this.inheritRefs = inheritRefs; | |||||
} | |||||
/** | |||||
* Initialise this task | |||||
* | |||||
* @param context core's context | |||||
* @exception ExecutionException if we can't access the data service | |||||
*/ | |||||
public void init(AntContext context) throws ExecutionException { | |||||
super.init(context); | |||||
dataService = (DataService)getCoreService(DataService.class); | |||||
} | |||||
/** | |||||
* Add a property to be passed to the subbuild | |||||
* | |||||
* @param property descriptor for the property to be passed | |||||
*/ | |||||
public void addProperty(Property property) { | |||||
properties.put(property.getName(), property.getValue()); | |||||
} | |||||
/** | |||||
* Add a reference to be passed | |||||
* | |||||
* @param reference the descriptor of the reference to be passed | |||||
* @exception ExecutionException if the reference does not reference a valid object | |||||
*/ | |||||
public void addReference(Reference reference) throws ExecutionException { | |||||
String refId = reference.getRefId(); | |||||
if (!dataService.isDataValueSet(refId)) { | |||||
throw new ExecutionException("RefId \"" + refId + "\" is not set"); | |||||
} | |||||
Object value = dataService.getDataValue(refId); | |||||
String toId = reference.getToId(); | |||||
if (toId == null) { | |||||
toId = refId; | |||||
} | |||||
properties.put(toId, value); | |||||
} | |||||
/** | |||||
* Get the list of targets to be executed | |||||
* | |||||
* @return A List of string target names. | |||||
*/ | |||||
protected List getTargets() { | |||||
List targets = new ArrayList(); | |||||
if (targetName != null) { | |||||
targets.add(targetName); | |||||
} | |||||
return targets; | |||||
} | |||||
/** | |||||
* Get the properties to be used with the sub-build | |||||
* | |||||
* @return the properties the sub-build will start with | |||||
*/ | |||||
protected Map getProperties() { | |||||
return properties; | |||||
} | |||||
} | |||||
@@ -0,0 +1,87 @@ | |||||
/* | |||||
* 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 apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.ant.antlib.system; | |||||
import org.apache.ant.common.service.ComponentService; | |||||
import org.apache.ant.common.util.ExecutionException; | |||||
/** | |||||
* The Ant task - used to execute a different build file | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 4 February 2002 | |||||
*/ | |||||
public class AntCall extends AntBase { | |||||
/** | |||||
* Execute the sub-build | |||||
* | |||||
* @exception ExecutionException if the build fails | |||||
*/ | |||||
public void execute() throws ExecutionException { | |||||
ComponentService componentService | |||||
= (ComponentService)getCoreService(ComponentService.class); | |||||
componentService.callTarget(getProperties(), getTargets()); | |||||
} | |||||
/** | |||||
* Alias to add a property to the sub-build | |||||
* | |||||
* @param param descriptor for the property to be passed | |||||
*/ | |||||
public void addParam(Property param) { | |||||
super.addProperty(param); | |||||
} | |||||
} | |||||
@@ -60,18 +60,20 @@ import java.io.PrintStream; | |||||
import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||
import java.net.URL; | import java.net.URL; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | |||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
import org.apache.ant.antcore.config.AntConfig; | import org.apache.ant.antcore.config.AntConfig; | ||||
import org.apache.ant.antcore.config.AntConfigHandler; | import org.apache.ant.antcore.config.AntConfigHandler; | ||||
import org.apache.ant.antcore.execution.ExecutionManager; | import org.apache.ant.antcore.execution.ExecutionManager; | ||||
import org.apache.ant.antcore.model.Project; | |||||
import org.apache.ant.antcore.model.xmlparser.XMLProjectParser; | |||||
import org.apache.ant.antcore.util.ConfigException; | |||||
import org.apache.ant.antcore.modelparser.XMLProjectParser; | |||||
import org.apache.ant.antcore.xml.ParseContext; | import org.apache.ant.antcore.xml.ParseContext; | ||||
import org.apache.ant.antcore.xml.XMLParseException; | import org.apache.ant.antcore.xml.XMLParseException; | ||||
import org.apache.ant.common.event.BuildListener; | import org.apache.ant.common.event.BuildListener; | ||||
import org.apache.ant.common.model.Project; | |||||
import org.apache.ant.common.util.AntException; | import org.apache.ant.common.util.AntException; | ||||
import org.apache.ant.common.util.ConfigException; | |||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; | ||||
import org.apache.ant.common.util.MessageLevel; | import org.apache.ant.common.util.MessageLevel; | ||||
import org.apache.ant.init.InitConfig; | import org.apache.ant.init.InitConfig; | ||||
@@ -87,6 +89,9 @@ public class Commandline { | |||||
/** The default build file name */ | /** The default build file name */ | ||||
public final static String DEFAULT_BUILD_FILENAME = "build.ant"; | public final static String DEFAULT_BUILD_FILENAME = "build.ant"; | ||||
/** The default build file name */ | |||||
public final static String DEFAULT_ANT1_FILENAME = "build.xml"; | |||||
/** The initialisation configuration for Ant */ | /** The initialisation configuration for Ant */ | ||||
private InitConfig config; | private InitConfig config; | ||||
@@ -102,6 +107,9 @@ public class Commandline { | |||||
/** The list of targets to be evaluated in this invocation */ | /** The list of targets to be evaluated in this invocation */ | ||||
private List targets = new ArrayList(4); | private List targets = new ArrayList(4); | ||||
/** The command line properties */ | |||||
private Map definedProperties = new HashMap(); | |||||
/** | /** | ||||
* This is the build file to run. By default it is a file: type URL but | * This is the build file to run. By default it is a file: type URL but | ||||
* other URL protocols can be used. | * other URL protocols can be used. | ||||
@@ -237,7 +245,7 @@ public class Commandline { | |||||
ExecutionManager executionManager | ExecutionManager executionManager | ||||
= new ExecutionManager(initConfig, config); | = new ExecutionManager(initConfig, config); | ||||
addBuildListeners(executionManager); | addBuildListeners(executionManager); | ||||
executionManager.runBuild(project, targets); | |||||
executionManager.runBuild(project, targets, definedProperties); | |||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
if (t instanceof AntException) { | if (t instanceof AntException) { | ||||
AntException e = (AntException)t; | AntException e = (AntException)t; | ||||
@@ -329,6 +337,9 @@ public class Commandline { | |||||
} else if (arg.equals("-verbose") || arg.equals("-v")) { | } else if (arg.equals("-verbose") || arg.equals("-v")) { | ||||
// printVersion(); | // printVersion(); | ||||
messageOutputLevel = MessageLevel.MSG_VERBOSE; | messageOutputLevel = MessageLevel.MSG_VERBOSE; | ||||
} else if (arg.equals("-debug")) { | |||||
// printVersion(); | |||||
messageOutputLevel = MessageLevel.MSG_DEBUG; | |||||
} else if (arg.equals("-listener")) { | } else if (arg.equals("-listener")) { | ||||
try { | try { | ||||
listeners.add(args[i++]); | listeners.add(args[i++]); | ||||
@@ -350,6 +361,17 @@ public class Commandline { | |||||
"using the -logger argument"); | "using the -logger argument"); | ||||
return; | return; | ||||
} | } | ||||
} else if (arg.startsWith("-D")) { | |||||
String name = arg.substring(2, arg.length()); | |||||
String value = null; | |||||
int posEq = name.indexOf("="); | |||||
if (posEq > 0) { | |||||
value = name.substring(posEq + 1); | |||||
name = name.substring(0, posEq); | |||||
} else if (i < args.length - 1) { | |||||
value = args[++i]; | |||||
} | |||||
definedProperties.put(name, value); | |||||
} else if (arg.startsWith("-")) { | } else if (arg.startsWith("-")) { | ||||
// we don't have any more args to recognize! | // we don't have any more args to recognize! | ||||
System.out.println("Unknown option: " + arg); | System.out.println("Unknown option: " + arg); | ||||
@@ -362,6 +384,12 @@ public class Commandline { | |||||
if (buildFileURL == null) { | if (buildFileURL == null) { | ||||
File defaultBuildFile = new File(DEFAULT_BUILD_FILENAME); | File defaultBuildFile = new File(DEFAULT_BUILD_FILENAME); | ||||
if (!defaultBuildFile.exists()) { | |||||
File ant1BuildFile = new File(DEFAULT_ANT1_FILENAME); | |||||
if (ant1BuildFile.exists()) { | |||||
defaultBuildFile = ant1BuildFile; | |||||
} | |||||
} | |||||
try { | try { | ||||
buildFileURL = InitUtils.getFileURL(defaultBuildFile); | buildFileURL = InitUtils.getFileURL(defaultBuildFile); | ||||
} catch (MalformedURLException e) { | } catch (MalformedURLException e) { | ||||
@@ -1,125 +1,103 @@ | |||||
/* | /* | ||||
* 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.cli; | package org.apache.ant.cli; | ||||
import java.io.PrintStream; | import java.io.PrintStream; | ||||
import org.apache.ant.common.model.BuildElement; | |||||
import org.apache.ant.common.model.Target; | |||||
import org.apache.ant.common.event.BuildEvent; | |||||
import org.apache.ant.common.util.AntException; | import org.apache.ant.common.util.AntException; | ||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; | ||||
import org.apache.ant.common.util.MessageLevel; | import org.apache.ant.common.util.MessageLevel; | ||||
import org.apache.ant.common.event.BuildEvent; | |||||
import org.apache.ant.antcore.model.BuildElement; | |||||
import org.apache.ant.antcore.model.Target; | |||||
/** | /** | ||||
* Writes build event to a PrintStream. Currently, it only writes which | |||||
* targets are being executed, and any messages that get logged. | |||||
* Writes build event to a PrintStream. Currently, it only writes which | |||||
* targets are being executed, and any messages that get logged. | |||||
* | * | ||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 15 January 2002 | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 15 January 2002 | |||||
*/ | */ | ||||
public class DefaultLogger implements BuildLogger { | public class DefaultLogger implements BuildLogger { | ||||
/** Standard field separator */ | |||||
private static String lSep = System.getProperty("line.separator"); | |||||
/** spacing to allow for task tags */ | |||||
private final static int LEFT_COLUMN_SIZE = 12; | |||||
/** The stream where output should be written */ | |||||
/** The stream where output should be written */ | |||||
private PrintStream out; | private PrintStream out; | ||||
/** The stream to where errors should be written */ | |||||
/** The stream to where errors should be written */ | |||||
private PrintStream err; | private PrintStream err; | ||||
/** The level of messages which should be let through */ | |||||
/** The level of messages which should be let through */ | |||||
private int messageOutputLevel = MessageLevel.MSG_ERR; | private int messageOutputLevel = MessageLevel.MSG_ERR; | ||||
/** Controls whether adornments are added */ | |||||
/** Controls whether adornments are added */ | |||||
private boolean emacsMode = false; | private boolean emacsMode = false; | ||||
/** The time at which the build started */ | |||||
/** The time at which the build started */ | |||||
private long startTime = System.currentTimeMillis(); | private long startTime = System.currentTimeMillis(); | ||||
/** | |||||
* Format the time into something readable | |||||
* | |||||
* @param millis Java millis value | |||||
* @return the formatted time | |||||
*/ | |||||
protected static String formatTime(long millis) { | |||||
long seconds = millis / 1000; | |||||
long minutes = seconds / 60; | |||||
if (minutes > 0) { | |||||
return Long.toString(minutes) + " minute" | |||||
+ (minutes == 1 ? " " : "s ") | |||||
+ Long.toString(seconds % 60) + " second" | |||||
+ (seconds % 60 == 1 ? "" : "s"); | |||||
} else { | |||||
return Long.toString(seconds) + " second" | |||||
+ (seconds % 60 == 1 ? "" : "s"); | |||||
} | |||||
} | |||||
/** Standard field separator */ | |||||
private static String lSep = System.getProperty("line.separator"); | |||||
/** spacing to allow for task tags */ | |||||
private final static int LEFT_COLUMN_SIZE = 12; | |||||
/** | /** | ||||
* Set the messageOutputLevel this logger is to respond to. Only | |||||
* messages with a message level lower than or equal to the given level | |||||
* are output to the log. <P> | |||||
* Set the messageOutputLevel this logger is to respond to. Only | |||||
* messages with a message level lower than or equal to the given level | |||||
* are output to the log. <P> | |||||
* | * | ||||
* Constants for the message levels are in Project.java. The order of | |||||
* the levels, from least to most verbose, is MSG_ERR, MSG_WARN, | |||||
* MSG_INFO, MSG_VERBOSE, MSG_DEBUG. The default message level for | |||||
* DefaultLogger is Project.MSG_ERR. | |||||
* Constants for the message levels are in Project.java. The order of | |||||
* the levels, from least to most verbose, is MSG_ERR, MSG_WARN, | |||||
* MSG_INFO, MSG_VERBOSE, MSG_DEBUG. The default message level for | |||||
* DefaultLogger is Project.MSG_ERR. | |||||
* | * | ||||
* @param level the logging level for the logger. | |||||
* @param level the logging level for the logger. | |||||
*/ | */ | ||||
public void setMessageOutputLevel(int level) { | public void setMessageOutputLevel(int level) { | ||||
this.messageOutputLevel = level; | this.messageOutputLevel = level; | ||||
@@ -127,27 +105,28 @@ public class DefaultLogger implements BuildLogger { | |||||
/** | /** | ||||
* Set the output stream to which this logger is to send its output. | |||||
* Set the output stream to which this logger is to send its output. | |||||
* | * | ||||
* @param output the output stream for the logger. | |||||
* @param output the output stream for the logger. | |||||
*/ | */ | ||||
public void setOutputPrintStream(PrintStream output) { | public void setOutputPrintStream(PrintStream output) { | ||||
this.out = output; | this.out = output; | ||||
} | } | ||||
/** | /** | ||||
* Set the output stream to which this logger is to send error messages. | |||||
* Set the output stream to which this logger is to send error | |||||
* messages. | |||||
* | * | ||||
* @param err the error stream for the logger. | |||||
* @param err the error stream for the logger. | |||||
*/ | */ | ||||
public void setErrorPrintStream(PrintStream err) { | public void setErrorPrintStream(PrintStream err) { | ||||
this.err = err; | this.err = err; | ||||
} | } | ||||
/** | /** | ||||
* Set this logger to produce emacs (and other editor) friendly output. | |||||
* Set this logger to produce emacs (and other editor) friendly output. | |||||
* | * | ||||
* @param emacsMode true if output is to be unadorned so that emacs and | |||||
* @param emacsMode true if output is to be unadorned so that emacs and | |||||
* other editors can parse files names, etc. | * other editors can parse files names, etc. | ||||
*/ | */ | ||||
public void setEmacsMode(boolean emacsMode) { | public void setEmacsMode(boolean emacsMode) { | ||||
@@ -155,9 +134,9 @@ public class DefaultLogger implements BuildLogger { | |||||
} | } | ||||
/** | /** | ||||
* Report an exception | |||||
* Report an exception | |||||
* | * | ||||
* @param t The exception to be reported. | |||||
* @param t The exception to be reported. | |||||
*/ | */ | ||||
public void reportException(Throwable t) { | public void reportException(Throwable t) { | ||||
if (t instanceof AntException) { | if (t instanceof AntException) { | ||||
@@ -182,72 +161,121 @@ public class DefaultLogger implements BuildLogger { | |||||
} | } | ||||
/** | /** | ||||
* Process an incoming build event | |||||
* Description of the Method | |||||
* | * | ||||
* @param event the build event to be processed | |||||
* @param event Description of Parameter | |||||
*/ | */ | ||||
public void processBuildEvent(BuildEvent event) { | |||||
switch (event.getEventType()) { | |||||
case BuildEvent.BUILD_STARTED: | |||||
startTime = System.currentTimeMillis(); | |||||
break; | |||||
case BuildEvent.BUILD_FINISHED: | |||||
Throwable cause = event.getCause(); | |||||
if (cause == null) { | |||||
out.println(lSep + "BUILD SUCCESSFUL"); | |||||
} else { | |||||
err.println(lSep + "BUILD FAILED" + lSep); | |||||
reportException(cause); | |||||
} | |||||
public void buildStarted(BuildEvent event) { | |||||
startTime = System.currentTimeMillis(); | |||||
} | |||||
out.println(lSep + "Total time: " | |||||
+ formatTime(System.currentTimeMillis() - startTime)); | |||||
break; | |||||
case BuildEvent.TARGET_STARTED: | |||||
if (MessageLevel.MSG_INFO <= messageOutputLevel) { | |||||
Target target = (Target)event.getSource(); | |||||
out.println(lSep + target.getName() + ":"); | |||||
} | |||||
break; | |||||
case BuildEvent.TARGET_FINISHED: | |||||
break; | |||||
case BuildEvent.TASK_STARTED: | |||||
break; | |||||
case BuildEvent.TASK_FINISHED: | |||||
break; | |||||
case BuildEvent.MESSAGE: | |||||
PrintStream logTo | |||||
= event.getPriority() == MessageLevel.MSG_ERR ? err : out; | |||||
// Filter out messages based on priority | |||||
if (event.getPriority() <= messageOutputLevel | |||||
&& event.getSource() instanceof BuildElement) { | |||||
// Print out the name of the task if we're in one | |||||
BuildElement buildElement | |||||
= (BuildElement)event.getSource(); | |||||
String name = buildElement.getType(); | |||||
if (!emacsMode) { | |||||
String msg = "[" + name + "] "; | |||||
int indentSize = LEFT_COLUMN_SIZE - msg.length(); | |||||
for (int i = 0; i < indentSize; i++) { | |||||
logTo.print(" "); | |||||
} | |||||
logTo.print(msg); | |||||
} | |||||
// Print the message | |||||
logTo.println(event.getMessage()); | |||||
/** | |||||
* Description of the Method | |||||
* | |||||
* @param event Description of Parameter | |||||
*/ | |||||
public void buildFinished(BuildEvent event) { | |||||
Throwable cause = event.getCause(); | |||||
if (cause == null) { | |||||
out.println(lSep + "BUILD SUCCESSFUL"); | |||||
} else { | |||||
err.println(lSep + "BUILD FAILED" + lSep); | |||||
reportException(cause); | |||||
} | |||||
out.println(lSep + "Total time: " | |||||
+ formatTime(System.currentTimeMillis() - startTime)); | |||||
} | |||||
/** | |||||
* Description of the Method | |||||
* | |||||
* @param event Description of Parameter | |||||
*/ | |||||
public void targetStarted(BuildEvent event) { | |||||
if (MessageLevel.MSG_INFO <= messageOutputLevel) { | |||||
Target target = (Target)event.getSource(); | |||||
out.println(lSep + target.getName() + ":"); | |||||
} | |||||
} | |||||
/** | |||||
* Description of the Method | |||||
* | |||||
* @param event Description of Parameter | |||||
*/ | |||||
public void targetFinished(BuildEvent event) { | |||||
} | |||||
/** | |||||
* Description of the Method | |||||
* | |||||
* @param event Description of Parameter | |||||
*/ | |||||
public void taskStarted(BuildEvent event) { | |||||
} | |||||
/** | |||||
* Description of the Method | |||||
* | |||||
* @param event Description of Parameter | |||||
*/ | |||||
public void taskFinished(BuildEvent event) { | |||||
} | |||||
/** | |||||
* Description of the Method | |||||
* | |||||
* @param event Description of Parameter | |||||
*/ | |||||
public void messageLogged(BuildEvent event) { | |||||
PrintStream logTo | |||||
= event.getPriority() == MessageLevel.MSG_ERR ? err : out; | |||||
// Filter out messages based on priority | |||||
if (event.getPriority() <= messageOutputLevel | |||||
&& event.getModelElement() instanceof BuildElement) { | |||||
// Print out the name of the task if we're in one | |||||
BuildElement buildElement | |||||
= (BuildElement)event.getModelElement(); | |||||
String name = buildElement.getType(); | |||||
if (!emacsMode) { | |||||
String msg = "[" + name + "] "; | |||||
int indentSize = LEFT_COLUMN_SIZE - msg.length(); | |||||
for (int i = 0; i < indentSize; i++) { | |||||
logTo.print(" "); | |||||
} | } | ||||
break; | |||||
default: | |||||
err.println("Unrecognized event type = " + | |||||
event.getEventType()); | |||||
break; | |||||
logTo.print(msg); | |||||
} | |||||
// Print the message | |||||
logTo.println(event.getMessage()); | |||||
} | } | ||||
} | } | ||||
/** | |||||
* Format the time into something readable | |||||
* | |||||
* @param millis Java millis value | |||||
* @return the formatted time | |||||
*/ | |||||
protected static String formatTime(long millis) { | |||||
long seconds = millis / 1000; | |||||
long minutes = seconds / 60; | |||||
if (minutes > 0) { | |||||
return Long.toString(minutes) + " minute" | |||||
+ (minutes == 1 ? " " : "s ") | |||||
+ Long.toString(seconds % 60) + " second" | |||||
+ (seconds % 60 == 1 ? "" : "s"); | |||||
} else { | |||||
return Long.toString(seconds) + " second" | |||||
+ (seconds % 60 == 1 ? "" : "s"); | |||||
} | |||||
} | |||||
} | } | ||||
@@ -0,0 +1,122 @@ | |||||
/* | |||||
* 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 apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.ant.common.antlib; | |||||
import org.apache.ant.common.util.ExecutionException; | |||||
/** | |||||
* Abstract implementation of the ExecutionComponent | |||||
* | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | |||||
* @created 5 February 2002 | |||||
*/ | |||||
public abstract class AbstractComponent implements ExecutionComponent { | |||||
/** The components's context */ | |||||
private AntContext context; | |||||
/** | |||||
* Initialise the component. The component may use the AntContext to | |||||
* request services from the Ant core. | |||||
* | |||||
* @param context the component's context | |||||
* @exception ExecutionException if initialisation fails | |||||
*/ | |||||
public void init(AntContext context) throws ExecutionException { | |||||
this.context = context; | |||||
} | |||||
/** | |||||
* Validate the component. This is called after the element has been | |||||
* configured from its build model. The element may perform validation | |||||
* of its configuration | |||||
* | |||||
* @exception ExecutionException if validation fails | |||||
*/ | |||||
public void validateComponent() throws ExecutionException { | |||||
// no validation by default | |||||
} | |||||
/** | |||||
* Get this component's context | |||||
* | |||||
* @return the component context | |||||
*/ | |||||
protected AntContext getContext() { | |||||
return context; | |||||
} | |||||
/** | |||||
* Short cut to get a core service instance | |||||
* | |||||
* @param serviceClass the required interface of which an instance is required | |||||
* @return the core's instance of the requested service | |||||
* @exception ExecutionException if the core does not support the requested service | |||||
*/ | |||||
protected Object getCoreService(Class serviceClass) | |||||
throws ExecutionException { | |||||
return context.getCoreService(serviceClass); | |||||
} | |||||
/** | |||||
* 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) { | |||||
context.log(message, level); | |||||
} | |||||
} | |||||
@@ -59,42 +59,10 @@ package org.apache.ant.common.antlib; | |||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | ||||
* @created 16 January 2002 | * @created 16 January 2002 | ||||
*/ | */ | ||||
public abstract class AbstractTask implements Task { | |||||
/** The task's context */ | |||||
private AntContext context; | |||||
/** | |||||
* Initialise the task. The task may use the AntContext to request | |||||
* services from the Ant core. | |||||
* | |||||
* @param context the Task's context | |||||
*/ | |||||
public void init(AntContext context) { | |||||
this.context = context; | |||||
} | |||||
public abstract class AbstractTask extends AbstractComponent implements Task { | |||||
/** Task is about to be cleaned up */ | /** Task is about to be cleaned up */ | ||||
public void destroy() { | public void destroy() { | ||||
// do nothing here | // do nothing here | ||||
} | } | ||||
/** | |||||
* Get this task's context | |||||
* | |||||
* @return the task context | |||||
*/ | |||||
protected AntContext getContext() { | |||||
return context; | |||||
} | |||||
/** | |||||
* 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) { | |||||
context.log(message, level); | |||||
} | |||||
} | } | ||||
@@ -53,9 +53,9 @@ | |||||
*/ | */ | ||||
package org.apache.ant.common.antlib; | package org.apache.ant.common.antlib; | ||||
import java.io.File; | import java.io.File; | ||||
import org.apache.ant.common.model.ModelElement; | |||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
import org.apache.ant.common.util.Location; | |||||
/** | /** | ||||
* The AntContext is the interface through which the Ant container and the | * The AntContext is the interface through which the Ant container and the | ||||
@@ -88,17 +88,17 @@ public interface AntContext { | |||||
throws ExecutionException; | throws ExecutionException; | ||||
/** | /** | ||||
* Get the build file location with which this context is associated. | |||||
* Get the basedir for the current execution | |||||
* | * | ||||
* @return the associated build file location | |||||
* @return the base directory for this execution of Ant | |||||
*/ | */ | ||||
Location getLocation(); | |||||
File getBaseDir(); | |||||
/** | /** | ||||
* Get the basedir for the current execution | |||||
* Get the model element associated with this context | |||||
* | * | ||||
* @return the base directory for this execution of Ant | |||||
* @return the modelElement associated with this context | |||||
*/ | */ | ||||
File getBaseDir(); | |||||
ModelElement getModelElement(); | |||||
} | } | ||||
@@ -55,8 +55,8 @@ package org.apache.ant.common.antlib; | |||||
import org.apache.ant.common.util.ExecutionException; | import org.apache.ant.common.util.ExecutionException; | ||||
/** | /** | ||||
* An execution component is a component from an AntLibrary which is used in the | |||||
* execution of an Ant build. A component can have a context. | |||||
* An execution component is a component from an AntLibrary which is used in | |||||
* the execution of an Ant build. A component can have a context. | |||||
* | * | ||||
* @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | * @author <a href="mailto:conor@apache.org">Conor MacNeill</a> | ||||
* @created 1 February 2002 | * @created 1 February 2002 | ||||
@@ -70,5 +70,14 @@ public interface ExecutionComponent { | |||||
* @exception ExecutionException if the component cannot be initialised | * @exception ExecutionException if the component cannot be initialised | ||||
*/ | */ | ||||
void init(AntContext context) throws ExecutionException; | void init(AntContext context) throws ExecutionException; | ||||
/** | |||||
* Validate the component. This is called after the element has been | |||||
* configured from its build model. The element may perform validation | |||||
* of its configuration | |||||
* | |||||
* @exception ExecutionException if the component is not validly configured | |||||
*/ | |||||
void validateComponent() throws ExecutionException; | |||||
} | } | ||||
@@ -54,6 +54,7 @@ | |||||
package org.apache.ant.common.event; | package org.apache.ant.common.event; | ||||
import java.util.EventObject; | import java.util.EventObject; | ||||
import org.apache.ant.common.model.ModelElement; | |||||
/** | /** | ||||
* A BuildEvent indicates the occurence of a significant event in the build. | * A BuildEvent indicates the occurence of a significant event in the build. | ||||
@@ -96,7 +97,7 @@ public class BuildEvent extends EventObject { | |||||
* @param eventType the type of the buildEvent. | * @param eventType the type of the buildEvent. | ||||
* @param source the element with which this event is associated | * @param source the element with which this event is associated | ||||
*/ | */ | ||||
public BuildEvent(Object source, int eventType) { | |||||
public BuildEvent(ModelElement source, int eventType) { | |||||
super(source); | super(source); | ||||
this.eventType = eventType; | this.eventType = eventType; | ||||
} | } | ||||
@@ -108,7 +109,7 @@ public class BuildEvent extends EventObject { | |||||
* @param cause An exception if associated with the event | * @param cause An exception if associated with the event | ||||
* @param source the object with which this event is associated | * @param source the object with which this event is associated | ||||
*/ | */ | ||||
public BuildEvent(Object source, int eventType, | |||||
public BuildEvent(ModelElement source, int eventType, | |||||
Throwable cause) { | Throwable cause) { | ||||
this(source, eventType); | this(source, eventType); | ||||
this.cause = cause; | this.cause = cause; | ||||
@@ -117,12 +118,11 @@ public class BuildEvent extends EventObject { | |||||
/** | /** | ||||
* Create a build event for a message | * Create a build event for a message | ||||
* | * | ||||
* @param source the object with which the event is | |||||
* associated. | |||||
* @param source the object with which the event is associated. | |||||
* @param message the message associated with this event | * @param message the message associated with this event | ||||
* @param priority the message priority | * @param priority the message priority | ||||
*/ | */ | ||||
public BuildEvent(Object source, String message, | |||||
public BuildEvent(ModelElement source, String message, | |||||
int priority) { | int priority) { | ||||
this(source, MESSAGE); | this(source, MESSAGE); | ||||
this.message = message; | this.message = message; | ||||
@@ -168,5 +168,14 @@ public class BuildEvent extends EventObject { | |||||
public Throwable getCause() { | public Throwable getCause() { | ||||
return cause; | return cause; | ||||
} | } | ||||
/** | |||||
* Gets the modelElement of the BuildEvent | |||||
* | |||||
* @return the model element this event is associated with | |||||
*/ | |||||
public ModelElement getModelElement() { | |||||
return (ModelElement)getSource(); | |||||
} | |||||
} | } | ||||
@@ -65,10 +65,55 @@ import java.util.EventListener; | |||||
*/ | */ | ||||
public interface BuildListener extends EventListener { | public interface BuildListener extends EventListener { | ||||
/** | /** | ||||
* Process an incoming build event | |||||
* Fired before any targets are started. | |||||
* | * | ||||
* @param event the event to be processed. | |||||
* @param event the build event for this notification | |||||
*/ | */ | ||||
void processBuildEvent(BuildEvent event); | |||||
void buildStarted(BuildEvent event); | |||||
/** | |||||
* Fired after the last target has finished. This event will still be | |||||
* thrown if an error occured during the build. | |||||
* | |||||
* @param event the build event for this notification | |||||
*/ | |||||
void buildFinished(BuildEvent event); | |||||
/** | |||||
* Fired when a target is started. | |||||
* | |||||
* @param event the build event for this notification | |||||
*/ | |||||
void targetStarted(BuildEvent event); | |||||
/** | |||||
* Fired when a target has finished. This event will still be thrown if | |||||
* an error occured during the build. | |||||
* | |||||
* @param event the build event for this notification | |||||
*/ | |||||
void targetFinished(BuildEvent event); | |||||
/** | |||||
* Fired when a task is started. | |||||
* | |||||
* @param event the build event for this notification | |||||
*/ | |||||
void taskStarted(BuildEvent event); | |||||
/** | |||||
* Fired when a task has finished. This event will still be throw if an | |||||
* error occured during the build. | |||||
* | |||||
* @param event the build event for this notification | |||||
*/ | |||||
void taskFinished(BuildEvent event); | |||||
/** | |||||
* Fired whenever a message is logged. | |||||
* | |||||
* @param event the build event for this notification | |||||
*/ | |||||
void messageLogged(BuildEvent event); | |||||
} | } | ||||
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model; | |||||
package org.apache.ant.common.model; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Iterator; | import java.util.Iterator; |
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model; | |||||
package org.apache.ant.common.model; | |||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.Map; | import java.util.Map; |
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model; | |||||
package org.apache.ant.common.model; | |||||
import org.apache.ant.common.util.AntException; | import org.apache.ant.common.util.AntException; | ||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; |
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model; | |||||
package org.apache.ant.common.model; | |||||
import java.net.URL; | import java.net.URL; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
@@ -61,10 +61,10 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | import java.util.Set; | ||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import org.apache.ant.common.util.CircularDependencyChecker; | |||||
import org.apache.ant.common.util.CircularDependencyException; | |||||
import org.apache.ant.common.util.ConfigException; | |||||
import org.apache.ant.common.util.Location; | import org.apache.ant.common.util.Location; | ||||
import org.apache.ant.antcore.util.CircularDependencyChecker; | |||||
import org.apache.ant.antcore.util.CircularDependencyException; | |||||
import org.apache.ant.antcore.util.ConfigException; | |||||
/** | /** | ||||
* A project is a collection of targets and global tasks. A project may | * A project is a collection of targets and global tasks. A project may | ||||
@@ -366,42 +366,12 @@ public class Project extends ModelElement { | |||||
} | } | ||||
/** | /** | ||||
* Validate that this build element is configured correctly | |||||
* Validate this project | |||||
* | * | ||||
* @param globalName The name of this project in the reference name | |||||
* space | |||||
* @exception ModelException if the element is invalid | |||||
* @exception ModelException if the project is not valid | |||||
*/ | */ | ||||
public void validate(String globalName) throws ModelException { | |||||
Set keys = referencedProjects.keySet(); | |||||
for (Iterator i = keys.iterator(); i.hasNext(); ) { | |||||
String refName = (String)i.next(); | |||||
Project referencedProject | |||||
= (Project)referencedProjects.get(refName); | |||||
String refGlobalName = refName; | |||||
if (globalName != null) { | |||||
refGlobalName = globalName + REF_DELIMITER + refName; | |||||
} | |||||
referencedProject.validate(refGlobalName); | |||||
} | |||||
// we now check whether all of dependencies for our targets | |||||
// exist in the model | |||||
// visited contains the targets we have already visited and verified | |||||
Set visited = new HashSet(); | |||||
// checker records the targets we are currently visiting | |||||
CircularDependencyChecker checker | |||||
= new CircularDependencyChecker("checking target dependencies"); | |||||
// dependency order is purely recorded for debug purposes | |||||
List dependencyOrder = new ArrayList(); | |||||
for (Iterator i = getTargets(); i.hasNext(); ) { | |||||
Target target = (Target)i.next(); | |||||
target.validate(); | |||||
fillinDependencyOrder(globalName, target, dependencyOrder, | |||||
visited, checker); | |||||
} | |||||
public void validate() throws ModelException { | |||||
validate(null); | |||||
} | } | ||||
/** | /** | ||||
@@ -466,8 +436,47 @@ public class Project extends ModelElement { | |||||
} | } | ||||
/** | /** | ||||
* Given a fully qualified target name, this method simply returns the | |||||
* fully qualified name of the project | |||||
* Validate that this build element is configured correctly | |||||
* | |||||
* @param globalName The name of this project in the reference name | |||||
* space | |||||
* @exception ModelException if the element is invalid | |||||
*/ | |||||
protected void validate(String globalName) throws ModelException { | |||||
Set keys = referencedProjects.keySet(); | |||||
for (Iterator i = keys.iterator(); i.hasNext(); ) { | |||||
String refName = (String)i.next(); | |||||
Project referencedProject | |||||
= (Project)referencedProjects.get(refName); | |||||
String refGlobalName = refName; | |||||
if (globalName != null) { | |||||
refGlobalName = globalName + REF_DELIMITER + refName; | |||||
} | |||||
referencedProject.validate(refGlobalName); | |||||
} | |||||
// we now check whether all of dependencies for our targets | |||||
// exist in the model | |||||
// visited contains the targets we have already visited and verified | |||||
Set visited = new HashSet(); | |||||
// checker records the targets we are currently visiting | |||||
CircularDependencyChecker checker | |||||
= new CircularDependencyChecker("checking target dependencies"); | |||||
// dependency order is purely recorded for debug purposes | |||||
List dependencyOrder = new ArrayList(); | |||||
for (Iterator i = getTargets(); i.hasNext(); ) { | |||||
Target target = (Target)i.next(); | |||||
target.validate(); | |||||
fillinDependencyOrder(globalName, target, dependencyOrder, | |||||
visited, checker); | |||||
} | |||||
} | |||||
/** | |||||
* Given a fully qualified target name, this method returns the fully | |||||
* qualified name of the project | |||||
* | * | ||||
* @param fullTargetName the full qualified target name | * @param fullTargetName the full qualified target name | ||||
* @return the full name of the containing project | * @return the full name of the containing project |
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.model; | |||||
package org.apache.ant.common.model; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Iterator; | import java.util.Iterator; | ||||
import java.util.List; | import java.util.List; |
@@ -52,6 +52,10 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.common.service; | 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; | import org.apache.ant.common.util.ExecutionException; | ||||
/** | /** | ||||
@@ -80,5 +84,37 @@ public interface ComponentService { | |||||
*/ | */ | ||||
void loadLib(String libLocation, boolean importAll) | void loadLib(String libLocation, boolean importAll) | ||||
throws ExecutionException; | 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; | |||||
} | } | ||||
@@ -133,9 +133,10 @@ public interface DataService { | |||||
* is an expensive operation since it must clone all of the property | * is an expensive operation since it must clone all of the property | ||||
* stores in all frames | * stores in all frames | ||||
* | * | ||||
* @return a Map containing the frames properties indexed by their full name. | |||||
* @return a Map containing the frames properties indexed by their full | |||||
* name. | |||||
*/ | */ | ||||
Map getAllProperties(); | |||||
Map getAllProperties(); | |||||
} | } | ||||
@@ -105,7 +105,7 @@ public abstract class AntException extends Exception { | |||||
*/ | */ | ||||
public AntException(String msg, Throwable cause, Location location) { | public AntException(String msg, Throwable cause, Location location) { | ||||
this(msg, cause); | this(msg, cause); | ||||
setLocation(location); | |||||
setLocation(location, true); | |||||
} | } | ||||
/** | /** | ||||
@@ -127,7 +127,7 @@ public abstract class AntException extends Exception { | |||||
*/ | */ | ||||
public AntException(String msg, Location location) { | public AntException(String msg, Location location) { | ||||
super(msg); | super(msg); | ||||
setLocation(location); | |||||
setLocation(location, true); | |||||
} | } | ||||
/** | /** | ||||
@@ -139,19 +139,22 @@ public abstract class AntException extends Exception { | |||||
*/ | */ | ||||
public AntException(Throwable cause, Location location) { | public AntException(Throwable cause, Location location) { | ||||
this(cause); | this(cause); | ||||
setLocation(location); | |||||
setLocation(location, true); | |||||
} | } | ||||
/** | /** | ||||
* Sets the file location where the error occured. | * Sets the file location where the error occured. | ||||
* | * | ||||
* @param location the new location value | |||||
* @param newLocation the new location value | |||||
* @param override true if the location should override any currently set location | |||||
*/ | */ | ||||
public void setLocation(Location location) { | |||||
if (location == null) { | |||||
this.location = Location.UNKNOWN_LOCATION; | |||||
} else { | |||||
this.location = location; | |||||
public void setLocation(Location newLocation, boolean override) { | |||||
if (override || location == Location.UNKNOWN_LOCATION) { | |||||
if (newLocation == null) { | |||||
this.location = Location.UNKNOWN_LOCATION; | |||||
} else { | |||||
this.location = newLocation; | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -51,7 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.util; | |||||
package org.apache.ant.common.util; | |||||
import java.util.Stack; | import java.util.Stack; | ||||
/** | /** |
@@ -51,10 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.util; | |||||
import org.apache.ant.common.util.AntException; | |||||
import org.apache.ant.common.util.Location; | |||||
package org.apache.ant.common.util; | |||||
/** | /** | ||||
* A CircularDependencyException indicates that a circular dependency has | * A CircularDependencyException indicates that a circular dependency has |
@@ -51,10 +51,7 @@ | |||||
* information on the Apache Software Foundation, please see | * information on the Apache Software Foundation, please see | ||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.ant.antcore.util; | |||||
import org.apache.ant.common.util.AntException; | |||||
import org.apache.ant.common.util.Location; | |||||
package org.apache.ant.common.util; | |||||
/** | /** | ||||
* A ConfigException indicates a problem with Ant's configuration or the | * A ConfigException indicates a problem with Ant's configuration or the |
@@ -0,0 +1,140 @@ | |||||
/* | |||||
* The Apache Software License, Version 1.1 | |||||
* | |||||
* Copyright (c) 2001 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 apache@apache.org. | |||||
* | |||||
* 5. Products derived from this software may not be called "Apache" | |||||
* nor may "Apache" appear in their names without prior written | |||||
* permission of the Apache Group. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
* ==================================================================== | |||||
* | |||||
* This software consists of voluntary contributions made by many | |||||
* individuals on behalf of the Apache Software Foundation. For more | |||||
* information on the Apache Software Foundation, please see | |||||
* <http://www.apache.org/>. | |||||
*/ | |||||
package org.apache.ant.common.util; | |||||
import java.io.PrintWriter; | |||||
import java.io.StringWriter; | |||||
import java.util.List; | |||||
import java.util.ArrayList; | |||||
/** | |||||
* A set of helper methods related to string manipulation. | |||||
* | |||||
* @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||||
*/ | |||||
public final class StringUtils { | |||||
/** the line separator for this OS */ | |||||
public final static String LINE_SEP = System.getProperty("line.separator"); | |||||
/** | |||||
* Convenient method to retrieve the full stacktrace from a given | |||||
* exception. | |||||
* | |||||
* @param t the exception to get the stacktrace from. | |||||
* @return the stacktrace from the given exception. | |||||
*/ | |||||
public static String getStackTrace(Throwable t) { | |||||
StringWriter sw = new StringWriter(); | |||||
PrintWriter pw = new PrintWriter(sw, true); | |||||
t.printStackTrace(pw); | |||||
pw.flush(); | |||||
pw.close(); | |||||
return sw.toString(); | |||||
} | |||||
/** | |||||
* Splits up a string into a list of lines. It is equivalent to <tt> | |||||
* split(data, '\n')</tt> . | |||||
* | |||||
* @param data the string to split up into lines. | |||||
* @return the list of lines available in the string. | |||||
*/ | |||||
public static List lineSplit(String data) { | |||||
return split(data, '\n'); | |||||
} | |||||
/** | |||||
* Splits up a string where elements are separated by a specific | |||||
* character and return all elements. | |||||
* | |||||
* @param data the string to split up. | |||||
* @param ch the separator character. | |||||
* @return the list of elements. | |||||
*/ | |||||
public static List split(String data, int ch) { | |||||
List elems = new ArrayList(); | |||||
int pos = -1; | |||||
int i = 0; | |||||
while ((pos = data.indexOf(ch, i)) != -1) { | |||||
String elem = data.substring(i, pos); | |||||
elems.add(elem); | |||||
i = pos + 1; | |||||
} | |||||
elems.add(data.substring(i)); | |||||
return elems; | |||||
} | |||||
/** | |||||
* Replace occurrences into a string. | |||||
* | |||||
* @param data the string to replace occurrences into | |||||
* @param from the occurrence to replace. | |||||
* @param to the occurrence to be used as a replacement. | |||||
* @return the new string with replaced occurrences. | |||||
*/ | |||||
public static String replace(String data, String from, String to) { | |||||
StringBuffer buf = new StringBuffer(data.length()); | |||||
int pos = -1; | |||||
int i = 0; | |||||
while ((pos = data.indexOf(from, i)) != -1) { | |||||
buf.append(data.substring(i, pos)).append(to); | |||||
i = pos + from.length(); | |||||
} | |||||
buf.append(data.substring(i)); | |||||
return buf.toString(); | |||||
} | |||||
} | |||||