/* * Copyright 2007 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * 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.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 _context; 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; _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 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 remaining = new ArrayList(_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; } }