use of org.apache.aries.blueprint.di.Recipe in project aries by apache.
the class BlueprintRepository method createInstances.
private Map<String, Object> createInstances(Collection<String> names) {
// Instance creation is synchronized inside each create method (via the use of futures), so that
// a recipe will only created once where appropriate
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();
ComponentMetadata component = blueprintContainer.getComponentDefinitionRegistry().getComponentDefinition(name);
boolean prototype = (component instanceof BeanMetadata) && MetadataUtil.isPrototypeScope((BeanMetadata) component);
if (!prototype || names.contains(name)) {
objects.put(name, entry.getValue().create());
}
}
return objects;
}
use of org.apache.aries.blueprint.di.Recipe in project aries by apache.
the class BlueprintRepository method validate.
public void validate() {
for (Recipe recipe : getAllRecipes()) {
// Check that references are satisfied
String ref = null;
if (recipe instanceof RefRecipe) {
ref = ((RefRecipe) recipe).getIdRef();
} else if (recipe instanceof IdRefRecipe) {
ref = ((IdRefRecipe) recipe).getIdRef();
}
if (ref != null && getRecipe(ref) == null) {
throw new ComponentDefinitionException("Unresolved ref/idref to component: " + ref);
}
// Check service
if (recipe instanceof ServiceRecipe) {
Recipe r = ((ServiceRecipe) recipe).getServiceRecipe();
if (r instanceof RefRecipe) {
r = getRecipe(((RefRecipe) r).getIdRef());
}
if (r instanceof ServiceRecipe) {
throw new ComponentDefinitionException("The target for a <service> element must not be <service> element");
}
if (r instanceof ReferenceListRecipe) {
throw new ComponentDefinitionException("The target for a <service> element must not be <reference-list> element");
}
CollectionRecipe listeners = ((ServiceRecipe) recipe).getListenersRecipe();
for (Recipe lr : listeners.getDependencies()) {
// The listener recipe is a bean recipe with the listener being set in a property
for (Recipe l : lr.getDependencies()) {
if (l instanceof RefRecipe) {
l = getRecipe(((RefRecipe) l).getIdRef());
}
if (l instanceof ServiceRecipe) {
throw new ComponentDefinitionException("The target for a <registration-listener> element must not be <service> element");
}
if (l instanceof ReferenceListRecipe) {
throw new ComponentDefinitionException("The target for a <registration-listener> element must not be <reference-list> element");
}
}
}
}
// Check references
if (recipe instanceof AbstractServiceReferenceRecipe) {
CollectionRecipe listeners = ((AbstractServiceReferenceRecipe) recipe).getListenersRecipe();
for (Recipe lr : listeners.getDependencies()) {
// The listener recipe is a bean recipe with the listener being set in a property
for (Recipe l : lr.getDependencies()) {
if (l instanceof RefRecipe) {
l = getRecipe(((RefRecipe) l).getIdRef());
}
if (l instanceof ServiceRecipe) {
throw new ComponentDefinitionException("The target for a <reference-listener> element must not be <service> element");
}
if (l instanceof ReferenceListRecipe) {
throw new ComponentDefinitionException("The target for a <reference-listener> element must not be <reference-list> element");
}
}
}
}
}
}
use of org.apache.aries.blueprint.di.Recipe in project aries by apache.
the class DependencyGraph method createNode.
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;
}
use of org.apache.aries.blueprint.di.Recipe in project aries by apache.
the class DependencyGraph method getSortedRecipes.
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) {
// 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);
}
}
}
// 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;
}
use of org.apache.aries.blueprint.di.Recipe in project aries by apache.
the class DependencyGraph method findCircuit.
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);
}
}
Aggregations