(no commit message)
[utils] / system / general / src / main / java / org / wamblee / system / graph / component / ComponentGraph.java
1 /*
2  * Copyright 2008 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */ 
16 package org.wamblee.system.graph.component;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.wamblee.general.Pair;
22 import org.wamblee.system.container.CompositeInterfaceRestriction;
23 import org.wamblee.system.container.InterfaceRestriction;
24 import org.wamblee.system.core.Component;
25 import org.wamblee.system.core.ProvidedInterface;
26 import org.wamblee.system.core.RequiredInterface;
27 import org.wamblee.system.graph.DefaultEdge;
28 import org.wamblee.system.graph.Edge;
29 import org.wamblee.system.graph.Graph;
30 import org.wamblee.system.graph.Node;
31
32
33 // TODO info superfluous required interfaces
34 // TODO check optional external required but mandatory internal.  
35
36 /**
37  * Represents a component graph and provides the bridge from the 
38  * component model to a graph model. The graph model is easier
39  * to work with to implement specific actions and validations than 
40  * the component model. 
41  */
42 public class ComponentGraph extends Graph {
43     
44     private CompositeInterfaceRestriction _restriction; 
45
46     /**
47      * Constructs an empty component graph. 
48      */
49     public ComponentGraph() { 
50         _restriction = new CompositeInterfaceRestriction(); 
51     }
52     
53     /**
54      * Adds a restriction that must be satisfied by the component model. 
55      * @param aRestriction Restriction. 
56      */
57     public void addRestriction(InterfaceRestriction aRestriction) { 
58         _restriction.add(aRestriction);
59     }
60     
61     /**
62      * Adds an externally required interface of a container.  
63      * This should be called before any components of the container are
64      * added. 
65      * @param aInterface Required interface. 
66      */
67     public void addRequiredInterface(RequiredInterface aInterface) { 
68         addNode(new ExternalRequiredInterfaceNode(aInterface));
69     }
70     
71     /**
72      * Adds an externally provided interface of a container.
73      * This should be called after all components of the container have been added.  
74      * @param aInterface Provided interface. 
75      */
76     public void addProvidedInterface(ProvidedInterface aInterface) { 
77         addNode(new ExternalProvidedInterfaceNode(aInterface));
78     }
79     
80     /**
81      * Validates the component graph. 
82      */
83     public void validate() { 
84         extend(new RequiredProvidedEdgeFactory());
85         accept(new ApplyRestrictionsVisitor(this, _restriction));
86         accept(new CheckRequiredProvidedMultiplicityVisitor(this));
87         accept(new CheckExternallyRequiredVisitor());
88         accept(new CheckExternallyProvidedVisitor(this));
89         accept(new CheckStartupDependenciesVisitor(this));
90     }
91     
92     /**
93      * Links provided and required interfaces together in the component
94      * model based on the graph model. 
95      */
96     public void link() { 
97         accept(new LinkVisitor());
98     }
99     
100     /**
101      * Finds a list of mappings of external provided interface to internal provided interface. 
102      * 
103      * @return List of pairs of external to internal interface. 
104      */
105     public List<Pair<ProvidedInterface, ProvidedInterface>> findExternalProvidedInterfaceMapping() { 
106         List<Pair<ProvidedInterface, ProvidedInterface>> result = 
107             new ArrayList<Pair<ProvidedInterface,ProvidedInterface>>(); 
108         for (Edge edge: getEdges()) { 
109             if ( edge.getFrom() instanceof ExternalProvidedInterfaceNode  && 
110                     edge.getTo() instanceof ProvidedInterfaceNode ) { 
111                 result.add(new Pair<ProvidedInterface,ProvidedInterface>(
112                         ((ExternalProvidedInterfaceNode)edge.getFrom()).getProvided(), 
113                         ((ProvidedInterfaceNode)edge.getTo()).getProvided()
114                         )); 
115             }
116         }
117         return result; 
118     }
119     
120     /**
121      * Adds a component by adding required interfaces, components, and
122      * provided interfaces. 
123      * @param aComponent Component to add. 
124      */
125     public void addComponent(Component aComponent) { 
126         // Add required interfaces. 
127         Node compNode = new ComponentNode(aComponent);
128         List<Node> requiredNodes = new ArrayList<Node>();
129         for (RequiredInterface required: aComponent.getRequiredInterfaces()) { 
130             Node reqNode = new RequiredInterfaceNode(aComponent, required); 
131             addNode(reqNode);
132             requiredNodes.add(reqNode);
133         }
134         // Add the component
135         addNode(compNode);
136      
137         // Edges from component to required interface. 
138         for (Node reqNode: requiredNodes) { 
139             addEdge(new DefaultEdge(compNode, reqNode));
140         }
141         
142         // Add provided interfaces
143         List<Node> providedNodes = new ArrayList<Node>();
144         for (ProvidedInterface provided: aComponent.getProvidedInterfaces()) { 
145             Node provNode = new ProvidedInterfaceNode(aComponent, provided); 
146             addNode(provNode);
147             providedNodes.add(provNode);
148         }
149         
150         // Edges from provided interface to component
151         for (Node provNode: providedNodes) { 
152             addEdge(new DefaultEdge(provNode, compNode));
153         }
154     }
155 }