X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2Fcore%2FContainer.java;h=b7ee4e60c6ddcb61f0fed6c52b911cfb37fb7998;hb=8a6ee427cf3de42d9dd9d8fea09ee9fd059ee53e;hp=ec45283e2d0fff00b1bc711658d80f5310414994;hpb=98dc838908507748b413ad0d93e9050cbb6ecdeb;p=utils diff --git a/system/general/src/main/java/org/wamblee/system/core/Container.java b/system/general/src/main/java/org/wamblee/system/core/Container.java index ec45283e..b7ee4e60 100644 --- a/system/general/src/main/java/org/wamblee/system/core/Container.java +++ b/system/general/src/main/java/org/wamblee/system/core/Container.java @@ -12,7 +12,7 @@ * 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.core; import java.util.ArrayList; @@ -26,8 +26,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * Composite system consisting of multiple subsystems. - * + * Composite system consisting of multiple subsystems. + * * @author Erik Brakkee */ public class Container extends AbstractComponent { @@ -49,8 +49,7 @@ public class Container extends AbstractComponent { } public static ProvidedInterface[] filterProvidedServices( - RequiredInterface aRequired, - Collection aProvided) { + RequiredInterface aRequired, Collection aProvided) { List provided = new ArrayList(); for (ProvidedInterface descriptor : aProvided) { if (aRequired.implementedBy(descriptor)) { @@ -59,30 +58,36 @@ public class Container extends AbstractComponent { } return provided.toArray(new ProvidedInterface[0]); } - + /** - * Construcst the composite system. - * @param aName Name of the system. - * @param aRegistry Service registry. - * @param aSystems Subsystems. - * @param aProvided Provided services of the system. - * @param aRequired Required services by the system. + * Construcst the composite system. + * + * @param aName + * Name of the system. + * @param aRegistry + * Service registry. + * @param aSystems + * Subsystems. + * @param aProvided + * Provided services of the system. + * @param aRequired + * Required services by the system. */ public Container(String aName, Component[] aSystems, ProvidedInterface[] aProvided, RequiredInterface[] aRequired) { super(aName, aProvided, aRequired); _systems = aSystems; - for (Component component: aSystems) { + for (Component component : aSystems) { component.addContext(getQualifiedName()); } validate(aRequired); } /** - * Validates the subsystems 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. + * Validates the subsystems 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(RequiredInterface[] aRequired) { List provided = new ArrayList(); @@ -97,7 +102,8 @@ public class Container extends AbstractComponent { for (ProvidedInterface service : getProvidedInterfaces()) { if (!(provided.contains(service))) { - throw new SystemAssemblyException(getName() + ": Service '" + service + throw new SystemAssemblyException(getName() + ": Service '" + + service + "' is not provided by any of the subsystems"); } } @@ -114,42 +120,43 @@ public class Container extends AbstractComponent { required); // Compute all required interfaces that are not provided for (ProvidedInterface service : provided) { - List fulfilled = - Arrays.asList(filterRequiredServices(service, - reallyRequired)); - reallyRequired.removeAll(fulfilled); + List fulfilled = Arrays + .asList(filterRequiredServices(service, reallyRequired)); + reallyRequired.removeAll(fulfilled); } // Now the remaining interfaces should be covered by the required - // list. + // list. reallyRequired.removeAll(Arrays.asList(aRequired)); - + String missingRequired = ""; - for (RequiredInterface service: reallyRequired) { + for (RequiredInterface service : reallyRequired) { missingRequired += service + "\n"; } - if ( missingRequired.length() > 0 ) { - throw new SystemAssemblyException(getName() + ": missing required services\n" + missingRequired); + if (missingRequired.length() > 0) { + throw new SystemAssemblyException(getName() + + ": missing required services\n" + missingRequired); } } @Override protected void doStart() { List provided = new ArrayList(); - + // all interfaces from the required list of this container are // provided to the components inside it. RequiredInterface[] required = getRequiredInterfaces(); - for (RequiredInterface intf: required) { - ProvidedInterface provider = intf.getProvider(); - if ( provider == null ) { - throw new SystemAssemblyException(getQualifiedName() + ": required interface '" + intf +"' is not provided"); - } + for (RequiredInterface intf : required) { + ProvidedInterface provider = intf.getProvider(); + if (provider == null) { + throw new SystemAssemblyException(getQualifiedName() + + ": required interface '" + intf + "' is not provided"); + } provided.add(intf.getProvider()); } - + startImpl(); } - + /** * Starts the subsystems. * @@ -160,55 +167,77 @@ public class Container extends AbstractComponent { private void startImpl() { LOG.info("Starting '" + getQualifiedName() + "'"); List allProvided = new ArrayList(); - - // Add the provides of all externally required interfaces to the list of available + + // Add the provides of all externally required interfaces to the list of + // available // interfaces - for (RequiredInterface required: getRequiredInterfaces()) { + for (RequiredInterface required : getRequiredInterfaces()) { allProvided.add(required.getProvider()); } - + + List started = new ArrayList(); for (Component system : _systems) { - // Check if all required services are already provided by earlier - // systems. - RequiredInterface[] required = system.getRequiredInterfaces(); - - 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"); + try { + // Check if all required services are already provided by + // earlier + // systems. + RequiredInterface[] required = system.getRequiredInterfaces(); + + 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]); } - if (filtered.length > 1) { - throw new SystemAssemblyException( - "Service '" - + descriptor - + "' required by system '" - + system - + "' matches multiple services provided by other systems: " + - Arrays.asList(filtered)); + + // Start the service. + system.start(); + started.add(system); + + // add all provided services + ProvidedInterface[] provided = system.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()); + } } - descriptor.setProvider(filtered[0]); + throw e; } - - // Start the service. - system.start(); - - // add all provided services - ProvidedInterface[] provided = system.getProvidedInterfaces(); - allProvided.addAll(Arrays.asList(provided)); } + } - @Override protected void doStop() { - for (int i = _systems.length-1; i >= 0; i--) { + for (int i = _systems.length - 1; i >= 0; i--) { _systems[i].stop(); } }