- Reworked the aspect API in order to allow to provide aspect parameters by
reusing the Service methods (setComposition/setCallbacks, etc ...).
- Changed return type of method Service.setServiceProperties().
- Fixed wrong synchronize in AbstractDecorator regarding factory configuration adapters.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@947378 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
index 2685e87..57ee254 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyActivatorBase.java
@@ -157,14 +157,8 @@
return m_manager.createResourceDependency();
}
- public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, Object aspectImplementation, Dictionary properties) {
- return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, aspectImplementation, properties);
- }
- public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, Object factory, String factoryCreateMethod, Dictionary properties) {
- return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, factory, factoryCreateMethod, properties);
- }
- public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, Object factory, String factoryCreateMethod, String attributeName, Dictionary properties) {
- return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, factory, factoryCreateMethod, attributeName, properties);
+ public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, String attributeName) {
+ return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, attributeName);
}
public Service createAdapterService(Class serviceInterface, String serviceFilter, String adapterInterface, Object adapterImplementation, Dictionary adapterProperties) {
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
index c704526..aeb5e3e 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/DependencyManager.java
@@ -31,7 +31,7 @@
import org.apache.felix.dm.dependencies.ServiceDependency;
import org.apache.felix.dm.dependencies.TemporalServiceDependency;
import org.apache.felix.dm.impl.AdapterImpl;
-import org.apache.felix.dm.impl.AspectImpl;
+import org.apache.felix.dm.impl.AspectServiceImpl;
import org.apache.felix.dm.impl.BundleAdapterImpl;
import org.apache.felix.dm.impl.FactoryConfigurationAdapterImpl;
import org.apache.felix.dm.impl.FactoryConfigurationAdapterMetaTypeImpl;
@@ -177,49 +177,29 @@
* It will also inherit all dependencies, and if you declare the original
* service as a member it will be injected.
*
+ * <h3>Usage Example</h3>
+ *
+ * <blockquote>
+ * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_aspect")
+ * .setImplementation(ExistingServiceAspect.class)
+ * .setServiceProperties(new Hashtable() {{ put("additional", "properties"); }})
+ * .setComposition("getComposition")
+ * .setCallbacks(new Handler(), null, "mystart", "mystop", null);
+ * <pre>
+ * </pre>
+ * </blockquote>
+ *
* @param serviceInterface the service interface to apply the aspect to
* @param serviceFilter the filter condition to use with the service interface
- * @param aspectImplementation the implementation of the aspect
- * @param aspectProperties additional properties to use with the aspect service registration
+ * @param ranking the level used to organize the aspect chain ordering
+ * @param attributeName, the aspect implementation field name where to inject original service.
+ * If null, any field matching the original service will be injected.
* @return a service that acts as a factory for generating aspects
*/
- public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, Object aspectImplementation, Dictionary aspectProperties) {
- return createService()
- .setImplementation(new AspectImpl(serviceInterface, serviceFilter, ranking, aspectImplementation, aspectProperties))
- .add(createServiceDependency()
- .setService(serviceInterface, createAspectFilter(serviceFilter))
- .setAutoConfig(false)
- .setCallbacks("added", "removed")
- );
+ public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, String attributeName) {
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, attributeName);
}
- public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, Object factory, String factoryCreateMethod, Dictionary aspectProperties) {
- return createService()
- .setImplementation(new AspectImpl(serviceInterface, serviceFilter, ranking, factory, factoryCreateMethod, aspectProperties))
- .add(createServiceDependency()
- .setService(serviceInterface, createAspectFilter(serviceFilter))
- .setAutoConfig(false)
- .setCallbacks("added", "removed")
- );
- }
- public Service createAspectService(Class serviceInterface, String serviceFilter, int ranking, Object factory, String factoryCreateMethod, String attributeName, Dictionary aspectProperties) {
- return createService()
- .setImplementation(new AspectImpl(serviceInterface, serviceFilter, ranking, factory, factoryCreateMethod, attributeName, aspectProperties))
- .add(createServiceDependency()
- .setService(serviceInterface, createAspectFilter(serviceFilter))
- .setAutoConfig(false)
- .setCallbacks("added", "removed")
- );
- }
- private String createAspectFilter(String filter) {
- // we only want to match services which are not themselves aspects
- if (filter == null || filter.length() == 0) {
- return "(!(" + ASPECT + "=*))";
- }
- else {
- return "(&(!(" + ASPECT + "=*))" + filter + ")";
- }
- }
-
+
/**
* Creates a new adapter. The adapter will be applied to any service that
* matches the specified interface and filter. For each matching service
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
index 16f23d6..cb9803e 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AbstractDecorator.java
@@ -21,11 +21,14 @@
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.Dependency;
import org.apache.felix.dm.resources.Resource;
import org.apache.felix.dm.service.Service;
+import org.apache.felix.dm.service.ServiceStateListener;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceReference;
import org.osgi.service.cm.ConfigurationException;
@@ -45,6 +48,90 @@
throw new NoSuchMethodError("Method updateService not implemented");
}
+ /**
+ * Set some service properties to all already instantiated services.
+ */
+ public void setServiceProperties(Dictionary serviceProperties) {
+ Map services = new HashMap();
+ synchronized (this) {
+ services.putAll(m_services);
+ }
+ Iterator i = services.values().iterator();
+ while (i.hasNext()) {
+ ((Service) i.next()).setServiceProperties(serviceProperties);
+ }
+ }
+
+ /**
+ * Remove a StateListener from all already instantiated services.
+ */
+ public void addStateListener(ServiceStateListener listener) {
+ Map services = new HashMap();
+ synchronized (this) {
+ services.putAll(m_services);
+ }
+ Iterator i = services.values().iterator();
+ while (i.hasNext()) {
+ ((Service) i.next()).addStateListener(listener);
+ }
+ }
+
+ /**
+ * Remove a StateListener from all already instantiated services.
+ */
+ public void removeStateListener(ServiceStateListener listener) {
+ Map services = new HashMap();
+ synchronized (this) {
+ services.putAll(m_services);
+ }
+ Iterator i = services.values().iterator();
+ while (i.hasNext()) {
+ ((Service) i.next()).removeStateListener(listener);
+ }
+ }
+
+ /**
+ * Add a Dependency to all already instantiated services.
+ */
+ public void addDependency(Dependency d) {
+ Map services = new HashMap();
+ synchronized (this) {
+ services.putAll(m_services);
+ }
+ Iterator i = services.values().iterator();
+ while (i.hasNext()) {
+ ((Service) i.next()).add(d);
+ }
+ }
+
+ /**
+ * Add a Dependency to all already instantiated services.
+ */
+ public void addDependencies(List dependencies) {
+ Map services = new HashMap();
+ synchronized (this) {
+ services.putAll(m_services);
+ }
+ Iterator i = services.values().iterator();
+ while (i.hasNext()) {
+ ((Service) i.next()).add(dependencies);
+ }
+ }
+
+ /**
+ * Remove a Dependency from all instantiated services.
+ */
+ public void removeDependency(Dependency d) {
+ Map services = new HashMap();
+ synchronized (this) {
+ services.putAll(m_services);
+ }
+ Iterator i = services.values().iterator();
+ while (i.hasNext()) {
+ ((Service) i.next()).remove(d);
+ }
+ }
+
// callbacks for FactoryConfigurationAdapterImpl
public void updated(String pid, Dictionary properties) throws ConfigurationException {
try {
@@ -74,8 +161,7 @@
}
}
- public synchronized void deleted(String pid)
- {
+ public void deleted(String pid) {
Service service = null;
synchronized (this) {
service = (Service) m_services.remove(pid);
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java
deleted file mode 100644
index 72c1436..0000000
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectImpl.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.impl;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.felix.dm.DependencyManager;
-import org.apache.felix.dm.service.Service;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class AspectImpl extends AbstractDecorator {
- private volatile Service m_service;
- private final Class m_serviceInterface;
- private final String m_serviceFilter;
- private final Object m_aspectImplementation;
- private final Dictionary m_aspectProperties;
- private final Object m_factory;
- private final String m_factoryCreateMethod;
- private final int m_ranking;
- private final String m_attributeName;
-
- public AspectImpl(Class serviceInterface, String serviceFilter, int ranking, Object aspectImplementation, Dictionary properties) {
- m_serviceInterface = serviceInterface;
- m_serviceFilter = serviceFilter;
- m_aspectImplementation = aspectImplementation;
- m_aspectProperties = properties;
- m_factory = null;
- m_factoryCreateMethod = null;
- m_ranking = ranking;
- m_attributeName = null;
- }
-
- public AspectImpl(Class serviceInterface, String serviceFilter, int ranking, Object factory, String factoryCreateMethod, Dictionary properties) {
- m_serviceInterface = serviceInterface;
- m_serviceFilter = serviceFilter;
- m_factory = factory;
- m_factoryCreateMethod = factoryCreateMethod;
- m_aspectProperties = properties;
- m_aspectImplementation = null;
- m_ranking = ranking;
- m_attributeName = null;
- }
-
- public AspectImpl(Class serviceInterface, String serviceFilter, int ranking, Object factory, String factoryCreateMethod, String attributeName, Dictionary properties) {
- m_serviceInterface = serviceInterface;
- m_serviceFilter = serviceFilter;
- m_factory = factory;
- m_factoryCreateMethod = factoryCreateMethod;
- m_attributeName = attributeName;
- m_aspectProperties = properties;
- m_aspectImplementation = null;
- m_ranking = ranking;
- }
-
- public Service createService(Object[] properties) {
- ServiceReference ref = (ServiceReference) properties[0];
- Object service = properties[1];
- Properties props = new Properties();
- // first add our aspect property
- props.put(DependencyManager.ASPECT, ref.getProperty(Constants.SERVICE_ID));
- // and the ranking
- props.put(Constants.SERVICE_RANKING, Integer.valueOf(m_ranking));
- String[] keys = ref.getPropertyKeys();
- for (int i = 0; i < keys.length; i++) {
- props.put(keys[i], ref.getProperty(keys[i]));
- }
- if (m_aspectProperties != null) {
- Enumeration e = m_aspectProperties.keys();
- while (e.hasMoreElements()) {
- Object key = e.nextElement();
- props.put(key, m_aspectProperties.get(key));
- }
- }
- List dependencies = m_service.getDependencies();
- dependencies.remove(0);
- if (m_aspectImplementation == null) {
- if (m_attributeName == null) {
- return m_manager.createService()
- .setInterface(m_serviceInterface.getName(), props)
- .setFactory(m_factory, m_factoryCreateMethod)
- .add(dependencies)
- .add(m_manager.createServiceDependency()
- .setService(m_serviceInterface, createAspectFilter(m_serviceFilter))
- .setRequired(true));
- }
- else {
- return m_manager.createService()
- .setInterface(m_serviceInterface.getName(), props)
- .setFactory(m_factory, m_factoryCreateMethod)
- .add(dependencies)
- .add(m_manager.createServiceDependency()
- .setService(m_serviceInterface, createAspectFilter(m_serviceFilter))
- .setAutoConfig(m_attributeName)
- .setRequired(true));
- }
- }
- else {
- return m_manager.createService()
- .setInterface(m_serviceInterface.getName(), props)
- .setImplementation(m_aspectImplementation)
- .add(dependencies)
- .add(m_manager.createServiceDependency()
- .setService(m_serviceInterface, createAspectFilter(m_serviceFilter))
- .setRequired(true));
- }
- }
- private String createAspectFilter(String filter) {
- if (filter == null || filter.length() == 0) {
- return "(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=" + (m_ranking - 1) + "))";
- }
- else {
- return "(&(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=" + (m_ranking - 1) + "))" + filter + ")";
- }
- }
-}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
new file mode 100644
index 0000000..b298e68
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AspectServiceImpl.java
@@ -0,0 +1,155 @@
+/*
+ * 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.impl;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.dependencies.Dependency;
+import org.apache.felix.dm.dependencies.ServiceDependency;
+import org.apache.felix.dm.service.Service;
+import org.apache.felix.dm.service.ServiceStateListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Aspect Service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual aspect service implementation.
+ */
+public class AspectServiceImpl extends FilterService
+{
+ public AspectServiceImpl(DependencyManager dm, Class aspectInterface, String aspectFilter, int ranking, String autoConfig)
+ {
+ super(dm.createService()); // This service will be filtered by our super class, allowing us to take control.
+ m_service.setImplementation(new AspectImpl(aspectInterface, aspectFilter, ranking, autoConfig))
+ .add(dm.createServiceDependency()
+ .setService(aspectInterface, createAspectFilter(aspectFilter))
+ .setAutoConfig(false)
+ .setCallbacks("added", "removed"));
+ }
+
+ private String createAspectFilter(String filter) {
+ // we only want to match services which are not themselves aspects
+ if (filter == null || filter.length() == 0) {
+ return "(!(" + DependencyManager.ASPECT + "=*))";
+ }
+ else {
+ return "(&(!(" + DependencyManager.ASPECT + "=*))" + filter + ")";
+ }
+ }
+
+ /**
+ * This class is the Aspect Implementation. It will create the actual Aspect Service, and
+ * will use the Aspect Service parameters provided by our enclosing class.
+ */
+ class AspectImpl extends AbstractDecorator {
+ private final Class m_aspectInterface; // the service decorated by this aspect
+ private final String m_aspectFilter; // the service filter decorated by this aspect
+ private final int m_ranking; // the aspect ranking
+ private final String m_field; // the aspect impl field name where to inject decorated service
+
+ public AspectImpl(Class aspectInterface, String aspectFilter, int ranking, String field) {
+ m_aspectInterface = aspectInterface;
+ m_aspectFilter = aspectFilter;
+ m_ranking = ranking;
+ m_field = field;
+ }
+
+ public Service createService(Object[] params) {
+ List dependencies = m_service.getDependencies();
+ // remove our internal dependency
+ dependencies.remove(0);
+ Properties serviceProperties = getServiceProperties(params);
+ String[] serviceInterfaces = getServiceInterfaces();
+ Service service = m_manager.createService()
+ .setInterface(serviceInterfaces, serviceProperties)
+ .setImplementation(m_serviceImpl)
+ .setFactory(m_factory, m_factoryCreateMethod) // if not set, no effect
+ .setComposition(m_compositionInstance, m_compositionMethod) // if not set, no effect
+ .setCallbacks(m_callbackObject, m_init, m_start, m_stop, m_destroy) // if not set, no effect
+ .add(dependencies)
+ .add(getAspectDependency());
+ for (int i = 0; i < m_stateListeners.size(); i ++) {
+ service.addStateListener((ServiceStateListener) m_stateListeners.get(i));
+ }
+ return service;
+ }
+
+ private Properties getServiceProperties(Object[] params) {
+ ServiceReference ref = (ServiceReference) params[0];
+ Object service = params[1];
+ Properties props = new Properties();
+ // first add our aspect property
+ props.put(DependencyManager.ASPECT, ref.getProperty(Constants.SERVICE_ID));
+ // and the ranking
+ props.put(Constants.SERVICE_RANKING, Integer.valueOf(m_ranking));
+ String[] keys = ref.getPropertyKeys();
+ for (int i = 0; i < keys.length; i++) {
+ props.put(keys[i], ref.getProperty(keys[i]));
+ }
+ if (m_serviceProperties != null) {
+ Enumeration e = m_serviceProperties.keys();
+ while (e.hasMoreElements()) {
+ Object key = e.nextElement();
+ props.put(key, m_serviceProperties.get(key));
+ }
+ }
+ return props;
+ }
+
+ private String[] getServiceInterfaces()
+ {
+ List serviceNames = new ArrayList();
+ // Of course, we provide the aspect interface.
+ serviceNames.add(m_aspectInterface.getName());
+ // But also append additional aspect implementation interfaces.
+ if (m_serviceInterfaces != null) {
+ for (int i = 0; i < m_serviceInterfaces.length; i ++) {
+ if (! m_serviceInterfaces[i].equals(m_aspectInterface.getName())) {
+ serviceNames.add(m_serviceInterfaces[i]);
+ }
+ }
+ }
+ return (String[]) serviceNames.toArray(new String[serviceNames.size()]);
+ }
+
+ private Dependency getAspectDependency() {
+ ServiceDependency sd =
+ m_manager.createServiceDependency()
+ .setService(m_aspectInterface, createAspectFilter(m_aspectFilter))
+ .setRequired(true);
+
+ if (m_field != null) {
+ sd.setAutoConfig(m_field);
+ }
+ return sd;
+ }
+
+ private String createAspectFilter(String filter) {
+ if (filter == null || filter.length() == 0) {
+ return "(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=" + (m_ranking - 1) + "))";
+ } else {
+ return "(&(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=" + (m_ranking - 1) + "))" + filter + ")";
+ }
+ }
+ }
+}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java
new file mode 100644
index 0000000..26719b5
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/FilterService.java
@@ -0,0 +1,254 @@
+/*
+ * 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.impl;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.felix.dm.dependencies.Dependency;
+import org.apache.felix.dm.service.Service;
+import org.apache.felix.dm.service.ServiceStateListener;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * This class allows to filter a Service interface. All Aspect/Adapters extends this class
+ * in order to add functionality to the default Service implementation.
+ */
+public class FilterService implements Service
+{
+ protected ServiceImpl m_service;
+ protected List m_stateListeners = new ArrayList();
+ protected String m_init = "init";
+ protected String m_start = "start";
+ protected String m_stop = "stop";
+ protected String m_destroy = "destroy";
+ protected Object m_callbackObject;
+ protected Object m_compositionInstance;
+ protected String m_compositionMethod;
+ protected String[] m_serviceInterfaces;
+ protected Object m_serviceImpl;
+ protected Object m_factory;
+ protected String m_factoryCreateMethod;
+ protected Dictionary m_serviceProperties;
+
+ public FilterService(Service service)
+ {
+ m_service = (ServiceImpl) service;
+ }
+
+ public Service add(Dependency dependency)
+ {
+ m_service.add(dependency);
+ // Add the dependency (if optional) to all already instantiated services.
+ // If the dependency is required, our internal service will be stopped/restarted, so in this case
+ // we have nothing to do.
+ if (! dependency.isRequired()) {
+ AbstractDecorator ad = (AbstractDecorator) m_service.getService();
+ if (ad != null)
+ {
+ ad.addDependency(dependency);
+ }
+ }
+ return this;
+ }
+
+ public Service add(List dependencies)
+ {
+ m_service.add(dependencies);
+ // Add the dependencies to all already instantiated services.
+ // If one dependency from the list is required, we have nothing to do, since our internal
+ // service will be stopped/restarted.
+ Iterator it = dependencies.iterator();
+ while (it.hasNext()) {
+ if (((Dependency) it.next()).isRequired()) {
+ return this;
+ }
+ }
+ // Ok, the list contains no required dependencies: add optionals dependencies in already instantiated
+ // services.
+ AbstractDecorator ad = (AbstractDecorator) m_service.getService();
+ if (ad != null)
+ {
+ ad.addDependencies(dependencies);
+ }
+ return this;
+ }
+
+ public void addStateListener(ServiceStateListener listener)
+ {
+ synchronized (this)
+ {
+ m_stateListeners.add(listener);
+ }
+ // Add the listener to all already instantiated services.
+ AbstractDecorator ad = (AbstractDecorator) m_service.getService();
+ if (ad != null)
+ {
+ ad.addStateListener(listener);
+ }
+ }
+
+ public List getDependencies()
+ {
+ return m_service.getDependencies();
+ }
+
+ public Object getService()
+ {
+ return m_service.getService();
+ }
+
+ public synchronized Dictionary getServiceProperties()
+ {
+ return m_serviceProperties;
+ }
+
+ public ServiceRegistration getServiceRegistration()
+ {
+ return m_service.getServiceRegistration();
+ }
+
+ public Service remove(Dependency dependency)
+ {
+ m_service.remove(dependency);
+ // Remove the dependency (if optional) from all already instantiated services.
+ // If the dependency is required, our internal service will be stopped, so in this case
+ // we have nothing to do.
+ if (!dependency.isRequired())
+ {
+ AbstractDecorator ad = (AbstractDecorator) m_service.getService();
+ if (ad != null)
+ {
+ ad.removeDependency(dependency);
+ }
+ }
+ return this;
+ }
+
+ public void removeStateListener(ServiceStateListener listener)
+ {
+ synchronized (this)
+ {
+ m_stateListeners.remove(listener);
+ }
+ // Remove the listener from all already instantiated services.
+ AbstractDecorator ad = (AbstractDecorator) m_service.getService();
+ if (ad != null)
+ {
+ ad.removeStateListener(listener);
+ }
+ }
+
+ public synchronized Service setCallbacks(Object instance, String init, String start, String stop,
+ String destroy)
+ {
+ m_service.ensureNotActive();
+ m_callbackObject = instance;
+ m_init = init;
+ m_start = start;
+ m_stop = stop;
+ m_destroy = destroy;
+ return this;
+ }
+
+ public Service setCallbacks(String init, String start, String stop, String destroy)
+ {
+ setCallbacks(null, init, start, stop, destroy);
+ return this;
+ }
+
+ public synchronized Service setComposition(Object instance, String getMethod)
+ {
+ m_service.ensureNotActive();
+ m_compositionInstance = instance;
+ m_compositionMethod = getMethod;
+ return this;
+ }
+
+ public synchronized Service setComposition(String getMethod)
+ {
+ m_service.ensureNotActive();
+ m_compositionMethod = getMethod;
+ return this;
+ }
+
+ public synchronized Service setFactory(Object factory, String createMethod)
+ {
+ m_service.ensureNotActive();
+ m_factory = factory;
+ m_factoryCreateMethod = createMethod;
+ return this;
+ }
+
+ public Service setFactory(String createMethod)
+ {
+ return setFactory(null, createMethod);
+ }
+
+ public synchronized Service setImplementation(Object implementation)
+ {
+ m_service.ensureNotActive();
+ m_serviceImpl = implementation;
+ return this;
+ }
+
+ public Service setInterface(String serviceName, Dictionary properties)
+ {
+ return setInterface(new String[] { serviceName }, properties);
+ }
+
+ public synchronized Service setInterface(String[] serviceInterfaces, Dictionary properties) {
+ m_service.ensureNotActive();
+ if (serviceInterfaces != null) {
+ m_serviceInterfaces = new String[serviceInterfaces.length];
+ System.arraycopy(serviceInterfaces, 0, m_serviceInterfaces, 0, serviceInterfaces.length);
+ m_serviceProperties = properties;
+ }
+ return this;
+ }
+
+ public Service setServiceProperties(Dictionary serviceProperties)
+ {
+ synchronized (this)
+ {
+ m_serviceProperties = serviceProperties;
+ }
+ // Set the properties to all already instantiated services.
+ if (serviceProperties != null) {
+ AbstractDecorator ad = (AbstractDecorator) m_service.getService();
+ if (ad != null)
+ {
+ ad.setServiceProperties(serviceProperties);
+ }
+ }
+ return this;
+ }
+
+ public void start()
+ {
+ m_service.start();
+ }
+
+ public void stop()
+ {
+ m_service.stop();
+ }
+}
\ No newline at end of file
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
index 36381c4..88fe9f1 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/ServiceImpl.java
@@ -422,11 +422,12 @@
return null;
}
- public synchronized void setServiceProperties(Dictionary serviceProperties) {
+ public synchronized Service setServiceProperties(Dictionary serviceProperties) {
m_serviceProperties = serviceProperties;
if ((m_registration != null) && (m_serviceName != null)) {
m_registration.setProperties(calculateServiceProperties());
}
+ return this;
}
// service state listener methods
@@ -991,7 +992,7 @@
}
}
- private void ensureNotActive() {
+ protected void ensureNotActive() {
State state;
synchronized (m_dependencies) {
state = m_state;
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/service/Service.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/service/Service.java
index c84fdff..8c06db6 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/service/Service.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/service/Service.java
@@ -136,7 +136,7 @@
*
* @param serviceProperties the properties
*/
- public void setServiceProperties(Dictionary serviceProperties);
+ public Service setServiceProperties(Dictionary serviceProperties);
/**
* Sets the names of the methods used as callbacks. These methods, when found, are