FELIX-2679 : Detect AnnotationTagProvider's through META-INF/services
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1029812 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/annotations/src/main/resources/META-INF/services/org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider b/scrplugin/annotations/src/main/resources/META-INF/services/org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider
new file mode 100644
index 0000000..a9f2add
--- /dev/null
+++ b/scrplugin/annotations/src/main/resources/META-INF/services/org.apache.felix.scrplugin.tags.annotation.AnnotationTagProvider
@@ -0,0 +1,2 @@
+org.apache.felix.scrplugin.tags.annotation.defaulttag.DefaultAnnotationTagProvider
+org.apache.felix.scrplugin.tags.annotation.sling.SlingAnnotationTagProvider
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
index 8320269..957521d 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/JavaClassDescriptorManager.java
@@ -14,14 +14,9 @@
package org.apache.felix.scrplugin;
-import java.io.File;
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
import java.util.*;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
+import java.util.jar.*;
import org.apache.felix.scrplugin.om.Component;
import org.apache.felix.scrplugin.om.Components;
@@ -31,6 +26,7 @@
import org.apache.felix.scrplugin.tags.cl.ClassLoaderJavaClassDescription;
import org.apache.felix.scrplugin.tags.qdox.QDoxJavaClassDescription;
import org.apache.felix.scrplugin.xml.ComponentDescriptorIO;
+
import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaSource;
@@ -86,7 +82,7 @@
this.processAnnotations = processAnnotations;
this.parseJavadocs = parseJavadocs;
this.log = log;
- this.annotationTagProviderManager = new AnnotationTagProviderManager( annotationTagProviders );
+ this.annotationTagProviderManager = new AnnotationTagProviderManager( log, annotationTagProviders, classLoader );
this.classloader = classLoader;
ClassUtil.classLoader = this.classloader;
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
index cd3f9d9..74b8300 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/tags/annotation/AnnotationTagProviderManager.java
@@ -19,9 +19,13 @@
package org.apache.felix.scrplugin.tags.annotation;
-import java.util.ArrayList;
-import java.util.List;
+import java.security.CodeSource;
+import java.security.ProtectionDomain;
+import java.util.*;
+import javax.imageio.spi.ServiceRegistry;
+
+import org.apache.felix.scrplugin.Log;
import org.apache.felix.scrplugin.SCRDescriptorFailureException;
import org.apache.felix.scrplugin.tags.JavaField;
import org.apache.felix.scrplugin.tags.JavaTag;
@@ -43,36 +47,97 @@
* that provide mappings from custom annotations to
* {@link org.apache.felix.scrplugin.tags.JavaTag} implementations.
*/
- private final List<AnnotationTagProvider> annotationTagProviders = new ArrayList<AnnotationTagProvider>();
+ private final Map<String, AnnotationTagProvider> annotationTagProviders = new LinkedHashMap<String, AnnotationTagProvider>();
+ private final Log log;
/**
* @param annotationTagProviderClasses List of classes that implements
* {@link AnnotationTagProvider} interface.
* @throws SCRDescriptorFailureException
*/
- public AnnotationTagProviderManager( String[] annotationTagProviderClasses ) throws SCRDescriptorFailureException
+ public AnnotationTagProviderManager( final Log log,
+ final String[] annotationTagProviderClasses,
+ final ClassLoader classLoader )
+ throws SCRDescriptorFailureException
{
+ this.log = log;
- // the classloader used to load the provider classes
- final ClassLoader classLoader = getClass().getClassLoader();
-
- // always add provider supporting built-in SCR default properties
- loadProvider( annotationTagProviders, classLoader,
- "org.apache.felix.scrplugin.tags.annotation.defaulttag.DefaultAnnotationTagProvider", true );
- loadProvider( annotationTagProviders, classLoader,
- "org.apache.felix.scrplugin.tags.annotation.sling.SlingAnnotationTagProvider", true );
+ // search for providers
+ final Iterator<AnnotationTagProvider> serviceIter = ServiceRegistry.lookupProviders(AnnotationTagProvider.class, classLoader);
+ while ( serviceIter.hasNext() )
+ {
+ final AnnotationTagProvider provider = serviceIter.next();
+ this.addProvider(provider, false);
+ }
// add custom providers defined in pom
for ( int i = 0; i < annotationTagProviderClasses.length; i++ )
{
- loadProvider( annotationTagProviders, classLoader, annotationTagProviderClasses[i], false );
+ loadProvider( classLoader, annotationTagProviderClasses[i], false );
+ }
+
+ // always add provider supporting built-in SCR default properties (for compatibility with older
+ // annotation versions)
+ loadProvider( classLoader,
+ "org.apache.felix.scrplugin.tags.annotation.defaulttag.DefaultAnnotationTagProvider", true );
+ loadProvider( classLoader,
+ "org.apache.felix.scrplugin.tags.annotation.sling.SlingAnnotationTagProvider", true );
+ }
+
+ /**
+ * Try to get the location (class loader) from the object.
+ */
+ private String getLocation(final Object obj)
+ {
+ try {
+ final ProtectionDomain pd = obj.getClass().getProtectionDomain();
+ if ( pd != null && pd.getCodeSource() != null )
+ {
+ final CodeSource cs = pd.getCodeSource();
+ if ( cs.getLocation() != null )
+ {
+ return cs.getLocation().toExternalForm();
+ }
+ }
+ }
+ catch (final SecurityException se)
+ {
+ // ignore this
+ }
+ // by default return the class laoder
+ return obj.getClass().getClassLoader().toString();
+ }
+
+ /**
+ * Add a provider (if not already available)
+ */
+ private void addProvider(final AnnotationTagProvider provider, final boolean silent)
+ {
+ // check if this provider is already loaded
+ final String key = provider.getClass().getName();
+ if ( !this.annotationTagProviders.containsKey(key) )
+ {
+ this.annotationTagProviders.put(key, provider);
+ }
+ else
+ {
+ if ( !silent )
+ {
+ // now check if the location of the providers (classloader) is different
+ // and log a warning
+ final AnnotationTagProvider usedProvider = this.annotationTagProviders.get(key);
+ if ( !usedProvider.equals(provider) )
+ {
+ this.log.warn("Ignoring provider " + provider + " from location " + getLocation(provider) +
+ ". Using previously found version from " + getLocation(usedProvider));
+ }
+
+ }
}
}
-
- private static void loadProvider( final List<AnnotationTagProvider> annotationTagProviders,
- final ClassLoader classLoader, final String className, final boolean silent )
+ private void loadProvider( final ClassLoader classLoader, final String className, final boolean silent )
throws SCRDescriptorFailureException
{
String failureMessage = null;
@@ -81,7 +146,7 @@
Class<?> clazz = classLoader.loadClass( className );
try
{
- annotationTagProviders.add( ( AnnotationTagProvider ) clazz.newInstance() );
+ addProvider( ( AnnotationTagProvider ) clazz.newInstance(), silent );
}
catch ( ClassCastException e )
{
@@ -135,7 +200,7 @@
{
List<JavaTag> tags = new ArrayList<JavaTag>();
- for ( AnnotationTagProvider provider : this.annotationTagProviders )
+ for ( AnnotationTagProvider provider : this.annotationTagProviders.values() )
{
tags.addAll( provider.getTags( annotation, description, field ) );
}
diff --git a/scrplugin/maven-scr-plugin/pom.xml b/scrplugin/maven-scr-plugin/pom.xml
index 7c8bbb0..353689d 100644
--- a/scrplugin/maven-scr-plugin/pom.xml
+++ b/scrplugin/maven-scr-plugin/pom.xml
@@ -60,12 +60,6 @@
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <version>1.3.1-SNAPSHOT</version>
- <scope>compile</scope>
- </dependency>
</dependencies>
<build>
diff --git a/scrplugin/scrtask/pom.xml b/scrplugin/scrtask/pom.xml
index 99687cf..935e5b0 100644
--- a/scrplugin/scrtask/pom.xml
+++ b/scrplugin/scrtask/pom.xml
@@ -57,12 +57,6 @@
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- <version>1.3.1-SNAPSHOT</version>
- <scope>compile</scope>
- </dependency>
</dependencies>
<build>