FELIX-3332 : SCR annotations @Activate @Deactivate @Modified in outer classes also affect nested classes, annotations in nested classes are ignored
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1440660 13f79535-47bb-0310-9956-ffa450edef68
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 195f45c..4217a2b 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
@@ -143,26 +143,7 @@
// load the class
final Class<?> annotatedClass = project.getClassLoader().loadClass(src.getClassName());
- final ClassDescription desc = this.processClass(annotatedClass, src.getFile().toString());
- if ( desc != null ) {
- this.allDescriptions.put(annotatedClass.getName(), desc);
- if ( desc.getDescriptions(ComponentDescription.class).size() > 0) {
- result.add(desc);
- log.debug("Found component description " + desc + " in " + annotatedClass.getName());
- } else {
- // check whether one of the other annotations is used and log a warning (FELIX-3636)
- if ( desc.getDescription(PropertyDescription.class) != null
- || desc.getDescription(ReferenceDescription.class) != null
- || desc.getDescription(ServiceDescription.class) != null ) {
- iLog.addWarning("Class '" + src.getClassName() + "' contains SCR annotations, but not a" +
- "@Component (or equivalent) annotation. Therefore no component descriptor is created for this" +
- "class. Please add a @Component annotation and consider making it abstract.",
- src.getFile().toString());
- }
- }
- } else {
- this.allDescriptions.put(annotatedClass.getName(), new ClassDescription(annotatedClass, GENERATED));
- }
+ this.process(annotatedClass, src, result);
} catch (final ClassNotFoundException cnfe) {
throw new SCRDescriptorFailureException("Unable to load compiled class: " + src.getClassName(), cnfe);
}
@@ -171,6 +152,41 @@
}
/**
+ * Process a class
+ * @throws SCRDescriptorException
+ * @throws SCRDescriptorFailureException
+ */
+ private void process(final Class<?> annotatedClass, final Source src, final List<ClassDescription> result)
+ throws SCRDescriptorFailureException, SCRDescriptorException {
+ final ClassDescription desc = this.processClass(annotatedClass, src.getFile().toString());
+ if ( desc != null ) {
+ this.allDescriptions.put(annotatedClass.getName(), desc);
+ if ( desc.getDescriptions(ComponentDescription.class).size() > 0) {
+ result.add(desc);
+ log.debug("Found component description " + desc + " in " + annotatedClass.getName());
+ } else {
+ // check whether one of the other annotations is used and log a warning (FELIX-3636)
+ if ( desc.getDescription(PropertyDescription.class) != null
+ || desc.getDescription(ReferenceDescription.class) != null
+ || desc.getDescription(ServiceDescription.class) != null ) {
+ iLog.addWarning("Class '" + src.getClassName() + "' contains SCR annotations, but not a" +
+ "@Component (or equivalent) annotation. Therefore no component descriptor is created for this" +
+ "class. Please add a @Component annotation and consider making it abstract.",
+ src.getFile().toString());
+ }
+ }
+ } else {
+ this.allDescriptions.put(annotatedClass.getName(), new ClassDescription(annotatedClass, GENERATED));
+ }
+ // process inner classes
+ for(final Class<?> innerClass : annotatedClass.getDeclaredClasses()) {
+ if ( !innerClass.isAnnotation() && !innerClass.isInterface() ) {
+ process(innerClass, src, result);
+ }
+ }
+ }
+
+ /**
* Scan a single class.
*/
private ClassDescription processClass(final Class<?> annotatedClass, final String location)
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 0f2eb45..2836783 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
@@ -24,7 +24,7 @@
import java.io.InputStream;
import java.security.Provider.Service;
import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
@@ -765,11 +765,34 @@
final List<String> fileNames = new ArrayList<String>();
if ( options.isGenerateSeparateDescriptors() ) {
final SpecVersion globalVersion = module.getOptions().getSpecVersion();
- for(final ComponentContainer component : components ) {
+ while ( !components.isEmpty() ) {
+ // get the first component
+ final List<ComponentContainer> innerList = new ArrayList<ComponentContainer>();
+ final ComponentContainer component = components.remove(0);
+ innerList.add(component);
+ final int pos = component.getClassDescription().getDescribedClass().getName().indexOf('$');
+ final String baseClassName;
+ if ( pos == -1 ) {
+ baseClassName = component.getClassDescription().getDescribedClass().getName();
+ } else {
+ baseClassName = component.getClassDescription().getDescribedClass().getName().substring(0, pos);
+ }
+ final String baseClassPrefix = baseClassName + '$';
+
+ // check for inner classes
+ final Iterator<ComponentContainer> i = components.iterator();
+ while ( i.hasNext() ) {
+ final ComponentContainer cc = i.next();
+ if ( cc.getClassDescription().getDescribedClass().getName().startsWith(baseClassPrefix) ) {
+ innerList.add(cc);
+ i.remove();
+ }
+ }
+
module.getOptions().setSpecVersion(component.getComponentDescription().getSpecVersion());
- final File file = new File(descriptorDir, component.getClassDescription().getDescribedClass().getName() + ".xml");
+ final File file = new File(descriptorDir, baseClassName + ".xml");
try {
- ComponentDescriptorIO.generateXML(module, Collections.singletonList(component), file, logger);
+ ComponentDescriptorIO.generateXML(module, innerList, file, logger);
} catch (final IOException e) {
throw new SCRDescriptorException("Unable to generate xml", file.toString(), e);
} catch (final TransformerException e) {
diff --git a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
index 208bb79..7aa1dfb 100644
--- a/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
+++ b/scrplugin/generator/src/main/java/org/apache/felix/scrplugin/xml/MetaTypeIO.java
@@ -21,7 +21,6 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -97,14 +96,43 @@
final List<String> fileNames = new ArrayList<String>();
if ( options.isGenerateSeparateDescriptors() ) {
+ // create a list with relevant components
+ final List<ComponentContainer> components = new ArrayList<ComponentContainer>();
for(final ComponentContainer component : module.getComponents() ) {
if ( component.getMetatypeContainer() != null ) {
- final File file = new File(mtDir, component.getClassDescription().getDescribedClass().getName() + ".xml");
- logger.info("Generating 1 MetaType Descriptor in " + file);
- MetaTypeIO.write(module, Collections.singletonList(component), file);
- fileNames.add(parentDir.getName() + '/' + mtDir.getName() + '/' + file.getName());
+ components.add(component);
}
}
+
+ while ( !components.isEmpty() ) {
+ // get the first component
+ final List<ComponentContainer> innerList = new ArrayList<ComponentContainer>();
+ final ComponentContainer component = components.remove(0);
+ innerList.add(component);
+ final int pos = component.getClassDescription().getDescribedClass().getName().indexOf('$');
+ final String baseClassName;
+ if ( pos == -1 ) {
+ baseClassName = component.getClassDescription().getDescribedClass().getName();
+ } else {
+ baseClassName = component.getClassDescription().getDescribedClass().getName().substring(0, pos);
+ }
+ final String baseClassPrefix = baseClassName + '$';
+
+ // check for inner classes
+ final Iterator<ComponentContainer> i = components.iterator();
+ while ( i.hasNext() ) {
+ final ComponentContainer cc = i.next();
+ if ( cc.getClassDescription().getDescribedClass().getName().startsWith(baseClassPrefix) ) {
+ innerList.add(cc);
+ i.remove();
+ }
+ }
+
+ final File file = new File(mtDir, baseClassName + ".xml");
+ logger.info("Generating " + innerList.size() + " MetaType Descriptor in " + file);
+ MetaTypeIO.write(module, innerList, file);
+ fileNames.add(parentDir.getName() + '/' + mtDir.getName() + '/' + file.getName());
+ }
} else {
logger.info("Generating " + metatypeCount + " MetaType Descriptors in " + mtFile);
MetaTypeIO.write(module, module.getComponents(), mtFile);