FELIX-3550 : Reimplement the SCR Generator

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1349775 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/maven-scr-plugin/NOTICE b/scrplugin/maven-scr-plugin/NOTICE
index 35bf375..1f049c9 100644
--- a/scrplugin/maven-scr-plugin/NOTICE
+++ b/scrplugin/maven-scr-plugin/NOTICE
@@ -1,5 +1,5 @@
 Apache Felix SCR Maven Plugin
-Copyright 2007-2011 The Apache Software Foundation
+Copyright 2007-2012 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/scrplugin/maven-scr-plugin/pom.xml b/scrplugin/maven-scr-plugin/pom.xml
index 5ba3f38..446a33e 100644
--- a/scrplugin/maven-scr-plugin/pom.xml
+++ b/scrplugin/maven-scr-plugin/pom.xml
@@ -29,7 +29,7 @@
     <groupId>org.apache.felix</groupId>
     <artifactId>maven-scr-plugin</artifactId>
 
-    <version>1.7.5-SNAPSHOT</version>
+    <version>1.8.0-SNAPSHOT</version>
     <packaging>maven-plugin</packaging>
 
     <name>Maven SCR Plugin</name>
@@ -57,9 +57,20 @@
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.scr.generator</artifactId>
-            <version>1.1.5-SNAPSHOT</version>
+            <version>1.2.0-SNAPSHOT</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <version>1.7.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm-all</artifactId>
+            <version>3.3.1</version>
+        </dependency>
     </dependencies>
     
     <build>
diff --git a/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenLog.java b/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenLog.java
index d5d9697..417509f 100644
--- a/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenLog.java
+++ b/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenLog.java
@@ -18,144 +18,154 @@
  */
 package org.apache.felix.scrplugin.mojo;
 
-
 import org.apache.felix.scrplugin.Log;
 
-
 /**
  * The <code>MavenLog</code> class implements the {@link Log} interface using
  * the Maven logger created on instantiation.
  */
-public class MavenLog implements Log
-{
+public class MavenLog implements Log {
 
     private final org.apache.maven.plugin.logging.Log mavenLog;
 
-
-    MavenLog( org.apache.maven.plugin.logging.Log mavenLog )
-    {
+    MavenLog(final org.apache.maven.plugin.logging.Log mavenLog) {
         this.mavenLog = mavenLog;
     }
 
-
-    public void debug( String content, Throwable error )
-    {
-        mavenLog.debug( content, error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#debug(java.lang.String,
+     *      java.lang.Throwable)
+     */
+    public void debug(final String content, final Throwable error) {
+        mavenLog.debug(content, error);
     }
 
-
-    public void debug( String content )
-    {
-        mavenLog.debug( content );
+    /**
+     * @see org.apache.felix.scrplugin.Log#debug(java.lang.String)
+     */
+    public void debug(final String content) {
+        mavenLog.debug(content);
     }
 
-
-    public void debug( Throwable error )
-    {
-        mavenLog.debug( error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#debug(java.lang.Throwable)
+     */
+    public void debug(final Throwable error) {
+        mavenLog.debug(error);
     }
 
-
-    public void error( String content, Throwable error )
-    {
-        mavenLog.error( content, error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#error(java.lang.String, java.lang.Throwable)
+     */
+    public void error(final String content, final Throwable error) {
+        mavenLog.error(content, error);
     }
 
-
-    public void error( String content, String location, int lineNumber )
-    {
-        if ( isErrorEnabled() )
-        {
-            final String message = formatMessage( content, location, lineNumber );
-            mavenLog.error( message );
-        }
+    /**
+     * @see org.apache.felix.scrplugin.Log#error(java.lang.String, java.lang.String, int)
+     */
+    public void error(final String content,
+            final String location,
+            final int lineNumber) {
+        final String message = formatMessage(content, location, lineNumber);
+        mavenLog.error(message);
     }
 
-
-    public void error( String content )
-    {
-        mavenLog.error( content );
+    /**
+     * @see org.apache.felix.scrplugin.Log#error(java.lang.String)
+     */
+    public void error(final String content) {
+        mavenLog.error(content);
     }
 
-
-    public void error( Throwable error )
-    {
-        mavenLog.error( error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#error(java.lang.Throwable)
+     */
+    public void error(final Throwable error) {
+        mavenLog.error(error);
     }
 
-
-    public void info( String content, Throwable error )
-    {
-        mavenLog.info( content, error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#info(java.lang.String, java.lang.Throwable)
+     */
+    public void info(final String content, final Throwable error) {
+        mavenLog.info(content, error);
     }
 
-
-    public void info( String content )
-    {
-        mavenLog.info( content );
+    /**
+     * @see org.apache.felix.scrplugin.Log#info(java.lang.String)
+     */
+    public void info(final String content) {
+        mavenLog.info(content);
     }
 
-
-    public void info( Throwable error )
-    {
-        mavenLog.info( error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#info(java.lang.Throwable)
+     */
+    public void info(final Throwable error) {
+        mavenLog.info(error);
     }
 
-
-    public boolean isDebugEnabled()
-    {
+    /**
+     * @see org.apache.felix.scrplugin.Log#isDebugEnabled()
+     */
+    public boolean isDebugEnabled() {
         return mavenLog.isDebugEnabled();
     }
 
-
-    public boolean isErrorEnabled()
-    {
+    /**
+     * @see org.apache.felix.scrplugin.Log#isErrorEnabled()
+     */
+    public boolean isErrorEnabled() {
         return mavenLog.isErrorEnabled();
     }
 
-
-    public boolean isInfoEnabled()
-    {
+    /**
+     * @see org.apache.felix.scrplugin.Log#isInfoEnabled()
+     */
+    public boolean isInfoEnabled() {
         return mavenLog.isInfoEnabled();
     }
 
-
-    public boolean isWarnEnabled()
-    {
+    /**
+     * @see org.apache.felix.scrplugin.Log#isWarnEnabled()
+     */
+    public boolean isWarnEnabled() {
         return mavenLog.isWarnEnabled();
     }
 
-
-    public void warn( String content, Throwable error )
-    {
-        mavenLog.warn( content, error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#warn(java.lang.String, java.lang.Throwable)
+     */
+    public void warn(final String content, final Throwable error) {
+        mavenLog.warn(content, error);
     }
 
-
-    public void warn( String content, String location, int lineNumber )
-    {
-        if ( isWarnEnabled() )
-        {
-            final String message = formatMessage( content, location, lineNumber );
-            mavenLog.warn( message );
-        }
+    /**
+     * @see org.apache.felix.scrplugin.Log#warn(java.lang.String, java.lang.String, int)
+     */
+    public void warn(final String content, final String location,
+            final int lineNumber) {
+        final String message = formatMessage(content, location, lineNumber);
+        mavenLog.warn(message);
     }
 
-
-    public void warn( String content )
-    {
-        mavenLog.warn( content );
+    /**
+     * @see org.apache.felix.scrplugin.Log#warn(java.lang.String)
+     */
+    public void warn(final String content) {
+        mavenLog.warn(content);
     }
 
-
-    public void warn( Throwable error )
-    {
-        mavenLog.warn( error );
+    /**
+     * @see org.apache.felix.scrplugin.Log#warn(java.lang.Throwable)
+     */
+    public void warn(final Throwable error) {
+        mavenLog.warn(error);
     }
 
-
-    private String formatMessage( String content, String location, int lineNumber )
-    {
+    private String formatMessage(final String content, final String location,
+            final int lineNumber) {
         return content + " at " + location + ":" + lineNumber;
     }
 }
diff --git a/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenJavaClassDescriptorManager.java b/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenProjectScanner.java
similarity index 63%
rename from scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenJavaClassDescriptorManager.java
rename to scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenProjectScanner.java
index 870ee04..3d8b1f6 100644
--- a/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenJavaClassDescriptorManager.java
+++ b/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/MavenProjectScanner.java
@@ -20,17 +20,20 @@
 
 
 import java.io.File;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
 
-import org.apache.felix.scrplugin.*;
+import org.apache.felix.scrplugin.Log;
 import org.apache.felix.scrplugin.helper.StringUtils;
+import org.apache.felix.scrplugin.scanner.Source;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.util.DirectoryScanner;
 
 
-public class MavenJavaClassDescriptorManager extends JavaClassDescriptorManager
-{
+public class MavenProjectScanner {
 
     private final MavenProject project;
 
@@ -38,28 +41,23 @@
 
     private final String excludeString;
 
-    public MavenJavaClassDescriptorManager( MavenProject project, Log log, ClassLoader classLoader,
-        String[] annotationTagProviders, String includeString, String excludeString, boolean parseJavadocs, boolean processAnnotations )
-        throws SCRDescriptorFailureException
-    {
-        super( log, classLoader, annotationTagProviders, parseJavadocs, processAnnotations );
+    private final Log log;
 
+    public MavenProjectScanner( final MavenProject project,
+            final String includeString,
+            final String excludeString,
+            final Log log) {
         this.project = project;
         this.includeString = includeString;
         this.excludeString = excludeString;
+        this.log = log;
     }
 
-
-    public String getOutputDirectory()
-    {
-        return this.project.getBuild().getOutputDirectory();
-    }
-
-
-    @Override
-    protected Iterator<File> getSourceFiles()
-    {
-        ArrayList<File> files = new ArrayList<File>();
+    /**
+     * Return all sources.
+     */
+    public Collection<Source> getSources() {
+        final ArrayList<Source> files = new ArrayList<Source>();
 
         @SuppressWarnings("unchecked")
         final Iterator<String> i = project.getCompileSourceRoots().iterator();
@@ -71,30 +69,24 @@
         }
 
         final String[] excludes;
-        if ( excludeString != null )
-        {
+        if ( excludeString != null ) {
             excludes = StringUtils.split( excludeString, "," );
-        }
-        else
-        {
+        } else {
             excludes = null;
         }
 
-        while ( i.hasNext() )
-        {
+        while ( i.hasNext() ) {
             final String tree = i.next();
             final File directory = new File( tree );
-            if ( !directory.exists() )
-            {
-                this.log.warn("Source tree does not exist. Ignoring " + tree);
+            if ( !directory.exists() ) {
+                log.warn("Source tree does not exist. Ignoring " + tree);
                 continue;
             }
-            this.log.debug( "Scanning source tree " + tree );
+            log.debug( "Scanning source tree " + tree );
             final DirectoryScanner scanner = new DirectoryScanner();
             scanner.setBasedir( directory );
 
-            if ( excludes != null && excludes.length > 0 )
-            {
+            if ( excludes != null && excludes.length > 0 ) {
                 scanner.setExcludes( excludes );
             }
             scanner.addDefaultExcludes();
@@ -102,53 +94,52 @@
 
             scanner.scan();
 
-            for ( String fileName : scanner.getIncludedFiles() )
-            {
-                files.add( new File( directory, fileName ) );
+            for ( final String fileName : scanner.getIncludedFiles() ) {
+                files.add( new Source() {
 
+                    public File getFile() {
+                        return new File(directory, fileName);
+                    }
+
+                    public String getClassName() {
+                        // remove ".java"
+                        String name = fileName.substring(0, fileName.length() - 5);
+                        return name.replace(File.separatorChar, '/').replace('/', '.');
+                    }
+                });
             }
         }
 
-        return files.iterator();
+        return files;
     }
 
-
-    @Override
-    protected List<File> getDependencies()
-    {
-        ArrayList<File> dependencies = new ArrayList<File>();
+    /**
+     * Return all dependencies
+     */
+    public List<File> getDependencies() {
+        final ArrayList<File> dependencies = new ArrayList<File>();
 
         @SuppressWarnings("unchecked")
         final Iterator<Artifact> it = project.getArtifacts().iterator();
-        while ( it.hasNext() )
-        {
+        while ( it.hasNext() ) {
             final Artifact declared = it.next();
             this.log.debug( "Checking artifact " + declared );
-            if ( this.isJavaArtifact( declared ) )
-            {
+            if ( this.isJavaArtifact( declared ) ) {
                 if ( Artifact.SCOPE_COMPILE.equals( declared.getScope() )
                     || Artifact.SCOPE_RUNTIME.equals( declared.getScope() )
                     || Artifact.SCOPE_PROVIDED.equals( declared.getScope() )
-                    || Artifact.SCOPE_SYSTEM.equals( declared.getScope() ) )
-                {
+                    || Artifact.SCOPE_SYSTEM.equals( declared.getScope() ) ) {
                     this.log.debug( "Resolving artifact " + declared );
-                    if ( declared.getFile() != null )
-                    {
+                    if ( declared.getFile() != null ) {
                         dependencies.add( declared.getFile() );
-                    }
-                    else
-                    {
+                    } else {
                         this.log.debug( "Unable to resolve artifact " + declared );
                     }
-                }
-                else
-                {
+                } else {
                     this.log.debug( "Artifact " + declared + " has not scope compile or runtime, but "
                         + declared.getScope() );
                 }
-            }
-            else
-            {
+            } else {
                 this.log.debug( "Artifact " + declared + " is not a java artifact, type is " + declared.getType() );
             }
         }
@@ -160,17 +151,13 @@
     /**
      * Check if the artifact is a java artifact (jar or bundle)
      */
-    private boolean isJavaArtifact( Artifact artifact )
-    {
-        if ( "jar".equals( artifact.getType() ) )
-        {
+    private boolean isJavaArtifact( Artifact artifact ) {
+        if ( "jar".equals( artifact.getType() ) ) {
             return true;
         }
-        if ( "bundle".equals( artifact.getType() ) )
-        {
+        if ( "bundle".equals( artifact.getType() ) ) {
             return true;
         }
         return false;
     }
-
 }
diff --git a/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/SCRDescriptorMojo.java b/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/SCRDescriptorMojo.java
index bc0a65c..c22f564 100644
--- a/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/SCRDescriptorMojo.java
+++ b/scrplugin/maven-scr-plugin/src/main/java/org/apache/felix/scrplugin/mojo/SCRDescriptorMojo.java
@@ -22,20 +22,34 @@
 import java.io.IOException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
 
-import org.apache.felix.scrplugin.*;
+import org.apache.felix.scrplugin.Options;
+import org.apache.felix.scrplugin.Project;
+import org.apache.felix.scrplugin.Result;
+import org.apache.felix.scrplugin.SCRDescriptorException;
+import org.apache.felix.scrplugin.SCRDescriptorFailureException;
+import org.apache.felix.scrplugin.SCRDescriptorGenerator;
+import org.apache.felix.scrplugin.description.SpecVersion;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.versioning.ArtifactVersion;
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.model.Resource;
-import org.apache.maven.plugin.*;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.util.StringUtils;
 
 /**
- * The <code>SCRDescriptorMojo</code>
- * generates a service descriptor file based on annotations found in the sources.
+ * The <code>SCRDescriptorMojo</code> generates a service descriptor file based
+ * on annotations found in the sources.
  *
  * @goal scr
  * @phase process-classes
@@ -67,7 +81,8 @@
      *
      * @see #checkAnnotationArtifact(Artifact)
      */
-    private static final ArtifactVersion SCR_ANN_MIN_VERSION = new DefaultArtifactVersion("1.5.1");
+    private static final ArtifactVersion SCR_ANN_MIN_VERSION = new DefaultArtifactVersion(
+            "1.6.9");
 
     /**
      * @parameter expression="${project.build.directory}/scr-plugin-generated"
@@ -88,7 +103,8 @@
     /**
      * Name of the generated descriptor.
      *
-     * @parameter expression="${scr.descriptor.name}" default-value="serviceComponents.xml"
+     * @parameter expression="${scr.descriptor.name}"
+     *            default-value="serviceComponents.xml"
      */
     private String finalName;
 
@@ -101,38 +117,25 @@
 
     /**
      * This flag controls the generation of the bind/unbind methods.
+     *
      * @parameter default-value="true"
      */
     private boolean generateAccessors;
 
     /**
-     * This flag controls whether the javadoc source code will be scanned for
-     * tags.
-     * @parameter default-value="true"
-     */
-    protected boolean parseJavadoc;
-
-    /**
-     * This flag controls whether the annotations in the sources will be
-     * processed.
-     * @parameter default-value="true"
-     */
-    protected boolean processAnnotations;
-
-    /**
      * In strict mode the plugin even fails on warnings.
+     *
      * @parameter default-value="false"
      */
     protected boolean strictMode;
 
-    
     /**
      * The comma separated list of tokens to include when processing sources.
-     * 
+     *
      * @parameter alias="includes"
      */
     private String sourceIncludes;
-    
+
     /**
      * The comma separated list of tokens to exclude when processing sources.
      *
@@ -149,87 +152,97 @@
 
     /**
      * Allows to define additional implementations of the interface
-     * {@link org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider}
-     * that provide mappings from custom annotations to
-     * {@link org.apache.felix.scrplugin.tags.JavaTag} implementations.
-     * List of full qualified class file names.
+     * {@link org.apache.felix.scrplugin.AnnotationProcessor} that provide
+     * mappings from custom annotations to descriptions.
      *
      * @parameter
      */
-    private String[] annotationTagProviders = {};
+    private String[] annotationProcessors = {};
 
     /**
-     * The version of the DS spec this plugin generates a descriptor for.
-     * By default the version is detected by the used tags.
+     * The version of the DS spec this plugin generates a descriptor for. By
+     * default the version is detected by the used tags.
+     *
      * @parameter
      */
     private String specVersion;
 
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        // create the log for the generator
+        final org.apache.felix.scrplugin.Log scrLog = new MavenLog(getLog());
+        // create the class loader
+        final ClassLoader classLoader = new URLClassLoader(getClassPath(), this
+                .getClass().getClassLoader());
 
-    public void execute() throws MojoExecutionException, MojoFailureException
-    {
-        try
-        {
-            final org.apache.felix.scrplugin.Log scrLog = new MavenLog( getLog() );
+        // create project
+        final MavenProjectScanner scanner = new MavenProjectScanner(
+                this.project, this.sourceIncludes, this.sourceExcludes, scrLog);
 
-            final ClassLoader classLoader = new URLClassLoader( getClassPath(), this.getClass().getClassLoader() );
-            final JavaClassDescriptorManager jManager = new MavenJavaClassDescriptorManager( project, scrLog,
-                classLoader, this.annotationTagProviders, this.sourceIncludes, this.sourceExcludes, this.parseJavadoc,
-                this.processAnnotations );
+        final Project project = new Project();
+        project.setClassLoader(classLoader);
+        project.setDependencies(scanner.getDependencies());
+        project.setSources(scanner.getSources());
+        project.setClassesDirectory(this.project.getBuild().getOutputDirectory());
 
-            final SCRDescriptorGenerator generator = new SCRDescriptorGenerator( scrLog );
+        // create options
+        final Options options = new Options();
+        options.setGenerateAccessors(generateAccessors);
+        options.setStrictMode(strictMode);
+        options.setProperties(properties);
+        options.setSpecVersion(SpecVersion.fromName(specVersion));
+        if ( specVersion != null && options.getSpecVersion() == null ) {
+            throw new MojoExecutionException("Unknown spec version specified: " + specVersion);
+        }
+        options.setAnnotationProcessors(annotationProcessors);
+        try {
+
+            final SCRDescriptorGenerator generator = new SCRDescriptorGenerator(
+                    scrLog);
 
             // setup from plugin configuration
-            generator.setOutputDirectory( outputDirectory );
-            generator.setDescriptorManager( jManager );
-            generator.setFinalName( finalName );
-            generator.setMetaTypeName( metaTypeName );
-            generator.setGenerateAccessors( generateAccessors );
-            generator.setStrictMode( strictMode );
-            generator.setProperties( properties );
-            generator.setSpecVersion( specVersion );
+            generator.setOutputDirectory(outputDirectory);
+            generator.setOptions(options);
+            generator.setProject(project);
+            generator.setFinalName(finalName);
+            generator.setMetaTypeName(metaTypeName);
 
-            if ( generator.execute() )
-            {
-                setServiceComponentHeader();
-                addResources();
-            }
-        }
-        catch ( SCRDescriptorException sde )
-        {
-            throw new MojoExecutionException( sde.getMessage(), sde.getCause() );
-        }
-        catch ( SCRDescriptorFailureException sdfe )
-        {
-            throw ( MojoFailureException ) new MojoFailureException( sdfe.getMessage() ).initCause( sdfe );
+            final Result result = generator.execute();
+            this.setServiceComponentHeader(result.getScrFiles());
+            this.updateProjectResources();
+
+        } catch (final SCRDescriptorException sde) {
+            throw new MojoExecutionException(sde.getMessage(), sde.getCause());
+        } catch (SCRDescriptorFailureException sdfe) {
+            throw (MojoFailureException) new MojoFailureException(
+                    sdfe.getMessage()).initCause(sdfe);
         }
     }
 
-    private URL[] getClassPath() throws MojoFailureException{
+    private URL[] getClassPath() throws MojoFailureException {
         @SuppressWarnings("unchecked")
         List<Artifact> artifacts = this.project.getCompileArtifacts();
         ArrayList<URL> path = new ArrayList<URL>();
 
-        try
-        {
-            path.add(new File( this.project.getBuild().getOutputDirectory() ).toURI().toURL());
-        }
-        catch ( IOException ioe )
-        {
-            throw new MojoFailureException( "Unable to add target directory to classloader.");
+        try {
+            path.add(new File(this.project.getBuild().getOutputDirectory())
+                    .toURI().toURL());
+        } catch (final IOException ioe) {
+            throw new MojoFailureException(
+                    "Unable to add target directory to classloader.");
         }
 
-        for (Iterator<Artifact> ai=artifacts.iterator(); ai.hasNext(); ) {
+        for (Iterator<Artifact> ai = artifacts.iterator(); ai.hasNext();) {
             Artifact a = ai.next();
             assertMinScrAnnotationArtifactVersion(a);
             try {
                 path.add(a.getFile().toURI().toURL());
             } catch (IOException ioe) {
-                throw new MojoFailureException("Unable to get compile class loader.");
+                throw new MojoFailureException(
+                        "Unable to get compile class loader.");
             }
         }
 
-        return path.toArray( new URL[path.size()] );
+        return path.toArray(new URL[path.size()]);
     }
 
     /**
@@ -240,61 +253,83 @@
      * SCR Annotation libraries do not produce descriptors any more. If the
      * artifact is not this method silently returns.
      *
-     * @param a The artifact to check and assert
+     * @param a
+     *            The artifact to check and assert
      * @see #SCR_ANN_ARTIFACTID
      * @see #SCR_ANN_GROUPID
      * @see #SCR_ANN_MIN_VERSION
-     * @throws MojoFailureException If the artifact refers to the SCR Annotation
-     *             library with a version less than {@link #SCR_ANN_MIN_VERSION}
+     * @throws MojoFailureException
+     *             If the artifact refers to the SCR Annotation library with a
+     *             version less than {@link #SCR_ANN_MIN_VERSION}
      */
-    private void assertMinScrAnnotationArtifactVersion(Artifact a) throws MojoFailureException
-    {
-        if (SCR_ANN_ARTIFACTID.equals(a.getArtifactId()) && SCR_ANN_GROUPID.equals(a.getGroupId()))
-        {
+    @SuppressWarnings("unchecked")
+    private void assertMinScrAnnotationArtifactVersion(final Artifact a)
+            throws MojoFailureException {
+        if (SCR_ANN_ARTIFACTID.equals(a.getArtifactId())
+                && SCR_ANN_GROUPID.equals(a.getGroupId())) {
             // assert minimal version number
-            ArtifactVersion aVersion = new DefaultArtifactVersion(a.getBaseVersion());
-            if (SCR_ANN_MIN_VERSION.compareTo(aVersion) > 0)
-            {
+            final ArtifactVersion aVersion = new DefaultArtifactVersion(a.getBaseVersion());
+            if (SCR_ANN_MIN_VERSION.compareTo(aVersion) > 0) {
                 getLog().error("Project depends on " + a);
-                getLog().error("Minimum required version is " + SCR_ANN_MIN_VERSION);
-                throw new MojoFailureException("Please use org.apache.felix:org.apache.felix.scr.annotations version "
-                    + SCR_ANN_MIN_VERSION + " or newer.");
+                getLog().error(
+                        "Minimum required version is " + SCR_ANN_MIN_VERSION);
+                throw new MojoFailureException(
+                        "Please use org.apache.felix:org.apache.felix.scr.annotations version "
+                                + SCR_ANN_MIN_VERSION + " or newer.");
             }
         }
     }
 
-    private void setServiceComponentHeader()
-    {
-        final File descriptorFile = StringUtils.isEmpty( this.finalName ) ? null : new File( new File(
-            this.outputDirectory, "OSGI-INF" ), this.finalName );
-        if ( descriptorFile.exists() )
-        {
-            String svcComp = project.getProperties().getProperty( "Service-Component" );
-            final String svcPath = "OSGI-INF/" + finalName;
-            svcComp = ( svcComp == null ) ? svcPath :
-                svcComp.contains(svcPath) ? svcComp : svcComp + ", " + svcPath;
-            project.getProperties().setProperty( "Service-Component", svcComp );
+    /**
+     * Set the service component header based on the scr files.
+     */
+    private void setServiceComponentHeader(final List<String> files) {
+        if ( files != null && files.size() > 0 ) {
+            final String svcHeader = project.getProperties().getProperty("Service-Component");
+            final Set<String> xmlFiles = new HashSet<String>();
+            if ( svcHeader != null ) {
+                final StringTokenizer st = new StringTokenizer(svcHeader, ",");
+                while ( st.hasMoreTokens() ) {
+                    final String token = st.nextToken();
+                    xmlFiles.add(token.trim());
+                }
+            }
+
+            for(final String path : files) {
+                xmlFiles.add(path);
+            }
+            final StringBuilder sb = new StringBuilder();
+            boolean first = true;
+            for(final String entry : xmlFiles) {
+                if ( !first ) {
+                    sb.append(", ");
+                } else {
+                    first = false;
+                }
+                sb.append(entry);
+            }
+            project.getProperties().setProperty("Service-Component", sb.toString());
         }
     }
 
-
-    private void addResources()
-    {
+    /**
+     * Update the Maven project resources.
+     */
+    private void updateProjectResources() {
         // now add the descriptor directory to the maven resources
         final String ourRsrcPath = this.outputDirectory.getAbsolutePath();
         boolean found = false;
         @SuppressWarnings("unchecked")
-        final Iterator<Resource> rsrcIterator = this.project.getResources().iterator();
-        while ( !found && rsrcIterator.hasNext() )
-        {
+        final Iterator<Resource> rsrcIterator = this.project.getResources()
+                .iterator();
+        while (!found && rsrcIterator.hasNext()) {
             final Resource rsrc = rsrcIterator.next();
-            found = rsrc.getDirectory().equals( ourRsrcPath );
+            found = rsrc.getDirectory().equals(ourRsrcPath);
         }
-        if ( !found )
-        {
+        if (!found) {
             final Resource resource = new Resource();
-            resource.setDirectory( this.outputDirectory.getAbsolutePath() );
-            this.project.addResource( resource );
+            resource.setDirectory(this.outputDirectory.getAbsolutePath());
+            this.project.addResource(resource);
         }
     }
 }