/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 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.
* 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.container;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.wamblee.general.Pair;
+
import org.wamblee.system.core.AbstractComponent;
import org.wamblee.system.core.Component;
import org.wamblee.system.core.DefaultScope;
import org.wamblee.system.graph.component.ConnectRequiredExternallyRequiredEdgeFilter;
import org.wamblee.system.graph.component.ConnectRequiredProvidedEdgeFilter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
* Container consisting of multiple components.
*
* @author Erik Brakkee
*/
public class Container extends AbstractComponent<Scope> {
-
private static final Log LOG = LogFactory.getLog(Container.class);
private List<Component> components;
- private CompositeEdgeFilter edgeFilter;
+
+ private CompositeEdgeFilter edgeFilter;
+
private boolean sealed;
/**
* Required services by the container.
*/
public Container(String aName, Component[] aComponents,
- List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
+ List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
super(aName, aProvided, aRequired);
components = new ArrayList<Component>();
edgeFilter = new CompositeEdgeFilter();
sealed = false;
+
for (Component component : aComponents) {
addComponent(component);
}
}
-
+
/**
* Constructs the container
*
* Required services by the container.
*/
public Container(String aName, Component[] aComponents,
- ProvidedInterface[] aProvided, RequiredInterface[] aRequired) {
- this(aName, aComponents, Arrays.asList(aProvided), Arrays.asList(aRequired));
+ ProvidedInterface[] aProvided, RequiredInterface[] aRequired) {
+ this(aName, aComponents, Arrays.asList(aProvided), Arrays
+ .asList(aRequired));
}
+ /**
+ * Creates a new Container object.
+ *
+ */
public Container(String aName) {
this(aName, new Component[0], new ProvidedInterface[0],
- new RequiredInterface[0]);
+ new RequiredInterface[0]);
}
public Container addComponent(Component aComponent) {
checkSealed();
+
if (aComponent.getContext() != null) {
throw new SystemAssemblyException(
- "Inconsistent hierarchy, component '"
- + aComponent.getName()
- + "' is already part of another hierarchy");
+ "Inconsistent hierarchy, component '" + aComponent.getName() +
+ "' is already part of another hierarchy");
}
- if ( findComponent(aComponent.getName()) != null ) {
- throw new SystemAssemblyException("Duplicate component '"
- + aComponent.getName() + "'");
+
+ if (findComponent(aComponent.getName()) != null) {
+ throw new SystemAssemblyException("Duplicate component '" +
+ aComponent.getName() + "'");
}
+
components.add(aComponent);
aComponent.addContext(getQualifiedName());
+
return this;
}
-
+
/**
- * Explictly connects required and provided interfaces.
- * @param aClientComponent Client component, may not be null.
- * @param aRequiredInterface Required interface. If null it means all required interfaces.
- * @param aServerComponent Server component to connect to. If null, it means that no server components
- * may be connected to and the provider of the required interface will be null.
- * @param aProvidedInterface Provided interface. If null, it means that there is no restriction on the
- * name of the provided interface and that it is automatically selected.
+ * Explictly connects required and provided interfaces.
+ *
+ * @param aClientComponent
+ * Client component, may not be null.
+ * @param aRequiredInterface
+ * Required interface. If null it means all required interfaces.
+ * @param aServerComponent
+ * Server component to connect to. If null, it means that no
+ * server components may be connected to and the provider of the
+ * required interface will be null.
+ * @param aProvidedInterface
+ * Provided interface. If null, it means that there is no
+ * restriction on the name of the provided interface and that it
+ * is automatically selected.
+ *
*/
- public void connectRequiredProvided(String aClientComponent, String aRequiredInterface,
- String aServerComponent, String aProvidedInterface) {
+ public void connectRequiredProvided(String aClientComponent,
+ String aRequiredInterface, String aServerComponent,
+ String aProvidedInterface) {
checkSealed();
+
Component client = findComponent(aClientComponent);
Component server = findComponent(aServerComponent);
- if ( client == null ) {
- throw new SystemAssemblyException(getQualifiedName() + ": No component '" + aClientComponent + "' in the container");
+
+ if (client == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": No component '" + aClientComponent + "' in the container");
}
- if ( aRequiredInterface != null ) {
- if ( findInterface(client.getRequiredInterfaces(), aRequiredInterface) == null ) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aClientComponent + "' does not have a required interface named '"
- + aRequiredInterface + "'");
- }
+
+ if (aRequiredInterface != null) {
+ if (findInterface(client.getRequiredInterfaces(),
+ aRequiredInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aClientComponent +
+ "' does not have a required interface named '" +
+ aRequiredInterface + "'");
+ }
}
- if ( server == null ) {
- throw new SystemAssemblyException("No component '" + aClientComponent + "' in the container");
+
+ if (server == null) {
+ throw new SystemAssemblyException("No component '" +
+ aClientComponent + "' in the container");
}
- if ( aProvidedInterface != null ) {
- if ( findInterface(server.getProvidedInterfaces(), aProvidedInterface) == null) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aServerComponent + "' does not have a provided interface named '"
- + aProvidedInterface + "'");
- }
+
+ if (aProvidedInterface != null) {
+ if (findInterface(server.getProvidedInterfaces(),
+ aProvidedInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aServerComponent +
+ "' does not have a provided interface named '" +
+ aProvidedInterface + "'");
+ }
}
- edgeFilter.add(new ConnectRequiredProvidedEdgeFilter(aClientComponent, aRequiredInterface, aServerComponent, aProvidedInterface));
+
+ 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).
+ * 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) {
+ public void connectExternalRequired(String aComponent,
+ String aRequiredInterface, String aExternalRequiredInterface) {
checkSealed();
+
Component client = findComponent(aComponent);
- if ( client == null ) {
- throw new SystemAssemblyException(getQualifiedName() + ": No component '" + aComponent + "' in the container");
+
+ if (client == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": No component '" + aComponent + "' in the container");
}
- if ( aRequiredInterface != null ) {
- if ( findInterface(client.getRequiredInterfaces(), aRequiredInterface) == null ) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aComponent + "' does not have a required interface named '"
- + aRequiredInterface + "'");
- }
+
+ if (aRequiredInterface != null) {
+ if (findInterface(client.getRequiredInterfaces(),
+ aRequiredInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aComponent +
+ "' does not have a required interface named '" +
+ aRequiredInterface + "'");
+ }
}
- if ( aExternalRequiredInterface != null) {
- if ( findInterface(getRequiredInterfaces(), aExternalRequiredInterface) == null ) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": container does not have a required interface named '"
- + aExternalRequiredInterface + "'");
- }
+
+ if (aExternalRequiredInterface != null) {
+ if (findInterface(getRequiredInterfaces(),
+ aExternalRequiredInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": container does not have a required interface named '" +
+ aExternalRequiredInterface + "'");
+ }
}
+
edgeFilter.add(new ConnectRequiredExternallyRequiredEdgeFilter(
- aComponent, aRequiredInterface, aExternalRequiredInterface));
+ aComponent, aRequiredInterface, aExternalRequiredInterface));
}
-
- public void connectExternalProvided(String aExternalProvided, String aComponent, String aProvidedInterface) {
+
+ public void connectExternalProvided(String aExternalProvided,
+ String aComponent, String aProvidedInterface) {
checkSealed();
+
Component server = findComponent(aComponent);
-
-
- if ( server == null ) {
- throw new SystemAssemblyException("No component '" + aComponent + "' in the container");
+
+ if (server == null) {
+ throw new SystemAssemblyException("No component '" + aComponent +
+ "' in the container");
}
- if ( aProvidedInterface != null ) {
- if ( findInterface(server.getProvidedInterfaces(), aProvidedInterface) == null) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Component '" + aComponent + "' does not have a provided interface named '"
- + aProvidedInterface + "'");
- }
+
+ if (aProvidedInterface != null) {
+ if (findInterface(server.getProvidedInterfaces(),
+ aProvidedInterface) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Component '" + aComponent +
+ "' does not have a provided interface named '" +
+ aProvidedInterface + "'");
+ }
}
- if ( aExternalProvided != null ) {
- if ( findInterface(getProvidedInterfaces(), aExternalProvided) == null) {
- throw new SystemAssemblyException(
- getQualifiedName() + ": Container does not have a provided interface named '"
- + aExternalProvided + "'");
- }
+
+ if (aExternalProvided != null) {
+ if (findInterface(getProvidedInterfaces(), aExternalProvided) == null) {
+ throw new SystemAssemblyException(getQualifiedName() +
+ ": Container does not have a provided interface named '" +
+ aExternalProvided + "'");
+ }
}
- edgeFilter.add(new ConnectExternalProvidedProvidedFilter(aExternalProvided, aComponent, aProvidedInterface));
- }
+ edgeFilter.add(new ConnectExternalProvidedProvidedFilter(
+ aExternalProvided, aComponent, aProvidedInterface));
+ }
@Override
public Container addProvidedInterface(ProvidedInterface aProvided) {
checkSealed();
super.addProvidedInterface(aProvided);
+
return this;
}
public Container addRequiredInterface(RequiredInterface aRequired) {
checkSealed();
super.addRequiredInterface(aRequired);
+
return this;
}
@Override
public void addContext(String aContext) {
super.addContext(aContext);
+
for (Component component : components) {
component.addContext(aContext);
}
* services not in the required list and no services in the provided list
* that cannot be provided. Also logs a warning in case of superfluous
* requirements.
- *
- * @throws SystemAssemblyException
- * in case of any validation problems.
*/
public void validate() {
doStartOptionalDryRun(null, true);
*/
public Scope start() {
Scope scope = new DefaultScope(getProvidedInterfaces());
+
return super.start(scope);
}
@Override
protected Scope doStart(Scope aExternalScope) {
validate();
- Scope scope = new DefaultScope(getProvidedInterfaces().toArray(new ProvidedInterface[0]), aExternalScope);
+
+ Scope scope = new DefaultScope(getProvidedInterfaces().toArray(
+ new ProvidedInterface[0]), aExternalScope);
ComponentGraph graph = doStartOptionalDryRun(scope, false);
exposeProvidedInterfaces(graph, aExternalScope, scope);
seal();
+
return scope;
}
- private void exposeProvidedInterfaces(ComponentGraph aGraph, Scope aExternalScope,
- Scope aInternalScope) {
- for (Pair<ProvidedInterface,ProvidedInterface> mapping:
- aGraph.findExternalProvidedInterfaceMapping()) {
- Object svc = aInternalScope.getInterfaceImplementation(mapping.getSecond(), Object.class);
+ private void exposeProvidedInterfaces(ComponentGraph aGraph,
+ Scope aExternalScope, Scope aInternalScope) {
+ for (Pair<ProvidedInterface, ProvidedInterface> mapping : aGraph
+ .findExternalProvidedInterfaceMapping()) {
+ Object svc = aInternalScope.getInterfaceImplementation(mapping
+ .getSecond(), Object.class);
addInterface(mapping.getFirst(), svc, aExternalScope);
}
}
LOG.info("Starting '" + getQualifiedName() + "'");
List<Component> started = new ArrayList<Component>();
+
for (Component component : components) {
try {
// Start the service.
} catch (SystemAssemblyException e) {
throw e;
} catch (RuntimeException e) {
- LOG.error(getQualifiedName() + ": could not start '"
- + component.getQualifiedName() + "'", e);
+ LOG.error(getQualifiedName() + ": could not start '" +
+ component.getQualifiedName() + "'", e);
stopAlreadyStartedComponents(started, aScope);
throw e;
}
}
+
return graph;
}
private ComponentGraph createComponentGraph() {
ComponentGraph graph = new ComponentGraph();
+
for (RequiredInterface req : getRequiredInterfaces()) {
graph.addRequiredInterface(this, req);
}
+
for (Component comp : components) {
graph.addComponent(comp);
}
- for (ProvidedInterface prov: getProvidedInterfaces()) {
+
+ for (ProvidedInterface prov : getProvidedInterfaces()) {
graph.addProvidedInterface(this, prov);
}
graph.addEdgeFilter(edgeFilter);
+
return graph;
}
private void stopAlreadyStartedComponents(List<Component> aStarted,
- Scope aScope) {
+ Scope aScope) {
// an exception occurred, stop the successfully started
// components
for (int i = aStarted.size() - 1; i >= 0; i--) {
Component component = aStarted.get(i);
aStarted.get(i).stop(aScope.getRuntime(component));
} catch (Throwable t) {
- LOG.error(getQualifiedName() + ": error stopping "
- + aStarted.get(i).getQualifiedName());
+ LOG.error(getQualifiedName() + ": error stopping " +
+ aStarted.get(i).getQualifiedName());
}
}
}
throw new SystemAssemblyException("Container is sealed");
}
}
-
+
/**
- * Finds a component based on the non-qualified name of the component.
- * @param aName Component name.
- * @return Component or null if not found.
+ * Finds a component based on the non-qualified name of the component.
+ *
+ * @param aName
+ * Component name.
+ *
+ * @return Component or null if not found.
*/
- public Component findComponent(String aName) {
- for (Component<?> component: components) {
- if ( component.getName().equals(aName)) {
- return component;
- }
- }
- return null;
+ public Component findComponent(String aName) {
+ for (Component<?> component : components) {
+ if (component.getName().equals(aName)) {
+ return component;
+ }
+ }
+
+ return null;
}
-
- private static <T extends NamedInterface> T findInterface(List<T> aInterfaces, String aInterfaceName) {
- for (T intf: aInterfaces) {
- if ( intf.getName().equals(aInterfaceName)) {
- return intf;
- }
- }
- return null;
+
+ private static <T extends NamedInterface> T findInterface(
+ List<T> aInterfaces, String aInterfaceName) {
+ for (T intf : aInterfaces) {
+ if (intf.getName().equals(aInterfaceName)) {
+ return intf;
+ }
+ }
+
+ return null;
}
}