You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by gn...@apache.org on 2018/01/19 09:44:58 UTC
svn commit: r1821610 - in /aries/trunk/blueprint: blueprint-bundle/
blueprint-core/
blueprint-core/src/main/java/org/apache/aries/blueprint/container/
blueprint-core/src/main/java/org/apache/aries/blueprint/di/
blueprint-core/src/main/java/org/apache/a...
Author: gnodet
Date: Fri Jan 19 09:44:57 2018
New Revision: 1821610
URL: http://svn.apache.org/viewvc?rev=1821610&view=rev
Log:
[ARIES-1535][ARIES-1536] Implement new policies for reference lifecycle and damping
Added:
aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/DampingPolicyTest.java
aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/LifecyclePolicyTest.java
Modified:
aries/trunk/blueprint/blueprint-bundle/pom.xml
aries/trunk/blueprint/blueprint-core/pom.xml
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintRepository.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/SatisfiableRecipe.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/DependentComponentFactoryRecipe.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java
aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java
aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml
aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java
aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java
aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java
aries/trunk/blueprint/itests/blueprint-itests/pom.xml
Modified: aries/trunk/blueprint/blueprint-bundle/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-bundle/pom.xml?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-bundle/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-bundle/pom.xml Fri Jan 19 09:44:57 2018
@@ -122,7 +122,7 @@
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.core</artifactId>
- <version>1.8.3-SNAPSHOT</version>
+ <version>1.9.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: aries/trunk/blueprint/blueprint-core/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/pom.xml?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/pom.xml (original)
+++ aries/trunk/blueprint/blueprint-core/pom.xml Fri Jan 19 09:44:57 2018
@@ -32,7 +32,7 @@
<artifactId>org.apache.aries.blueprint.core</artifactId>
<packaging>bundle</packaging>
<name>Apache Aries Blueprint Core</name>
- <version>1.8.4-SNAPSHOT</version>
+ <version>1.9.0-SNAPSHOT</version>
<description>
This bundle contains the core implementation of Blueprint
along with the "ext" namespace handler.
@@ -92,7 +92,7 @@
</aries.osgi.include.resource>
<blueprint.annotation.api.version>1.0.0</blueprint.annotation.api.version>
<blueprint.api.version>1.0.0</blueprint.api.version>
- <blueprint.parser.version>1.4.0</blueprint.parser.version>
+ <blueprint.parser.version>1.5.0-SNAPSHOT</blueprint.parser.version>
<proxy.api.version>1.1.0</proxy.api.version>
<proxy.impl.version>1.1.0</proxy.impl.version>
<quiesce.api.version>1.0.0</quiesce.api.version>
@@ -106,7 +106,7 @@
<properties>
<blueprint.annotation.api.version>1.0.1</blueprint.annotation.api.version>
<blueprint.api.version>1.0.1</blueprint.api.version>
- <blueprint.parser.version>1.4.0</blueprint.parser.version>
+ <blueprint.parser.version>1.5.0-SNAPSHOT</blueprint.parser.version>
<proxy.api.version>1.1.0</proxy.api.version>
<proxy.impl.version>1.1.0</proxy.impl.version>
<quiesce.api.version>1.0.0</quiesce.api.version>
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe.java Fri Jan 19 09:44:57 2018
@@ -358,8 +358,8 @@ public abstract class AbstractServiceRef
synchronized (tracked) {
satisfied = optional || !tracked.isEmpty();
}
- setSatisfied(satisfied);
track(ref);
+ setSatisfied(satisfied);
}
}
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java Fri Jan 19 09:44:57 2018
@@ -656,7 +656,16 @@ public class BlueprintContainerImpl
}
LOGGER.debug("Notified satisfaction {} in bundle {}/{}: {}",
satisfiable.getName(), bundle.getSymbolicName(), getBundle().getVersion(), satisfiable.isSatisfied());
- if (state == State.Create || state == State.Created ) {
+
+ if ((state == State.Create || state == State.Created) && satisfiable.isStaticLifecycle()) {
+ if (satisfiable.isSatisfied()) {
+ repository.reCreateInstance(satisfiable.getName());
+ }
+ else {
+ repository.destroyInstance(satisfiable.getName());
+ }
+ }
+ else if (state == State.Create || state == State.Created) {
Map<String, List<SatisfiableRecipe>> dependencies = getSatisfiableDependenciesMap();
for (Map.Entry<String, List<SatisfiableRecipe>> entry : dependencies.entrySet()) {
String name = entry.getKey();
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintRepository.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintRepository.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintRepository.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintRepository.java Fri Jan 19 09:44:57 2018
@@ -87,6 +87,8 @@ public class BlueprintRepository impleme
* stack is used to detect circular dependencies.
*/
private final ThreadLocal<LinkedList<Recipe>> stack = new ThreadLocal<LinkedList<Recipe>>();
+
+ private Map<String, Set<String>> invertedDependencies;
public BlueprintRepository(ExtendedBlueprintContainer container) {
blueprintContainer = container;
@@ -124,6 +126,7 @@ public class BlueprintRepository impleme
throw new ComponentDefinitionException("Name " + name + " is already registered to instance " + getInstance(name));
}
recipes.put(name, recipe);
+ invertedDependencies = null;
}
public void removeRecipe(String name) {
@@ -131,6 +134,7 @@ public class BlueprintRepository impleme
throw new ComponentDefinitionException("Name " + name + " is already instanciated as " + getInstance(name) + " and cannot be removed.");
recipes.remove(name);
+ invertedDependencies = null;
}
private Object convert(String name, Object instance) throws ComponentDefinitionException {
@@ -214,6 +218,107 @@ public class BlueprintRepository impleme
}
}
+ private static <S, T> void addToMapSet(Map<S, Set<T>> map, S key, T value) {
+ Set<T> values = map.get(key);
+ if (values == null) {
+ values = new HashSet<T>();
+ map.put(key, values);
+ }
+ values.add(value);
+ }
+
+ private Map<String, Set<String>> getInvertedDependencies() {
+ if (invertedDependencies == null) {
+ Map<String, Set<String>> deps = new HashMap<String, Set<String>>();
+ for (String n : recipes.keySet()) {
+ Recipe r = recipes.get(n);
+ Set<Recipe> d = new HashSet<Recipe>();
+ internalGetAllRecipes(d, r);
+ for (Recipe e : d) {
+ addToMapSet(deps, e.getName(), r.getName());
+ }
+ }
+ invertedDependencies = deps;
+ }
+ return invertedDependencies;
+ }
+
+ public void reCreateInstance(String name) {
+ ExecutionContext oldContext = ExecutionContext.Holder.setContext(this);
+ try {
+ Set<String> toCreate = new HashSet<String>();
+ Set<String> deps = getInvertedDependencies().get(name);
+ if (deps == null) {
+ throw new NoSuchComponentException(name);
+ }
+ for (String dep : deps) {
+ boolean ok = true;
+ for (SatisfiableRecipe r : getAllRecipes(SatisfiableRecipe.class, dep)) {
+ if (!r.isSatisfied()) {
+ ok = false;
+ break;
+ }
+ }
+ if (ok) {
+ toCreate.add(dep);
+ }
+ }
+ createInstances(toCreate);
+ for (String n : toCreate) {
+ Recipe r = recipes.get(n);
+ if (r instanceof ServiceRecipe) {
+ ServiceRecipe sr = (ServiceRecipe) r;
+ if (!sr.isRegistered()) {
+ sr.register();
+ }
+ }
+ }
+ } finally {
+ ExecutionContext.Holder.setContext(oldContext);
+ }
+ }
+
+ public void destroyInstance(String name) {
+ ExecutionContext oldContext = ExecutionContext.Holder.setContext(this);
+ try {
+ Map<Recipe, Future<Object>> toDestroy = new LinkedHashMap<Recipe, Future<Object>>();
+ doGetInstancesToDestroy(toDestroy, name);
+ for (Map.Entry<Recipe, Future<Object>> entry : toDestroy.entrySet()) {
+ try {
+ Recipe recipe = entry.getKey();
+ Future<Object> future = entry.getValue();
+ Object instance = future.get();
+ if (instance != null) {
+ recipe.destroy(instance);
+ }
+ } catch (Exception e) {
+ throw new ComponentDefinitionException("Error destroying instance", e);
+ }
+ }
+ } finally {
+ ExecutionContext.Holder.setContext(oldContext);
+ }
+ }
+
+ protected void doGetInstancesToDestroy(Map<Recipe, Future<Object>> toDestroy, String name) {
+ Recipe recipe = recipes.get(name);
+ if (recipe != null) {
+ if (recipe instanceof ServiceRecipe) {
+ ((ServiceRecipe) recipe).unregister();
+ }
+ Future<Object> future = instances.remove(name);
+ if (future != null && future.isDone()) {
+ Set<String> deps = getInvertedDependencies().get(name);
+ for (String dep : deps) {
+ doGetInstancesToDestroy(toDestroy, dep);
+ }
+ toDestroy.put(recipe, future);
+ }
+ } else {
+ throw new NoSuchComponentException(name);
+ }
+ }
+
/*
* This method should not be called directly, only from one of the getAllRecipes() methods.
*/
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceListRecipe.java Fri Jan 19 09:44:57 2018
@@ -64,6 +64,11 @@ public class ReferenceListRecipe extends
}
@Override
+ public boolean isStaticLifecycle() {
+ return false;
+ }
+
+ @Override
protected Object internalCreate() throws ComponentDefinitionException {
try {
if (explicitDependencies != null) {
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/ReferenceRecipe.java Fri Jan 19 09:44:57 2018
@@ -67,6 +67,8 @@ public class ReferenceRecipe extends Abs
private final Collection<Class<?>> proxyChildBeanClasses;
private final Collection<WeakReference<Voidable>> proxiedChildren;
+
+ private final boolean staticLifecycle;
public ReferenceRecipe(String name,
ExtendedBlueprintContainer blueprintContainer,
@@ -76,15 +78,25 @@ public class ReferenceRecipe extends Abs
List<Recipe> explicitDependencies) {
super(name, blueprintContainer, metadata, filterRecipe, listenersRecipe, explicitDependencies);
this.metadata = metadata;
- if(metadata instanceof ExtendedReferenceMetadata)
- proxyChildBeanClasses = ((ExtendedReferenceMetadata) metadata).getProxyChildBeanClasses();
- else
+ if (metadata instanceof ExtendedReferenceMetadata) {
+ staticLifecycle = ((ExtendedReferenceMetadata) metadata).getLifecycle()
+ == ExtendedReferenceMetadata.LIFECYCLE_STATIC;
+ if (!staticLifecycle) {
+ proxyChildBeanClasses = ((ExtendedReferenceMetadata) metadata).getProxyChildBeanClasses();
+ if (proxyChildBeanClasses != null) {
+ proxiedChildren = new ArrayList<WeakReference<Voidable>>();
+ } else {
+ proxiedChildren = null;
+ }
+ } else {
+ proxyChildBeanClasses = null;
+ proxiedChildren = null;
+ }
+ } else {
+ staticLifecycle = false;
proxyChildBeanClasses = null;
-
- if (proxyChildBeanClasses != null)
- proxiedChildren = new ArrayList<WeakReference<Voidable>>();
- else
proxiedChildren = null;
+ }
}
@Override
@@ -104,19 +116,24 @@ public class ReferenceRecipe extends Abs
interfaces.addAll(loadAllClasses(((ExtendedReferenceMetadata)metadata).getExtraInterfaces()));
}
- proxy = createProxy(new ServiceDispatcher(), interfaces);
+ Object result;
+ if (isStaticLifecycle()) {
+ result = getService();
+ }
+ else {
+ proxy = createProxy(new ServiceDispatcher(), interfaces);
- // Add partially created proxy to the context
- ServiceProxyWrapper wrapper = new ServiceProxyWrapper();
+ // Add partially created proxy to the context
+ result = new ServiceProxyWrapper();
+ }
- addPartialObject(wrapper);
+ addPartialObject(result);
// Handle initial references
createListeners();
updateListeners();
- // Return a ServiceProxy that can injection of references or proxies can be done correctly
- return wrapper;
+ return result;
} catch (ComponentDefinitionException e) {
throw e;
} catch (Throwable t) {
@@ -141,18 +158,21 @@ public class ReferenceRecipe extends Abs
}
protected void track(ServiceReference ref) {
- // TODO: make this behavior configurable through a custom attribute
- // TODO: policy = sticky | replace
+ boolean replace;
+ if (metadata instanceof ExtendedReferenceMetadata) {
+ replace = ((ExtendedReferenceMetadata) metadata).getDamping()
+ == ExtendedReferenceMetadata.DAMPING_GREEDY;
+ } else {
+ replace = false;
+ }
synchronized (monitor) {
- if (trackedServiceReference == null) {
+ if (trackedServiceReference == null || replace) {
retrack();
}
}
}
protected void untrack(ServiceReference ref) {
- // TODO: make this behavior configurable through a custom attribute
- // TODO: policy = sticky | replace
synchronized (monitor) {
if (trackedServiceReference == ref) {
retrack();
@@ -160,7 +180,12 @@ public class ReferenceRecipe extends Abs
}
}
- private void bind(ServiceReference ref) {
+ @Override
+ public boolean isStaticLifecycle() {
+ return staticLifecycle;
+ }
+
+ protected void bind(ServiceReference ref) {
LOGGER.debug("Binding reference {} to {}", getName(), ref);
synchronized (monitor) {
ServiceReference oldReference = trackedServiceReference;
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/SatisfiableRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/SatisfiableRecipe.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/SatisfiableRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/SatisfiableRecipe.java Fri Jan 19 09:44:57 2018
@@ -49,4 +49,6 @@ public interface SatisfiableRecipe exten
String getOsgiFilter();
+ boolean isStaticLifecycle();
+
}
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/DependentComponentFactoryRecipe.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/DependentComponentFactoryRecipe.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/DependentComponentFactoryRecipe.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/di/DependentComponentFactoryRecipe.java Fri Jan 19 09:44:57 2018
@@ -41,6 +41,11 @@ public class DependentComponentFactoryRe
super(name, metadata, container, dependencies);
}
+ @Override
+ public boolean isStaticLifecycle() {
+ return false;
+ }
+
public String getOsgiFilter() {
return getMetadata().getDependencyDescriptor();
}
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java Fri Jan 19 09:44:57 2018
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Set;
import org.apache.aries.blueprint.ExtendedReferenceListMetadata;
+import org.apache.aries.blueprint.ExtendedReferenceMetadata;
import org.apache.aries.blueprint.ParserContext;
import org.apache.aries.blueprint.ext.PlaceholdersUtils;
import org.apache.aries.blueprint.ext.PropertyPlaceholder;
@@ -76,6 +77,7 @@ public class ExtNamespaceHandler impleme
public static final String BLUEPRINT_EXT_NAMESPACE_V1_3 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.3.0";
public static final String BLUEPRINT_EXT_NAMESPACE_V1_4 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.4.0";
public static final String BLUEPRINT_EXT_NAMESPACE_V1_5 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.5.0";
+ public static final String BLUEPRINT_EXT_NAMESPACE_V1_6 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0";
public static final String PROPERTY_PLACEHOLDER_ELEMENT = "property-placeholder";
public static final String DEFAULT_PROPERTIES_ELEMENT = "default-properties";
@@ -114,7 +116,16 @@ public class ExtNamespaceHandler impleme
public static final String BEAN = "bean";
public static final String REFERENCE = "reference";
-
+
+ public static final String DAMPING_ATTRIBUTE = "damping";
+
+ public static final String DAMPING_RELUCTANT = "reluctant";
+ public static final String DAMPING_GREEDY = "greedy";
+
+ public static final String LIFECYCLE_ATTRIBUTE = "lifecycle";
+
+ public static final String LIFECYCLE_DYNAMIC = "dynamic";
+ public static final String LIFECYCLE_STATIC = "static";
private static final Logger LOGGER = LoggerFactory.getLogger(ExtNamespaceHandler.class);
@@ -139,6 +150,8 @@ public class ExtNamespaceHandler impleme
return getClass().getResource("blueprint-ext-1.4.xsd");
} else if (BLUEPRINT_EXT_NAMESPACE_V1_5.equals(namespace)) {
return getClass().getResource("blueprint-ext-1.5.xsd");
+ } else if (BLUEPRINT_EXT_NAMESPACE_V1_6.equals(namespace)) {
+ return getClass().getResource("blueprint-ext-1.6.xsd");
} else if ("http://www.w3.org/XML/1998/namespace".equals(namespace)) {
return getClass().getResource("xml.xsd");
}
@@ -150,7 +163,8 @@ public class ExtNamespaceHandler impleme
|| BLUEPRINT_EXT_NAMESPACE_V1_2.equals(e)
|| BLUEPRINT_EXT_NAMESPACE_V1_3.equals(e)
|| BLUEPRINT_EXT_NAMESPACE_V1_4.equals(e)
- || BLUEPRINT_EXT_NAMESPACE_V1_5.equals(e);
+ || BLUEPRINT_EXT_NAMESPACE_V1_5.equals(e)
+ || BLUEPRINT_EXT_NAMESPACE_V1_6.equals(e);
}
public Set<Class> getManagedClasses() {
@@ -191,6 +205,10 @@ public class ExtNamespaceHandler impleme
} else if (node instanceof Element && nodeNameEquals(node, REFERENCE)) {
RefMetadata rd = context.parseElement(RefMetadata.class, component, (Element)node);
return createReference(context, rd.getComponentId());
+ } else if (node instanceof Attr && nodeNameEquals(node, DAMPING_ATTRIBUTE)) {
+ return decorateDamping(node, component, context);
+ } else if (node instanceof Attr && nodeNameEquals(node, LIFECYCLE_ATTRIBUTE)) {
+ return decorateLifecycle(node, component, context);
} else {
throw new ComponentDefinitionException("Unsupported node: " + node.getNodeName());
}
@@ -309,6 +327,42 @@ public class ExtNamespaceHandler impleme
return component;
}
+ private ComponentMetadata decorateDamping(Node node, ComponentMetadata component, ParserContext context) {
+ if (!(component instanceof ReferenceMetadata)) {
+ throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <reference> element");
+ }
+ if (!(component instanceof MutableReferenceMetadata)) {
+ throw new ComponentDefinitionException("Expected an instance of MutableReferenceMetadata");
+ }
+ int damping = ExtendedReferenceMetadata.DAMPING_GREEDY;
+ String value = ((Attr) node).getValue();
+ if (DAMPING_RELUCTANT.equals(value)) {
+ damping = ExtendedReferenceMetadata.DAMPING_RELUCTANT;
+ } else if (!DAMPING_GREEDY.equals(value)) {
+ throw new ComponentDefinitionException("Unknown damping method: " + value);
+ }
+ ((MutableReferenceMetadata) component).setDamping(damping);
+ return component;
+ }
+
+ private ComponentMetadata decorateLifecycle(Node node, ComponentMetadata component, ParserContext context) {
+ if (!(component instanceof ReferenceMetadata)) {
+ throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <reference> element");
+ }
+ if (!(component instanceof MutableReferenceMetadata)) {
+ throw new ComponentDefinitionException("Expected an instance of MutableReferenceMetadata");
+ }
+ int lifecycle = ExtendedReferenceMetadata.LIFECYCLE_DYNAMIC;
+ String value = ((Attr) node).getValue();
+ if (LIFECYCLE_STATIC.equals(value)) {
+ lifecycle = ExtendedReferenceMetadata.LIFECYCLE_STATIC;
+ } else if (!LIFECYCLE_DYNAMIC.equals(value)) {
+ throw new ComponentDefinitionException("Unknown lifecycle method: " + value);
+ }
+ ((MutableReferenceMetadata) component).setLifecycle(lifecycle);
+ return component;
+ }
+
private Metadata parsePropertyPlaceholder(ParserContext context, Element element) {
MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
metadata.setProcessor(true);
Modified: aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java Fri Jan 19 09:44:57 2018
@@ -23,7 +23,6 @@ import java.util.concurrent.ExecutorServ
import org.apache.aries.blueprint.ComponentDefinitionRegistry;
import org.apache.aries.blueprint.Processor;
-import org.apache.aries.blueprint.di.Repository;
import org.apache.aries.proxy.ProxyManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
Modified: aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml (original)
+++ aries/trunk/blueprint/blueprint-core/src/main/resources/OSGI-INF/blueprint/blueprint-ext.xml Fri Jan 19 09:44:57 2018
@@ -52,7 +52,12 @@
<entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.5.0"/>
</service-properties>
</service>
-
+ <service ref="ExtNamespaceHandler" interface="org.apache.aries.blueprint.NamespaceHandler">
+ <service-properties>
+ <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0"/>
+ </service-properties>
+ </service>
+
<!-- Also provide the "xml" namespace as a core functionality to avoid many bundles registering a handler for this -->
<service ref="ExtNamespaceHandler" interface="org.apache.aries.blueprint.NamespaceHandler">
<service-properties>
Added: aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd?rev=1821610&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd (added)
+++ aries/trunk/blueprint/blueprint-core/src/main/resources/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.6.xsd Fri Jan 19 09:44:57 2018
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0"
+ xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ attributeFormDefault="unqualified" elementFormDefault="qualified"
+ targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0" version="1.0.0">
+
+ <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0"/>
+
+ <!-- property placeholder -->
+
+ <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
+
+ <xsd:complexType name="TpropertyPlaceholder">
+ <xsd:complexContent>
+ <xsd:extension base="bp:Tcomponent">
+ <xsd:sequence>
+ <!-- nested properties declaration -->
+ <xsd:element maxOccurs="1" minOccurs="0" name="default-properties" type="TdefaultProperties"/>
+ <xsd:element maxOccurs="unbounded" minOccurs="0" name="location" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:attribute default="${" name="placeholder-prefix" type="xsd:string" use="optional"/>
+ <xsd:attribute default="}" name="placeholder-suffix" type="xsd:string" use="optional"/>
+ <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
+ <xsd:attribute default="false" name="ignore-missing-locations" type="xsd:boolean" use="optional"/>
+ <xsd:attribute default="fallback" name="system-properties" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="never"/>
+ <xsd:enumeration value="fallback"/>
+ <xsd:enumeration value="override"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="evaluator" type="xsd:string" use="optional"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="TdefaultProperties">
+ <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+ <xsd:element name="property" type="bp:Tproperty"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- proxy method -->
+
+ <xsd:attribute default="default" name="proxy-method">
+ <xsd:simpleType>
+ <xsd:restriction>
+ <xsd:simpleType>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="default"/>
+ <xsd:enumeration value="classes"/>
+ <xsd:enumeration value="greedy"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ <xsd:minLength value="1"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <!-- role -->
+
+ <xsd:attribute name="role">
+ <xsd:simpleType>
+ <xsd:restriction>
+ <xsd:simpleType>
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="processor"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <!-- CM property placeholder extenstion -->
+
+ <xsd:element name="location" type="xsd:string"/>
+ <xsd:attribute default="false" name="ignore-missing-locations" type="xsd:boolean"/>
+ <xsd:attribute default="fallback" name="system-properties">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="never"/>
+ <xsd:enumeration value="fallback"/>
+ <xsd:enumeration value="override"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <xsd:attribute default="false" name="field-injection" type="xsd:boolean"/>
+
+ <!-- Default reference bean -->
+ <xsd:attribute name="default" type="bp:Tidref"/>
+
+ <!-- Filter attribute -->
+ <xsd:attribute name="filter" type="xsd:normalizedString"/>
+
+ <!-- Additional interfaces for references -->
+ <xsd:element name="additional-interfaces" type="bp:Tinterfaces"/>
+
+ <!-- ARIES-1293, provide a way to create or reference beans from within -->
+ <!-- custom namespace handlers and other locations. (blueprint.xsd does -->
+ <!-- not provide top level element definitions for these) -->
+ <xsd:element name="bean" type="bp:Tinlined-bean"/>
+ <xsd:element name="reference" type="bp:Tref"/>
+
+ <xsd:attribute default="reluctant" name="damping">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="reluctant"/>
+ <xsd:enumeration value="greedy"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <xsd:attribute default="dynamic" name="lifecycle">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="dynamic"/>
+ <xsd:enumeration value="static"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+</xsd:schema>
Added: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/DampingPolicyTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/DampingPolicyTest.java?rev=1821610&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/DampingPolicyTest.java (added)
+++ aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/DampingPolicyTest.java Fri Jan 19 09:44:57 2018
@@ -0,0 +1,98 @@
+/*
+ * 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.aries.blueprint.container;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.aries.blueprint.ExtendedReferenceMetadata;
+import org.apache.aries.blueprint.container.SatisfiableRecipe.SatisfactionListener;
+import org.apache.aries.blueprint.reflect.ReferenceMetadataImpl;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+
+public class DampingPolicyTest {
+
+ @Test
+ public void testGreedy() throws InvalidSyntaxException {
+ ExtendedBlueprintContainer container = EasyMock.createMock(ExtendedBlueprintContainer.class);
+ BundleContext containerContext = EasyMock.createMock(BundleContext.class);
+
+ ReferenceMetadataImpl metadata = new ReferenceMetadataImpl();
+ metadata.setInterface("my.interface");
+ metadata.setDamping(ExtendedReferenceMetadata.DAMPING_GREEDY);
+
+ final AtomicReference<ServiceReference> currentReference = new AtomicReference<ServiceReference>();
+
+ ReferenceRecipe recipe = new ReferenceRecipe(
+ "myref",
+ container,
+ metadata,
+ null, null, null
+ ) {
+ @Override
+ protected void bind(ServiceReference ref) {
+ currentReference.set(ref);
+ super.bind(ref);
+ }
+ };
+
+ SatisfactionListener listener = new SatisfactionListener() {
+ @Override
+ public void notifySatisfaction(SatisfiableRecipe satisfiable) {
+
+ }
+ };
+ ServiceReference svcRef1 = EasyMock.createMock(ServiceReference.class);
+
+ EasyMock.expect(container.getBundleContext()).andReturn(containerContext).anyTimes();
+ containerContext.addServiceListener(recipe, "(objectClass=my.interface)");
+ EasyMock.expectLastCall();
+ EasyMock.expect(containerContext.getServiceReferences((String) null, "(objectClass=my.interface)"))
+ .andReturn(new ServiceReference[] { svcRef1 });
+ EasyMock.replay(container, containerContext, svcRef1);
+
+ recipe.start(listener);
+ Assert.assertSame(svcRef1, currentReference.get());
+ EasyMock.verify(container, containerContext, svcRef1);
+
+ EasyMock.reset(container, containerContext, svcRef1);
+
+
+ ServiceReference svcRef2 = EasyMock.createMock(ServiceReference.class);
+ ServiceEvent event2 = new ServiceEvent(ServiceEvent.REGISTERED, svcRef2);
+
+ EasyMock.expect(svcRef1.getProperty(Constants.SERVICE_ID)).andReturn(0L).anyTimes();
+ EasyMock.expect(svcRef1.getProperty(Constants.SERVICE_RANKING)).andReturn(0).anyTimes();
+ EasyMock.expect(svcRef2.getProperty(Constants.SERVICE_ID)).andReturn(1L).anyTimes();
+ EasyMock.expect(svcRef2.getProperty(Constants.SERVICE_RANKING)).andReturn(1).anyTimes();
+ EasyMock.replay(container, containerContext, svcRef1, svcRef2);
+
+ recipe.serviceChanged(event2);
+ Assert.assertSame(svcRef2, currentReference.get());
+ EasyMock.verify(container, containerContext, svcRef1, svcRef2);
+
+ }
+}
Added: aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/LifecyclePolicyTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/LifecyclePolicyTest.java?rev=1821610&view=auto
==============================================================================
--- aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/LifecyclePolicyTest.java (added)
+++ aries/trunk/blueprint/blueprint-core/src/test/java/org/apache/aries/blueprint/container/LifecyclePolicyTest.java Fri Jan 19 09:44:57 2018
@@ -0,0 +1,248 @@
+/*
+ * 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.aries.blueprint.container;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.aries.blueprint.ExtendedReferenceMetadata;
+import org.apache.aries.blueprint.parser.NamespaceHandlerSet;
+import org.apache.aries.blueprint.reflect.BeanMetadataImpl;
+import org.apache.aries.blueprint.reflect.RefMetadataImpl;
+import org.apache.aries.blueprint.reflect.ReferenceMetadataImpl;
+import org.apache.aries.proxy.ProxyManager;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Version;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.BlueprintEvent;
+import org.osgi.service.blueprint.container.BlueprintListener;
+
+public class LifecyclePolicyTest {
+
+ @Test
+ public void testStatic() throws Exception {
+ final ReferenceMetadataImpl ref = new ReferenceMetadataImpl();
+ ref.setId("ref");
+ ref.setRuntimeInterface(TestItf.class);
+ ref.setLifecycle(ExtendedReferenceMetadata.LIFECYCLE_STATIC);
+
+ final BeanMetadataImpl bean1 = new BeanMetadataImpl();
+ bean1.setId("bean1");
+ bean1.setRuntimeClass(Bean1.class);
+ bean1.setInitMethod("init");
+ bean1.setDestroyMethod("destroy");
+ bean1.addProperty("itf", new RefMetadataImpl("ref"));
+
+ final BeanMetadataImpl bean2 = new BeanMetadataImpl();
+ bean2.setId("bean2");
+ bean2.setRuntimeClass(Bean2.class);
+ bean2.setInitMethod("init");
+ bean2.setDestroyMethod("destroy");
+ bean2.addProperty("bean1", new RefMetadataImpl("bean1"));
+
+ Bundle bundle = EasyMock.createMock(Bundle.class);
+ BundleContext bundleContext = EasyMock.createMock(BundleContext.class);
+ Bundle extenderBundle = EasyMock.createMock(Bundle.class);
+ BundleContext extenderBundleContext = EasyMock.createMock(BundleContext.class);
+ BlueprintListener eventDispatcher = EasyMock.createMock(BlueprintListener.class);
+ NamespaceHandlerRegistry namespaceHandlerRegistry = EasyMock.createMock(NamespaceHandlerRegistry.class);
+ ProxyManager proxyManager = EasyMock.createMock(ProxyManager.class);
+ NamespaceHandlerSet namespaceHandlerSet = EasyMock.createMock(NamespaceHandlerSet.class);
+ TestItf itf = EasyMock.createMock(TestItf.class);
+ ServiceRegistration registration = EasyMock.createMock(ServiceRegistration.class);
+ ExecutorService executorService = Executors.newFixedThreadPool(1);
+ ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
+ List<URL> pathList = new ArrayList<URL>();
+ Set<URI> namespaces = new HashSet<URI>();
+
+ BlueprintContainerImpl container = new BlueprintContainerImpl(
+ bundle, bundleContext, extenderBundle, eventDispatcher, namespaceHandlerRegistry,
+ executorService, timer, pathList, proxyManager, namespaces
+ ) {
+ private boolean repoCreated = false;
+ @Override
+ public BlueprintRepository getRepository() {
+ if (!repoCreated) {
+ getComponentDefinitionRegistry().registerComponentDefinition(ref);
+ getComponentDefinitionRegistry().registerComponentDefinition(bean1);
+ getComponentDefinitionRegistry().registerComponentDefinition(bean2);
+ repoCreated = true;
+ }
+ return super.getRepository();
+ }
+ };
+
+ ServiceReference svcRef1 = EasyMock.createMock(ServiceReference.class);
+
+ EasyMock.expect(bundle.getSymbolicName()).andReturn("bundleSymbolicName").anyTimes();
+ EasyMock.expect(bundle.getVersion()).andReturn(Version.emptyVersion).anyTimes();
+ EasyMock.expect(bundle.getState()).andReturn(Bundle.ACTIVE).anyTimes();
+ EasyMock.expect(bundle.getBundleContext()).andReturn(bundleContext).anyTimes();
+ Hashtable<String, String> headers = new Hashtable<String, String>();
+ headers.put(Constants.BUNDLE_SYMBOLICNAME, "bundleSymbolicName;blueprint.aries.xml-validation:=false");
+ EasyMock.expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+ eventDispatcher.blueprintEvent(EasyMock.<BlueprintEvent>anyObject());
+ EasyMock.expectLastCall().anyTimes();
+ EasyMock.expect(namespaceHandlerRegistry.getNamespaceHandlers(namespaces, bundle))
+ .andReturn(namespaceHandlerSet).anyTimes();
+ EasyMock.expect(namespaceHandlerSet.getNamespaces()).andReturn(namespaces).anyTimes();
+ namespaceHandlerSet.addListener(container);
+ EasyMock.expectLastCall();
+ Properties props = new Properties();
+ props.put("osgi.blueprint.container.version", Version.emptyVersion);
+ props.put("osgi.blueprint.container.symbolicname", "bundleSymbolicName");
+ EasyMock.expect(bundleContext.registerService(
+ EasyMock.aryEq(new String[] {BlueprintContainer.class.getName()}),
+ EasyMock.same(container),
+ EasyMock.eq((Dictionary)props))).andReturn(registration);
+ bundleContext.addServiceListener(EasyMock.<org.osgi.framework.ServiceListener>anyObject(), EasyMock.<String>anyObject());
+ EasyMock.expectLastCall();
+ EasyMock.expect(bundleContext.getServiceReferences((String) null, "(objectClass=" + TestItf.class.getName() + ")"))
+ .andReturn(new ServiceReference[] { svcRef1 });
+
+ EasyMock.expect(bundleContext.getService(svcRef1)).andReturn(itf);
+ EasyMock.expect(bundle.loadClass("java.lang.Object")).andReturn((Class) Object.class).anyTimes();
+
+ EasyMock.replay(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ container.run();
+ ReferenceRecipe recipe = (ReferenceRecipe) container.getRepository().getRecipe("ref");
+ recipe.start(container);
+
+ Bean2 bean2i = (Bean2) container.getRepository().create("bean2");
+ Assert.assertNotNull(bean2i);
+ Assert.assertEquals(1, Bean2.initialized);
+ Assert.assertEquals(0, Bean2.destroyed);
+
+ EasyMock.verify(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ //
+ // Unregister the service
+ //
+ // Given the lifecycle is 'static', this should cause the Bean1 and Bean2
+ // to be destroyed
+ //
+
+ EasyMock.reset(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ EasyMock.expect(bundle.getSymbolicName()).andReturn("bundleSymbolicName").anyTimes();
+ EasyMock.expect(bundle.getVersion()).andReturn(Version.emptyVersion).anyTimes();
+ EasyMock.expect(bundleContext.ungetService(svcRef1)).andReturn(false);
+
+ EasyMock.replay(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ recipe.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, svcRef1));
+ Assert.assertEquals(1, Bean2.initialized);
+ Assert.assertEquals(1, Bean2.destroyed);
+
+ EasyMock.verify(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ //
+ // Re-register the service
+ //
+ // Given the lifecycle is 'static', this should cause the Bean1 and Bean2
+ // to be recreated
+ //
+
+ EasyMock.reset(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ EasyMock.expect(bundle.getSymbolicName()).andReturn("bundleSymbolicName").anyTimes();
+ EasyMock.expect(bundle.getVersion()).andReturn(Version.emptyVersion).anyTimes();
+ EasyMock.expect(bundleContext.getService(svcRef1)).andReturn(itf);
+ EasyMock.expect(bundle.loadClass("java.lang.Object")).andReturn((Class) Object.class).anyTimes();
+
+ EasyMock.replay(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+
+ recipe.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, svcRef1));
+ Assert.assertEquals(2, Bean2.initialized);
+ Assert.assertEquals(1, Bean2.destroyed);
+
+ EasyMock.verify(bundle, bundleContext, extenderBundle, extenderBundleContext,
+ eventDispatcher, namespaceHandlerRegistry, namespaceHandlerSet, proxyManager,
+ svcRef1, registration);
+ }
+
+ public interface TestItf {
+
+ }
+
+ public static class Bean1 {
+ private TestItf itf;
+ public TestItf getItf() {
+ return itf;
+ }
+ public void setItf(TestItf itf) {
+ this.itf = itf;
+ }
+ public void init() {
+ }
+ public void destroy() {
+ }
+ }
+
+ public static class Bean2 {
+ private Bean1 bean1;
+ static int initialized = 0;
+ static int destroyed = 0;
+ public Bean1 getBean1() {
+ return bean1;
+ }
+ public void setBean1(Bean1 bean1) {
+ this.bean1 = bean1;
+ }
+ public void init() {
+ initialized++;
+ }
+ public void destroy() {
+ destroyed++;
+ }
+ }
+}
Modified: aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java (original)
+++ aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/ExtendedReferenceMetadata.java Fri Jan 19 09:44:57 2018
@@ -24,9 +24,22 @@ import org.osgi.service.blueprint.reflec
public interface ExtendedReferenceMetadata extends ReferenceMetadata
{
+ public int DAMPING_RELUCTANT = 0;
+
+ public int DAMPING_GREEDY = 1;
+
+ public int LIFECYCLE_DYNAMIC = 0;
+
+ public int LIFECYCLE_STATIC = 1;
+
public String getDefaultBean();
public Collection<Class<?>> getProxyChildBeanClasses();
public Collection<String> getExtraInterfaces();
+
+ public int getDamping();
+
+ public int getLifecycle();
+
}
\ No newline at end of file
Modified: aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java (original)
+++ aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/mutable/MutableReferenceMetadata.java Fri Jan 19 09:44:57 2018
@@ -36,4 +36,8 @@ public interface MutableReferenceMetadat
void setProxyChildBeanClasses(Collection<Class<?>> classes);
void setExtraInterfaces(Collection<String> interfaces);
+
+ void setDamping(int damping);
+
+ void setLifecycle(int lifecycle);
}
\ No newline at end of file
Modified: aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java (original)
+++ aries/trunk/blueprint/blueprint-parser/src/main/java/org/apache/aries/blueprint/reflect/ReferenceMetadataImpl.java Fri Jan 19 09:44:57 2018
@@ -35,6 +35,8 @@ public class ReferenceMetadataImpl exten
private String defaultBeanId;
private Collection<Class<?>> proxyChildBeanClasses;
private Collection<String> extraInterfaces;
+ private int damping;
+ private int lifecycle;
public ReferenceMetadataImpl() {
}
@@ -73,6 +75,8 @@ public class ReferenceMetadataImpl exten
", referenceListeners=" + referenceListeners +
", timeout=" + timeout +
", additonalInterfaces=" + getExtraInterfaces() +
+ ", damping=" + getDamping() +
+ ", lifecycle=" + getLifecycle() +
']';
}
@@ -94,4 +98,20 @@ public class ReferenceMetadataImpl exten
public void setExtraInterfaces(Collection<String> interfaces) {
extraInterfaces = interfaces;
}
+
+ public int getDamping() {
+ return damping;
+ }
+
+ public void setDamping(int damping) {
+ this.damping = damping;
+ }
+
+ public int getLifecycle() {
+ return lifecycle;
+ }
+
+ public void setLifecycle(int lifecycle) {
+ this.lifecycle = lifecycle;
+ }
}
Modified: aries/trunk/blueprint/itests/blueprint-itests/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/blueprint/itests/blueprint-itests/pom.xml?rev=1821610&r1=1821609&r2=1821610&view=diff
==============================================================================
--- aries/trunk/blueprint/itests/blueprint-itests/pom.xml (original)
+++ aries/trunk/blueprint/itests/blueprint-itests/pom.xml Fri Jan 19 09:44:57 2018
@@ -56,7 +56,7 @@
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.core</artifactId>
- <version>1.8.3-SNAPSHOT</version>
+ <version>1.9.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
@@ -71,7 +71,7 @@
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.spring</artifactId>
- <version>1.0.0-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
@@ -194,7 +194,7 @@
<dependency>
<groupId>org.apache.aries.blueprint</groupId>
<artifactId>org.apache.aries.blueprint.testquiescebundle</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <version>${project.version}</version>
</dependency>
<!-- pax exam -->