Author: pderop
Date: Mon May 23 08:42:48 2011
New Revision: 1126383
URL: http://svn.apache.org/viewvc?rev=1126383&view=rev
Log:
[FELIX-2965] - Apply @Registered/@Unregistered annotation on composition
instances.
Added:
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1Service.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C2.java
Removed:
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/Composite.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/CompositeService.java
Modified:
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/CompositeAnnotationsTest.java
Modified:
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java?rev=1126383&r1=1126382&r2=1126383&view=diff
==============================================================================
---
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
(original)
+++
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
Mon May 23 08:42:48 2011
@@ -335,8 +335,13 @@ public class AnnotationCollector extends
// properties attribute
parseProperties(annotation, EntryParam.properties, writer);
- // provides attribute
- writer.putClassArray(annotation, EntryParam.provides, m_interfaces,
m_exportService);
+ // provides attribute.
+ if (writer.putClassArray(annotation, EntryParam.provides,
m_interfaces, m_exportService) == 0)
+ {
+ // no service provided: check if @Registered/@Unregistered
annotation are used
+ // and raise an error if true.
+ checkRegisteredUnregisteredNotPresent();
+ }
// factorySet attribute
String factorySetName = writer.putString(annotation,
EntryParam.factorySet, null);
@@ -644,7 +649,10 @@ public class AnnotationCollector extends
parseProperties(annotation, EntryParam.properties, writer);
// Parse the provided adapter service (use directly implemented
interface by default).
- writer.putClassArray(annotation, EntryParam.provides, m_interfaces,
m_exportService);
+ if (writer.putClassArray(annotation, EntryParam.provides,
m_interfaces, m_exportService) == 0)
+ {
+ checkRegisteredUnregisteredNotPresent();
+ }
// Parse factoryMethod attribute
writer.putString(annotation, EntryParam.factoryMethod, null);
@@ -684,7 +692,10 @@ public class AnnotationCollector extends
parseProperties(annotation, EntryParam.properties, writer);
// Parse the optional adapter service (use directly implemented
interface by default).
- writer.putClassArray(annotation, EntryParam.provides, m_interfaces,
m_exportService);
+ if (writer.putClassArray(annotation, EntryParam.provides,
m_interfaces, m_exportService) == 0)
+ {
+ checkRegisteredUnregisteredNotPresent();
+ }
// Parse propagate attribute
writer.putString(annotation, EntryParam.propagate,
Boolean.FALSE.toString());
@@ -720,7 +731,10 @@ public class AnnotationCollector extends
parseProperties(annotation, EntryParam.properties, writer);
// Parse the provided adapter service (use directly implemented
interface by default).
- writer.putClassArray(annotation, EntryParam.provides, m_interfaces,
m_exportService);
+ if (writer.putClassArray(annotation, EntryParam.provides,
m_interfaces, m_exportService) == 0)
+ {
+ checkRegisteredUnregisteredNotPresent();
+ }
// Parse propagate attribute
writer.putString(annotation, EntryParam.propagate,
Boolean.FALSE.toString());
@@ -754,7 +768,10 @@ public class AnnotationCollector extends
writer.putString(annotation, EntryParam.propagate,
Boolean.FALSE.toString());
// Parse the provided adapter service (use directly implemented
interface by default).
- writer.putClassArray(annotation, EntryParam.provides, m_interfaces,
m_exportService);
+ if (writer.putClassArray(annotation, EntryParam.provides,
m_interfaces, m_exportService) == 0)
+ {
+ checkRegisteredUnregisteredNotPresent();
+ }
// Parse Adapter properties.
parseProperties(annotation, EntryParam.properties, writer);
@@ -1008,6 +1025,27 @@ public class AnnotationCollector extends
}
/**
+ * This method checks if the @Registered and/or @Unregistered annotations
have been defined
+ * while they should not, because the component does not provide a service.
+ */
+ private void checkRegisteredUnregisteredNotPresent()
+ {
+ if (m_registeredMethod != null)
+ {
+ throw new IllegalStateException("@Registered annotation can't be
used on a Component " +
+ " which does not provide a service
(class=" + m_className + ")");
+
+ }
+
+ if (m_unregisteredMethod != null)
+ {
+ throw new IllegalStateException("@Unregistered annotation can't be
used on a Component " +
+ " which does not provide a service
(class=" + m_className + ")");
+
+ }
+ }
+
+ /**
* Get an annotation attribute, and return a default value if its not
present.
* @param <T> the type of the variable which is assigned to the return
value of this method.
* @param annotation The annotation we are parsing
Modified:
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java?rev=1126383&r1=1126382&r2=1126383&view=diff
==============================================================================
---
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
(original)
+++
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
Mon May 23 08:42:48 2011
@@ -221,8 +221,9 @@ public class EntryWriter
/**
* Get a class array attribute value from an annotation and write it into
this descriptor entry.
* Also collect classes found from the array into a given Set.
+ * @return the class array size.
*/
- public void putClassArray(Annotation annotation, EntryParam param, Object
def, Set<String> collect)
+ public int putClassArray(Annotation annotation, EntryParam param, Object
def, Set<String> collect)
{
checkType(param.toString());
@@ -258,7 +259,11 @@ public class EntryWriter
+ value.toString(), e);
}
}
+
+ return ((Object[]) value).length;
}
+
+ return 0;
}
/**
Modified:
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java?rev=1126383&r1=1126382&r2=1126383&view=diff
==============================================================================
---
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
(original)
+++
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AbstractBuilder.java
Mon May 23 08:42:48 2011
@@ -144,18 +144,23 @@ public abstract class AbstractBuilder
{
if (m_registered != null)
{
- Object instance = c.getService();
- try
- {
- InvocationUtil
- .invokeCallbackMethod(instance,
- m_registered,
- new Class[][] {{
ServiceRegistration.class }, {}},
- new Object[][] {{
c.getServiceRegistration() }, {}});
- }
- catch (Throwable t)
+ // The component has registered a service: notify all
component instances
+ Object[] componentInstances = c.getCompositionInstances();
+ for (Object instance : componentInstances)
{
- Log.instance().error("Exception caught while invoking
method %s on component %s", t, m_registered, instance);
+ try
+ {
+ Class[][] signatures = new Class[][] { {
ServiceRegistration.class }, {} };
+ Object[][] params = new Object[][] { {
c.getServiceRegistration() }, {} };
+ InvocationUtil.invokeCallbackMethod(instance,
m_registered, signatures, params);
+ }
+ catch (Throwable t)
+ {
+ Log.instance().error("Exception caught while invoking
method %s on component %s",
+ t,
+ m_registered,
+ instance);
+ }
}
}
}
Added:
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1.java?rev=1126383&view=auto
==============================================================================
---
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1.java
(added)
+++
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1.java
Mon May 23 08:42:48 2011
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
information
+ * regarding copyright ownership. The ASF licenses this file to you under the
Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance
with the License.
+ * You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless
+ * required by applicable law or agreed to in writing, software distributed
under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express
+ * or implied. See the License for the specific language governing permissions
and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.test.bundle.annotation.composite;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.dm.annotation.api.Component;
+import org.apache.felix.dm.annotation.api.Composition;
+import org.apache.felix.dm.annotation.api.Destroy;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Registered;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.annotation.api.Stop;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * This service is also composed of the Component object.
+ */
+@Component
+public class C1 implements C1Service
+{
+ /* We are composed of this object, which will also be injected with our
dependencies */
+ private C2 m_c2 = new C2();
+
+ /* This dependency filter will be configured from our init method */
+ @ServiceDependency(name = "D")
+ public volatile Runnable m_runnable;
+
+ /* Object used to check that methods are called in the proper sequence */
+ @ServiceDependency(filter="(name=C1)")
+ private volatile Sequencer m_sequencer;
+
+ /**
+ * Dynamically configure our "D" dependency, using a dependency
customization map
+ */
+ @Init
+ Map<String, String> init()
+ {
+ m_sequencer.step(1);
+ // Configure a filter for our dependency whose name is "D"
+ Map<String, String> customization = new HashMap<String, String>();
+ customization.put("D.filter", "(foo=bar2)");
+ customization.put("D.required", "true");
+ return customization;
+ }
+
+ /**
+ * Return the list of object our service is composed of
+ */
+ @Composition
+ Object[] getComposition()
+ {
+ return new Object[] { this, m_c2 };
+ }
+
+ /**
+ * Our Service is starting, and our Composites will also be
+ */
+ @Start
+ void start()
+ {
+ System.out.println("start: m_runnable=" + m_runnable);
+ m_sequencer.step(3);
+ m_runnable.run(); /* step 4 */
+ // Our Component.start() method should be called once this method
returns.
+ }
+
+ /**
+ * Our provided service has been registered into the OSGi service registry.
+ */
+ @Registered
+ void registered(ServiceRegistration sr)
+ {
+ m_sequencer.step(7);
+ }
+
+ /**
+ * Our Service is stopping, and our Composites will also be
+ */
+ @Stop
+ void stop()
+ {
+ m_sequencer.step(9);
+ // Our Component.stop() method should be called once this method
returns.
+ }
+
+ /**
+ * Our Service is destroying, and our Composites will also be.
+ */
+ @Destroy
+ void destroy()
+ {
+ m_sequencer.step(11);
+ // Our Component.destroy() method should be called once this method
returns.
+ }
+}
Added:
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1Service.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1Service.java?rev=1126383&view=auto
==============================================================================
---
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1Service.java
(added)
+++
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C1Service.java
Mon May 23 08:42:48 2011
@@ -0,0 +1,5 @@
+package org.apache.felix.dm.test.bundle.annotation.composite;
+
+public interface C1Service
+{
+}
Added:
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C2.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C2.java?rev=1126383&view=auto
==============================================================================
---
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C2.java
(added)
+++
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/C2.java
Mon May 23 08:42:48 2011
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional
information
+ * regarding copyright ownership. The ASF licenses this file to you under the
Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in compliance
with the License.
+ * You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 Unless
+ * required by applicable law or agreed to in writing, software distributed
under the License is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express
+ * or implied. See the License for the specific language governing permissions
and limitations
+ * under the License.
+ */
+package org.apache.felix.dm.test.bundle.annotation.composite;
+
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The CompositeService is also made up of this Class.
+ */
+public class C2
+{
+ // Injected dependency (from CompositeService)
+ private volatile Sequencer m_sequencer;
+
+ // Injected dependency (from CompositeService)
+ public volatile Runnable m_runnable;
+
+ // lifecycle callback (same method as the one from CompositeService)
+ void init()
+ {
+ m_sequencer.step(2);
+ }
+
+ // lifecycle callback (same method as the one from CompositeService)
+ void start()
+ {
+ m_sequencer.step(5);
+ m_runnable.run(); /* step 6 */
+ }
+
+ void registered(ServiceRegistration sr)
+ {
+ if (sr == null)
+ {
+ m_sequencer.throwable(new Exception("null service registration"));
+ }
+ m_sequencer.step(8);
+ }
+
+ // lifecycle callback (same method as the one from CompositeService)
+ void stop()
+ {
+ m_sequencer.step(10);
+ }
+
+ // lifecycle callback (same method as the one from CompositeService)
+ void destroy()
+ {
+ m_sequencer.step(12);
+ }
+}
Modified:
felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/CompositeAnnotationsTest.java
URL:
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/CompositeAnnotationsTest.java?rev=1126383&r1=1126382&r2=1126383&view=diff
==============================================================================
---
felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/CompositeAnnotationsTest.java
(original)
+++
felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/CompositeAnnotationsTest.java
Mon May 23 08:42:48 2011
@@ -64,7 +64,7 @@ public class CompositeAnnotationsTest ex
{
DependencyManager m = new DependencyManager(context);
// Provide the Sequencer service to the "Component" service.
- m.add(makeSequencer(m, "CompositeService"));
+ m.add(makeSequencer(m, "C1"));
m.add(makeSequencer(m, "Dependency1"));
m.add(makeSequencer(m, "Dependency2"));
// Check if the components have been initialized orderly
@@ -72,6 +72,6 @@ public class CompositeAnnotationsTest ex
// Stop the bundle
stopBundle("CompositeAnnotationsTest", context);
// And check if the components lifecycle callbacks are called orderly
- m_ensure.waitForStep(10, 10000);
+ m_ensure.waitForStep(12, 10000);
}
}