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);
* 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
@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);
+ }
}
}
}
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);
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
/**
* Constructs an empty component graph.
*/
- public ComponentGraph() {
+ public ComponentGraph() {
_restriction = new CompositeInterfaceRestriction();
}
* 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));
}
/**
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));
}
*/
package org.wamblee.system.graph.component;
+import org.wamblee.system.core.Component;
import org.wamblee.system.core.ProvidedInterface;
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;
}
return _provided.getName();
}
+ public Component getComponent() {
+ return _component;
+ }
+
public ProvidedInterface getProvided() {
return _provided;
}
*/
package org.wamblee.system.graph.component;
+import org.wamblee.system.core.Component;
import org.wamblee.system.core.RequiredInterface;
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;
}
return _required.getName();
}
+ public Component getComponent() {
+ return _component;
+ }
+
public RequiredInterface getRequired() {
return _required;
}
@Override
public String toString() {
- return "EXTERNAL" + ":" + _required;
+ return _component.getQualifiedName() + ":" + _required;
}
}
.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() {
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]));
}
}