X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2FSystemAssembler.java;h=80bab167fa1de1bf7c7c071d14f6ad60e93b627a;hb=b6364aebdb15bb0648e8db2030d8ad793e209af6;hp=9e38a3e1a0a332cf5c47c9433f53ac018b058873;hpb=16504cb35c59542f7817abfe3c852e9fedd870a3;p=utils diff --git a/system/general/src/main/java/org/wamblee/system/SystemAssembler.java b/system/general/src/main/java/org/wamblee/system/SystemAssembler.java index 9e38a3e1..80bab167 100644 --- a/system/general/src/main/java/org/wamblee/system/SystemAssembler.java +++ b/system/general/src/main/java/org/wamblee/system/SystemAssembler.java @@ -1,6 +1,8 @@ package org.wamblee.system; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -9,9 +11,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * Assembler to control multiple subsystems. It makes sure that - * all dependencies are met and controls the order in which systems - * are initialized. + * Assembler to control multiple subsystems. It makes sure that all dependencies + * are met and controls the order in which systems are initialized. */ public class SystemAssembler { @@ -21,25 +22,57 @@ public class SystemAssembler { private String _context; private SubSystem[] _systems; + public static RequiredServiceDescriptor[] filterRequiredServices( + ProvidedServiceDescriptor aProvided, + Collection aDescriptors) { + List required = new ArrayList(); + for (RequiredServiceDescriptor descriptor : aDescriptors) { + if (descriptor.implementedBy(aProvided)) { + required.add(descriptor); + } + } + return required.toArray(new RequiredServiceDescriptor[0]); + } + + public static ProvidedServiceDescriptor[] filterProvidedServices( + RequiredServiceDescriptor aRequired, + Collection aProvided) { + List provided = new ArrayList(); + for (ProvidedServiceDescriptor descriptor : aProvided) { + if (aRequired.implementedBy(descriptor)) { + provided.add(descriptor); + } + } + return provided.toArray(new ProvidedServiceDescriptor[0]); + } + /** - * Constructs the assembler. - * @param aSystems Systems that must be assembled. - * @param aAvailableServices Available services from other systems - * outside of the systems that this assembler manages. + * Constructs the assembler. + * + * @param aSystems + * Systems that must be assembled. + * @param aAvailableServices + * Available services from other systems outside of the systems + * that this assembler manages. */ - public SystemAssembler(SubSystem[] aSystems, ServiceDescriptor[] aAvailableServices) { + public SystemAssembler(SubSystem[] aSystems, + ProvidedServiceDescriptor[] aAvailableServices) { this(ROOT_CONTEXT_NAME, aSystems, aAvailableServices); } /** - * Constructs the assembler. - * @param aContext Context (unique name) of the assembler. - * @param aSystems Systems that must be assembled. - * @param aAvailableServices Available services from other systems - * outside of the systems that this assembler manages. + * Constructs the assembler. + * + * @param aContext + * Context (unique name) of the assembler. + * @param aSystems + * Systems that must be assembled. + * @param aAvailableServices + * Available services from other systems outside of the systems + * that this assembler manages. */ - public SystemAssembler(String aContext, SubSystem[] aSystems, - ServiceDescriptor[] aAvailableServices) { + public SystemAssembler(String aContext, SubSystem[] aSystems, + ProvidedServiceDescriptor[] aAvailableServices) { _context = aContext; _systems = aSystems; validate(aAvailableServices); @@ -49,18 +82,23 @@ public class SystemAssembler { * Determines if the systems are ordered appropriately so that all * dependencies are met. */ - private void validate(ServiceDescriptor[] aDescriptors) throws SystemAssemblyException { + private void validate(ProvidedServiceDescriptor[] aDescriptors) + throws SystemAssemblyException { - List allProvided = new ArrayList(); - for (ServiceDescriptor descriptor: aDescriptors) { + List allProvided = new ArrayList(); + for (ProvidedServiceDescriptor descriptor : aDescriptors) { allProvided.add(descriptor); } for (SubSystem system : _systems) { // Check if all required services are already provided by earlier // systems. - ServiceDescriptor[] required = system.getRequiredServices(); - for (ServiceDescriptor descriptor : required) { - if (!(allProvided.contains(descriptor))) { + RequiredServiceDescriptor[] required = system.getRequiredServices(); + + for (RequiredServiceDescriptor descriptor : required) { + ProvidedServiceDescriptor[] filtered = filterProvidedServices( + descriptor, allProvided); + + if (filtered.length == 0) { throw new SystemAssemblyException( "Service '" + descriptor @@ -68,42 +106,57 @@ public class SystemAssembler { + 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)); + } } // add all provided services - ServiceDescriptor[] provided = system.getProvidedServices(); - for (ServiceDescriptor descriptor : provided) { - allProvided.add(descriptor); - } + ProvidedServiceDescriptor[] provided = system.getProvidedServices(); + allProvided.addAll(Arrays.asList(provided)); } } /** * Starts the subsystems. - * @param aRegistry Service registry to which created services must be registered. - * @param aRequiredServices Services that are available from - * other systems that have been started before. + * + * @param aRegistry + * Service registry to which created services must be registered. + * @param aRequiredServices + * Services that are available from other systems that have been + * started before. */ public void start(ServiceRegistry aRegistry, Service[] aRequiredServices) { LOG.info("Starting '" + _context + "'"); - Map allProvided = new HashMap(); + Map allProvided = new HashMap(); for (Service service : aRequiredServices) { allProvided.put(service.getDescriptor(), service); } for (SubSystem system : _systems) { - ServiceDescriptor[] descriptors = system.getRequiredServices(); + + // Compose a list of the required services required for the subsystem. + + RequiredServiceDescriptor[] descriptors = system + .getRequiredServices(); List services = new ArrayList(); - for (ServiceDescriptor descriptor : descriptors) { - Service required = allProvided.get(descriptor); - if (required == null) { - throw new SystemAssemblyException("Service '" + descriptor - + "' required by '" + system + "' is null."); - } - services.add(required); + for (RequiredServiceDescriptor descriptor : descriptors) { + ProvidedServiceDescriptor[] provided = filterProvidedServices( + descriptor, allProvided.keySet()); + services.add(allProvided.get(provided[0])); } + + // Start the service. Service[] provided = system.start(_context, services .toArray(new Service[0])); + + // Add started services to the map of started services. for (Service service : provided) { allProvided.put(service.getDescriptor(), service); }