apt-jelly

  soothes irritation and swelling caused by abrasive annotation processing


   

Introduction

The following is a brief overview of the APT-Jelly Decorated Mirror API. You may want to read the section on the decorated API in the reference guide to establish a context for reading this. There will be no attempt here to present the decorated API in detail. For the details, use the API docs.

Because these are decorations, all decorated classes provide the same properties that did the Mirror API interfaces that they are decorating. An important enhancement to note, however, is that all decorated declarations and type mirrors that have properties whose values are declarations or type mirrors (or collections thereof) return the declarations and type mirrors (or collections thereof) in their decorated form. The template data model also decorates declarations or type mirrors as necessary when set as variables.

To extend the decorations, refer to the relevant section in the reference guide.



Decorated Declarations

declaration modifiers

The decorated declarations provide additional boolean properties for determining the declartion modifiers. The relevant properties are public, "protected", "private", "abstract", "static", "final", "transient", "volatile", "synchronized", "native", and "strictfp". These properties provide a simple way in the template to determine the modifiers that are present on a declaration. As an example, consider the following template snippet:

<@forAllTypes var="type">
  <#if type.public>
    ${type} is public.
  </#if>
  <#if type.static>
    ${type} is static.
  </#if>
  <#if type.final>
    ${type} is final.
  </#if>

  <#-- could be done for the other modifiers, too. -->

</@forAllTypes>
                

javaDoc

The decorated declarations also provide an interesting new property named "javaDoc". This is property is useful when accessing the JavaDocs for the declaration. This property is a map that represents the different parts of the doc comment associated with the declaration. Each key in this map is a JavaDoc tag. The value associated with the key is a list of JavaDoc tag values. Use of the "javaDoc" property is best described by example. Consider the following class:

/**
 * This is the comment for my class.
 *
 * @author Sam
 * @author Mike
 * @version 1.2
 */
public class MyClass {
}
                

If the "myclass" variable in a template were assigned the type declaration for MyClass as declared above, then the following template snippet:

---------------- myclass.docComment ----------------
${myclass.docComment}
---------------- myclass.javaDoc -------------------
${myclass.javaDoc}
---------------- myclass.javaDoc.author ------------
${myclass.javaDoc.author}
---------------- myclass.javaDoc.version -----------
${myclass.javaDoc.version}
---------------- list of myclass.javaDoc.author ----
<#list myclass.javaDoc.author as author>
  ${author}
</#list>
                

Would produce the following output:

---------------- myclass.docComment ----------------
This is the comment for my class.

@author Sam
@author Mike
@version 1.2
---------------- myclass.javaDoc -------------------
This is the comment for my class.
---------------- myclass.javaDoc.author ------------
Sam
---------------- myclass.javaDoc.version -----------
1.2
---------------- list of myclass.javaDoc.author ----
  Sam
  Brian
                

It's interesting to note that the javaDoc property for parameter declarations contains the value of the associated comments in the associated method declaration. Also, note that the decorated type mirror has a "docComment" property. This property is set on some decorated type mirrors, most notably the type mirrors for the thrown types of the method.

By default, APT-Jelly passes the value of the JavaDoc comment directly through and does no processing of inline JavaDoc tags and markup. However, you can define your own handling mechanism if you don't want that text passed through literally. At the time that APT is invoked, pass the -Anet.sf.jelly.apt.util.JavaDocTagHandler option with the value of a class that implements net.sf.jelly.apt.util.JavaDocTagHandler.

annotations

There is also an "annotations" property on the decorated declaration that is a map containing the annotation mirrors on the declaration. The key of the map is the fully-qualified name of the annotation, the value is the (decorated) annotation mirror.



Decorated Annotation Mirrors

APT-Jelly decorates AnnotationMirror by adding properties for each of the elements of the annotation so they can be referenced from the template. To illustrate, consider the following two template snippets. Each snippet outputs the value of the "bar" element of the annotation "com.foo.Foo". The first snippet uses the Mirror API as if it were not decorated. The second leverages the API as decorated by APT-Jelly.

@com.foo.Foo {
  bar = "hello"
}
public class MyClass {
}
                

Example of a class annotated with com.foo.Foo.

<#list annotation.elementValues.entrySet as entry>
  <#if entry.key.simpleName = "bar">
    ${entry.value}
  </#if>
</#list>
                

Freemarker template snippet that outputs "hello" without using the decorated API. The context variable "annotation" is assigned the value of the com.foo.Foo AnnotationMirror featured in the example source code above.

${annotation.bar}
                

Freemarker template snippet that outputs "hello" using the decorated API. Again, the context variable "annotation" is assigned the value of the com.foo.Foo AnnotationMirror featured in the example source code above.



Decorated Type Declarations

The decorated type declarations provide properties for whether the type declaration is a class, interface, enum, or annotation type declaration. As should be expected, these properties are boolean properties named "class", "interface", "enum", and "annotation".



Decorated Method Declarations

There is a set of properties on a decorated method declaration that are concerned with whether this method is a property accessor. A boolean property specifying whether the method is a getter is named "getter." A boolean property specifying whether the method is a setter is named "setter." There is also a property that calculates the name of the property for which this is a property accessor is named "propertyName."



Decorated Type Mirrors

There is a set of properties on the decorated type mirrors that can be used to determine what kind of type mirror it is. The properties are boolean and are named "annotation", "array", "class", "collection", "declared", "enum", "interface", "primitive", "referenceType", "typeVariable", "void", and "wildcard".

As explained above, there is also a "docComment" property for types that can be assigned a JavaDoc comment. Most notable of these is the thrown types of a method.

There is also a method on decorated type mirrors named "isInstanceOf" that takes as a parameter a string. This method can be used in template to determine whether the type is an instance of the specified (fully-qualified) name. While all decorated type mirrors have this method available, it only has meaning if the type mirror is an array, is declared, or is a primitive.

The following is an example of using the isInstanceOf method in template. It will output "It is a map" if the "typeMirror" context varible holds a reference to a declared type that is an instance of java.util.Map.

<#if typeMirror.isIntanceOf("java.util.Map")>
  It is a map
</#if>
                

page design by Phlash