From adc2a72f97f72460b20765d2d0f34b6c21caca3d Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Wed, 9 Apr 2008 18:07:28 +0000 Subject: [PATCH] elimintated the system assembler. --- .../org/wamblee/system/AbstractComponent.java | 13 +- .../java/org/wamblee/system/Component.java | 8 + .../java/org/wamblee/system/Container.java | 91 ++++++++- .../org/wamblee/system/SystemAssembler.java | 185 ------------------ ...mAssemblerTest.java => ContainerTest.java} | 37 ++-- 5 files changed, 126 insertions(+), 208 deletions(-) delete mode 100644 system/general/src/main/java/org/wamblee/system/SystemAssembler.java rename system/general/src/test/java/org/wamblee/system/{SystemAssemblerTest.java => ContainerTest.java} (90%) diff --git a/system/general/src/main/java/org/wamblee/system/AbstractComponent.java b/system/general/src/main/java/org/wamblee/system/AbstractComponent.java index a9752d1f..3b472583 100644 --- a/system/general/src/main/java/org/wamblee/system/AbstractComponent.java +++ b/system/general/src/main/java/org/wamblee/system/AbstractComponent.java @@ -31,7 +31,8 @@ public abstract class AbstractComponent implements Component { private static final Log LOG = LogFactory.getLog(AbstractComponent.class); - private Status _status; + private Status _status; + private String _context; private String _name; private List _provided; private List _required; @@ -50,6 +51,7 @@ public abstract class AbstractComponent implements Component { protected AbstractComponent(String aName, ProvidedInterface[] aProvided, RequiredInterface[] aRequired) { _status = Status.NOT_STARTED; + _context = null; _name = aName; _provided = new ArrayList(); _provided.addAll(Arrays.asList(aProvided)); @@ -67,6 +69,14 @@ public abstract class AbstractComponent implements Component { public final String getName() { return _name; } + + @Override + public String getQualifiedName() { + if ( _context == null ) { + return getName(); + } + return _context + "." + getName(); + } @Override public final ProvidedInterface[] getProvidedServices() { @@ -81,6 +91,7 @@ public abstract class AbstractComponent implements Component { @Override public final void start(String aContext) { LOG.info("Initializing '" + aContext + "." + _name + "'"); + _context = aContext; doStart(aContext + "." + getName()); _status = Status.RUNNING; if ( _running.size() != _provided.size()) { diff --git a/system/general/src/main/java/org/wamblee/system/Component.java b/system/general/src/main/java/org/wamblee/system/Component.java index 22ad381e..0234005f 100644 --- a/system/general/src/main/java/org/wamblee/system/Component.java +++ b/system/general/src/main/java/org/wamblee/system/Component.java @@ -38,6 +38,14 @@ public interface Component { * @return Subsystem name. */ String getName(); + + /** + * Gets the fully qualified name of the component which includes + * the context of the component. + * This method can only be used after the component has started. + * @return Qualified name. + */ + String getQualifiedName(); /** * Gets a description of the provided interfaces. 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..bd059902 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. @@ -87,7 +112,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); } @@ -119,11 +144,65 @@ public class Container extends AbstractComponent { 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 '" + "'"); + 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(getQualifiedName()); + + // add all provided services + ProvidedInterface[] provided = system.getProvidedServices(); + allProvided.addAll(Arrays.asList(provided)); + } + } + + @Override protected void doStop() { for (int i = _systems.length-1; i >= 0; i--) { diff --git a/system/general/src/main/java/org/wamblee/system/SystemAssembler.java b/system/general/src/main/java/org/wamblee/system/SystemAssembler.java deleted file mode 100644 index 90a98440..00000000 --- a/system/general/src/main/java/org/wamblee/system/SystemAssembler.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2007 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -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. - * - * @author Erik Brakkee - */ -public class SystemAssembler { - - private static final Log LOG = LogFactory.getLog(SystemAssembler.class); - - private static final String ROOT_CONTEXT_NAME = "root"; - private String _context; - private Component[] _systems; - private ProvidedInterface[] _required; - - 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]); - } - - /** - * 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(Component[] aSystems, - ProvidedInterface[] 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. - */ - public SystemAssembler(String aContext, Component[] aSystems, - ProvidedInterface[] aAvailableServices) { - _context = aContext; - _systems = aSystems; - _required = aAvailableServices; - validate(); - } - - /** - * Determines if the systems are ordered appropriately so that all - * dependencies are met. - */ - private void validate() - throws SystemAssemblyException { - - List allProvided = new ArrayList(); - for (ProvidedInterface descriptor : _required) { - allProvided.add(descriptor); - } - 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)); - } - } - - // add all provided services - ProvidedInterface[] provided = system.getProvidedServices(); - allProvided.addAll(Arrays.asList(provided)); - } - } - - /** - * Starts the subsystems. - * - * @param aRequiredServices - * Services that are available from other systems that have been - * started before. - */ - public void start() { - LOG.info("Starting '" + _context + "'"); - Set allProvided = new HashSet(); - allProvided.addAll(Arrays.asList(_required)); - - for (Component system : _systems) { - - // Compose a list of the required services required for the subsystem. - - RequiredInterface[] descriptors = system - .getRequiredServices(); - List services = new ArrayList(); - for (RequiredInterface required : descriptors) { - ProvidedInterface[] provided = filterProvidedServices( - required, allProvided); - assert provided.length == 1; - services.add(provided[0]); - required.setProvider(provided[0]); - } - - // Start the service. - system.start(_context); - - // Add started services to the set of started services. - for (ProvidedInterface service : system.getProvidedServices()) { - allProvided.add(service); - } - - } - } - -} diff --git a/system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java b/system/general/src/test/java/org/wamblee/system/ContainerTest.java similarity index 90% rename from system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java rename to system/general/src/test/java/org/wamblee/system/ContainerTest.java index c67529b8..33f3c00d 100644 --- a/system/general/src/test/java/org/wamblee/system/SystemAssemblerTest.java +++ b/system/general/src/test/java/org/wamblee/system/ContainerTest.java @@ -25,7 +25,7 @@ import org.wamblee.test.EventTracker; import junit.framework.TestCase; -public class SystemAssemblerTest extends TestCase { +public class ContainerTest extends TestCase { private EventTracker _tracker; @@ -55,32 +55,34 @@ public class SystemAssemblerTest extends TestCase { MyMultiple.class); AssertionUtils.assertEquals(new RequiredInterface[] { req1 }, - SystemAssembler.filterRequiredServices(prov1, Arrays + Container.filterRequiredServices(prov1, Arrays .asList(new RequiredInterface[] { req1 }))); AssertionUtils.assertEquals(new RequiredInterface[] { req1 }, - SystemAssembler.filterRequiredServices(prov1, Arrays + Container.filterRequiredServices(prov1, Arrays .asList(new RequiredInterface[] { req1, req2 }))); AssertionUtils.assertEquals(new RequiredInterface[] { req1, req2 }, - SystemAssembler.filterRequiredServices(prov3, Arrays + Container.filterRequiredServices(prov3, Arrays .asList(new RequiredInterface[] { req1, req2 }))); AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 }, - SystemAssembler.filterProvidedServices(req1, Arrays + Container.filterProvidedServices(req1, Arrays .asList(new ProvidedInterface[] { prov1 }))); AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 }, - SystemAssembler.filterProvidedServices(req1, Arrays + Container.filterProvidedServices(req1, Arrays .asList(new ProvidedInterface[] { prov1, prov2 }))); AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 }, - SystemAssembler.filterProvidedServices(req1, Arrays + Container.filterProvidedServices(req1, Arrays .asList(new ProvidedInterface[] { prov1, prov3 }))); } public void testEnvironmentApplication() { Component environment = new Environment(_tracker); Component application = new Application(_tracker); - SystemAssembler assembler = new SystemAssembler(new Component[] { - environment, application }, new ProvidedInterface[0]); - assembler.start(); + Container container = new Container("root", new Component[] { + environment, application }, new ProvidedInterface[0], + new RequiredInterface[0]); + + container.start("top"); AssertionUtils.assertEquals(new String[] { "start.environment", "start.application" }, _tracker.getEvents( Thread.currentThread()).toArray(new String[0])); @@ -95,9 +97,12 @@ public class SystemAssemblerTest extends TestCase { try { Component environment = new Environment(); Component application = new Application(); - SystemAssembler assembler = new SystemAssembler(new Component[] { - application, environment }, new ProvidedInterface[0]); - assembler.start(); + Container container = new Container( + "root", + new Component[] { + application, environment }, + new ProvidedInterface[0], new RequiredInterface[0]); + container.start("top"); } catch (SystemAssemblyException e) { // e.printStackTrace(); return; @@ -229,10 +234,10 @@ public class SystemAssemblerTest extends TestCase { Component environment1 = new Environment(); Component environment2 = new Environment(); Component application = new Application(); - SystemAssembler assembler = new SystemAssembler(new Component[] { + Container container = new Container("root", new Component[] { environment1, environment2, application }, - new ProvidedInterface[0]); - assembler.start(); + new ProvidedInterface[0], new RequiredInterface[0]); + container.start("top"); } catch (SystemAssemblyException e) { return; -- 2.31.1