We have finally arrived at our last and final part of this series of articles on annotations.
In the previous three articles (part 1, part 2 and part 3), we saw how to design and develop a custom annotation; we also looked at how to write a processor to handle the custom annotation. Now we come to the part where we put all these elements together and see how to use them. Finally, if you are interested in developing this @Option annotation further, I'll give some suggestions at the end of this article.
Using the ""="">@Option Annotation
In the first
article are details on how to use the ""="">@Option annotation and generate the option processor, so I will not repeat them
here. I will, however, talk about packaging and environment settings.
- The
easiest way to distribute our annotation and its corresponding processor
is to package it in a JAR file. Generally you package the annotation
class, the annotation processor class and all utility classes used by the
processor. In our case, we have only 2 classes to package, ""="">options.Option.class and ""="">options.OptionProcessor.class
- When you are annotating your option bean with the ""="">@Option annotation, you have to either add the
annotation JAR to your ""="">CLASSPATH environment variable or as a classpath parameter when you are compiling the option bean.
-
Now, when you are generating the option processor class, you have to again
either include the annotation JAR in your CLASSPATH environment variable
or use""="">-classpath option to ""="">javac.
You will also need to specify the name of the processor class by using the
""="">-processor option. Unfortunately at the time of writing,
this option has yet to be documented on the official Java 6 (a.k.a Mustang)
Javadocs. Below is an example of using ""="">-processor option:
javac
-processor options.OptionProcessor -classpath ./options.jar \
FileTransferOptions.java
|
The ""="">FileTransferOptions.java is our option bean; the ""="">options.OptionProcessor is our option processor fully qualified class name.
Note that we use""="">-processor to specify the option processor class to use.
Assume that ""="">options.jar is where we package the annotation and processor
class.
The class ""="">FileTransferOptionsProcessor will be generated after the compilation. You can now
use this class to process all the option switches defined in ""="">FileTransferOptions. Again see the first
article on how you use this.
Going Further
The options processor
developed in this series of articles is quite simplistic. If you are interested
in developing it further, here are some ideas:
- Error
checking is not done on the option switches. The generated option
processor will just ignore any switches that it did not understand. Add
error handling so that the option processor will print out the list of
options and its corresponding help string, if any, when it encounters an
error.
- Auto
generate a help switch (""="">-help) so that it will print out the list of supported
options and its corresponding help string, if any.
java
Main -help
The options are
-filename - Text file name
-config - Configuration file
-server |
- Currently
the option processor only supports ""="">String; rewrite
the option processor so that it supports all primitive types. The option
processor should look at the type in the option bean and automatically
convert the option value to the corresponding type. Here is an example:
public class
MyOptions {
@Option(name="-filename") public String fileName;
@Option(name="-copies", help="Number of
copies") public int copies;
@Option(name="-header", help="Print header?
y|n") public boolean printHeader;
@Option(name="-printer") public String printServer;
} |
Now if we type the following
java
Main -filename fred.txt -copies 2 -header n -printer myprinter |
then ""="">2
and ""="">n will be converted to the integer value ""="">2
and ""="">false respectively.
- Support
for multi-valued options. In the code snipped below -filename is
multivalued; this is inferred from the ""="">String array
public class
MyOptions {
@Option(name="-filename") public String[] fileName;
@Option(name="-copies", help="Number of
copies") public int copies;
... |
The following are two ways of
how you specify multivalued options:
java
Main -filename fred.txt barney.txt -header n -printer myprinter |
or
java
Main -filename fred.txt -filename barney.txt -header n -printer myprinter |
- Regular
expression support
public class
MyOptions {
@Option(name="^-[Ff][Ii][Ll][Ee][[Nn][Aa][Mm][Ee]]*",
re=true) public String[] fileName;
@Option(name="-copies", help="Number of
copies") public int copies;
... |
The following are then valid options
java
Main -FileName fred.txt -file barney.txt -header n -printer myprinter |
- If
there is anything else you care to implement, here are some suggestions:
validators, mutually exclusive options and option switch only viz. specify
""="">-debug to enable the debug option instead of ""="">-debug y
Lee Chuk-Munn has been programming in the Java language since 1996, when he first joined Sun Microsystems in Hong Kong. He currently works as a senior developer consultant and technology evangelist for Technology Outreach at Sun in Singapore. Chuk's focus is in Java APIs, Java EE, Java SE, and Java ME. Chuk graduated in 1987 from the Royal Melbourne Institute of Technology in Melbourne, Australia, where his favorite subject was compiler theory.