(no commit message)
authorerik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Sun, 18 May 2008 08:34:02 +0000 (08:34 +0000)
committererik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Sun, 18 May 2008 08:34:02 +0000 (08:34 +0000)
system/general/src/main/java/org/wamblee/system/container/Container.java
system/general/src/main/java/org/wamblee/system/graph/component/CheckExternallyRequiredVisitor.java
system/general/src/main/java/org/wamblee/system/graph/component/CheckRequiredProvidedMultiplicityVisitor.java
system/general/src/main/java/org/wamblee/system/graph/component/ComponentGraph.java
system/general/src/main/java/org/wamblee/system/graph/component/ExternalProvidedInterfaceNode.java
system/general/src/main/java/org/wamblee/system/graph/component/ExternalRequiredInterfaceNode.java
system/general/src/test/java/org/wamblee/system/container/ContainerTest.java

index cfc5b8aa140ad34fe11a65d06c009e4afe288da9..92aba2144c3286f49ef0554fa5b537b6acf9e1b3 100644 (file)
@@ -224,13 +224,13 @@ public class Container extends AbstractComponent<Scope> {
     private ComponentGraph createComponentGraph() {
         ComponentGraph graph = new ComponentGraph();
         for (RequiredInterface req : getRequiredInterfaces()) {
-            graph.addRequiredInterface(req);
+            graph.addRequiredInterface(this, req);
         }
         for (Component comp : _components) {
             graph.addComponent(comp);
         }
         for (ProvidedInterface prov: getProvidedInterfaces()) { 
-            graph.addProvidedInterface(prov);
+            graph.addProvidedInterface(this, prov);
         }
 
         graph.addRestriction(_restriction);
index 9e412b6fdbacbb5b3f4e8de6cb4feb1e63bea8b9..1ce53d0732e4de4d67f35785ed04604781c71215 100644 (file)
  * 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.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.wamblee.system.core.SystemAssemblyException;
 import org.wamblee.system.graph.Edge;
+import org.wamblee.system.graph.Graph;
 import org.wamblee.system.graph.Node;
 import org.wamblee.system.graph.Visitor;
 
 /**
  * Visitor that checks whether all required external interfaces of the container
- * are provided. 
+ * are provided.
+ * 
  * @author Erik Brakkee
- *
+ * 
  */
 public class CheckExternallyRequiredVisitor implements Visitor {
-    
-    public CheckExternallyRequiredVisitor() { 
-        // Empty.
+
+    private Log LOG = LogFactory.getLog(CheckExternallyRequiredVisitor.class);
+
+    private Graph _graph;
+
+    public CheckExternallyRequiredVisitor(Graph aGraph) {
+        _graph = aGraph;
     }
 
     @Override
@@ -39,10 +49,30 @@ public class CheckExternallyRequiredVisitor implements Visitor {
 
     @Override
     public void visitNode(Node aNode) {
-        if ( aNode instanceof ExternalRequiredInterfaceNode) { 
-            ExternalRequiredInterfaceNode required = (ExternalRequiredInterfaceNode) aNode; 
-            if ( !required.getRequired().isOptional() && required.getRequired().getProvider() == null) { 
-                throw new SystemAssemblyException(aNode + ": External required interface is not provided");
+        if (aNode instanceof ExternalRequiredInterfaceNode) {
+            ExternalRequiredInterfaceNode required = (ExternalRequiredInterfaceNode) aNode;
+            if (!required.getRequired().isOptional()
+                    && required.getRequired().getProvider() == null) {
+                throw new SystemAssemblyException(aNode
+                        + ": External required interface is not provided");
+            }
+
+            List<Edge> edges = _graph.findIncoming(aNode);
+
+            if (edges.isEmpty()) {
+                LOG.warn(aNode + ": Superfluous required interface");
+            }
+            for (Edge edge : edges) {
+                Node from = edge.getFrom();
+                assert from instanceof RequiredInterfaceNode;
+                RequiredInterfaceNode reqNode = (RequiredInterfaceNode)from;
+                if (!reqNode.getRequired().isOptional()
+                        && required.getRequired().isOptional()) {
+                    throw new SystemAssemblyException(
+                            aNode
+                                    + ": externally required interface is optional but a corresponding internal required interface is mandatory: "
+                                    + reqNode);
+                }
             }
         }
     }
index 526b8923e02e8cd7ca6e8e92792faefa3ca3a942..608dfc16dff4714f39c9fb3ab0c9e58f2de88797 100644 (file)
@@ -55,14 +55,14 @@ public class CheckRequiredProvidedMultiplicityVisitor implements Visitor {
             RequiredInterfaceNode required = (RequiredInterfaceNode) aNode;
             List<Edge> edges = _graph.findOutgoing(aNode);
             if (edges.size() > 1) {
-                createDuplicateException("Multiple internal providers of interface found", aNode, edges);
+                createDuplicateException("Multiple providers of required interface found", aNode, edges);
             }
             if (edges.size() == 0 && !required.getRequired().isOptional()) {
                 throw new SystemAssemblyException(
                         aNode
                                 + ": mandatpory required interface not provided by other components started earlier");
             }
-        } else if ( aNode instanceof ProvidedInterfaceNode) { 
+        } else if ( aNode instanceof ExternalProvidedInterfaceNode) { 
             List<Edge> edges = _graph.findOutgoing(aNode); 
             if ( edges.size() > 1) { 
                 createDuplicateException("multiple internal matches for externally provided interface", aNode, edges);
index 15f86557ab2a55dccdec85b2d8604d6b3bfcc07a..be861f309255da4deb64ed63cd12e63f15ab56da 100644 (file)
@@ -29,10 +29,6 @@ import org.wamblee.system.graph.Edge;
 import org.wamblee.system.graph.Graph;
 import org.wamblee.system.graph.Node;
 
-
-// TODO info superfluous required interfaces
-// TODO check optional external required but mandatory internal.  
-
 /**
  * Represents a component graph and provides the bridge from the 
  * component model to a graph model. The graph model is easier
@@ -46,7 +42,7 @@ public class ComponentGraph extends Graph {
     /**
      * Constructs an empty component graph. 
      */
-    public ComponentGraph() { 
+    public ComponentGraph() {
         _restriction = new CompositeInterfaceRestriction(); 
     }
     
@@ -62,19 +58,21 @@ public class ComponentGraph extends Graph {
      * 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(RequiredInterface aInterface) { 
-        addNode(new ExternalRequiredInterfaceNode(aInterface));
+    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.  
+     * 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(ProvidedInterface aInterface) { 
-        addNode(new ExternalProvidedInterfaceNode(aInterface));
+    public void addProvidedInterface(Component aComponent, ProvidedInterface aInterface) { 
+        addNode(new ExternalProvidedInterfaceNode(aComponent, aInterface));
     }
     
     /**
@@ -84,7 +82,7 @@ public class ComponentGraph extends Graph {
         extend(new RequiredProvidedEdgeFactory());
         accept(new ApplyRestrictionsVisitor(this, _restriction));
         accept(new CheckRequiredProvidedMultiplicityVisitor(this));
-        accept(new CheckExternallyRequiredVisitor());
+        accept(new CheckExternallyRequiredVisitor(this)); 
         accept(new CheckExternallyProvidedVisitor(this));
         accept(new CheckStartupDependenciesVisitor(this));
     }
index 388012709538d607b99c8fb9e4702e55fb21a439..9f91447cd8f2ba54e5688f07829fb09a93c7a30f 100644 (file)
@@ -15,6 +15,7 @@
  */ 
 package org.wamblee.system.graph.component;
 
+import org.wamblee.system.core.Component;
 import org.wamblee.system.core.ProvidedInterface;
 import org.wamblee.system.graph.Node;
 
@@ -25,9 +26,11 @@ import org.wamblee.system.graph.Node;
  */
 public class ExternalProvidedInterfaceNode implements Node {
 
+    private Component _component; 
     private ProvidedInterface _provided; 
     
-    public ExternalProvidedInterfaceNode(ProvidedInterface aProvided) { 
+    public ExternalProvidedInterfaceNode(Component aComponent, ProvidedInterface aProvided) {
+        _component = aComponent; 
         _provided = aProvided; 
     }
     
@@ -36,6 +39,10 @@ public class ExternalProvidedInterfaceNode implements Node {
         return _provided.getName(); 
     }
     
+    public Component getComponent() {
+        return _component;
+    }
+    
     public ProvidedInterface getProvided() {
         return _provided;
     }
index 3b195a65742089d837680640ddcc89e2383dba10..5c65ebdb5e1985ebecafeaed88342bb762ba81b3 100644 (file)
@@ -15,6 +15,7 @@
  */ 
 package org.wamblee.system.graph.component;
 
+import org.wamblee.system.core.Component;
 import org.wamblee.system.core.RequiredInterface;
 import org.wamblee.system.graph.Node;
 
@@ -25,9 +26,11 @@ import org.wamblee.system.graph.Node;
  */
 public class ExternalRequiredInterfaceNode implements Node {
     
+    private Component _component;
     private RequiredInterface _required; 
 
-    public ExternalRequiredInterfaceNode(RequiredInterface aRequired) { 
+    public ExternalRequiredInterfaceNode(Component aComponent, RequiredInterface aRequired) {
+        _component = aComponent; 
         _required = aRequired; 
     }
     
@@ -36,12 +39,16 @@ public class ExternalRequiredInterfaceNode implements Node {
         return _required.getName(); 
     }
     
+    public Component getComponent() {
+        return _component;
+    }
+    
     public RequiredInterface getRequired() {
         return _required;
     }
     
     @Override
     public String toString() {
-        return "EXTERNAL" + ":" + _required;
+        return _component.getQualifiedName() + ":" + _required;
     }
 }
index 95d7e312f0d77ced6cc3c9eceba0d41885d7bee7..5908a85e30c029eb60e5f5579138b5cb1e3037fd 100644 (file)
@@ -398,15 +398,12 @@ public class ContainerTest extends TestCase {
                 .getProvidedInterfaces()[0]);
         container.getRequiredInterfaces()[1].setProvider(env
                 .getProvidedInterfaces()[1]);
-        container.start();
-        assertSame(env.getProvidedInterfaces()[0], container
-                .getRequiredInterfaces()[0].getProvider());
-        assertSame(env.getProvidedInterfaces()[1], container
-                .getRequiredInterfaces()[1].getProvider());
-        assertSame(env.getProvidedInterfaces()[0], application
-                .getRequiredInterfaces()[0].getProvider());
-        assertSame(env.getProvidedInterfaces()[1], application
-                .getRequiredInterfaces()[1].getProvider());
+        try {
+            container.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
     }
 
     public void testSealed() {
@@ -521,9 +518,9 @@ public class ContainerTest extends TestCase {
         top.addComponent(envcontainer).addComponent(appcontainer);
 
         top.start();
-        AssertionUtils.assertEquals(new String[] { "start.environment", "start.application" },
-                _tracker.getEvents(Thread.currentThread()).toArray(
-                        new String[0]));
+        AssertionUtils.assertEquals(new String[] { "start.environment",
+                "start.application" }, _tracker.getEvents(
+                Thread.currentThread()).toArray(new String[0]));
 
     }
 }