FELIX-1684 JavaDoc extensions
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@821016 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
index b9e1794..87dedbe 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.scrplugin;
+
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
@@ -35,10 +36,16 @@
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaSource;
+
/**
- * The <code>JavaClassDescriptorManager</code>
+ * The <code>JavaClassDescriptorManager</code> must be implemented to provide
+ * access to the java sources to be scanned for descriptor annotations and
+ * JavaDoc tags, the descriptors of components from the class path and the
+ * location of the generated class files to be able to add the bind and unbind
+ * methods.
*/
-public abstract class JavaClassDescriptorManager {
+public abstract class JavaClassDescriptorManager
+{
/** The maven log. */
protected final Log log;
@@ -60,6 +67,7 @@
/** Process Annotations? */
private final boolean processAnnotations;
+
/**
* Construct a new manager.
* @param log
@@ -71,41 +79,78 @@
* @throws SCRDescriptorFailureException
* @throws SCRDescriptorException
*/
- public JavaClassDescriptorManager(final Log log,
- final ClassLoader classLoader,
- final String[] annotationTagProviders,
- final boolean parseJavadocs,
- final boolean processAnnotations)
- throws SCRDescriptorFailureException {
+ public JavaClassDescriptorManager( final Log log, final ClassLoader classLoader,
+ final String[] annotationTagProviders, final boolean parseJavadocs, final boolean processAnnotations )
+ throws SCRDescriptorFailureException
+ {
this.processAnnotations = processAnnotations;
this.parseJavadocs = parseJavadocs;
this.log = log;
- this.annotationTagProviderManager = new AnnotationTagProviderManager(annotationTagProviders);
+ this.annotationTagProviderManager = new AnnotationTagProviderManager( annotationTagProviders );
this.classloader = classLoader;
ClassUtil.classLoader = this.classloader;
}
+
+ /**
+ * Returns the QDox JavaSource instances representing the source files
+ * for which the Declarative Services and Metatype descriptors have to be
+ * generated.
+ *
+ * @throws SCRDescriptorException May be thrown if an error occurrs gathering
+ * the java sources.
+ */
+ protected abstract JavaSource[] getSources() throws SCRDescriptorException;
+
+
+ /**
+ * Returns a map of component descriptors which may be extended by the java
+ * sources returned by the {@link #getSources()} method.
+ *
+ * @throws SCRDescriptorException May be thrown if an error occurrs gethering
+ * the component descriptors.
+ */
+ protected abstract Map<String, Component> getComponentDescriptors() throws SCRDescriptorException;
+
+
+ /**
+ * Returns the absolute filesystem path to the directory where the classes
+ * compiled from the java source files (see {@link #getSources()}) have been
+ * placed.
+ * <p>
+ * This method is called to find the class files to which bind and unbind
+ * methods are to be added.
+ */
+ public abstract String getOutputDirectory();
+
+
/**
* Return the log.
*/
- public Log getLog() {
+ public Log getLog()
+ {
return this.log;
}
+
/**
* Return the class laoder.
*/
- public ClassLoader getClassLoader() {
+ public ClassLoader getClassLoader()
+ {
return this.classloader;
}
+
/**
* @return Annotation tag provider manager
*/
- public AnnotationTagProviderManager getAnnotationTagProviderManager() {
+ public AnnotationTagProviderManager getAnnotationTagProviderManager()
+ {
return this.annotationTagProviderManager;
}
+
/**
* Returns <code>true</code> if this class descriptor manager is parsing
* JavaDoc tags.
@@ -115,6 +160,7 @@
return parseJavadocs;
}
+
/**
* Returns <code>true</code> if this class descriptor manager is parsing
* Java 5 annotations.
@@ -124,101 +170,123 @@
return processAnnotations;
}
- protected Components parseServiceComponentDescriptor(InputStream file)
- throws SCRDescriptorException {
- final Components list = ComponentDescriptorIO.read(file);
- return list;
- }
/**
- * Get the absolute path to the target directory where the class files are
- * compiled to.
+ * Parses the descriptors read from the given input stream. This method
+ * may be called by the {@link #getComponentDescriptors()} method to parse
+ * the descriptors gathered in an implementation dependent way.
+ *
+ * @throws SCRDescriptorException If an error occurrs reading the descriptors
+ * from the stream.
*/
- public abstract String getOutputDirectory();
+ protected Components parseServiceComponentDescriptor( InputStream file ) throws SCRDescriptorException
+ {
+ return ComponentDescriptorIO.read( file );
+ }
/**
* Return all source descriptions of this project.
* @return All contained java class descriptions.
*/
- public JavaClassDescription[] getSourceDescriptions() throws SCRDescriptorException {
+ public JavaClassDescription[] getSourceDescriptions() throws SCRDescriptorException
+ {
final JavaClass[] javaClasses = getJavaClassesFromSources();
final JavaClassDescription[] descs = new JavaClassDescription[javaClasses.length];
- for(int i=0; i<javaClasses.length; i++) {
- descs[i] = this.getJavaClassDescription(javaClasses[i].getFullyQualifiedName());
+ for ( int i = 0; i < javaClasses.length; i++ )
+ {
+ descs[i] = this.getJavaClassDescription( javaClasses[i].getFullyQualifiedName() );
}
return descs;
}
+
/**
* Get a java class description for the class.
* @param className
* @return The java class description.
* @throws SCRDescriptorException
*/
- public JavaClassDescription getJavaClassDescription(String className)
- throws SCRDescriptorException {
- JavaClassDescription result = this.javaClassDescriptions.get(className);
- if ( result == null ) {
- this.log.debug("Searching description for: " + className);
+ public JavaClassDescription getJavaClassDescription( String className ) throws SCRDescriptorException
+ {
+ JavaClassDescription result = this.javaClassDescriptions.get( className );
+ if ( result == null )
+ {
+ this.log.debug( "Searching description for: " + className );
int index = 0;
final JavaClass[] javaClasses = getJavaClassesFromSources();
- while ( result == null && index < javaClasses.length) {
+ while ( result == null && index < javaClasses.length )
+ {
final JavaClass javaClass = javaClasses[index];
- if ( javaClass.getFullyQualifiedName().equals(className) ) {
- try {
+ if ( javaClass.getFullyQualifiedName().equals( className ) )
+ {
+ try
+ {
// check for java annotation descriptions - fallback to QDox if none found
- Class<?> clazz = this.classloader.loadClass(className);
- if (this.processAnnotations && getAnnotationTagProviderManager().hasScrPluginAnnotation(javaClass)) {
- this.log.debug("Found java annotation description for: " + className);
- result = new AnnotationJavaClassDescription(clazz, javaClasses[index], this);
- } else if ( this.parseJavadocs ) {
- this.log.debug("Found qdox description for: " + className);
- result = new QDoxJavaClassDescription(clazz, javaClasses[index], this);
+ Class<?> clazz = this.classloader.loadClass( className );
+ if ( this.processAnnotations
+ && getAnnotationTagProviderManager().hasScrPluginAnnotation( javaClass ) )
+ {
+ this.log.debug( "Found java annotation description for: " + className );
+ result = new AnnotationJavaClassDescription( clazz, javaClasses[index], this );
}
- } catch (ClassNotFoundException e) {
- throw new SCRDescriptorException("Unable to load class " + className);
+ else if ( this.parseJavadocs )
+ {
+ this.log.debug( "Found qdox description for: " + className );
+ result = new QDoxJavaClassDescription( clazz, javaClasses[index], this );
+ }
}
- } else {
+ catch ( ClassNotFoundException e )
+ {
+ throw new SCRDescriptorException( "Unable to load class " + className );
+ }
+ }
+ else
+ {
index++;
}
}
- if ( result == null ) {
- try {
- this.log.debug("Generating classloader description for: " + className);
- result = new ClassLoaderJavaClassDescription(this.classloader.loadClass(className), this.getComponentDescriptors().get(className), this);
- } catch (ClassNotFoundException e) {
- throw new SCRDescriptorException("Unable to load class " + className);
+ if ( result == null )
+ {
+ try
+ {
+ this.log.debug( "Generating classloader description for: " + className );
+ result = new ClassLoaderJavaClassDescription( this.classloader.loadClass( className ), this
+ .getComponentDescriptors().get( className ), this );
+ }
+ catch ( ClassNotFoundException e )
+ {
+ throw new SCRDescriptorException( "Unable to load class " + className );
}
}
- this.javaClassDescriptions.put(className, result);
+ this.javaClassDescriptions.put( className, result );
}
return result;
}
- protected abstract JavaSource[] getSources() throws SCRDescriptorException;
- protected abstract Map<String, Component> getComponentDescriptors() throws SCRDescriptorException;
-
-
/**
* Get a list of all {@link JavaClass} definitions four all source files (including nested/inner classes)
* @return List of {@link JavaClass} definitions
*/
- private JavaClass[] getJavaClassesFromSources() throws SCRDescriptorException {
+ private JavaClass[] getJavaClassesFromSources() throws SCRDescriptorException
+ {
final JavaSource[] sources = this.getSources();
final List<JavaClass> classes = new ArrayList<JavaClass>();
- for(int i=0; i<sources.length; i++) {
- for(int j=0; j<sources[i].getClasses().length; j++) {
+ for ( int i = 0; i < sources.length; i++ )
+ {
+ for ( int j = 0; j < sources[i].getClasses().length; j++ )
+ {
final JavaClass clazz = sources[i].getClasses()[j];
- classes.add(clazz);
- for (int k=0; k<clazz.getNestedClasses().length; k++) {
+ classes.add( clazz );
+ for ( int k = 0; k < clazz.getNestedClasses().length; k++ )
+ {
final JavaClass nestedClass = clazz.getNestedClasses()[k];
- classes.add(nestedClass);
+ classes.add( nestedClass );
}
}
}
- return classes.toArray(new JavaClass[classes.size()]);
+ return classes.toArray( new JavaClass[classes.size()] );
}
}
diff --git a/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java b/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
index 35155ca..7dc3f74 100644
--- a/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
+++ b/scrplugin/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
@@ -51,11 +51,19 @@
import org.apache.felix.scrplugin.xml.MetaTypeIO;
import org.osgi.service.metatype.MetaTypeService;
+
/**
* The <code>SCRDescriptorGenerator</code> class does the hard work of
* generating the SCR descriptors. This class is being instantiated and
* configured by clients and the {@link #execute()} method called to generate
* the descriptor files.
+ * <p>
+ * When using this class carefully consider calling <i>all</i> setter methods
+ * to properly configure the generator. All setter method document, which
+ * default value is assumed for the respective property if the setter is
+ * not called.
+ * <p>
+ * Instances of this class are not thread save and should not be reused.
*/
public class SCRDescriptorGenerator
{
@@ -79,14 +87,22 @@
private String specVersion = null;
+ /**
+ * Create an instance of this generator using the given {@link Log}
+ * instance of logging.
+ */
public SCRDescriptorGenerator( Log logger )
{
this.logger = logger;
}
- //---------- property setup (write-only for now)
-
+ /**
+ * Sets the directory where the descriptor files will be created.
+ * <p>
+ * This field has no default value and this setter <b>must</b> called prior
+ * to calling {@link #execute()}.
+ */
public void setOutputDirectory( File outputDirectory )
{
this.outputDirectory = outputDirectory;
@@ -94,51 +110,122 @@
/**
- * Sets the class path used for resolving tags and annotations. The first
- * entry in the class path is assumed to be the build target location.
+ * Sets the {@link JavaClassDescriptorManager} instance used to access
+ * existing descriptors and to parse JavaDoc tags as well as interpret
+ * the SCR annotations.
+ * <p>
+ * This field has no default value and this setter <b>must</b> called prior
+ * to calling {@link #execute()}.
*/
public void setDescriptorManager( JavaClassDescriptorManager descriptorManager )
{
this.descriptorManager = descriptorManager;
}
+
+ /**
+ * Sets the name of the SCR declaration descriptor file. This file will be
+ * created in the <i>OSGI-INF</i> directory below the
+ * {@link #setOutputDirectory(File) output directory}.
+ * <p>
+ * This file will be overwritten if already existing. If no descriptors
+ * are created the file is actually removed.
+ * <p>
+ * The default value of this property is <code>serviceComponents.xml</code>.
+ */
public void setFinalName( String finalName )
{
this.finalName = finalName;
}
+ /**
+ * Sets the name of the file taking the Metatype Service descriptors. This
+ * file will be created in the <i>OSGI-INF/metatype</i> directory below the
+ * {@link #setOutputDirectory(File) output directory}.
+ * <p>
+ * This file will be overwritten if already existing. If no descriptors
+ * are created the file is actually removed.
+ * <p>
+ * The default value of this property is <code>metatype.xml</code>.
+ */
public void setMetaTypeName( String metaTypeName )
{
this.metaTypeName = metaTypeName;
}
+ /**
+ * Defines whether bind and unbind methods are automatically created by
+ * the SCR descriptor generator.
+ * <p>
+ * The generator uses the ASM library to create the method byte codes
+ * directly inside the class files. If bind and unbind methods are not
+ * to be created, the generator fails if such methods are missing.
+ * <p>
+ * The default value of this property is <code>true</code>.
+ */
public void setGenerateAccessors( boolean generateAccessors )
{
this.generateAccessors = generateAccessors;
}
+ /**
+ * Defines whether warnings should be considered as errors and thus cause
+ * the generation process to fail.
+ * <p>
+ * The default value of this property is <code>false</code>.
+ */
public void setStrictMode( boolean strictMode )
{
this.strictMode = strictMode;
}
+ /**
+ * Sets global properties to be set for each descriptor. If a descriptor
+ * provides properties of the same name, the descriptor properties are preferred
+ * over the properties provided here.
+ * <p>
+ * The are no default global properties.
+ */
public void setProperties( Map<String, String> properties )
{
this.properties = new HashMap<String, String>( properties );
}
+ /**
+ * Sets the Declarative Services specification version number to be forced
+ * on the declarations.
+ * <p>
+ * Supported values for this property are <code>null</code> to autodetect
+ * the specification version, <code>1.0</code> to force 1.0 descriptors and
+ * <code>1.1</code> to force 1.1 descriptors. If 1.0 descriptors are forced
+ * the generation fails if a descriptor requires 1.1 functionality.
+ * <p>
+ * The default is to generate the descriptor version according to the
+ * capabilities used by the descriptors. If no 1.1 capabilities, such as
+ * <code>configuration-policy</code>, are used, version 1.0 is used,
+ * otherwise a 1.1 descriptor is generated.
+ */
public void setSpecVersion( String specVersion )
{
this.specVersion = specVersion;
}
- //---------- descriptor generation
+ /**
+ * Actually generates the Declarative Services and Metatype descriptors
+ * scanning the java sources provided by the
+ * {@link #setDescriptorManager(JavaClassDescriptorManager) descriptor manager}.
+ *
+ * @return <code>true</code> if descriptors have been generated.
+ *
+ * @throws SCRDescriptorException
+ * @throws SCRDescriptorFailureException
+ */
public boolean execute() throws SCRDescriptorException, SCRDescriptorFailureException
{
this.logger.debug( "Starting SCRDescriptorMojo...." );