FELIX-3550 : Reimplement the SCR Generator. Apply patch from Stefan Seifert
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1364542 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
index 5bf532c..4573735 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/SCRDescriptorGenerator.java
@@ -240,7 +240,8 @@
createBind,
createUnbind,
this.project.getClassLoader(),
- this.project.getClassesDirectory());
+ this.project.getClassesDirectory(),
+ this.logger);
}
}
}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java
index b856739..205a0fd 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassModifier.java
@@ -22,6 +22,7 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import org.apache.felix.scrplugin.Log;
import org.apache.felix.scrplugin.SCRDescriptorException;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
@@ -54,7 +55,8 @@
final boolean createBind,
final boolean createUnbind,
final ClassLoader classLoader,
- final String outputDirectory)
+ final String outputDirectory,
+ final Log logger)
throws SCRDescriptorException {
// now do byte code manipulation
final String fileName = outputDirectory + File.separatorChar + className.replace('.', File.separatorChar) + ".class";
@@ -93,12 +95,12 @@
cn.accept(writer);
if ( createBind ) {
- System.out.println("Adding bind " + className + " " + fieldName);
+ logger.debug("Adding bind " + className + " " + fieldName);
createMethod(writer, className, referenceName, fieldName, typeName, true);
}
if ( createUnbind ) {
- System.out.println("Adding unbind " + className + " " + fieldName);
+ logger.debug("Adding unbind " + className + " " + fieldName);
createMethod(writer, className, referenceName, fieldName, typeName, false);
}
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java
index 91e4e50..9e528863 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/helper/ClassScanner.java
@@ -40,6 +40,8 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.felix.scrplugin.Log;
import org.apache.felix.scrplugin.Project;
@@ -82,6 +84,9 @@
/** Source for all generated descriptions. */
private static final String GENERATED = "<generated>";
+
+ /** With this syntax array pameters names are returned by reflection API */
+ private static final Pattern ARRAY_PARAM_TYPE_NAME = Pattern.compile("^\\[L(.*);$");
/** Component descriptions loaded from dependencies*/
private Map<String, ClassDescription> loadedDependencies;
@@ -195,7 +200,7 @@
final List<ScannedAnnotation> descriptions = new ArrayList<ScannedAnnotation>();
// first parse class annotations
@SuppressWarnings("unchecked")
- final List<AnnotationNode> annotations = classNode.invisibleAnnotations;
+ final List<AnnotationNode> annotations = getAllAnnotations(classNode.invisibleAnnotations, classNode.visibleAnnotations);
if (annotations != null) {
for (final AnnotationNode annotation : annotations) {
this.parseAnnotation(descriptions, annotation, annotatedClass);
@@ -208,7 +213,7 @@
for (final MethodNode method : methods) {
@SuppressWarnings("unchecked")
- final List<AnnotationNode> annos = method.invisibleAnnotations;
+ final List<AnnotationNode> annos = getAllAnnotations(method.invisibleAnnotations, method.visibleAnnotations);
if (annos != null) {
final String name = method.name;
final Type[] signature = Type.getArgumentTypes(method.desc);
@@ -223,11 +228,21 @@
if (m.getParameterTypes().length > 0 && signature != null && m.getParameterTypes().length == signature.length) {
found = m;
for(int index = 0; index < m.getParameterTypes().length; index++ ) {
- if ( !m.getParameterTypes()[index].getName().equals(signature[index].getClassName()) ) {
+ String parameterTypeName = m.getParameterTypes()[index].getName();
+ // Name of array parameters is returned with syntax [L<name>;, convert to <name>[]
+ Matcher matcher = ARRAY_PARAM_TYPE_NAME.matcher(parameterTypeName);
+ if (matcher.matches()) {
+ parameterTypeName = matcher.group(1) + "[]";
+ }
+ if (!parameterTypeName.equals(signature[index].getClassName())) {
found = null;
}
}
}
+ // if method is found return it now, to avoid resetting 'found' to null if next method has same name but different parameters
+ if (found != null) {
+ break;
+ }
}
}
if (found == null) {
@@ -247,7 +262,7 @@
if (fields != null) {
for (final FieldNode field : fields) {
@SuppressWarnings("unchecked")
- final List<AnnotationNode> annos = field.invisibleAnnotations;
+ final List<AnnotationNode> annos = getAllAnnotations(field.invisibleAnnotations, field.visibleAnnotations);
if (annos != null) {
final String name = field.name;
final Field[] allFields = annotatedClass.getDeclaredFields();
@@ -255,6 +270,7 @@
for (final Field f : allFields) {
if (f.getName().equals(name)) {
found = f;
+ break;
}
}
if (found == null) {
@@ -271,6 +287,26 @@
return descriptions;
}
+ /**
+ * Method is used to get both invisible (e.g. RetentionPolicy.CLASS) and visible (e.g. RetentionPolicy.RUNTIME) annotations.
+ * Although it is recommended to use RetentionPolicy.CLASS for SCR annotations, it may make sense to declae them with another
+ * RetentionPolicy if the same annotation is used for other usecases which require runtime access as well.
+ * @param annotationLists List of invisible and visible annotations.
+ * @return List with all annotations from all lists, or null if none found
+ */
+ private List<AnnotationNode> getAllAnnotations(List<AnnotationNode>... annotationLists) {
+ List<AnnotationNode> resultList = null;
+ for (List<AnnotationNode> annotationList : annotationLists) {
+ if (annotationList!=null && annotationList.size()>0) {
+ if (resultList==null) {
+ resultList = new ArrayList<AnnotationNode>();
+ }
+ resultList.addAll(annotationList);
+ }
+ }
+ return resultList;
+ }
+
private <T> T[] convertToArray(final List<?> values, final Class<T> type) {
@SuppressWarnings("unchecked")
final T[] result = (T[]) Array.newInstance(type, values.size());
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
index 4bb2b44..57b17e6 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/ComponentDescriptorIO.java
@@ -240,7 +240,8 @@
// attributes new in 1.1
if (module.getOptions().getSpecVersion().ordinal() >= SpecVersion.VERSION_1_1.ordinal() ) {
- if ( component.getConfigurationPolicy() != ComponentConfigurationPolicy.OPTIONAL ) {
+ if ( component.getConfigurationPolicy() != null
+ && component.getConfigurationPolicy() != ComponentConfigurationPolicy.OPTIONAL ) {
IOUtils.addAttribute(ai, COMPONENT_ATTR_POLICY, component.getConfigurationPolicy().name().toLowerCase());
}
IOUtils.addAttribute(ai, COMPONENT_ATTR_ACTIVATE, component.getActivate());
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 8a2c22b..19270cd 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
@@ -219,7 +219,7 @@
this.updateProjectResources();
} catch (final SCRDescriptorException sde) {
- throw new MojoExecutionException(sde.getSourceLocation() + " : " + sde.getMessage(), sde.getCause());
+ throw new MojoExecutionException(sde.getSourceLocation() + " : " + sde.getMessage(), sde);
} catch (final SCRDescriptorFailureException sdfe) {
throw (MojoFailureException) new MojoFailureException(
sdfe.getMessage()).initCause(sdfe);