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 &lt;taskdef&gt; 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 
&lt;property&gt;");
          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 += "&quot;" + values[i] + "&quot;";
                      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>
  
  
  

Reply via email to