Print
XDoclet 1.x Vs XDoclet2 comparison

XDoclet 1.x Vs XDoclet2 comparison

XDoclet 1.x Architecture

• XDoclet 1.x can be run only from Ant. It is probably not as restrictive as it is made out to be. But then the fact is that you are tied to Ant interface.

• XDoclet 1.x folks developed XJavaDoc that can read custom doclet tags from java source files. If you find a better, faster way of parsing and extracting information from @tags from java source files, you simply cannot get XDoclet to use the new engine. Or worse, XDoclet is rendered un-usable if the metadata source is not Java.

• If you don't understand XDoclet templates or find it too complex, you cant write custom templates. XDoclet is tightly coupled to its own template language.

• In essence XDoclet 1.x architecture, by commiting itself to concrete implementations of the parser and template language, imposes severe restrictions on itself.

Next we will see how XDoclet 2 breaks these dependencies on concrete implementations by following the simple yet effective principle of 'Program to an Interface and NOT to an Implementation'

XDoclet2 Architecture

• XDoclet is a wrapper on top of Generama. Generama in turn just extends PicoContainer. Ant is just one way of invoking generama. It can be as easily invoked from a commandline for eg.

• Generama leaves it to us to register a MetadataProvider. It just provides QDoxMetaDataProvider by default. But you can easily provide an implementation of MetaDataProvider to pull metadata from a database for example.

• Generama abstracts away the Template Engine behind an interface. We just plugged in a Groovy Template Engine sometimeback.

• The generated QDox tags automatically incorporate tag validation. So we should hopefully not run into nasty surprises during deployment. The errors are caught in the build stage itself.

You probably don't believe that invoking XDoclet2 plugin from command line is a breeze. If that is indeed the case, lets quickly put that to rest by developing a simple utility.

Invoking XDoclet2 Plugin from Command line

We will try invoking the GroovyCommandPlugin that we developed earlier from command line. We also need to make sure that it will work for your plugin as well. That informs us that our utility class is likely to be abstract, needs to work with abstract org.generama.Plugin class and that we need to delegate the task of creating the concrete plugin to the implementers.We inject ('explicitly that is') an instance of SinkWriterMapper and 'start' the plugin which runs the plugin and causes the template engine to flush its output to a java.io.StringWriter.

AbstractRunPluginFromCommandLineUtil.java
import org.generama.MetadataProvider;
import org.generama.Plugin;
import org.generama.WriterMapper;
import org.generama.tests.SinkWriterMapper;

abstract class AbstractRunPluginFromCommandLineUtil{

    protected Plugin plugin;
    private SinkWriterMapper writerMapper;

    public AbstractRunPluginFromCommandLineUtil() throws Throwable {
      writerMapper = new SinkWriterMapper();
      plugin = createPlugin(createMetadataProvider(), writerMapper);
    }

    public void run() throws Throwable {
      try{
        plugin.start();
      }finally{
        System.out.println("++++++++++++Generated Content Start++++++++++++\n\n");
        System.out.println(writerMapper.getContent());
        System.out.println("\n\n++++++++++++Generated Content End++++++++++++");
      }    
    }

    protected abstract Plugin createPlugin(MetadataProvider metadataProvider, WriterMapper writerMapper) throws Exception;
    protected abstract MetadataProvider createMetadataProvider() throws Exception;
}

Concrete implementations of the above class can then be provided. Find below RunGroovyCommandPluginFromCommandLine.java for eg:

RunGroovyCommandPluginFromCommandLine.java
public class RunGroovyCommandPluginFromCommandLine extends AbstractRunPluginFromCommandLineUtil {

  public RunCommandPluginFromCommandLineUtil() throws Throwable{
    super();
  }

  protected MetadataProvider createMetadataProvider() throws IOException {
    URL reader = new File("D:/software/java/XDoclet2/Xdoclet-JAG/Xdoclet-JAG/src/main/java").toURL();
    return new QDoxMetadataProvider(new File(reader.getPath()));
  }

  protected Plugin createPlugin(MetadataProvider metadataProvider, WriterMapper writerMapper)
    throws Exception {
   return new GroovyCommandPlugin(new GroovyTemplateEngine(), (QDoxMetadataProvider) metadataProvider, writerMapper);
  }

  public static void main(String[] args) throws Throwable{
    AbstractRunPluginFromCommandLineUtil pluginRunner = new RunCommandPluginFromCommandLineUtil();
    pluginRunner.run();

  }

}

XDoclet1.x comparisons //TODO

XDoclet1.x has a concept of tasks and sub tasks. Each task addresses a specific while the sub-tasks do the actual code generation. XDoclet2 does not have an equivalent for a XDoclet1.x task. The XDoclet2 plugins are equivalent to Xdoclet1.x tasks. When using XDoclet1.x, one needs to declare all the tasks that one intends to employ using ant's ,<taskdef> element.

Powered by Atlassian Confluence