196 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES Listing 10-6 puts all the pieces together to define an annotation processor that prints out the specified classes and interfaces, along with the names of their methods (though not the constructors, which requires another visitXXXDeclaration() method implemented). Listing 10-6. J2SE 5.0 Annotation Processor import com.sun.mirror.apt.*; import com.sun.mirror.declaration.*; import com.sun.mirror.type.*; import com.sun.mirror.util.*; import static com.sun.mirror.util.DeclarationVisitors.*; import java.util.*; public class DumpFactory implements AnnotationProcessorFactory { // Process all annotations private static final Collection supportedAnnotations = Collections.unmodifiableCollection(Arrays.asList(”*”)); // No options support private static final Collection supportedOptions = Collections.emptySet(); public Collection supportedAnnotationTypes() { return supportedAnnotations; } public Collection supportedOptions() { return supportedOptions; } public AnnotationProcessor getProcessorFor(Set atds, AnnotationProcessorEnvironment env) { return new DumpProcessor(env); } private static class DumpProcessor implements AnnotationProcessor { private final AnnotationProcessorEnvironment env;
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES 195 To get started, you need to create an implementation of the com.sun.mirror.apt. AnnotationProcessorFactory interface. There are three methods to the interface, as follows: AnnotationProcessor getProcessorFor(Set atds, AnnotationProcessorEnvironment env) Collection supportedAnnotationTypes() Collection supportedOptions() Note For Java SE 6.0, the latter two methods here, supportedAnnotationTypes() and supportedOptions(), have become annotations themselves. The first method is what is used to look up the annotation processor. All the method needs to do is return a new instance of your class, which implements AnnotationProcessor. The processor interface implementation is the worker bee. It has a single method to implement: process(). If you use the AnnotationProcessorEnvironment implementation passed into the constructor of your AnnotationProcessor, your process() method loops through all the declarations requested. The AnnotationProcessorEnvironment offers different ways to request declarations. The Collection getDeclarationsAnnotatedWith(AnnotationTypeDeclaration a) method allows you to ask for those declarations (methods, classes, and fields) defined with a particular annotation. The Collection getSpecifiedType. Declarations() method essentially allows you to get all of them, giving you access to everything passed from the command line. Lastly, Collection getTypeDeclarations() doesn t require you to specify everything. For the sample in Listing 10-6, use the getSpecifiedTypeDeclarations() variety. To process each declaration, you need a visitor. The com.sun.mirror.util package offers the DeclarationVisitor interface and SimpleDeclarationVisitor implementation to help. The DeclarationVisitor interface offers a series of visitXXXDeclaration() methods so that you can choose to work with only certain types of declarations, such as all the classes, all the interfaces, or all the methods. For instance, to print out the name of each class, you would override the visitClassDeclaration() method. public void visitClassDeclaration(ClassDeclaration d) { System.out.println(d.getQualifiedName()); }
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES 193 Annotation Description XmlIDREF Maps a JavaBean property to XML IDREF XmlInlineBinaryData Disables consideration of XOP encoding for data types that are bound to base64-encoded binary data in XML XmlList Maps a property to a list simple type XmlMimeType Associates the mime type that controls the XML representation of the property XmlMixed Annotates a JavaBean multivalued property to support mixed content XmlNs Associates a namespace prefix with an XML namespace URI XmlRegistry Marks a class that has XML element factories XmlRootElement Maps a class or an enumerated type to an XML element XmlSchema Maps a package name to an XML namespace XmlSchemaType Maps a Java type to a simple schema built-in type XmlSchemaTypes Contains multiple @XmlSchemaType annotations XmlTransient Prevents the mapping of a JavaBean property to an XML representation XmlType Maps a class or an Enum type to an XML Schema type XmlValue Enables mapping a class to an XML Schema complex type with a simpleContent type or an XML Schema simple type The javax.xml.bind.annotation.adapters Package The javax.xml.bind.annotation.adapters package is for allowing Java classes to be used with JAXB. Again, this was shown in Chapter 6. There are two annotations in this package: XmlJavaTypeAdapter XmlJavaTypeAdapters The javax.xml.ws Package There are nine annotations found in the javax.xml.ws package. They are as follows: BindingType RequestWrapper ResponseWrapper
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
194 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES ServiceMode WebEndpoint WebFault WebServiceClient WebServiceProvider WebServiceRef These annotations are part of the core Java API for XML Web Services (JAX-WS) APIs. These were also explored in Chapter 6. Annotation Processing Enough about what annotations are out there. Let s take a look at what you can do with them when writing them yourself. First, we ll take a quick look at the 5.0 way of annotation processing. Then we ll move on to the new way. J2SE 5.0 Processing The way to process annotations with J2SE 5.0 was to use a library called the Mirror API. The Mirror API contains two parts: one for the processor, in the com.sun.mirror.apt package; and the other for a series of support classes that model the language. The language modeling piece stays put for Java SE 6, while the apt pieces relocate to the javax.annotation.processing package, with a few changes. Note For information on the Mirror API, visit http://java.sun.com/j2se/1.5.0/docs/guide/ apt/mirror/overview-summary.html. It is now released under a BSD license and available at https://aptmirrorapi.dev.java.net. To learn about the language modeling piece, you ll write a short little processor that walks through the classes found in the classpath and generates a list of all methods of all classes found. This doesn t involve writing any new tags, just processing information already made available by the runtime environment. A slightly different form of this example is part of the documentation that comes with the apt tool.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
192 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES For the negative cases, there are only two: // Default naming public interface MyClass { } @MXBean(false) public interface MyMXBean { } The javax.xml.bind.annotation Package The javax.xml.bind.annotation package is for customizing Java program elements to an XML Schema mapping, as shown in Chapter 6. It defines the annotations shown in Table 10-1. Table 10-1. Annotations Found in the javax.xml.bind.annotation Package Annotation Description XmlAccessorOrder Controls the ordering of fields and properties in a class XmlAccessorType Controls whether fields or JavaBean properties are serialized by default XmlAnyAttribute Maps a JavaBean property to a map of wildcard attributes XmlAnyElement Maps a JavaBean property to an XML infoset representation and/or JAXB element XmlAttachmentRef Marks a field/property to indicate that its XML form is a URI reference to mime content XmlAttribute Maps a JavaBean property to an XML attribute XmlElement Maps a JavaBean property to an XML element derived from the property name XmlElementDecl Maps a factory method to an XML element XmlElementRef Maps a JavaBean property to an XML element derived from the property s type XmlElementRefs Marks a property that refers to classes with XmlElement or JAXBElement XmlElements Contains multiple @XmlElement annotations XmlElementWrapper Generates a wrapper element around an XML representation XmlEnum Maps an enumeration of type Enum to an XML representation XmlEnumValue Maps an enumerated constant in an Enum type to XML representation XmlID Maps a JavaBean property to XML ID
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES 191 Tip If you declare your own annotations, keep in mind the pattern shown here. Repeated annotations are not allowed, so they must be grouped together into a single annotation. The javax.annotation.processing Package The annotations found in the javax.annotation.processing package are used by the capabilities added with JSR 269 for annotation processing. There are three annotations there: SupportedAnnotationTypes, SupportedOptions, and SupportedSourceVersion. Each of these will be described later in the chapter, in the Annotation Processing section. The javax.management Package The two annotations found in the javax.management package are DescriptorKey and MXBean. If you are familiar with the Java Management Extensions, their usage will prove helpful. The DescriptorKey annotation is for describing annotation elements related to a field. For an attribute, operation, or construction, you can add descriptors such that when the resulting descriptor is created, you can configure its values. See the javadoc for the DescriptorKey annotation for more information about auto-conversion of annotation elements, such as rules for how a primitive becomes an object. The MXBean annotation is used to explicitly tag an interface as an MXBean interface or not. If the interface name ends in MXBean, it is an MXBean interface by default. If it doesn t, then the interface isn t an MXBean-related interface. The @MXBean annotation allows you to tag an interface as an MXBean if it doesn t end with MXBean, and allows you to reject the automatic association if you don t want it. For the positive case, the following three declarations in Listing 10-5 are defined to be MXBean interfaces, assuming proper imports. Listing 10-5. @MXBean Annotation Usage // Default naming public interface MyMXBean { } @MXBean public interface MyInterface1 { } @MXBean(true) public interface MyInterface2 { }
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
190 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES Generated: Used to flag autogenerated source. Usage would include the value of the source generator: @Generated(”net.zukowski.revealed.FooGenerator”) InjectionComplete: Used to flag methods to be called after insertion into the container. PostConstruct: Used to flag initialization methods to be called after construction. PreDestroy: Used to flag methods that release resources upon finalization of class usage such as when removed from an EJB container. For instance, if PostConstruct got a database connection, then PreDestroy would probably close it. private DataSource aDB; private Connection connection; @Resource private void setADB(DataSource ds) { aDB = ds; } @PostConstruct private void initialize() { connection = aDB.getConnection(); } @PreDestroy private void cleanup() { connection.close(); } Resource: Used to declare a reference to a resource. The name specified would be the JNDI name of the resource. For instance, to look up the JNDI resource named fooDB, use the following: @Resource(name=”fooDB”) private DataSource aDB; Resources: Used to block multiple Resource declarations together. @Resources ({ @Resource(name=”fooDB” type=javax.sql.DataSource), @Resource(name=”fooMQ” type=javax.jms.ConnectionFactory) })
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
188 CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES Listing 10-4. @ConstructorProperties Annotation Usage import java.beans.ConstructorProperties; public class Point { private double x, y; public Point() { } @ConstructorProperties({”x”, “y”}) public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; } } By specifying the names x and y as arguments to @ConstructorProperties, you are saying that methods named getX() and getY() are available to access the property values. And, of course, that x comes first in the argument list. Tip As in Listing 10-4 with the import java.beans.ConstructorProperties; line, don t forget to import the classes for the annotations. Without the import line, the compiler will look in the default package for the annotation class (@ConstructorProperties here). The compiler has no internal mapping of annotations to classes in other packages.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES 189 At least for the early access releases of JDK 6.0, Sun has yet to add @ConstructorProperties lines to the core library classes that are typically used as JavaBeans components. So, if you use an IDE, the core classes won t act smart and show the extra information about parameter order for constructors. The java.lang Package No new annotations here. Just the original three: @Deprecated, @Override, and @SuppressWarnings. The java.lang.annotation Package This package is primarily for the library support for the annotation facility. It includes four annotations that help annotation creators document the proper usage of their annotations. These were part of JDK 5.0, and are not new to Mustang. Documented: States whether the annotation should be documented by javadoc. Inherited: States that a parent class should be queried when an annotation is not found in main class. Retention: Identifies how long the annotation is retained. The enumeration RetentionPolicy offers three possible settings: SOURCE, CLASS, and RUNTIME. A setting of SOURCE means that the annotation is only needed to compile; CLASS means that the data is stored in the class file, but isn t necessarily used by the virtual machine (VM); and RUNTIME means that the VM retains it and thus can be read if requested. Target: Identifies the program element associated with the metadata. The ElementType enumeration offers eight possible values: ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, and TYPE. The java.sql Package The four java.sql annotations were explored in Chapter 5: @AutoGeneratedKeys, @ResultColumn, @Select, and @Update. See Chapter 5 for more information on them. The javax.annotation Package Six annotations are found in the javax.annotation package. These are heavily weighted toward usage with the enterprise edition of the Java platform, but are a standard part of Java SE 6. When used, they can provide additional information to the application server.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
CHAPTER 10 PLUGGABLE ANNOTATION PROCESSING UPDATES 187 However, because of the @Override, you learn at compile time that there are problems, as shown in the following snippet: > javac Over.java Over.java:6: method does not override a method from its superclass @Override ^ 1 error Thus, you can fix the problem sooner and more cheaply because it is identified much earlier in the process. JDK 6.0 Annotations JSR 175 defined the original metadata facility of JDK 5.0. JSR 269 introduces the Pluggable Annotation Processing API, which is a part of JDK 6.0. This standardizes some processing that was difficult at best with JDK 5.0 when creating your own annotations. In addition to this standardization, JDK 6.0 adds its own set of new annotations, many of which have been described in earlier chapters. We ll look at the new annotations first. New Annotations There is no single place I could find that listed all the annotations, new and old. The best you can do is grep through the source and find the classes defined with an @interface, as in the following line: public @interface ResultColumn { When defining your own annotations, that is the syntax for how they are declared. Here is information about all the annotations in JDK 6.0. Why use them for your classes? Because tools that know about them can be made smarter to make your life as a developer easier. The java.beans Package The first annotation, @ConstructorProperties, is used in conjunction with a JavaBeans component constructor. If you are using a third-party library with an IDE and don t necessarily know the names or order of the arguments to the constructor (but you do know their types), the @ConstructorProperties annotation can be used to designate their appropriate order by name. Thus, the IDE can present names for arguments, not just types. Listing 10-4 shows what using the @ConstructorProperties annotation might look like for a fictitious Point class with two properties, x and y, of the same type.
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services