An early implementation of a jellydoc plugin.
The idea behind this plugin is to generate javadoc-like documentation for Jelly tags. Now there are various projects which define their own library (or libraries) of Jelly tags. So this code which used to reside inside the Jelly build has now been refactored into a Maven plugin.
To add it to your build just add this to your maven.xml
<preGoal name="site">
<attainGoal name="jellydoc"/>
</preGoal>
Its still fairly simple and basic right now. Its using a doclet (rather than xdoclet or qdox) and doesn't handle DynaTag implementations very well - so I'm sure we can improve this over time. However for now this might help other projects (like Maven itself as well as other projects like Latka, Drools, Werkflow etc) create auto-generated documentation for their tags.
git-svn-id: https://svn.apache.org/repos/asf/maven/maven-1/plugins/trunk@112852 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
1 parent
cfdd9154c4
commit
46d3cf7bfd
12 files changed
+1545
No files matched your search
@@ -0,0 +1,3 @@
|
||||
target
|
||||
velocity.log
|
||||
maven.log
|
||||
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<project
|
||||
xmlns:j="jelly:core"
|
||||
xmlns:maven="jelly:maven"
|
||||
xmlns:m="maven">
|
||||
|
||||
<!-- ================================================================== -->
|
||||
<!-- GENERATE THE XML DOCUMENTATION -->
|
||||
<!-- ================================================================== -->
|
||||
<goal name="jellydoc" prereqs="jellydoc:doclet, create-classpath"
|
||||
description="Generates the tag documentation">
|
||||
|
||||
<mkdir dir="${maven.build.dir}/generated-xdocs"/>
|
||||
|
||||
<j:file name="${maven.build.dir}/generated-xdocs/tags.xml">
|
||||
|
||||
<!-- the following should be way easier - j:include should support files -->
|
||||
<j:new var="file" className="java.io.File">
|
||||
<j:arg value="${plugin.resources}/${plugin.artifactId}.jelly"/>
|
||||
</j:new>
|
||||
|
||||
<!--
|
||||
<echo>About to include ${file.toURL()}</echo>
|
||||
-->
|
||||
|
||||
<j:include uri="${file.toURL().toString()}"/>
|
||||
</j:file>
|
||||
</goal>
|
||||
|
||||
<!-- runs the Tag doclet -->
|
||||
<goal name="jellydoc:doclet" prereqs="jellydoc:init"
|
||||
description="A doclet which outputs all the Jelly tag related metadata as XML">
|
||||
|
||||
<j:if test="${context.getVariable('maven.jellydoc.packages') == null}">
|
||||
<j:set var="maven.jellydoc.packages" value="${pom.package}.*"/>
|
||||
</j:if>
|
||||
|
||||
<echo>Generating jellydoc for packages ${maven.jellydoc.packages}</echo>
|
||||
|
||||
<javadoc
|
||||
sourcepath="${pom.build.sourceDirectory}"
|
||||
packagenames="${maven.jellydoc.packages}"
|
||||
docletpathref="doclet.classpath"
|
||||
doclet="org.apache.maven.jellydoc.TagXMLDoclet">
|
||||
</javadoc>
|
||||
|
||||
</goal>
|
||||
|
||||
<!-- runs the XML doclet -->
|
||||
<goal name="jellydoc:xml-doclet" prereqs="jellydoc:init"
|
||||
description="Creates an XML representation of the doclet information">
|
||||
|
||||
<javadoc
|
||||
sourcepath="${pom.build.sourceDirectory}"
|
||||
packagenames="${pom.package}.*"
|
||||
docletpathref="doclet.classpath"
|
||||
doclet="org.apache.maven.jellydoc.XMLDoclet">
|
||||
</javadoc>
|
||||
|
||||
</goal>
|
||||
|
||||
|
||||
<!-- sets the classpath used for doclet invocations -->
|
||||
<goal name="jellydoc:init">
|
||||
<path id="doclet.classpath">
|
||||
<path refid="maven.dependency.classpath"/>
|
||||
<pathelement path="${plugin.dir}"/>
|
||||
<pathelement path="${plugin.getDependencyPath('javadoc')}"/>
|
||||
<pathelement path="${plugin.getDependencyPath('nekohtml')}"/>
|
||||
<pathelement path="${plugin.getDependencyPath('dom4j')}"/>
|
||||
<pathelement path="${plugin.getDependencyPath('xerces')}"/>
|
||||
<pathelement path="${plugin.getDependencyPath('xml-apis')}"/>
|
||||
</path>
|
||||
</goal>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,11 @@
|
||||
# -------------------------------------------------------------------
|
||||
# P L U G I N P R O P E R I E S
|
||||
# -------------------------------------------------------------------
|
||||
# Activity log plugin.
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
maven.build.dir = ${basedir}/target
|
||||
|
||||
maven.docs.outputencoding = ISO-8859-1
|
||||
|
||||
maven.activitylog.range = 30
|
||||
@@ -0,0 +1,95 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<project>
|
||||
|
||||
<extend>${basedir}/../project.xml</extend>
|
||||
<pomVersion>3</pomVersion>
|
||||
<id>maven-jellydoc-plugin</id>
|
||||
<name>Maven JellyDoc Plug-in</name>
|
||||
<currentVersion>1.0-SNAPSHOT</currentVersion>
|
||||
|
||||
<!-- Gump integration -->
|
||||
<gumpRepositoryId>jakarta</gumpRepositoryId>
|
||||
|
||||
<description>
|
||||
Creates a JavaDoc like report for any Jelly Tags used in a project.
|
||||
</description>
|
||||
|
||||
<shortDescription></shortDescription>
|
||||
|
||||
<url>http://jakarta.apache.org/turbine/maven/reference/plugins/jellydoc/</url>
|
||||
<issueTrackingUrl>http://jira.werken.com/BrowseProject.jspa?id=10030</issueTrackingUrl>
|
||||
<siteAddress>jakarta.apache.org</siteAddress>
|
||||
<siteDirectory>/www/jakarta.apache.org/turbine/maven/reference/plugins/jellydoc/</siteDirectory>
|
||||
<distributionDirectory>/www/jakarta.apache.org/builds/jakarta-turbine-maven/</distributionDirectory>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>James Strachan</name>
|
||||
<id>jstrachan</id>
|
||||
<email>jstrachan@apache.org</email>
|
||||
<organization>SpiritSoft, Inc.</organization>
|
||||
<roles>
|
||||
<role>Java Developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-jelly</groupId>
|
||||
<artifactId>commons-jelly-tags-jsl</artifactId>
|
||||
<version>SNAPSHOT</version>
|
||||
<url>http://jakarta.apache.org/commons/jelly/tags/jsl/</url>
|
||||
<properties>
|
||||
<classloader>root.maven</classloader>
|
||||
</properties>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-jelly</groupId>
|
||||
<artifactId>commons-jelly-tags-xml</artifactId>
|
||||
<version>SNAPSHOT</version>
|
||||
<url>http://jakarta.apache.org/commons/jelly/tags/xml/</url>
|
||||
<properties>
|
||||
<classloader>root.maven</classloader>
|
||||
</properties>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<id>javadoc</id>
|
||||
<version>1.3</version>
|
||||
<properties>
|
||||
<classloader>root.maven</classloader>
|
||||
</properties>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<id>nekohtml</id>
|
||||
<version>0.7.1</version>
|
||||
<properties>
|
||||
<classloader>root.maven</classloader>
|
||||
</properties>
|
||||
</dependency>
|
||||
|
||||
<!-- core dependencies which i'd have thought Maven introduced -->
|
||||
<dependency>
|
||||
<id>dom4j</id>
|
||||
<version>1.4-dev-8</version>
|
||||
<url>http://www.dom4j.org/</url>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<id>xml-apis</id>
|
||||
<version>1.0.b2</version>
|
||||
<url>http://xml.apache.org/xerces2-j/</url>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<id>xerces</id>
|
||||
<version>2.2.1</version>
|
||||
<url>http://xml.apache.org/xerces2-j/</url>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* /home/cvs/maven-plugins/jellydoc/src/main/org/apache/maven/jellydoc/TagXMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp
|
||||
* 1.1
|
||||
* 2003/02/07 12:10:44
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
* Copyright (c) 2002 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", "Commons", 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
* TagXMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp
|
||||
*/
|
||||
|
||||
package org.apache.maven.jellydoc;
|
||||
|
||||
import java.beans.Introspector;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
|
||||
import org.cyberneko.html.parsers.SAXParser;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import com.sun.javadoc.ClassDoc;
|
||||
import com.sun.javadoc.Doc;
|
||||
import com.sun.javadoc.Doclet;
|
||||
import com.sun.javadoc.MethodDoc;
|
||||
import com.sun.javadoc.PackageDoc;
|
||||
import com.sun.javadoc.Parameter;
|
||||
import com.sun.javadoc.RootDoc;
|
||||
import com.sun.javadoc.SeeTag;
|
||||
import com.sun.javadoc.Tag;
|
||||
|
||||
/**
|
||||
* Main Doclet class to generate Tag Library ML.
|
||||
*
|
||||
* @author <a href="mailto:gopi@aztecsoft.com">Gopinath M.R.</a>
|
||||
* @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
|
||||
* @author Rodney Waldhoff
|
||||
*/
|
||||
|
||||
// #### somehow we need to handle taglib inheritence...
|
||||
|
||||
public class TagXMLDoclet extends Doclet {
|
||||
|
||||
private String xmlns = "jvx";
|
||||
private String encodingFormat="UTF-8";
|
||||
private String localName = "javadoc";
|
||||
private ContentHandler cm = null;
|
||||
private String targetFileName="target/taglib.xml";
|
||||
private Attributes emptyAtts = new AttributesImpl();
|
||||
|
||||
public TagXMLDoclet (RootDoc root) throws Exception {
|
||||
FileOutputStream writer = new FileOutputStream(targetFileName);
|
||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||
XMLWriter xmlWriter = new XMLWriter(writer, format);
|
||||
try {
|
||||
cm = xmlWriter;
|
||||
cm.startDocument();
|
||||
javadocXML(root);
|
||||
cm.endDocument();
|
||||
xmlWriter.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
xmlWriter.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the xml for the tag libraries
|
||||
*/
|
||||
private void javadocXML(RootDoc root) throws SAXException {
|
||||
cm.startElement(xmlns, localName, "tags", emptyAtts);
|
||||
PackageDoc[] packageArray = root.specifiedPackages();
|
||||
|
||||
// Generate for packages.
|
||||
for (int i = 0; i < packageArray.length; ++i) {
|
||||
packageXML(packageArray[i]);
|
||||
}
|
||||
|
||||
cm.endElement(xmlns, localName, "tags");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for a tag library
|
||||
*/
|
||||
private void packageXML(PackageDoc packageDoc) throws SAXException {
|
||||
ClassDoc[] classArray = packageDoc.ordinaryClasses();
|
||||
|
||||
// lets see if we find a Tag
|
||||
boolean foundTag = false;
|
||||
for (int i = 0; i < classArray.length; ++i) {
|
||||
ClassDoc classDoc = classArray[i];
|
||||
if ( isTag( classArray[i] ) ) {
|
||||
foundTag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( ! foundTag ) {
|
||||
return;
|
||||
}
|
||||
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", packageDoc.name());
|
||||
|
||||
String name = packageDoc.name();
|
||||
int idx = name.lastIndexOf('.');
|
||||
if ( idx > 0 ) {
|
||||
name = name.substring(idx+1);
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "prefix", "String", name);
|
||||
|
||||
String uri = "jelly:" + name;
|
||||
|
||||
atts.addAttribute(xmlns, localName, "uri", "String", uri );
|
||||
cm.startElement(xmlns, localName, "library", atts);
|
||||
|
||||
// generate Doc element.
|
||||
docXML(packageDoc);
|
||||
|
||||
// generate tags
|
||||
for (int i = 0; i < classArray.length; ++i) {
|
||||
if ( isTag( classArray[i] ) ) {
|
||||
tagXML(classArray[i]);
|
||||
}
|
||||
}
|
||||
cm.endElement(xmlns, localName, "library");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this class is a Jelly Tag
|
||||
*/
|
||||
private boolean isTag(ClassDoc classDoc) {
|
||||
ClassDoc[] interfaceArray = classDoc.interfaces();
|
||||
for (int i = 0; i < interfaceArray.length; ++i) {
|
||||
String name = interfaceArray[i].qualifiedName();
|
||||
if ("org.apache.commons.jelly.Tag".equals(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
ClassDoc base = classDoc.superclass();
|
||||
if ( base != null ) {
|
||||
return isTag(base);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for a tag
|
||||
*/
|
||||
private void tagXML(ClassDoc classDoc) throws SAXException {
|
||||
if (classDoc.isAbstract()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "className", "String", classDoc.name());
|
||||
String name = classDoc.name();
|
||||
if ( name.endsWith( "Tag" ) ) {
|
||||
name = name.substring(0, name.length() - 3 );
|
||||
}
|
||||
name = Introspector.decapitalize(name);
|
||||
|
||||
atts.addAttribute(xmlns, localName, "name", "String", name);
|
||||
cm.startElement(xmlns, localName, "tag", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(classDoc);
|
||||
|
||||
// generate the attributes
|
||||
propertiesXML(classDoc);
|
||||
|
||||
// generate "method" sub-elements
|
||||
cm.endElement(xmlns, localName, "tag");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for a tag property
|
||||
*/
|
||||
private void propertiesXML(ClassDoc classDoc) throws SAXException {
|
||||
MethodDoc[] methodArray = classDoc.methods();
|
||||
for (int i = 0; i < methodArray.length; ++i) {
|
||||
propertyXML(methodArray[i]);
|
||||
}
|
||||
ClassDoc base = classDoc.superclass();
|
||||
if ( base != null ) {
|
||||
propertiesXML( base );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates doc for a tag property
|
||||
*/
|
||||
private void propertyXML(MethodDoc methodDoc) throws SAXException {
|
||||
if ( ! methodDoc.isPublic() || methodDoc.isStatic() ) {
|
||||
return;
|
||||
}
|
||||
String name = methodDoc.name();
|
||||
if ( ! name.startsWith( "set" ) ) {
|
||||
return;
|
||||
}
|
||||
Parameter[] parameterArray = methodDoc.parameters();
|
||||
if ( parameterArray == null || parameterArray.length != 1 ) {
|
||||
return;
|
||||
}
|
||||
Parameter parameter = parameterArray[0];
|
||||
|
||||
name = name.substring(3);
|
||||
name = Introspector.decapitalize(name);
|
||||
|
||||
if ( name.equals( "body") || name.equals( "context" ) || name.equals( "parent" ) ) {
|
||||
return;
|
||||
}
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", name);
|
||||
atts.addAttribute(xmlns, localName, "type", "String", parameter.typeName());
|
||||
|
||||
cm.startElement(xmlns, localName, "attribute", atts);
|
||||
|
||||
// maybe do more semantics, like use custom tags to denote if its required, optional etc.
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(methodDoc);
|
||||
|
||||
cm.endElement(xmlns, localName, "attribute");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "doc"
|
||||
*/
|
||||
private void docXML(Doc doc) throws SAXException {
|
||||
cm.startElement(xmlns, localName, "doc", emptyAtts);
|
||||
// handle the "comment" part, including {@link} tags
|
||||
{
|
||||
Tag[] tags = doc.inlineTags();
|
||||
for(int i=0;i<tags.length;i++) {
|
||||
// if tags[i] is an @link tag
|
||||
if(tags[i] instanceof SeeTag) {
|
||||
String label = ((SeeTag)tags[i]).label();
|
||||
// if the label is null or empty, use the class#member part of the link
|
||||
if(null == label || "".equals(label)) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
String className = ((SeeTag)tags[i]).referencedClassName();
|
||||
if("".equals(className)) { className = null; }
|
||||
String memberName = ((SeeTag)tags[i]).referencedMemberName();
|
||||
if("".equals(memberName)) { memberName = null; }
|
||||
if(null != className) {
|
||||
buf.append(className);
|
||||
if(null != memberName) {
|
||||
buf.append(".");
|
||||
}
|
||||
}
|
||||
if(null != memberName) {
|
||||
buf.append(memberName);
|
||||
}
|
||||
label = buf.toString();
|
||||
}
|
||||
parseHTML(label);
|
||||
} else {
|
||||
parseHTML(tags[i].text());
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle the "tags" part
|
||||
{
|
||||
Tag[] tags = doc.tags();
|
||||
for (int i = 0; i < tags.length; ++i) {
|
||||
javadocTagXML(tags[i]);
|
||||
}
|
||||
}
|
||||
cm.endElement(xmlns, localName, "doc");
|
||||
}
|
||||
|
||||
protected void parseHTML(String text) throws SAXException {
|
||||
SAXParser parser = new SAXParser();
|
||||
parser.setProperty(
|
||||
"http://cyberneko.org/html/properties/names/elems",
|
||||
"lower"
|
||||
);
|
||||
parser.setProperty(
|
||||
"http://cyberneko.org/html/properties/names/attrs",
|
||||
"lower"
|
||||
);
|
||||
parser.setContentHandler(
|
||||
new DefaultHandler() {
|
||||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
|
||||
if ( validDocElementName( localName ) ) {
|
||||
cm.startElement(namespaceURI, localName, qName, atts);
|
||||
}
|
||||
}
|
||||
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
|
||||
if ( validDocElementName( localName ) ) {
|
||||
cm.endElement(namespaceURI, localName, qName);
|
||||
}
|
||||
}
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
cm.characters(ch, start, length);
|
||||
}
|
||||
}
|
||||
);
|
||||
try {
|
||||
parser.parse( new InputSource(new StringReader( text )) );
|
||||
}
|
||||
catch (IOException e) {
|
||||
System.err.println( "This should never happen!" + e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the given name is a valid HTML markup element.
|
||||
*/
|
||||
protected boolean validDocElementName(String name) {
|
||||
return ! name.equalsIgnoreCase( "html" ) && ! name.equalsIgnoreCase( "body" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for all tag elements.
|
||||
*/
|
||||
private void javadocTagXML(Tag tag) throws SAXException {
|
||||
String name = tag.name().substring(1) + "tag";
|
||||
if (! tag.text().equals("")) {
|
||||
cm.startElement(xmlns, localName, name, emptyAtts);
|
||||
cm.characters(tag.text().toCharArray(), 0, tag.text().length());
|
||||
cm.endElement(xmlns, localName, name);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean start(RootDoc root) {
|
||||
try {
|
||||
new TagXMLDoclet(root);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,707 @@
|
||||
/*
|
||||
* /home/cvs/maven-plugins/jellydoc/src/main/org/apache/maven/jellydoc/XMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp
|
||||
* 1.1
|
||||
* 2003/02/07 12:10:44
|
||||
*
|
||||
* ====================================================================
|
||||
*
|
||||
* The Apache Software License, Version 1.1
|
||||
*
|
||||
* Copyright (c) 2002 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", "Commons", 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
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
* XMLDoclet.java,v 1.1 2003/02/07 12:10:44 jstrachan Exp
|
||||
*/
|
||||
|
||||
package org.apache.maven.jellydoc;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import com.sun.javadoc.*;
|
||||
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
|
||||
import org.xml.sax.*;
|
||||
import org.xml.sax.helpers.*;
|
||||
|
||||
/**
|
||||
* Main Doclet class to generate JavaDocXML. This doclet generates the
|
||||
* document conforming to DTD specified in javadoc-v04draft.dtd.
|
||||
* @author <a href="mailto:gopi@aztecsoft.com">Gopinath M.R.</a>
|
||||
* @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
|
||||
*/
|
||||
|
||||
public class XMLDoclet extends Doclet {
|
||||
|
||||
private String xmlns = "jvx";
|
||||
private String encodingFormat="UTF-8";
|
||||
private String localName = "javadoc";
|
||||
private ContentHandler cm = null;
|
||||
private String targetFileName="target/javadoc.xml";
|
||||
private Attributes emptyAtts = new AttributesImpl();
|
||||
|
||||
public XMLDoclet (RootDoc root) throws Exception {
|
||||
FileOutputStream writer = new FileOutputStream(targetFileName);
|
||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||
XMLWriter xmlWriter = new XMLWriter(writer, format);
|
||||
try {
|
||||
cm = xmlWriter;
|
||||
cm.startDocument();
|
||||
javadocXML(root);
|
||||
cm.endDocument();
|
||||
xmlWriter.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
xmlWriter.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the xml data for the top element.
|
||||
* <xmp><!ELEMENT javadoc (package*, class*, interface*)></xmp>
|
||||
*/
|
||||
private void javadocXML(RootDoc root) throws SAXException {
|
||||
cm.startElement(xmlns, localName, "javadoc", emptyAtts);
|
||||
PackageDoc[] packageArray = root.specifiedPackages();
|
||||
|
||||
// Generate for packages.
|
||||
for (int i = 0; i < packageArray.length; ++i) {
|
||||
packageXML(packageArray[i]);
|
||||
}
|
||||
|
||||
// Generate for classes.
|
||||
ClassDoc[] classArray = root.specifiedClasses();
|
||||
Vector interfaceVector = new Vector();
|
||||
for (int i = 0; i < classArray.length; ++i) {
|
||||
if (classArray[i].isInterface()) {
|
||||
interfaceVector.addElement(classArray[i]);
|
||||
} else {
|
||||
classXML(classArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate for interfaces.
|
||||
Enumeration interfaceEnum = interfaceVector.elements();
|
||||
if (interfaceEnum.hasMoreElements()) {
|
||||
ClassDoc interfaceDoc = (ClassDoc)interfaceEnum.nextElement();
|
||||
interfaceXML(interfaceDoc);
|
||||
}
|
||||
cm.endElement(xmlns, localName, "javadoc");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for "package".
|
||||
* <xmp><!ELEMENT package (doc?, package*, class*, interface*)>
|
||||
*<!ATTLIST package
|
||||
* name CDATA #REQUIRED></xmp>
|
||||
*/
|
||||
private void packageXML(PackageDoc packageDoc) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", packageDoc.name());
|
||||
cm.startElement(xmlns, localName, "package", atts);
|
||||
|
||||
// generate Doc element.
|
||||
docXML(packageDoc);
|
||||
|
||||
// TODO:generate Package elements.
|
||||
// doubt: How package can exist inside a package?
|
||||
|
||||
/* Generate for classes. */
|
||||
// for ordinary classes.
|
||||
ClassDoc[] classArray = packageDoc.ordinaryClasses();
|
||||
for (int i = 0; i < classArray.length; ++i) {
|
||||
classXML(classArray[i]);
|
||||
}
|
||||
// for Exception classes.
|
||||
classArray = packageDoc.exceptions();
|
||||
for (int i = 0; i < classArray.length; ++i) {
|
||||
classXML(classArray[i]);
|
||||
}
|
||||
// for Error classes
|
||||
classArray = packageDoc.errors();
|
||||
for (int i = 0; i < classArray.length; ++i) {
|
||||
classXML(classArray[i]);
|
||||
}
|
||||
|
||||
/* Generate for interfaces. */
|
||||
ClassDoc[] interfaceArray = packageDoc.interfaces();
|
||||
for (int i = 0; i < interfaceArray.length; ++i) {
|
||||
interfaceXML(interfaceArray[i]);
|
||||
}
|
||||
|
||||
cm.endElement(xmlns, localName, "package");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "class".
|
||||
* <xmp> <!ELEMENT class (doc?,
|
||||
* extends_class?,
|
||||
* implements?,
|
||||
* constructor*,
|
||||
* method*,
|
||||
* innerclass*)>
|
||||
* <!ATTLIST class
|
||||
* %name;
|
||||
* %extensibility;
|
||||
* %class.access;></xmp>
|
||||
*/
|
||||
private void classXML(ClassDoc classDoc) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", classDoc.name());
|
||||
|
||||
String extensibility = "default";
|
||||
if (classDoc.isAbstract()) {
|
||||
extensibility = "abstract";
|
||||
} else if (classDoc.isFinal()) {
|
||||
extensibility = "final";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "extensibility", "String", extensibility);
|
||||
String access = "package";
|
||||
if (classDoc.isPublic()) {
|
||||
access = "public";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "access", "String", access);
|
||||
cm.startElement(xmlns, localName, "class", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(classDoc);
|
||||
|
||||
// generate "extends_class" sub-element
|
||||
extendsXML(classDoc);
|
||||
|
||||
// generate "implements" sub-element
|
||||
implementsXML(classDoc);
|
||||
|
||||
// generate "field" sub-elements
|
||||
FieldDoc[] fieldArray = classDoc.fields();
|
||||
for (int i = 0; i < fieldArray.length; ++i) {
|
||||
fieldXML(fieldArray[i]);
|
||||
}
|
||||
|
||||
// generate "constructor" sub-elements
|
||||
ConstructorDoc[] constructorArray = classDoc.constructors();
|
||||
for (int i = 0; i < constructorArray.length; ++i) {
|
||||
constructorXML(constructorArray[i]);
|
||||
}
|
||||
|
||||
// generate "method" sub-elements
|
||||
MethodDoc[] methodArray = classDoc.methods();
|
||||
for (int i = 0; i < methodArray.length; ++i) {
|
||||
methodXML(methodArray[i]);
|
||||
}
|
||||
|
||||
// generate "innerclass" sub-elements
|
||||
ClassDoc[] innerClassArray = classDoc.innerClasses();
|
||||
for (int i = 0; i < innerClassArray.length; ++i) {
|
||||
innerClassXML(innerClassArray[i]);
|
||||
}
|
||||
|
||||
cm.endElement(xmlns, localName, "class");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "extends_class"
|
||||
* <xmp><!ELEMENT extends_class (classref+)></xmp>
|
||||
*/
|
||||
private void extendsXML(ClassDoc classDoc) throws SAXException {
|
||||
if (classDoc.superclass() != null) {
|
||||
cm.startElement(xmlns, localName, "extends_class", emptyAtts);
|
||||
createRefXML("classref", classDoc.superclass().qualifiedName());
|
||||
cm.endElement(xmlns, localName, "extends_class");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "innerclass"
|
||||
* <xmp> <!ELEMENT innerclass (doc?,
|
||||
* extends?,
|
||||
* implements?,
|
||||
* field*,
|
||||
* constructor*,
|
||||
* method*)>
|
||||
* <!ATTLIST innerclass
|
||||
* %name;
|
||||
* %access;
|
||||
* %abstract;
|
||||
* %anonymous;
|
||||
* %final;
|
||||
* %static;></xmp>
|
||||
*/
|
||||
private void innerClassXML(ClassDoc classDoc) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", classDoc.name());
|
||||
String access = "package";
|
||||
if (classDoc.isPublic()) {
|
||||
access = "public";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "access", "String", access);
|
||||
atts.addAttribute(xmlns, localName, "abstract", "String", ""+ classDoc.isAbstract());
|
||||
String anonymous = "false";
|
||||
if (classDoc.name().equals("")) {
|
||||
anonymous = "true";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "anonymous", "String", ""+ anonymous);
|
||||
atts.addAttribute(xmlns, localName, "final", "String", ""+ "" + classDoc.isFinal());
|
||||
atts.addAttribute(xmlns, localName, "static", "String", ""+ "" + classDoc.isStatic());
|
||||
cm.startElement(xmlns, localName, "innerclass", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(classDoc);
|
||||
|
||||
// generate "extends" sub-element
|
||||
extendsXML(classDoc);
|
||||
|
||||
// generate "implements" sub-element
|
||||
implementsXML(classDoc);
|
||||
|
||||
// generate "field" sub-elements
|
||||
FieldDoc[] fieldArray = classDoc.fields();
|
||||
for (int i = 0; i < fieldArray.length; ++i) {
|
||||
fieldXML(fieldArray[i]);
|
||||
}
|
||||
|
||||
// generate "constructor" sub-elements
|
||||
ConstructorDoc[] constructorArray = classDoc.constructors();
|
||||
for (int i = 0; i < constructorArray.length; ++i) {
|
||||
constructorXML(constructorArray[i]);
|
||||
}
|
||||
|
||||
// generate "method" sub-elements
|
||||
MethodDoc[] methodArray = classDoc.methods();
|
||||
for (int i = 0; i < methodArray.length; ++i) {
|
||||
methodXML(methodArray[i]);
|
||||
}
|
||||
|
||||
cm.endElement(xmlns, localName,"innerclass");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "interface"
|
||||
* <xmp><!ELEMENT interface (doc?,
|
||||
* extends_interface?,
|
||||
* field*,
|
||||
* method*)>
|
||||
* <!ATTLIST interface
|
||||
* %name;
|
||||
* %access;></xmp>
|
||||
*/
|
||||
private void interfaceXML(ClassDoc interfaceDoc) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", interfaceDoc.name());
|
||||
String access = "package";
|
||||
if (interfaceDoc.isPublic()) {
|
||||
access = "public";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "access", "String", access);
|
||||
cm.startElement(xmlns, localName, "interface", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(interfaceDoc);
|
||||
|
||||
// generate "extends_interface"
|
||||
extends_interfaceXML(interfaceDoc);
|
||||
|
||||
// generate "field" sub-elements
|
||||
FieldDoc[] fieldArray = interfaceDoc.fields();
|
||||
for (int i = 0; i < fieldArray.length; ++i) {
|
||||
fieldXML(fieldArray[i]);
|
||||
}
|
||||
|
||||
// generate "method" sub-elements
|
||||
MethodDoc[] methodArray = interfaceDoc.methods();
|
||||
for (int i = 0; i < methodArray.length; ++i) {
|
||||
methodXML(methodArray[i]);
|
||||
}
|
||||
cm.endElement(xmlns, localName, "interface");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "extends_interface"
|
||||
* <xmp><!ELEMENT extends_interface (interfaceref+)></xmp>
|
||||
*/
|
||||
private void extends_interfaceXML(ClassDoc interfaceDoc) throws SAXException {
|
||||
ClassDoc[] interfaceArray = interfaceDoc.interfaces();
|
||||
if (interfaceArray.length > 0) {
|
||||
cm.startElement(xmlns, localName, "extends_interface", emptyAtts);
|
||||
for (int i = 0; i < interfaceArray.length; ++i) {
|
||||
createRefXML("interfaceref", interfaceArray[i].qualifiedName());
|
||||
}
|
||||
cm.endElement(xmlns, localName, "extends_interface");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "implements"
|
||||
* <xmp><!ELEMENT implements (interfaceref+)></xmp>
|
||||
*/
|
||||
private void implementsXML(ClassDoc classDoc) throws SAXException {
|
||||
ClassDoc[] interfaceArray = classDoc.interfaces();
|
||||
if (interfaceArray.length > 0) {
|
||||
cm.startElement(xmlns, localName, "implements", emptyAtts);
|
||||
for (int i = 0; i < interfaceArray.length; ++i) {
|
||||
createRefXML("interfaceref", interfaceArray[i].qualifiedName());
|
||||
}
|
||||
cm.endElement(xmlns, localName, "implements");
|
||||
}
|
||||
if (classDoc.superclass() != null) {
|
||||
implementsXML(classDoc.superclass());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "throws"
|
||||
* <xmp><!ELEMENT throws (classref)+></xmp>
|
||||
*/
|
||||
private void throwsXML(ExecutableMemberDoc member) throws SAXException {
|
||||
ThrowsTag[] tagArray = member.throwsTags();
|
||||
if(tagArray.length > 0) {
|
||||
cm.startElement(xmlns, localName, "throws", emptyAtts);
|
||||
for (int i = 0; i < tagArray.length; ++i) {
|
||||
ClassDoc exceptionClass = tagArray[i].exception();
|
||||
String name = null;
|
||||
if (exceptionClass == null) {
|
||||
name = tagArray[i].exceptionName();
|
||||
} else {
|
||||
name = tagArray[i].exception().qualifiedName();
|
||||
}
|
||||
createRefXML("classref", name);
|
||||
}
|
||||
cm.endElement(xmlns, localName, "throws");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for following elements
|
||||
* <xmp> <!ELEMENT classref EMPTY>
|
||||
* <!ATTLIST classref %name;>
|
||||
* <!ELEMENT interfaceref EMPTY>
|
||||
* <!ATTLIST interfaceref %name;>
|
||||
* <!ELEMENT methodref EMPTY>
|
||||
* <!ATTLIST methodref %name;>
|
||||
* <!ELEMENT packageref EMPTY>
|
||||
* <!ATTLIST packageref %name;></xmp>
|
||||
*/
|
||||
private void createRefXML(String elementName, String nameValue) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", nameValue);
|
||||
cm.startElement(xmlns, localName, elementName, atts);
|
||||
cm.endElement(xmlns, localName, elementName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for "(classref|interfaceref|primitive)" sub-element
|
||||
*/
|
||||
private void createTypeRef(Type type) throws SAXException {
|
||||
String qualifiedName = type.qualifiedTypeName();
|
||||
ClassDoc fieldType = type.asClassDoc();
|
||||
if (fieldType == null) {
|
||||
// primitive data type
|
||||
AttributesImpl subElmAtts = new AttributesImpl();
|
||||
subElmAtts.addAttribute(xmlns, localName, "type", "String", qualifiedName);
|
||||
cm.startElement(xmlns, localName, "primitive", subElmAtts);
|
||||
cm.endElement(xmlns, localName, "primitive");
|
||||
} else if (fieldType.isInterface()) {
|
||||
// interface
|
||||
createRefXML("interfaceref", qualifiedName);
|
||||
} else {
|
||||
// class
|
||||
createRefXML("classref", qualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "field"
|
||||
* <xmp> <!ELEMENT field (doc?, (classref | interfaceref | primitive))>
|
||||
* <!ATTLIST field
|
||||
* %name;
|
||||
* %access;
|
||||
* %dimension;
|
||||
* %synthetic;
|
||||
* %static;
|
||||
* %final;
|
||||
* %transient;
|
||||
* %volatile;></xmp>
|
||||
*/
|
||||
private void fieldXML(FieldDoc field) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
|
||||
atts.addAttribute(xmlns, localName, "name", "String", field.name());
|
||||
|
||||
String access = "package";
|
||||
if (field.isPrivate()) {
|
||||
access = "private";
|
||||
} else if (field.isProtected()) {
|
||||
access = "protected";
|
||||
} else if (field.isPublic()) {
|
||||
access = "public";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "access", "String", access);
|
||||
|
||||
atts.addAttribute(xmlns, localName, "dimension", "String", field.type().dimension());
|
||||
atts.addAttribute(xmlns, localName, "synthetic", "String", "" + field.isSynthetic());
|
||||
atts.addAttribute(xmlns, localName, "static", "String", "" + field.isStatic());
|
||||
atts.addAttribute(xmlns, localName, "final", "String", "" + field.isFinal());
|
||||
atts.addAttribute(xmlns, localName, "transient", "String", "" + field.isTransient());
|
||||
atts.addAttribute(xmlns, localName, "volatile", "String", "" + field.isVolatile());
|
||||
cm.startElement(xmlns, localName, "field", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(field);
|
||||
|
||||
// generate "(classref|interfaceref|primitive)" sub-element
|
||||
createTypeRef(field.type()); // foo , field.qualifiedName());
|
||||
|
||||
cm.endElement(xmlns, localName, "field");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "constructor"
|
||||
* <xmp><!ELEMENT constructor (doc?, parameter*, throws*)>
|
||||
* <!ATTLIST constructor
|
||||
* %name;
|
||||
* %access;
|
||||
* %synthetic;></xmp>
|
||||
*/
|
||||
private void constructorXML(ConstructorDoc constrDoc) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", constrDoc.qualifiedName());
|
||||
String access = "package";
|
||||
if (constrDoc.isPrivate()) {
|
||||
access = "private";
|
||||
} else if (constrDoc.isProtected()) {
|
||||
access = "protected";
|
||||
} else if (constrDoc.isPublic()) {
|
||||
access = "public";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "access", "String", access);
|
||||
atts.addAttribute(xmlns, localName, "synthetic", "String", "" + constrDoc.isSynthetic());
|
||||
cm.startElement(xmlns, localName, "constructor", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(constrDoc);
|
||||
|
||||
// generate "parameter" sub-elements
|
||||
Parameter[] parameterArray = constrDoc.parameters();
|
||||
for (int i = 0; i < parameterArray.length; ++i) {
|
||||
parameterXML(parameterArray[i]);
|
||||
}
|
||||
|
||||
// generate "throws" sub-element
|
||||
throwsXML(constrDoc);
|
||||
|
||||
cm.endElement(xmlns, localName, "constructor");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "method"
|
||||
* <xmp> <!ELEMENT method (doc?, returns, parameter*, throws*)>
|
||||
* <!ATTLIST method
|
||||
* %name;
|
||||
* %access;
|
||||
* %extensibility;
|
||||
* %native;
|
||||
* %synthetic;
|
||||
* %static;
|
||||
* %synchronized;></xmp>
|
||||
*/
|
||||
private void methodXML(MethodDoc methodDoc) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
//atts.addAttribute(xmlns, localName, "", String, );
|
||||
atts.addAttribute(xmlns, localName, "name", "String", methodDoc.name());
|
||||
|
||||
String access = "package";
|
||||
if (methodDoc.isPrivate()) {
|
||||
access = "private";
|
||||
} else if (methodDoc.isProtected()) {
|
||||
access = "protected";
|
||||
} else if (methodDoc.isPublic()) {
|
||||
access = "public";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "access", "String", access);
|
||||
|
||||
String extensibility = "default";
|
||||
if (methodDoc.isAbstract()) {
|
||||
extensibility = "abstract";
|
||||
} else if (methodDoc.isFinal()) {
|
||||
extensibility = "final";
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "extensiblity", "String", extensibility);
|
||||
|
||||
atts.addAttribute(xmlns, localName, "native", "String", ""+ methodDoc.isNative());
|
||||
atts.addAttribute(xmlns, localName, "synthetic", "String", "" + methodDoc.isSynthetic());
|
||||
atts.addAttribute(xmlns, localName, "static", "String", "" + methodDoc.isStatic());
|
||||
atts.addAttribute(xmlns, localName, "synchronized", "String", ""+ methodDoc.isSynchronized());
|
||||
cm.startElement(xmlns, localName, "method", atts);
|
||||
|
||||
// generate "doc" sub-element
|
||||
docXML(methodDoc);
|
||||
|
||||
// generate "returns" sub-element
|
||||
returnsXML(methodDoc.returnType());
|
||||
|
||||
// generate "parameter" sub-elements
|
||||
Parameter[] parameterArray = methodDoc.parameters();
|
||||
for (int i = 0; i < parameterArray.length; ++i) {
|
||||
parameterXML(parameterArray[i]);
|
||||
}
|
||||
|
||||
// generate "throws" sub-element
|
||||
throwsXML(methodDoc);
|
||||
|
||||
cm.endElement(xmlns, localName, "method");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "returns"
|
||||
* <xmp> <!ELEMENT returns (classref | interfaceref | primitive)>
|
||||
* <!ATTLIST returns %dimension;></xmp>
|
||||
*/
|
||||
private void returnsXML(Type type) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "dimension", "String", type.dimension());
|
||||
cm.startElement(xmlns, localName, "returns", atts);
|
||||
|
||||
// generate "(classref|interfaceref|primitive)" sub-element
|
||||
createTypeRef(type);
|
||||
|
||||
cm.endElement(xmlns, localName, "returns");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "parameter"
|
||||
* <xmp> <!ELEMENT parameter (classref | interfaceref | primitive)>
|
||||
* <!ATTLIST parameter
|
||||
* %name;
|
||||
* %final;
|
||||
* %dimension;></xmp>
|
||||
*/
|
||||
private void parameterXML(Parameter parameter) throws SAXException {
|
||||
AttributesImpl atts = new AttributesImpl();
|
||||
atts.addAttribute(xmlns, localName, "name", "String", parameter.name());
|
||||
boolean isFinal = false;
|
||||
Type type = parameter.type();
|
||||
if (type.asClassDoc() == null) {
|
||||
isFinal = true;
|
||||
}
|
||||
atts.addAttribute(xmlns, localName, "final", "String", ""+ "" + isFinal);
|
||||
atts.addAttribute(xmlns, localName, "dimension", "String", parameter.type().dimension());
|
||||
cm.startElement(xmlns, localName, "parameter", atts);
|
||||
|
||||
// generate "(classref|interfaceref|primitive)" sub-element
|
||||
createTypeRef(parameter.type());
|
||||
|
||||
cm.endElement(xmlns, localName,"parameter");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for element "doc"
|
||||
* <xmp><!ELEMENT doc (#PCDATA |
|
||||
* linktag |
|
||||
* authortag |
|
||||
* versiontag |
|
||||
* paramtag |
|
||||
* returntag |
|
||||
* exceptiontag |
|
||||
* throwstag |
|
||||
* seetag |
|
||||
* sincetag |
|
||||
* deprecatedtag |
|
||||
* serialtag |
|
||||
* serialfieldtag |
|
||||
* serialdatatag)*></xmp>
|
||||
*/
|
||||
private void docXML(Doc doc) throws SAXException {
|
||||
String commentText = "";
|
||||
boolean createDoc = false;
|
||||
commentText = doc.commentText();
|
||||
if (! commentText.equals("")) {
|
||||
createDoc = true;
|
||||
}
|
||||
Tag[] tags = doc.tags();
|
||||
if (tags.length > 0) {
|
||||
createDoc = true;
|
||||
}
|
||||
if (createDoc) {
|
||||
cm.startElement(xmlns, localName, "doc", emptyAtts);
|
||||
if (! commentText.equals("")) {
|
||||
cm.characters(commentText.toCharArray(), 0, commentText.length());
|
||||
}
|
||||
for (int i = 0; i < tags.length; ++i) {
|
||||
tagXML(tags[i]);
|
||||
}
|
||||
cm.endElement(xmlns, localName, "doc");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates doc for all tag elements.
|
||||
*/
|
||||
private void tagXML(Tag tag) throws SAXException {
|
||||
String name = tag.name().substring(1) + "tag";
|
||||
if (! tag.text().equals("")) {
|
||||
cm.startElement(xmlns, localName, name, emptyAtts);
|
||||
cm.characters(tag.text().toCharArray(), 0, tag.text().length());
|
||||
cm.endElement(xmlns, localName, name);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean start(RootDoc root) {
|
||||
try {
|
||||
new XMLDoclet(root);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0"?>
|
||||
<j:jelly
|
||||
xmlns:j="jelly:core"
|
||||
xmlns:x="jelly:xml"
|
||||
xmlns:jsl="jelly:jsl">
|
||||
|
||||
<j:new var="file" className="java.io.File">
|
||||
<j:arg value="target/taglib.xml"/>
|
||||
</j:new>
|
||||
|
||||
<x:parse var="doc" xml="${file}"/>
|
||||
<x:set var="libraries" select="$doc/tags/library"/>
|
||||
|
||||
<!-- lets create a JSL stylesheet that we'll use later -->
|
||||
<jsl:stylesheet var="docStylesheet">
|
||||
|
||||
<!-- don't output <doc> element but output its contents -->
|
||||
<jsl:template match="doc">
|
||||
<jsl:applyTemplates/>
|
||||
</jsl:template>
|
||||
|
||||
<!-- ignore javadoc tags-->
|
||||
<jsl:template match="authortag"/>
|
||||
<jsl:template match="versiontag"/>
|
||||
<jsl:template match="tagtag"/>
|
||||
<jsl:template match="paramtag"/>
|
||||
<jsl:template match="requiredtag"/>
|
||||
<jsl:template match="seetag"/>
|
||||
|
||||
<!-- let other text and elements pass through via default rules-->
|
||||
<jsl:template match="*" trim="false">
|
||||
<jsl:copy>
|
||||
<jsl:applyTemplates/>
|
||||
</jsl:copy>
|
||||
</jsl:template>
|
||||
|
||||
<jsl:template match="@*"/>
|
||||
</jsl:stylesheet>
|
||||
|
||||
<document>
|
||||
|
||||
<properties>
|
||||
<title>Tag Documentation</title>
|
||||
</properties>
|
||||
|
||||
<body>
|
||||
<section name="Tag Documentation">
|
||||
|
||||
<p>
|
||||
[<a href="#Tag Libraries">tag libraries</a>]
|
||||
[<a href="#Tags">tags</a>]
|
||||
</p>
|
||||
<p>
|
||||
The following document contains a summary of all the core
|
||||
<a href="http://jakarta.apache.org/commons/sandbox/jelly/">Jelly</a> tag libraries.
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="Tag Libraries">
|
||||
<p>
|
||||
[<a href="#Tag Libraries">tag libraries</a>]
|
||||
[<a href="#Tags">tags</a>]
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Library</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<x:forEach select="$libraries">
|
||||
<x:set var="uri" select="string(@uri)"/>
|
||||
<tr>
|
||||
<td><a href="#${uri}">${uri}</a></td>
|
||||
<td>
|
||||
<jsl:style stylesheet="${docStylesheet}" select="doc"/>
|
||||
</td>
|
||||
</tr>
|
||||
</x:forEach>
|
||||
</table>
|
||||
|
||||
|
||||
<x:forEach select="$libraries">
|
||||
<x:set var="name" select="string(@uri)"/>
|
||||
<x:set var="prefix" select="string(@prefix)"/>
|
||||
|
||||
<subsection name="${name}">
|
||||
<p>
|
||||
<jsl:style stylesheet="${docStylesheet}" select="doc"/>
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Tag Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<x:forEach select="tag">
|
||||
<x:set var="tagName" select="string(@name)"/>
|
||||
<x:set var="doc" select="doc"/>
|
||||
<tr>
|
||||
<td><a href="#${prefix}:${tagName}">${tagName}</a></td>
|
||||
<td>
|
||||
<jsl:style stylesheet="${docStylesheet}" select="$doc"/>
|
||||
</td>
|
||||
</tr>
|
||||
</x:forEach>
|
||||
</table>
|
||||
</subsection>
|
||||
|
||||
</x:forEach>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section name="Tags">
|
||||
<p>
|
||||
[<a href="#Tag Libraries">tag libraries</a>]
|
||||
[<a href="#Tags">tags</a>]
|
||||
</p>
|
||||
|
||||
<x:forEach select="$libraries">
|
||||
<x:set var="prefix" select="string(@prefix)"/>
|
||||
<x:forEach select="tag" var="tag">
|
||||
<x:set var="tagName" select="string(@name)"/>
|
||||
|
||||
<subsection name="${prefix}:${tagName}">
|
||||
<p>
|
||||
<jsl:style stylesheet="${docStylesheet}" select="$tag/doc"/>
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Attribute Name</th>
|
||||
<th>Type</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<x:forEach var="attr" select="$tag/attribute">
|
||||
<tr>
|
||||
<td><x:expr select="$attr/@name"/></td>
|
||||
<td><x:expr select="$attr/@type"/></td>
|
||||
<td>
|
||||
<jsl:style stylesheet="${docStylesheet}" select="$attr/doc"/>
|
||||
</td>
|
||||
</tr>
|
||||
</x:forEach>
|
||||
</table>
|
||||
</subsection>
|
||||
|
||||
|
||||
|
||||
</x:forEach>
|
||||
</x:forEach>
|
||||
</section>
|
||||
|
||||
</body>
|
||||
</document>
|
||||
|
||||
</j:jelly>
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
stylesheets
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<document>
|
||||
|
||||
<properties>
|
||||
<title>JellyDoc Plugin Goals</title>
|
||||
<author email="jstrachan@apache.org">James Strachan</author>
|
||||
</properties>
|
||||
|
||||
<body>
|
||||
<section name="Goals">
|
||||
<table>
|
||||
<tr><th>Goal</th><th>Description</th></tr>
|
||||
|
||||
<a name="jellydoc" />
|
||||
<tr>
|
||||
<td>jellydoc</td>
|
||||
<td>
|
||||
The default goal. This goal generates the JellyDoc documentation of
|
||||
all Jelly tags defined within your code base which can then be styled
|
||||
into HTML as part of the xdoc goal
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0"?>
|
||||
<document>
|
||||
|
||||
<properties>
|
||||
<title>Maven JellyDoc Plug-in</title>
|
||||
<author email="jstrachan@apache.org">James Strachan</author>
|
||||
</properties>
|
||||
|
||||
<body>
|
||||
<section name="Maven JellyDoc Plug-in">
|
||||
<p>
|
||||
This plug-in provides JellyDoc reporting documenting all the Jelly
|
||||
Tags defined in your code base using the
|
||||
<code>jellydoc</code> goal as described <a href="goals.html">here</a>.
|
||||
</p>
|
||||
<p>
|
||||
The properties that allow you to customize the execution
|
||||
are documented <a href="properties.html">here</a>.
|
||||
</p>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<project name="Maven JellyDoc Plugin">
|
||||
|
||||
<title>Maven JellyDoc Plugin</title>
|
||||
|
||||
<body>
|
||||
<links>
|
||||
<item name="Maven" href="http://jakarta.apache.org/turbine/maven/"/>
|
||||
<item name="Jelly" href="http://jakarta.apache.org/commons/jelly/"/>
|
||||
</links>
|
||||
<menu name="Overview">
|
||||
<item name="Goals" href="/goals.html" />
|
||||
<item name="Properties" href="/properties.html" />
|
||||
</menu>
|
||||
</body>
|
||||
</project>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<document>
|
||||
|
||||
<properties>
|
||||
<title>JellyDoc Properties</title>
|
||||
<author email="jstrachan@apache.org">James Strachan</author>
|
||||
</properties>
|
||||
|
||||
<body>
|
||||
<section name="JellyDoc Settings">
|
||||
<table>
|
||||
<tr><th>Property</th><th>Optional?</th><th>Description</th></tr>
|
||||
<tr>
|
||||
<td>maven.jellydoc.packages</td>
|
||||
<td>Yes</td>
|
||||
<td>
|
||||
Specifies the packages which contain Jelly tags.
|
||||
By restricting this to a subset of your packages will optimise the
|
||||
goal and simplify the documentation. e.g. setting it to org.foo.jelly.*
|
||||
The default value is <code>${pom.build.sourceDirectory}.*</code>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</section>
|
||||
</body>
|
||||
</document>
|
||||
Reference in new issue
Block a user