From 3abecbb4fb32d45bfd43ab34e12901c84920b5e8 Mon Sep 17 00:00:00 2001 From: Erik Hatcher Date: Tue, 29 Apr 2003 19:42:00 +0000 Subject: [PATCH] migrated Ant XDoclet code here, to maintain it easier git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274536 13f79535-47bb-0310-9956-ffa450edef68 --- proposal/xdocs/build.xml | 23 +- .../lib/xdoclet-apache-module-1.2b3-dev.jar | Bin 56558 -> 0 bytes proposal/xdocs/metadata/xdoclet.xml | 23 + .../xdoclet/AntDocletTask.java} | 60 +- .../org/apache/ant/xdoclet/AntSubTask.java | 173 ++++ .../{tools => }/ant/xdoclet/IndexGen.java | 2 +- .../xdoclet/TaskDefPropertiesSubTask.java} | 81 +- .../xdoclet/TaskDescriptorSubTask.java} | 90 +- .../apache/ant/xdoclet/TaskTagsHandler.java | 886 ++++++++++++++++++ .../apache/ant/xdoclet/resources/task_xml.xdt | 92 ++ .../xdoclet/resources/taskdef_properties.xdt | 2 + 11 files changed, 1271 insertions(+), 161 deletions(-) delete mode 100644 proposal/xdocs/lib/xdoclet-apache-module-1.2b3-dev.jar create mode 100644 proposal/xdocs/metadata/xdoclet.xml rename proposal/xdocs/src/org/apache/{tools/ant/xdoclet/AntXDocletTask.java => ant/xdoclet/AntDocletTask.java} (67%) create mode 100644 proposal/xdocs/src/org/apache/ant/xdoclet/AntSubTask.java rename proposal/xdocs/src/org/apache/{tools => }/ant/xdoclet/IndexGen.java (99%) rename proposal/xdocs/src/org/apache/{tools/ant/xdoclet/DatatypeTagsHandler.java => ant/xdoclet/TaskDefPropertiesSubTask.java} (53%) rename proposal/xdocs/src/org/apache/{tools/ant/xdoclet/DatatypeSubTask.java => ant/xdoclet/TaskDescriptorSubTask.java} (60%) create mode 100644 proposal/xdocs/src/org/apache/ant/xdoclet/TaskTagsHandler.java create mode 100644 proposal/xdocs/src/org/apache/ant/xdoclet/resources/task_xml.xdt create mode 100644 proposal/xdocs/src/org/apache/ant/xdoclet/resources/taskdef_properties.xdt diff --git a/proposal/xdocs/build.xml b/proposal/xdocs/build.xml index 712a84f3e..42369ee28 100644 --- a/proposal/xdocs/build.xml +++ b/proposal/xdocs/build.xml @@ -384,10 +384,14 @@ - + + classname="org.apache.ant.xdoclet.AntDocletTask"> + + + + + + + + + + + + + diff --git a/proposal/xdocs/lib/xdoclet-apache-module-1.2b3-dev.jar b/proposal/xdocs/lib/xdoclet-apache-module-1.2b3-dev.jar deleted file mode 100644 index 533af957393fdd4bc9bc7d34850f0f645bca00ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56558 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 Pz)ufA85!m4>#P3 + + + + + + + + + diff --git a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/AntXDocletTask.java b/proposal/xdocs/src/org/apache/ant/xdoclet/AntDocletTask.java similarity index 67% rename from proposal/xdocs/src/org/apache/tools/ant/xdoclet/AntXDocletTask.java rename to proposal/xdocs/src/org/apache/ant/xdoclet/AntDocletTask.java index 0186f88b5..c90d8a471 100644 --- a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/AntXDocletTask.java +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/AntDocletTask.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2002 The Apache Software Foundation. All rights + * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,48 +51,30 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.tools.ant.xdoclet; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.types.FileSet; -import xdoclet.DocletTask; -import xdoclet.doc.info.InfoSubTask; -import xdoclet.doc.DocumentDocletTask; - -import java.io.File; -import java.util.Vector; - -public class AntXDocletTask extends DocumentDocletTask { - private Vector _subTasks = new Vector(); - - public void addTasks(TaskSubTask subtask) { - _subTasks.add(subtask); - } +package org.apache.ant.xdoclet; - public void addDatatypes(DatatypeSubTask subtask) { - _subTasks.add(subtask); - } +import org.apache.tools.ant.BuildException; - /** - * Borrowed a bit from Darrell DeBoer's myrmidon stuff (thanks Darrell!) - */ - public void execute() throws BuildException { - // Add the base directories of all the filesets to the sourcepath - final Vector filesets = getFilesets(); - for (int i = 0; i < filesets.size(); i++) { - final FileSet fileSet = (FileSet) filesets.elementAt(i); - final File basedir = fileSet.getDir(project); - createSourcepath().setLocation(basedir); - } +import xdoclet.DocletTask; - super.execute(); +/** + * @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 Vector getSubTasks() { - Vector subtasks = super.getSubTasks(); - - subtasks.addAll(_subTasks); - - return subtasks; + protected void validateOptions() throws BuildException + { + super.validateOptions(); + checkClass("org.apache.tools.ant.IntrospectionHelper"); } -} \ No newline at end of file +} diff --git a/proposal/xdocs/src/org/apache/ant/xdoclet/AntSubTask.java b/proposal/xdocs/src/org/apache/ant/xdoclet/AntSubTask.java new file mode 100644 index 000000000..7230ac6e0 --- /dev/null +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/AntSubTask.java @@ -0,0 +1,173 @@ +/* + * 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 apache@apache.org. + * + * 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 + * . + */ +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; + } +} diff --git a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/IndexGen.java b/proposal/xdocs/src/org/apache/ant/xdoclet/IndexGen.java similarity index 99% rename from proposal/xdocs/src/org/apache/tools/ant/xdoclet/IndexGen.java rename to proposal/xdocs/src/org/apache/ant/xdoclet/IndexGen.java index 2b69460fb..a7f6f5962 100644 --- a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/IndexGen.java +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/IndexGen.java @@ -52,7 +52,7 @@ * . */ -package org.apache.tools.ant.xdoclet; +package org.apache.ant.xdoclet; import org.apache.tools.ant.Task; import org.apache.tools.ant.BuildException; diff --git a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/DatatypeTagsHandler.java b/proposal/xdocs/src/org/apache/ant/xdoclet/TaskDefPropertiesSubTask.java similarity index 53% rename from proposal/xdocs/src/org/apache/tools/ant/xdoclet/DatatypeTagsHandler.java rename to proposal/xdocs/src/org/apache/ant/xdoclet/TaskDefPropertiesSubTask.java index d69c99dcc..283132e52 100644 --- a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/DatatypeTagsHandler.java +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/TaskDefPropertiesSubTask.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2002 The Apache Software Foundation. All rights + * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,75 +51,28 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.tools.ant.xdoclet; -import com.sun.javadoc.ClassDoc; -import com.sun.javadoc.MethodDoc; -import com.sun.javadoc.Parameter; -import com.sun.javadoc.Type; +package org.apache.ant.xdoclet; -import xdoclet.XDocletException; -import xdoclet.XDocletTagSupport; -import xdoclet.tags.AbstractProgramElementTagsHandler; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; +import xdoclet.TemplateSubTask; /** - * Custom tag handler for XDoclet templates for Ant-specific processing. - * - * @author Erik Hatcher - * @created February 17, 2002 + * Generates Ant taskdef properties files, suitable for bulk defining tasks with Ant's <taskdef> task. * - * @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 + * @author Erik Hatcher (ehatcher@apache.org) + * @created January 5, 2003 + * @ant.element display-name="taskdefproperties" name="taskdefproperties" + * parent="org.apache.ant.xdoclet.AntDocletTask" + * @ant.task ignore="true" + * @version $Revision$ */ -public class DatatypeTagsHandler extends XDocletTagSupport { - - /** - * Iterates over all Ant datatypes - */ - public void forAllDatatypes(String template, Properties attributes) throws XDocletException { - ClassDoc[] classes = AbstractProgramElementTagsHandler.getAllClasses(); - ClassDoc cur_class = null; - - for (int i = 0; i < classes.length; i++) { - cur_class = classes[i]; - setCurrentClass(cur_class); - - if (DatatypeSubTask.isAntDatatype(cur_class)) { - generate(template); - } - } - } +public class TaskDefPropertiesSubTask extends AntSubTask +{ + protected static String DEFAULT_TEMPLATE_FILE = "resources/taskdef_properties.xdt"; - /** - * Provides the datatype name - */ - public String typeName() throws XDocletException { - return getDatatypeName(getCurrentClass()); - } - - public static final String getDatatypeName(ClassDoc clazz) throws XDocletException { - // sheesh! There should be a friendlier method than this! - String tagValue = getTagValue(clazz, "ant:datatype", "name", -1, - null, null, null, null, - null, false, XDocletTagSupport.FOR_CLASS, false); - - if (tagValue == null) { - tagValue = clazz.name(); - - tagValue = tagValue.toLowerCase(); - } - return tagValue; + public TaskDefPropertiesSubTask() + { + setTemplateURL(getClass().getResource(DEFAULT_TEMPLATE_FILE)); + setDestinationFile("taskdef.properties"); } } - diff --git a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/DatatypeSubTask.java b/proposal/xdocs/src/org/apache/ant/xdoclet/TaskDescriptorSubTask.java similarity index 60% rename from proposal/xdocs/src/org/apache/tools/ant/xdoclet/DatatypeSubTask.java rename to proposal/xdocs/src/org/apache/ant/xdoclet/TaskDescriptorSubTask.java index 1db35673c..486e332b4 100644 --- a/proposal/xdocs/src/org/apache/tools/ant/xdoclet/DatatypeSubTask.java +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/TaskDescriptorSubTask.java @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2002 The Apache Software Foundation. All rights + * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,71 +51,57 @@ * information on the Apache Software Foundation, please see * . */ -package org.apache.tools.ant.xdoclet; -import com.sun.javadoc.ClassDoc; +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.tags.TypeTagsHandler; import xdoclet.util.TypeConversionUtil; -import java.io.File; -import java.text.MessageFormat; - /** - * Custom XDoclet subtask to handle Ant datatypes + * Generates Ant task descriptors. + * + * @author Erik Hatcher (ehatcher@apache.org) + * @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$ + * @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 DatatypeSubTask extends TemplateSubTask { - public final static String SUBTASK_NAME = "datatypes"; - - public String getSubTaskName() { - return SUBTASK_NAME; - } - - /** - * Returns true if the class is an Ant task. This causes the task to be processed - * by the XDoclet template task. - */ - protected boolean matchesGenerationRules(ClassDoc clazz) throws XDocletException { - return isAntDatatype(clazz); - } - - /** - * @todo a datatype doesn't have to extend Datatype, right? so perhaps should - * another condition to flag a class with @ant.datatype name="..." - */ - public static final boolean isAntDatatype(ClassDoc clazz) throws XDocletException { - if (clazz.isAbstract()) { - return false; - } - - // no inner classes - if (clazz.containingClass() != null) { - return false; - } - - String ignoreValue = XDocletTagSupport.getClassTagValue(clazz, "ant:datatype", "ignore", 0, null, "false", false, false); - boolean ignore = TypeConversionUtil.stringToBoolean(ignoreValue, true); +public class TaskDescriptorSubTask extends AntSubTask +{ + protected static String DEFAULT_TEMPLATE_FILE = "resources/task_xml.xdt"; - if (ignore) { - return false; - } - - return TypeTagsHandler.isOfType(clazz, - "org.apache.tools.ant.types.DataType", - TypeTagsHandler.TYPE_HIERARCHY); + 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. + * Custom file naming. Use the task name for the file name rather than the default class name. * - * @todo fix hardcoded path name + * @param clazz + * @return + * @exception XDocletException */ - protected String getGeneratedFileName(ClassDoc clazz) throws XDocletException { - String typeName = DatatypeTagsHandler.getDatatypeName(clazz); - return typeName + ".xml"; + protected String getGeneratedFileName(XClass clazz) throws XDocletException + { + String dir = TaskTagsHandler.getCategoryName(clazz); + String taskName = TaskTagsHandler.getTaskName(clazz); + + return new File(dir, taskName + ".xml").toString(); } } diff --git a/proposal/xdocs/src/org/apache/ant/xdoclet/TaskTagsHandler.java b/proposal/xdocs/src/org/apache/ant/xdoclet/TaskTagsHandler.java new file mode 100644 index 000000000..1a5d29063 --- /dev/null +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/TaskTagsHandler.java @@ -0,0 +1,886 @@ +/* + * 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 apache@apache.org. + * + * 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 + * . + */ + +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: + *
    + *
  1. Value of + * + * @param clazz + * @return + * @ant:task name="..."
  2. + *
  3. Lowercased classname with "Task" suffix removed
  4. + *
+ * + */ + 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 = ""; + + 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]); + } +} + diff --git a/proposal/xdocs/src/org/apache/ant/xdoclet/resources/task_xml.xdt b/proposal/xdocs/src/org/apache/ant/xdoclet/resources/task_xml.xdt new file mode 100644 index 000000000..ec4564a19 --- /dev/null +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/resources/task_xml.xdt @@ -0,0 +1,92 @@ +deprecated="true" + matchingTask="true"> + + + + + + ]]> + + ]]> + + + + + + + + + deprecated="true" + briefType=""> + ]]> + ]]> + + + + + + + + deprecated="true" + briefType=""> + ]]> + ]]> + + + + + + + + deprecated="true" + briefType=""> + ]]> + ]]> + + + + + + + + + + deprecated="true" + briefType="" + + abstract="true"> + + ]]> + + ]]> + + + + + + + + deprecated="true"> + + ]]> + + + + + + + + diff --git a/proposal/xdocs/src/org/apache/ant/xdoclet/resources/taskdef_properties.xdt b/proposal/xdocs/src/org/apache/ant/xdoclet/resources/taskdef_properties.xdt new file mode 100644 index 000000000..09d21c4d1 --- /dev/null +++ b/proposal/xdocs/src/org/apache/ant/xdoclet/resources/taskdef_properties.xdt @@ -0,0 +1,2 @@ += +