package org.wamblee.system; 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 sun.util.LocaleServiceProviderPool.LocalizedObjectGetter; /** * Composite system consisting of multiple subsystems. */ public class CompositeSystem extends AbstractSubSystem { private static final Log LOG = LogFactory.getLog(CompositeSystem.class); private SubSystem[] _systems; /** * Construcst the composite system. * @param aName Name of the system. * @param aSystems Subsystems. * @param aProvided Provided services of the system. * @param aRequired Required services by the system. */ public CompositeSystem(String aName, SubSystem[] aSystems, ServiceDescriptor[] aProvided, ServiceDescriptor[] aRequired) { super(aName, aProvided, aRequired); _systems = aSystems; validate(); } /** * 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() { List provided = new ArrayList(); for (SubSystem system : _systems) { provided.addAll(Arrays.asList(system.getProvidedServices())); } List required = new ArrayList(); for (SubSystem system : _systems) { required.addAll(Arrays.asList(system.getRequiredServices())); } for (ServiceDescriptor service : getProvidedServices()) { if (!(provided.contains(service))) { throw new SystemAssemblyException(getName() + ": Service '" + service + "' is not provided by any of the subsystems"); } } for (ServiceDescriptor service : getRequiredServices()) { if (!(required.contains(service))) { info("Service '" + service + "' indicated as required is not actually required by any of the subsystems"); } } List reallyRequired = new ArrayList( required); for (ServiceDescriptor service : provided) { reallyRequired.remove(service); } for (ServiceDescriptor service: getRequiredServices()) { reallyRequired.remove(service); } for (ServiceDescriptor service: reallyRequired) { throw new SystemAssemblyException(getName() + ": " + "Service '" + service + "' is not provided internally and is not indicated as required for this sub system"); } } @Override protected void doStart(String aContext, ServiceRegistry aRegistry, Service[] aRequiredServices) { List descriptors = new ArrayList(); for (Service service : aRequiredServices) { descriptors.add(service.getDescriptor()); } SystemAssembler assembler = new SystemAssembler(getName(), _systems, descriptors.toArray(new ServiceDescriptor[0])); assembler.start(aRegistry, aRequiredServices); } private void info(String aMsg) { LOG.info(getName() + ": " + aMsg); } }