X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2Fcore%2FAbstractComponent.java;h=579fd27435907d4ee9c0db8466fb1bb12db71270;hb=0d8d8f24656e585ee75558cfd6a4c661f8f14985;hp=5d89e4a46f839078c7adc5876bae684a3d2cdb8f;hpb=4845c677310814de4c98e22aad483e49b9dfc594;p=utils diff --git a/system/general/src/main/java/org/wamblee/system/core/AbstractComponent.java b/system/general/src/main/java/org/wamblee/system/core/AbstractComponent.java index 5d89e4a4..579fd274 100644 --- a/system/general/src/main/java/org/wamblee/system/core/AbstractComponent.java +++ b/system/general/src/main/java/org/wamblee/system/core/AbstractComponent.java @@ -12,14 +12,13 @@ * 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.core; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; +import java.util.Collections; import java.util.List; -import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,20 +26,20 @@ import org.apache.commons.logging.LogFactory; /** * Abstract subsystem class making it easy to implement new subsystems. */ -public abstract class AbstractComponent implements Component { +public abstract class AbstractComponent implements Component { private static final Log LOG = LogFactory.getLog(AbstractComponent.class); - private Status _status; - private String _context; - private String _name; - private List _provided; - private List _required; - private Set _running; - + private ThreadLocal> remaining; + + private String context; + private String name; + private List provided; + private List required; + /** * Constructs the subsystem. - * + * * @param aName * Name of the system. * @param aProvided @@ -48,105 +47,167 @@ public abstract class AbstractComponent implements Component { * @param aRequired * Required services. */ - protected AbstractComponent(String aName, ProvidedInterface[] aProvided, - RequiredInterface[] aRequired) { - _status = Status.NOT_STARTED; - _context = null; - _name = aName; - _provided = new ArrayList(); - _provided.addAll(Arrays.asList(aProvided)); - _required = new ArrayList(); - _required.addAll(Arrays.asList(aRequired)); - _running = new HashSet(); + protected AbstractComponent(String aName, List aProvided, + List aRequired) { + remaining = new ThreadLocal>(); + context = null; + name = aName; + provided = new ArrayList(aProvided); + required = new ArrayList(aRequired); } - @Override - public Status getStatus() { - return _status; + /** + * 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) { + this(aName, Arrays.asList(aProvided), Arrays.asList(aRequired)); + } + + protected AbstractComponent(String aName) { + this(aName, new ProvidedInterface[0], new RequiredInterface[0]); } - + + public AbstractComponent addProvidedInterface(ProvidedInterface aProvided) { + provided.add(aProvided); + return this; + } + + public AbstractComponent addRequiredInterface(RequiredInterface aRequired) { + required.add(aRequired); + return this; + } + @Override public final String getName() { - return _name; + return name; } - + @Override public void addContext(String aContext) { - if (_context == null ) { - _context = aContext; - } - else { - _context = aContext + "." + _context; + if (context == null) { + context = aContext; + } else { + context = aContext + "." + context; } } + @Override + public String getContext() { + return context; + } + @Override public String getQualifiedName() { - if ( _context == null ) { - return getName(); + if (context == null) { + return getName(); } - return _context + "." + getName(); + return context + "." + getName(); } @Override - public final ProvidedInterface[] getProvidedServices() { - return _provided.toArray(new ProvidedInterface[0]); + public final List getProvidedInterfaces() { + return Collections.unmodifiableList(provided); } @Override - public final RequiredInterface[] getRequiredServices() { - return _required.toArray(new RequiredInterface[0]); + public final List getRequiredInterfaces() { + return Collections.unmodifiableList(required); } @Override - public final void start() { - LOG.info("Initializing '" + getQualifiedName() + "'"); - doStart(); - _status = Status.RUNNING; - if ( _running.size() != _provided.size()) { - List remaining = - new ArrayList(_provided); - remaining.removeAll(_running); - throw new SystemAssemblyException(getQualifiedName() + ": not all services were started, missing " + remaining); + public final Type start(Scope aScope) { + LOG.info("Initialization starting '" + getQualifiedName() + "'"); + List oldRemaining = remaining.get(); + remaining.set(new ArrayList(getProvidedInterfaces())); + try { + Type runtime = doStart(aScope); + checkNotStartedInterfaces(); + LOG.info("Initialization finished '" + getQualifiedName() + "'"); + return runtime; + } finally { + remaining.set(oldRemaining); + } + } + + private void checkNotStartedInterfaces() { + if (remaining.get().size() > 0) { + String notProvided = ""; + for (ProvidedInterface provided : remaining.get()) { + notProvided += "\nComponent " + getQualifiedName() + + " did not start interface " + provided; + } + throw new SystemAssemblyException(notProvided); } } /** * Must be implemented for initializing the subsystem. The implementation - * must call {@link #addService(Service)} for each service that is started. + * must call {@link #addInterface(ProvidedInterface, Object, Scope)} for each service that is started. + * + * @return Returns the runtime of the component. */ - protected abstract void doStart(); + protected abstract Type doStart(Scope aScope); /** * Implementations must call this method to indicate that a new service has * been started. * + * @param aDescriptor + * Provided interface. * @param aService - * Service. + * Implementation of the interface. + * @param aScope + * scope in which to publish the implementation. */ - protected final void addService( - ProvidedInterface aDescriptor, Object aService) { - LOG.info("Interface '" + getQualifiedName() + "." + aDescriptor.getName() + "' started."); - _running.add(aDescriptor); - aDescriptor.publish(aService); + protected final void addInterface(ProvidedInterface aDescriptor, + Object aService, Scope aScope) { + LOG.info("Interface '" + getQualifiedName() + "." + + aDescriptor.getName() + "' started."); + if ( !remaining.get().remove(aDescriptor) ) { + throw new SystemAssemblyException("Component '" + getQualifiedName() + "' started an unexpected interface '" + + aDescriptor + "' that was not registerd as a provided interface before"); + } + aScope.publishInterface(aDescriptor, aService); } @Override - public ProvidedInterface[] getRunningServices() { - return _running.toArray(new ProvidedInterface[0]); + public void stop(Type aRuntime) { + LOG.info("Stopping initiated '" + getQualifiedName() + "'"); + doStop(aRuntime); + LOG.info("Stopping completed '" + getQualifiedName() + "'"); } - - @Override - public void stop() { - doStop(); - _status = Status.STOPPED; - } - - protected abstract void doStop(); + + protected abstract void doStop(Type aRuntime); @Override public String toString() { - return _name; + return getQualifiedName(); + } + + public ProvidedInterface findProvidedInterface(String aName) { + for (ProvidedInterface provided: getProvidedInterfaces()) { + if ( provided.getName().equals(aName)) { + return provided; + } + } + return null; + } + + public RequiredInterface findRequiredInterface(String aName) { + for (RequiredInterface required: getRequiredInterfaces()) { + if ( required.getName().equals(aName)) { + return required; + } + } + return null; } }