apt jelly tag library
---------------------

         Key: JELLY-225
         URL: http://issues.apache.org/jira/browse/JELLY-225
     Project: jelly
        Type: New Feature
  Components: submissions  
    Reporter: Ryan Heaton


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 http://java.sun.com/j2se/1.5.0/docs/guide/apt/index.html).

>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 java.io.PrintWriter.

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 java.io.IOException;
    import java.io.PrintWriter;

    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\");", typeDeclaration.getQualifiedName()));
              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 http://xdoclet.sourceforge.net).  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:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to