package org.wamblee.system; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; 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 AbstractComponent implements Component { private static final Log LOG = LogFactory.getLog(AbstractComponent.class); private Status _status; private String _name; private List _provided; private List _required; private Set _running; /** * Constructs the subsystem. * * @param aName * Name of the system. * @param aProvided * Provided services. * @param aRequired * Required services. */ protected AbstractComponent(String aName, ProvidedInterface[] aProvided, RequiredInterface[] aRequired) { _status = Status.NOT_STARTED; _name = aName; _provided = new ArrayList(); _provided.addAll(Arrays.asList(aProvided)); _required = new ArrayList(); _required.addAll(Arrays.asList(aRequired)); _running = new HashSet(); } @Override public Status getStatus() { return _status; } @Override public final String getName() { return _name; } @Override public final ProvidedInterface[] getProvidedServices() { return _provided.toArray(new ProvidedInterface[0]); } @Override public final RequiredInterface[] getRequiredServices() { return _required.toArray(new RequiredInterface[0]); } @Override public final void start(String aContext) { LOG.info("Initializing '" + aContext + "." + _name + "'"); doStart(aContext + "." + getName()); _status = Status.RUNNING; if ( _running.size() != _provided.size()) { List remaining = new ArrayList(_provided); remaining.removeAll(_running); throw new SystemAssemblyException(aContext + "." + getName() + ": not all services were started, missing " + remaining); } } /** * Must be implemented for initializing the subsystem. The implementation * must call {@link #addService(Service)} for each service that is started. */ protected abstract void doStart(String aContext); /** * Implementations must call this method to indicate that a new service has * been started. * * @param aService * Service. */ protected final void addService(String aContext, ProvidedInterface aDescriptor, Object aService) { LOG.info(aContext + ": service '" + aService + "' started."); _running.add(aDescriptor); aDescriptor.publish(aService); } @Override public ProvidedInterface[] getRunningServices() { return _running.toArray(new ProvidedInterface[0]); } @Override public void stop() { doStop(); _status = Status.STOPPED; } protected abstract void doStop(); @Override public String toString() { return _name; } }