-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<ProvidedInterface> _provided;
- private List<RequiredInterface> _required;
- private Set<ProvidedInterface> _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;
- _context = null;
- _name = aName;
- _provided = new ArrayList<ProvidedInterface>();
- _provided.addAll(Arrays.asList(aProvided));
- _required = new ArrayList<RequiredInterface>();
- _required.addAll(Arrays.asList(aRequired));
- _running = new HashSet<ProvidedInterface>();
- }
-
- @Override
- public Status getStatus() {
- return _status;
- }
-
- @Override
- public final String getName() {
- return _name;
- }
-
- @Override
- public void addContext(String aContext) {
- if (_context == null ) {
- _context = aContext;
- }
- else {
- _context = aContext + "." + _context;
- }
- }
-
- @Override
- public String getQualifiedName() {
- if ( _context == null ) {
- return getName();
- }
- return _context + "." + getName();
- }
-
- @Override
- public final ProvidedInterface[] getProvidedInterfaces() {
- return _provided.toArray(new ProvidedInterface[0]);
- }
-
- @Override
- public final RequiredInterface[] getRequiredInterfaces() {
- return _required.toArray(new RequiredInterface[0]);
- }
-
- @Override
- public final void start() {
- LOG.info("Initializing '" + getQualifiedName() + "'");
- doStart();
- _status = Status.RUNNING;
- if ( _running.size() != _provided.size()) {
- List<ProvidedInterface> remaining =
- new ArrayList<ProvidedInterface>(_provided);
- remaining.removeAll(_running);
- throw new SystemAssemblyException(getQualifiedName() + ": 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();
-
- /**
- * Implementations must call this method to indicate that a new service has
- * been started.
- *
- * @param aService
- * Service.
- */
- protected final void addService(
- ProvidedInterface aDescriptor, Object aService) {
- LOG.info("Interface '" + getQualifiedName() + "." + aDescriptor.getName() + "' 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;
- }
+public abstract class AbstractComponent<Type> implements Component<Type> {
+ private static final Log LOG = LogFactory.getLog(AbstractComponent.class);
+
+ private ThreadLocal<List<ProvidedInterface>> remaining;
+
+ private String context;
+
+ private String name;
+
+ private List<ProvidedInterface> provided;
+
+ private List<RequiredInterface> required;
+
+ /**
+ * Constructs the subsystem.
+ *
+ * @param aName
+ * Name of the system.
+ * @param aProvided
+ * Provided services.
+ * @param aRequired
+ * Required services.
+ */
+ protected AbstractComponent(String aName,
+ List<ProvidedInterface> aProvided, List<RequiredInterface> aRequired) {
+ remaining = new ThreadLocal<List<ProvidedInterface>>();
+ context = null;
+ name = aName;
+ provided = new ArrayList<ProvidedInterface>(aProvided);
+ required = new ArrayList<RequiredInterface>(aRequired);
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * Creates a new AbstractComponent object.
+ *
+ */
+ protected AbstractComponent(String aName) {
+ this(aName, new ProvidedInterface[0], new RequiredInterface[0]);
+ }
+
+ public AbstractComponent<Type> addProvidedInterface(
+ ProvidedInterface aProvided) {
+ provided.add(aProvided);
+
+ return this;
+ }
+
+ public AbstractComponent<Type> addRequiredInterface(
+ RequiredInterface aRequired) {
+ required.add(aRequired);
+
+ return this;
+ }
+
+ @Override
+ public final String getName() {
+ return name;
+ }
+
+ @Override
+ public void addContext(String aContext) {
+ if (context == null) {
+ context = aContext;
+ } else {
+ context = aContext + "." + context;
+ }
+ }
+
+ @Override
+ public String getContext() {
+ return context;
+ }
+
+ @Override
+ public String getQualifiedName() {
+ if (context == null) {
+ return getName();
+ }
+
+ return context + "." + getName();
+ }
+
+ @Override
+ public final List<ProvidedInterface> getProvidedInterfaces() {
+ return Collections.unmodifiableList(provided);
+ }
+
+ @Override
+ public final List<RequiredInterface> getRequiredInterfaces() {
+ return Collections.unmodifiableList(required);
+ }
+
+ @Override
+ public final Type start(Scope aScope) {
+ LOG.info("Initialization starting '" + getQualifiedName() + "'");
+
+ List<ProvidedInterface> oldRemaining = remaining.get();
+ remaining
+ .set(new ArrayList<ProvidedInterface>(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 #addInterface(ProvidedInterface, Object, Scope)} for
+ * each service that is started.
+ *
+ *
+ * @return Returns the runtime of the component.
+ */
+ 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
+ * Implementation of the interface.
+ * @param aScope
+ * scope in which to publish the implementation.
+ *
+ */
+ 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 void stop(Type aRuntime) {
+ LOG.info("Stopping initiated '" + getQualifiedName() + "'");
+ doStop(aRuntime);
+ LOG.info("Stopping completed '" + getQualifiedName() + "'");
+ }
+
+ protected abstract void doStop(Type aRuntime);
+
+ @Override
+ public String toString() {
+ 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;
+ }
+ }