Return-Path: Delivered-To: apmail-ant-dev-archive@www.apache.org Received: (qmail 57748 invoked from network); 27 May 2004 14:39:29 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 27 May 2004 14:39:29 -0000 Received: (qmail 61768 invoked by uid 500); 27 May 2004 14:39:05 -0000 Delivered-To: apmail-ant-dev-archive@ant.apache.org Received: (qmail 61538 invoked by uid 500); 27 May 2004 14:39:02 -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 61287 invoked by uid 500); 27 May 2004 14:39:01 -0000 Received: (qmail 61180 invoked by uid 98); 27 May 2004 14:39:00 -0000 Received: from peterreilly@apache.org by hermes.apache.org by uid 82 with qmail-scanner-1.20 (clamuko: 0.70. Clear:RC:0(209.237.227.194):. Processed in 0.3801 secs); 27 May 2004 14:39:00 -0000 X-Qmail-Scanner-Mail-From: peterreilly@apache.org via hermes.apache.org X-Qmail-Scanner: 1.20 (Clear:RC:0(209.237.227.194):. Processed in 0.3801 secs) Received: from unknown (HELO minotaur.apache.org) (209.237.227.194) by hermes.apache.org with SMTP; 27 May 2004 14:38:58 -0000 Received: (qmail 57424 invoked by uid 1539); 27 May 2004 14:38:46 -0000 Date: 27 May 2004 14:38:46 -0000 Message-ID: <20040527143846.57423.qmail@minotaur.apache.org> From: peterreilly@apache.org To: ant-cvs@apache.org Subject: cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs MacroDefTest.java X-Spam-Rating: hermes.apache.org 1.6.2 0/1000/N X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N peterreilly 2004/05/27 07:38:46 Modified: docs/manual/CoreTasks macrodef.html src/etc/testcases/taskdefs macrodef.xml src/main/org/apache/tools/ant IntrospectionHelper.java UnknownElement.java src/main/org/apache/tools/ant/taskdefs MacroDef.java MacroInstance.java src/testcases/org/apache/tools/ant/taskdefs MacroDefTest.java Added: src/main/org/apache/tools/ant DynamicAttribute.java DynamicAttributeNS.java DynamicElement.java DynamicElementNS.java Log: add implicit element to macrodef PR: 25633 Revision Changes Path 1.21 +50 -0 ant/docs/manual/CoreTasks/macrodef.html Index: macrodef.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/macrodef.html,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- macrodef.html 26 May 2004 12:25:20 -0000 1.20 +++ macrodef.html 27 May 2004 14:38:45 -0000 1.21 @@ -132,6 +132,17 @@ No + implicit + + If true this nested element is implicit. This means that + any nested elements of the macrodef instance will be placed + in the element indicated by the name of this element. + There can only be one element if an element is implicit. + The default value is false. since ant 1.6.2 + + No + + description This contains a description @@ -253,6 +264,45 @@ <fileset dir="${gen.dir}" includes = "*.cpp"/> <linker refid="linker-libs"/> </cc-elements> +</call-cc> + + +

+ The following fragment shows <call-cc>, but this time + using an implicit element and with the link and target.dir arguments + having default values. +

+
+
  +<macrodef name="call-cc">
  +   <attribute name="target"/>
  +   <attribute name="link" default="executable"/>
  +   <attribute name="target.dir" default="${build.bin.dir}"/>
  +   <element name="cc-elements" implicit="yes"/>
  +   <sequential>
  +      <mkdir dir="${obj.dir}/@{target}"/>
  +      <mkdir dir="@{target.dir}"/>
  +         <cc link="@{link}" objdir="${obj.dir}/@{target}"
  +             outfile="@{target.dir}/@{target}">
  +            <compiler refid="compiler.options"/>
  +            <cc-elements/>
  +         </cc>
  +      </sequential>
  +</macrodef>
  +
+
+

+ This then can be used as follows, note that <cc-elements> + is not specified. +

+
+
  +<call-cc target="unittests"/>
  +   <includepath location="${gen.dir}"/>
  +   <includepath location="test"/>
  +   <fileset dir="test/unittest" includes = "**/*.cpp"/>
  +   <fileset dir="${gen.dir}" includes = "*.cpp"/>
  +   <linker refid="linker-libs"/>
   </call-cc>
   
1.12 +55 -0 ant/src/etc/testcases/taskdefs/macrodef.xml Index: macrodef.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/macrodef.xml,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- macrodef.xml 24 Feb 2004 09:30:30 -0000 1.11 +++ macrodef.xml 27 May 2004 14:38:46 -0000 1.12 @@ -168,4 +168,59 @@ + + + + + Before implicit + + After implicit + + + + + In implicit + + + + + + + + Before implicit + + After implicit + + + + + + + + + + + + Before implicit + + After implicit + + + + + + + + + + + + + + + + + + + 1.84 +12 -12 ant/src/main/org/apache/tools/ant/IntrospectionHelper.java Index: IntrospectionHelper.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v retrieving revision 1.83 retrieving revision 1.84 diff -u -r1.83 -r1.84 --- IntrospectionHelper.java 25 May 2004 08:25:00 -0000 1.83 +++ IntrospectionHelper.java 27 May 2004 14:38:46 -0000 1.84 @@ -489,8 +489,8 @@ = (AttributeSetter) attributeSetters.get( attributeName.toLowerCase(Locale.US)); if (as == null) { - if (element instanceof DynamicConfiguratorNS) { - DynamicConfiguratorNS dc = (DynamicConfiguratorNS) element; + if (element instanceof DynamicAttributeNS) { + DynamicAttributeNS dc = (DynamicAttributeNS) element; String uriPlusPrefix = ProjectHelper.extractUriFromComponentName(attributeName); String uri = @@ -502,8 +502,8 @@ dc.setDynamicAttribute(uri, localName, qName, value); return; - } else if (element instanceof DynamicConfigurator) { - DynamicConfigurator dc = (DynamicConfigurator) element; + } else if (element instanceof DynamicAttribute) { + DynamicAttribute dc = (DynamicAttribute) element; dc.setDynamicAttribute(attributeName.toLowerCase(Locale.US), value); return; } else { @@ -611,8 +611,8 @@ if (nc == null) { nc = createAddTypeCreator(project, parent, elementName); } - if (nc == null && parent instanceof DynamicConfiguratorNS) { - DynamicConfiguratorNS dc = (DynamicConfiguratorNS) parent; + if (nc == null && parent instanceof DynamicElementNS) { + DynamicElementNS dc = (DynamicElementNS) parent; String qName = (child == null ? name : child.getQName()); final Object nestedElement = dc.createDynamicElement( @@ -640,8 +640,8 @@ }; } } - if (nc == null && parent instanceof DynamicConfigurator) { - DynamicConfigurator dc = (DynamicConfigurator) parent; + if (nc == null && parent instanceof DynamicElement) { + DynamicElement dc = (DynamicElement) parent; final Object nestedElement = dc.createDynamicElement(name.toLowerCase(Locale.US)); if (nestedElement != null) { @@ -749,8 +749,8 @@ */ public boolean supportsNestedElement(String elementName) { return nestedCreators.containsKey(elementName.toLowerCase(Locale.US)) - || DynamicConfigurator.class.isAssignableFrom(bean) - || DynamicConfiguratorNS.class.isAssignableFrom(bean) + || DynamicElement.class.isAssignableFrom(bean) + || DynamicElementNS.class.isAssignableFrom(bean) || addTypeMethods.size() != 0; } @@ -776,8 +776,8 @@ return ( nestedCreators.containsKey(name.toLowerCase(Locale.US)) && (uri.equals(parentUri))) // || uri.equals(""))) - || DynamicConfigurator.class.isAssignableFrom(bean) - || DynamicConfiguratorNS.class.isAssignableFrom(bean) + || DynamicElement.class.isAssignableFrom(bean) + || DynamicElementNS.class.isAssignableFrom(bean) || addTypeMethods.size() != 0; } 1.80 +7 -0 ant/src/main/org/apache/tools/ant/UnknownElement.java Index: UnknownElement.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/UnknownElement.java,v retrieving revision 1.79 retrieving revision 1.80 diff -u -r1.79 -r1.80 --- UnknownElement.java 7 Apr 2004 12:11:17 -0000 1.79 +++ UnknownElement.java 27 May 2004 14:38:46 -0000 1.80 @@ -72,6 +72,13 @@ } /** + * @return the list of nested UnknownElements for this UnknownElement. + */ + public List getChildren() { + return children; + } + + /** * Returns the name of the XML element which generated this unknown * element. * 1.1 ant/src/main/org/apache/tools/ant/DynamicAttribute.java Index: DynamicAttribute.java =================================================================== /* * Copyright 2002-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant; /** * Enables a task to control unknown attributes * * @since Ant 1.5 */ public interface DynamicAttribute { /** * Set a named attribute to the given value * * @param name the name of the attribute * @param value the new value of the attribute * @throws BuildException when any error occurs */ void setDynamicAttribute(String name, String value) throws BuildException; } 1.1 ant/src/main/org/apache/tools/ant/DynamicAttributeNS.java Index: DynamicAttributeNS.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant; /** * Enables a task to control unknown attributes. * * @since Ant 1.7 */ public interface DynamicAttributeNS { /** * Set a named attribute to the given value * * @param uri The namespace uri for this attribute, "" is * used if there is no namespace uri. * @param localName The localname of this attribute. * @param qName The qualified name for this attribute * @param value The value of this attribute. * @throws BuildException when any error occurs */ void setDynamicAttribute( String uri, String localName, String qName, String value) throws BuildException; } 1.1 ant/src/main/org/apache/tools/ant/DynamicElement.java Index: DynamicElement.java =================================================================== /* * Copyright 2002-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant; /** * Enables a task to control unknown elements. * * @since Ant 1.5 */ public interface DynamicElement { /** * Create an element with the given name * * @param name the element nbame * @throws BuildException when any error occurs * @return the element created */ Object createDynamicElement(String name) throws BuildException; } 1.1 ant/src/main/org/apache/tools/ant/DynamicElementNS.java Index: DynamicElementNS.java =================================================================== /* * Copyright 2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.tools.ant; /** * Enables a task to control unknown elements. * * @since Ant 1.7 */ public interface DynamicElementNS { /** * Create an element with the given name * * @param uri The namespace uri for this attribute. * @param localName The localname of this attribute. * @param qName The qualified name for this element. * @throws BuildException when any error occurs * @return the element created for this element. */ Object createDynamicElement( String uri, String localName, String qName) throws BuildException; } 1.26 +28 -2 ant/src/main/org/apache/tools/ant/taskdefs/MacroDef.java Index: MacroDef.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/MacroDef.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- MacroDef.java 17 May 2004 13:30:17 -0000 1.25 +++ MacroDef.java 27 May 2004 14:38:46 -0000 1.26 @@ -46,6 +46,7 @@ private Map elements = new HashMap(); private String textName = null; private Text text = null; + private boolean hasImplicitElement = false; /** * Name of the definition @@ -254,6 +255,12 @@ "the element " + element.getName() + " has already been specified"); } + if (hasImplicitElement + || (element.isImplicit() && elements.size() != 0)) { + throw new BuildException( + "Only one element allowed when using implicit elements"); + } + hasImplicitElement = element.isImplicit(); elements.put(element.getName(), element); } @@ -507,6 +514,7 @@ public static class TemplateElement { private String name; private boolean optional = false; + private boolean implicit = false; private String description; /** @@ -547,6 +555,23 @@ } /** + * is this element implicit ? + * + * @param implicit if true this element may be left out, default + * is false. + */ + public void setImplicit(boolean implicit) { + this.implicit = implicit; + } + + /** + * @return the implicit attribute + */ + public boolean isImplicit() { + return implicit; + } + + /** * @param desc Description of the element. * @since ant 1.6.1 */ @@ -584,14 +609,15 @@ } else if (!name.equals(other.name)) { return false; } - return optional == other.optional; + return optional == other.optional && implicit == other.implicit; } /** * @return a hash code value for this object. */ public int hashCode() { - return objectHashCode(name) + (optional ? 1 : 0); + return objectHashCode(name) + + (optional ? 1 : 0) + (implicit ? 1 : 0); } } 1.27 +59 -19 ant/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java Index: MacroInstance.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/MacroInstance.java,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- MacroInstance.java 7 Apr 2004 12:39:12 -0000 1.26 +++ MacroInstance.java 27 May 2004 14:38:46 -0000 1.27 @@ -29,7 +29,7 @@ import java.util.Enumeration; import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DynamicConfigurator; +import org.apache.tools.ant.DynamicAttribute; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.RuntimeConfigurable; import org.apache.tools.ant.Target; @@ -44,13 +44,15 @@ * the parameter values in attributes and text. * @since Ant 1.6 */ -public class MacroInstance extends Task implements DynamicConfigurator { +public class MacroInstance extends Task implements DynamicAttribute, TaskContainer { private MacroDef macroDef; private Map map = new HashMap(); private Map nsElements = null; private Map presentElements = new HashMap(); private Hashtable localProperties = new Hashtable(); private String text = null; + private String implicitTag = null; + private List unknownElements = new ArrayList(); /** * Called from MacroDef.MyAntTypeDefinition#create() @@ -79,22 +81,14 @@ } /** - * Add an element. - * @param name the name of the element - * @return an inner Element type - * @throws BuildException if the name is not known or if this element - * has already been seen + * Method present for BC purposes. + * @param name not used + * @return nothing + * @deprecated + * @throws BuildException always */ public Object createDynamicElement(String name) throws BuildException { - if (getNsElements().get(name) == null) { - throw new BuildException("unsupported element " + name); - } - if (presentElements.get(name) != null) { - throw new BuildException("Element " + name + " already present"); - } - Element ret = new Element(); - presentElements.put(name, ret); - return ret; + throw new BuildException("Not implemented any more"); } private Map getNsElements() { @@ -105,12 +99,44 @@ Map.Entry entry = (Map.Entry) i.next(); nsElements.put((String) entry.getKey(), entry.getValue()); + MacroDef.TemplateElement te = (MacroDef.TemplateElement) + entry.getValue(); + if (te.isImplicit()) { + implicitTag = te.getName(); + } } } return nsElements; } /** + * Add a unknownElement for the macro instances nested elements. + * + * @param nestedTask a nested element. + */ + public void addTask(Task nestedTask) { + unknownElements.add(nestedTask); + } + + private void processTasks() { + if (implicitTag != null) { + return; + } + for (Iterator i = unknownElements.iterator(); i.hasNext();) { + UnknownElement ue = (UnknownElement) i.next(); + String name = ProjectHelper.extractNameFromComponentName( + ue.getTag()).toLowerCase(Locale.US); + if (getNsElements().get(name) == null) { + throw new BuildException("unsupported element " + name); + } + if (presentElements.get(name) != null) { + throw new BuildException("Element " + name + " already present"); + } + presentElements.put(name, ue.getChildren()); + } + } + + /** * Embedded element in macro instance */ public static class Element implements TaskContainer { @@ -255,9 +281,21 @@ UnknownElement child = copy(unknownElement); rc.addChild(child.getWrapper()); ret.addChild(child); + } else if (templateElement.isImplicit()) { + if (unknownElements.size() == 0 && !templateElement.isOptional()) { + throw new BuildException( + "Missing nested elements for implicit element " + + templateElement.getName()); + } + for (Iterator i = unknownElements.iterator(); + i.hasNext();) { + UnknownElement child = (UnknownElement) i.next(); + rc.addChild(child.getWrapper()); + ret.addChild(child); + } } else { - Element element = (Element) presentElements.get(tag); - if (element == null) { + List list = (List) presentElements.get(tag); + if (list == null) { if (!templateElement.isOptional()) { throw new BuildException( "Required nested element " @@ -265,7 +303,7 @@ } continue; } - for (Iterator i = element.getUnknownElements().iterator(); + for (Iterator i = list.iterator(); i.hasNext();) { UnknownElement child = (UnknownElement) i.next(); rc.addChild(child.getWrapper()); @@ -283,6 +321,8 @@ * */ public void execute() { + getNsElements(); + processTasks(); localProperties = new Hashtable(); Set copyKeys = new HashSet(map.keySet()); for (Iterator i = macroDef.getAttributes().iterator(); i.hasNext();) { 1.17 +20 -0 ant/src/testcases/org/apache/tools/ant/taskdefs/MacroDefTest.java Index: MacroDefTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/MacroDefTest.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- MacroDefTest.java 9 Mar 2004 16:48:57 -0000 1.16 +++ MacroDefTest.java 27 May 2004 14:38:46 -0000 1.17 @@ -108,5 +108,25 @@ "attribute.description", "description is hello world"); } + public void testImplicit() { + expectLog( + "implicit", "Before implicitIn implicitAfter implicit"); + } + public void testImplicitNotOptional() { + expectSpecificBuildException( + "implicit.notoptional", + "Missing nested elements for implicit element implicit", + "Missing nested elements for implicit element implicit"); + } + public void testImplicitOptional() { + expectLog( + "implicit.optional", "Before implicitAfter implicit"); + } + public void testImplicitExplicit() { + expectSpecificBuildException( + "implicit.explicit", + "Only one element allowed when using implicit elements", + "Only one element allowed when using implicit elements"); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org For additional commands, e-mail: dev-help@ant.apache.org