Invoke service lifecycle callbacks on composition (each init method can return a dependency customization map).
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@958127 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
index 3b3b2e5..d9b3363 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
@@ -91,9 +91,18 @@
private List<Dependency> m_namedDeps = new ArrayList<Dependency>();
private Bundle m_bundle;
+ /**
+ * Makes a new ServiceLifecycleHandler object. This objects allows to decorate the "init" service callback, in
+ * order to see if "init" callback returns a dependency customization map.
+ *
+ * @param srv The Service for the annotated class
+ * @param srvBundle the Service bundle
+ * @param dm The DependencyManager bundle
+ * @param srvMeta The Service MetaData
+ * @param depMeta The Dependencies MetaData
+ */
public ServiceLifecycleHandler(Service srv, Bundle srvBundle, DependencyManager dm,
MetaData srvMeta, List<MetaData> depMeta)
- throws Exception
{
m_srvMeta = srvMeta;
m_init = srvMeta.getString(Params.init, null);
@@ -104,19 +113,34 @@
m_depsMeta = depMeta;
}
+ /**
+ * Handles an "init" lifecycle service callback. We just catch the "init" method, and callback ourself
+ * the actual Service' init method, to see if it returns a dependency customization map.
+ *
+ * @param service The Annotated Service
+ * @throws Exception on any errors
+ */
@SuppressWarnings("unchecked")
public void init(Service service)
throws Exception
{
Object serviceInstance = service.getService();
DependencyManager dm = service.getDependencyManager();
- // Invoke the service instance init method, and check if it returns a dependency
- // customization map. This map will be used to configure some dependency filters
- // (or required flag).
+
+ // Invoke all composites' init methods, and for each one, check if a dependency
+ // customization map is returned by the method. This map will be used to configure
+ // some dependency filters (or required flag).
- Object o = invokeMethod(serviceInstance, m_init, dm, service);
- Map<String, String> customization = (o != null && Map.class.isAssignableFrom(o.getClass())) ?
- (Map<String, String>) o : new HashMap<String, String>();
+ Map<String, String> customization = new HashMap<String, String>();
+ Object[] composites = service.getCompositionInstances();
+ for (Object composite : composites)
+ {
+ Object o = invokeMethod(composite, m_init, dm, service);
+ if (o != null && Map.class.isAssignableFrom(o.getClass()))
+ {
+ customization.putAll((Map) o);
+ }
+ }
Log.instance().log(LogService.LOG_DEBUG,
"ServiceLifecycleHandler.init: invoked init method from service %s " +
@@ -153,33 +177,74 @@
m_namedDeps.add(d);
service.add(d);
}
- }
+ }
}
-
+
+ /**
+ * Catches the Service's start lifecycle callback. We just invoke ourself the service "start" callback on
+ * the service instance, as well as on all eventual service composites.
+ *
+ * @param service The Annotated Service
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
public void start(Service service)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
- Object serviceInstance = service.getService();
- DependencyManager dm = service.getDependencyManager();
- invokeMethod(serviceInstance, m_start, dm, service);
+ callbackComposites(service, m_start);
}
+ /**
+ * Catches the Service's stop lifecycle callback. We just invoke ourself the service "stop" callback on
+ * the service instance, as well as on all eventual service composites.
+ *
+ * @param service The Annotated Service
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
public void stop(Service service)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
- Object serviceInstance = service.getService();
- DependencyManager dm = service.getDependencyManager();
- invokeMethod(serviceInstance, m_stop, dm, service);
+ callbackComposites(service, m_stop);
}
+ /**
+ * Catches the Service's destroy lifecycle callback. We just invoke ourself the service "destroy" callback on
+ * the service instance, as well as on all eventual service composites.
+ *
+ * @param service The Annotated Service
+ * @throws IllegalArgumentException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
public void destroy(Service service)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
- Object serviceInstance = service.getService();
- DependencyManager dm = service.getDependencyManager();
- invokeMethod(serviceInstance, m_destroy, dm, service);
+ callbackComposites(service, m_destroy);
}
+ /**
+ * Invoke a callback on the actual Service.
+ *
+ * @param service the Service used to managed the annotated Service
+ * @param callback the callback to invoke (init, start, stop, or destroy)
+ */
+ private void callbackComposites(Service service, String callback)
+ throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
+ {
+ Object serviceInstance = service.getService();
+ Object[] composites = service.getCompositionInstances();
+ for (Object composite: composites)
+ {
+ invokeMethod(composite, callback, service.getDependencyManager(), service);
+ }
+ }
+
+ /**
+ * Invoke a callback on an Object instance.
+ */
private Object invokeMethod(Object serviceInstance, String method, DependencyManager dm, Service service)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{