January 21, 2021
Hot Topics:

Make Your Code Work for You with Java Annotations

  • By David Thurmond
  • Send Email »
  • More Articles »

The @Help annotation allows the programmer to specify three parameters: a context ID, a help topic, and text. Each parameter corresponds to a method declared in the annotation's interface. Valid return values for these methods include primitive data types, such as int, double, char, Boolean, and so on; strings, classes, enumerations, annotations, and arrays of any of these types. Annotation parameter methods are not allowed to accept any arguments, nor are they allowed to throw any exceptions. Doing either will result in a compiler error.

Note that the @Retention annotation in Listing 3 indicates that the @Help annotation's information is available to any development tools only at coding time. Also, note that the @Target annotation indicates that a @Help annotation can appear on any Java program element.

A method that uses the @Help annotation might look like the one shown in Listing 4.

Listing 4: Using @Help annotation in code

 * @Help (contextID=99, topic="How To Do Something Terrific",
 *        text="When you invoke the doSomething() method,
 *        something awesome might happen.")
public void doSomething() {
}    // doSomething()

The method declaration above shows that the parameters specified in parentheses correspond to the method names in the annotation interface declared earlier. The order of the parameters does not matter, but the data type for each parameter must correspond to the data type of the corresponding method in the annotation interface; otherwise, a compiler error will be generated. Note that strings must be enclosed in quotes as shown.

Listing 5 shows one last bit of razzle-dazzle that can be used when creating your own annotations: allowing some parameters to be optional.

Listing 5: MemoryCheck.java

package com.dlt.developer.annotation;

import java.lang.annotation.*;

public @interface MemoryCheck {
   public static final String B  = "B";
   public static final String KB = "KB";
   public static final String MB = "MB";

   String size() default KB;
}    // interface MemoryCheck

This annotation only accepts one parameter, size, which is optional, and will default to KB if it is not specified, as shown by the "default" keyword after the method declaration.

Annotations serve no purpose unless they are used by development tools, so the following sections show how to create tools that use the annotations created above at coding time and run time.

Using Annotations at Coding Time

Coding can be a lot of work, but remember the old saying, "Work smarter, not harder.W Annotations are a great way to take the drudgery out of repetitive coding tasks, such as coding Enterprise Java Beans' local and remote interfaces, bean descriptor files, JSP taglib files, wrapper classes, and so on.

Rather than focus on J2EE technologies that may not be familiar to all readers, I will demonstrate how to write a very simple help XML file using the @Help annotation shown earlier.

Listing 6 shows HelpGenerator.java, which looks through the code for the @Help annotation and generates an XML tag for each method that has the annotation. This program could be enhanced to account for help entered for constructors, fields, and other program elements that allow the @Help annotation as well.

Listing 6: HelpGenerator.java

package com.dlt.developer.helpgenerator;

import java.io.*;

import com.sun.javadoc.*;

public class HelpGenerator {

   public static boolean start(RootDoc root){
      System.out.println("Running help generator...");
      try {
      } catch (Exception e) {
         System.out.println("Error generating help.");
      }    // catch
      return true;
   }    // start()

   private static void writeContents(ClassDoc[] classes)
      throws Exception {
      System.out.println("Processing class doc...");
      for (int i=0; i < classes.length; i++) {
         StringBuffer outBuff = new StringBuffer();
         outBuff.append("<Help class=\"" + classes[i].name() +
         PrintWriter out = 
            new PrintWriter(new FileOutputStream("help_" +
            classes[i].name() + ".xml"));
         MethodDoc[] methods = classes[i].methods();
         for (int j=0; j < methods.length; j++) {
            MethodDoc theMethod = (MethodDoc)methods[j];
            System.out.println("Method " + theMethod.name());
            AnnotationDesc[] annotations = theMethod.annotations();
            for (int k=0; k < annotations.length; k++) {
               AnnotationDesc theAnnotationDesc = annotations[k];
                  AnnotationTypeDoc theAnnotationType =
               AnnotationDesc.ElementValuePair[] valuePairs =
               String contextID = "";
               String text = "";
               String topic = "";
               for (int l = 0; l < valuePairs.length; l++) {
                  AnnotationDesc.ElementValuePair thePair =
                  AnnotationTypeElementDoc theElement =
                  AnnotationValue theValue = thePair.value();
                  System.out.println("Element=" + theElement.name() +
                     " Value=" + theValue.toString());
                  if (theAnnotationType.name().equals("Help")) {
                     if (theElement.name().equals("contextID")) {
                        contextID = theValue.toString();
                     } else if (theElement.name().equals("text")) {
                        text =
                           theValue.toString().replaceAll("\"", "");
                     } else if (theElement.name().equals("topic")) {
                        topic =
                           theValue.toString().replaceAll("\"", "");
                     }    // if
                  }       // if
               }          // for l
               if (theAnnotationType.name().equals("Help")) {
                  outBuff.append("<HelpTopic contextID=\"");
                  outBuff.append("\" topic=\"");
                  outBuff.append("\" text=\"");
                  outBuff.append(text); outBuff.append("\"/>");
               }    // if
            }       // for k
         }          // for j
      }    // for i
   }       // writeContents()
}          // class HelpGenerator

Page 2 of 4

This article was originally published on December 15, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date