On Thursday 06 November 2003 10:02, Stefan Bodewig wrote: > On Wed, 5 Nov 2003, peter reilly <[EMAIL PROTECTED]> wrote: > > On Wednesday 05 November 2003 16:26, Dominique Devienne wrote: > >> > From: Stefan Bodewig [mailto:[EMAIL PROTECTED] > >> > > >> > On Wed, 5 Nov 2003, Matt Benson <[EMAIL PROTECTED]> wrote: > >> > > In beta1, the following worked: > >> > > > >> > > <myns:mytask> > >> > > <myns:mytype /> > >> > > </myns:mytask> > >> > > > >> > > In beta2, I get an error to the effect that "mytask" > >> > > does not support nested "mytype". > > > > There was a bug in beta1 with regard to namespace > > handling of nested elements (the prefix was > > incorrectly ignored). > > > > This has been fixed in beta2. > > See Matt, I told you it wasn't decided yet. Obviously Peter and I > disagree on what the "correct" behavior would be 8-)
The bug that was fixed was the prefix being ignored (html:mytype would also work). The bug meant that add(type) did not work for namespaced types. I noticed it while testing Dale's new conditions- <antcontrib:if> <antcontrib:ispropertytrue property="a"/> <then> <echo>a is true</echo> </then> </antcontrib:if> > > > The current behaviour is that introspection discovered > > nested elements belong to the ant default namespace. > > Why do you think it should do so? Well, I originally thought that the namespace could be used to distinguish between types and tasks defined by third parties. There is no need to use namespace to distinguish the nested elements (except for typedef'ed elements), so they would be in the ant default namespace. However, I understand the problem of writing schemas, using xml editors and also the fact that it is a little strange ... So now I think that the nested elements should have the namespace of the enclosing element (except for typedef'ed elements) I have a patch ready to do this (enclosed) (without unit tests) and am ready to commit. Note that this applies also to types/tasks created by <presetdef/>. <antgoodies:javac> <antgoodies:exclude name="**/Ignore*.java"/> </antgoodies:javac> Also note that this will affect all current users of namespaced antlib's. So when a new beta is released, this needs to be included in the release notes. > > >> And what about an Ant task (say <dummy>) with a AddXyz(Xyz xyz) > >> method, and I have an <my:xyz> in my AntLib that extends Xyz? > >> Should I be able to say: > >> > >> <dummy> > >> <my:xyz ... /> > >> </dummy> > > > > No, the ant task needs to have a add(Xyz xyz) method for this to > > work ... > > Peter is correct (of course, I should add). > > > well there is an undocumented attribute ant-type > > we really should document it. Yes... Note that when this feature was first disussed it was pointed out that ant-type does not work for Type create<NestedElement>() methods - like <src/> in javac. It was assumed that one could add new methods - add<NestedElement>(Type..) to get around this problem, and make add<NestedElement> have a lower priorirty than create<NestedElement>(). This however does have the nasty effect of causing problems for new classes that extend for example javac and override the createSrc() method. The introspection will still pick up the addSrc() method. 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.67 diff -u -r1.67 IntrospectionHelper.java --- src/main/org/apache/tools/ant/IntrospectionHelper.java 6 Nov 2003 09:04:08 -0000 1.67 +++ src/main/org/apache/tools/ant/IntrospectionHelper.java 6 Nov 2003 11:51:54 -0000 @@ -642,6 +642,52 @@ return nc; } + private NestedCreator getNestedCreator( + Project project, String parentUri, Object parent, + String elementName) throws BuildException { + + String uri = ProjectHelper.extractUriFromComponentName(elementName); + String name = ProjectHelper.extractNameFromComponentName(elementName); + + NestedCreator nc = null; + if (uri.equals(parentUri)) { // || uri.equals("")) { + nc = (NestedCreator) nestedCreators.get( + name.toLowerCase(Locale.US)); + } + if (nc == null) { + nc = createAddTypeCreator(project, parent, elementName); + } + if (nc == null && parent instanceof DynamicConfigurator) { + DynamicConfigurator dc = (DynamicConfigurator) parent; + final Object nestedElement = dc.createDynamicElement(elementName); + 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) { + throwNotSupported(project, parent, elementName); + } + return nc; + } + /** * Creates a named nested element. Depending on the results of the * initial introspection, either a method in the given parent instance @@ -692,6 +738,7 @@ * for an element of a parent. * * @param project Project to which the parent object belongs. + * @param parentUri The namespace uri of the parent object. * @param parent Parent object used to create the creator object to * create and store and instance of a subelement. * @param elementName Name of the element to create an instance of. @@ -699,8 +746,9 @@ */ public Creator getElementCreator( - Project project, Object parent, String elementName) { - NestedCreator nc = getNestedCreator(project, parent, elementName); + Project project, String parentUri, Object parent, String elementName) { + NestedCreator nc = getNestedCreator( + project, parentUri, parent, elementName); return new Creator(project, parent, nc); } @@ -714,6 +762,26 @@ */ public boolean supportsNestedElement(String elementName) { return nestedCreators.containsKey(elementName.toLowerCase(Locale.US)) + || DynamicConfigurator.class.isAssignableFrom(bean) + || addTypeMethods.size() != 0; + } + + /** + * Indicate if this element supports a nested element of the + * given name. + * + * @param parentUri the uri of the parent + * @param elementName the name of the nested element being checked + * + * @return true if the given nested element is supported + */ + public boolean supportsNestedElement(String parentUri, String elementName) { + String uri = ProjectHelper.extractUriFromComponentName(elementName); + String name = ProjectHelper.extractNameFromComponentName(elementName); + + return ( + nestedCreators.containsKey(name.toLowerCase(Locale.US)) + && (uri.equals(parentUri))) // || uri.equals(""))) || DynamicConfigurator.class.isAssignableFrom(bean) || addTypeMethods.size() != 0; } Index: src/main/org/apache/tools/ant/ProjectHelper.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/ProjectHelper.java,v retrieving revision 1.102 diff -u -r1.102 ProjectHelper.java --- src/main/org/apache/tools/ant/ProjectHelper.java 29 Oct 2003 10:18:14 -0000 1.102 +++ src/main/org/apache/tools/ant/ProjectHelper.java 6 Nov 2003 11:51:54 -0000 @@ -531,5 +531,19 @@ } return componentName.substring(0, index); } + + /** + * extract the element name from a component name + * + * @param componentName The stringified form for {uri, name} + * @return The element name of the component + */ + public static String extractNameFromComponentName(String componentName) { + int index = componentName.lastIndexOf(':'); + if (index == -1) { + return componentName; + } + return componentName.substring(index+1); + } //end class } 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.68 diff -u -r1.68 UnknownElement.java --- src/main/org/apache/tools/ant/UnknownElement.java 6 Nov 2003 09:04:08 -0000 1.68 +++ src/main/org/apache/tools/ant/UnknownElement.java 6 Nov 2003 11:51:54 -0000 @@ -336,13 +336,15 @@ * * @exception BuildException if the children cannot be configured. */ - protected void handleChildren(Object parent, - RuntimeConfigurable parentWrapper) + protected void handleChildren( + Object parent, + RuntimeConfigurable parentWrapper) throws BuildException { if (parent instanceof TypeAdapter) { parent = ((TypeAdapter) parent).getProxy(); } + String parentUri = getNamespace(); Class parentClass = parent.getClass(); IntrospectionHelper ih = IntrospectionHelper.getHelper(parentClass); @@ -352,8 +354,8 @@ for (int i = 0; it.hasNext(); i++) { RuntimeConfigurable childWrapper = parentWrapper.getChild(i); UnknownElement child = (UnknownElement) it.next(); - if (!handleChild(ih, parent, child, - childWrapper)) { + if (!handleChild( + parentUri, ih, parent, child, childWrapper)) { if (!(parent instanceof TaskContainer)) { ih.throwNotSupported(getProject(), parent, child.getTag()); @@ -548,14 +550,16 @@ * * @return whether the creation has been successful */ - private boolean handleChild(IntrospectionHelper ih, - Object parent, UnknownElement child, - RuntimeConfigurable childWrapper) { + private boolean handleChild( + String parentUri, + IntrospectionHelper ih, + Object parent, UnknownElement child, + RuntimeConfigurable childWrapper) { String childName = ProjectHelper.genComponentName( child.getNamespace(), child.getTag()); - if (ih.supportsNestedElement(childName)) { + if (ih.supportsNestedElement(parentUri, childName)) { IntrospectionHelper.Creator creator = - ih.getElementCreator(getProject(), parent, childName); + ih.getElementCreator(getProject(), parentUri, parent, childName); creator.setPolyType(childWrapper.getPolyType()); Object realChild = creator.create(); if (realChild instanceof PreSetDef.PreSetDefinition) {
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]