blob: b851e40240ca06c953ab6270ba07a70979e38d0c [file] [log] [blame]
<html>
<head>
<title>Using JAM to ease the transition to JSR175</title>
<link href="jam.css" rel="stylesheet" type="text/css" />
</style>
</head>
<body>
<h2>Using JAM to ease the transition to JSR175</h2>
<p>This document describes how <a href='/stuff/jamdocs'>JAM</a> can help you transition your metadata processing from javadoc tags to <a href='http://www.jcp.org/en/jsr/detail?id=175'>JSR175</a>.
<h3>Before you can require 1.5</h3>
<p>First, define a set of java beans that reflect what you expect your
175 annotation types to ultimately look like. Ideally, they should also
directly reflect the javadoc tags you are currently using. (If they can't,
you will have to do a little more work than this example describes - more
on that later). Here is a simple example of such a bean:</p>
<pre>
package foo.bar;
/**
* This is a 'fake' 175 annotation type that will work under 1.4.
* It's just a generic java bean except that it should conform to
* the 175 annotation conventions. This means, among other things,
* that the getters are not prefixed with 'get'.
*/
public class MyAnnotation {
public MyAnnotation() {} // a public no-arg constructor is required
public int id() { return mId;}
public void setId(int id) { mId = id; }
private int mId = 13;
}
</pre>
<p>In your client/tool code, when creating a JService, you need to specify
a mapping between javadoc tag names and the qualified classnames of these
annotation beans. For example:</p>
<pre>
String[][] mappings = { "myannotation", "foo.bar.MyAnnotation" };
JServiceFactory factory = JServiceFactory.getInstance();
JServiceParams params = factory.createServiceParams();
p.setJavadoc175Mappings(mappings);
// (also do other stuff like include your .java files in the params)
JService service = factory.createService(params);
</pre>
<p>For every javadoc tag encountered named 'myannotation,' and instance
of foo.bar.MyAnnotation will be created and populated by mapping the
tag attributes to the setters via reflection. For example, if you
were using the JService created above to inspect the following source
file:
<pre>
package foo.bar;
/**
* @myannotation id=42
*/
public class SomeClass {
}
</pre>
<p>you could access the myannotation metadata as follows:</p>
<pre>
JClass someClass = service.getClassLoader().load("foo.bar.SomeClass");
JAnnotation jAnn = someClass.getAnnotation(MyAnnotation.class);
MyAnnotation myAnnotation = (MyAnnotation)jAnn.getAnnotationObject();
System.out.println(myAnnotation.getId()); // prints out 42
</pre>
<p>In this way, our access to the javadoc'ed metadata is strongly-typed,
structured, and isolated from the vagaries of javadoc parsing. Better still,
the stage is now set for an easy transition to JSR175-style annotations,
even though none of the code here requires JDK 1.5.</p>
<h3>After you can require 1.5</h3>
<p>Once you are sure that you can require JRE 1.5, and
that you no longer need to support javadoc tags, the transition away from
this mechanism is extremely simple. Building on the previous example,
the first step is to change MyAnnotation.java so that MyAnnotation is a
genuine 175 annotation:</p>
<pre>
package foo.bar;
/**
* This is a genuine 175 annotation type.
*/
public @interface MyAnnotation {
int id() default 13;
}
</pre>
<p>It is important to be sure that the package and class name remains the
same so that your client code does not need to change. With this done,
it no longer is necessary to provide the javadoc-to-class mappings
as we did above when creating the JService. Now, all we have to do is:</p>
<pre>
JServiceFactory factory = JServiceFactory.getInstance();
JServiceParams params = factory.createServiceParams();
// (also do other stuff like include your .java files in the params)
JService service = factory.createService(params);
</pre>
<p>That's it. The beautiful part is that our client code does not
have to change at all:</p>
<pre>
JClass someClass = service.getClassLoader().load("foo.bar.SomeClass");
JAnnotation jAnn = someClass.getAnnotation(MyAnnotation.class);
MyAnnotation myAnnotation = (MyAnnotation)jAnn.getAnnotationObject();
System.out.println(myAnnotation.getId()); // still prints out 42
</pre>
<p>The MyAnnotation instance we get here is no longer the annnotation
bean we defined earlier - it's a real java.lang.annotation.Annotation.
But the beauty of it is that because we planned things out well, it
doesn't make any difference to the client code.</p>
<p>Again, though, it's important to note that once we get to this point,
nothing will work without JRE 1.5, and javadoc-style metadata will no
longer be recognized.</p>
</body>
</html>