You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by pd...@apache.org on 2011/05/23 10:42:48 UTC
svn commit: r1126383 - in /felix/trunk/dependencymanager:
annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/
runtime/src/main/java/org/apache/felix/dm/runtime/
test/src/main/java/org/apache/felix/dm/test/bundle/annotation/composite/
te...
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);
}
}