<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ ModeShape (http://www.modeshape.org)
  ~
  ~ See the COPYRIGHT.txt file distributed with this work for information
  ~ regarding copyright ownership.  Some portions may be licensed
  ~ to Red Hat, Inc. under one or more contributor license agreements.
  ~ See the AUTHORS.txt file in the distribution for a full listing of 
  ~ individual contributors.
  ~
  ~ ModeShape is free software. Unless otherwise indicated, all code in ModeShape
  ~ is licensed to you under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ ModeShape is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"	[
<!ENTITY % CustomDTD SYSTEM "../../custom.dtd">
%CustomDTD;
]>
<chapter id="java-class-sequencer">
  <title>Java Class File Sequencer</title>
     <para>
		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 <code>classFileRecorder</code> or <code>classFileRecorderClassName</code> 
		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.  
     </para>
	<para>
		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:
	</para>
	<table frame='all'>
		<title>&ClassFileSequencer; properties</title>
		<tgroup cols='2' align='left' colsep='1' rowsep='1'>
      <colspec colname='c1' colwidth="1*"/>
      <colspec colname='c2' colwidth="1*"/>
			<thead>
				<row>
		  		<entry>Property</entry>
		  		<entry>Description</entry>
				</row>
			</thead>
			<tbody>
				<row>
					<entry>classFileRecorder</entry>
					<entry>
						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.  
					</entry>
				</row>
				<row>
					<entry>classFileRecorderClassName</entry>
					<entry>
						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.  
					</entry>
				</row>
			</tbody>
		</tgroup>
	</table>
	<para>
		The default class file recorder creates a subgraph rooted at the output location that takes the following form:  
	</para>
	<programlisting language="XML" role="XML"><![CDATA[
<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>
]]></programlisting>
	<para>
		The compact node definitions for the class:* types is provided below.  <emphasis>Please note that these definitions may change in a future release.</emphasis>
	</para>
	<programlisting><![CDATA[
	
[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
 ]]></programlisting>
    <para>
        To use this sequencer, simply include the <code>modeshape-sequencer-classfile</code> JAR
        in your application and configure the &JcrConfiguration; to use this sequencer using something similar to:
    </para>
   	<programlisting language="JAVA" role="JAVA"><![CDATA[
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");
]]></programlisting>

</chapter>
