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 2010/08/22 13:43:18 UTC
svn commit: r987871 - in /felix/trunk/dependencymanager:
annotation/src/main/java/org/apache/felix/dm/annotation/api/
annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/
runtime/src/main/java/org/apache/felix/dm/runtime/ test/src/main/j...
Author: pderop
Date: Sun Aug 22 11:43:17 2010
New Revision: 987871
URL: http://svn.apache.org/viewvc?rev=987871&view=rev
Log:
Replaced the publisher/unpublisher Service attributes by a new LifecycelControler annotation, which can apply to any kind of Services
(service, adapters, or aspect).
A Service can now take control of its component activation/deactivation like this:
@AspectService(ranking=10)
public class MyServiceImpl implements MyService {
@LifecycleController
Runnable m_componentActivator;
@LifecycleController(start=false)
Runnable m_componentDeactivator;
void activateMyComponentWheneverIWant() {
m_componentActivator.run();
}
void deactivateMyComponentWheneverIWant() {
m_componentDeactivator.run();
}
}
Added:
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ToggleServiceDependency.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/AdapterServiceTestWithPublisher.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/BundleAdapterServiceTestWithPublisher.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryConfigurationAdapterServiceTestWithPublisher.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/Utils.java
Removed:
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServicePublisher.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/Provider.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ServiceTestWthEarlyPublisher.java
Modified:
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java
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/EntryParam.java
felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java
felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryServiceTestWthPublisher.java
felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ServiceTestWthPublisher.java
felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/PublisherAnnotationTest.java
Modified: felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java (original)
+++ felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleAdapterService.java Sun Aug 22 11:43:17 2010
@@ -60,7 +60,7 @@ public @Retention(RetentionPolicy.CLASS)
int stateMask() default Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
/**
- * Specifies if properties from the bundle should be propagated to the service.
+ * Specifies if manifest headers from the bundle should be propagated to the service.
*/
boolean propagate() default true;
Modified: felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java (original)
+++ felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/BundleDependency.java Sun Aug 22 11:43:17 2010
@@ -58,7 +58,8 @@ public @interface BundleDependency
int stateMask() default Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
/**
- * @TODO
+ * Specifies if the manifest headers from the bundle should be propagated to
+ * the service properties.
*/
boolean propagate() default false;
}
Modified: felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java (original)
+++ felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/api/Service.java Sun Aug 22 11:43:17 2010
@@ -173,81 +173,5 @@ public @interface Service
/**
* Sets the static method used to create the Service implementation instance.
*/
- String factoryMethod() default "";
-
- /**
- * Injects a <code>Runnable</code> object to invoke for manually registering the Service into the OSGi registry.
- * By default, a Service is implicitly registered into the OSGi registry when the service's bundle is
- * started and when all required dependencies are satisfied. However, it is sometimes required to programatically
- * take control of when the service is registered. In this case, this attribute can be used and provides a
- * </code>Runnable</code> object that can be invoked in order to register a Service at any time.
- * <p>
- * <h3>Usage Examples</h3>
- * <blockquote>
- *
- * <pre>
- * /**
- * * This Service will be registered programatically into the OSGi registry, using the publisher attribute.
- * */
- * @Service(publisher="m_publisher")
- * class X implements Z {
- * Runnable m_publisher;
- *
- * @Start
- * void start() {
- * // Our Z Service is started but won't be registered into the OSGi registry once this method returns,
- * // because we are using the publisher attribute. The service will be registered only when we
- * // decide to invoke the Runnable injected by the publisher attribute.
- * }
- *
- * public void registerServiceWheneverIWant() {
- * m_publisher.run(); // register our service into the osgi registry.
- * }
- * }
- * </pre>
- * </blockquote>
- */
- String publisher() default "";
-
- /**
- * Injects a <code>Runnable</code> object for manually unregistering the Service from the OSGi registry.
- * By default, a Service is implicitly unregistered from the OSGi registry when the service's bundle is
- * stopped, or when the Service has lost one of its required dependencies. However, it is sometimes required to programatically
- * take control of when the service is unregistered. In this case, this attribute can be used and provides a
- * </code>Runnable</code> object that can be invoked in order to unregister a Service at any time.
- *
- * <p> Notice that this attribute is generally used with the {@link #publisher()} attribute.
- * <p>
- * <h3>Usage Examples</h3>
- * <blockquote>
- *
- * <pre>
- * /**
- * * This Service will be registered programatically into the OSGi registry, using the publisher attribute.
- * * It will also be unregistered unsing the Runnable injected by the unpublisher attribute.
- * */
- * @Service(publisher="m_publisher", unpublisher="m_unpublisher")
- * class X implements Z {
- * Runnable m_publisher;
- * Runnable m_unpublisher;
- *
- * @Start
- * void start() {
- * // Our Z Service is started but won't be registered into the OSGi registry once this method returns,
- * // because we are using the publisher attribute. The service will be registered only when we
- * // decide to invoke the Runnable injected by the publisher attribute.
- * }
- *
- * public void registerServiceWheneverIWant() {
- * m_publisher.run(); // register our service into the OSGi registry.
- * }
- *
- * public void unregisterServiceWheneverIWant() {
- * m_unpublisher.run(); // unregister our Z service from the OSGi registry.
- * }
- * }
- * </pre>
- * </blockquote>
- */
- String unpublisher() default "";
+ String factoryMethod() default "";
}
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=987871&r1=987870&r2=987871&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 Sun Aug 22 11:43:17 2010
@@ -36,6 +36,7 @@ import org.apache.felix.dm.annotation.ap
import org.apache.felix.dm.annotation.api.Destroy;
import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.LifecycleController;
import org.apache.felix.dm.annotation.api.ResourceAdapterService;
import org.apache.felix.dm.annotation.api.ResourceDependency;
import org.apache.felix.dm.annotation.api.Service;
@@ -60,27 +61,19 @@ public class AnnotationCollector extends
private final static String A_START = "L" + Start.class.getName().replace('.', '/') + ";";
private final static String A_STOP = "L" + Stop.class.getName().replace('.', '/') + ";";
private final static String A_DESTROY = "L" + Destroy.class.getName().replace('.', '/') + ";";
- private final static String A_COMPOSITION = "L" + Composition.class.getName().replace('.', '/')
- + ";";
+ private final static String A_COMPOSITION = "L" + Composition.class.getName().replace('.', '/') + ";";
+ private final static String A_LIFCLE_CTRL = "L" + LifecycleController.class.getName().replace('.', '/')+ ";";
+
private final static String A_SERVICE = "L" + Service.class.getName().replace('.', '/') + ";";
- private final static String A_SERVICE_DEP = "L"
- + ServiceDependency.class.getName().replace('.', '/') + ";";
- private final static String A_CONFIGURATION_DEPENDENCY = "L"
- + ConfigurationDependency.class.getName().replace('.', '/') + ";";
- private final static String A_BUNDLE_DEPENDENCY = "L"
- + BundleDependency.class.getName().replace('.', '/') + ";";
- private final static String A_RESOURCE_DEPENDENCY = "L"
- + ResourceDependency.class.getName().replace('.', '/') + ";";
- private final static String A_ASPECT_SERVICE = "L"
- + AspectService.class.getName().replace('.', '/') + ";";
- private final static String A_ADAPTER_SERVICE = "L"
- + AdapterService.class.getName().replace('.', '/') + ";";
- private final static String A_BUNDLE_ADAPTER_SERVICE = "L"
- + BundleAdapterService.class.getName().replace('.', '/') + ";";
- private final static String A_RESOURCE_ADAPTER_SERVICE = "L"
- + ResourceAdapterService.class.getName().replace('.', '/') + ";";
- private final static String A_FACTORYCONFIG_ADAPTER_SERVICE = "L"
- + FactoryConfigurationAdapterService.class.getName().replace('.', '/') + ";";
+ private final static String A_SERVICE_DEP = "L" + ServiceDependency.class.getName().replace('.', '/') + ";";
+ private final static String A_CONFIGURATION_DEPENDENCY = "L" + ConfigurationDependency.class.getName().replace('.', '/') + ";";
+ private final static String A_BUNDLE_DEPENDENCY = "L" + BundleDependency.class.getName().replace('.', '/') + ";";
+ private final static String A_RESOURCE_DEPENDENCY = "L" + ResourceDependency.class.getName().replace('.', '/') + ";";
+ private final static String A_ASPECT_SERVICE = "L"+ AspectService.class.getName().replace('.', '/') + ";";
+ private final static String A_ADAPTER_SERVICE = "L" + AdapterService.class.getName().replace('.', '/') + ";";
+ private final static String A_BUNDLE_ADAPTER_SERVICE = "L" + BundleAdapterService.class.getName().replace('.', '/') + ";";
+ private final static String A_RESOURCE_ADAPTER_SERVICE = "L" + ResourceAdapterService.class.getName().replace('.', '/') + ";";
+ private final static String A_FACTORYCONFIG_ADAPTER_SERVICE = "L" + FactoryConfigurationAdapterService.class.getName().replace('.', '/') + ";";
private Reporter m_reporter;
private String m_className;
@@ -98,6 +91,8 @@ public class AnnotationCollector extends
private String m_initMethod;
private String m_destroyMethod;
private String m_compositionMethod;
+ private String m_starter;
+ private String m_stopper;
/**
* This class represents a DependencyManager component descriptor entry.
@@ -226,6 +221,9 @@ public class AnnotationCollector extends
{
Patterns.parseMethod(m_method, m_descriptor, Patterns.COMPOSITION);
m_compositionMethod = m_method;
+ } else if (annotation.getName().equals(A_LIFCLE_CTRL))
+ {
+ parseLifecycleAnnotation(annotation);
}
else if (annotation.getName().equals(A_SERVICE_DEP))
{
@@ -274,10 +272,6 @@ public class AnnotationCollector extends
// factoryMethod attribute
writer.putString(annotation, EntryParam.factoryMethod, null);
-
- // Parse publisher/unpublisher attributes.
- writer.putString(annotation, EntryParam.publisher, null);
- writer.putString(annotation, EntryParam.unpublisher, null);
}
private void addCommonServiceParams(EntryWriter writer)
@@ -305,7 +299,22 @@ public class AnnotationCollector extends
if (m_compositionMethod != null)
{
writer.put(EntryParam.composition, m_compositionMethod);
- }
+ }
+
+ if (m_starter != null)
+ {
+ writer.put(EntryParam.starter, m_starter);
+ }
+
+ if (m_stopper != null)
+ {
+ writer.put(EntryParam.stopper, m_stopper);
+ if (m_starter == null)
+ {
+ throw new IllegalArgumentException("Can't use a @LifecycleController annotation for stopping a service without declaring a " +
+ "@LifecycleController that starts the component in class " + m_className);
+ }
+ }
}
/**
@@ -652,6 +661,25 @@ public class AnnotationCollector extends
writer.putString(annotation, EntryParam.factoryMethod, null);
}
+ private void parseLifecycleAnnotation(Annotation annotation)
+ {
+ Patterns.parseField(m_field, m_descriptor, Patterns.Runnable);
+ if ("true".equals(get(annotation,EntryParam.start.name(), "true")))
+ {
+ if (m_starter != null) {
+ throw new IllegalStateException("Lifecycle annotation already defined on field " +
+ m_starter + " in class " + m_className);
+ }
+ m_starter = m_field;
+ } else {
+ if (m_stopper != null) {
+ throw new IllegalStateException("Lifecycle annotation already defined on field " +
+ m_stopper + " in class " + m_className);
+ }
+ m_stopper = m_field;
+ }
+ }
+
/**
* Parse optional meta types annotation attributes
* @param annotation
@@ -809,11 +837,11 @@ public class AnnotationCollector extends
return false;
}
- // We must have at least a Service or an AspectService annotation.
+ // We must have at least a Service annotation.
checkServiceDeclared(EntryType.Service, EntryType.AspectService, EntryType.AdapterService,
EntryType.BundleAdapterService,
EntryType.ResourceAdapterService, EntryType.FactoryConfigurationAdapterService);
-
+
StringBuilder sb = new StringBuilder();
sb.append("Parsed annotation for class ");
sb.append(m_className);
Modified: felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java (original)
+++ felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/EntryParam.java Sun Aug 22 11:43:17 2010
@@ -34,7 +34,7 @@ public enum EntryParam
factoryConfigure,
factoryMethod,
field,
- name,
- publisher,
- unpublisher
+ name,
+ starter,
+ stopper,
}
Modified: felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java (original)
+++ felix/trunk/dependencymanager/annotation/src/main/java/org/apache/felix/dm/annotation/plugin/bnd/Patterns.java Sun Aug 22 11:43:17 2010
@@ -18,7 +18,7 @@ public class Patterns
public final static Pattern CLASS = Pattern.compile("L([^;]+);");
// Pattern used to parse the field on which a Publisher annotation may be applied on
- public final static Pattern PUBLISHER = Pattern.compile("Ljava/lang/Runnable;");
+ public final static Pattern Runnable = Pattern.compile("Ljava/lang/Runnable;");
/**
* Parses a class.
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/AdapterServiceBuilder.java Sun Aug 22 11:43:17 2010
@@ -48,8 +48,9 @@ public class AdapterServiceBuilder exten
Dictionary<String, Object> adapterProperties = srvMeta.getDictionary(Params.properties, null);
Class<?> adapteeService = b.loadClass(srvMeta.getString(Params.adapteeService));
String adapteeFilter = srvMeta.getString(Params.adapteeFilter, null);
- Service service = dm.createAdapterService(adapteeService, adapteeFilter)
- .setInterface(provides, adapterProperties);
+ Service service = dm.createAdapterService(adapteeService, adapteeFilter);
+ service.setInterface(provides, adapterProperties);
+
String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
if (factoryMethod == null)
{
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/BundleAdapterServiceBuilder.java Sun Aug 22 11:43:17 2010
@@ -45,8 +45,8 @@ public class BundleAdapterServiceBuilder
String[] provides = srvMeta.getStrings(Params.provides, null);
Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
- Service srv = dm.createBundleAdapterService(stateMask, filter, propagate)
- .setInterface(provides, properties);
+ Service srv = dm.createBundleAdapterService(stateMask, filter, propagate);
+ srv.setInterface(provides, properties);
String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
if (factoryMethod == null)
{
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactoryConfigurationAdapterServiceBuilder.java Sun Aug 22 11:43:17 2010
@@ -45,8 +45,8 @@ public class FactoryConfigurationAdapter
String[] provides = srvMeta.getStrings(Params.provides, null);
Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
- Service srv = dm.createFactoryConfigurationAdapterService(factoryPid, updated, propagate)
- .setInterface(provides, properties);
+ Service srv = dm.createFactoryConfigurationAdapterService(factoryPid, updated, propagate);
+ srv.setInterface(provides, properties);
String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
if (factoryMethod == null)
{
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/FactorySet.java Sun Aug 22 11:43:17 2010
@@ -367,28 +367,7 @@ public class FactorySet extends Abstract
{
// Merge service properties with the configuration provided by the factory.
Dictionary serviceProperties = mergeSettings(m_serviceProperties, configuration);
-
- // Set the exposed service, unless a Publisher field is present.
- // If present, the publisher field means that we have to inject
- // a Runnable that will be called back by the service for firing a service
- // registration.
-
- String publisherField = m_srvMeta.getString(Params.publisher, null);
- String unpublisherField = m_srvMeta.getString(Params.unpublisher, null);
- if (publisherField == null)
- {
- s.setInterface(m_provide, serviceProperties);
- } else
- {
- // Services will be manually provided by the service itself.
- ServicePublisher publisher = new ServicePublisher(publisherField,
- unpublisherField,
- s,
- m_bundle.getBundleContext(),
- m_provide,
- serviceProperties);
- publisher.register(m_dm);
- }
+ s.setInterface(m_provide, serviceProperties);
}
s.setComposition(m_srvMeta.getString(Params.composition, null));
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/Params.java Sun Aug 22 11:43:17 2010
@@ -54,6 +54,6 @@ public enum Params
factoryMethod,
name,
field,
- publisher,
- unpublisher
+ starter,
+ stopper
}
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ResourceAdapterServiceBuilder.java Sun Aug 22 11:43:17 2010
@@ -45,8 +45,8 @@ public class ResourceAdapterServiceBuild
Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
boolean propagate = "true".equals(srvMeta.getString(Params.propagate, "false"));
String changed = srvMeta.getString(Params.changed, null /* no change callback if not specified explicitly */);
- Service srv = dm.createResourceAdapterService(filter, propagate, null, changed)
- .setInterface(provides, properties);
+ Service srv = dm.createResourceAdapterService(filter, propagate, null, changed);
+ srv.setInterface(provides, properties);
String factoryMethod = srvMeta.getString(Params.factoryMethod, null);
if (factoryMethod == null)
{
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceBuilder.java Sun Aug 22 11:43:17 2010
@@ -74,23 +74,7 @@ public class ServiceBuilder extends Serv
// Set the provided services
Dictionary<String, Object> properties = srvMeta.getDictionary(Params.properties, null);
String[] services = srvMeta.getStrings(Params.provides, null);
- String publisherField = srvMeta.getString(Params.publisher, null);
- String unpublisherField = srvMeta.getString(Params.unpublisher, null);
- if (publisherField == null)
- {
- service.setInterface(services, properties);
- }
- else if (services != null)
- {
- // Services will be manually provided by the service itself.
- ServicePublisher publisher = new ServicePublisher(publisherField,
- unpublisherField,
- service,
- b.getBundleContext(),
- services,
- properties);
- publisher.register(dm);
- }
+ service.setInterface(services, properties);
}
else
{
Modified: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java (original)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ServiceLifecycleHandler.java Sun Aug 22 11:43:17 2010
@@ -18,7 +18,9 @@
*/
package org.apache.felix.dm.runtime;
+import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
@@ -26,11 +28,14 @@ import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.felix.dm.Dependency;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.Service;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
import org.osgi.service.log.LogService;
/**
@@ -93,6 +98,9 @@ public class ServiceLifecycleHandler
private List<MetaData> m_depsMeta;
private List<Dependency> m_namedDeps = new ArrayList<Dependency>();
private Bundle m_bundle;
+ private final AtomicBoolean m_started = new AtomicBoolean(false);
+ private ToggleServiceDependency m_toggle;
+ private final static Object SYNC = new Object();
/**
* Makes a new ServiceLifecycleHandler object. This objects allows to decorate the "init" service callback, in
@@ -119,7 +127,8 @@ public class ServiceLifecycleHandler
/**
* Handles an "init" lifecycle service callback. We just catch the "init" method, and callback
* the actual Service' init method, to see if a dependency customization map is returned.
- *
+ * We also check if a Lifecycle Controller is used. In this case, we add a hidden custom dependency,
+ * allowing to take control of when the component is actually started/stopped.
* @param service The Annotated Service
*/
@SuppressWarnings("unchecked")
@@ -127,15 +136,34 @@ public class ServiceLifecycleHandler
throws Exception
{
Object serviceInstance = service.getService();
- DependencyManager dm = service.getDependencyManager();
-
+ DependencyManager dm = service.getDependencyManager();
+
+ // Check if a lifecycle controller is defined for this service. If true, then
+ // We'll use the ToggleServiceDependency in order to manually activate/deactivate
+ // the component ...
+ String starter = m_srvMeta.getString(Params.starter, null);
+ String stopper = m_srvMeta.getString(Params.stopper, null);
+
+ if (starter != null)
+ {
+ Log.instance().log(LogService.LOG_DEBUG, "Setting up a lifecycle controller for service %s", serviceInstance);
+ String componentName = serviceInstance.getClass().getName();
+ m_toggle = new ToggleServiceDependency();
+ service.add(m_toggle);
+ setField(serviceInstance, starter, Runnable.class, new ComponentStarter(componentName));
+
+ if (stopper != null) {
+ setField(serviceInstance, stopper, Runnable.class, new ComponentStopper(componentName));
+ }
+ }
+
// 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).
-
+
Map<String, String> customization = new HashMap<String, String>();
Object[] composites = service.getCompositionInstances();
- for (Object composite : composites)
+ for (Object composite: composites)
{
Object o = invokeMethod(composite, m_init, dm, service);
if (o != null && Map.class.isAssignableFrom(o.getClass()))
@@ -143,18 +171,19 @@ public class ServiceLifecycleHandler
customization.putAll((Map) o);
}
}
-
+
Log.instance().log(LogService.LOG_DEBUG,
"ServiceLifecycleHandler.init: invoked init method from service %s " +
- ", returned map: %s", serviceInstance, customization);
-
- for (MetaData dependency : m_depsMeta)
+ ", returned map: %s", serviceInstance, customization);
+
+ for (MetaData dependency: m_depsMeta)
{
// Check if this dependency has a name, and if we find the name from the
// customization map, then apply filters and required flag from the map into it.
-
+
String name = dependency.getString(Params.name, null);
- if (name != null) {
+ if (name != null)
+ {
String filter = customization.get(name + ".filter");
String required = customization.get(name + ".required");
@@ -179,9 +208,9 @@ public class ServiceLifecycleHandler
m_namedDeps.add(d);
service.add(d);
}
- }
+ }
}
-
+
/**
* Handles the Service's start lifecycle callback. We just invoke the service "start" service callback on
* the service instance, as well as on all eventual service composites.
@@ -251,7 +280,7 @@ public class ServiceLifecycleHandler
/**
* Invoke a callback on all Service compositions.
*/
- private void callbackComposites(Service service, String callback)
+ private void callbackComposites(Service service, String callback)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
Object serviceInstance = service.getService();
@@ -268,25 +297,102 @@ public class ServiceLifecycleHandler
private Object invokeMethod(Object serviceInstance, String method, DependencyManager dm, Service service)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
- if (method != null) {
- try
+ if (method != null)
+ {
+ try
{
return InvocationUtil.invokeCallbackMethod(
- serviceInstance, method,
- new Class[][] { { Service.class }, {} },
- new Object[][] { { service }, {} }
+ serviceInstance, method,
+ new Class[][] { { Service.class }, {} },
+ new Object[][] { { service }, {} }
);
- }
-
- catch (NoSuchMethodException e)
+ }
+
+ catch (NoSuchMethodException e)
{
// ignore this
}
-
+
// Other exception will be thrown up to the ServiceImpl.invokeCallbackMethod(), which is
// currently invoking our method. So, no need to log something here, since the invokeCallbackMethod
// method is already logging any thrown exception.
}
return null;
}
+
+ /**
+ * Sets a field of an object by reflexion.
+ */
+ private void setField(Object instance, String fieldName, Class fieldClass, Object fieldValue)
+ {
+ Object serviceInstance = instance;
+ Class serviceClazz = serviceInstance.getClass();
+ if (Proxy.isProxyClass(serviceClazz))
+ {
+ serviceInstance = Proxy.getInvocationHandler(serviceInstance);
+ serviceClazz = serviceInstance.getClass();
+ }
+ while (serviceClazz != null)
+ {
+ Field[] fields = serviceClazz.getDeclaredFields();
+ for (int j = 0; j < fields.length; j++)
+ {
+ Field field = fields[j];
+ Class type = field.getType();
+ if (field.getName().equals(fieldName) && type.isAssignableFrom(fieldClass))
+ {
+ try
+ {
+ field.setAccessible(true);
+ // synchronized makes sure the field is actually written to immediately
+ synchronized (SYNC)
+ {
+ field.set(serviceInstance, fieldValue);
+ }
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Could not set field " + field, e);
+ }
+ }
+ }
+ serviceClazz = serviceClazz.getSuperclass();
+ }
+ }
+
+ private class ComponentStarter implements Runnable {
+ private String m_componentName;
+
+ public ComponentStarter(String name)
+ {
+ m_componentName = name;
+ }
+
+ public void run()
+ {
+ if (m_started.compareAndSet(false, true)) {
+ Log.instance().log(LogService.LOG_DEBUG, "Lifecycle controller is activating the component %s",
+ m_componentName);
+ m_toggle.setAvailable(true);
+ }
+ }
+ }
+
+ private class ComponentStopper implements Runnable {
+ private Object m_componentName;
+
+ public ComponentStopper(String componentName)
+ {
+ m_componentName = componentName;
+ }
+
+ public void run()
+ {
+ if (m_started.compareAndSet(true, false)) {
+ Log.instance().log(LogService.LOG_DEBUG, "Lifecycle controller is deactivating the component %s",
+ m_componentName);
+ m_toggle.setAvailable(false);
+ }
+ }
+ }
}
Added: felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ToggleServiceDependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ToggleServiceDependency.java?rev=987871&view=auto
==============================================================================
--- felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ToggleServiceDependency.java (added)
+++ felix/trunk/dependencymanager/runtime/src/main/java/org/apache/felix/dm/runtime/ToggleServiceDependency.java Sun Aug 22 11:43:17 2010
@@ -0,0 +1,150 @@
+/*
+ * 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.runtime;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivation;
+import org.apache.felix.dm.DependencyService;
+
+/**
+ * This is a custom DependencyManager Dependency, allowing to take control of when the dependency
+ * is available or not. It's used in the context of the LifecycleController class, in order to
+ * activate/deactivate a Component on demand.
+ */
+public class ToggleServiceDependency implements Dependency, DependencyActivation {
+ private final List m_services = new ArrayList();
+ private boolean m_isAvailable;
+ private boolean m_stopped;
+
+ public ToggleServiceDependency()
+ {
+ }
+
+ public ToggleServiceDependency(boolean mIsAvailable)
+ {
+ m_isAvailable = mIsAvailable;
+ }
+
+ public void setAvailable(boolean isAvailable) {
+ if (m_stopped) {
+ return;
+ }
+ boolean changed = m_isAvailable != isAvailable;
+ m_isAvailable = isAvailable;
+ // invoked on every change
+ if (m_isAvailable) {
+ Object[] services = m_services.toArray();
+ for (int i = 0; i < services.length; i++) {
+ DependencyService ds = (DependencyService) services[i];
+ ds.dependencyAvailable(this);
+ if (!isRequired()) {
+ invokeAdded(ds);
+ }
+ }
+ }
+ else {
+ Object[] services = m_services.toArray();
+ for (int i = 0; i < services.length; i++) {
+ DependencyService ds = (DependencyService) services[i];
+ ds.dependencyUnavailable(this);
+ if (!isRequired()) {
+ invokeRemoved(ds);
+ }
+ }
+ }
+ }
+
+ public Dependency createCopy() {
+ return new ToggleServiceDependency(m_isAvailable);
+ }
+
+ public Object getAutoConfigInstance() {
+ return "" + m_isAvailable;
+ }
+
+ public String getAutoConfigName() {
+ return null;
+ }
+
+ public Class getAutoConfigType() {
+ return String.class;
+ }
+
+ public Dictionary getProperties() {
+ return null;
+ }
+
+ public void invokeAdded(DependencyService service) {
+ invoke(service, "added");
+ }
+
+ public void invokeRemoved(DependencyService service) {
+ invoke(service, "removed");
+ }
+
+ public void invoke(DependencyService dependencyService, String name) {
+ if (name != null) {
+ dependencyService.invokeCallbackMethod(getCallbackInstances(dependencyService), name,
+ new Class[][] {{String.class}, {Object.class}, {}},
+ new Object[][] {{getAutoConfigInstance()}, {getAutoConfigInstance()}, {}}
+ );
+ }
+ }
+
+ private synchronized Object[] getCallbackInstances(DependencyService dependencyService) {
+ return dependencyService.getCompositionInstances();
+ }
+
+ public boolean isAutoConfig() {
+ return true;
+ }
+
+ public boolean isAvailable() {
+ return m_isAvailable;
+ }
+
+ public boolean isInstanceBound() {
+ return true;
+ }
+
+ public boolean isPropagated() {
+ return false;
+ }
+
+ public boolean isRequired() {
+ return true;
+ }
+
+ public void start(DependencyService service) {
+ synchronized (this) {
+ m_services.add(service);
+ }
+ }
+
+ public void stop(DependencyService service) {
+ synchronized (this) {
+ m_services.remove(service);
+ }
+ m_stopped = true;
+ }
+}
Added: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/AdapterServiceTestWithPublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/AdapterServiceTestWithPublisher.java?rev=987871&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/AdapterServiceTestWithPublisher.java (added)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/AdapterServiceTestWithPublisher.java Sun Aug 22 11:43:17 2010
@@ -0,0 +1,126 @@
+/*
+ * 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.publisher;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.dm.annotation.api.AdapterService;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.LifecycleController;
+import org.apache.felix.dm.annotation.api.Service;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+
+/**
+ * Test an AdapterService which provides its interface using a @ServiceLifecycle.
+ */
+public class AdapterServiceTestWithPublisher
+{
+ public interface Provider
+ {
+ }
+
+ public interface Provider2
+ {
+ }
+
+ @Service
+ public static class Consumer
+ {
+ @ServiceDependency(filter="(test=AdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ @ServiceDependency(required=false, removed = "unbind")
+ void bind(Map properties, Provider2 provider)
+ {
+ m_sequencer.step(1);
+ // check ProviderImpl properties
+ if ("bar".equals(properties.get("foo")))
+ {
+ m_sequencer.step(2);
+ }
+ // check extra ProviderImpl properties (returned by start method)
+ if ("bar2".equals(properties.get("foo2")))
+ {
+ m_sequencer.step(3);
+ }
+ // check Provider2Impl properties
+ if ("bar3".equals(properties.get("foo3")))
+ {
+ m_sequencer.step(4);
+ }
+ // check extra Provider2Impl properties (returned by start method)
+ if ("bar4".equals(properties.get("foo4")))
+ {
+ m_sequencer.step(5);
+ }
+
+ }
+
+ void unbind(Provider2 provider)
+ {
+ m_sequencer.step(6);
+ }
+ }
+
+ @Service(properties={@Property(name="foo", value="bar")})
+ public static class ProviderImpl implements Provider
+ {
+ @Start
+ Map start()
+ {
+ // Add some extra service properties ... they will be appended to the one we have defined
+ // in the @Service annotation.
+ return new HashMap() {{ put("foo2", "bar2"); }};
+ }
+ }
+
+ @AdapterService(properties={@Property(name="foo3", value="bar3")}, adapteeService=Provider.class)
+ public static class Provider2Impl implements Provider2
+ {
+ @LifecycleController
+ Runnable m_publisher; // injected and used to register our service
+
+ @LifecycleController(start=false)
+ Runnable m_unpublisher; // injected and used to unregister our service
+
+ @ServiceDependency(filter="(test=AdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ @Init
+ void init()
+ {
+ // register service in 1 second
+ Utils.schedule(m_publisher, 1000);
+ // unregister the service in 2 seconds
+ Utils.schedule(m_unpublisher, 2000);
+ }
+
+ @Start
+ Map start()
+ {
+ // Add some extra service properties ... they will be appended to the one we have defined
+ // in the @Service annotation.
+ return new HashMap() {{ put("foo4", "bar4"); }};
+ }
+ }
+}
Added: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/BundleAdapterServiceTestWithPublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/BundleAdapterServiceTestWithPublisher.java?rev=987871&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/BundleAdapterServiceTestWithPublisher.java (added)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/BundleAdapterServiceTestWithPublisher.java Sun Aug 22 11:43:17 2010
@@ -0,0 +1,111 @@
+/*
+ * 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.publisher;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.dm.annotation.api.BundleAdapterService;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.LifecycleController;
+import org.apache.felix.dm.annotation.api.Service;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.Bundle;
+
+/**
+ * Test a BundleAdapterService which provides its interface using a @ServiceLifecycle.
+ */
+public class BundleAdapterServiceTestWithPublisher
+{
+ public interface Provider
+ {
+ }
+
+ @Service
+ public static class Consumer
+ {
+ @ServiceDependency(filter="(test=BundleAdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ @ServiceDependency(required=false, removed = "unbind")
+ void bind(Map properties, Provider provider)
+ {
+ m_sequencer.step(1);
+ // check ProviderImpl properties
+ if ("bar".equals(properties.get("foo")))
+ {
+ m_sequencer.step(2);
+ }
+ // check extra ProviderImpl properties (returned by start method)
+ if ("bar2".equals(properties.get("foo2")))
+ {
+ m_sequencer.step(3);
+ }
+ // check properties propagated from bundle
+ if ("org.apache.felix.dependencymanager".equals(properties.get("Bundle-SymbolicName")))
+ {
+ m_sequencer.step(4);
+ } else {
+ Thread.dumpStack();
+ System.out.println(properties);
+ }
+ }
+
+ void unbind(Provider provider)
+ {
+ m_sequencer.step(5);
+ }
+ }
+
+ @BundleAdapterService(properties={@Property(name="foo", value="bar")},
+ filter = "(Bundle-SymbolicName=org.apache.felix.dependencymanager)",
+ stateMask = Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE,
+ propagate = true)
+ public static class ProviderImpl implements Provider
+ {
+ @LifecycleController
+ Runnable m_publisher; // injected and used to register our service
+
+ @LifecycleController(start=false)
+ Runnable m_unpublisher; // injected and used to unregister our service
+
+ @ServiceDependency(filter="(test=BundleAdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ @Init
+ void init()
+ {
+ // register service in 1 second
+ Utils.schedule(m_publisher, 1000);
+ // unregister the service in 2 seconds
+ Utils.schedule(m_unpublisher, 2000);
+ }
+
+ @Start
+ Map start()
+ {
+ // Add some extra service properties ... they will be appended to the one we have defined
+ // in the @Service annotation.
+ return new HashMap() {{ put("foo2", "bar2"); }};
+ }
+ }
+}
Added: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryConfigurationAdapterServiceTestWithPublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryConfigurationAdapterServiceTestWithPublisher.java?rev=987871&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryConfigurationAdapterServiceTestWithPublisher.java (added)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryConfigurationAdapterServiceTestWithPublisher.java Sun Aug 22 11:43:17 2010
@@ -0,0 +1,124 @@
+/*
+ * 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.publisher;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.felix.dm.annotation.api.FactoryConfigurationAdapterService;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.LifecycleController;
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.Service;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Test a FactoryConfigurationAdapterService which provides its interface using a @ServiceLifecycle.
+ */
+public class FactoryConfigurationAdapterServiceTestWithPublisher
+{
+ public interface Provider
+ {
+ }
+
+ @Service
+ public static class Consumer
+ {
+ @ServiceDependency(filter="(test=FactoryConfigurationAdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ @ServiceDependency(required=false, removed = "unbind")
+ void bind(Map properties, Provider provider)
+ {
+ m_sequencer.step(1);
+ // check ProviderImpl properties
+ if ("bar".equals(properties.get("foo")))
+ {
+ m_sequencer.step(2);
+ }
+ // check extra ProviderImpl properties (returned by start method)
+ if ("bar2".equals(properties.get("foo2")))
+ {
+ m_sequencer.step(3);
+ }
+ // check Factory Configuration properties
+ if ("bar3".equals(properties.get("foo3")))
+ {
+ m_sequencer.step(4);
+ }
+ }
+
+ void unbind(Provider provider)
+ {
+ m_sequencer.step(5);
+ }
+ }
+
+ @Service
+ public static class Configurator
+ {
+ @ServiceDependency
+ void bind(ConfigurationAdmin cm) throws IOException
+ {
+ Configuration cf = cm.createFactoryConfiguration("MyPid", null);
+ cf.update(new Hashtable() {{ put("foo3", "bar3"); }});
+ }
+ }
+
+ @FactoryConfigurationAdapterService(propagate=true, properties={@Property(name="foo", value="bar")}, factoryPid="MyPid", updated="updated")
+ public static class ProviderImpl implements Provider
+ {
+ @LifecycleController
+ Runnable m_publisher; // injected and used to register our service
+
+ @LifecycleController(start=false)
+ Runnable m_unpublisher; // injected and used to unregister our service
+
+ @ServiceDependency(filter="(test=FactoryConfigurationAdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ void updated(Dictionary conf) {
+ }
+
+ @Init
+ void init()
+ {
+ // register service in 1 second
+ Utils.schedule(m_publisher, 1000);
+ // unregister the service in 2 seconds
+ Utils.schedule(m_unpublisher, 2000);
+ }
+
+ @Start
+ Map start()
+ {
+ // Add some extra service properties ... they will be appended to the one we have defined
+ // in the @Service annotation.
+ return new HashMap() {{ put("foo2", "bar2"); }};
+ }
+
+ }
+}
Modified: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryServiceTestWthPublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryServiceTestWthPublisher.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryServiceTestWthPublisher.java (original)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/FactoryServiceTestWthPublisher.java Sun Aug 22 11:43:17 2010
@@ -24,22 +24,28 @@ import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
+import org.apache.felix.dm.annotation.api.Init;
import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.LifecycleController;
import org.apache.felix.dm.annotation.api.Service;
import org.apache.felix.dm.annotation.api.ServiceDependency;
import org.apache.felix.dm.annotation.api.Start;
import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
/**
- * This test validates that a basic "ProviderImpl" which is instantiated from a FactorySet can register/unregister its
- * service using the Publisher annotation.
+ * A Service instantiated from a FactorySet, and which registers/unregisters its service,
+ * using the @ServiceLifecycle annotation.
*/
public class FactoryServiceTestWthPublisher
{
+ public interface Provider
+ {
+ }
+
@Service
public static class Consumer
{
- @ServiceDependency(filter="(test=testFactoryService)")
+ @ServiceDependency(filter="(test=FactoryServiceTestWthPublisher)")
Sequencer m_sequencer;
@ServiceDependency(required=false, removed = "unbind")
@@ -66,46 +72,34 @@ public class FactoryServiceTestWthPublis
}
}
- @Service(publisher="m_publisher", unpublisher="m_unpublisher", factorySet="MyFactory", properties={@Property(name="foo", value="bar")})
+ @Service(factorySet="MyFactory", properties={@Property(name="foo", value="bar")})
public static class ProviderImpl implements Provider
{
+ @LifecycleController
Runnable m_publisher; // injected and used to register our service
+
+ @LifecycleController(start=false)
Runnable m_unpublisher; // injected and used to unregister our service
- @ServiceDependency(filter="(test=testFactoryService)")
+ @ServiceDependency(filter="(test=FactoryServiceTestWthPublisher)")
Sequencer m_sequencer;
- @Start
- Map start()
+ @Init
+ void init()
{
// register service in 1 second
- schedule(m_publisher, 1000);
+ Utils.schedule(m_publisher, 1000);
// unregister the service in 2 seconds
- schedule(m_unpublisher, 2000);
+ Utils.schedule(m_unpublisher, 2000);
+ }
+
+ @Start
+ Map start()
+ {
// At this point, our service properties are the one specified in our @Service annotation + the one specified by our Factory.
// We also append an extra service property here:
return new HashMap() {{ put("foo3", "bar3"); }};
}
-
- private void schedule(final Runnable task, final long n)
- {
- Thread t = new Thread() {
- public void run()
- {
- try
- {
- sleep(n);
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- task.run();
- }
- };
- t.start();
- }
}
@Service
Added: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java?rev=987871&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java (added)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ResourceAdapterServiceTestWithPublisher.java Sun Aug 22 11:43:17 2010
@@ -0,0 +1,216 @@
+/*
+ * 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.publisher;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.ResourceHandler;
+import org.apache.felix.dm.ResourceUtil;
+import org.apache.felix.dm.annotation.api.Destroy;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.LifecycleController;
+import org.apache.felix.dm.annotation.api.Property;
+import org.apache.felix.dm.annotation.api.ResourceAdapterService;
+import org.apache.felix.dm.annotation.api.Service;
+import org.apache.felix.dm.annotation.api.ServiceDependency;
+import org.apache.felix.dm.annotation.api.Start;
+import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Test a ResourceAdapterService which provides its interface using a @ServiceLifecycle.
+ */
+public class ResourceAdapterServiceTestWithPublisher
+{
+ public interface Provider
+ {
+ }
+
+ @Service
+ public static class Consumer
+ {
+ @ServiceDependency(filter="(test=ResourceAdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ @ServiceDependency(required=false, removed = "unbind")
+ void bind(Map properties, Provider provider)
+ {
+ m_sequencer.step(1);
+ // check ProviderImpl properties
+ if ("bar".equals(properties.get("foo")))
+ {
+ m_sequencer.step(2);
+ }
+ // check extra ProviderImpl properties (returned by start method)
+ if ("bar2".equals(properties.get("foo2")))
+ {
+ m_sequencer.step(3);
+ }
+ // check properties propagated by the resource adapter
+ if ("/path/to/test1.txt".equals(properties.get(ResourceHandler.PATH)))
+ {
+ m_sequencer.step(4);
+ }
+ if ("localhost".equals(properties.get(ResourceHandler.HOST)))
+ {
+ m_sequencer.step(5);
+ }
+ }
+
+ void unbind(Provider provider)
+ {
+ m_sequencer.step(6);
+ }
+ }
+
+ @Service
+ public static class ResourceProvider
+ {
+ private volatile BundleContext m_context;
+ private final Map m_handlers = new HashMap();
+ private URL[] m_resources;
+
+ public ResourceProvider() throws Exception {
+ m_resources = new URL[] {
+ new URL("file://localhost/path/to/test1.txt"),
+ new URL("file://localhost/path/to/test2.txt"),
+ new URL("file://localhost/path/to/README.doc")
+ };
+ }
+
+ /**
+ * Handles a new Resource consumer
+ * @param serviceProperties
+ * @param handler
+ */
+ @ServiceDependency(removed = "remove", required=false)
+ public void add(Map serviceProperties, ResourceHandler handler)
+ {
+ String filterString = (String) serviceProperties.get("filter");
+ Filter filter = null;
+ if (filterString != null) {
+ try
+ {
+ filter = m_context.createFilter(filterString);
+ }
+ catch (InvalidSyntaxException e)
+ {
+ Assert.fail("Could not create filter for resource handler: " + e);
+ return;
+ }
+ }
+ synchronized (m_handlers)
+ {
+ m_handlers.put(handler, filter);
+ }
+ for (int i = 0; i < m_resources.length; i++)
+ {
+ if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[i])))
+ {
+ handler.added(m_resources[i]);
+ }
+ }
+ }
+
+ /**
+ * Remove a Resource consumer.bar
+ * @param handler
+ */
+ public void remove(ResourceHandler handler)
+ {
+ Filter filter;
+ synchronized (m_handlers)
+ {
+ filter = (Filter) m_handlers.remove(handler);
+ }
+ removeResources(handler, filter);
+ }
+
+ private void removeResources(ResourceHandler handler, Filter filter)
+ {
+ for (int i = 0; i < m_resources.length; i++)
+ {
+ if (filter == null || filter.match(ResourceUtil.createProperties(m_resources[i])))
+ {
+ handler.removed(m_resources[i]);
+ }
+ }
+ }
+
+ /**
+ * Our component is being destroyed: notify all our registered Resource consumers that we don't
+ * provide our Resources anymore.
+ */
+ @Destroy
+ public void destroy()
+ {
+ Entry[] handlers;
+ synchronized (m_handlers)
+ {
+ handlers = (Entry[]) m_handlers.entrySet().toArray(new Entry[m_handlers.size()]);
+ }
+ for (int i = 0; i < handlers.length; i++)
+ {
+ removeResources((ResourceHandler) handlers[i].getKey(), (Filter) handlers[i].getValue());
+ }
+ }
+ }
+
+ @ResourceAdapterService(filter = "(&(path=/path/to/test1.txt)(host=localhost))",
+ properties = {@Property(name="foo", value="bar")},
+ propagate = true)
+ public static class ProviderImpl implements Provider
+ {
+ @LifecycleController
+ Runnable m_publisher; // injected and used to register our service
+
+ @LifecycleController(start=false)
+ Runnable m_unpublisher; // injected and used to unregister our service
+
+ @ServiceDependency(filter="(test=ResourceAdapterServiceTestWithPublisher)")
+ Sequencer m_sequencer;
+
+ // Injected by reflection
+ URL m_resource;
+
+ @Init
+ void init()
+ {
+ // register service in 1 second
+ Utils.schedule(m_publisher, 1000);
+ // unregister the service in 2 seconds
+ Utils.schedule(m_unpublisher, 2000);
+ }
+
+ @Start
+ Map start()
+ {
+ // Add some extra service properties ... they will be appended to the one we have defined
+ // in the @Service annotation.
+ return new HashMap() {{ put("foo2", "bar2"); }};
+ }
+ }
+}
Modified: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ServiceTestWthPublisher.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ServiceTestWthPublisher.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ServiceTestWthPublisher.java (original)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/ServiceTestWthPublisher.java Sun Aug 22 11:43:17 2010
@@ -21,7 +21,8 @@ package org.apache.felix.dm.test.bundle.
import java.util.HashMap;
import java.util.Map;
-import org.apache.felix.dm.annotation.api.Destroy;
+import org.apache.felix.dm.annotation.api.Init;
+import org.apache.felix.dm.annotation.api.LifecycleController;
import org.apache.felix.dm.annotation.api.Property;
import org.apache.felix.dm.annotation.api.Service;
import org.apache.felix.dm.annotation.api.ServiceDependency;
@@ -29,15 +30,18 @@ import org.apache.felix.dm.annotation.ap
import org.apache.felix.dm.test.bundle.annotation.sequencer.Sequencer;
/**
- * This test validates that a basic "ProviderImpl" services can register/unregister its
- * service using the Publisher annotation.
+ * A Service that just registers/unregisters its service, using the @ServiceLifecycle annotation.
*/
public class ServiceTestWthPublisher
{
+ public interface Provider
+ {
+ }
+
@Service
public static class Consumer
{
- @ServiceDependency(filter="(test=testService)")
+ @ServiceDependency(filter="(test=ServiceTestWthPublisher)")
Sequencer m_sequencer;
@ServiceDependency(required=false, removed = "unbind")
@@ -60,46 +64,33 @@ public class ServiceTestWthPublisher
}
}
- @Service(publisher="m_publisher", unpublisher="m_unpublisher", properties={@Property(name="foo", value="bar")})
+ @Service(properties={@Property(name="foo", value="bar")})
public static class ProviderImpl implements Provider
{
+ @LifecycleController
Runnable m_publisher; // injected and used to register our service
+
+ @LifecycleController(start=false)
Runnable m_unpublisher; // injected and used to unregister our service
- @ServiceDependency(filter="(test=testService)")
+ @ServiceDependency(filter="(test=ServiceTestWthPublisher)")
Sequencer m_sequencer;
- @Start
- Map start()
+ @Init
+ void init()
{
// register service in 1 second
- schedule(m_publisher, 1000);
+ Utils.schedule(m_publisher, 1000);
// unregister the service in 2 seconds
- schedule(m_unpublisher, 2000);
-
+ Utils.schedule(m_unpublisher, 2000);
+ }
+
+ @Start
+ Map start()
+ {
// Add some extra service properties ... they will be appended to the one we have defined
// in the @Service annotation.
return new HashMap() {{ put("foo2", "bar2"); }};
}
-
- private void schedule(final Runnable task, final long n)
- {
- Thread t = new Thread() {
- public void run()
- {
- try
- {
- sleep(n);
- }
- catch (InterruptedException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- task.run();
- }
- };
- t.start();
- }
}
}
Added: felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/Utils.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/Utils.java?rev=987871&view=auto
==============================================================================
--- felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/Utils.java (added)
+++ felix/trunk/dependencymanager/test/src/main/java/org/apache/felix/dm/test/bundle/annotation/publisher/Utils.java Sun Aug 22 11:43:17 2010
@@ -0,0 +1,42 @@
+/*
+ * 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.publisher;
+
+public class Utils
+{
+ public static void schedule(final Runnable task, final long n)
+ {
+ Thread t = new Thread() {
+ public void run()
+ {
+ try
+ {
+ sleep(n);
+ }
+ catch (InterruptedException e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ task.run();
+ }
+ };
+ t.start();
+ }
+}
Modified: felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/PublisherAnnotationTest.java
URL: http://svn.apache.org/viewvc/felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/PublisherAnnotationTest.java?rev=987871&r1=987870&r2=987871&view=diff
==============================================================================
--- felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/PublisherAnnotationTest.java (original)
+++ felix/trunk/dependencymanager/test/src/test/java/org/apache/felix/dm/test/annotation/PublisherAnnotationTest.java Sun Aug 22 11:43:17 2010
@@ -37,8 +37,7 @@ import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
/**
- * Use case: Verify the Publisher annotation, which allows a component to register/unregister
- * its service programatically.
+ * Use case: Verify the @ServiceLifecycle annotation, which allows a component to activate/deactivate itself programatically.
*/
@RunWith(JUnit4TestRunner.class)
public class PublisherAnnotationTest extends AnnotationBase
@@ -51,6 +50,7 @@ public class PublisherAnnotationTest ext
provision(
mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium").version("4.1.0"),
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager").versionAsInProject(),
+ mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.configadmin").version("1.2.4"),
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.dependencymanager.runtime").versionAsInProject()),
provision(
new BundleGenerator()
@@ -63,43 +63,81 @@ public class PublisherAnnotationTest ext
}
/**
- * A Provider that just registers/unregisters its service, using the Publisher annotation.
+ * Registers the Sequencer interface, for activating a given testcase
+ */
+ private void registerSequencer(DependencyManager m, final String testName)
+ {
+ m.add(m.createService()
+ .setImplementation(this)
+ .setInterface(Sequencer.class.getName(),new Hashtable() {{
+ put("test", testName);
+ }}));
+ }
+
+ /**
+ * A Service that just registers/unregisters its service, using the @ServiceLifecycle annotation.
*/
@Test
public void testServiceWithPublisher(BundleContext context)
{
DependencyManager m = new DependencyManager(context);
- // Provide the Sequencer service to the "Component" service.
- m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(),
- new Hashtable() {{ put("test", "testService"); }}));
+ registerSequencer(m, "ServiceTestWthPublisher");
m_ensure.waitForStep(4, 10000);
}
/**
- * A Provider instantiated from a FactorySet, and which registers/unregisters its service, using the Publisher annotation.
+ * A Service instantiated from a FactorySet, and which registers/unregisters its service,
+ * using the @ServiceLifecycle annotation.
*/
@Test
public void testFactoryServiceWithPublisher(BundleContext context)
{
DependencyManager m = new DependencyManager(context);
- // Provide the Sequencer service to the "Component" service.
- m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(),
- new Hashtable() {{ put("test", "testFactoryService"); }}));
+ registerSequencer(m, "FactoryServiceTestWthPublisher");
m_ensure.waitForStep(5, 10000);
}
-
+
+ /**
+ * Test an AdapterService which provides its interface using a @ServiceLifecycle.
+ */
+ @Test
+ public void testAdapterServiceWithPublisher(BundleContext context)
+ {
+ DependencyManager m = new DependencyManager(context);
+ registerSequencer(m, "AdapterServiceTestWithPublisher");
+ m_ensure.waitForStep(6, 10000);
+ }
+
+ /**
+ * Test a BundleAdapterService which provides its interface using a @ServiceLifecycle.
+ */
+ @Test
+ public void testBundleAdapterServiceWithPublisher(BundleContext context)
+ {
+ DependencyManager m = new DependencyManager(context);
+ registerSequencer(m, "BundleAdapterServiceTestWithPublisher");
+ m_ensure.waitForStep(5, 10000);
+ }
+
+ /**
+ * Test a ResourceAdapterService which provides its interface using a @ServiceLifecycle.
+ */
+ @Test
+ public void TestResourceAdapterServiceWithPublisher(BundleContext context)
+ {
+ DependencyManager m = new DependencyManager(context);
+ registerSequencer(m, "ResourceAdapterServiceTestWithPublisher");
+ m_ensure.waitForStep(5, 10000);
+ }
+
/**
- * A Provider that registers its service, using the Publisher annotation, but very early: before
- * the start callback is invoked ! In this case, we must verify that the runtime will delay the
- * service registration until the service is fully started.
+ * Test a FactoryConfigurationAdapterService which provides its interface using a @ServiceLifecycle.
*/
@Test
- public void testServiceWithEarlyPublisher(BundleContext context)
+ public void testFactoryAdapterServiceWithPublisher(BundleContext context)
{
DependencyManager m = new DependencyManager(context);
- // Provide the Sequencer service to the "Component" service.
- m.add(m.createService().setImplementation(this).setInterface(Sequencer.class.getName(),
- new Hashtable() {{ put("test", "testEarlyService"); }}));
+ registerSequencer(m, "FactoryConfigurationAdapterServiceTestWithPublisher");
m_ensure.waitForStep(5, 10000);
}
}