reworked BundleAdapter API in order to allow to provide adapter parameters by reusing the Service interface methods (setInterface, setImplementation, etc ...)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@947502 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 1548034..53156a0 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
@@ -169,11 +169,8 @@
return m_manager.createResourceAdapterService(resourceFilter, propagate);
}
- public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String adapterInterface, Dictionary adapterProperties, boolean propagate) {
- return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate);
- }
- public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String[] adapterInterface, Dictionary adapterProperties, boolean propagate) {
- return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate);
+ public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
+ return m_manager.createBundleAdapterService(bundleStateMask, bundleFilter, propagate);
}
/**
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 d9b8b4c..81cfc32 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
@@ -33,6 +33,7 @@
import org.apache.felix.dm.impl.AdapterServiceImpl;
import org.apache.felix.dm.impl.AspectServiceImpl;
import org.apache.felix.dm.impl.BundleAdapterImpl;
+import org.apache.felix.dm.impl.BundleAdapterServiceImpl;
import org.apache.felix.dm.impl.FactoryConfigurationAdapterImpl;
import org.apache.felix.dm.impl.FactoryConfigurationAdapterMetaTypeImpl;
import org.apache.felix.dm.impl.Logger;
@@ -46,6 +47,7 @@
import org.apache.felix.dm.impl.metatype.PropertyMetaDataImpl;
import org.apache.felix.dm.resources.Resource;
import org.apache.felix.dm.service.Service;
+import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.service.cm.ManagedServiceFactory;
@@ -270,31 +272,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.createBundleAdapterService(Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE,
+ * "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
+ * true)
+ * // The interface to use when registering adapter
+ * .setInterface(AdapterService.class, new Hashtable() {{ put("foo", "bar"); }})
+ * // the implementation of the adapter
+ * .setImplementation(AdapterServiceImpl.class)
+ * // The callback invoked on adapter lifecycle events
+ * .setCallbacks(new Handler(), "init", "start", "stop", "destroy");
+ * <pre>
+ * </pre>
+ * </blockquote>
+ *
* @param bundleStateMask the bundle state mask to apply
* @param bundleFilter the filter to apply to the bundle manifest
- * @param adapterImplementation the implementation of the adapter
- * @param adapterInterface the interface to use when registering adapters
- * @param adapterProperties additional properties to use with the service registration
* @param propagate <code>true</code> if properties from the bundle should be propagated to the service
* @return a service that acts as a factory for generating bundle adapters
*/
- public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String adapterInterface, Dictionary adapterProperties, boolean propagate) {
- return createService()
- .setImplementation(new BundleAdapterImpl(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate))
- .add(createBundleDependency()
- .setFilter(bundleFilter)
- .setStateMask(bundleStateMask)
- .setCallbacks("added", "removed")
- );
- }
- public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, Object adapterImplementation, String[] adapterInterface, Dictionary adapterProperties, boolean propagate) {
- return createService()
- .setImplementation(new BundleAdapterImpl(bundleStateMask, bundleFilter, adapterImplementation, adapterInterface, adapterProperties, propagate))
- .add(createBundleDependency()
- .setFilter(bundleFilter)
- .setStateMask(bundleStateMask)
- .setCallbacks("added", "removed")
- );
+ public Service createBundleAdapterService(int bundleStateMask, String bundleFilter, boolean propagate) {
+ return new BundleAdapterServiceImpl(this, bundleStateMask, bundleFilter, propagate);
}
/**
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterImpl.java
deleted file mode 100644
index 2f9a9dc..0000000
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterImpl.java
+++ /dev/null
@@ -1,97 +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.service.Service;
-import org.osgi.framework.Bundle;
-
-public class BundleAdapterImpl extends AbstractDecorator {
- private volatile Service m_service;
- private final String m_resourceFilter;
- private final Object m_adapterImplementation;
- private final Object m_adapterInterface;
- private final Dictionary m_adapterProperties;
- private final boolean m_propagate;
- private final int m_bundleStateMask;
-
- public BundleAdapterImpl(int bundleStateMask, String bundleFilter, Object adapterImplementation, String adapterInterface, Dictionary adapterProperties, boolean propagate) {
- m_bundleStateMask = bundleStateMask;
- m_resourceFilter = bundleFilter;
- m_adapterImplementation = adapterImplementation;
- m_adapterInterface = adapterInterface;
- m_adapterProperties = adapterProperties;
- m_propagate = propagate;
- }
-
- public BundleAdapterImpl(int bundleStateMask, String bundleFilter, Object adapterImplementation, String[] adapterInterfaces, Dictionary adapterProperties, boolean propagate) {
- m_bundleStateMask = bundleStateMask;
- m_resourceFilter = bundleFilter;
- m_adapterImplementation = adapterImplementation;
- m_adapterInterface = adapterInterfaces;
- m_adapterProperties = adapterProperties;
- m_propagate = propagate;
- }
-
- public Service createService(Object[] properties) {
- Bundle bundle = (Bundle) properties[0];
- Properties props = new Properties();
- if (m_adapterProperties != null) {
- Enumeration e = m_adapterProperties.keys();
- while (e.hasMoreElements()) {
- Object key = e.nextElement();
- props.put(key, m_adapterProperties.get(key));
- }
- }
- List dependencies = m_service.getDependencies();
- // the first dependency is always the dependency on the bundle, which
- // will be replaced with a more specific dependency below
- dependencies.remove(0);
- if (m_adapterInterface instanceof String) {
- return m_manager.createService()
- .setInterface((String) m_adapterInterface, props)
- .setImplementation(m_adapterImplementation)
- .add(dependencies)
- .add(m_manager.createBundleDependency()
- .setBundle(bundle)
- .setPropagate(m_propagate)
- .setCallbacks(null, "changed", null)
- .setAutoConfig(true)
- .setRequired(true)
- );
- }
- else {
- return m_manager.createService()
- .setInterface((String[]) m_adapterInterface, props)
- .setImplementation(m_adapterImplementation)
- .add(dependencies)
- .add(m_manager.createBundleDependency()
- .setBundle(bundle)
- .setPropagate(m_propagate)
- .setCallbacks(null, "changed", null)
- .setAutoConfig(true)
- .setRequired(true)
- );
- }
- }
-}
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java
new file mode 100644
index 0000000..1256c77
--- /dev/null
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/BundleAdapterServiceImpl.java
@@ -0,0 +1,93 @@
+/*
+ * 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.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.service.Service;
+import org.apache.felix.dm.service.ServiceStateListener;
+import org.osgi.framework.Bundle;
+
+/**
+ * Bundle Adapter Service implementation. This class extends the FilterService in order to catch
+ * some Service methods for configuring actual adapter service implementation.
+ */
+public class BundleAdapterServiceImpl extends FilterService
+{
+ /**
+ * Creates a new Bundle Adapter Service implementation.
+ */
+ public BundleAdapterServiceImpl(DependencyManager dm, int bundleStateMask, String bundleFilter, boolean propagate)
+ {
+ super(dm.createService()); // This service will be filtered by our super class, allowing us to take control.
+ m_service.setImplementation(new BundleAdapterImpl(bundleStateMask, bundleFilter, propagate))
+ .add(dm.createBundleDependency()
+ .setFilter(bundleFilter)
+ .setStateMask(bundleStateMask)
+ .setCallbacks("added", "removed"));
+ }
+
+ public class BundleAdapterImpl extends AbstractDecorator {
+ private final boolean m_propagate;
+ private final int m_bundleStateMask;
+ private final String m_bundleFilter;
+
+ public BundleAdapterImpl(int bundleStateMask, String bundleFilter, boolean propagate) {
+ m_bundleStateMask = bundleStateMask;
+ m_bundleFilter = bundleFilter;
+ m_propagate = propagate;
+ }
+
+ public Service createService(Object[] properties) {
+ Bundle bundle = (Bundle) properties[0];
+ Properties props = new Properties();
+ if (m_serviceProperties != null) {
+ Enumeration e = m_serviceProperties.keys();
+ while (e.hasMoreElements()) {
+ Object key = e.nextElement();
+ props.put(key, m_serviceProperties.get(key));
+ }
+ }
+ List dependencies = m_service.getDependencies();
+ // the first dependency is always the dependency on the bundle, which
+ // will be replaced with a more specific dependency below
+ dependencies.remove(0);
+ Service service = m_manager.createService()
+ .setInterface(m_serviceInterfaces, props)
+ .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(m_manager.createBundleDependency()
+ .setBundle(bundle)
+ .setPropagate(m_propagate)
+ .setCallbacks(null, "changed", null)
+ .setAutoConfig(true)
+ .setRequired(true));
+ for (int i = 0; i < m_stateListeners.size(); i ++) {
+ service.addStateListener((ServiceStateListener) m_stateListeners.get(i));
+ }
+ return service;
+ }
+ }
+}
diff --git a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
index f41f6d4..249c65b 100644
--- a/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
+++ b/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
@@ -47,7 +47,9 @@
String[] service = serviceMetaData.getStrings(Params.service, null);
Dictionary<String, Object> properties = serviceMetaData.getDictionary(Params.properties, null);
boolean propagate = "true".equals(serviceMetaData.getString(Params.propagate, "false"));
- Service srv = dm.createBundleAdapterService(stateMask, filter, adapterImpl, service, properties, propagate);
+ Service srv = dm.createBundleAdapterService(stateMask, filter, propagate)
+ .setInterface(service, properties)
+ .setImplementation(adapterImpl);
setCommonServiceParams(srv, serviceMetaData);
for (MetaData dependencyMetaData: serviceDependencies)
{