Author: mahrwald
Date: Thu Aug 11 15:57:04 2011
New Revision: 1156657
URL: http://svn.apache.org/viewvc?rev=1156657&view=rev
Log:
ARIES-725: Scan for anonymous inner services and references during modelling
Modified:
aries/trunk/application/application-modeller-common-test/src/test/java/org/apache/aries/application/modelling/ModellerTest.java
aries/trunk/application/application-modeller-common-test/src/test/resources/test.bundle/OSGI-INF/blueprint/bp.xml
aries/trunk/application/application-modeller/pom.xml
aries/trunk/application/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/AbstractParserProxy.java
Modified:
aries/trunk/application/application-modeller-common-test/src/test/java/org/apache/aries/application/modelling/ModellerTest.java
URL:
http://svn.apache.org/viewvc/aries/trunk/application/application-modeller-common-test/src/test/java/org/apache/aries/application/modelling/ModellerTest.java?rev=1156657&r1=1156656&r2=1156657&view=diff
==============================================================================
---
aries/trunk/application/application-modeller-common-test/src/test/java/org/apache/aries/application/modelling/ModellerTest.java
(original)
+++
aries/trunk/application/application-modeller-common-test/src/test/java/org/apache/aries/application/modelling/ModellerTest.java
Thu Aug 11 15:57:04 2011
@@ -6,7 +6,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.jar.Manifest;
@@ -39,7 +38,7 @@ public class ModellerTest {
ModelledResourceManagerImpl manager = new
ModelledResourceManagerImpl();
manager.setModellingManager(new ModellingManagerImpl());
manager.setParserProxy(ParserProxyTest.getMockParserServiceProxy());
-
manager.setModellingPlugins((Collection<ServiceModeller>)Collections.EMPTY_LIST);
+ manager.setModellingPlugins(Collections.<ServiceModeller>emptyList());
return Arrays.asList(new Object[][] {
{OfflineModellingFactory.getModelledResourceManager()},
@@ -127,13 +126,19 @@ public class ModellerTest {
// sanity check that we have parsed the services
- assertEquals(3, resource.getExportedServices().size());
- assertEquals(1, resource.getImportedServices().size());
+ assertEquals(4, resource.getExportedServices().size());
+ assertEquals(4, resource.getImportedServices().size());
- ImportedService service =
resource.getImportedServices().iterator().next();
- assertEquals("foo.bar.MyInjectedService", service.getInterface());
- assertTrue(service.isOptional());
- assertFalse(service.isList());
- assertEquals("anOptionalReference", service.getId());
+ boolean foundFirst = false;
+ for (ImportedService service : resource.getImportedServices()) {
+ if ("foo.bar.MyInjectedService".equals(service.getInterface())) {
+ foundFirst = true;
+ assertTrue(service.isOptional());
+ assertFalse(service.isList());
+ assertEquals("anOptionalReference", service.getId());
+ }
+ }
+
+ assertTrue(foundFirst);
}
}
Modified:
aries/trunk/application/application-modeller-common-test/src/test/resources/test.bundle/OSGI-INF/blueprint/bp.xml
URL:
http://svn.apache.org/viewvc/aries/trunk/application/application-modeller-common-test/src/test/resources/test.bundle/OSGI-INF/blueprint/bp.xml?rev=1156657&r1=1156656&r2=1156657&view=diff
==============================================================================
---
aries/trunk/application/application-modeller-common-test/src/test/resources/test.bundle/OSGI-INF/blueprint/bp.xml
(original)
+++
aries/trunk/application/application-modeller-common-test/src/test/resources/test.bundle/OSGI-INF/blueprint/bp.xml
Thu Aug 11 15:57:04 2011
@@ -41,6 +41,26 @@
<bean id="namedInnerBean" class="an.anonymous.Bean"/>
</service>
-
<reference id="anOptionalReference" interface="foo.bar.MyInjectedService"
availability="optional"/>
+
+ <bean class="java.util.ArrayList">
+ <argument>
+ <reference interface="java.util.Collection" />
+ </argument>
+ <argument>
+ <service interface="java.util.Collection">
+ <bean class="java.util.HashSet" />
+ </service>
+ </argument>
+
+ <property name="elements">
+ <reference interface="java.util.List" />
+ </property>
+ <property name="elementsInCollection">
+ <list>
+ <reference interface="java.util.Set" />
+ </list>
+ </property>
+ </bean>
+
</blueprint>
\ No newline at end of file
Modified: aries/trunk/application/application-modeller/pom.xml
URL:
http://svn.apache.org/viewvc/aries/trunk/application/application-modeller/pom.xml?rev=1156657&r1=1156656&r2=1156657&view=diff
==============================================================================
--- aries/trunk/application/application-modeller/pom.xml (original)
+++ aries/trunk/application/application-modeller/pom.xml Thu Aug 11 15:57:04
2011
@@ -77,6 +77,21 @@
<scope>provided</scope>
<version>0.3</version>
</dependency>
+
+ <!-- Blueprint API must come before OSGi compendium because we want to
compile against the Java 5 interfaces
+ with generics -->
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.api</artifactId>
+ <version>0.3.2-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.blueprint</groupId>
+ <artifactId>org.apache.aries.blueprint.core</artifactId>
+ <version>0.3.2-SNAPSHOT</version>
+ </dependency>
+
+
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
@@ -103,16 +118,6 @@
<scope>provided</scope>
<version>0.3.1-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.apache.aries.blueprint</groupId>
- <artifactId>org.apache.aries.blueprint.api</artifactId>
- <version>0.3.2-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.apache.aries.blueprint</groupId>
- <artifactId>org.apache.aries.blueprint.core</artifactId>
- <version>0.3.2-SNAPSHOT</version>
- </dependency>
</dependencies>
</project>
Modified:
aries/trunk/application/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/AbstractParserProxy.java
URL:
http://svn.apache.org/viewvc/aries/trunk/application/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/AbstractParserProxy.java?rev=1156657&r1=1156656&r2=1156657&view=diff
==============================================================================
---
aries/trunk/application/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/AbstractParserProxy.java
(original)
+++
aries/trunk/application/application-modeller/src/main/java/org/apache/aries/application/modelling/impl/AbstractParserProxy.java
Thu Aug 11 15:57:04 2011
@@ -8,6 +8,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -21,13 +22,18 @@ import org.apache.aries.application.mode
import org.apache.aries.application.modelling.WrappedServiceMetadata;
import org.apache.aries.blueprint.ComponentDefinitionRegistry;
import org.apache.aries.util.manifest.ManifestHeaderProcessor;
+import org.osgi.service.blueprint.reflect.BeanArgument;
import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.BeanProperty;
import org.osgi.service.blueprint.reflect.CollectionMetadata;
import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.MapEntry;
+import org.osgi.service.blueprint.reflect.MapMetadata;
import org.osgi.service.blueprint.reflect.Metadata;
import org.osgi.service.blueprint.reflect.RefMetadata;
import org.osgi.service.blueprint.reflect.ReferenceListMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceListener;
+import org.osgi.service.blueprint.reflect.RegistrationListener;
import org.osgi.service.blueprint.reflect.ServiceMetadata;
import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
import org.osgi.service.blueprint.reflect.Target;
@@ -101,9 +107,7 @@ abstract public class AbstractParserProx
boolean suppressAnonymousServices) {
_logger.debug(LOG_ENTRY, "parseCDRForServices", new Object[]{cdr,
suppressAnonymousServices});
List<ExportedService> result = new ArrayList<ExportedService>();
- Set<String> names = cdr.getComponentDefinitionNames();
- for (String name: names) {
- ComponentMetadata compMetadata = cdr.getComponentDefinition(name);
+ for (ComponentMetadata compMetadata : findAllComponents(cdr)) {
if (compMetadata instanceof ServiceMetadata) {
ServiceMetadata serviceMetadata = (ServiceMetadata)compMetadata;
String serviceName;
@@ -181,9 +185,7 @@ abstract public class AbstractParserProx
private List<ImportedService> parseCDRForReferences
(ComponentDefinitionRegistry cdr) throws InvalidAttributeException {
_logger.debug(LOG_ENTRY, "parseCDRForReferences", new
Object[]{cdr});
List<ImportedService> result = new ArrayList<ImportedService>();
- Set<String> names = cdr.getComponentDefinitionNames();
- for (String name: names) {
- ComponentMetadata compMetadata = cdr.getComponentDefinition(name);
+ for (ComponentMetadata compMetadata : findAllComponents(cdr)) {
if (compMetadata instanceof ServiceReferenceMetadata) {
ServiceReferenceMetadata referenceMetadata =
(ServiceReferenceMetadata)compMetadata;
@@ -210,6 +212,91 @@ abstract public class AbstractParserProx
_logger.debug(LOG_EXIT, "parseCDRForReferences", new
Object[]{result});
return result;
}
+
+ /**
+ * Find all the components in a given {@link
ComponentDefinitionRegistry} this finds top-level
+ * components as well as their nested counter-parts. It may however
not find components in custom namespacehandler
+ * {@link ComponentMetadata} instances.
+ *
+ * @param cdr The {@link ComponentDefinitionRegistry} to scan
+ * @return a {@link Set} of {@link ComponentMetadata}
+ */
+ private Set<ComponentMetadata>
findAllComponents(ComponentDefinitionRegistry cdr) {
+ Set<ComponentMetadata> components = new
HashSet<ComponentMetadata>();
+
+ for (String name : cdr.getComponentDefinitionNames()) {
+ ComponentMetadata component =
cdr.getComponentDefinition(name);
+ traverseComponent(component, components);
+ }
+
+ return components;
+ }
+
+ /**
+ * Traverse to find all nested {@link ComponentMetadata} instances
+ * @param metadata
+ * @param output
+ */
+ private void traverse(Metadata metadata, Set<ComponentMetadata>
output) {
+ if (metadata instanceof ComponentMetadata) {
+ traverseComponent((ComponentMetadata) metadata, output);
+ } else if (metadata instanceof CollectionMetadata) {
+ CollectionMetadata collection = (CollectionMetadata) metadata;
+
+ for (Metadata v : collection.getValues()) traverse(v, output);
+ } else if (metadata instanceof MapMetadata) {
+ MapMetadata map = (MapMetadata) metadata;
+
+ for (MapEntry e : map.getEntries()) {
+ traverse(e.getKey(), output);
+ traverse(e.getValue(), output);
+ }
+ }
+ }
+
+ /**
+ * Traverse {@link ComponentMetadata} instances to find all nested
{@link ComponentMetadata} instances
+ * @param component
+ * @param output
+ */
+ private void traverseComponent(ComponentMetadata component,
Set<ComponentMetadata> output) {
+ if (!!!output.add(component)) return;
+
+ if (component instanceof BeanMetadata) {
+ BeanMetadata bean = (BeanMetadata) component;
+
+ traverse(bean.getFactoryComponent(), output);
+
+ for (BeanArgument argument : bean.getArguments()) {
+ traverse(argument.getValue(), output);
+ }
+
+ for (BeanProperty property : bean.getProperties()) {
+ traverse(property.getValue(), output);
+ }
+
+ } else if (component instanceof ServiceMetadata) {
+ ServiceMetadata service = (ServiceMetadata) component;
+
+ traverse(service.getServiceComponent(), output);
+
+ for (RegistrationListener listener :
service.getRegistrationListeners()) {
+ traverse(listener.getListenerComponent(), output);
+ }
+
+ for (MapEntry e : service.getServiceProperties()) {
+ traverse(e.getKey(), output);
+ traverse(e.getValue(), output);
+ }
+
+ } else if (component instanceof ServiceReferenceMetadata) {
+ ServiceReferenceMetadata reference =
(ServiceReferenceMetadata) component;
+
+ for (ReferenceListener listener :
reference.getReferenceListeners()) {
+ traverse(listener.getListenerComponent(), output);
+ }
+ }
+ }
/**
* Some services are injected directly into isolated frameworks by
default. We do