You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2009/07/30 23:12:29 UTC
svn commit: r799440 - in /geronimo/sandbox/blueprint/blueprint-core/src:
main/java/org/apache/geronimo/blueprint/container/
main/java/org/apache/geronimo/blueprint/di/
test/java/org/apache/geronimo/blueprint/
test/java/org/apache/geronimo/blueprint/poj...
Author: gawor
Date: Thu Jul 30 21:12:29 2009
New Revision: 799440
URL: http://svn.apache.org/viewvc?rev=799440&view=rev
Log:
break cyclic dependencies and other updates
Added:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java (with props)
Modified:
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AbstractServiceReferenceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BeanRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintContainerImpl.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ServiceRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/AbstractRecipe.java
geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/Recipe.java
geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoCircular.java
geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-circular.xml
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AbstractServiceReferenceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AbstractServiceReferenceRecipe.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AbstractServiceReferenceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/AbstractServiceReferenceRecipe.java Thu Jul 30 21:12:29 2009
@@ -169,14 +169,21 @@
return satisfied.get();
}
+ @Override
+ public List<Recipe> getConstructorDependencies() {
+ List<Recipe> recipes = new ArrayList<Recipe>();
+ if (explicitDependencies != null) {
+ recipes.addAll(explicitDependencies);
+ }
+ return recipes;
+ }
+
public List<Recipe> getDependencies() {
List<Recipe> recipes = new ArrayList<Recipe>();
if (listenersRecipe != null) {
recipes.add(listenersRecipe);
}
- if (explicitDependencies != null) {
- recipes.addAll(explicitDependencies);
- }
+ recipes.addAll(getConstructorDependencies());
return recipes;
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BeanRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BeanRecipe.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BeanRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BeanRecipe.java Thu Jul 30 21:12:29 2009
@@ -128,13 +128,11 @@
this.explicitDependencies = explicitDependencies;
}
- public List<Recipe> getDependencies() {
+ @Override
+ public List<Recipe> getConstructorDependencies() {
List<Recipe> recipes = new ArrayList<Recipe>();
- for (Object o : properties.values()) {
- if (o instanceof Recipe) {
- Recipe recipe = (Recipe) o;
- recipes.add(recipe);
- }
+ if (explicitDependencies != null) {
+ recipes.addAll(explicitDependencies);
}
if (arguments != null) {
for (Object argument : arguments) {
@@ -143,9 +141,18 @@
}
}
}
- if (explicitDependencies != null) {
- recipes.addAll(explicitDependencies);
+ return recipes;
+ }
+
+ public List<Recipe> getDependencies() {
+ List<Recipe> recipes = new ArrayList<Recipe>();
+ for (Object o : properties.values()) {
+ if (o instanceof Recipe) {
+ Recipe recipe = (Recipe) o;
+ recipes.add(recipe);
+ }
}
+ recipes.addAll(getConstructorDependencies());
return recipes;
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintContainerImpl.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintContainerImpl.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintContainerImpl.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintContainerImpl.java Thu Jul 30 21:12:29 2009
@@ -437,7 +437,8 @@
}
Map<String, Object> objects = repository.createAll(typeConverters);
- for (Object obj : objects.values()) {
+ for (String name : typeConverters) {
+ Object obj = objects.get(name);
if (obj instanceof Converter) {
converter.registerConverter((Converter) obj);
} else {
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/BlueprintRepository.java Thu Jul 30 21:12:29 2009
@@ -21,6 +21,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -116,13 +117,27 @@
recipes.put(name, recipe);
}
+ private Object convert(String name, Object instance) throws ComponentDefinitionException {
+ try {
+ // Make sure to go through the conversion step in case we have a Convertible object
+ return convert(instance, new ReifiedType(Object.class));
+ } catch (Exception e) {
+ throw new ComponentDefinitionException("Unable to convert instance " + name, e);
+ }
+ }
+
public Object create(String name) throws ComponentDefinitionException {
return create(name, true);
}
public Object create(String name, boolean allowReentry) throws ComponentDefinitionException {
- Map<String, Object> instances = createAll(Arrays.asList(name), allowReentry);
- return instances.get(name);
+ ExecutionContext oldContext = ExecutionContext.Holder.setContext(this);
+ try {
+ Object instance = createInstance(name, allowReentry);
+ return convert(name, instance);
+ } finally {
+ ExecutionContext.Holder.setContext(oldContext);
+ }
}
public Map<String, Object> createAll(Collection<String> names) throws ComponentDefinitionException {
@@ -132,16 +147,10 @@
public Map<String, Object> createAll(Collection<String> names, boolean allowReentry) throws ComponentDefinitionException {
ExecutionContext oldContext = ExecutionContext.Holder.setContext(this);
try {
- Map<String, Object> instances = new LinkedHashMap<String, Object>();
+ Map<String, Object> instances = createInstances(names, allowReentry);
for (String name : names) {
- Object obj = createInstance(name, allowReentry);
- try {
- // Make sure to go through the conversion step in case we have a Convertible object
- obj = convert(obj, new ReifiedType(Object.class));
- } catch (Exception e) {
- throw new ComponentDefinitionException("Unable to convert instance " + name, e);
- }
- instances.put(name, obj);
+ Object obj = instances.get(name);
+ instances.put(name, convert(name, obj));
}
return instances;
} finally {
@@ -187,36 +196,46 @@
}
private Object createInstance(String name, boolean allowReentry) {
+ Object instance = getInstance(name);
+ if (instance == null) {
+ Map <String, Object> instances = createInstances(Arrays.asList(name), allowReentry);
+ instance = instances.get(name);
+ if (instance == null) {
+ throw new NoSuchComponentException(name);
+ }
+ }
+ return instance;
+ }
+
+ private Map<String, Object> createInstances(Collection<String> names, boolean allowReentry) {
// We need to synchronize recipe creation on the repository
// so that we don't end up with multiple threads creating the
// same instance at the same time.
- Object instance = getInstance(name);
- if (instance == null) {
- synchronized (instanceLock) {
- try {
- if (!allowReentry) {
- createReentered++;
- }
- instance = getInstance(name);
- if (instance == null) {
- Recipe recipe = getRecipe(name);
- if (recipe != null) {
- instance = recipe.create();
- }
- }
- } finally {
- if (!allowReentry) {
- createReentered--;
+ synchronized (instanceLock) {
+ try {
+ if (!allowReentry) {
+ createReentered++;
+ }
+ DependencyGraph graph = new DependencyGraph(this);
+ HashMap<String, Object> objects = new LinkedHashMap<String, Object>();
+ for (Map.Entry<String, Recipe> entry : graph.getSortedRecipes(names).entrySet()) {
+ String name = entry.getKey();
+ Object object = instances.get(name);
+ if (object == null) {
+ Recipe recipe = entry.getValue();
+ object = recipe.create();
}
+ objects.put(name, object);
+ }
+ return objects;
+ } finally {
+ if (!allowReentry) {
+ createReentered--;
}
}
}
- if (instance == null) {
- throw new NoSuchComponentException(name);
- }
- return instance;
}
-
+
public boolean isCreateReentered() {
return createReentered >= 2;
}
Added: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java?rev=799440&view=auto
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java (added)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java Thu Jul 30 21:12:29 2009
@@ -0,0 +1,188 @@
+/**
+ *
+ * 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.geronimo.blueprint.container;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.geronimo.blueprint.di.CircularDependencyException;
+import org.apache.geronimo.blueprint.di.Recipe;
+import org.apache.geronimo.blueprint.di.RefRecipe;
+import org.osgi.service.blueprint.container.NoSuchComponentException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DependencyGraph {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DependencyGraph.class);
+
+ private BlueprintRepository repository;
+
+ public DependencyGraph(BlueprintRepository repository) {
+ this.repository = repository;
+ }
+
+ public LinkedHashMap<String, Recipe> getSortedRecipes(Collection<String> names) {
+ // construct the graph
+ Map<String, Node> nodes = new LinkedHashMap<String, Node>();
+ for (String name : names) {
+ Object object = repository.getObject(name);
+ if (object == null) {
+ throw new NoSuchComponentException(name);
+ }
+ if (object instanceof Recipe) {
+ Recipe recipe = (Recipe) object;
+ if (!recipe.getName().equals(name)) {
+ throw new RuntimeException("Recipe '" + name + "' returned from the repository has name '" + name + "'");
+ }
+ createNode(name, recipe, nodes);
+ }
+ }
+
+ // find all initial leaf nodes (and islands)
+ List<Node> sortedNodes = new ArrayList<Node>(nodes.size());
+ LinkedList<Node> leafNodes = new LinkedList<Node>();
+ for (Node n : nodes.values()) {
+ if (n.referenceCount == 0) {
+ // if the node is totally isolated (no in or out refs),
+ // move it directly to the finished list, so they are first
+ if (n.references.size() == 0) {
+ sortedNodes.add(n);
+ } else {
+ leafNodes.add(n);
+ }
+ }
+ }
+
+ // pluck the leaves until there are no leaves remaining
+ while (!leafNodes.isEmpty()) {
+ Node node = leafNodes.removeFirst();
+ sortedNodes.add(node);
+ for (Node ref : node.references) {
+ ref.referenceCount--;
+ if (ref.referenceCount == 0) {
+ leafNodes.add(ref);
+ }
+ }
+ }
+
+ // There are no more leaves so if there are there still
+ // unprocessed nodes in the graph, we have one or more curcuits
+ if (sortedNodes.size() != nodes.size()) {
+ findCircuit(nodes.values().iterator().next(), new ArrayList<Recipe>(nodes.size()));
+ // find circuit should never fail, if it does there is a programming error
+ throw new RuntimeException("Internal Error: expected a CircularDependencyException");
+ }
+
+ // return the recipes
+ LinkedHashMap<String, Recipe> sortedRecipes = new LinkedHashMap<String, Recipe>();
+ for (Node node : sortedNodes) {
+ sortedRecipes.put(node.name, node.recipe);
+ }
+
+ return sortedRecipes;
+ }
+
+ private void findCircuit(Node node, ArrayList<Recipe> stack) {
+ if (stack.contains(node.recipe)) {
+ ArrayList<Recipe> circularity = new ArrayList<Recipe>(stack.subList(stack.indexOf(node.recipe), stack.size()));
+
+ // remove anonymous nodes from circularity list
+ for (Iterator<Recipe> iterator = circularity.iterator(); iterator.hasNext();) {
+ Recipe recipe = iterator.next();
+ if (recipe != node.recipe && recipe.getName() == null) {
+ iterator.remove();
+ }
+ }
+
+ // add ending node to list so a full circuit is shown
+ circularity.add(node.recipe);
+
+ throw new CircularDependencyException(circularity);
+ }
+
+ stack.add(node.recipe);
+ for (Node reference : node.references) {
+ findCircuit(reference, stack);
+ }
+ }
+
+ private Node createNode(String name, Recipe recipe, Map<String, Node> nodes) {
+ // if node already exists, verify that the exact same recipe instnace is used for both
+ if (nodes.containsKey(name)) {
+ Node node = nodes.get(name);
+ if (node.recipe != recipe) {
+ throw new RuntimeException("The name '" + name +"' is assigned to multiple recipies");
+ }
+ return node;
+ }
+
+ // create the node
+ Node node = new Node();
+ node.name = name;
+ node.recipe = recipe;
+ nodes.put(name, node);
+
+ // link in the references
+ LinkedList<Recipe> constructorRecipes = new LinkedList<Recipe>(recipe.getConstructorDependencies());
+ while (!constructorRecipes.isEmpty()) {
+ Recipe nestedRecipe = constructorRecipes.removeFirst();
+ if (nestedRecipe instanceof RefRecipe) {
+ nestedRecipe = nestedRecipe.getDependencies().get(0);
+ String nestedName = nestedRecipe.getName();
+ Node nestedNode = createNode(nestedName, nestedRecipe, nodes);
+ node.referenceCount++;
+ nestedNode.references.add(node);
+ } else {
+ constructorRecipes.addAll(nestedRecipe.getDependencies());
+ }
+ }
+
+ return node;
+ }
+
+ private class Node {
+ String name;
+ Recipe recipe;
+ final List<Node> references = new ArrayList<Node>();
+ int referenceCount;
+
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("Node[").append(name);
+ if (references.size() > 0) {
+ buf.append(" <- ");
+ Iterator<Node> iter = references.iterator();
+ while(iter.hasNext()) {
+ buf.append(iter.next().name);
+ if (iter.hasNext()) {
+ buf.append(", ");
+ }
+ }
+ }
+ buf.append("]");
+ return buf.toString();
+ }
+
+ }
+}
Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/DependencyGraph.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ServiceRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ServiceRecipe.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ServiceRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/container/ServiceRecipe.java Thu Jul 30 21:12:29 2009
@@ -102,6 +102,15 @@
return listenersRecipe;
}
+ @Override
+ public List<Recipe> getConstructorDependencies() {
+ List<Recipe> recipes = new ArrayList<Recipe>();
+ if (explicitDependencies != null) {
+ recipes.addAll(explicitDependencies);
+ }
+ return recipes;
+ }
+
public List<Recipe> getDependencies() {
List<Recipe> recipes = new ArrayList<Recipe>();
if (serviceRecipe != null) {
@@ -112,10 +121,8 @@
}
if (propertiesRecipe != null) {
recipes.add(propertiesRecipe);
- }
- if (explicitDependencies != null) {
- recipes.addAll(explicitDependencies);
- }
+ }
+ recipes.addAll(getConstructorDependencies());
return recipes;
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/AbstractRecipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/AbstractRecipe.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/AbstractRecipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/AbstractRecipe.java Thu Jul 30 21:12:29 2009
@@ -19,6 +19,8 @@
import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import org.apache.geronimo.blueprint.container.GenericType;
import org.osgi.service.blueprint.container.ReifiedType;
@@ -28,6 +30,7 @@
protected final String name;
protected boolean prototype = true;
+ private boolean creating = false;
protected AbstractRecipe(String name) {
if (name == null) throw new NullPointerException("name is null");
@@ -51,18 +54,19 @@
ExecutionContext context = ExecutionContext.Holder.getContext();
synchronized (context.getInstanceLock()) {
+ if (creating && context.isCreateReentered()) {
+ ArrayList<Recipe> circularity = new ArrayList<Recipe>();
+ circularity.add(this);
+ throw new CircularDependencyException("Dynamic cycle detected in recipe", circularity);
+ }
// if this recipe has already been executed in this container, return the currently registered value
Object obj = context.getPartialObject(name);
if (obj != null) {
- if (context.isCreateReentered()) {
- ArrayList<Recipe> circularity = new ArrayList<Recipe>();
- circularity.add(this);
- throw new CircularDependencyException("Dynamic cycle detected in recipe", circularity);
- }
return obj;
}
// execute the recipe
+ creating = true;
context.push(this);
try {
obj = internalCreate();
@@ -73,6 +77,7 @@
}
return obj;
} finally {
+ creating = false;
Recipe popped = context.pop();
if (popped != this) {
//noinspection ThrowFromFinallyBlock
@@ -120,6 +125,10 @@
public void destroy(Object instance) {
}
+ public List<Recipe> getConstructorDependencies() {
+ return Collections.emptyList();
+ }
+
public String toString() {
return getClass().getSimpleName() + "[" +
"name='" + name + '\'' +
Modified: geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/Recipe.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/Recipe.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/Recipe.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/main/java/org/apache/geronimo/blueprint/di/Recipe.java Thu Jul 30 21:12:29 2009
@@ -33,9 +33,19 @@
* @return the unique name for this recipe.
*/
String getName();
+
+ /**
+ * Get the list of constructor dependencies, i.e. explicit and
+ * argument dependencies. These dependencies must be satisfied
+ * before the an object can be created.
+ *
+ * @return a list of constructor dependencies
+ */
+ List<Recipe> getConstructorDependencies();
/**
- * Get the list of nested recipes, i.e. its dependencies.
+ * Get the list of nested recipes, i.e. all dependencies including
+ * constructor dependencies.
*
* @return a list of dependencies
*/
Modified: geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/WiringTest.java Thu Jul 30 21:12:29 2009
@@ -338,20 +338,11 @@
}
public void testCircular() throws Exception {
- ComponentDefinitionRegistryImpl registry = parse("/test-circular.xml");
- Repository repository = new TestBlueprintContainer(registry).getRepository();
+ BlueprintRepository repository = createBlueprintContainer().getRepository();
// this should pass (we allow circular dependencies for components without init method)
Object obj1 = repository.create("a");
-
-// // this should fail (we do not allow circular dependencies for components with init method)
-// try {
-// graph.create("c");
-// fail("Test should have thrown an exception caused by the circular reference");
-// } catch (Exception e) {
-// // ok
-// }
-
+
// test service and listener circular dependencies
Object obj2 = repository.create("service");
assertNotNull(obj2);
@@ -365,8 +356,7 @@
}
public void testCircularPrototype() throws Exception {
- ComponentDefinitionRegistryImpl registry = parse("/test-circular.xml");
- BlueprintRepository repository = new TestBlueprintContainer(registry).getRepository();
+ BlueprintRepository repository = createBlueprintContainer().getRepository();
PojoCircular driver1 = (PojoCircular) repository.create("circularPrototypeDriver");
@@ -385,8 +375,7 @@
}
public void testRecursive() throws Exception {
- ComponentDefinitionRegistryImpl registry = parse("/test-circular.xml");
- BlueprintRepository repository = new TestBlueprintContainer(registry).getRepository();
+ BlueprintRepository repository = createBlueprintContainer().getRepository();
try {
repository.create("recursiveConstructor", false);
@@ -424,4 +413,23 @@
}
}
}
+
+ public void testCircularBreaking() throws Exception {
+ BlueprintRepository repository;
+
+ repository = createBlueprintContainer().getRepository();
+ assertNotNull(repository.create("c1"));
+
+ repository = createBlueprintContainer().getRepository();
+ assertNotNull(repository.create("c2"));
+
+ repository = createBlueprintContainer().getRepository();
+ assertNotNull(repository.create("c3"));
+ }
+
+ private TestBlueprintContainer createBlueprintContainer() throws Exception {
+ ComponentDefinitionRegistryImpl registry = parse("/test-circular.xml");
+ return new TestBlueprintContainer(registry);
+ }
+
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoCircular.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoCircular.java?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoCircular.java (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/test/java/org/apache/geronimo/blueprint/pojos/PojoCircular.java Thu Jul 30 21:12:29 2009
@@ -22,6 +22,13 @@
private PojoCircular circular;
+ public PojoCircular() {
+ }
+
+ public PojoCircular(PojoCircular circular) {
+ this.circular = circular;
+ }
+
public PojoCircular getCircular() {
return circular;
}
Modified: geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-circular.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-circular.xml?rev=799440&r1=799439&r2=799440&view=diff
==============================================================================
--- geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-circular.xml (original)
+++ geronimo/sandbox/blueprint/blueprint-core/src/test/resources/test-circular.xml Thu Jul 30 21:12:29 2009
@@ -55,7 +55,7 @@
unregistration-method="unregister"/>
</service>
-
+ <!-- for prototype cycle tests -->
<bean id="circularPrototype" class="org.apache.geronimo.blueprint.pojos.PojoCircular" scope = "prototype">
<property name="circular" ref="circularPrototype"/>
@@ -64,9 +64,9 @@
<bean id="circularPrototypeDriver" class="org.apache.geronimo.blueprint.pojos.PojoCircular" scope = "prototype">
<property name="circular" ref="circularPrototypeDriver"/>
</bean>
-
-
-
+
+ <!-- for dynamic cycle tests (blueprintContainer.getComponentInstance()) -->
+
<bean id="recursiveConstructor" class="org.apache.geronimo.blueprint.pojos.PojoRecursive">
<argument ref="blueprintContainer"/>
<argument value="recursiveConstructor"/>
@@ -84,4 +84,18 @@
<argument value="recursiveInitMethod"/>
</bean>
+ <!-- for breaking dependency cycle tests -->
+
+ <bean id="c1" class="org.apache.geronimo.blueprint.pojos.PojoCircular">
+ <argument ref="c2"/>
+ </bean>
+
+ <bean id="c2" class="org.apache.geronimo.blueprint.pojos.PojoCircular">
+ <argument ref="c3"/>
+ </bean>
+
+ <bean id="c3" class="org.apache.geronimo.blueprint.pojos.PojoCircular">
+ <property name="circular" ref="c1"/>
+ </bean>
+
</blueprint>
\ No newline at end of file