(no commit message)
authorErik Brakkee <erik@brakkee.org>
Fri, 11 Apr 2008 20:36:14 +0000 (20:36 +0000)
committerErik Brakkee <erik@brakkee.org>
Fri, 11 Apr 2008 20:36:14 +0000 (20:36 +0000)
system/general/src/main/java/org/wamblee/system/core/Container.java

index 81dcb6a2c95bc106ce2195e384eb7c521d07b5c6..fd322c6bbd49aabd10187501d630f2db762a2204 100644 (file)
@@ -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<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
-               for (Component system : _systems) {
-                       provided.addAll(Arrays.asList(system.getProvidedInterfaces()));
+               for (Component component : _components) {
+                       provided.addAll(Arrays.asList(component.getProvidedInterfaces()));
                }
 
                List<RequiredInterface> required = new ArrayList<RequiredInterface>();
-               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<RequiredInterface> validateRequiredProvidedMatch(
-                       List<ProvidedInterface> provided, List<RequiredInterface> required) {
+                       List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
                List<RequiredInterface> reallyRequired = new ArrayList<RequiredInterface>(
-                               required);
+                               aRequired);
                // Compute all required interfaces that are not provided
 
-               for (ProvidedInterface service : provided) {
+               for (ProvidedInterface service : aProvided) {
                        List<RequiredInterface> fulfilled = Arrays
                                        .asList(filterRequiredServices(service, reallyRequired));
                        reallyRequired.removeAll(fulfilled);
@@ -141,41 +139,40 @@ public class Container extends AbstractComponent {
                return reallyRequired;
        }
 
-       private void validateRequiredInterfaces(List<RequiredInterface> required) {
+       private void validateRequiredInterfaces(List<RequiredInterface> 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<ProvidedInterface> provided) {
+       private void validateProvidedInterfaces(List<ProvidedInterface> 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<Component> started = new ArrayList<Component>();
-               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<Component> 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<ProvidedInterface> 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<Component> getClients(RequiredInterface aRequirement) {
                List<Component> clients = new ArrayList<Component>();
-               for (Component component: _systems) { 
+               for (Component component: _components) { 
                        for (RequiredInterface required: component.getRequiredInterfaces()) { 
                                if ( required.equals(aRequirement) && required.isOptional() == aRequirement.isOptional()) { 
                                        clients.add(component);