/* * 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 java.util.ArrayList; import java.util.List; 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; /** * 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 { private CompositeEdgeFilter _edgeFilter; /** * Constructs an empty component graph. */ public ComponentGraph() { _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() { accept(new LinkVisitor()); } /** * 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)); } } public void addEdgeFilter(CompositeEdgeFilter aEdgeFilter) { _edgeFilter.add(aEdgeFilter); } }