Return-Path: Delivered-To: apmail-ant-dev-archive@www.apache.org Received: (qmail 79001 invoked from network); 6 Nov 2003 11:55:07 -0000 Received: from daedalus.apache.org (HELO mail.apache.org) (208.185.179.12) by minotaur-2.apache.org with SMTP; 6 Nov 2003 11:55:07 -0000 Received: (qmail 92768 invoked by uid 500); 6 Nov 2003 11:55:05 -0000 Delivered-To: apmail-ant-dev-archive@ant.apache.org Received: (qmail 92592 invoked by uid 500); 6 Nov 2003 11:55:03 -0000 Mailing-List: contact dev-help@ant.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Ant Developers List" Reply-To: "Ant Developers List" Delivered-To: mailing list dev@ant.apache.org Received: (qmail 92576 invoked from network); 6 Nov 2003 11:55:02 -0000 Received: from unknown (HELO corvil.com) (213.94.219.177) by daedalus.apache.org with SMTP; 6 Nov 2003 11:55:02 -0000 Received: from preilly.local.corvil.com (preilly.local.corvil.com [172.18.1.173]) by corvil.com (8.12.9/8.12.5) with ESMTP id hA6Bsxd8071773 for ; Thu, 6 Nov 2003 11:55:00 GMT (envelope-from peter.reilly@corvil.com) From: peter reilly Organization: corvil To: Ant Developers List Subject: Re: antlibs/namespaces Date: Thu, 6 Nov 2003 11:54:47 +0000 User-Agent: KMail/1.5 References: <200311051710.19271.peter.reilly@corvil.com> In-Reply-To: MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_Hajq/Nc+x9Yq6LL" Message-Id: <200311061154.47339.peter.reilly@corvil.com> X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N --Boundary-00=_Hajq/Nc+x9Yq6LL Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Thursday 06 November 2003 10:02, Stefan Bodewig wrote: > On Wed, 5 Nov 2003, peter reilly wrote: > > On Wednesday 05 November 2003 16:26, Dominique Devienne wrote: > >> > From: Stefan Bodewig [mailto:bodewig@apache.org] > >> > > >> > On Wed, 5 Nov 2003, Matt Benson wrote: > >> > > In beta1, the following worked: > >> > > > >> > > > >> > > > >> > > > >> > > > >> > > 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- a is true > > > 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 . 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 ) with a AddXyz(Xyz xyz) > >> method, and I have an in my AntLib that extends Xyz? > >> Should I be able to say: > >> > >> > >> > >> > > > > 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() methods - like in javac. It was assumed that one could add new methods - add(Type..) to get around this problem, and make add have a lower priorirty than create(). 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 --Boundary-00=_Hajq/Nc+x9Yq6LL Content-Type: text/x-diff; charset="iso-8859-1"; name="ns.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ns.diff" 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) { --Boundary-00=_Hajq/Nc+x9Yq6LL Content-Type: text/plain; charset=us-ascii --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org For additional commands, e-mail: dev-help@ant.apache.org --Boundary-00=_Hajq/Nc+x9Yq6LL--