Hi Peter,
How serious is the problem ?
Will we be able to fix the problem in a minor release without
breaking the
backward compatibility ?
Cheers,
Antoine
----- Original Message -----
From: "Peter Reilly" <[EMAIL PROTECTED]>
To: "Ant Developers List" <[EMAIL PROTECTED]>
Sent: Tuesday, December 16, 2003 9:04 PM
Subject: Re: DynamicConfigurator namespace problem
Stefan Bodewig wrote:
On Fri, 12 Dec 2003, Christopher Lenz <[EMAIL PROTECTED]> wrote:
public class DynamicConfiguratorNS {
looks fine to me.
I don't think this interface should extend DynamicConfigurator.
Same here.
I'd also like Ant to pass element and attribute names in as they are,
i.e. without changing their case in any way.
I have code for this, however I am uneasy about placing it
it ANT for 1.6, without a new beta release.
The interface is:
public interface DynamicConfiguratorNS {
void setDynamicAttribute(String uri, String qualifiedName,
String value)
throws BuildException;
Object createDynamicElement(
String uri, String localName) throws BuildException;
}
The prefix is not set. - It is possible to get it for the element
but not (without more major changes) for the attributes.
One issue with the patch is that if the namespace of
the attribute is the same as the element, the namespace URI
is replaced with a "".
For an example:
public class DTest2 extends Task implements DynamicConfiguratorNS {
public Object createDynamicElement(
String uri,
String localName) {
System.out.println("Element {" + uri +", " + localName + "}");
return new DTest2();
}
public void setDynamicAttribute(
String uri,
String localName,
String value) {
System.out.println("Attribute {" + uri +", " + localName +
"}");
}
}
<dtest x="b" ant:b="b" xmlns:ant="antlib:org.apache.tools.ant"/>
will print:
Attribute {, x}
Attribute {antlib:org.apache.tools.ant, b}
and
<dtest x="b" ant:b="b" xmlns:ant="antlib:org.apache.tools.ant"
xmlns="antlib:org.apache.tools.ant"/>
will print
Attribute {, x}
Attribute {, b}
Another Namespace issue is the handling of the ant core uri by the
code. Currently the code sets this to "" at an early stage.
It however should be retained in the system (ie. whether
the namespace URI of an element is "" or
"antlib:org.apache.tools.ant").
For ant 1.6 (and beyond) we can make macrodef namespace independent,
without
this patch.
So for example:
<macrodef name="example">
<element name="element"/>
<sequential>
<element/>
</sequential>
</macrodef>
In a antlib referred to by a namespace prefix x, the following
would work:
<x:example>
<x:element>
<echo>Hello world</echo>
</x:element>
</x:example>
And the following would work:
<x:example>
<element>
<echo>Hello world</echo>
</element>
</x:example>
Peter
----------------------------------------------------------------------------
----
Index: src/main/org/apache/tools/ant/IntrospectionHelper.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v
retrieving revision 1.69
diff -u -r1.69 IntrospectionHelper.java
--- src/main/org/apache/tools/ant/IntrospectionHelper.java 11 Dec 2003
17:21:05 -0000 1.69
+++ src/main/org/apache/tools/ant/IntrospectionHelper.java 16 Dec 2003
19:27:25 -0000
@@ -517,13 +517,24 @@
public void setAttribute(Project p, Object element, String
attributeName,
String value) throws BuildException {
AttributeSetter as
- = (AttributeSetter) attributeSetters.get(attributeName);
+ = (AttributeSetter) attributeSetters.get(
+ attributeName.toLowerCase(Locale.US));
if (as == null) {
- if (element instanceof DynamicConfigurator) {
+ if (element instanceof DynamicConfiguratorNS) {
+ DynamicConfiguratorNS dc = (DynamicConfiguratorNS)
element;
+ dc.setDynamicAttribute(
+
ProjectHelper.extractUriFromComponentName(attributeName),
+
ProjectHelper.extractNameFromComponentName(attributeName),
+ value);
+ return;
+ } else if (element instanceof DynamicConfigurator) {
DynamicConfigurator dc = (DynamicConfigurator) element;
- dc.setDynamicAttribute(attributeName, value);
+
dc.setDynamicAttribute(attributeName.toLowerCase(Locale.US), value);
return;
} else {
+ if (attributeName.indexOf(':') != -1) {
+ return; // Ignore attribute from unknown uri's
+ }
String msg = getElementName(p, element)
+ " doesn't support the \"" + attributeName
+ "\" attribute.";
@@ -543,6 +554,7 @@
throw new BuildException(t);
}
}
+
/**
* Adds PCDATA to an element, using the element's
@@ -611,6 +623,9 @@
if (nc == null) {
nc = createAddTypeCreator(project, parent, elementName);
}
+ if (nc == null && parent instanceof DynamicConfiguratorNS) {
+ throw new BuildException("SHOULD NOT BE HERE");
+ }
if (nc == null && parent instanceof DynamicConfigurator) {
DynamicConfigurator dc = (DynamicConfigurator) parent;
final Object nestedElement =
dc.createDynamicElement(elementName);
@@ -644,7 +659,7 @@
private NestedCreator getNestedCreator(
Project project, String parentUri, Object parent,
- String elementName) throws BuildException {
+ String elementName, UnknownElement child) throws
BuildException {
String uri =
ProjectHelper.extractUriFromComponentName(elementName);
String name =
ProjectHelper.extractNameFromComponentName(elementName);
@@ -657,6 +672,33 @@
if (nc == null) {
nc = createAddTypeCreator(project, parent, elementName);
}
+ if (nc == null && parent instanceof DynamicConfiguratorNS) {
+ DynamicConfiguratorNS dc = (DynamicConfiguratorNS) parent;
+ final Object nestedElement =
+ dc.createDynamicElement(
+ child.getNamespace(), child.getTag());
+ if (nestedElement != null) {
+ nc = new NestedCreator() {
+ public boolean isPolyMorphic() {
+ return false;
+ }
+ public Class getElementClass() {
+ return null;
+ }
+
+ public Object getRealObject() {
+ return null;
+ }
+
+ public Object create(
+ Project project, Object parent, Object
ignore) {
+ return nestedElement;
+ }
+ public void store(Object parent, Object child) {
+ }
+ };
+ }
+ }
if (nc == null && parent instanceof DynamicConfigurator) {
DynamicConfigurator dc = (DynamicConfigurator) parent;
final Object nestedElement =
@@ -747,9 +789,10 @@
*/
public Creator getElementCreator(
- Project project, String parentUri, Object parent, String
elementName) {
+ Project project, String parentUri, Object parent, String
elementName,
+ UnknownElement child) {
NestedCreator nc = getNestedCreator(
- project, parentUri, parent, elementName);
+ project, parentUri, parent, elementName, child);
return new Creator(project, parent, nc);
}
@@ -764,6 +807,7 @@
public boolean supportsNestedElement(String elementName) {
return
nestedCreators.containsKey(elementName.toLowerCase(Locale.US))
|| DynamicConfigurator.class.isAssignableFrom(bean)
+ || DynamicConfiguratorNS.class.isAssignableFrom(bean)
|| addTypeMethods.size() != 0;
}
@@ -784,6 +828,7 @@
nestedCreators.containsKey(name.toLowerCase(Locale.US))
&& (uri.equals(parentUri))) // || uri.equals("")))
|| DynamicConfigurator.class.isAssignableFrom(bean)
+ || DynamicConfiguratorNS.class.isAssignableFrom(bean)
|| addTypeMethods.size() != 0;
}
Index: src/main/org/apache/tools/ant/RuntimeConfigurable.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java,v
retrieving revision 1.46
diff -u -r1.46 RuntimeConfigurable.java
--- src/main/org/apache/tools/ant/RuntimeConfigurable.java 6 Nov 2003
09:04:08 -0000 1.46
+++ src/main/org/apache/tools/ant/RuntimeConfigurable.java 16 Dec 2003
19:27:25 -0000
@@ -206,7 +206,8 @@
* @param value the attribute's value.
*/
public void setAttribute(String name, String value) {
- if (name.equalsIgnoreCase(ANT_TYPE)) {
+ if (name.equalsIgnoreCase(ANT_TYPE) || name.equalsIgnoreCase(
+ ProjectHelper.ANT_CORE_URI + ":" + ANT_TYPE)) {
this.polyType = value;
} else {
if (attributeNames == null) {
@@ -391,7 +392,6 @@
Object target = (wrappedObject instanceof TypeAdapter)
? ((TypeAdapter) wrappedObject).getProxy() : wrappedObject;
- //PropertyHelper ph=PropertyHelper.getPropertyHelper(p);
IntrospectionHelper ih =
IntrospectionHelper.getHelper(p, target.getClass());
@@ -403,8 +403,7 @@
// reflect these into the target
value = p.replaceProperties(value);
try {
- ih.setAttribute(p, target,
- name.toLowerCase(Locale.US),
value);
+ ih.setAttribute(p, target, name, value);
} catch (BuildException be) {
// id attribute must be set externally
if (!name.equals("id")) {
Index: src/main/org/apache/tools/ant/UnknownElement.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/UnknownElement.java,v
retrieving revision 1.70
diff -u -r1.70 UnknownElement.java
--- src/main/org/apache/tools/ant/UnknownElement.java 24 Nov 2003
09:15:41 -0000 1.70
+++ src/main/org/apache/tools/ant/UnknownElement.java 16 Dec 2003
19:27:25 -0000
@@ -564,7 +564,8 @@
child.getNamespace(), child.getTag());
if (ih.supportsNestedElement(parentUri, childName)) {
IntrospectionHelper.Creator creator =
- ih.getElementCreator(getProject(), parentUri, parent,
childName);
+ ih.getElementCreator(
+ getProject(), parentUri, parent, childName,
child);
creator.setPolyType(childWrapper.getPolyType());
Object realChild = creator.create();
if (realChild instanceof PreSetDef.PreSetDefinition) {
Index: src/main/org/apache/tools/ant/helper/ProjectHelper2.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/helper/ProjectHelper2.java,v
retrieving revision 1.37
diff -u -r1.37 ProjectHelper2.java
--- src/main/org/apache/tools/ant/helper/ProjectHelper2.java 18 Nov
2003
17:06:58 -0000 1.37
+++ src/main/org/apache/tools/ant/helper/ProjectHelper2.java 16 Dec
2003
19:27:25 -0000
@@ -484,9 +484,6 @@
*/
public void startElement(String uri, String tag, String qname,
Attributes attrs)
throws SAXParseException {
- if (uri.equals(ANT_CORE_URI)) {
- uri = "";
- }
AntHandler next
= currentHandler.onStartChild(uri, tag, qname, attrs,
context);
antHandlers.push(currentHandler);
@@ -519,9 +516,6 @@
*
*/
public void endElement(String uri, String name, String qName)
throws SAXException {
- if (uri.equals(ANT_CORE_URI)) {
- uri = "";
- }
currentHandler.onEndElement(uri, name, context);
AntHandler prev = (AntHandler) antHandlers.pop();
currentHandler = prev;
@@ -585,7 +579,8 @@
Attributes attrs,
AntXMLContext context)
throws SAXParseException {
- if (name.equals("project") && uri.equals("")) {
+ if (name.equals("project")
+ && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
return ProjectHelper2.projectHandler;
} else {
// if (context.importlevel > 0) {
@@ -756,7 +751,8 @@
Attributes attrs,
AntXMLContext context)
throws SAXParseException {
- if (name.equals("target") && uri.equals("")) {
+ if (name.equals("target")
+ && (uri.equals("") || uri.equals(ANT_CORE_URI))) {
return ProjectHelper2.targetHandler;
} else {
return ProjectHelper2.elementHandler;
@@ -979,19 +975,20 @@
= new RuntimeConfigurable(task, task.getTaskName());
for (int i = 0; i < attrs.getLength(); i++) {
+ String name = attrs.getLocalName(i);
String attrUri = attrs.getURI(i);
if (attrUri != null
&& !attrUri.equals("")
&& !attrUri.equals(uri)) {
- continue; // Ignore attributes from unknown uris
+ name = attrUri + ":" + name;
}
- String name = attrs.getLocalName(i);
String value = attrs.getValue(i);
// PR: Hack for ant-type value
// an ant-type is a component name which can
// be namespaced, need to extract the name
// and convert from qualified name to uri/name
- if (name.equals("ant-type")) {
+ if (name.equals("ant-type")
+ || name.equals(ANT_CORE_URI + ":ant-type")) {
int index = value.indexOf(":");
if (index != -1) {
String prefix = value.substring(0, index);