<chapter id="annotationcompiler">
   <title>Annotation Compiler for JDK 1.4</title>
   <sect1 id="annotationcompiler-annotations" revision="1">
      <title>Annotations with JDK 1.4.2</title>

      <para>
         Annotations are only available in JDK 1.5, but using our annotation compiler
         you can acheive similar functionality with JDK 1.4.2.
      </para>

      <para>
         Annotations must map to an annotation type, in JDK 1.5 they are defined as:

         <programlisting>
   package com.mypackage;
   
   public @interface MyAnnotation
   {
      String myString();
      int myInteger();
   }            
         </programlisting>
         
         Annotation types for use with the annotation compiler are defined in exactly 
         the same way for JDK 1.4.2, with the important difference that '@interface'
         is replaced by 'interface'. i.e. the simulater annotation type is a normal 
         Java interface:
         <programlisting>
   package com.mypackage;
   
   public interface MyAnnotation
   {
      String myString();
      int myInteger();
   }            
         </programlisting>
      </para>

      <para>
         The syntax for using annotations in JDK 1.4.2 is almost exactly the same as 
         JDK 1.5 annotations except for these subtle differences:
         <itemizedlist>
            <listitem>they are embedded as doclet tags</listitem>
            <listitem>You use a double at sign, i.e. '@@'</listitem>
            <listitem>
               You MUST have a space after the tag name otherwise you will get 
               a compilation error. (This is the quirkiness of the QDox doclet compiler 
               used to compile the annotations.')
            </listitem>
            <listitem>
               You cannot import the annotation type, you must use the fully
               qualified name of the interface.
            </listitem>
            <listitem>You cannot specify default values for an annotation's value</listitem>
         </itemizedlist>
      </para>

      <para>
         This example shows an annotated class in JDK 1.4.2:
         <programlisting>
   package com.mypackage;
   
   /**
    * @@com.mypackage.MyAnnotation (myString="class", myInteger=5)
    */
   public class MyClass
   {
      /**
       * @@com.mypackage.MyAnnotation (myString="field", myInteger=4)
       */
      private String myField;
      
      /**
       * @@com.mypackage.MyAnnotation (myString="constructor", myInteger=3)
       */
      public MyClass()
      {
      }
      
      /**
       * @@com.mypackage.MyAnnotation (myString="method", myInteger=3)
       */
      public int myMethod()
      {
      }
   }            
         </programlisting>
      </para>

   </sect1>
   <sect1 id="annotationcompiler-enums" revision="1">
      <title>Enums in JDK 1.4.2</title>
      <para>
         Another JDK 1.5 feature that JBoss AOP helps introduce to JBoss 1.4.2 are Enums.
         As an example we can look at the
         <literal>org.jboss.aop.advice.Scope</literal>
         enum that is used for the
         <literal>@Aspect</literal> annotation. Here is the
         JDK 1.5 version.
         <programlisting>
            package org.jboss.aop.advice;
            
            public enum Scope
            {
               PER_VM, PER_CLASS, PER_INSTANCE, PER_JOINPOINT
            }         
         </programlisting>
         
         And it's usage in JDK 1.5
         <programlisting>
   package com.mypackage;

   @Aspect (scope=org.jboss.aop.advice.Scope.PER_VM)
   public class SomeAspect
   {
   }     
         </programlisting>
         The usage in JDK 1.4.2 is similar:
         <programlisting>
   package com.mypackage;
   
   /**
    * @@org.jboss.aop.Aspect (scope=org.jboss.aop.advice.Scope.PER_VM)
    */
   public class SomeAspect
   {
      //...
   }     
         </programlisting>
         However the declaration of the enumeration is different in 1.4.2:
         <programlisting>
   package org.jboss.aop.advice;
   
   import java.io.ObjectStreamException;
   
   public class Scope extends org.jboss.lang.Enum
   {
      private Scope(String name, int v)
      {
         super(name, v);
      }
   
      public static final Scope PER_VM = new Scope("PER_VM", 0);
      public static final Scope PER_CLASS = new Scope("PER_CLASS", 1);
      public static final Scope PER_INSTANCE = new Scope("PER_INSTANCE", 2);
      public static final Scope PER_JOINPOINT = new Scope("PER_JOINPOINT", 3);
      
      private static final Scope[] values = {PER_VM, PER_CLASS, PER_INSTANCE, PER_JOINPOINT};
   
      Object readResolve() throws ObjectStreamException
      {
         return values[ordinal];
      }
   
   }
         </programlisting>
      </para>
      <para>
         To create your own enum class for use within annotations, you need to inherit 
         from
         <literal>org.jboss.lang.Enum</literal>. Each enum has two values, a
         String name, and an integer ordinal. The value used for the ordinal must
         be the same as it's index in the static array.
      </para>
   </sect1>

   <sect1 id="annotationcompiler-nestedannotations" revision="1">
      <title>Using Annotations within Annotations</title>
      <para>
         The annotation compiler allows you to use annotations within annotations. This 
         is best illustrated with an example. The definitions of the annotation 
         interfaces in JDK 1.4.2:

         <programlisting>
            com.mypackage;
            
            public interface Outer
            {
               Inner[] values();
            }
         </programlisting>

         <programlisting>
            com.mypackage;
            
            public interface Inner
            {
               String str();
               int integer();
            }
         </programlisting>
      </para>
      <para>
         The annotations can be applied as follows
         <programlisting>
            com.mypackage;
            
            /**
             * @@com.mypackage.Outer ({@@com.mypackage.Inner (str="x", integer=1), \ 
                   @@com.mypackage.Inner (str="y", integer=2)})
             */
            public class Test
            {
               Inner[] values();
            }
         </programlisting>

      </para>
   </sect1>


   <sect1 id="annotationcompiler-compiler" revision="1">
      <title>Using the Annotation Compiler</title>
      <para>
         In order to use the JDK 1.4.2 annotations you have to precompile your 
         files with an annotation compiler.
      </para>

      <para>
         To use the annotation compiler you can create a simple ant build.xml file

         <programlisting>
            &lt;?xml version="1.0" encoding="UTF-8"?&gt;

            &lt;project default="run" name="JBoss/AOP"&gt;
            &lt;target name="prepare"&gt;
         </programlisting>
         Include the jars AOP depends on
         <programlisting>
            &lt;path id="javassist.classpath"&gt;
            &lt;pathelement path="../../../javassist.jar"/&gt;
            &lt;/path&gt;
            &lt;path id="trove.classpath"&gt;
            &lt;pathelement path="../../../trove.jar"/&gt;
            &lt;/path&gt;
            &lt;path id="concurrent.classpath"&gt;
            &lt;pathelement path="../../../concurrent.jar"/&gt;
            &lt;/path&gt;
            &lt;path id="jboss.common.classpath"&gt;
            &lt;pathelement path="../../../jboss-common.jar"/&gt;
            &lt;/path&gt;
            &lt;path id="jboss.aop.classpath"&gt;
            &lt;pathelement path="../../../jboss-aop.jar"/&gt;
            &lt;/path&gt;
            &lt;path id="qdox.classpath"&gt;
            &lt;pathelement path="../../../qdox.jar"/&gt;
            &lt;/path&gt;
            &lt;path id="classpath"&gt;
            &lt;path refid="javassist.classpath"/&gt;
            &lt;path refid="trove.classpath"/&gt;
            &lt;path refid="jboss.aop.classpath"/&gt;
            &lt;path refid="jboss.common.classpath"/&gt;
            &lt;path refid="concurrent.classpath"/&gt;
            &lt;path refid="qdox.classpath"/&gt;
            &lt;/path&gt;

         </programlisting>
         Define the ant task that does the annnotation compilation
         <programlisting>
            &lt;taskdef
         name="annotationc" 
         classname="org.jboss.aop.ant.AnnotationC"
         classpathref="jboss.aop.classpath"
      /&gt;
            &lt;/target&gt;


            &lt;target name="compile" depends="prepare"&gt;
         </programlisting>
         Compile the source files
         <programlisting>
            &lt;javac srcdir="."
         destdir="."
         debug="on"
         deprecation="on"
         optimize="off"
         includes="**"&gt;
            &lt;classpath refid="classpath"/&gt;
            &lt;/javac&gt;
         </programlisting>
         Run the annotation compiler
         <programlisting>

            &lt;annotationc compilerclasspathref="classpath" classpath="." bytecode="true"&gt;
            &lt;src path="."/&gt;
            &lt;/annotationc&gt;
            &lt;/target&gt;

            &lt;/project&gt;
         </programlisting>
      </para>

      <para>
         The
         <literal>org.jboss.aop.ant.AnnotationC</literal> ant task takes several parameters.

         <itemizedlist>
            <listitem>
               <literal>compilerclasspath</literal> or
               <literal>compilerclasspathref</literal> -
               These are interchangable, and represent the jars needed for the annotation compiler
               to work. The
               <literal>compilerclasspath</literal> version takes the paths of the
               jar files, and the
               <literal>compilerclasspathref</literal> version takes the
               name of a predefined ant path.
            </listitem>
            <listitem>
               <literal>bytecode</literal> - The default is false. If true the annotation compiler 
               instruments (i.e. modifies) the class files with the annotations. In this case, 
               the classes must be precompiled with javac and
               <literal>classpath</literal> or
               <literal>classpathref</literal> must be specified.
            </listitem>
            <listitem>
               <literal>classpath</literal> or
               <literal>classpathref</literal> - Path to the
               compiled classes to be instrumented with annotations, if
               <literal>bytecode</literal>="true". The
               <literal>classpath</literal>
               version takes the path of the directory, and the
               <literal>classpathref</literal>
               version takes the name of a predefined ant path.
            </listitem>
            <listitem>
               <literal>xml</literal> - Default is false. If true an xml file is generated
               containing information of how to attach the annotations at a later stage in
               the aop process.
            </listitem>
            <listitem>
               <literal>output</literal> - If
               <literal>xml</literal>="true", this lets
               you specify the name you would like for the generated xml file. The default
               name is
               <literal>metadata-aop.xml</literal>
            </listitem>
            <listitem>
               <literal>verbose</literal> - Default is false. If true, verbose output 
               is generated, which comes in handy for diagnosing unexpected results.
            </listitem>
         </itemizedlist>
         You cannot currently specify both
         <literal>bytecode</literal> and
         <literal>xml</literal>.
      </para>
      <para>
         You can also run
         <literal>org.jboss.aop.ant.AnnotationC</literal> from the command line, you need
         <programlisting>
   $ java -cp &lt;all the JBoss AOP jars and the directory containing files we want to AOP&gt; \ 
         org.jboss.aop.annotation.compiler.AnnotationCompiler \ 
         [-xml [-o outputfile ]] [-bytecode]&lt;files&gt;+
         </programlisting>
      </para>
      <para>
         In the /bin folder of the distribution we have provided batch/script files to make
         this easier. It includes all the aop libs for you, so you just have to worry
         about your files. The usage is:
         <programlisting>
   $ annotationc &lt;classpath&gt; [-verbose] [-xml [-o outputfile]] [-bytecode] &lt;dir_or_file&gt;+
         </programlisting>
      </para>
      <para>
         <itemizedlist>
            <listitem>
               <literal>classpath</literal> - path to your classes and any jars your code depends on
            </listitem>
         </itemizedlist>
         The other parameters are the same as above.
      </para>
   </sect1>
</chapter>

