Aligned the aspect and adapter features. Added support for callback methods. Updated the documentation.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1079720 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 81a9835..817388d 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
@@ -189,19 +189,61 @@
* Creates a new aspect service.
*
* @return the aspect service
+ * @see DependencyManager#createAspectService(Class, String, int, String)
*/
public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String attributeName) {
return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, attributeName);
}
+
+ /**
+ * Creates a new aspect service.
+ *
+ * @return the aspect service
+ * @see DependencyManager#createAspectService(Class, String, int)
+ */
+ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) {
+ return m_manager.createAspectService(serviceInterface, serviceFilter, ranking);
+ }
+
+ /**
+ * Creates a new aspect service.
+ *
+ * @return the aspect service
+ * @see DependencyManager#createAspectService(Class, String, int, String, String, String)
+ */
+ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
+ return m_manager.createAspectService(serviceInterface, serviceFilter, ranking, add, change, remove);
+ }
/**
* Creates a new adapter service.
*
* @return the adapter service
+ * @see DependencyManager#createAdapterService(Class, String)
*/
public Component createAdapterService(Class serviceInterface, String serviceFilter) {
return m_manager.createAdapterService(serviceInterface, serviceFilter);
}
+
+ /**
+ * Creates a new adapter service.
+ *
+ * @return the adapter service
+ * @see DependencyManager#createAdapterService(Class, String, String)
+ */
+ public Component createAdapterService(Class serviceInterface, String serviceFilter, String autoConfig) {
+ return m_manager.createAdapterService(serviceInterface, serviceFilter, autoConfig);
+ }
+
+ /**
+ * Creates a new adapter service.
+ *
+ * @return the adapter service
+ * @see DependencyManager#createAdapterService(Class, String, String, String, String)
+ */
+ public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove) {
+ return m_manager.createAdapterService(serviceInterface, serviceFilter, add, change, remove);
+ }
/**
* Creates a new resource adapter service.
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 6522a9c..62910bc 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
@@ -167,20 +167,73 @@
* <h3>Usage Example</h3>
*
* <blockquote><pre>
- * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_aspect")
- * .setImplementation(ExistingServiceAspect.class)
- * .setServiceProperties(new Hashtable() {{ put("additional", "properties"); }});
+ * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "m_service")
+ * .setImplementation(ExistingServiceAspect.class)
+ * );
* </pre></blockquote>
*
* @param serviceInterface the service interface to apply the aspect to
* @param serviceFilter the filter condition to use with the service interface
* @param ranking the level used to organize the aspect chain ordering
- * @param attributeName the aspect implementation field name where to inject original service.
+ * @param autoConfig 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 Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String attributeName) {
- return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, attributeName);
+ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String autoConfig) {
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, autoConfig, null, null, null);
+ }
+ /**
+ * Creates a new aspect. The aspect will be applied to any service that
+ * matches the specified interface and filter. For each matching service
+ * an aspect will be created based on the aspect implementation class.
+ * The aspect will be registered with the same interface and properties
+ * as the original service, plus any extra properties you supply here.
+ * 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><pre>
+ * manager.createAspectService(ExistingService.class, "(foo=bar)", 10)
+ * .setImplementation(ExistingServiceAspect.class)
+ * );
+ * </pre></blockquote>
+ *
+ * @param serviceInterface the service interface to apply the aspect to
+ * @param serviceFilter the filter condition to use with the service interface
+ * @param ranking the level used to organize the aspect chain ordering
+ * @return a service that acts as a factory for generating aspects
+ */
+ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking) {
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, null, null, null);
+ }
+ /**
+ * Creates a new aspect. The aspect will be applied to any service that
+ * matches the specified interface and filter. For each matching service
+ * an aspect will be created based on the aspect implementation class.
+ * The aspect will be registered with the same interface and properties
+ * as the original service, plus any extra properties you supply here.
+ * 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><pre>
+ * manager.createAspectService(ExistingService.class, "(foo=bar)", 10, "add", "change", "remove")
+ * .setImplementation(ExistingServiceAspect.class)
+ * );
+ * </pre></blockquote>
+ *
+ * @param serviceInterface the service interface to apply the aspect to
+ * @param serviceFilter the filter condition to use with the service interface
+ * @param ranking the level used to organize the aspect chain ordering
+ * @param add name of the callback method to invoke on add
+ * @param change name of the callback method to invoke on change
+ * @param remove name of the callback method to invoke on remove
+ * @return a service that acts as a factory for generating aspects
+ */
+ public Component createAspectService(Class serviceInterface, String serviceFilter, int ranking, String add, String change, String remove) {
+ return new AspectServiceImpl(this, serviceInterface, serviceFilter, ranking, null, add, change, remove);
}
/**
@@ -195,18 +248,69 @@
* <h3>Usage Example</h3>
*
* <blockquote><pre>
- * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
- * // The interface to use when registering adapter
- * .setInterface(AdapterService.class, new Hashtable() {{ put("additional", "properties"); }})
- * // the implementation of the adapter
- * .setImplementation(AdapterImpl.class);
+ * manager.createAdapterService(AdapteeService.class, "(foo=bar)")
+ * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+ * .setImplementation(AdapterImpl.class);
* </pre></blockquote>
+ *
* @param serviceInterface the service interface to apply the adapter to
* @param serviceFilter the filter condition to use with the service interface
* @return a service that acts as a factory for generating adapters
*/
public Component createAdapterService(Class serviceInterface, String serviceFilter) {
- return new AdapterServiceImpl(this, serviceInterface, serviceFilter);
+ return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, null, null, null);
+ }
+ /**
+ * Creates a new adapter. The adapter will be applied to any service that
+ * matches the specified interface and filter. For each matching service
+ * an adapter will be created based on the adapter implementation class.
+ * The adapter will be registered with the specified interface and existing properties
+ * from the original service plus any extra properties you supply here.
+ * 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><pre>
+ * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "m_service")
+ * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+ * .setImplementation(AdapterImpl.class);
+ * </pre></blockquote>
+ *
+ * @param serviceInterface the service interface to apply the adapter to
+ * @param serviceFilter the filter condition to use with the service interface
+ * @param autoConfig the name of the member to inject the service into
+ * @return a service that acts as a factory for generating adapters
+ */
+ public Component createAdapterService(Class serviceInterface, String serviceFilter, String autoConfig) {
+ return new AdapterServiceImpl(this, serviceInterface, serviceFilter, autoConfig, null, null, null);
+ }
+ /**
+ * Creates a new adapter. The adapter will be applied to any service that
+ * matches the specified interface and filter. For each matching service
+ * an adapter will be created based on the adapter implementation class.
+ * The adapter will be registered with the specified interface and existing properties
+ * from the original service plus any extra properties you supply here.
+ * 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><pre>
+ * manager.createAdapterService(AdapteeService.class, "(foo=bar)", "add", "change", "remove")
+ * .setInterface(AdapterService.class, new Hashtable() {{ put("extra", "property"); }})
+ * .setImplementation(AdapterImpl.class);
+ * </pre></blockquote>
+ *
+ * @param serviceInterface the service interface to apply the adapter to
+ * @param serviceFilter the filter condition to use with the service interface
+ * @param add name of the callback method to invoke on add
+ * @param change name of the callback method to invoke on change
+ * @param remove name of the callback method to invoke on remove
+ * @return a service that acts as a factory for generating adapters
+ */
+ public Component createAdapterService(Class serviceInterface, String serviceFilter, String add, String change, String remove) {
+ return new AdapterServiceImpl(this, serviceInterface, serviceFilter, null, add, change, remove);
}
/**
diff --git a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
index a2c7fc9..4aebed3 100644
--- a/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
+++ b/dependencymanager/core/src/main/java/org/apache/felix/dm/impl/AdapterServiceImpl.java
@@ -25,6 +25,7 @@
import org.apache.felix.dm.ComponentStateListener;
import org.apache.felix.dm.Dependency;
import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
@@ -36,14 +37,18 @@
{
/**
* Creates a new Adapter Service implementation.
+ *
* @param dm the dependency manager used to create our internal adapter service
* @param adapteeInterface the service interface to apply the adapter to
* @param adapteeFilter the filter condition to use with the service interface
+ * @param add
+ * @param change
+ * @param remove
*/
- public AdapterServiceImpl(DependencyManager dm, Class adapteeInterface, String adapteeFilter)
+ public AdapterServiceImpl(DependencyManager dm, Class adapteeInterface, String adapteeFilter, String autoConfig, String add, String change, String remove)
{
super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
- m_service.setImplementation(new AdapterImpl(adapteeInterface, adapteeFilter))
+ m_service.setImplementation(new AdapterImpl(adapteeInterface, adapteeFilter, autoConfig, add, change, remove))
.add(dm.createServiceDependency()
.setService(adapteeInterface, adapteeFilter)
.setAutoConfig(false)
@@ -53,10 +58,18 @@
public class AdapterImpl extends AbstractDecorator {
private final Class m_adapteeInterface;
private final String m_adapteeFilter;
+ private final String m_add;
+ private final String m_change;
+ private final String m_remove;
+ private final String m_autoConfig;
- public AdapterImpl(Class adapteeInterface, String adapteeFilter) {
+ public AdapterImpl(Class adapteeInterface, String adapteeFilter, String autoConfig, String add, String change, String remove) {
m_adapteeInterface = adapteeInterface;
m_adapteeFilter = adapteeFilter;
+ m_autoConfig = autoConfig;
+ m_add = add;
+ m_change = change;
+ m_remove = remove;
}
public Component createService(Object[] properties) {
@@ -81,15 +94,23 @@
}
List dependencies = m_service.getDependencies();
dependencies.remove(0);
+ ServiceDependency dependency = m_manager.createServiceDependency()
+ .setService(m_adapteeInterface, ref)
+ .setRequired(true);
+ if (m_autoConfig != null) {
+ dependency.setAutoConfig(m_autoConfig);
+ }
+ if (m_add != null || m_change != null || m_remove != null) {
+ dependency.setCallbacks(m_add, m_change, m_remove);
+ }
+
Component service = m_manager.createComponent()
.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(m_manager.createServiceDependency()
- .setService(m_adapteeInterface, ref)
- .setRequired(true));
+ .add(dependency);
configureAutoConfigState(service, m_service);
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
index 8ba2c61..d1f2a92 100644
--- 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
@@ -23,11 +23,11 @@
import java.util.List;
import java.util.Properties;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ComponentStateListener;
import org.apache.felix.dm.Dependency;
import org.apache.felix.dm.DependencyManager;
-import org.apache.felix.dm.Component;
import org.apache.felix.dm.ServiceDependency;
-import org.apache.felix.dm.ComponentStateListener;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
@@ -36,10 +36,10 @@
* 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)
+ public AspectServiceImpl(DependencyManager dm, Class aspectInterface, String aspectFilter, int ranking, String autoConfig, String add, String change, String remove)
{
super(dm.createComponent()); // This service will be filtered by our super class, allowing us to take control.
- m_service.setImplementation(new AspectImpl(aspectInterface, aspectFilter, ranking, autoConfig))
+ m_service.setImplementation(new AspectImpl(aspectInterface, aspectFilter, ranking, autoConfig, add, change, remove))
.add(dm.createServiceDependency()
.setService(aspectInterface, createDependencyFilterForAspect(aspectFilter))
.setAutoConfig(false)
@@ -64,13 +64,19 @@
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
+ private final String m_autoConfig; // the aspect impl field name where to inject decorated service
+ private final String m_add;
+ private final String m_change;
+ private final String m_remove;
- public AspectImpl(Class aspectInterface, String aspectFilter, int ranking, String field) {
+ public AspectImpl(Class aspectInterface, String aspectFilter, int ranking, String autoConfig, String add, String change, String remove) {
m_aspectInterface = aspectInterface;
m_aspectFilter = aspectFilter;
m_ranking = ranking;
- m_field = field;
+ m_autoConfig = autoConfig;
+ m_add = add;
+ m_change = change;
+ m_remove = remove;
}
public Component createService(Object[] params) {
@@ -80,13 +86,21 @@
// replace it with one that points to the specific service that just was passed in
Properties serviceProperties = getServiceProperties(params);
String[] serviceInterfaces = getServiceInterfaces();
+ ServiceReference ref = (ServiceReference) params[0];
+ ServiceDependency dependency = m_manager.createServiceDependency().setService(m_aspectInterface, createAspectFilter(ref)).setRequired(true);
+ if (m_autoConfig != null) {
+ dependency.setAutoConfig(m_autoConfig);
+ }
+ if (m_add != null || m_change != null || m_remove != null) {
+ dependency.setCallbacks(m_add, m_change, m_remove);
+ }
Component service = m_manager.createComponent()
.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(getAspectDependency(params));
+ .add(dependency);
configureAutoConfigState(service, m_service);
@@ -142,15 +156,6 @@
return (String[]) serviceNames.toArray(new String[serviceNames.size()]);
}
- private Dependency getAspectDependency(Object[] params) {
- ServiceReference ref = (ServiceReference) params[0];
- ServiceDependency sd = m_manager.createServiceDependency().setService(m_aspectInterface, createAspectFilter(ref)).setRequired(true);
- if (m_field != null) {
- sd.setAutoConfig(m_field);
- }
- return sd;
- }
-
private String createAspectFilter(ServiceReference ref) {
Long sid = (Long) ref.getProperty(Constants.SERVICE_ID);
return "(&(|(!(" + Constants.SERVICE_RANKING + "=*))(" + Constants.SERVICE_RANKING + "<=" + (m_ranking - 1) + "))(|(" + Constants.SERVICE_ID + "=" + sid + ")(" + DependencyManager.ASPECT + "=" + sid + ")))";