/* * Copyright 2008 the original author or authors. * * Licensed 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.wamblee.system.graph.component; import org.wamblee.general.Pair; import org.wamblee.system.core.Component; import org.wamblee.system.core.ProvidedInterface; import org.wamblee.system.core.RequiredInterface; import org.wamblee.system.graph.CompositeEdgeFilter; import org.wamblee.system.graph.DefaultEdge; import org.wamblee.system.graph.Edge; import org.wamblee.system.graph.Graph; import org.wamblee.system.graph.Node; import java.util.ArrayList; import java.util.List; /** * Represents a component graph and provides the bridge from the component * model to a graph model. The graph model is easier to work with to implement * specific actions and validations than the component model. */ public class ComponentGraph extends Graph { /** * DOCUMENT ME! */ private boolean isLinked; /** * DOCUMENT ME! */ private CompositeEdgeFilter edgeFilter; /** * Constructs an empty component graph. */ public ComponentGraph() { isLinked = false; edgeFilter = new CompositeEdgeFilter(); } /** * Adds an externally required interface of a container. This * should be called before any components of the container are added. * * @param aComponent Component requiring the interface. * @param aInterface Required interface. */ public void addRequiredInterface(Component aComponent, RequiredInterface aInterface) { addNode(new ExternalRequiredInterfaceNode(aComponent, aInterface)); } /** * Adds an externally provided interface of a container. This * should be called after all components of the container have been added. * * @param aComponent Component providing the interface. * @param aInterface Provided interface. */ public void addProvidedInterface(Component aComponent, ProvidedInterface aInterface) { addNode(new ExternalProvidedInterfaceNode(aComponent, aInterface)); } /** * Validates the component graph. */ public void validate() { extend(new RequiredProvidedEdgeFactory()); applyFilter(edgeFilter); accept(new CheckRequiredProvidedMultiplicityVisitor(this)); accept(new CheckExternallyRequiredVisitor(this)); accept(new CheckExternallyProvidedVisitor(this)); accept(new CheckStartupDependenciesVisitor(this)); } /** * Links provided and required interfaces together in the component * model based on the graph model. */ public void link() { if (isLinked) { return; } accept(new LinkVisitor()); isLinked = true; } /** * Finds a list of mappings of external provided interface to * internal provided interface. * * @return List of pairs of external to internal interface. */ public List> findExternalProvidedInterfaceMapping() { List> result = new ArrayList>(); for (Edge edge : getEdges()) { if (edge.getFrom() instanceof ExternalProvidedInterfaceNode && edge.getTo() instanceof ProvidedInterfaceNode) { result.add(new Pair( ((ExternalProvidedInterfaceNode) edge.getFrom()) .getProvided(), ((ProvidedInterfaceNode) edge.getTo()).getProvided())); } } return result; } /** * Adds a component by adding required interfaces, components, and * provided interfaces. * * @param aComponent Component to add. */ public void addComponent(Component aComponent) { // Add required interfaces. Node compNode = new ComponentNode(aComponent); List requiredNodes = new ArrayList(); for (RequiredInterface required : aComponent.getRequiredInterfaces()) { Node reqNode = new RequiredInterfaceNode(aComponent, required); addNode(reqNode); requiredNodes.add(reqNode); } // Add the component addNode(compNode); // Edges from component to required interface. for (Node reqNode : requiredNodes) { addEdge(new DefaultEdge(compNode, reqNode)); } // Add provided interfaces List providedNodes = new ArrayList(); for (ProvidedInterface provided : aComponent.getProvidedInterfaces()) { Node provNode = new ProvidedInterfaceNode(aComponent, provided); addNode(provNode); providedNodes.add(provNode); } // Edges from provided interface to component for (Node provNode : providedNodes) { addEdge(new DefaultEdge(provNode, compNode)); } } /** * DOCUMENT ME! * * @param aEdgeFilter DOCUMENT ME! */ public void addEdgeFilter(CompositeEdgeFilter aEdgeFilter) { edgeFilter.add(aEdgeFilter); } }