From: erik Date: Fri, 11 Apr 2008 20:36:14 +0000 (+0000) Subject: (no commit message) X-Git-Tag: wamblee-utils-0.2@603~183 X-Git-Url: http://wamblee.org/gitweb/?a=commitdiff_plain;h=3a8e7a7c051c61d309799fb5cd73aa7852736f25;p=utils --- diff --git a/trunk/system/general/src/main/java/org/wamblee/system/core/Container.java b/trunk/system/general/src/main/java/org/wamblee/system/core/Container.java index 81dcb6a2..fd322c6b 100644 --- a/trunk/system/general/src/main/java/org/wamblee/system/core/Container.java +++ b/trunk/system/general/src/main/java/org/wamblee/system/core/Container.java @@ -25,7 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * Composite system consisting of multiple subsystems. + * Container consisting of multiple components. * * @author Erik Brakkee */ @@ -33,7 +33,7 @@ public class Container extends AbstractComponent { private static final Log LOG = LogFactory.getLog(Container.class); - private Component[] _systems; + private Component[] _components; public static RequiredInterface[] filterRequiredServices( ProvidedInterface aProvided, @@ -59,44 +59,42 @@ public class Container extends AbstractComponent { } /** - * Construcst the composite system. + * Construcst the container * * @param aName - * Name of the system. - * @param aRegistry - * Service registry. - * @param aSystems - * Subsystems. + * Name of the container + * @param aComponents + * Components. * @param aProvided - * Provided services of the system. + * Provided services of the container * @param aRequired - * Required services by the system. + * Required services by the container. */ - public Container(String aName, Component[] aSystems, + public Container(String aName, Component[] aComponents, ProvidedInterface[] aProvided, RequiredInterface[] aRequired) { super(aName, aProvided, aRequired); - _systems = aSystems; - for (Component component : aSystems) { + _components = aComponents; + for (Component component : aComponents) { component.addContext(getQualifiedName()); } validate(); } /** - * Validates the subsystems together to check that there are no required + * Validates the components together to check that there are no required * 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. */ private void validate() { List provided = new ArrayList(); - for (Component system : _systems) { - provided.addAll(Arrays.asList(system.getProvidedInterfaces())); + for (Component component : _components) { + provided.addAll(Arrays.asList(component.getProvidedInterfaces())); } List required = new ArrayList(); - for (Component system : _systems) { - required.addAll(Arrays.asList(system.getRequiredInterfaces())); + for (Component component : _components) { + required.addAll(Arrays.asList(component.getRequiredInterfaces())); } validateProvidedInterfaces(provided); @@ -117,12 +115,12 @@ public class Container extends AbstractComponent { } private List validateRequiredProvidedMatch( - List provided, List required) { + List aProvided, List aRequired) { List reallyRequired = new ArrayList( - required); + aRequired); // Compute all required interfaces that are not provided - for (ProvidedInterface service : provided) { + for (ProvidedInterface service : aProvided) { List fulfilled = Arrays .asList(filterRequiredServices(service, reallyRequired)); reallyRequired.removeAll(fulfilled); @@ -141,41 +139,40 @@ public class Container extends AbstractComponent { return reallyRequired; } - private void validateRequiredInterfaces(List required) { + private void validateRequiredInterfaces(List aRequired) { for (RequiredInterface service : getRequiredInterfaces()) { - // TODO required services by the subsystem could be + // TODO required interfaces by the component could be // subclasses or implementations of the requirements - // of the contained systems. The code below assumes + // of the contained components. The code below assumes // an exact match. - if (!(required.contains(service))) { + if (!(aRequired.contains(service))) { info("Service '" + service - + "' indicated as required is not actually required by any of the subsystems"); + + "' indicated as required is not actually required by any of the components"); } // Check for the case that the externally required service // is optional whereas the internally required service is // mandatory. if ( service.isOptional()) { - for (RequiredInterface intf: required) { - if ( intf.equals(service) && !intf.isOptional()) { - // TODO indicate which subsystem this is. - warn("Required service '" + service + "' indicated as optional is mandatory by one of its subsystems (" + getClients(intf) + ", " + intf + "), this can lead to problems when the system is started and the service is not there."); + for (RequiredInterface intf: aRequired) { + if ( intf.equals(service) && !intf.isOptional()) { + warn("Required service '" + service + "' indicated as optional is mandatory by one of its components (" + getClients(intf) + ", " + intf + "), this can lead to problems when the container is started and the interface is not provided to the container."); } } } } } - private void validateProvidedInterfaces(List provided) { + private void validateProvidedInterfaces(List aProvided) { for (ProvidedInterface service : getProvidedInterfaces()) { - // TODO provided interfaces by subsystems could be + // TODO provided interfaces by components could be // provide subclasses or implementations of the // provided interfaces of the container. // The code below assumes an exact match. - if (!(provided.contains(service))) { + if (!(aProvided.contains(service))) { throw new SystemAssemblyException(getName() + ": Service '" + service - + "' is not provided by any of the subsystems"); + + "' is not provided by any of its components"); } } } @@ -201,70 +198,79 @@ public class Container extends AbstractComponent { } List started = new ArrayList(); - for (Component system : _systems) { + for (Component component : _components) { try { - // Check if all required services are already provided by - // earlier - // systems. - - for (RequiredInterface descriptor : system.getRequiredInterfaces()) { - ProvidedInterface[] filtered = filterProvidedServices( - descriptor, allProvided); - if ( filtered.length == 1 ) { - descriptor.setProvider(filtered[0]); - } else if ( filtered.length > 1 ) { - throw new SystemAssemblyException( - "Service '" - + descriptor - + "' required by system '" - + system - + "' matches multiple services provided by other systems: " - + Arrays.asList(filtered)); - } else { - // filtered.length == 0 - if ( !descriptor.isOptional()) { - throw new SystemAssemblyException( - "Service '" - + descriptor - + "' required by system '" - + system - + "' is not provided by systems that are started earlier"); - } - } - } + checkAllRequiredServicesAlreadyProvided(allProvided, component); // Start the service. - system.start(); - started.add(system); + component.start(); + started.add(component); // add all provided services - ProvidedInterface[] provided = system.getProvidedInterfaces(); + ProvidedInterface[] provided = component.getProvidedInterfaces(); allProvided.addAll(Arrays.asList(provided)); } catch (SystemAssemblyException e) { throw e; } catch (RuntimeException e) { LOG.error(getQualifiedName() + ": could not start '" - + system.getQualifiedName() + "'", e); - // an exception occurred, stop the successfully started - // systems - for (int i = started.size() - 1; i >= 0; i--) { - try { - started.get(i).stop(); - } catch (Throwable t) { - LOG.error(getQualifiedName() + ": error stopping " - + started.get(i).getQualifiedName()); - } - } + + component.getQualifiedName() + "'", e); + stopAlreadyStartedComponents(started); throw e; } } } + private void stopAlreadyStartedComponents(List aStarted) { + // an exception occurred, stop the successfully started + // components + for (int i = aStarted.size() - 1; i >= 0; i--) { + try { + aStarted.get(i).stop(); + } catch (Throwable t) { + LOG.error(getQualifiedName() + ": error stopping " + + aStarted.get(i).getQualifiedName()); + } + } + } + + private void checkAllRequiredServicesAlreadyProvided( + List aAllProvided, Component aComponent) { + // Check if all required services are already provided by + // earlier + // systems. + + for (RequiredInterface descriptor : aComponent.getRequiredInterfaces()) { + ProvidedInterface[] filtered = filterProvidedServices( + descriptor, aAllProvided); + if ( filtered.length == 1 ) { + descriptor.setProvider(filtered[0]); + } else if ( filtered.length > 1 ) { + throw new SystemAssemblyException( + "Service '" + + descriptor + + "' required by system '" + + aComponent + + "' matches multiple services provided by other systems: " + + Arrays.asList(filtered)); + } else { + // filtered.length == 0 + if ( !descriptor.isOptional()) { + throw new SystemAssemblyException( + "Service '" + + descriptor + + "' required by system '" + + aComponent + + "' is not provided by systems that are started earlier"); + } + } + } + } + @Override protected void doStop() { - for (int i = _systems.length - 1; i >= 0; i--) { - _systems[i].stop(); + for (int i = _components.length - 1; i >= 0; i--) { + _components[i].stop(); } } @@ -278,7 +284,7 @@ public class Container extends AbstractComponent { private List getClients(RequiredInterface aRequirement) { List clients = new ArrayList(); - for (Component component: _systems) { + for (Component component: _components) { for (RequiredInterface required: component.getRequiredInterfaces()) { if ( required.equals(aRequirement) && required.isOptional() == aRequirement.isOptional()) { clients.add(component);