Pages

Saturday, October 11, 2008

I work on flex and it was necessary for me to generate the flex side model classes in sync with the java side value objects. I Googled but was not able to find one that is as simple as the one written by Joe Berkovitz of Allurent. It was pretty old code and lacked configuration options for generating AS classes. I decided to write my own plugin for xdoclet2 that can be used to generate the flex code. And, here given below is a tutorial for learning xdoclet2. Since, the template engine it uses is velocity, this post also serves as a tutorial for velocity. Finally, I provide you with a complete working edition of the xdoclet2 plugin, and a sample to use the same.

Please look at the end of this tutorial to find links to the source, plugin jar and sample files.

XDoclet2 allows you to read the annotations on the java source files, and generate either XML or Java or any other file. It uses velocity template engine for any file type generation, and Jelly template engine for XML generation.

Define Tag validators. This is helpful for validating if the annotations provided are as anticipated. Tag validators extends DocletTag as shown below. The interface itself is annotated using the qtags.

There are some points to be noted:a. There is a one to one matching between the name of the interface - As3ClassTag - and the annotation on the sample class -as3.class-. The First letter is capitalized, the '.' is removed, the next letter is also capitalized, a 'Tag' is appended. b. The methods in the interface uses the standard java bean convention. For each attribute in the tag, 'get' or 'is' is prefixed to the attribute name with the first letter capitalized. c. 'name' is a special attribute, a '_' should be used at the end of the getter to avoid internal naming collision. d. The attribute when contains '-', the methods in the interface nelects it and follows the first letter capitalization rule. e. Do not use camel casing in the sample annotation. Use only small letters or hyphens to separate for ease of work.

Definitions of tags:a. qtags.location Whether the tag applies to class level or field level or method level, repectively, we have class, field, method as its values. b. qtags.once The tag can be used only once in teh source file. c. qtags.required The field is required. d. qtags.default The default value of the field.

Step 4:

Generate the tag validator implementation and tag library. The tag library will be used by our plugin. A ant script is used to generate these items. The target to generate is given below. Please look at source code to get the entire build script.

In the above snippet, the constructor takes VelocityTemplateEngine as argument. Do not bother how it gets that. The xdoclet is responsible for injecting it to the constructor. First, call the super class constructor.

/** * Over ridden method, determines whether the given java class should be converted to as3 or not. * * @param metadata A java Class. * @return */ public boolean shouldGenerate(Object metadata) { JavaClass javaClass = (JavaClass) metadata; boolean ignore = "false".equalsIgnoreCase(javaClass.getNamedParameter("as3.class","generate")); if (!ignore) return true; else return false; } The above method decides whether AS files should be generated or not for the annotated java file. This is called by xdoclet and the Object argument is a JavaClass type. The getNamedParameter takes the annotation name and the attribute whose value has to be retrieved. If, it is false then do not generate the AS file.

The above code initializes the context map by adding tagUtil, so that it can be accessed by velocity template.

Now for each of the annotation and its attribute write a public method to get its value. This is present in TagUtil.java. Remember, it is public. Protected will not work, as this will be later used by the Velocity. Here below are sample for two of them:

Step 1: Create a As3Plugin.vm file at com.ssb.plugin.as3 package, same package as the plugin. The file name must identical to the plugin name.

Step 2: Write the velocity code in the vm file. It is shown below as snippets.

// ${dontedit} #set( $class = $metadata ) #set( $truevalue = "true")

The ${} are variables that can hold values in the VTL(Velocity template language). #set is used to assign values. In working with xdoclet, the $metadata is injected from xdoclet and holds the class name. $truevalue is assigned string 'true';

Other variables that are available to the velocity are $plugin and $tagUtil. $plugin holds the instance of the As3Plugin class. Velocity can be used to invoke java methods through this variable, passing any arguments if required. The getDestinationPackage method is present in the base class of the As3Plugin. It gives the package of the java class. The package of the AS class will be same as this one. #foreach is a directive to loop in velocity. Velocity supports #if#elseif#else#end directive also. Any method you see being invoked on $plugin is actually being invoked on As3Plugin java side object. So, shouldImport calls the As3Plugin classes shouldImport method. Similarly, isGenerateBindableMetadata calls the TagUtil classes isGenerateBindableMetadata method.

Velocity supports writing methods, by defining macro's etc, but that is not needed for writing this template file. That's all is velocity!! Its the most basic stuff in velocity that is being used here. Please refer velocity user manual for more detailed information( http://velocity.apache.org/engine/devel/user-guide.html ).

Every thing needed for our plugin is now in place. Just compile the classes, include all the resources and build the plugin jar. The build script is provided in the source.

1. Download the latest plugin jar from dist folder (as3-plugin.jar) to use the lib.

2. Download the latest source of the plugin by cloning git (or download zip). Edit the build.properties to provide the xdoclet2 installation directory. Run ant on build.xml to generate the as3-plugin.jar in the base directory.

3. Download the latest samples from sample folder by cloning git (or download zip). Edit the build.properties to provide the xdoclet2 installation directory. Run ant on build.xml to generate Model.as, Model2.as at com.ssb.sample.

4. Download the latest java doc from folder api on git by cloning or downloading zip.

Please read my next post to understand the capabilities of the plugin.