(no commit message)
[utils] / system / general / src / main / java / org / wamblee / system / graph / component / CheckRequiredProvidedMultiplicityVisitor.java
1 /*
2  * Copyright 2005-2010 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 org.wamblee.system.core.SystemAssemblyException;
19 import org.wamblee.system.graph.Edge;
20 import org.wamblee.system.graph.Graph;
21 import org.wamblee.system.graph.Node;
22 import org.wamblee.system.graph.Visitor;
23
24 import java.util.List;
25
26 /**
27  * Visitor that checks whether required and provided interfaces are matched
28  * appropriately:
29  * <ul>
30  * <li>Each required interface is connected to at most one provided interface</li>
31  * <li>Required interfaces that are not optional must be connected to precisely
32  * one provided interface</li>
33  * </ul>
34  * 
35  * @author Erik Brakkee
36  */
37 public class CheckRequiredProvidedMultiplicityVisitor implements Visitor {
38     private Graph graph;
39
40     /**
41      * Creates a new CheckRequiredProvidedMultiplicityVisitor object.
42      * 
43      */
44     public CheckRequiredProvidedMultiplicityVisitor(Graph aGraph) {
45         graph = aGraph;
46     }
47
48     @Override
49     public void visitEdge(Edge aEdge) {
50         // Empty
51     }
52
53     @Override
54     public void visitNode(Node aNode) {
55         if (aNode instanceof RequiredInterfaceNode) {
56             RequiredInterfaceNode required = (RequiredInterfaceNode) aNode;
57             List<Edge> edges = graph.findOutgoing(aNode);
58
59             if (edges.size() > 1) {
60                 createDuplicateException(
61                     "Multiple providers of required interface found", aNode,
62                     edges);
63             }
64
65             if ((edges.size() == 0) && !required.getRequired().isOptional()) {
66                 throw new SystemAssemblyException(
67                     aNode +
68                         ": mandatpory required interface not provided by other components started earlier");
69             }
70         } else if (aNode instanceof ExternalProvidedInterfaceNode) {
71             List<Edge> edges = graph.findOutgoing(aNode);
72
73             if (edges.size() > 1) {
74                 createDuplicateException(
75                     "multiple internal matches for externally provided interface",
76                     aNode, edges);
77             }
78
79             if (edges.size() == 0) {
80                 throw new SystemAssemblyException(aNode +
81                     ": external provided interface is not provided internally");
82             }
83         }
84     }
85
86     private void createDuplicateException(String aMsg, Node aNode,
87         List<Edge> aEdges) {
88         StringBuffer buf = new StringBuffer();
89         buf.append(aNode + ": " + aMsg + ": ");
90
91         for (Edge edge : aEdges) {
92             buf.append(edge.getTo() + "/ ");
93         }
94
95         throw new SystemAssemblyException(buf.toString());
96     }
97 }