diff --git a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java index 761fc1b88..f9db97230 100755 --- a/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java +++ b/proposal/mutant/src/java/antcore/org/apache/ant/antcore/antlib/AntLibHandler.java @@ -129,8 +129,8 @@ public class AntLibHandler extends ElementHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a parsing problem. */ - public void startElement(String uri, String localName, String qualifiedName, - Attributes attributes) + protected void addNestedElement(String uri, String localName, + String qualifiedName, Attributes attributes) throws SAXParseException { try { if (qualifiedName.equals("taskdef") 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 3f82a3818..6b3bb9859 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 @@ -126,8 +126,8 @@ public class AntConfigHandler extends ElementHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a parsing problem. */ - public void startElement(String uri, String localName, String qualifiedName, - Attributes attributes) + protected void addNestedElement(String uri, String localName, + String qualifiedName, Attributes attributes) throws SAXParseException { // configs support two task collections as elements 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 14f656337..ba4c36f0d 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 @@ -396,6 +396,45 @@ public class ComponentManager implements ComponentService { return libFactory; } + /** + * Set an attribute on an object. + * + * This method is useful for manipulating components without assuming + * anything about the component's type. The context classloader should be + * set to the component's loaded when calling this method. + * + * @param component the component on which to set the attribute + * @param attributeName the attribute name + * @param attributeValue the required value + * + * @exception AntException if the attribute cannot be set. + */ + public void setAttribute(Object component, String attributeName, + String attributeValue) throws AntException { + + Setter setter = getSetter(component.getClass()); + setter.setAttribute(component, attributeName, + frame.replacePropertyRefs(attributeValue)); + } + + /** + * Add a nested element to a component. + * + * This method is useful for manipulating components without assuming + * anything about the component's type. The context classloader should be + * set to the component's loaded when calling this method. + * + * @param component the component to which the nested element will be added. + * @param nestedElementName the name of the nested element. + * @param nestedElement the actual object to be added. + * + * @exception AntException if the nested element cannot be added. + */ + public void addNestedElement(Object component, String nestedElementName, + Object nestedElement) throws AntException { + Setter setter = getSetter(component.getClass()); + setter.addElement(component, nestedElementName, nestedElement); + } /** * Get an imported definition from the component manager * @@ -416,7 +455,7 @@ public class ComponentManager implements ComponentService { * @exception AntException if there is a problem creating or * configuring the component */ - protected Object createComponent(BuildElement model) + public Object createComponent(BuildElement model) throws AntException { String componentName = model.getType(); return createComponent(componentName, model); @@ -474,7 +513,6 @@ public class ComponentManager implements ComponentService { boolean isTask = libDefinition.getDefinitionType() == AntLibrary.TASKDEF; - Object component = null; if (model != null) { location = model.getLocation(); @@ -678,15 +716,15 @@ public class ComponentManager implements ComponentService { * the attribute is to be added. * @exception AntException if the nested element cannot be created */ - private void addNestedElement(AntLibFactory factory, Setter setter, - Object element, BuildElement model) + private void addNested(AntLibFactory factory, Setter setter, + Object element, BuildElement model) throws AntException { String nestedElementName = model.getType(); Class nestedType = setter.getType(nestedElementName); // is there a polymorph indicator - look in Ant aspects String typeName - = model.getNamespaceAttributeValue(Namespace.ANT_META_URI, "type"); + = model.getNamespaceAttributeValue(Namespace.XSI_URI, "type"); Object typeInstance = null; if (typeName != null) { @@ -706,9 +744,8 @@ public class ComponentManager implements ComponentService { } else { throw new ExecutionException("The type of the <" + nestedElementName + "> nested element is not known. " - + "Please specify by the type using the \"ant:type\" " - + "attribute or provide a reference to an instance with " - + "the \"ant:id\" attribute"); + + "Please specify by the type using the \"xsi:type\" " + + "attribute or provide a reference to another instance"); } // is the typeInstance compatible with the type expected @@ -732,8 +769,8 @@ public class ComponentManager implements ComponentService { * the nested element * @exception AntException if the nested element cannot be created. */ - private void createNestedElement(AntLibFactory factory, Setter setter, - Object element, BuildElement model) + private void createNested(AntLibFactory factory, Setter setter, + Object element, BuildElement model) throws AntException { String nestedElementName = model.getType(); try { @@ -819,11 +856,9 @@ public class ComponentManager implements ComponentService { container.addNestedTask(nestedTask); } else { if (setter.supportsNestedAdder(nestedElementName)) { - addNestedElement(factory, setter, element, - nestedElementModel); + addNested(factory, setter, element, nestedElementModel); } else if (setter.supportsNestedCreator(nestedElementName)) { - createNestedElement(factory, setter, element, - nestedElementModel); + createNested(factory, setter, element, nestedElementModel); } else { throw new ExecutionException("<" + model.getType() + ">" + " does not support the \"" + nestedElementName 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 084a12a71..4d0d31d10 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 @@ -145,8 +145,6 @@ public class CoreExecService implements ExecService { frame.executeTask(task, aspectValues); } - - /** * Get the base directory for this execution of this frame * 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 04f35d6a2..858beb900 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 @@ -107,8 +107,8 @@ public class BuildElementHandler extends ModelElementHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a parsing problem. */ - public void startElement(String uri, String localName, String qualifiedName, - Attributes attributes) + protected void addNestedElement(String uri, String localName, + String qualifiedName, Attributes attributes) throws SAXParseException { // everything within a task element is also a task element 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 62ddf573f..5a8f59d1d 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 @@ -154,8 +154,8 @@ public class ProjectHandler extends ModelElementHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a parsing problem. */ - public void startElement(String uri, String localName, String qualifiedName, - Attributes attributes) + protected void addNestedElement(String uri, String localName, + String qualifiedName, Attributes attributes) throws SAXParseException { if (qualifiedName.equals(INCLUDE_ELEMENT)) { 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 f359fd537..1b4adc5ca 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 @@ -130,8 +130,8 @@ public class TargetHandler extends ModelElementHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a parsing problem. */ - public void startElement(String uri, String localName, String qualifiedName, - Attributes attributes) + protected void addNestedElement(String uri, String localName, + String qualifiedName, Attributes attributes) throws SAXParseException { // everything is a task BuildElementHandler taskHandler = new BuildElementHandler(); 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 e28b2167b..26da99ddf 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 @@ -58,6 +58,7 @@ import org.apache.ant.common.util.Location; import org.apache.ant.common.model.Project; import org.apache.ant.antcore.xml.ParseContext; import org.apache.ant.antcore.xml.XMLParseException; +import org.apache.ant.common.constants.Namespace; /** * Parses an Ant project model from an XML source using a SAX Parser. @@ -78,7 +79,11 @@ public class XMLProjectParser { throws XMLParseException { try { ParseContext context = new ParseContext(); - context.declareNamespace("ant", "http://jakarta.apache.org/ant"); + context.declareNamespace(Namespace.ANT_META_PREFIX, + Namespace.ANT_META_URI); + context.declareNamespace(Namespace.XSI_PREFIX, + Namespace.XSI_URI); + 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 21fb851e6..d2b26b5be 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 @@ -215,6 +215,22 @@ public abstract class ElementHandler extends DefaultHandler { } + /** + * Process an element. This resolves any namespaces against + * prefixes declared in the ParseContext. + * + * @param uri The Namespace URI. + * @param localName The local name (without prefix). + * @param qualifiedName The qualified name (with prefix) + * @param attributes The attributes attached to the element. + * @throws SAXParseException if there is a problem parsng the subelement + */ + final public void startElement(String uri, String localName, + String qualifiedName, Attributes attributes) + throws SAXParseException { + addNestedElement(uri, localName, qualifiedName, attributes); + } + /** * By default an element handler does not support nested elements. This * method will always throw an exception. Subclasses should override @@ -226,10 +242,10 @@ public abstract class ElementHandler extends DefaultHandler { * @param attributes The attributes attached to the element. * @throws SAXParseException if there is a problem parsng the subelement */ - public void startElement(String uri, String localName, String qualifiedName, - Attributes attributes) + protected void addNestedElement(String uri, String localName, + String qualifiedName, + Attributes attributes) throws SAXParseException { - // everything is a task throw new SAXParseException("<" + elementName + "> does not support a <" + qualifiedName + "> nested element", getLocator()); } @@ -320,7 +336,6 @@ public abstract class ElementHandler extends DefaultHandler { protected abstract void processElement(String elementName) throws SAXParseException; - /** * Process all of the attributes of the element into maps, one for * aspects and one for other attributes @@ -335,13 +350,14 @@ public abstract class ElementHandler extends DefaultHandler { elementAttributes = new AttributeCollection(); int length = attributes.getLength(); for (int i = 0; i < length; ++i) { + String localName = attributes.getLocalName(i); + String qName = 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) { if (qName.indexOf(":") != -1) { // try to resolve through known namespaces 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 2f5a36eff..40cc6dc15 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 @@ -95,6 +95,7 @@ public class ParseContext { ClassLoader thisLoader = this.getClass().getClassLoader(); thread.setContextClassLoader(thisLoader); parserFactory = SAXParserFactory.newInstance(); + parserFactory.setNamespaceAware(true); } finally { thread.setContextClassLoader(currentContextLoader); } @@ -131,7 +132,7 @@ public class ParseContext { // create a parser for this source SAXParser saxParser = null; - + Thread thread = Thread.currentThread(); ClassLoader currentContextLoader = thread.getContextClassLoader(); try { @@ -141,7 +142,7 @@ public class ParseContext { } finally { thread.setContextClassLoader(currentContextLoader); } - + XMLReader xmlReader = saxParser.getXMLReader(); // create a root handler for this diff --git a/proposal/mutant/src/java/common/org/apache/ant/common/Namespace.java b/proposal/mutant/src/java/common/org/apache/ant/common/constants/Namespace.java similarity index 100% rename from proposal/mutant/src/java/common/org/apache/ant/common/Namespace.java rename to proposal/mutant/src/java/common/org/apache/ant/common/constants/Namespace.java 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 5c79c0a31..ba134f83e 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 @@ -54,6 +54,7 @@ package org.apache.ant.common.service; import java.net.URL; import org.apache.ant.common.antlib.AntLibFactory; +import org.apache.ant.common.model.BuildElement; import org.apache.ant.common.util.AntException; import org.apache.ant.common.util.AttributeCollection; @@ -187,6 +188,49 @@ public interface ComponentService { Object createComponent(String libraryId, String localName) throws AntException; + /** + * Create a component from a build model. The returned object will be + * configured according to the model. + * + * @param model the build element to use to create and configure the + * component + * @return the created component. + * @exception AntException if the component cannot be created + */ + Object createComponent(BuildElement model) throws AntException; + + /** + * Set an attribute on an object. + * + * This method is useful for manipulating components without assuming + * anything about the component's type. The context classloader should be + * set to the component's loaded when calling this method. + * + * @param component the component on which to set the attribute + * @param attributeName the attribute name + * @param attributeValue the required value + * + * @exception AntException if the attribute cannot be set. + */ + void setAttribute(Object component, String attributeName, + String attributeValue) throws AntException; + + /** + * Add a nested element to a component. + * + * This method is useful for manipulating components without assuming + * anything about the component's type. The context classloader should be + * set to the component's loaded when calling this method. + * + * @param component the component to which the nested element will be added. + * @param nestedElementName the name of the nested element. + * @param nestedElement the actual object to be added. + * + * @exception AntException if the nested element cannot be added. + */ + void addNestedElement(Object component, String nestedElementName, + Object nestedElement) throws AntException; + /** * configure an object with attribtes from the given map * diff --git a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java b/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java index 29c485300..9cc94fa4d 100644 --- a/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java +++ b/proposal/mutant/src/java/frontend/org/apache/ant/frontend/FrontendUtils.java @@ -62,6 +62,7 @@ import org.apache.ant.antcore.config.AntConfigHandler; import org.apache.ant.antcore.xml.ParseContext; import org.apache.ant.antcore.xml.XMLParseException; import org.apache.ant.init.InitUtils; +import org.apache.ant.common.constants.Namespace; /** * Frontend Utilities methods and constants. @@ -113,6 +114,11 @@ public class FrontendUtils { URL configFileURL = InitUtils.getFileURL(configFile); ParseContext context = new ParseContext(); + context.declareNamespace(Namespace.ANT_META_PREFIX, + Namespace.ANT_META_URI); + context.declareNamespace(Namespace.XSI_PREFIX, + Namespace.XSI_URI); + AntConfigHandler configHandler = new AntConfigHandler(); context.parse(configFileURL, "antconfig", configHandler);