1 package org.wamblee.system;
3 import java.util.ArrayList;
4 import java.util.HashMap;
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
12 * Assembler to control multiple subsystems. It makes sure that
13 * all dependencies are met and controls the order in which systems
16 public class SystemAssembler {
18 private static final Log LOG = LogFactory.getLog(SystemAssembler.class);
20 private static final String ROOT_CONTEXT_NAME = "root";
21 private String _context;
22 private SubSystem[] _systems;
25 * Constructs the assembler.
26 * @param aSystems Systems that must be assembled.
27 * @param aAvailableServices Available services from other systems
28 * outside of the systems that this assembler manages.
30 public SystemAssembler(SubSystem[] aSystems, ServiceDescriptor[] aAvailableServices) {
31 this(ROOT_CONTEXT_NAME, aSystems, aAvailableServices);
35 * Constructs the assembler.
36 * @param aContext Context (unique name) of the assembler.
37 * @param aSystems Systems that must be assembled.
38 * @param aAvailableServices Available services from other systems
39 * outside of the systems that this assembler manages.
41 public SystemAssembler(String aContext, SubSystem[] aSystems,
42 ServiceDescriptor[] aAvailableServices) {
45 validate(aAvailableServices);
49 * Determines if the systems are ordered appropriately so that all
50 * dependencies are met.
52 private void validate(ServiceDescriptor[] aDescriptors) throws SystemAssemblyException {
54 List<ServiceDescriptor> allProvided = new ArrayList<ServiceDescriptor>();
55 for (ServiceDescriptor descriptor: aDescriptors) {
56 allProvided.add(descriptor);
58 for (SubSystem system : _systems) {
59 // Check if all required services are already provided by earlier
61 ServiceDescriptor[] required = system.getRequiredServices();
62 for (ServiceDescriptor descriptor : required) {
63 if (!(allProvided.contains(descriptor))) {
64 throw new SystemAssemblyException(
67 + "' required by system '"
69 + "' is not provided by systems that are started earlier");
73 // add all provided services
74 ServiceDescriptor[] provided = system.getProvidedServices();
75 for (ServiceDescriptor descriptor : provided) {
76 allProvided.add(descriptor);
82 * Starts the subsystems.
83 * @param aRequiredServices Services that are available from
84 * other systems that have been started before.
86 public void start(Service[] aRequiredServices) {
87 LOG.info("Starting '" + _context + "'");
88 Map<ServiceDescriptor, Service> allProvided = new HashMap<ServiceDescriptor, Service>();
90 for (Service service : aRequiredServices) {
91 allProvided.put(service.getDescriptor(), service);
93 for (SubSystem system : _systems) {
94 ServiceDescriptor[] descriptors = system.getRequiredServices();
95 List<Service> services = new ArrayList<Service>();
96 for (ServiceDescriptor descriptor : descriptors) {
97 Service required = allProvided.get(descriptor);
98 if (required == null) {
99 throw new SystemAssemblyException("Service '" + descriptor
100 + "' required by '" + system + "' is null.");
102 services.add(required);
104 Service[] provided = system.initialize(_context, services
105 .toArray(new Service[0]));
106 for (Service service : provided) {
107 allProvided.put(service.getDescriptor(), service);