JBoss.orgCommunity Documentation

Chapter 27. Java Class File Sequencer

The Java class file sequencer parses Java class file to extract metadata for the class, its methods, its fields, and its annotations. The output of the sequencer can be customized by using the classFileRecorder or classFileRecorderClassName properties to provide a custom implementation of the ClassFileRecorder interface. A default implementation (DefaultClassFileRecorder) is provided that records all extracted metadata to the output location.

As noted previously, the ClassFileSequencer class provides a pair of JavaBean properties that can be used to specify a custom ClassFileRecorder implementation to use to map the extracted metadata to an output location:

Table 27.1. ClassFileSequencer properties

PropertyDescription
classFileRecorder Optional property that, if set, provides an instance of the ClassFileRecorder interface that will be used for all subsequent sequencing activity for this sequencer. If this property is set to null, a default implementation will be used. The default value of this property is null.
classFileRecorderClassName Optional property that, if set, provides the name of a class that provides a custom implementation of the ClassFileRecorder interface. This class must have a no-argument, public constructor. If set, an instance of this class will be created immediately and reused for all subsequent sequencing activity for this sequencer. If this property is set to null, a default implementation will be used. The default value of this property is null.

The default class file recorder creates a subgraph rooted at the output location that takes the following form:



<nt:unstructured jcr:name="packageName1"
                 jcr:mixinTypes = mode:derived 
                 mode:derivedAt="2011-05-13T13:12:03.925Z" 
                 mode:derivedFrom="/files/org/modeshape/Foo.class">
    ...
    <nt:unstructured jcr:name="packageNameN">
        <class:class jcr:name="ClassName">
            <class:annotations jcr:name="class:annotations">
                <class:annotation jcr:name="AnnotationName1"/>
                ...
                <class:annotation jcr:name="AnnotationNameN"/>
            </class:annotations>
            <class:constructors jcr:name="class:constructors">
                <class:constructor jcr:name="constructor parameters">
                    <class:annotation jcr:name="AnnotationName1"/>
                    ...
                    <class:annotation jcr:name="AnnotationNameN"/>
                </class:constructor>
            </class:constructors>
            <class:methods jcr:name="class:methods">
                <class:method jcr:name="methodName(parameters)">
                    <class:annotation jcr:name="AnnotationName1"/>
                    ...
                    <class:annotation jcr:name="AnnotationNameN"/>
                </class:method>
            </class:methods>
            <class:fields jcr:name="class:fields">
                <class:field jcr:name="fieldName">
                    <class:annotation jcr:name="AnnotationName1"/>
                    ...
                    <class:annotation jcr:name="AnnotationNameN"/>
                </class:field>
            </class:fields>
          </class:class>
    </nt:unstructured>
    ...
</nt:unstructured>

The compact node definitions for the class:* types is provided below. Please note that these definitions may change in a future release.

	
[class:annotationMember]
- class:name (string) mandatory
- class:value (string) 

[class:annotation]
- class:name (string) mandatory
+ * (class:annotationMember) = class:annotationMember

[class:annotations]
+ * (class:annotation) = class:annotation

[class:field]
- class:name (string) mandatory 
- class:typeClassName (string) mandatory 
- class:visibility (string) mandatory < 'public', 'protected', 'package', 'private'
- class:static (boolean) mandatory
- class:final (boolean) mandatory
- class:transient (boolean) mandatory
- class:volatile (boolean) mandatory
+ class:annotations (class:annotations) = class:annotations

[class:fields]
+ * (class:field) = class:field

[class:interfaces]
- * (string)

[class:parameters]
- * (string)

[class:method]
- class:name (string) mandatory 
- class:returnTypeClassName (string) mandatory 
- class:visibility (string) mandatory < 'public', 'protected', 'package', 'private'
- class:static (boolean) mandatory
- class:final (boolean) mandatory
- class:abstract (boolean) mandatory
- class:strictFp (boolean) mandatory
- class:native (boolean) mandatory
- class:synchronized (boolean) mandatory
- class:parameters (string) multiple
+ class:annotations (class:annotations) = class:annotations

[class:methods]
+ * (class:method) = class:method

[class:constructors]
+ * (class:method) = class:method

[class:class]
- class:name (string) mandatory 
- class:superClassName (string) 
- class:visibility (string) mandatory < 'public', 'protected', 'package', 'private'
- class:abstract (boolean) mandatory
- class:interface (boolean) mandatory
- class:final (boolean) mandatory
- class:strictFp (boolean) mandatory
- class:interfaces (string) multiple
+ class:annotations (class:annotations) = class:annotations
+ class:constructors (class:constructors) = class:constructors
+ class:methods (class:methods) = class:methods
+ class:fields (class:fields) = class:fields

[class:enum] > class:class
- class:enumValues (string) mandatory multiple
 

To use this sequencer, simply include the modeshape-sequencer-classfile JAR in your application and configure the JcrConfiguration to use this sequencer using something similar to:



JcrConfiguration config = ...
config.sequencer("Java Class Sequencer")
      .usingClass(ClassFileSequencer.class)
      .setDescription("Sequences Java class files to extract the structure of the classes")
      .sequencingFrom("//*.class[*]/jcr:content[@jcr:data]")
      .andOutputtingTo("/classes");