added explicit linking of required to externally required interfaces.
authorerik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Sun, 18 May 2008 20:59:54 +0000 (20:59 +0000)
committererik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Sun, 18 May 2008 20:59:54 +0000 (20:59 +0000)
system/general/src/main/java/org/wamblee/system/container/Container.java
system/general/src/main/java/org/wamblee/system/graph/component/ConnectRequiredExternallyRequiredEdgeFilter.java [new file with mode: 0644]
system/general/src/test/java/org/wamblee/system/container/ContainerTest.java
system/general/src/test/java/org/wamblee/system/graph/component/ConnectRequiredExternallyRequiredEdgeFilterTest.java [new file with mode: 0644]

index 59067f974f2835d6980078ab8b240a518e628d58..dc45dd7d0ef7e1f5d70fd7fecf3cc2abbe1dd4fb 100644 (file)
@@ -33,6 +33,7 @@ import org.wamblee.system.core.SystemAssemblyException;
 import org.wamblee.system.graph.CompositeEdgeFilter;
 import org.wamblee.system.graph.EdgeFilter;
 import org.wamblee.system.graph.component.ComponentGraph;
+import org.wamblee.system.graph.component.ConnectRequiredExternallyRequiredEdgeFilter;
 import org.wamblee.system.graph.component.ConnectRequiredProvidedEdgeFilter;
 import org.wamblee.system.graph.component.RequiredProvidedEdgeFactory;
 
@@ -113,11 +114,17 @@ public class Container extends AbstractComponent<Scope> {
         _edgeFilter.add(new ConnectRequiredProvidedEdgeFilter(aClientComponent, aRequiredInterface, aServerComponent, aProvidedInterface));
     }
     
+    /**
+     * Explicitly connects a externally required interface to an internally required interface. 
+     * @param aComponent Component requiring the interface (must be non-null). 
+     * @param aRequiredInterface Required interface of the component (must be non-null).
+     * @param aExternalRequiredInterface Externally required interface (must be non-null).
+     */
     public void connectExternalRequired(String aComponent, String aRequiredInterface, 
             String aExternalRequiredInterface) {
         checkSealed();
-        // TODO implement. 
-        throw new RuntimeException("not implemented");
+        _edgeFilter.add(new ConnectRequiredExternallyRequiredEdgeFilter(
+                aComponent, aRequiredInterface, aExternalRequiredInterface));
     }
     
     public void connectExternalProvided(String aExternalProvided, String aComponent, String aProvidedInterface) {
diff --git a/system/general/src/main/java/org/wamblee/system/graph/component/ConnectRequiredExternallyRequiredEdgeFilter.java b/system/general/src/main/java/org/wamblee/system/graph/component/ConnectRequiredExternallyRequiredEdgeFilter.java
new file mode 100644 (file)
index 0000000..598608c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.system.graph.Edge;
+import org.wamblee.system.graph.EdgeFilter;
+import org.wamblee.system.graph.EdgeSelector;
+import org.wamblee.system.graph.Node;
+
+/**
+ * Filter used to explicitly connect required and provided interfaces within a
+ * container.
+ * 
+ * @author Erik Brakkee
+ * 
+ */
+public class ConnectRequiredExternallyRequiredEdgeFilter implements EdgeFilter {
+
+    private String _client;
+    private String _required;
+    private String _externalRequired;
+
+    public ConnectRequiredExternallyRequiredEdgeFilter(String aClient, String aRequired,
+            String aExternalRequired) {
+        _client = aClient;
+        _required = aRequired;
+        _externalRequired = aExternalRequired; 
+        if ( _client == null ) { 
+            throw new IllegalArgumentException("Client component must be specified"); 
+        }
+        if ( _required == null ) { 
+            throw new IllegalArgumentException("Required interface must be specified");
+        }
+        if ( _externalRequired == null ) { 
+            throw new IllegalArgumentException("External required interface must be specified");
+        }
+    }
+
+    @Override
+    public boolean isViolated(Edge aEdge) {
+        if (aEdge.getFrom() instanceof RequiredInterfaceNode
+                && aEdge.getTo() instanceof ExternalRequiredInterfaceNode) {
+            return isViolated((RequiredInterfaceNode) aEdge.getFrom(),
+                    (ExternalRequiredInterfaceNode) aEdge.getTo());
+        }
+        return false;
+    }
+
+    private boolean isViolated(RequiredInterfaceNode aFrom,
+            ExternalRequiredInterfaceNode aTo) {
+        if ( !aFrom.getComponent().getName().equals(_client)) { 
+            return false; // wrong component. 
+        }
+        if ( !(_required == null || aFrom.getRequired().getName().equals(_required))) { 
+            return false; // wrong interface
+        }
+        if ( !aTo.getRequired().getName().equals(_externalRequired)) { 
+            return true; // wrong externally required interface.  
+        }
+      
+        return false; 
+    }
+}
index c4f64ba88eee53a6651bb1b7b0ee46c2cfa31e65..156d4dd6f4222c6748d414287d9a4d71c7d87c1c 100644 (file)
@@ -527,4 +527,44 @@ public class ContainerTest extends TestCase {
                 Thread.currentThread()).toArray(new String[0]));
 
     }
+    
+    public void testNonUniqueRequiredInterface() { 
+        final Container container = new Container("top");
+        container.addRequiredInterface(new DefaultRequiredInterface("i", Integer.class));
+        container.addRequiredInterface(new DefaultRequiredInterface("x", String.class));
+        container.addRequiredInterface(new DefaultRequiredInterface("y", String.class));
+        
+        Application app = new Application("1");
+        container.addComponent(app);
+
+    
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() { 
+            @Override
+            public void run() throws Exception {
+                container.start();                
+            }
+        }, SystemAssemblyException.class);
+           
+        container.connectExternalRequired("1", app.getRequiredInterfaces()[0].getName(), 
+                "y");
+        
+        ProvidedInterface i = new DefaultProvidedInterface("i", Integer.class);
+        ProvidedInterface x = new DefaultProvidedInterface("x", String.class);
+        ProvidedInterface y = new DefaultProvidedInterface("y", String.class);
+    
+        Scope externalScope = new DefaultScope(new ProvidedInterface[0]);
+        
+        externalScope.publishInterface(i, 100);
+        externalScope.publishInterface(x, "x-value");
+        externalScope.publishInterface(y, "y-value");
+        
+        container.getRequiredInterfaces()[0].setProvider(i);
+        container.getRequiredInterfaces()[1].setProvider(x);
+        container.getRequiredInterfaces()[2].setProvider(y);
+        
+        Scope runtime = container.start(externalScope);
+        
+        assertEquals("y-value", app.getString());
+        
+    }
 }
diff --git a/system/general/src/test/java/org/wamblee/system/graph/component/ConnectRequiredExternallyRequiredEdgeFilterTest.java b/system/general/src/test/java/org/wamblee/system/graph/component/ConnectRequiredExternallyRequiredEdgeFilterTest.java
new file mode 100644 (file)
index 0000000..3fd7c61
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.system.container.Application;
+import org.wamblee.system.container.Container;
+import org.wamblee.system.core.Component;
+import org.wamblee.system.core.DefaultRequiredInterface;
+import org.wamblee.system.core.RequiredInterface;
+import org.wamblee.system.graph.DefaultEdge;
+import org.wamblee.system.graph.DefaultNode;
+import org.wamblee.system.graph.Edge;
+import org.wamblee.system.graph.EdgeFilter;
+import org.wamblee.system.graph.Node;
+
+import junit.framework.TestCase;
+
+public class ConnectRequiredExternallyRequiredEdgeFilterTest extends TestCase {
+
+    private Component _comp;
+    private Container _container;
+    private Edge _edge;
+
+    @Override
+    protected void setUp() throws Exception {
+        _comp = new Application();
+        _container = new Container("container")
+                .addRequiredInterface(new DefaultRequiredInterface("x",
+                        String.class));
+        Node req = new RequiredInterfaceNode(_comp, _comp
+                .getRequiredInterfaces()[0]);
+        Node external = new ExternalRequiredInterfaceNode(_container,
+                _container.getRequiredInterfaces()[0]);
+        _edge = new DefaultEdge(req, external);
+    }
+
+    public void testRightComponentRightInterface() {
+        EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
+                _comp.getName(), _comp.getRequiredInterfaces()[0].getName(),
+                _container.getRequiredInterfaces()[0].getName());
+        assertFalse(filter.isViolated(_edge));
+    }
+
+    public void testWrongInterface() {
+        EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
+                _comp.getName(), _comp.getRequiredInterfaces()[0].getName()
+                        + "xx", _container.getRequiredInterfaces()[0].getName());
+        assertFalse(filter.isViolated(_edge));
+    }
+
+    public void testWrongComponent() {
+        EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
+                _comp.getName() + "xx", _comp.getRequiredInterfaces()[0]
+                        .getName(), _container.getRequiredInterfaces()[0]
+                        .getName());
+        assertFalse(filter.isViolated(_edge));
+    }
+
+    public void testWrongExternalInterface() {
+        EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
+                _comp.getName(), _comp.getRequiredInterfaces()[0].getName(),
+                _container.getRequiredInterfaces()[0].getName() + "xx");
+        assertTrue(filter.isViolated(_edge));
+    }
+
+    public void testWrongEdgeType() {
+        DefaultEdge edge = new DefaultEdge(new DefaultNode("x"),
+                new DefaultNode("y"));
+        EdgeFilter filter = new ConnectRequiredExternallyRequiredEdgeFilter(
+                _comp.getName(), _comp.getRequiredInterfaces()[0].getName(),
+                _container.getRequiredInterfaces()[0].getName());
+        assertFalse(filter.isViolated(edge));
+    }
+}