diff --git a/proposal/mutant/build/ant1compat.xml b/proposal/mutant/build/ant1compat.xml index 039e4f2d6..af1fbac3b 100644 --- a/proposal/mutant/build/ant1compat.xml +++ b/proposal/mutant/build/ant1compat.xml @@ -98,6 +98,7 @@ + diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java index 1b27b7607..949a30c9d 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibManager.java @@ -65,7 +65,7 @@ import org.apache.ant.antcore.xml.ParseContext; 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.init.InitConfig; +import org.apache.ant.init.AntEnvironment; import org.apache.ant.init.LoaderUtils; /** @@ -90,7 +90,7 @@ public class AntLibManager { private boolean remoteAllowed; /** The Ant initialization config - location of vital components */ - private InitConfig initConfig; + private AntEnvironment antEnv; /** * This map stores a list of additional paths for each library indexed by @@ -101,13 +101,13 @@ public class AntLibManager { /** * Constructor for the AntLibManager object * - * @param initConfig the init config of the system. + * @param antEnv the init config of the system. * @param remoteAllowed true if remote libraries can be used and * configured */ - public AntLibManager(InitConfig initConfig, boolean remoteAllowed) { + public AntLibManager(AntEnvironment antEnv, boolean remoteAllowed) { this.remoteAllowed = remoteAllowed; - this.initConfig = initConfig; + this.antEnv = antEnv; } /** @@ -335,12 +335,12 @@ public class AntLibManager { urlsList.add(librarySpec.getLibraryURL()); } if (librarySpec.isToolsJarRequired() - && initConfig.getToolsJarURL() != null) { - urlsList.add(initConfig.getToolsJarURL()); + && antEnv.getToolsJarURL() != null) { + urlsList.add(antEnv.getToolsJarURL()); } if (librarySpec.usesAntXML()) { - URL[] parserURLs = initConfig.getParserURLs(); + URL[] parserURLs = antEnv.getParserURLs(); for (int i = 0; i < parserURLs.length; ++i) { urlsList.add(parserURLs[i]); } @@ -357,7 +357,7 @@ public class AntLibManager { antLibrary.setExtendsLibrary(extendsLibrary); } - antLibrary.setParentLoader(initConfig.getCommonLoader()); + antLibrary.setParentLoader(antEnv.getCommonLoader()); newLibraries.put(libraryId, antLibrary); if (libPathsMap != null) { diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java index 973d139a4..3f82a3818 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/config/AntConfigHandler.java @@ -78,7 +78,7 @@ public class AntConfigHandler extends ElementHandler { public static final String GLOBAL_TASKS_ELEMENT = "global-tasks"; /** The per-frame tasks element */ - public static final String PERFRAME_TASKS_ELEMENT = "frame-tasks"; + public static final String PERFRAME_TASKS_ELEMENT = "project-tasks"; /** The list of allowed Attributes */ public static final String[] ALLOWED_ATTRIBUTES diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java index a04595485..ae5d480e4 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/BuildEventSupport.java @@ -77,7 +77,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { * The listeners attached to the object which contains this support * object */ - private List listeners = new ArrayList(); + private ArrayList listeners = new ArrayList(); /** Records the latest task to be executed on a thread (Thread to Task). */ private Map threadTasks = new HashMap(); @@ -87,8 +87,8 @@ public class BuildEventSupport implements DemuxOutputReceiver { * * @return the listeners value */ - public Iterator getListeners() { - return listeners.iterator(); + public List getListeners() { + return (List) listeners.clone(); } /** @@ -116,6 +116,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { */ public void fireBuildStarted(ModelElement element) { BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_STARTED); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.buildStarted(event); @@ -132,6 +133,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { Throwable cause) { BuildEvent event = new BuildEvent(element, BuildEvent.BUILD_FINISHED, cause); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.buildFinished(event); @@ -145,6 +147,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { */ public void fireTargetStarted(ModelElement element) { BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_STARTED); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.targetStarted(event); @@ -161,6 +164,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { Throwable cause) { BuildEvent event = new BuildEvent(element, BuildEvent.TARGET_FINISHED, cause); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.targetFinished(event); @@ -177,6 +181,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { threadTasks.put(Thread.currentThread(), task); } BuildEvent event = new BuildEvent(task, BuildEvent.TASK_STARTED); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.taskStarted(event); @@ -198,6 +203,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { } BuildEvent event = new BuildEvent(task, BuildEvent.TASK_FINISHED, cause); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.taskFinished(event); @@ -214,6 +220,7 @@ public class BuildEventSupport implements DemuxOutputReceiver { public void fireMessageLogged(Object source, String message, int priority) { BuildEvent event = new BuildEvent(source, message, priority); + List listeners = getListeners(); for (Iterator i = listeners.iterator(); i.hasNext();) { BuildListener listener = (BuildListener) i.next(); listener.messageLogged(event); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java index 422cbd7e1..14f656337 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/ComponentManager.java @@ -80,6 +80,8 @@ import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.Location; import org.apache.ant.init.LoaderUtils; +import org.apache.ant.common.util.AttributeCollection; +import org.apache.ant.common.constants.Namespace; /** * The instance of the ComponentServices made available by the core to the ant @@ -684,7 +686,7 @@ public class ComponentManager implements ComponentService { // is there a polymorph indicator - look in Ant aspects String typeName - = model.getAspectAttributeValue(Constants.ANT_ASPECT, "type"); + = model.getNamespaceAttributeValue(Namespace.ANT_META_URI, "type"); Object typeInstance = null; if (typeName != null) { @@ -767,13 +769,14 @@ public class ComponentManager implements ComponentService { * @exception AntException if the object does not support an * attribute in the map. */ - public void configureAttributes(Object object, Map attributeValues, + public void configureAttributes(Object object, + AttributeCollection attributeValues, boolean ignoreUnsupported) throws AntException { Setter setter = getSetter(object.getClass()); - for (Iterator i = attributeValues.keySet().iterator(); i.hasNext();) { + for (Iterator i = attributeValues.getAttributeNames(); i.hasNext();) { String attributeName = (String) i.next(); - String attributeValue = (String) attributeValues.get(attributeName); + String attributeValue = attributeValues.getAttribute(attributeName); if (!setter.supportsAttribute(attributeName)) { if (!ignoreUnsupported) { throw new ExecutionException(object.getClass().getName() diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java index 7b93c42cc..341184371 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Constants.java @@ -62,8 +62,5 @@ package org.apache.ant.antcore.execution; public abstract class Constants { /** The prefix for library ids that are automatically imported */ public static final String ANT_LIB_PREFIX = "ant."; - - /** The Ant aspect used to identify Ant metadata */ - public static final String ANT_ASPECT = "ant"; } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java index bb9a0c5c8..084a12a71 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/CoreExecService.java @@ -54,7 +54,6 @@ package org.apache.ant.antcore.execution; import java.io.File; import java.net.MalformedURLException; -import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ant.antcore.modelparser.XMLProjectParser; @@ -64,9 +63,8 @@ import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.model.Project; import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.service.ExecService; -import org.apache.ant.common.service.BuildKey; import org.apache.ant.init.InitUtils; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; import org.apache.ant.common.event.BuildListener; import org.apache.ant.common.util.AntException; @@ -81,10 +79,6 @@ public class CoreExecService implements ExecService { /** The Frame this service instance is working for */ private Frame frame; - /** A map of subbuild keys to the frame of the subbuild. */ - private Map subBuilds = new HashMap(); - - /** * Constructor * @@ -106,11 +100,11 @@ public class CoreExecService implements ExecService { ExecutionContext execContext = getTaskExecutionContext(task); BuildElement model = execContext.getModel(); - AspectValueCollection aspectValues = null; + NamespaceValueCollection namespaceValues = null; if (model != null) { - aspectValues = model.getAspectAttributes(); + namespaceValues = model.getNamespaceAttributes(); } - frame.executeTask(task, aspectValues); + frame.executeTask(task, namespaceValues); } /** @@ -144,7 +138,7 @@ public class CoreExecService implements ExecService { * @param aspectValues the aspect attribute values. * @exception AntException if there is an execution problem */ - public void executeTask(Task task, AspectValueCollection aspectValues) + public void executeTask(Task task, NamespaceValueCollection aspectValues) throws AntException { ExecutionContext execContext = getTaskExecutionContext(task); @@ -184,24 +178,6 @@ public class CoreExecService implements ExecService { } - /** - * Gets the Frame for a subbuild based on the key - * - * @param key Description of the Parameter - * @return the subbuild's Frame - * @exception ExecutionException if the build cannot be found. - */ - private Frame getSubbuildFrame(Object key) throws ExecutionException { - Frame subFrame = (Frame) subBuilds.get(key); - - if (subFrame == null) { - throw new ExecutionException("Could not find execution frame " - + "for subbuild"); - } - return subFrame; - } - - /** * Handle subbuild output. * @@ -212,7 +188,8 @@ public class CoreExecService implements ExecService { */ public void handleBuildOutput(Object subbuildKey, String line, boolean isErr) throws ExecutionException { - getSubbuildFrame(subbuildKey).threadOutput(line, isErr); + Frame subFrame = (Frame) subbuildKey; + subFrame.threadOutput(line, isErr); } @@ -224,9 +201,9 @@ public class CoreExecService implements ExecService { * @param libraryId the id of the library to be initialized. * @exception AntException if the build cannot be run */ - public void initializeBuildLibrary(BuildKey key, String libraryId) + public void initializeBuildLibrary(Object key, String libraryId) throws AntException { - Frame subFrame = getSubbuildFrame(key); + Frame subFrame = (Frame) key; subFrame.initializeLibrary(libraryId); } @@ -238,9 +215,10 @@ public class CoreExecService implements ExecService { * * @exception ExecutionException if the build cannot be found. */ - public void addBuildListener(BuildKey key, BuildListener listener) + public void addBuildListener(Object key, BuildListener listener) throws ExecutionException { - getSubbuildFrame(key).addBuildListener(listener); + Frame subFrame = (Frame) key; + subFrame.addBuildListener(listener); } @@ -251,20 +229,9 @@ public class CoreExecService implements ExecService { * @param key Description of the Parameter * @exception AntException if the build cannot be run */ - public void runBuild(BuildKey key, List targets) throws AntException { - getSubbuildFrame(key).runBuild(targets); - } - - - /** - * Release a subbuild that is no longer in use. - * - * @param key the BuildKey identifiying the subbuild. - * - * @exception ExecutionException if the build was not registered. - */ - public void releaseBuild(BuildKey key) throws ExecutionException { - subBuilds.remove(key); + public void runBuild(Object key, List targets) throws AntException { + Frame subFrame = (Frame) key; + subFrame.runBuild(targets); } @@ -316,7 +283,7 @@ public class CoreExecService implements ExecService { * @return Description of the Return Value * @exception AntException if the subbuild cannot be run */ - public BuildKey setupBuild(Project model, Map properties, + public Object setupBuild(Project model, Map properties, boolean addListeners) throws AntException { Frame newFrame = frame.createFrame(model); @@ -325,11 +292,7 @@ public class CoreExecService implements ExecService { } newFrame.initialize(properties); - // create an anonymous inner class key. - BuildKey key = new BuildKey() {}; - - subBuilds.put(key, newFrame); - return key; + return newFrame; } @@ -342,7 +305,7 @@ public class CoreExecService implements ExecService { * @return Description of the Return Value * @exception AntException if the subbuild cannot be run */ - public BuildKey setupBuild(Map properties, boolean addListeners) + public Object setupBuild(Map properties, boolean addListeners) throws AntException { return setupBuild(frame.getProject(), properties, addListeners); } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java index c3c89661c..9d404864f 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/execution/Frame.java @@ -72,7 +72,7 @@ import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.model.ModelException; import org.apache.ant.common.model.Project; import org.apache.ant.common.model.Target; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.EventService; @@ -84,7 +84,7 @@ import org.apache.ant.common.util.DemuxOutputReceiver; import org.apache.ant.common.util.FileUtils; import org.apache.ant.common.util.Location; import org.apache.ant.common.util.AntException; -import org.apache.ant.init.InitConfig; +import org.apache.ant.init.AntEnvironment; import org.apache.ant.init.LoaderUtils; /** @@ -129,7 +129,7 @@ public class Frame implements DemuxOutputReceiver { * Ant's initialization configuration with information on the location of * Ant and its libraries. */ - private InitConfig initConfig; + private AntEnvironment antEnv; /** BuildEvent support used to fire events and manage listeners */ private BuildEventSupport eventSupport = new BuildEventSupport(); @@ -176,26 +176,26 @@ public class Frame implements DemuxOutputReceiver { * Create the main or root Execution Frame. * * @param config the user config to use for this execution of Ant - * @param initConfig Ant's initialisation config + * @param antEnv Ant's initialisation config */ - public Frame(InitConfig initConfig, AntConfig config) { + public Frame(AntEnvironment antEnv, AntConfig config) { this.config = config; - this.initConfig = initConfig; + this.antEnv = antEnv; this.parent = null; this.libManager - = new AntLibManager(initConfig, config.isRemoteLibAllowed()); + = new AntLibManager(antEnv, config.isRemoteLibAllowed()); } /** * Create an Execution Frame. * * @param config the user config to use for this execution of Ant - * @param initConfig Ant's initialisation config + * @param antEnv Ant's initialisation config * @param parent the frame creating this frame. */ - private Frame(InitConfig initConfig, AntConfig config, Frame parent) { + private Frame(AntEnvironment antEnv, AntConfig config, Frame parent) { this.config = config; - this.initConfig = initConfig; + this.antEnv = antEnv; this.parent = parent; this.libManager = parent.libManager; } @@ -396,7 +396,7 @@ public class Frame implements DemuxOutputReceiver { */ protected void setMagicProperties() throws AntException { // ant.home - URL antHomeURL = initConfig.getAntHome(); + URL antHomeURL = antEnv.getAntHome(); String antHomeString = null; if (antHomeURL.getProtocol().equals("file")) { @@ -500,8 +500,8 @@ public class Frame implements DemuxOutputReceiver { * * @return Ant's initialization configuration */ - protected InitConfig getInitConfig() { - return initConfig; + protected AntEnvironment getAntEnvironment() { + return antEnv; } @@ -726,7 +726,7 @@ public class Frame implements DemuxOutputReceiver { protected Frame createFrame(Project project) throws ModelException { Frame newFrame - = new Frame(initConfig, config, this); + = new Frame(antEnv, config, this); newFrame.setProject(project); @@ -740,7 +740,8 @@ public class Frame implements DemuxOutputReceiver { * will be added. */ protected void addListeners(Frame subFrame) { - for (Iterator j = eventSupport.getListeners(); j.hasNext();) { + List listeners = eventSupport.getListeners(); + for (Iterator j = listeners.iterator(); j.hasNext();) { BuildListener listener = (BuildListener) j.next(); subFrame.addBuildListener(listener); @@ -863,6 +864,10 @@ public class Frame implements DemuxOutputReceiver { } String fullProjectName = getFullProjectName(fullTargetName); Frame frame = getContainingFrame(fullTargetName); + if (frame == null) { + throw new ExecutionException("No project available under the " + + "referenced name \"" + fullTargetName, targetRefLocation); + } String localTargetName = getNameInFrame(fullTargetName); Target target = frame.getProject().getTarget(localTargetName); if (target == null) { @@ -930,17 +935,18 @@ public class Frame implements DemuxOutputReceiver { * Execute a task with the given aspect values. * * @param task the task to be executed. - * @param aspectValues the collection of aspect attribute values. + * @param namespaceValues the collection of namespace attribute values. * @exception AntException if the task has a problem. */ - protected void executeTask(Task task, AspectValueCollection aspectValues) + protected void executeTask(Task task, + NamespaceValueCollection namespaceValues) throws AntException { List aspects = componentManager.getAspects(); Map aspectContexts = new HashMap(); for (Iterator i = aspects.iterator(); i.hasNext();) { Aspect aspect = (Aspect) i.next(); - Object aspectContext = aspect.preExecuteTask(task, aspectValues); + Object aspectContext = aspect.preExecuteTask(task, namespaceValues); if (aspectContext != null) { aspectContexts.put(aspect, aspectContext); } @@ -1156,14 +1162,14 @@ public class Frame implements DemuxOutputReceiver { try { // load system ant lib URL systemLibs - = new URL(initConfig.getLibraryURL(), "syslibs/"); + = new URL(antEnv.getLibraryURL(), "syslibs/"); componentManager.loadLib(systemLibs, false); importStandardComponents(); executeTasks(config.getGlobalTasks()); // now load other system libraries - URL antLibs = new URL(initConfig.getLibraryURL(), "antlibs/"); + URL antLibs = new URL(antEnv.getLibraryURL(), "antlibs/"); componentManager.loadLib(antLibs, false); runBuild(targets); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java index df406840e..04f35d6a2 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/BuildElementHandler.java @@ -87,13 +87,13 @@ public class BuildElementHandler extends ModelElementHandler { buildElement = new BuildElement(getLocation(), elementName); setModelElement(buildElement); - + for (Iterator i = getAttributes(); i.hasNext();) { String attributeName = (String) i.next(); buildElement.addAttribute(attributeName, getAttribute(attributeName)); } - buildElement.addAspectAttributes(getAspectAttributes()); + addNamespaceAttributes(); } @@ -110,6 +110,7 @@ public class BuildElementHandler extends ModelElementHandler { public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) throws SAXParseException { + // everything within a task element is also a task element BuildElementHandler nestedHandler = new BuildElementHandler(); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ModelElementHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ModelElementHandler.java index e57763287..49edd3b8e 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ModelElementHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ModelElementHandler.java @@ -55,6 +55,8 @@ package org.apache.ant.antcore.modelparser; import org.apache.ant.antcore.xml.ElementHandler; import org.apache.ant.common.model.ModelElement; +import java.util.Iterator; +import org.apache.ant.common.util.AttributeCollection; /** * A BuildElementHandler parses the task elements of a build. Task elements @@ -84,5 +86,18 @@ public abstract class ModelElementHandler extends ElementHandler { modelElement.setEndLocation(getLocation()); } } + + /** + * Add all attributes which belong to namespaces rather than the default + * namespace for the build files. + */ + protected void addNamespaceAttributes() { + for (Iterator i = getNamespaces(); i.hasNext();) { + String uri = (String) i.next(); + AttributeCollection namespaceValues = getNamespaceAttributes(uri); + modelElement.addNamespaceAttributes(uri, namespaceValues); + } + } + } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java index 1d8db526b..62ddf573f 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/ProjectHandler.java @@ -77,10 +77,10 @@ public class ProjectHandler extends ModelElementHandler { /** The name of the element used to define references */ public static final String REF_ELEMENT = "ant:ref"; - + /** The name of the element used to define references */ public static final String INCLUDE_ELEMENT = "ant:include"; - + /** The name of the element used to define references */ public static final String TARGET_ELEMENT = "target"; @@ -129,11 +129,11 @@ public class ProjectHandler extends ModelElementHandler { if (project == null) { project = new Project(getElementSource(), getLocation()); setModelElement(project); - + project.setDefaultTarget(getAttribute(DEFAULT_ATTR)); project.setBase(getAttribute(BASEDIR_ATTR)); project.setName(getAttribute(NAME_ATTR)); - project.addAspectAttributes(getAspectAttributes()); + addNamespaceAttributes(); } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java index 5469f3f25..f359fd537 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/TargetHandler.java @@ -76,7 +76,7 @@ public class TargetHandler extends ModelElementHandler { /** The if attribute name */ public static final String IF_ATTR = "if"; - + /** The unless attribute name */ public static final String UNLESS_ATTR = "unless"; @@ -105,7 +105,7 @@ public class TargetHandler extends ModelElementHandler { target = new Target(getLocation(), getAttribute(NAME_ATTR)); setModelElement(target); target.setDescription(getAttribute(DESC_ATTR)); - target.addAspectAttributes(getAspectAttributes()); + addNamespaceAttributes(); String depends = getAttribute(DEPENDS_ATTR); if (depends != null) { @@ -151,9 +151,9 @@ public class TargetHandler extends ModelElementHandler { protected void validateAttribute(String attributeName, String attributeValue) 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); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java index bb568d32a..e28b2167b 100644 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/modelparser/XMLProjectParser.java @@ -78,6 +78,7 @@ public class XMLProjectParser { throws XMLParseException { try { ParseContext context = new ParseContext(); + context.declareNamespace("ant", "http://jakarta.apache.org/ant"); ProjectHandler projectHandler = new ProjectHandler(); context.parse(buildSource, "project", projectHandler); diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java index 6e576eff3..2eb56f960 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ElementHandler.java @@ -58,6 +58,7 @@ import java.util.Iterator; import java.util.Map; import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AttributeCollection; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; @@ -98,10 +99,13 @@ public abstract class ElementHandler extends DefaultHandler { private String elementName; /** The attributes read from this element */ - private Map elementAttributes; + private AttributeCollection elementAttributes; - /** The aspect attributes read from the element definition */ - private Map aspectAttributes; + /** + * This map contains a set of attribute collections for each namespace + * encountered. + */ + private Map namespaces; /** The content of this element */ private String content; @@ -115,6 +119,29 @@ public abstract class ElementHandler extends DefaultHandler { return source; } + /** + * Get an interator over the namespace URIs encountered in the processing + * of the element + * + * @return an iterator over the namespace URIs. + */ + public Iterator getNamespaces() { + return namespaces.keySet().iterator(); + } + + /** + * Get the collection of namespace attributes for a given namespace. + * + * @param uri the URI of the namespace from which the attribute collection + * is required. + * + * @return an attribute collection if any attributes of the requested + * namespace have beebn encountered - otherwise null. + */ + public AttributeCollection getNamespaceAttributes(String uri) { + return (AttributeCollection) namespaces.get(uri); + } + /** * Gets the attributeValue attribute of the ElementHandler object * @@ -123,7 +150,7 @@ public abstract class ElementHandler extends DefaultHandler { * snot defined. */ public String getAttribute(String attributeName) { - return (String) elementAttributes.get(attributeName); + return elementAttributes.getAttribute(attributeName); } /** @@ -135,23 +162,14 @@ public abstract class ElementHandler extends DefaultHandler { protected boolean getBooleanAttribute(String attributeName) { return PropertyUtils.toBoolean(getAttribute(attributeName)); } - + /** * Get an iterator to this elements attributes * * @return an iterator over the attribute names */ public Iterator getAttributes() { - return elementAttributes.keySet().iterator(); - } - - /** - * Get the aspect attributes of this element. - * - * @return The aspect attributes. - */ - public Map getAspectAttributes() { - return aspectAttributes; + return elementAttributes.getAttributeNames(); } /** @@ -313,17 +331,35 @@ public abstract class ElementHandler extends DefaultHandler { */ protected final void processAttributes(Attributes attributes) throws SAXParseException { - aspectAttributes = new HashMap(); - elementAttributes = new HashMap(); - int length = attributes.getLength(); + namespaces = new HashMap(); + elementAttributes = new AttributeCollection(); + int length = attributes.getLength(); for (int i = 0; i < length; ++i) { - String attributeName = attributes.getQName(i); + String uri = attributes.getURI(i); + if (uri != null && uri.trim().length() == 0) { + uri = null; + } + String localName = attributes.getLocalName(i); + String qName = attributes.getQName(i); + if (uri == null && qName.indexOf(":") != -1) { + // try to resolve through known namespaces + uri = context.resolveNamespace(qName); + localName = qName.substring(qName.indexOf(":") + 1); + } + String attributeValue = attributes.getValue(i); - if (attributeName.indexOf(":") != -1) { - aspectAttributes.put(attributeName, attributeValue); + if (uri != null) { + AttributeCollection namespaceAttributes + = (AttributeCollection) namespaces.get(uri); + if (namespaceAttributes == null) { + namespaceAttributes = new AttributeCollection(); + namespaces.put(uri, namespaceAttributes); + } + + namespaceAttributes.putAttribute(localName, attributeValue); } else { - validateAttribute(attributeName, attributeValue); - elementAttributes.put(attributeName, attributeValue); + validateAttribute(localName, attributeValue); + elementAttributes.putAttribute(localName, attributeValue); } } } diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java index ed9711fee..20bcdbdf6 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/xml/ParseContext.java @@ -54,6 +54,8 @@ package org.apache.ant.antcore.xml; import java.io.IOException; +import java.util.Map; +import java.util.HashMap; import java.net.URL; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; @@ -73,6 +75,9 @@ import org.xml.sax.XMLReader; * @created 9 January 2002 */ public class ParseContext { + /** These are namespace to URIs which need not be declared in the XML */ + private Map knownNamespaces = new HashMap(); + /** * Used to check if we are trying to parse a build file within its own * context. @@ -145,5 +150,29 @@ public class ParseContext { throw new XMLParseException(e); } } + + /** + * Given an XML qName, this method tries to resolve a name into a URI + * using the map of well known namespaces. + * + * @param qName the XML qName + * @return the namespace URI for the given name. If the namespace + * prefix is unknown the prefix is returned. + */ + public String resolveNamespace(String qName) { + String namespaceId = qName.substring(0, qName.indexOf(":")); + String namespaceURI = (String) knownNamespaces.get(namespaceId); + return namespaceURI == null ? namespaceId : namespaceURI; + } + + /** + * Declare a namespace + * + * @param prefix the prefix that is used in the XML for the namespace. + * @param uri the namespace's unique URI. + */ + public void declareNamespace(String prefix, String uri) { + knownNamespaces.put(prefix, uri); + } } diff --git a/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml b/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml index 8d0399e29..50a1570c7 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml +++ b/proposal/mutant/src/java/antlibs/ant1compat/antlib.xml @@ -1,18 +1,21 @@ - - - - + + + + + + @@ -27,15 +30,19 @@ + + + + @@ -56,6 +63,10 @@ + + + + @@ -65,13 +76,13 @@ - - + + @@ -101,6 +112,8 @@ + + @@ -119,6 +132,7 @@ + @@ -132,8 +146,11 @@ + + + @@ -142,28 +159,36 @@ + + + - + + - - - + + + + + + - - + - - - + + + + - + + diff --git a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java index d2bcd0bfd..8ff27de8e 100644 --- a/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java +++ b/proposal/mutant/src/java/antlibs/ant1compat/org/apache/tools/ant/Project.java @@ -68,7 +68,6 @@ import java.util.Vector; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.event.MessageLevel; -import org.apache.ant.common.service.BuildKey; import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.ExecService; @@ -197,7 +196,7 @@ public class Project implements org.apache.ant.common.event.BuildListener { /** * The build key used to control the proxied build. */ - private BuildKey proxyBuildKey; + private Object proxyBuildKey; /** * The subordinate project if proxying diff --git a/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java index dcef233de..0c11fcfb2 100644 --- a/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java +++ b/proposal/mutant/src/java/antlibs/monitor/org/apache/ant/antlib/monitor/MonitorAspect.java @@ -57,7 +57,7 @@ import org.apache.ant.common.antlib.AbstractAspect; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.model.BuildElement; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; import org.apache.ant.common.util.AntException; import org.apache.ant.common.event.MessageLevel; import java.util.Date; @@ -97,8 +97,8 @@ public class MonitorAspect extends AbstractAspect { * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use - * during the task execution - may be null if no aspect values are + * @param namespaceValues a collection of namesapce attribute values for use + * during the task execution - may be null if no namespace values are * provided. * @return an object which indicates that this aspect wishes to * be notified after execution has been completed, in which case the obkect @@ -106,7 +106,8 @@ public class MonitorAspect extends AbstractAspect { * the aspect's postExecuteTask method will not be invoked. * @exception AntException if the aspect cannot process the task. */ - public Object preExecuteTask(Task task, AspectValueCollection aspectValues) + public Object preExecuteTask(Task task, + NamespaceValueCollection namespaceValues) throws AntException { System.gc(); AntContext taskContext = task.getAntContext(); diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java index 404ab1725..5e62557ed 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/Ant.java @@ -57,7 +57,6 @@ import java.io.PrintStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.ant.common.model.Project; -import org.apache.ant.common.service.BuildKey; import org.apache.ant.common.service.ExecService; import org.apache.ant.common.service.FileService; import org.apache.ant.common.service.MagicProperties; @@ -137,7 +136,7 @@ public class Ant extends AntBase { ExecService execService = getExecService(); Project model = execService.parseXMLBuildFile(antFile); - BuildKey key = execService.setupBuild(model, getProperties(), true); + Object key = execService.setupBuild(model, getProperties(), true); setSubBuildKey(key); @@ -166,7 +165,7 @@ public class Ant extends AntBase { } execService.runBuild(key, getTargets()); - execService.releaseBuild(key); + setSubBuildKey(null); } } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java index a2458d114..9102e7747 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntAspect.java @@ -53,7 +53,6 @@ */ package org.apache.ant.antlib.system; -import java.util.Map; import org.apache.ant.common.antlib.AbstractAspect; import org.apache.ant.common.antlib.AntContext; import org.apache.ant.common.antlib.Task; @@ -62,7 +61,9 @@ import org.apache.ant.common.service.DataService; import org.apache.ant.common.service.ComponentService; import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.BuildElement; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; +import org.apache.ant.common.util.AttributeCollection; +import org.apache.ant.common.constants.Namespace; /** * The Ant aspect - handles all ant aspects @@ -70,9 +71,6 @@ import org.apache.ant.common.model.AspectValueCollection; * @author Conor MacNeill */ public class AntAspect extends AbstractAspect { - /** The Ant aspect used to identify Ant metadata */ - public static final String ANT_ASPECT = "ant"; - /** The core's data service implementation */ private DataService dataService = null; @@ -107,7 +105,8 @@ public class AntAspect extends AbstractAspect { */ public Object preCreateComponent(Object component, BuildElement model) throws AntException { - String refId = model.getAspectAttributeValue(ANT_ASPECT, "refid"); + String refId + = model.getNamespaceAttributeValue(Namespace.ANT_META_URI, "refid"); if (refId != null) { if (model.getAttributeNames().hasNext() || model.getNestedElements().hasNext() || @@ -141,7 +140,8 @@ public class AntAspect extends AbstractAspect { */ public Object postCreateComponent(Object component, BuildElement model) throws AntException { - String typeId = model.getAspectAttributeValue(ANT_ASPECT, "id"); + String typeId + = model.getNamespaceAttributeValue(Namespace.ANT_META_URI, "id"); if (typeId != null) { dataService.setMutableDataValue(typeId, component); @@ -154,7 +154,7 @@ public class AntAspect extends AbstractAspect { * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use + * @param namespaceValues a collection of namespace attribute values for use * during the task execution. * * @return an objectwhich indicates that this aspect wishes to @@ -163,10 +163,12 @@ public class AntAspect extends AbstractAspect { * the aspect's postExecuteTask method will not be invoked. * @exception AntException if the aspect cannot process the task. */ - public Object preExecuteTask(Task task, AspectValueCollection aspectValues) + public Object preExecuteTask(Task task, + NamespaceValueCollection namespaceValues) throws AntException { AntAspectContext aspectContext = new AntAspectContext(); - Map antAspectValues = aspectValues.getAttributes(ANT_ASPECT); + AttributeCollection antAspectValues + = namespaceValues.getAttributes(Namespace.ANT_META_URI); if (antAspectValues == null) { return null; } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java index b67be9791..44afc828c 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntBase.java @@ -56,7 +56,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.ant.common.util.AntException; -import org.apache.ant.common.service.BuildKey; /** * Common Base class for the Ant and AntCall tasks @@ -81,7 +80,7 @@ public abstract class AntBase extends SubBuild { /** * The key to the subbuild with which the Ant task can manage the subbuild */ - private BuildKey subbuildKey; + private Object subbuildKey; /** The name of the target to be evaluated in the sub-build */ private String targetName; @@ -181,7 +180,7 @@ public abstract class AntBase extends SubBuild { * * @param key the key returned by the Ant core for managing the subbuild */ - protected void setSubBuildKey(BuildKey key) { + protected void setSubBuildKey(Object key) { this.subbuildKey = key; } diff --git a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java index b93d1b149..f3abb82f8 100644 --- a/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java +++ b/proposal/mutant/src/java/antlibs/system/org/apache/ant/antlib/system/AntCall.java @@ -54,7 +54,6 @@ package org.apache.ant.antlib.system; import org.apache.ant.common.util.AntException; import org.apache.ant.common.service.MagicProperties; -import org.apache.ant.common.service.BuildKey; /** * The Ant task - used to execute a different build file @@ -72,10 +71,10 @@ public class AntCall extends AntBase { setProperty(MagicProperties.BASEDIR, getExecService().getBaseDir().getAbsolutePath()); - BuildKey key = getExecService().setupBuild(getProperties(), true); + Object key = getExecService().setupBuild(getProperties(), true); setSubBuildKey(key); getExecService().runBuild(key, getTargets()); - getExecService().releaseBuild(key); + setSubBuildKey(null); } /** diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java b/proposal/mutant/src/java/common/org/apache/ant/common/Namespace.java similarity index 79% rename from proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java rename to proposal/mutant/src/java/common/org/apache/ant/common/Namespace.java index 678138ffb..76ee4e69d 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/BuildKey.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/Namespace.java @@ -51,13 +51,27 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.ant.common.service; +package org.apache.ant.common.constants; /** - * Opaque key used to refer to builds setup in the core. + * Namespace constants * * @author Conor MacNeill + * @created 14 June 2002 */ -public interface BuildKey { +public class Namespace { + /** The Ant namespace used to identify Ant metadata */ + public static final String ANT_META_URI + = "http://jakarta.apache.org/ant/meta"; + + /** The namespace id that is predeclared for the Ant metadata namespace */ + public static final String ANT_META_PREFIX = "ant"; + + /** The XML Schema namespace */ + public static final String XSI_URI + = "http://www.w3.org/2001/XMLSchema-instance"; + + /** The namespace id that is predeclared for the Ant metadata namespace */ + public static final String XSI_PREFIX = "xsi"; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java index 089dea59c..b00aeddae 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/AbstractAspect.java @@ -55,7 +55,7 @@ package org.apache.ant.common.antlib; import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.BuildElement; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; /** * An implementation of the Aspect interface providing default behaviour. @@ -126,8 +126,8 @@ public class AbstractAspect implements Aspect { * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use - * during the task execution - may be null if no aspect values are + * @param namespaceValues a collection of namespace attribute values for use + * during the task execution - may be null if no namespace values are * provided. * @return an object which indicates that this aspect wishes to * be notified after execution has been completed, in which case the obkect @@ -135,7 +135,8 @@ public class AbstractAspect implements Aspect { * the aspect's postExecuteTask method will not be invoked. * @exception AntException if the aspect cannot process the task. */ - public Object preExecuteTask(Task task, AspectValueCollection aspectValues) + public Object preExecuteTask(Task task, + NamespaceValueCollection namespaceValues) throws AntException { return null; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java index ced0d4562..5d8f4203f 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/antlib/Aspect.java @@ -55,7 +55,7 @@ package org.apache.ant.common.antlib; import org.apache.ant.common.util.AntException; import org.apache.ant.common.model.BuildElement; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; /** * An aspect is a component which is activated across all task and @@ -108,8 +108,8 @@ public interface Aspect { * This join point is activated just prior to task execution. * * @param task the task being executed. - * @param aspectValues a collection of aspect attribute values for use - * during the task execution - may be null if no aspect values are + * @param namespaceValues a collection of namespace attribute values for use + * during the task execution - may be null if no namespace values are * provided. * @return an object which indicates that this aspect wishes to * be notified after execution has been completed, in which case the obkect @@ -117,7 +117,7 @@ public interface Aspect { * the aspect's postExecuteTask method will not be invoked. * @exception AntException if the aspect cannot process the task. */ - Object preExecuteTask(Task task, AspectValueCollection aspectValues) + Object preExecuteTask(Task task, NamespaceValueCollection namespaceValues) throws AntException; /** diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java b/proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java index 4bb9643d4..3a803e039 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/model/ModelElement.java @@ -54,9 +54,9 @@ package org.apache.ant.common.model; import java.util.Iterator; -import java.util.Map; import org.apache.ant.common.util.Location; +import org.apache.ant.common.util.AttributeCollection; /** * A ModelElement is an element of a build model. A location may be @@ -68,11 +68,12 @@ import org.apache.ant.common.util.Location; */ public abstract class ModelElement { /** The aspectValues defined for this element. */ - private AspectValueCollection aspectValues = new AspectValueCollection(); + private NamespaceValueCollection namespaceValues + = new NamespaceValueCollection(); /** The starting location of this element */ private Location location = Location.UNKNOWN_LOCATION; - + /** The ending location of this element */ private Location endLocation = Location.UNKNOWN_LOCATION; @@ -105,15 +106,17 @@ public abstract class ModelElement { public void setEndLocation(Location endLocation) { this.endLocation = endLocation; } - + /** - * Adds aspect related attributes of this element + * Adds attributes of a given namespace detected for this element. * - * @param aspectAttributes a Map of aspect realted attributes that pertain - * to this model element. + * @param uri the namespace's URI. + * @param attributes the attribute collection of the namespace's attribute + * values. */ - public void addAspectAttributes(Map aspectAttributes) { - aspectValues.addAttributes(aspectAttributes); + public void addNamespaceAttributes(String uri, + AttributeCollection attributes) { + namespaceValues.addAttributes(uri, attributes); } /** @@ -144,44 +147,45 @@ public abstract class ModelElement { } /** - * Get an iterator on the aspectValues which have been given values on this + * Get an iterator on the namespaces which have been given values on this * element * - * @return an iterator of Strings , being the aspectValues which have been + * @return an iterator of Strings, being the namespaces which have been * given values on this element. */ - public Iterator getAspectNames() { - return aspectValues.getNames(); + public Iterator getNamespaceURIs() { + return namespaceValues.getNames(); } /** - * Get the set of attribute values related to the given aspect + * Get the set of attribute values related to the given namespace * - * @param aspectName the aspect identifier - * @return a map of the attribute values for the given aspect. + * @param namespaceURI the namesace URI. + * @return a map of the attribute values for the given namespace. */ - public Map getAspectAttributes(String aspectName) { - return aspectValues.getAttributes(aspectName); + public AttributeCollection getNamespaceAttributes(String namespaceURI) { + return namespaceValues.getAttributes(namespaceURI); } /** - * Get the value of a single aspect attribute + * Get the value of a single namespace attribute * - * @param aspectName the aspect name + * @param namepaceURI the aspect name * @param keyName the attribute name * @return the aspect value */ - public String getAspectAttributeValue(String aspectName, String keyName) { - return aspectValues.getAttributeValue(aspectName, keyName); + public String getNamespaceAttributeValue(String namepaceURI, + String keyName) { + return namespaceValues.getAttributeValue(namepaceURI, keyName); } - + /** - * Get the complete collection of aspect attribute values. + * Get the complete collection of namespace attribute values. * - * @return an AspectValueCollection instance. + * @return an NamespaceValueCollection instance. */ - public AspectValueCollection getAspectAttributes() { - return aspectValues; + public NamespaceValueCollection getNamespaceAttributes() { + return namespaceValues; } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/model/AspectValueCollection.java b/proposal/mutant/src/java/common/org/apache/ant/common/model/NamespaceValueCollection.java similarity index 59% rename from proposal/mutant/src/java/common/org/apache/ant/common/model/AspectValueCollection.java rename to proposal/mutant/src/java/common/org/apache/ant/common/model/NamespaceValueCollection.java index 3c0f6db46..374a756ee 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/model/AspectValueCollection.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/model/NamespaceValueCollection.java @@ -55,80 +55,77 @@ package org.apache.ant.common.model; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import org.apache.ant.common.util.AttributeCollection; /** - * The AspectValueCollection holds aspect values for a range of aspects. - * Values can be retrieved for a particular aspect attribute or all attributes - * of a given aspect. - * + * The NamespaceValueCollection holds namespace values for a range of + * namespaces. Values can be retrieved for a particular namespace attribute + * or all attributes of a given namespace. + * * @author Conor MacNeill * @created 11 January 2002 */ -public class AspectValueCollection { - /** The aspects defined for this element. */ - private Map aspectMaps = new HashMap(); +public class NamespaceValueCollection { + /** + * The namespaces defined for this collection. Each entry is an attribute + * collection keyed by the namespace URI. + */ + private Map namespaces = new HashMap(); /** - * Set the aspect attribute values. + * Add the attributes of a given namespace to this collection. * - * The attributes are sorted into their various aspects - * - * @param attributes a Map of aspect attributes values. The keys are the - * aspect + * @param uri the namespace's URI. + * @param attributes the collection of attributes for the given namespace. */ - public void addAttributes(Map attributes) { - for (Iterator i = attributes.keySet().iterator(); i.hasNext();) { + public void addAttributes(String uri, AttributeCollection attributes) { + AttributeCollection currentCollection + = (AttributeCollection) namespaces.get(uri); + if (currentCollection == null) { + currentCollection = new AttributeCollection(); + namespaces.put(uri, currentCollection); + } + for (Iterator i = attributes.getAttributeNames(); i.hasNext();) { String attributeName = (String) i.next(); - int separator = attributeName.indexOf(":"); - if (separator != -1) { - String aspectName = attributeName.substring(0, separator); - String name = attributeName.substring(separator + 1); - if (aspectName.length() != 0 && name.length() != 0) { - Map prefixMap = (Map) aspectMaps.get(aspectName); - if (prefixMap == null) { - prefixMap = new HashMap(); - aspectMaps.put(aspectName, prefixMap); - } - prefixMap.put(name, attributes.get(attributeName)); - } - } + currentCollection.putAttribute(attributeName, + attributes.getAttribute(attributeName)); } } /** - * Get an iterator on the aspects which have been given values on this - * element + * Get an iterator on the namespaces which have been given values on this + * collection * - * @return an iterator of Strings , being the aspects which have been + * @return an iterator of Strings, being the namespaces which have been * given values on this element. */ public Iterator getNames() { - return aspectMaps.keySet().iterator(); + return namespaces.keySet().iterator(); } /** - * Get the set of attribute values related to the given aspect + * Get the set of attribute values related to the given namespace * - * @param aspectName the aspect name - * @return a map of the attribute values for the given aspect. + * @param namespaceURI the namespace URI + * @return an attribute collection */ - public Map getAttributes(String aspectName) { - return (Map) aspectMaps.get(aspectName); + public AttributeCollection getAttributes(String namespaceURI) { + return (AttributeCollection) namespaces.get(namespaceURI); } /** - * Get the value of a single aspect attribute + * Get the value of a single namespace attribute * - * @param aspectName the prefix which identifies the aspectr + * @param namespaceURI the namespace URI * @param keyName the attribute name - * @return the aspect value + * @return the namespace attribute value */ - public String getAttributeValue(String aspectName, String keyName) { - Map aspectAttributes = getAttributes(aspectName); - if (aspectAttributes == null) { + public String getAttributeValue(String namespaceURI, String keyName) { + AttributeCollection namespaceAttributes = getAttributes(namespaceURI); + if (namespaceAttributes == null) { return null; } - return (String) aspectAttributes.get(keyName); + return namespaceAttributes.getAttribute(keyName); } } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java index 556e34b1c..5c79c0a31 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ComponentService.java @@ -53,9 +53,9 @@ */ package org.apache.ant.common.service; import java.net.URL; -import java.util.Map; import org.apache.ant.common.antlib.AntLibFactory; import org.apache.ant.common.util.AntException; +import org.apache.ant.common.util.AttributeCollection; /** @@ -197,7 +197,7 @@ public interface ComponentService { * @exception AntException if the object does not support an * attribute in the map. */ - void configureAttributes(Object object, Map attributeValues, + void configureAttributes(Object object, AttributeCollection attributeValues, boolean ignoreUnsupported) throws AntException; } diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java index 83beb0ba0..13175b6e7 100644 --- a/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java +++ b/proposal/mutant/src/java/common/org/apache/ant/common/service/ExecService.java @@ -58,7 +58,7 @@ import java.util.Map; import org.apache.ant.common.antlib.Task; import org.apache.ant.common.model.Project; import org.apache.ant.common.util.AntException; -import org.apache.ant.common.model.AspectValueCollection; +import org.apache.ant.common.model.NamespaceValueCollection; import org.apache.ant.common.event.BuildListener; /** @@ -101,7 +101,7 @@ public interface ExecService { * @return a key to the build allowing it to be executed and managed * @exception AntException if the subbuild cannot be setup */ - BuildKey setupBuild(Project model, Map properties, boolean addListeners) + Object setupBuild(Project model, Map properties, boolean addListeners) throws AntException; @@ -114,7 +114,7 @@ public interface ExecService { * @return a key to the build allowing it to be executed and managed * @exception AntException if the subbuild cannot be setup */ - BuildKey setupBuild(Map properties, boolean addListeners) + Object setupBuild(Map properties, boolean addListeners) throws AntException; @@ -126,7 +126,7 @@ public interface ExecService { * @param libraryId the id of the library to be initialized. * @exception AntException if the build cannot be run */ - void initializeBuildLibrary(BuildKey key, String libraryId) + void initializeBuildLibrary(Object key, String libraryId) throws AntException; /** @@ -137,31 +137,21 @@ public interface ExecService { * * @exception AntException if the build cannot be found. */ - public void addBuildListener(BuildKey key, BuildListener listener) + void addBuildListener(Object key, BuildListener listener) throws AntException; /** * Run a build which have been previously setup * - * @param buildKey the buildKey returned previously when the build was + * @param key the key returned previously when the build was * setup * @param targets A list of targets to be run * @exception AntException if the build cannot be run */ - void runBuild(BuildKey buildKey, List targets) + void runBuild(Object key, List targets) throws AntException; - - /** - * Release a subbuild that is no longer in use. - * - * @param key the BuildKey identifiying the subbuild. - * - * @exception AntException if the build was not registered. - */ - void releaseBuild(BuildKey key) throws AntException; - /** * execute a task. The task should have already been initialised by the * core @@ -180,10 +170,10 @@ public interface ExecService { * by their nature, aspect values are not part of the task configuration. * * @param task the task to be executed - * @param aspectValues the aspect attribute values. + * @param namespaceValues the namespace attribute values. * @exception AntException if there is an execution problem */ - void executeTask(Task task, AspectValueCollection aspectValues) + void executeTask(Task task, NamespaceValueCollection namespaceValues) throws AntException; diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/util/AttributeCollection.java b/proposal/mutant/src/java/common/org/apache/ant/common/util/AttributeCollection.java new file mode 100644 index 000000000..a652d9fa2 --- /dev/null +++ b/proposal/mutant/src/java/common/org/apache/ant/common/util/AttributeCollection.java @@ -0,0 +1,99 @@ +/* + * 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 + * . + */ +package org.apache.ant.common.util; +import java.util.HashMap; +import java.util.Iterator; + +import java.util.Map; + +/** + * An Attribute collection is a simple collection of named values + * + * @author Conor MacNeill + * @created 14 June 2002 + */ +public class AttributeCollection { + /** The attribute values */ + private Map attributes = new HashMap(); + + /** + * Get the value of an attribute given its name + * + * @param attributeName the attribute name + * @return the attribute value or null if there is no such attribute. + */ + public String getAttribute(String attributeName) { + return (String) attributes.get(attributeName); + } + + /** + * Set the value of an attribute. + * + * @param attributeName the name of the attribute. + * @param attributeValue the value of the attribute. + */ + public void putAttribute(String attributeName, String attributeValue) { + attributes.put(attributeName, attributeValue); + } + + /** + * Get an iterator over the names of all the attributes in the collection. + * + * @return an iterator of attribute names. + */ + public Iterator getAttributeNames() { + return attributes.keySet().iterator(); + } +} + diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java index 55b25e5b6..77b5407d3 100755 --- a/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java +++ b/proposal/mutant/src/java/frontend/org/apache/ant/cli/Commandline.java @@ -75,7 +75,7 @@ import org.apache.ant.common.model.Project; import org.apache.ant.common.util.DemuxOutputStream; import org.apache.ant.common.logger.DefaultLogger; import org.apache.ant.common.logger.BuildLogger; -import org.apache.ant.init.InitConfig; +import org.apache.ant.init.AntEnvironment; import org.apache.ant.init.InitUtils; import org.apache.ant.frontend.FrontendUtils; import org.apache.ant.frontend.FrontendException; @@ -88,7 +88,7 @@ import org.apache.ant.frontend.FrontendException; */ public class Commandline { /** The initialisation configuration for Ant */ - private InitConfig initConfig; + private AntEnvironment antEnv; /** Stream that we are using for logging */ private PrintStream out = System.out; @@ -133,7 +133,7 @@ public class Commandline { * @param args the commandline arguments * @param config the initialisation configuration */ - public static void start(String[] args, InitConfig config) { + public static void start(String[] args, AntEnvironment config) { // create a command line and use it to run ant Commandline commandline = new Commandline(); commandline.process(args, config); @@ -203,10 +203,10 @@ public class Commandline { * Start the command line front end for mutant. * * @param args the commandline arguments - * @param initConfig Ant's initialization configuration + * @param antEnv Ant's initialization configuration */ - private void process(String[] args, InitConfig initConfig) { - this.initConfig = initConfig; + private void process(String[] args, AntEnvironment antEnv) { + this.antEnv = antEnv; Frame mainFrame = null; Project project = null; try { @@ -216,9 +216,9 @@ public class Commandline { AntConfig config = new AntConfig(); AntConfig userConfig = - FrontendUtils.getAntConfig(initConfig.getUserConfigArea()); + FrontendUtils.getAntConfig(antEnv.getUserConfigArea()); AntConfig systemConfig - = FrontendUtils.getAntConfig(initConfig.getSystemConfigArea()); + = FrontendUtils.getAntConfig(antEnv.getSystemConfigArea()); if (systemConfig != null) { config.merge(systemConfig); @@ -243,7 +243,7 @@ public class Commandline { project = parseProject(); // create the execution manager to execute the build - mainFrame = new Frame(initConfig, config); + mainFrame = new Frame(antEnv, config); OutputStream demuxOut = new DemuxOutputStream(mainFrame, false); OutputStream demuxErr diff --git a/proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java b/proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java old mode 100755 new mode 100644 similarity index 90% rename from proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java rename to proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java index bfe8dd57d..5479035e2 --- a/proposal/mutant/src/java/init/org/apache/ant/init/InitConfig.java +++ b/proposal/mutant/src/java/init/org/apache/ant/init/AntEnvironment.java @@ -59,13 +59,13 @@ import java.net.URL; import java.net.URLClassLoader; /** - * InitConfig is the initialization configuration created to start Ant. This - * is passed to the front end when Ant is started. + * AntEnvironment describes the environment in which Ant is operating. + * It provides the locations of a number of key Ant components. * * @author Conor MacNeill * @created 9 January 2002 */ -public class InitConfig { +public class AntEnvironment { /** The default name of the jar containing the XML parser */ public static final String DEFAULT_PARSER_JAR = "crimson.jar"; @@ -114,12 +114,19 @@ public class InitConfig { private File userConfigArea; /** - * Constructor for the Initialization configuration + * Create an unconfigured AntEnvironment which will be configured manually + * by the user + */ + public AntEnvironment() { + } + + /** + * Create and automatically configure the Ant Environment * * @param libraryClass - a class loaded from the Ant library area. * @exception InitException if the configuration cannot be initialized */ - public InitConfig(Class libraryClass) throws InitException { + public AntEnvironment(Class libraryClass) throws InitException { try { URL antLibURL = getAntLibURL(libraryClass); setLibraryURL(antLibURL); @@ -195,7 +202,7 @@ public class InitConfig { } /** - * Sets the systemLoader of the InitConfig + * Sets the systemLoader of the AntEnvironment * * @param systemLoader the new systemLoader value */ @@ -204,7 +211,7 @@ public class InitConfig { } /** - * Sets the commonLoader of the InitConfig + * Sets the commonLoader of the AntEnvironment * * @param commonLoader the new commonLoader value */ @@ -213,7 +220,7 @@ public class InitConfig { } /** - * Sets the coreLoader of the InitConfig + * Sets the coreLoader of the AntEnvironment * * @param coreLoader the new coreLoader value */ @@ -222,7 +229,7 @@ public class InitConfig { } /** - * Sets the toolsJarURL of the InitConfig + * Sets the toolsJarURL of the AntEnvironment * * @param toolsJarURL the new toolsJarURL value */ @@ -231,7 +238,7 @@ public class InitConfig { } /** - * Sets the parserURLs of the InitConfig + * Sets the parserURLs of the AntEnvironment * * @param parserURLs the new parserURLs value */ @@ -240,7 +247,7 @@ public class InitConfig { } /** - * Sets the libraryURL of the InitConfig + * Sets the libraryURL of the AntEnvironment * * @param libraryURL the new libraryURL value */ @@ -276,7 +283,7 @@ public class InitConfig { } /** - * Gets the systemLoader of the InitConfig + * Gets the systemLoader of the AntEnvironment * * @return the systemLoader value */ @@ -285,7 +292,7 @@ public class InitConfig { } /** - * Gets the commonLoader of the InitConfig + * Gets the commonLoader of the AntEnvironment * * @return the commonLoader value */ @@ -294,7 +301,7 @@ public class InitConfig { } /** - * Gets the coreLoader of the InitConfig + * Gets the coreLoader of the AntEnvironment * * @return the coreLoader value */ @@ -303,7 +310,7 @@ public class InitConfig { } /** - * Gets the toolsJarURL of the InitConfig + * Gets the toolsJarURL of the AntEnvironment * * @return the toolsJarURL value */ @@ -312,7 +319,7 @@ public class InitConfig { } /** - * Gets the parserURLs of the InitConfig + * Gets the parserURLs of the AntEnvironment * * @return the parserURLs value */ @@ -321,7 +328,7 @@ public class InitConfig { } /** - * Gets the libraryURL of the InitConfig + * Gets the libraryURL of the AntEnvironment * * @return the libraryURL value */ @@ -334,7 +341,7 @@ public class InitConfig { * * @param libraryClass - a class loaded from the Ant library area. * @return the URL for the Ant library directory - * @throws MalformedURLException if there is a problem constructing the + * @throws MalformedURLException if there is a problem constructing the * library URL */ private URL getAntLibURL(Class libraryClass) throws MalformedURLException { diff --git a/proposal/mutant/src/java/start/org/apache/ant/start/Main.java b/proposal/mutant/src/java/start/org/apache/ant/start/Main.java index 7b5eef3f6..e264f8a50 100755 --- a/proposal/mutant/src/java/start/org/apache/ant/start/Main.java +++ b/proposal/mutant/src/java/start/org/apache/ant/start/Main.java @@ -60,7 +60,7 @@ import java.net.URLClassLoader; import java.util.jar.Attributes; import java.util.jar.JarInputStream; import java.util.jar.Manifest; -import org.apache.ant.init.InitConfig; +import org.apache.ant.init.AntEnvironment; import org.apache.ant.init.InitException; import java.io.File; @@ -128,21 +128,21 @@ public class Main { * * @param frontend the frontend jar to launch * @param args commandline arguments - * @param defaultClass the default class to use if it cannot be determined + * @param defaultClass the default class to use if it cannot be determined * from the jar itself * @exception InitException if the front end cannot be started */ public void start(String frontend, String defaultClass, String[] args) throws InitException { - try { - InitConfig config = new InitConfig(getClass()); - + try { + AntEnvironment config = new AntEnvironment(getClass()); + URL frontendJar = new URL(config.getLibraryURL(), "frontend/" + frontend + ".jar"); URL[] frontendJars = new URL[]{frontendJar}; ClassLoader frontEndLoader = new URLClassLoader(frontendJars, config.getCoreLoader()); - + //System.out.println("Front End Loader config"); //LoaderUtils.dumpLoader(System.out, frontEndLoader); @@ -154,26 +154,26 @@ public class Main { } } String mainClass = getMainClass(frontendJar); - + if (mainClass == null) { mainClass = defaultClass; } - + if (mainClass == null) { throw new InitException("Unable to determine main class " + " for \"" + frontend + "\" frontend"); } - + // Now start the front end by reflection. Class frontendClass = Class.forName(mainClass, true, frontEndLoader); - + final Class[] param = {Class.forName("[Ljava.lang.String;"), - InitConfig.class}; + AntEnvironment.class}; final Method startMethod = frontendClass.getMethod("start", param); final Object[] argument = {args, config}; - + startMethod.invoke(null, argument); } catch (Exception e) { throw new InitException(e);