commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ryan Heaton (JIRA)" <>
Subject [jira] Commented: (JELLY-225) apt jelly tag library
Date Wed, 28 Dec 2005 18:13:01 GMT
    [ ] 

Ryan Heaton commented on JELLY-225:

Thanks for the pointer to XDoclet2.  It looks like a good tool.  However, I still believe
an apt tag library holds significant advantages over XDoclet2, including the following:

-An interface to APT.  I believe this in and of itself is very useful to developers who want
to use apt to generate code.
-A smaller dependency footprint.  Also, dependencies on tools that are packaged with the JDK
imply that this tag library will more easily adapt to future syntax and core library changes.
-Complete support for full Java 5 syntax, including generics, annotations, static imports,
enums, etc.
-A more complete set of tags for traversing source code classes, including tags like forAllPackages,
forAllImportedTypes, forAllNestedTypes, forAllThrownTypes, etc.

> apt jelly tag library
> ---------------------
>          Key: JELLY-225
>          URL:
>      Project: jelly
>         Type: New Feature
>   Components: submissions
>     Reporter: Ryan Heaton
>  Attachments: testBasicExample.jelly, testForAllTypesIncludeInterfaces.jelly
> This is a proposal for a new jelly tag library that provides an interface to the new
Java 5 Annotation Processing Tool (apt) and its associated Mirror API (see
> From the official apt documentation: "apt is a command-line utility for annotation processing.
It includes a set of reflective APIs and supporting infrastructure to process program annotations
(JSR 175). These reflective APIs provide a build-time, source-based, read-only view of program
structure. They are designed to cleanly model the Java programming language's type system
after the addition of generics (JSR 14)."
> Developers who which to process Java source code are presently limited to working with
the Mirror API directly.  If, for example, a developer wished to generate an artifact such
as an xml config file or another Java class must do so by writing to an instance of
> As an admittedly impotent example, to generate a simple class that will print out all
methods of all classes in a given source base, the developer would implement instances of
com.sun.mirror.apt.AnnotationProcessorFactory and com.sun.mirror.apt.AnnotationProcessor that
look something like this:
>     package org.apache.commons.jelly.examples;
>     import java.util.Collection;
>     import java.util.Set;
>     import java.util.Collections;
>     import;
>     import;
>     import com.sun.mirror.apt.AnnotationProcessorFactory;
>     import com.sun.mirror.apt.AnnotationProcessor;
>     import com.sun.mirror.apt.AnnotationProcessorEnvironment;
>     import com.sun.mirror.declaration.AnnotationTypeDeclaration;
>     import com.sun.mirror.declaration.TypeDeclaration;
>     import com.sun.mirror.declaration.MethodDeclaration;
>     public class ClassAndMethodPrinterAnnotationProcessorFactory implements AnnotationProcessorFactory
>       public Collection<String> supportedOptions() {
>         return Collections.EMPTY_LIST;
>       }
>       public Collection<String> supportedAnnotationTypes() {
>         return Collections.EMPTY_LIST;
>       }
>       public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration>
atds, AnnotationProcessorEnvironment env) {
>         return new ClassAndMethodPrinterAnnotationProcessor(env);
>       }
>       private class ClassAndMethodPrinterAnnotationProcessor implements AnnotationProcessor
>         AnnotationProcessorEnvironment env;
>         public ClassAndMethodPrinterAnnotationProcessor(AnnotationProcessorEnvironment
env) {
>           this.env = env;
>         }
>         public void process() {
>           try {
>             PrintWriter writer = env.getFiler().createSourceFile("org.apache.commons.jelly.examples.ClassAndMethodPrinter");
>             writer.println("package org.apache.commons.jelly.examples;");
>             writer.println();
>             writer.println("public class ClassAndMethodPrinter {");
>             writer.println();
>             writer.println("  public static void main(String[] args) {");
>             for (TypeDeclaration typeDeclaration : env.getTypeDeclarations()) {
>               writer.println(String.format("    System.out.println(\"Class: %s\");",
>               for (MethodDeclaration methodDeclaration : typeDeclaration.getMethods())
>                 writer.println(String.format("    System.out.println(\"Method: %s.%s\");",
typeDeclaration.getQualifiedName(), methodDeclaration.getSimpleName()));
>               }
>             }
>             writer.println("  }");
>             writer.println();
>             writer.println("}");
>           }
>           catch (IOException e) {
>             throw new RuntimeException(e);
>           }
>         }
>       }
>     }
> Any Java programmer with a little bit of experience could testify that using a PrintWriter
for large and complex output is significantly heavy and burdensome.  To use a familiar paradigm
in J2EE, nobody wants to use a Servlet's PrintWriter for outputting many large and complex
html documents.  For this reason, Java Server Pages (JSP) were created to ease development
of complex output.
> An apt tag library would be to the Mirror API what JSPs are to the Servlet API.  Instead
of writing implementations of AnnotationProcessorFactory and AnnotationProcessor, why not
just use Jelly to manage your output, like so:
>     <j:jelly xmlns:j="jelly:core" xmlns:apt="jelly:apt">
>       <apt:javaSource name="org.apache.commons.jelly.examples.ClassAndMethodPrinter">
>     package org.apache.commons.jelly.examples;
>     public class ClassAndMethodPrinter {
>       public static void main(String[] args) {
>         <apt:forAllTypes var="type">
>         System.out.println("<j:out value="${type.qualifiedName}"/>");
>           <apt:forAllMethods var="method">
>         System.out.println("<j:out value="${type.qualifiedName}"/>.<j:out value="${method.simpleName}"/>");
>           </apt:forAllMethods>
>         </apt:forAllTypes>
>       }
>     }
>       </apt:javaSource>
>     </j:jelly>
> Not only is the requirement to implement Mirror API classes lifted from the developer,
but it's easy to see how easily Jelly provides a much cleaner and easier-to-read abstraction
on top of the Mirror API.  Developers could also take advantage of the rich set of jelly tag
libararies for managing output.
> The new apt tag library would be a replacement for the popular tool XDoclet (see
 Not only would it provide everything that XDoclet currently provides, but it would have many
significant advantages over XDoclet, including:
> -No tight coupling to Ant
> -Availability of a rich set of tag libraries, including all the current jelly tag libararies
like jelly core and xml taglibs.
> -Complete support for full Java 5 syntax, including generics, annotations, static imports,
enums, etc.
> -A richer (and significantly cleaner) template language (i.e. Jelly)
> -A more complete set of tags for traversing source code classes, including tags like
forAllPackages, forAllImportedTypes, forAllNestedTypes, forAllThrownTypes, etc.
> I already have everything implemented and integrated into the current maven jelly build.
 Attached are a few examples that show what this new library can do.  All examples output
properties files (these are examples I use for unit testing).

This message is automatically generated by JIRA.
If you think it was sent incorrectly contact one of the administrators:
For more information on JIRA, see:

To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message