X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2FContainer.java;h=65d10f06e2960d74eff34b5ed63cd560d6fa1337;hb=b0e1c060d6207c0fc06e4673764a6980da775210;hp=a1bb29c24554967812b739636c4ebf443b96e1ee;hpb=6f8bb575523e672b9f8797e543f7c59d15db7253;p=utils diff --git a/system/general/src/main/java/org/wamblee/system/Container.java b/system/general/src/main/java/org/wamblee/system/Container.java index a1bb29c2..65d10f06 100644 --- a/system/general/src/main/java/org/wamblee/system/Container.java +++ b/system/general/src/main/java/org/wamblee/system/Container.java @@ -17,13 +17,14 @@ package org.wamblee.system; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import sun.util.LocaleServiceProviderPool.LocalizedObjectGetter; - /** * Composite system consisting of multiple subsystems. * @@ -35,6 +36,30 @@ public class Container extends AbstractComponent { private Component[] _systems; + public static RequiredInterface[] filterRequiredServices( + ProvidedInterface aProvided, + Collection aDescriptors) { + List required = new ArrayList(); + for (RequiredInterface descriptor : aDescriptors) { + if (descriptor.implementedBy(aProvided)) { + required.add(descriptor); + } + } + return required.toArray(new RequiredInterface[0]); + } + + public static ProvidedInterface[] filterProvidedServices( + RequiredInterface aRequired, + Collection aProvided) { + List provided = new ArrayList(); + for (ProvidedInterface descriptor : aProvided) { + if (aRequired.implementedBy(descriptor)) { + provided.add(descriptor); + } + } + return provided.toArray(new ProvidedInterface[0]); + } + /** * Construcst the composite system. * @param aName Name of the system. @@ -47,6 +72,9 @@ public class Container extends AbstractComponent { ProvidedInterface[] aProvided, RequiredInterface[] aRequired) { super(aName, aProvided, aRequired); _systems = aSystems; + for (Component component: aSystems) { + component.addContext(getQualifiedName()); + } validate(aRequired); } @@ -87,7 +115,7 @@ public class Container extends AbstractComponent { // Compute all required interfaces that are not provided for (ProvidedInterface service : provided) { List fulfilled = - Arrays.asList(SystemAssembler.filterRequiredServices(service, + Arrays.asList(filterRequiredServices(service, reallyRequired)); reallyRequired.removeAll(fulfilled); } @@ -105,7 +133,7 @@ public class Container extends AbstractComponent { } @Override - protected void doStart(String aContext) { + protected void doStart() { List provided = new ArrayList(); // all interfaces from the required list of this container are @@ -114,15 +142,69 @@ public class Container extends AbstractComponent { for (RequiredInterface intf: required) { ProvidedInterface provider = intf.getProvider(); if ( provider == null ) { - throw new SystemAssemblyException(aContext + ": required interface '" + intf +"' is not provided"); + throw new SystemAssemblyException(getQualifiedName() + ": required interface '" + intf +"' is not provided"); } provided.add(intf.getProvider()); } - SystemAssembler assembler = new SystemAssembler( _systems, - provided.toArray(new ProvidedInterface[0])); - assembler.start(); + startImpl(); + } + + /** + * Starts the subsystems. + * + * @param aRequiredServices + * Services that are available from other systems that have been + * started before. + */ + private void startImpl() { + LOG.info("Starting '" + getQualifiedName() + "'"); + List allProvided = new ArrayList(); + + // Add the provides of all externally required interfaces to the list of available + // interfaces + for (RequiredInterface required: getRequiredServices()) { + allProvided.add(required.getProvider()); + } + + for (Component system : _systems) { + // Check if all required services are already provided by earlier + // systems. + RequiredInterface[] required = system.getRequiredServices(); + + for (RequiredInterface descriptor : required) { + ProvidedInterface[] filtered = filterProvidedServices( + descriptor, allProvided); + + if (filtered.length == 0) { + throw new SystemAssemblyException( + "Service '" + + descriptor + + "' required by system '" + + system + + "' is not provided by systems that are started earlier"); + } + if (filtered.length > 1) { + throw new SystemAssemblyException( + "Service '" + + descriptor + + "' required by system '" + + system + + "' matches multiple services provided by other systems: " + + Arrays.asList(filtered)); + } + descriptor.setProvider(filtered[0]); + } + + // Start the service. + system.start(); + + // add all provided services + ProvidedInterface[] provided = system.getProvidedServices(); + allProvided.addAll(Arrays.asList(provided)); + } } + @Override protected void doStop() {