private static final Log LOG = LogFactory.getLog(AbstractComponent.class);
- private Status _status;
+ private Status _status;
+ private String _context;
private String _name;
private List<ProvidedInterface> _provided;
private List<RequiredInterface> _required;
protected AbstractComponent(String aName, ProvidedInterface[] aProvided,
RequiredInterface[] aRequired) {
_status = Status.NOT_STARTED;
+ _context = null;
_name = aName;
_provided = new ArrayList<ProvidedInterface>();
_provided.addAll(Arrays.asList(aProvided));
public final String getName() {
return _name;
}
+
+ @Override
+ public String getQualifiedName() {
+ if ( _context == null ) {
+ return getName();
+ }
+ return _context + "." + getName();
+ }
@Override
public final ProvidedInterface[] getProvidedServices() {
@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()) {
* @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.
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.
*
private Component[] _systems;
+ public static RequiredInterface[] filterRequiredServices(
+ ProvidedInterface aProvided,
+ Collection<RequiredInterface> aDescriptors) {
+ List<RequiredInterface> required = new ArrayList<RequiredInterface>();
+ for (RequiredInterface descriptor : aDescriptors) {
+ if (descriptor.implementedBy(aProvided)) {
+ required.add(descriptor);
+ }
+ }
+ return required.toArray(new RequiredInterface[0]);
+ }
+
+ public static ProvidedInterface[] filterProvidedServices(
+ RequiredInterface aRequired,
+ Collection<ProvidedInterface> aProvided) {
+ List<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
+ 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.
// Compute all required interfaces that are not provided
for (ProvidedInterface service : provided) {
List<RequiredInterface> fulfilled =
- Arrays.asList(SystemAssembler.filterRequiredServices(service,
+ Arrays.asList(filterRequiredServices(service,
reallyRequired));
reallyRequired.removeAll(fulfilled);
}
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<ProvidedInterface> allProvided = new ArrayList<ProvidedInterface>();
+
+ // 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--) {
+++ /dev/null
-/*
- * 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<RequiredInterface> aDescriptors) {
- List<RequiredInterface> required = new ArrayList<RequiredInterface>();
- for (RequiredInterface descriptor : aDescriptors) {
- if (descriptor.implementedBy(aProvided)) {
- required.add(descriptor);
- }
- }
- return required.toArray(new RequiredInterface[0]);
- }
-
- public static ProvidedInterface[] filterProvidedServices(
- RequiredInterface aRequired,
- Collection<ProvidedInterface> aProvided) {
- List<ProvidedInterface> provided = new ArrayList<ProvidedInterface>();
- 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<ProvidedInterface> allProvided = new ArrayList<ProvidedInterface>();
- 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<ProvidedInterface> allProvided = new HashSet<ProvidedInterface>();
- 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<ProvidedInterface> services = new ArrayList<ProvidedInterface>();
- 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);
- }
-
- }
- }
-
-}
import junit.framework.TestCase;
-public class SystemAssemblerTest extends TestCase {
+public class ContainerTest extends TestCase {
private EventTracker<String> _tracker;
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]));
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;
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;