package org.wamblee.system; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Abstract subsystem class making it easy to implement new subsystems. */ public abstract class AbstractSubSystem implements SubSystem { private static final Log LOG = LogFactory.getLog(AbstractSubSystem.class); private String _name; private ServiceRegistry _registry; private List _provided; private List _required; private Map _running; /** * Constructs the subsystem. * * @param aRegistry * Registry of services. * @param aName * Name of the system. * @param aProvided * Provided services. * @param aRequired * Required services. */ protected AbstractSubSystem(String aName, ServiceRegistry aRegistry, ServiceDescriptor[] aProvided, ServiceDescriptor[] aRequired) { _name = aName; _registry = aRegistry; _provided = new ArrayList(); _provided.addAll(Arrays.asList(aProvided)); _required = new ArrayList(); _required.addAll(Arrays.asList(aRequired)); _running = new HashMap(); } @Override public final String getName() { return _name; } public ServiceRegistry getRegistry() { return _registry; } @Override public final ServiceDescriptor[] getProvidedServices() { return _provided.toArray(new ServiceDescriptor[0]); } @Override public final ServiceDescriptor[] getRequiredServices() { return _required.toArray(new ServiceDescriptor[0]); } @Override public final Service[] start(String aContext, Service[] aRequiredServices) { LOG.info("Initializing '" + aContext + "." + _name + "' with " + Arrays.asList(aRequiredServices)); doStart(aContext + "." + getName(), aRequiredServices); return _running.values().toArray(new Service[0]); } /** * Must be implemented for initializing the subsystem. The implementation * must call {@link #addService(Service)} for each service that is started. * * @param aRequiredServices * Services that are already running from other subsystems that * may be used. */ protected abstract void doStart(String aContext, Service[] aRequiredServices); /** * Implementations must call this method to indicate that a new service has * been started. * * @param aService * Service. */ protected final void addService(String aContext, ServiceDescriptor aDescriptor, Object aService) { LOG.info(aContext + ": service '" + aService + "' started."); Service svc = getRegistry().register(aDescriptor, aService); _running.put(svc.getDescriptor(), svc); } @Override public Service[] getRunningServices() { return _running.values().toArray(new Service[0]); } @Override public void stop() { doStop(); for (Service svc: _running.values()) { getRegistry().remove(svc); } } protected abstract void doStop(); @Override public String toString() { return _name; } }