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.
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>
|