peterreilly 2003/11/06 01:07:51 Modified: docs/manual/CoreTasks Tag: ANT_16_BRANCH presetdef.html src/etc/testcases/taskdefs Tag: ANT_16_BRANCH presetdef.xml src/main/org/apache/tools/ant Tag: ANT_16_BRANCH IntrospectionHelper.java RuntimeConfigurable.java UnknownElement.java src/main/org/apache/tools/ant/taskdefs Tag: ANT_16_BRANCH PreSetDef.java src/testcases/org/apache/tools/ant/taskdefs Tag: ANT_16_BRANCH PreSetDefTest.java Log: Sync with HEAD Revision Changes Path No revision No revision 1.1.2.3 +50 -18 ant/docs/manual/CoreTasks/presetdef.html Index: presetdef.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/presetdef.html,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- presetdef.html 14 Oct 2003 09:59:49 -0000 1.1.2.2 +++ presetdef.html 6 Nov 2003 09:07:51 -0000 1.1.2.3 @@ -44,35 +44,67 @@ This nested element can be any other type or task. The attributes and elements that need to be preset are placed here. </p> - + <h3>Examples</h3> - <p> - The following fragment defines a javac task with the debug and deprecation + The following fragment defines a javac task with the debug, deprecation + srcdir and destdir attributes set. It also has a src element to source files from a generated directory. - </p> <blockquote> - <pre> +<pre class="code"> <presetdef name="my.javac"> - <javac debug="${debug}" deprecation="${deprecation}"> + <javac debug="${debug}" deprecation="${deprecation}" + srcdir="${src.dir}" destdir="${classes.dir}"> <src path="${gen.dir}"/> </javac> </presetdef> - </pre> +</pre> </blockquote> - <p> This can be used as a normal javac task - example: - </p> <blockquote> - <pre> -<my.javac src="${src.dir}" destdir="${classes.dir}"/> - </pre> +<pre class="code"> +<my.javac/> +</pre> </blockquote> - -<hr> -<p align="center">Copyright © 2003 Apache Software -Foundation. All rights Reserved.</p> - -</body> + The attributes specified in the preset task may be overridden - i.e. + they may be seen as optional attributes - example: + <blockquote> +<pre class="code"> +<my.javac srcdir="${test.src}" deprecation="no"/> +</pre> + </blockquote> + One may put a presetdef definition in an antlib. + For example suppose the jar file antgoodies.jar has + the antlib.xml as follows: + <blockquote> +<pre class="code"> +<antlib> + <taskdef resource="com/acme/antgoodies/tasks.properties"/> + <!-- Implement the common use of the javac command --> + <presetdef name="javac"> + <javac deprecation="${deprecation}" debug="${debug}" + srcdir="src" destdir="classes"/> + </presetdef> +</antlib> +</pre> + </blockquote> + One may then use this in a build file as follows: + <blockquote> +<pre class="code"> +<project default="example" xmlns:antgoodies="antlib:com.acme.antgoodies"> + <target name="example"> + <!-- Compile source --> + <antgoodies:javac srcdir="src/main"/> + <!-- Compile test code --> + <antgoodies:javac srcdir="src/test"/> + </target> +</project> +</pre> + </blockquote> + <hr></hr> + <p align="center">Copyright © 2003 Apache Software + Foundation. All rights Reserved.</p> + + </body> </html> No revision No revision 1.1.2.1 +67 -0 ant/src/etc/testcases/taskdefs/presetdef.xml Index: presetdef.xml =================================================================== RCS file: /home/cvs/ant/src/etc/testcases/taskdefs/presetdef.xml,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -r1.1 -r1.1.2.1 --- presetdef.xml 14 Aug 2003 13:17:25 -0000 1.1 +++ presetdef.xml 6 Nov 2003 09:07:51 -0000 1.1.2.1 @@ -1,20 +1,87 @@ <project> + <path id="test-classes"> + <pathelement location="../../../../build/testcases" /> + <pathelement path="${java.class.path}" /> + </path> + <target name="simple"> <presetdef name="my.echo"> <echo message="Hello world"/> </presetdef> <my.echo/> </target> + <target name="text"> <presetdef name="my.echo"> <echo>Inner Text</echo> </presetdef> <my.echo/> </target> + <target name="uri"> <presetdef name="echo" uri="abc"> <echo message="Hello world"/> </presetdef> <x:echo xmlns:x="abc"/> </target> + + <target name="defaulttest"> + <taskdef name="defaulttest" + classname="org.apache.tools.ant.taskdefs.PreSetDefTest$DefaultTest" + classpathref="test-classes"/> + <presetdef name="d"> + <defaulttest attribute="true"/> + </presetdef> + <d attribute="false"/> + </target> + + <target name="doubledefault"> + <taskdef name="defaulttest" + classname="org.apache.tools.ant.taskdefs.PreSetDefTest$DefaultTest" + classpathref="test-classes"/> + <presetdef name="d"> + <defaulttest attribute="true"/> + </presetdef> + <presetdef name="dd"> + <d attribute="false"/> + </presetdef> + <dd/> + <dd attribute="true"/> + </target> + + <target name="text.optional"> + <presetdef name="echo.mytext"> + <echo>MyText</echo> + </presetdef> + <echo.mytext/> + <echo.mytext>override text</echo.mytext> + </target> + + <target name="element.order"> + <presetdef name="el.order"> + <sequential> + <echo>Line 1</echo> + </sequential> + </presetdef> + <el.order> + <echo>Line 2</echo> + </el.order> + </target> + + <target name="element.order2"> + <presetdef name="el.order"> + <sequential> + <echo>Line 1</echo> + </sequential> + </presetdef> + <presetdef name="el.order2"> + <el.order> + <echo>Line 2</echo> + </el.order> + </presetdef> + <el.order2> + <echo>Line 3</echo> + </el.order2> + </target> + </project> No revision No revision 1.65.2.2 +39 -3 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.65.2.1 retrieving revision 1.65.2.2 diff -u -r1.65.2.1 -r1.65.2.2 --- IntrospectionHelper.java 15 Oct 2003 15:46:20 -0000 1.65.2.1 +++ IntrospectionHelper.java 6 Nov 2003 09:07:51 -0000 1.65.2.2 @@ -65,6 +65,7 @@ import java.util.Locale; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.taskdefs.PreSetDef; /** * Helper class that collects the methods a task or nested element @@ -286,11 +287,14 @@ if (nestedCreators.get(propName) == null) { nestedTypes.put(propName, returnType); nestedCreators.put(propName, new NestedCreator() { - public boolean isPolyMorphic() { return false; } + public Object getRealObject() { + return null; + } + public Class getElementClass() { return null; } @@ -332,6 +336,10 @@ return true; } + public Object getRealObject() { + return null; + } + public Class getElementClass() { return c.getDeclaringClass(); } @@ -387,6 +395,10 @@ return true; } + public Object getRealObject() { + return null; + } + public Class getElementClass() { return c.getDeclaringClass(); } @@ -611,6 +623,10 @@ return null; } + public Object getRealObject() { + return null; + } + public Object create( Project project, Object parent, Object ignore) { return nestedElement; @@ -1113,6 +1129,14 @@ } /** + * @return the real object (used currently only + * for preset def) + */ + public Object getRealObject() { + return nestedCreator.getRealObject(); + } + + /** * Stores the nested element object using a storage method * determined by introspection. * @@ -1147,6 +1171,7 @@ private interface NestedCreator { boolean isPolyMorphic(); Class getElementClass(); + Object getRealObject(); Object create(Project project, Object parent, Object child) throws InvocationTargetException, IllegalAccessException, InstantiationException; void store(Object parent, Object child) @@ -1252,8 +1277,14 @@ if (addedObject == null) { return null; } + Object rObject = addedObject; + if (addedObject instanceof PreSetDef.PreSetDefinition) { + rObject = ((PreSetDef.PreSetDefinition) addedObject).createObject( + project); + } final Method method = addMethod; final Object nestedObject = addedObject; + final Object realObject = rObject; return new NestedCreator() { public boolean isPolyMorphic() { @@ -1266,15 +1297,20 @@ public Object create(Project project, Object parent, Object ignore) throws InvocationTargetException, IllegalAccessException { if (!method.getName().endsWith("Configured")) { - method.invoke(parent, new Object[]{nestedObject}); + method.invoke(parent, new Object[]{realObject}); } return nestedObject; } + + public Object getRealObject() { + return realObject; + } + public void store(Object parent, Object child) throws InvocationTargetException, IllegalAccessException, InstantiationException { if (method.getName().endsWith("Configured")) { - method.invoke(parent, new Object[]{nestedObject}); + method.invoke(parent, new Object[]{realObject}); } } }; 1.45.2.1 +43 -1 ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java Index: RuntimeConfigurable.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/RuntimeConfigurable.java,v retrieving revision 1.45 retrieving revision 1.45.2.1 diff -u -r1.45 -r1.45.2.1 --- RuntimeConfigurable.java 12 Sep 2003 20:56:45 -0000 1.45 +++ RuntimeConfigurable.java 6 Nov 2003 09:07:51 -0000 1.45.2.1 @@ -63,6 +63,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Iterator; import org.apache.tools.ant.util.CollectionUtils; import org.xml.sax.AttributeList; @@ -222,7 +223,6 @@ * @return Attribute name to attribute value map */ public Hashtable getAttributeMap() { - // Nobody calls this method, maybe it could just be deleted? if (attributeMap != null) { return new Hashtable(attributeMap); } else { @@ -463,5 +463,47 @@ public void reconfigure(Project p) { proxyConfigured = false; maybeConfigure(p); + } + + + /** + * Apply presets, attributes and text are set if not currently set. + * nested elements are prepended. + * + * @param r a <code>RuntimeConfigurable</code> value + */ + public void applyPreSet(RuntimeConfigurable r) { + // Attributes + if (r.attributeMap != null) { + for (Iterator i = r.attributeMap.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + if (attributeMap == null || attributeMap.get(name) == null) { + setAttribute(name, (String) r.attributeMap.get(name)); + } + } + } + // poly type + if (r.polyType != null && polyType == null) { + polyType = r.polyType; + } + + // Children (this is a shadow of unknownElement#children) + if (r.children != null) { + List newChildren = new ArrayList(); + newChildren.addAll(r.children); + if (children != null) { + newChildren.addAll(children); + } + children = newChildren; + } + + // Text + if (r.characters != null) { + if (characters == null + || characters.toString().trim().length() == 0) { + characters = + new StringBuffer(r.characters.toString()); + } + } } } 1.63.2.4 +43 -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.63.2.3 retrieving revision 1.63.2.4 diff -u -r1.63.2.3 -r1.63.2.4 --- UnknownElement.java 15 Oct 2003 15:46:20 -0000 1.63.2.3 +++ UnknownElement.java 6 Nov 2003 09:07:51 -0000 1.63.2.4 @@ -58,6 +58,7 @@ import java.util.Iterator; import java.util.List; import java.io.IOException; +import org.apache.tools.ant.taskdefs.PreSetDef; /** * Wrapper class that holds all the information necessary to create a task @@ -95,6 +96,9 @@ */ private List/*<UnknownElement>*/ children = null; + /** Specifies if a predefined definition has been done */ + private boolean presetDefed = false; + /** * Creates an UnknownElement for the given element name. * @@ -372,6 +376,31 @@ } /** + * This is used then the realobject of the UE is a PreSetDefinition. + * This is also used when a presetdef is used on a presetdef + * The attributes, elements and text are applied to this + * UE. + * + * @param u an UnknownElement containing the attributes, elements and text + */ + public void applyPreSet(UnknownElement u) { + if (presetDefed) { + return; + } + // Do the runtime + getWrapper().applyPreSet(u.getWrapper()); + if (u.children != null) { + List newChildren = new ArrayList(); + newChildren.addAll(u.children); + if (children != null) { + newChildren.addAll(children); + } + children = newChildren; + } + presetDefed = true; + } + + /** * Creates a named task or data type. If the real object is a task, * it is configured up to the init() stage. * @@ -386,9 +415,17 @@ getProject()); String name = ue.getComponentName(); Object o = helper.createComponent(ue, ue.getNamespace(), name); + if (o == null) { throw getNotFoundException("task or type", name); } + + if (o instanceof PreSetDef.PreSetDefinition) { + PreSetDef.PreSetDefinition def = (PreSetDef.PreSetDefinition) o; + o = def.createObject(ue.getProject()); + ue.applyPreSet(def.getPreSets()); + } + if (o instanceof Task) { Task task = (Task) o; task.setOwningTarget(getOwningTarget()); @@ -521,6 +558,12 @@ ih.getElementCreator(getProject(), parent, childName); creator.setPolyType(childWrapper.getPolyType()); Object realChild = creator.create(); + if (realChild instanceof PreSetDef.PreSetDefinition) { + PreSetDef.PreSetDefinition def = + (PreSetDef.PreSetDefinition) realChild; + realChild = creator.getRealObject(); + child.applyPreSet(def.getPreSets()); + } childWrapper.setCreator(creator); childWrapper.setProxy(realChild); if (realChild instanceof Task) { No revision No revision 1.7.2.2 +53 -7 ant/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java Index: PreSetDef.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/PreSetDef.java,v retrieving revision 1.7.2.1 retrieving revision 1.7.2.2 diff -u -r1.7.2.1 -r1.7.2.2 --- PreSetDef.java 23 Sep 2003 06:00:00 -0000 1.7.2.1 +++ PreSetDef.java 6 Nov 2003 09:07:51 -0000 1.7.2.2 @@ -130,26 +130,52 @@ "Unable to find typedef " + componentName); } - MyAntTypeDefinition newDef = new MyAntTypeDefinition(def, nestedTask); + PreSetDefinition newDef = new PreSetDefinition(def, nestedTask); newDef.setName(name); helper.addDataTypeDefinition(newDef); } - private static class MyAntTypeDefinition extends AntTypeDefinition { + /** + * This class contains the unknown element and the object + * that is predefined. + * @see AntTypeDefinition + */ + public static class PreSetDefinition extends AntTypeDefinition { private AntTypeDefinition parent; private UnknownElement element; - public MyAntTypeDefinition(AntTypeDefinition parent, UnknownElement el) { + /** + * Creates a new <code>PresetDefinition</code> instance. + * + * @param parent The parent of this predefintion. + * @param el The predefined attributes, nested elements and text. + */ + public PreSetDefinition(AntTypeDefinition parent, UnknownElement el) { + if (parent instanceof PreSetDefinition) { + PreSetDefinition p = (PreSetDefinition) parent; + el.applyPreSet(p.element); + parent = p.parent; + } this.parent = parent; this.element = el; } + /** + * Override so that it is not allowed + * + * @param clazz a <code>Class</code> value + */ public void setClass(Class clazz) { throw new BuildException("Not supported"); } + /** + * Override so that it is not allowed + * + * @param className a <code>String</code> value + */ public void setClassName(String className) { throw new BuildException("Not supported"); } @@ -200,6 +226,7 @@ /** * get the exposed class for this definition. + * @param project the current project * @return the exposed class */ public Class getExposedClass(Project project) { @@ -227,19 +254,38 @@ /** * create an instance of the definition. * The instance may be wrapped in a proxy class. + * This is a special version of create for IH and UE. * @param project the current project * @return the created object */ - public Object create(Project project) { + public Object createObject(Project project) { Object o = parent.create(project); if (o == null) { return null; } - element.configure(o); return o; } /** + * @return the predefined attributes, elements and text as + * a UnknownElement + */ + public UnknownElement getPreSets() { + return element; + } + + /** + * Fake create an object, used by IH and UE to see that + * this is a predefined object. + * + * @param project the current project + * @return this object + */ + public Object create(Project project) { + return this; + } + + /** * Equality method for this definition * * @param other another definition @@ -253,7 +299,7 @@ if (other.getClass() != getClass()) { return false; } - MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other; + PreSetDefinition otherDef = (PreSetDefinition) other; if (!parent.sameDefinition(otherDef.parent, project)) { return false; } @@ -278,7 +324,7 @@ if (!other.getClass().getName().equals(getClass().getName())) { return false; } - MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other; + PreSetDefinition otherDef = (PreSetDefinition) other; if (!parent.similarDefinition(otherDef.parent, project)) { return false; } No revision No revision 1.1.2.1 +39 -0 ant/src/testcases/org/apache/tools/ant/taskdefs/PreSetDefTest.java Index: PreSetDefTest.java =================================================================== RCS file: /home/cvs/ant/src/testcases/org/apache/tools/ant/taskdefs/PreSetDefTest.java,v retrieving revision 1.1 retrieving revision 1.1.2.1 diff -u -r1.1 -r1.1.2.1 --- PreSetDefTest.java 14 Aug 2003 13:17:26 -0000 1.1 +++ PreSetDefTest.java 6 Nov 2003 09:07:51 -0000 1.1.2.1 @@ -55,6 +55,7 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.BuildFileTest; +import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; @@ -82,5 +83,43 @@ expectLog("uri", "Hello world"); } + public void testDefaultTest() { + expectLog("defaulttest", "attribute is false"); + } + + public void testDoubleDefault() { + expectLog("doubledefault", "attribute is falseattribute is true"); + } + + public void testTextOptional() { + expectLog("text.optional", "MyTextoverride text"); + } + + public void testElementOrder() { + expectLog("element.order", "Line 1Line 2"); + } + + public void testElementOrder2() { + expectLog("element.order2", "Line 1Line 2Line 3"); + } + + /** + * A test class to check default properties + */ + public static class DefaultTest extends Task { + boolean isSet = false; + boolean attribute = false; + public void setAttribute(boolean b) { + if (isSet) { + throw new BuildException("Attribute Already set"); + } + attribute = b; + isSet = true; + } + + public void execute() { + getProject().log("attribute is " + attribute); + } + } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]