ehatcher 2003/04/29 12:42:00
Modified: proposal/xdocs build.xml Added: proposal/xdocs/metadata xdoclet.xml proposal/xdocs/src/org/apache/ant/xdoclet AntDocletTask.java AntSubTask.java IndexGen.java TaskDefPropertiesSubTask.java TaskDescriptorSubTask.java TaskTagsHandler.java proposal/xdocs/src/org/apache/ant/xdoclet/resources task_xml.xdt taskdef_properties.xdt Removed: proposal/xdocs/lib xdoclet-apache-module-1.2b3-dev.jar proposal/xdocs/src/org/apache/tools/ant/xdoclet AntXDocletTask.java DatatypeSubTask.java DatatypeTagsHandler.java IndexGen.java Log: migrated Ant XDoclet code here, to maintain it easier Revision Changes Path 1.22 +18 -5 ant/proposal/xdocs/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/ant/proposal/xdocs/build.xml,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- build.xml 16 Mar 2003 02:33:59 -0000 1.21 +++ build.xml 29 Apr 2003 19:41:59 -0000 1.22 @@ -384,10 +384,14 @@ <delete dir="${gen.dir}"/> </target> - <target name="gen" depends="init"> + <target name="gen" depends="jar"> <taskdef name="antdoclet" - classname="xdoclet.modules.apache.ant.AntDocletTask" - classpathref="xdoclet.classpath"/> + classname="org.apache.ant.xdoclet.AntDocletTask"> + <classpath> + <path refid="xdoclet.classpath"/> + <pathelement location="${build.dir}/xdoclet-ant.jar"/> + </classpath> + </taskdef> <antdoclet destdir="${gen.dir}" excludedtags="@version,@author" force="${xdoclet.force}" @@ -462,15 +466,24 @@ <mkdir dir="${build.dir}/classes"/> <javac destdir="${build.dir}/classes" srcdir="src" + deprecation="on" debug="true" - includes="**/IndexGen.java" + classpathref="xdoclet.classpath" /> </target> + <target name="jar" depends="compile"> + <jar destfile="${build.dir}/xdoclet-ant.jar"> + <fileset dir="${build.dir}/classes"/> + <metainf dir="metadata" includes="xdoclet.xml"/> + <fileset dir="src" includes="**/*.xdt"/> + </jar> + </target> + <target name="indexgen" depends="compile"> <taskdef name="indexgen" classpath="${build.dir}/classes" - classname="org.apache.tools.ant.xdoclet.IndexGen" + classname="org.apache.ant.xdoclet.IndexGen" /> <indexgen rootdir="${build.dir}/docs/manual"/> </target> 1.1 ant/proposal/xdocs/metadata/xdoclet.xml Index: xdoclet.xml =================================================================== <?xml version="1.0" encoding="UTF-8"?> <!-- <!DOCTYPE xdoclet-module PUBLIC "-//XDoclet Team//DTD XDoclet Module 1.0//EN" "http://xdoclet.sourceforge.net/dtd/xdoclet-module_1_0.dtd"> --> <xdoclet-module> <taghandler namespace="Ant" class="org.apache.ant.xdoclet.TaskTagsHandler" /> <subtask name="taskdescriptor" implementation-class="org.apache.ant.xdoclet.TaskDescriptorSubTask" parent-task-class="org.apache.ant.xdoclet.AntDocletTask" /> <subtask name="taskdefproperties" implementation-class="org.apache.ant.xdoclet.TaskDefPropertiesSubTask" parent-task-class="org.apache.ant.xdoclet.AntDocletTask" /> </xdoclet-module> 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/AntDocletTask.java Index: AntDocletTask.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.ant.xdoclet; import org.apache.tools.ant.BuildException; import xdoclet.DocletTask; /** * @created January 5, 2003 * @ant.element name="antdoclet" display-name="AntDoclet Task" */ public class AntDocletTask extends DocletTask { public AntDocletTask() { // by default, binary classes do not provide their // methods for performance reasons, but it is needed // here to climb up and find true tasks. System.setProperty("xjavadoc.compiledmethods", "true"); } protected void validateOptions() throws BuildException { super.validateOptions(); checkClass("org.apache.tools.ant.IntrospectionHelper"); } } 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/AntSubTask.java Index: AntSubTask.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.ant.xdoclet; import java.util.Collection; import java.util.Iterator; import xjavadoc.XClass; import xjavadoc.XJavaDoc; import xjavadoc.XMethod; import xdoclet.TemplateSubTask; import xdoclet.XDocletException; import xdoclet.util.TypeConversionUtil; /** * @created January 5, 2003 */ public abstract class AntSubTask extends TemplateSubTask { /** * Checks many factors to determine if the class is indeed an Ant task or not. * * @param clazz * @return * @exception XDocletException * @todo perhaps make deprecation switch configurable */ public final static boolean isAntTask(XClass clazz) throws XDocletException { if (clazz.isAbstract()) { return false; } // no inner classes (for now - but is this possible? desired?) if (clazz.isInner()) { return false; } String ignoreValue = clazz.getDoc().getTagAttributeValue("ant.task", "ignore"); boolean ignore = TypeConversionUtil.stringToBoolean(ignoreValue, false); if (ignore) { return false; } /* * Tag[] tags = clazz.tags(); * for (int i = 0; i < tags.length; i++) { * if ("@deprecated".equals(tags[i].name())) { * return false; * } * } */ if (hasExecuteMethod(clazz)) { return true; } return false; } /** * Check for class implementing an execute() method. Recursive calls are made to superclasses. * * @param clazz * @return */ private static boolean hasExecuteMethod(XClass clazz) { if (clazz == null) { return false; } // It ain't a task if we've climbed back to Task itself. // Also ignore other special Ant classes if ("org.apache.tools.ant.Task".equals(clazz.getQualifiedName()) || "org.apache.tools.ant.Target".equals(clazz.getQualifiedName()) || "org.apache.tools.ant.TaskAdapter".equals(clazz.getQualifiedName()) || "org.apache.tools.ant.UnknownElement".equals(clazz.getQualifiedName())) { return false; } // need to check that only runtime exceptions are thrown? Collection methods = clazz.getMethods(true); Iterator iter = methods.iterator(); while (iter.hasNext()) { XMethod method = (XMethod) iter.next(); if ("execute".equals(method.getName())) { if (method.getParameters().size() == 0) { if (method.getReturnType().getType().getName().equals("void")) { return true; } } } } return false; } protected void startProcess() throws XDocletException { Collection classes = XJavaDoc.getInstance().getSourceClasses(false, processInnerClasses()); super.startProcess(); } /** * Returns true if the class is an Ant task. This causes the task to be processed by the XDoclet template task. * * @param clazz * @return * @exception XDocletException */ protected boolean matchesGenerationRules(XClass clazz) throws XDocletException { boolean match = isAntTask(clazz); return match; } } 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/IndexGen.java Index: IndexGen.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.ant.xdoclet; import org.apache.tools.ant.Task; import org.apache.tools.ant.BuildException; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.TreeMap; import java.util.Arrays; import java.util.Iterator; /** * Quick and dirty index.html generator for proposal/xdocs * * @author Erik Hatcher */ public class IndexGen extends Task { private File rootDir; public void setRootDir(File rootDir) { this.rootDir = rootDir; } public void execute() throws BuildException { TreeMap data = new TreeMap(); String[] categories = rootDir.list(); StringBuffer sb = new StringBuffer(); sb.append("<html><head><title>xdocs index</title></head>"); sb.append("<body>"); int catCount = 0; int taskCount = 0; // grab all categories and tasks for (int i=0; i < categories.length; i++) { String category = categories[i]; File catDir = new File(rootDir, category); if (!catDir.isDirectory()) { continue; } String[] tasks = catDir.list(); Arrays.sort(tasks); data.put(category, tasks); } Iterator iter = data.keySet().iterator(); while (iter.hasNext()) { catCount++; String category = (String) iter.next(); sb.append("<h2>" + category + "</h2>"); sb.append("<ul>"); String[] tasks = (String[]) data.get(category); for (int j=0; j < tasks.length; j++) { taskCount++; String task = tasks[j]; sb.append("<li>"); sb.append("<a href=\"" + category + "/" + task + "\">" + task + "</a>"); sb.append("</li>"); } sb.append("</ul>"); } sb.append("</body></html>"); FileWriter fw = null; try { fw = new FileWriter(new File(rootDir,"index.html")); fw.write(sb.toString()); fw.close(); } catch (IOException e) { throw new BuildException(e); } log("Index generated: " + catCount + " categories and " + taskCount + " tasks"); } } 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/TaskDefPropertiesSubTask.java Index: TaskDefPropertiesSubTask.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.ant.xdoclet; import xdoclet.TemplateSubTask; /** * Generates Ant taskdef properties files, suitable for bulk defining tasks with Ant's <taskdef> task. * * @author Erik Hatcher ([EMAIL PROTECTED]) * @created January 5, 2003 * @ant.element display-name="taskdefproperties" name="taskdefproperties" * parent="org.apache.ant.xdoclet.AntDocletTask" * @ant.task ignore="true" * @version $Revision: 1.1 $ */ public class TaskDefPropertiesSubTask extends AntSubTask { protected static String DEFAULT_TEMPLATE_FILE = "resources/taskdef_properties.xdt"; public TaskDefPropertiesSubTask() { setTemplateURL(getClass().getResource(DEFAULT_TEMPLATE_FILE)); setDestinationFile("taskdef.properties"); } } 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/TaskDescriptorSubTask.java Index: TaskDescriptorSubTask.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.ant.xdoclet; import java.io.File; import java.util.Collection; import java.util.Iterator; import xjavadoc.XClass; import xjavadoc.XJavaDoc; import xjavadoc.XMethod; import xdoclet.TemplateSubTask; import xdoclet.XDocletException; import xdoclet.XDocletTagSupport; import xdoclet.util.TypeConversionUtil; /** * Generates Ant task descriptors. * * @author Erik Hatcher ([EMAIL PROTECTED]) * @created January 1, 2003 * @ant.element display-name="taskdescriptor" name="taskdescriptor" * parent="xdoclet.modules.apache.ant.org.apache.ant.xdoclet.AntDocletTask" * @ant.task ignore="true" * @version $Revision: 1.1 $ * @xdoclet.merge-file file="{0}.xml" relates-to="{0}.xml" description="Used for code examples. An example merge file * may be found in Ant's proposal/xdocs/src directory." */ public class TaskDescriptorSubTask extends AntSubTask { protected static String DEFAULT_TEMPLATE_FILE = "resources/task_xml.xdt"; public TaskDescriptorSubTask() { setTemplateURL(getClass().getResource(DEFAULT_TEMPLATE_FILE)); setDestinationFile("{0}.xml"); } /** * Custom file naming. Use the task name for the file name rather than the default class name. * * @param clazz * @return * @exception XDocletException */ protected String getGeneratedFileName(XClass clazz) throws XDocletException { String dir = TaskTagsHandler.getCategoryName(clazz); String taskName = TaskTagsHandler.getTaskName(clazz); return new File(dir, taskName + ".xml").toString(); } } 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/TaskTagsHandler.java Index: TaskTagsHandler.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.ant.xdoclet; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.tools.ant.IntrospectionHelper; import org.apache.tools.ant.types.EnumeratedAttribute; import xjavadoc.TagIterator; import xjavadoc.XClass; import xjavadoc.XCollections; import xjavadoc.XMethod; import xjavadoc.XParameter; import xjavadoc.XTag; import xdoclet.XDocletException; import xdoclet.XDocletTagSupport; import xdoclet.tagshandler.AbstractProgramElementTagsHandler; import xdoclet.tagshandler.MethodTagsHandler; /** * Custom tag handler for XDoclet templates for Ant-specific processing. * * @author Erik Hatcher * @author Jesse Stockall * @created January 1, 2003 * @xdoclet.taghandler namespace="Ant" * @todo clean up logic so that all setters are gathered first (even superclass) and sorted along wih * them * @todo need to create better logic for finding proper setters * @todo add ifIsAntTask, among other convenience tags */ public class TaskTagsHandler extends XDocletTagSupport { /** * Default category for tasks without a category attribute. */ public final static String DEFAULT_CATEGORY = "other"; /** * Default requirement group for attributes without group. */ public final static String DEFAULT_GROUP = "optional"; /** * Requirement group description for optional attributes. */ public final static String DESC_OPTIONAL = "optional"; /** * Requirement group description for required attributes. */ public final static String DESC_REQUIRED = "required"; private static Map attributeDisplayMap = new HashMap(); private static Map elementDisplayMap = new HashMap(); private static String[] fluffPrefixes = {"set a", "set the", "sets a", "sets the"}; static { attributeDisplayMap.put("java.lang.String", "String"); attributeDisplayMap.put("boolean", "boolean"); attributeDisplayMap.put("org.apache.tools.ant.types.Path", "Path"); attributeDisplayMap.put("org.apache.tools.ant.types.Reference", "Reference"); attributeDisplayMap.put("java.io.File", "File"); attributeDisplayMap.put("java.util.Date", "Date"); attributeDisplayMap.put("java.net.URL", "URL"); attributeDisplayMap.put("java.lang.Long", "long"); attributeDisplayMap.put("java.lang.Integer", "int"); attributeDisplayMap.put("java.lang.Float", "float"); attributeDisplayMap.put("java.lang.Double", "double"); elementDisplayMap.put("org.apache.tools.ant.types.Path", "Path"); elementDisplayMap.put("org.apache.tools.ant.types.FileSet", "Fileset"); elementDisplayMap.put("org.apache.tools.ant.taskdefs.Property", "see <property>"); elementDisplayMap.put("org.apache.tools.ant.types.Mapper", "Mapper"); elementDisplayMap.put("org.apache.tools.ant.types.PatternSet", "Patternset"); elementDisplayMap.put("org.apache.tools.ant.types.FileList", "Filelist"); elementDisplayMap.put("org.apache.tools.ant.types.FilterChain", "FilterChain"); elementDisplayMap.put("org.apache.tools.ant.types.FilterSet", "Filterset"); elementDisplayMap.put("org.apache.tools.ant.types.ZipFileSet", "ZipFileset"); elementDisplayMap.put("org.apache.tools.ant.types.DirSet", "Dirset"); elementDisplayMap.put("org.apache.tools.ant.types.XMLCatalog", "XMLCatalog"); } /** * Provides the Ant task name. Order of rules: * <ol> * <li> Value of * * @param clazz * @return * @ant:task name="..."</li> * <li> Lowercased classname with "Task" suffix removed</li> * </ol> * */ public final static String getTaskName(XClass clazz) { String tagValue = clazz.getDoc().getTagAttributeValue("ant.task", "name"); if (tagValue == null) { // use classname, but strip "Task" suffix if there tagValue = clazz.getName(); if (tagValue.endsWith("Task")) { tagValue = tagValue.substring(0, tagValue.indexOf("Task")); } tagValue = tagValue.toLowerCase(); } return tagValue; } /** * Provides the Ant category name as the Value of the category attribute. * * @param clazz * @return */ public final static String getCategoryName(XClass clazz) { String tagValue = clazz.getDoc().getTagAttributeValue("ant.task", "category"); if (tagValue != null) { tagValue = tagValue.toLowerCase(); } else { tagValue = DEFAULT_CATEGORY; } return tagValue; } /** * Iterates over all Ant tasks * * @param template * @param attributes * @exception XDocletException */ public void forAllTasks(String template, Properties attributes) throws XDocletException { Collection classes = AbstractProgramElementTagsHandler.getAllClasses(); XClass cur_class = null; Iterator iter = classes.iterator(); while (iter.hasNext()) { cur_class = (XClass) iter.next(); setCurrentClass(cur_class); if (AntSubTask.isAntTask(cur_class)) { generate(template); } } } // /** // * Iterates over all Ant attributes. // * // * @param template XDoclet template // * @param attributes Tag parameters // * @exception XDocletException Oops! // */ // public void forAllAttributes(String template, Properties attributes) throws XDocletException // { // // throw exception if not an Ant task // // XClass cur_class = getCurrentClass(); // // XMethod[] methods = getAttributeMethods(cur_class); // //// System.out.println("# attributes = " + methods.length); // // for (int i = 0; i < methods.length; i++) { // setCurrentMethod(methods[i]); // generate(template); // } // } /** * Iterates over all Ant attributes. * * @param template XDoclet template * @param attributes Tag parameters * @exception XDocletException Oops! */ public void forAllAttributesInGroup(String template, Properties attributes) throws XDocletException { // throw exception if not an Ant task XClass cur_class = getCurrentClass(); XMethod[] methods = getAttributeMethods(cur_class); String group = attributes.getProperty("group", DEFAULT_GROUP); for (int i = 0; i < methods.length; i++) { String value = methods[i].getDoc().getTagAttributeValue("ant.attribute", "group"); if ((value != null && value.equals(group)) || (value == null && group.equals(DEFAULT_GROUP))) { setCurrentMethod(methods[i]); generate(template); } } } /** * Determines if there's at least one Ant attribute. * * @param template XDoclet template * @param attributes Tag parameters * @exception XDocletException Oops! */ public void ifHasAttributes(String template, Properties attributes) throws XDocletException { // throw exception if not an Ant task XClass cur_class = getCurrentClass(); XMethod[] methods = getAttributeMethods(cur_class); if (methods.length > 0) { generate(template); } } /** * Iterates over all Ant nested element methods (addXXX, addConfiguredXXX, addXXX) * * @param template XDoclet template * @param attributes Tag parameters * @exception XDocletException Oops! */ public void forAllElements(String template, Properties attributes) throws XDocletException { // throw exception if not an Ant task XClass cur_class = getCurrentClass(); XMethod[] methods = getElementMethods(cur_class); for (int i = 0; i < methods.length; i++) { setCurrentMethod(methods[i]); generate(template); } } /** * Iterates over all ant.attribute.group tags. * * @param template XDoclet template * @param attributes Tag parameters * @throws XDocletException Oops! */ public void forAllAttributeGroups(String template, Properties attributes) throws XDocletException { Collection tags = getCurrentClass().getDoc().getTags("ant.attribute.group"); for (TagIterator t = XCollections.tagIterator(tags); t.hasNext(); ) { setCurrentClassTag(t.next()); generate(template); } } /** * Provides the name of a requirement group. * * @return The description of the group, or 'optional' if not is defined * @throws XDocletException */ public String attributeGroupName() throws XDocletException { XTag tag = getCurrentClassTag(); String name = tag.getAttributeValue("name"); return name != null ? name : DEFAULT_GROUP; } /** * Provides the description for a requirement group. * * @return The description of the group, or 'Optional' if not is defined * @throws XDocletException */ public String attributeGroupDesc() throws XDocletException { XTag tag = getCurrentClassTag(); String desc = tag.getAttributeValue("description"); return desc != null ? desc : DESC_OPTIONAL; } /** * Provides the element name for the current method * * @return * @exception XDocletException */ public String elementName() throws XDocletException { String methodName = getCurrentMethod().getName(); String elementName = "<not a valid element>"; if (methodName.startsWith("addConfigured")) { elementName = methodName.substring(13, methodName.length()); } else if (methodName.startsWith("add")) { elementName = methodName.substring(3, methodName.length()); } else if (methodName.startsWith("create")) { elementName = methodName.substring(6, methodName.length()); } return elementName.toLowerCase(); } public String displayAttributeType() throws XDocletException { Collection parameters = getCurrentMethod().getParameters(); XParameter param = XCollections.parameterIterator(parameters).next(); String methodType = param.getType().getQualifiedName(); String display = (String) attributeDisplayMap.get(methodType); if (display == null) { // System.out.println("type = " + methodType); Class clazz = getAttributeClass(methodType); if (clazz == null) { return methodType; } Object instance = null; try { instance = clazz.newInstance(); } catch (InstantiationException e) { } catch (IllegalAccessException e) { } if (instance != null && instance instanceof EnumeratedAttribute) { EnumeratedAttribute enum = (EnumeratedAttribute) instance; String[] values = enum.getValues(); display = ""; for (int i = 0; i < values.length; i++) { display += """ + values[i] + """; if (i != (values.length - 1)) { display += ", "; } } return display; } display = ""; } return display; } public String displayElementType() throws XDocletException { String elementType = elementType(); String display = (String) elementDisplayMap.get(elementType); if (display == null) { display = ""; } return display; } /** * Provides the element type for the current method * * @return * @exception XDocletException */ public String elementType() throws XDocletException { XClass clazz = elementClassDoc(); if (clazz == null) { throw new XDocletException("Method is not an Ant element!"); } return clazz.getQualifiedName(); } /** * Provides the Ant task name. * * @return * @exception XDocletException * @see #getTaskName(xjavadoc.XClass) */ public String taskName() throws XDocletException { return getTaskName(getCurrentClass()); } public String propertyName() { return MethodTagsHandler.getPropertyNameFor(getCurrentMethod()).toLowerCase(); } public String shortMethodDescription() throws XDocletException { String desc = getCurrentMethod().getDoc().getFirstSentence(); if (desc == null || desc.length() == 0) { desc = "no description"; } desc = desc.trim(); String descLower = desc.toLowerCase(); for (int i = 0; i < fluffPrefixes.length; i++) { String prefix = fluffPrefixes[i].toLowerCase() + " "; if (descLower.startsWith(prefix)) { desc = desc.substring(prefix.length()); break; } } desc = desc.substring(0, 1).toUpperCase() + desc.substring(1); if (!desc.endsWith(".")) { desc += "."; } return desc; } /** * Provides the Ant category name. * * @return * @exception XDocletException * @see #getCategoryName(xjavadoc.XClass) */ public String categoryName() throws XDocletException { return getCategoryName(getCurrentClass()); } /** * Provides the requirment group for the current method * * @return The group listed in the source, or 'optional' of none is listed * @throws XDocletException oops */ public String attributeGroup() throws XDocletException { String value = getCurrentMethod().getDoc().getTagAttributeValue("ant.attribute", "group"); return value != null ? value : DEFAULT_GROUP; } private Class getAttributeClass(String type) throws XDocletException { // System.out.println("type = " + type); Class clazz = null; try { clazz = Class.forName(type); } catch (ClassNotFoundException e) { int lastDotPosition = type.lastIndexOf('.'); if (lastDotPosition < 0) { // probably a primitive return null; } type = type.substring(0, lastDotPosition) + "$" + type.substring(lastDotPosition + 1); try { clazz = Class.forName(type); } catch (ClassNotFoundException e1) { throw new XDocletException(e1.getMessage()); } } return clazz; } /** * @param cur_class * @return * @exception XDocletException * @todo refactor to cache methods per class, and save some time */ private XMethod[] getAttributeMethods(XClass cur_class) throws XDocletException { // Use Ant's own introspection mechanism to gather the // attributes this class supports IntrospectionHelper is = null; try { is = IntrospectionHelper.getHelper(Class.forName(cur_class.getQualifiedName())); } catch (ClassNotFoundException e) { throw new XDocletException(e, e.getMessage()); } // Regroup the attributes, since IntrospectionHelper // doesn't give us the whole data structure directly Enumeration enum = is.getAttributes(); Properties attributeTypeMap = new Properties(); while (enum.hasMoreElements()) { String name = (String) enum.nextElement(); Class type = is.getAttributeType(name); attributeTypeMap.setProperty(name, type.getName()); // System.out.println(name + " = " + type.getName()); } // We need to return XMethod[] from this method // so get all methods from the current class XMethod[] allMethods = getMethods(cur_class); // System.out.println("allMethods = " + allMethods.length); // And now filter the methods based // on what IntrospectionHelper says List attributeMethods = new ArrayList(); for (int i = 0; i < allMethods.length; i++) { XMethod method = allMethods[i]; String methodName = method.getName(); // System.out.println("methodName = " + methodName); if (!methodName.startsWith("set")) { continue; } String attributeName = methodName.substring(3).toLowerCase(); // System.out.println("attributeName = " + attributeName); if ((method.getParameters().size() != 1) || (!method.isPublic())) { continue; } String attributeType = XCollections.parameterIterator(method.getParameters()).next().getType().getQualifiedName(); // System.out.println("attributeType = " + attributeType); String mapAttribute = attributeTypeMap.getProperty(attributeName); if (mapAttribute == null) { continue; } // inner classes are noted with $ in our map, but not // n the parameter type name. if (!attributeType.equals(mapAttribute.replace('$', '.'))) { continue; } // System.out.println(methodName + " : " + attributeName + " : " + attributeType); attributeMethods.add(method); } return (XMethod[]) attributeMethods.toArray(new XMethod[0]); } /** * @param cur_class * @return * @exception XDocletException * @todo add checks for number parameters and appropriate return value check for proper * exception too? method prefixes: add, create, addConfigured (but not addText) * @todo add DynamicConfigurator (this should be noted in the template, not dealt with here) */ private XMethod[] getElementMethods(XClass cur_class) throws XDocletException { // Use Ant's own introspection mechanism to gather the // elements this class supports IntrospectionHelper is = null; try { is = IntrospectionHelper.getHelper(Class.forName(cur_class.getQualifiedName())); } catch (ClassNotFoundException e) { throw new XDocletException(e.getMessage()); } // Regroup the elements, since IntrospectionHelper // doesn't give us the whole data structure directly Enumeration enum = is.getNestedElements(); Properties elementTypeMap = new Properties(); while (enum.hasMoreElements()) { String name = (String) enum.nextElement(); Class type = is.getElementType(name); elementTypeMap.setProperty(name, type.getName()); // System.out.println(name + " = " + type.getName()); } // We need to return MethodDoc[] from this method // so get all methods from the current class XMethod[] allMethods = getMethods(cur_class); // And now filter the MethodDoc's based // on what IntrospectionHelper says List elementMethods = new ArrayList(); for (int i = 0; i < allMethods.length; i++) { XMethod method = allMethods[i]; String methodName = method.getName(); // Object create(), void add(Object), void addConfigured(Object) String elementName = null; // true if addXXX or addConfiguredXXX boolean adder = false; if (methodName.startsWith("create")) { elementName = methodName.substring(6).toLowerCase(); } if (methodName.startsWith("add")) { int length = 3; if (methodName.startsWith("addConfigured")) { length = 13; } elementName = methodName.substring(length).toLowerCase(); adder = true; } if (elementName == null) { continue; } // System.out.println("elementName = " + elementName); String elementType = null; if (adder) { if (method.getParameters().size() != 1) { continue; } elementType = XCollections.parameterIterator(method.getParameters()).next().getType().getQualifiedName(); } else { elementType = method.getReturnType().getType().getQualifiedName(); } if (!method.isPublic()) { continue; } String mapElementType = elementTypeMap.getProperty(elementName); // System.out.println("elementType = " + elementType + " mapElementType = " + mapElementType); if (mapElementType == null) { continue; } // inner classes are noted with $ in our map, but not // the parameter type name. if (!elementType.equals(mapElementType.replace('$', '.'))) { continue; } elementMethods.add(method); } return (XMethod[]) elementMethods.toArray(new XMethod[0]); } /** * This is a slightly refactored (thank you IntelliJ) version of some cut-and-paste from XDoclet code. It sorts all * methods together rather than in batches of superclasses like XDoclet stuff does. * * @param cur_class * @return * @exception XDocletException */ private XMethod[] getMethods(XClass cur_class) throws XDocletException { Map already = new HashMap(); List methods = new ArrayList(); while (cur_class != null) { // hardcoded to stop when it hits Task, nothing there // or above that needs to be processed if (cur_class.getQualifiedName().equals("org.apache.tools.ant.Task") || cur_class.getQualifiedName().equals("org.apache.tools.ant.taskdefs.MatchingTask")) { break; } Collection curMethods = cur_class.getMethods(); Iterator iter = curMethods.iterator(); while (iter.hasNext()) { XMethod method = (XMethod) iter.next(); if (isDeprecated(method)) { continue; } if (shouldIgnore(method)) { continue; } String methodName = method.getName(); // System.out.println("method = " + method + ":" + methodName); if (method.getContainingClass() == cur_class) { if (already.containsKey(methodName) == false) { already.put(methodName, method); methods.add(method); } } } cur_class = cur_class.getSuperclass(); } return sortMethods(methods); } private boolean isDeprecated(XMethod method) { Collection tags = method.getDoc().getTags(); Iterator iter = tags.iterator(); while (iter.hasNext()) { XTag tag = (XTag) iter.next(); if (tag.getName().equals("@deprecated")) { return true; } } return false; } /** * Provides the element type for the current method. If the return type is null, the first parameter is used. * * @return */ private XClass elementClassDoc() { XClass clazz = null; String methodName = getCurrentMethod().getName(); if (methodName.startsWith("addConfigured") || methodName.startsWith("add") || methodName.startsWith("create")) { clazz = getCurrentMethod().getReturnType().getType(); if ("void".equals(clazz.getName())) { Collection params = getCurrentMethod().getParameters(); if (params.size() == 1) { clazz = XCollections.parameterIterator(params).next().getType(); } } } // System.out.println(methodName + ": clazz = " + clazz.getQualifiedName()); return clazz; } /** * For now, lump attributes and elements together since we won't have those tags on the same method. * * @param method * @return True if the method should be ignored. */ private boolean shouldIgnore(XMethod method) { String value = method.getDoc().getTagAttributeValue("ant.attribute", "ignore"); if ("true".equals(value)) { return true; } value = method.getDoc().getTagAttributeValue("ant.element", "ignore"); if ("true".equals(value)) { return true; } return false; } private XMethod[] sortMethods(List methods) { //sort methods Collections.sort(methods, new Comparator() { public int compare(Object o1, Object o2) { XMethod m1 = (XMethod) o1; XMethod m2 = (XMethod) o2; return m1.getName().compareTo(m2.getName()); } public boolean equals(Object obj) { //dumb return obj == this; } }); return (XMethod[]) methods.toArray(new XMethod[0]); } } 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/resources/task_xml.xdt Index: task_xml.xdt =================================================================== <task name="<XDtAnt:taskName/>" category="<XDtAnt:categoryName/>" classname="<XDtClass:fullClassName/>" <XDtClass:ifHasClassTag tagName="deprecated">deprecated="true"</XDtClass:ifHasClassTag> <XDtType:ifIsOfType type="org.apache.tools.ant.taskdefs.MatchingTask">matchingTask="true"</XDtType:ifIsOfType>> <XDtMerge:merge file="{0}.xml" generateMergedFile="false"> <!-- no merge file present --> </XDtMerge:merge> <short-description><![CDATA[<XDtClass:firstSentenceDescription/>]]></short-description> <long-description> <![CDATA[<XDtClass:classComment no-comment-signs="true"/>]]> </long-description> <structure> <attribute-groups> <attribute-group name="required" description="Required"> <XDtAnt:forAllAttributesInGroup group="required"> <attribute name="<XDtAnt:propertyName/>" type="<XDtParameter:forAllMethodParams><XDtParameter:methodParamType/></XDtParameter:forAllMethodParams>" <XDtMethod:ifHasMethodTag tagName="deprecated">deprecated="true"</XDtMethod:ifHasMethodTag> briefType="<XDtAnt:displayAttributeType/>"> <short-description><![CDATA[<XDtAnt:shortMethodDescription/>]]></short-description> <description><![CDATA[<XDtMethod:methodComment no-comment-signs="true"/>]]></description> </attribute> </XDtAnt:forAllAttributesInGroup> </attribute-group> <XDtAnt:forAllAttributeGroups> <attribute-group name="<XDtAnt:attributeGroupName/>" description="<XDtAnt:attributeGroupDesc/>"> <XDtAnt:forAllAttributesInGroup group="<XDtAnt:attributeGroupName/>"> <attribute name="<XDtAnt:propertyName/>" type="<XDtParameter:forAllMethodParams><XDtParameter:methodParamType/></XDtParameter:forAllMethodParams>" <XDtMethod:ifHasMethodTag tagName="deprecated">deprecated="true"</XDtMethod:ifHasMethodTag> briefType="<XDtAnt:displayAttributeType/>"> <short-description><![CDATA[<XDtAnt:shortMethodDescription/>]]></short-description> <description><![CDATA[<XDtMethod:methodComment no-comment-signs="true"/>]]></description> </attribute> </XDtAnt:forAllAttributesInGroup> </attribute-group> </XDtAnt:forAllAttributeGroups> <attribute-group name="optional" description="Optional"> <XDtAnt:forAllAttributesInGroup group="optional"> <attribute name="<XDtAnt:propertyName/>" type="<XDtParameter:forAllMethodParams><XDtParameter:methodParamType/></XDtParameter:forAllMethodParams>" <XDtMethod:ifHasMethodTag tagName="deprecated">deprecated="true"</XDtMethod:ifHasMethodTag> briefType="<XDtAnt:displayAttributeType/>"> <short-description><![CDATA[<XDtAnt:shortMethodDescription/>]]></short-description> <description><![CDATA[<XDtMethod:methodComment no-comment-signs="true"/>]]></description> </attribute> </XDtAnt:forAllAttributesInGroup> </attribute-group> </attribute-groups> <elements> <XDtAnt:forAllElements> <element name="<XDtAnt:elementName/>" type="<XDtAnt:elementType/>" <XDtMethod:ifHasMethodTag tagName="deprecated">deprecated="true"</XDtMethod:ifHasMethodTag> briefType="<XDtAnt:displayElementType/>" <XDtClass:pushClass value="<XDtAnt:elementType/>"> <XDtClass:ifIsClassAbstract>abstract="true"</XDtClass:ifIsClassAbstract>> </XDtClass:pushClass> <short-description><![CDATA[<XDtAnt:shortMethodDescription/>]]></short-description> <description> <![CDATA[<XDtMethod:methodComment no-comment-signs="true"/>]]> </description> </element> </XDtAnt:forAllElements> </elements> <XDtMethod:setCurrentMethod name="addText" parameters="java.lang.String"> <body <XDtMethod:ifHasMethodTag tagName="deprecated">deprecated="true"</XDtMethod:ifHasMethodTag>> <description><![CDATA[ <XDtMethod:methodComment no-comment-signs="true"/> ]]></description> </body> </XDtMethod:setCurrentMethod> </structure> </task> 1.1 ant/proposal/xdocs/src/org/apache/ant/xdoclet/resources/taskdef_properties.xdt Index: taskdef_properties.xdt =================================================================== <XDtAnt:forAllTasks><XDtAnt:taskName/>=<XDtClass:fullClassName/> </XDtAnt:forAllTasks>