X-Git-Url: http://wamblee.org/gitweb/?a=blobdiff_plain;f=system%2Fgeneral%2Fsrc%2Fmain%2Fjava%2Forg%2Fwamblee%2Fsystem%2Fcore%2FAbstractComponent.java;h=b8e4e6be9b2f5276b041d44e9e61434c1c503ac0;hb=dea786c9d49228a37cb5fd5b4113b86d9f6cddbf;hp=01eff741ac362aa13e6b0d3280c9ae9975b001d6;hpb=e73828b054b0734ddce0ff9194fca75ed3c98b7a;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 01eff741..b8e4e6be 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,7 +12,7 @@ * 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; @@ -27,19 +27,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 String _context; - private String _name; + private ThreadLocal> _remaining; + + private String _context; + private String _name; private List _provided; private List _required; - private Set _running; - + /** * Constructs the subsystem. - * + * * @param aName * Name of the system. * @param aProvided @@ -49,36 +50,35 @@ public abstract class AbstractComponent implements Component { */ protected AbstractComponent(String aName, ProvidedInterface[] aProvided, RequiredInterface[] aRequired) { - _context = null; + _remaining = new ThreadLocal>(); + _context = null; _name = aName; _provided = new ArrayList(); _provided.addAll(Arrays.asList(aProvided)); _required = new ArrayList(); _required.addAll(Arrays.asList(aRequired)); - _running = new HashSet(); } @Override public final String getName() { return _name; } - + @Override public void addContext(String aContext) { - if (_context == null ) { - _context = aContext; - } - else { + if (_context == null) { + _context = aContext; + } else { _context = aContext + "." + _context; } } - + @Override public String getQualifiedName() { - if ( _context == null ) { - return getName(); + if (_context == null) { + return getName(); } - return _context + "." + getName(); + return _context + "." + getName(); } @Override @@ -92,67 +92,64 @@ public abstract class AbstractComponent implements Component { } @Override - public final void start() { + public final Type start(Scope aScope) { LOG.info("Initializing '" + getQualifiedName() + "'"); - doStart(); - if ( _running.size() != _provided.size()) { - List remaining = - new ArrayList(_provided); - remaining.removeAll(_running); - throw new SystemAssemblyException(getQualifiedName() + ": not all services were started, missing " + remaining); + List oldRemaining = _remaining.get(); + _remaining.set(new ArrayList(Arrays.asList(getProvidedInterfaces()))); + try { + Type runtime = doStart(aScope); + checkNotStartedInterfaces(); + 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. + * + * @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 addInterface( - 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."); + _remaining.get().remove(aDescriptor); + aScope.publishInterface(aDescriptor, aService); } @Override - public ProvidedInterface[] getRunningInterfaces() { - return _running.toArray(new ProvidedInterface[0]); - } - - @Override - public void stop() { - doStop(); - if ( _running.size() > 0 ) { - // programming error. - throw new RuntimeException(getQualifiedName() + ": still services running after the stop call."); - } - } - - protected abstract void doStop(); - - /** - * Implementations must call this method to indicate that a running service has - * been stopped. - * - * @param aService - * Service. - */ - protected final void removeInterface( - ProvidedInterface aDescriptor) { - LOG.info("Interface '" + getQualifiedName() + "." + aDescriptor.getName() + "' stopped."); - _running.remove(aDescriptor); - aDescriptor.publish(null); + public void stop(Type aRuntime) { + doStop(aRuntime); } + protected abstract void doStop(Type aRuntime); + @Override public String toString() { return getQualifiedName();