package org.wamblee.system; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wamblee.system.Component.Status; /** * Abstract subsystem class making it easy to implement new subsystems. */ public abstract class AbstractComponent implements Component { private static final Log LOG = LogFactory.getLog(AbstractComponent.class); private Status _status; 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 AbstractComponent(String aName, ServiceRegistry aRegistry, InterfaceDescriptor[] aProvided, InterfaceDescriptor[] aRequired) { _status = Status.NOT_STARTED; _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 Status getStatus() { return _status; } @Override public final String getName() { return _name; } public ServiceRegistry getRegistry() { return _registry; } @Override public final ProvidedInterfaceDescriptor[] getProvidedServices() { return _provided.toArray(new ProvidedInterfaceDescriptor[0]); } @Override public final RequiredInterfaceDescriptor[] getRequiredServices() { return _required.toArray(new RequiredInterfaceDescriptor[0]); } @Override public final Service[] start(String aContext, Service[] aRequiredServices) { LOG.info("Initializing '" + aContext + "." + _name + "' with " + Arrays.asList(aRequiredServices)); doStart(aContext + "." + getName(), aRequiredServices); _status = Status.RUNNING; 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, ProvidedInterfaceDescriptor 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); } _status = Status.STOPPED; } protected abstract void doStop(); @Override public String toString() { return _name; } }