org.apache.xbean.kernel.standard.StandardKernel Maven / Gradle / Ivy
The newest version!
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.xbean.kernel.standard;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;
import org.apache.xbean.kernel.IllegalServiceStateException;
import org.apache.xbean.kernel.Kernel;
import org.apache.xbean.kernel.KernelErrorsError;
import org.apache.xbean.kernel.KernelMonitor;
import org.apache.xbean.kernel.ServiceAlreadyExistsException;
import org.apache.xbean.kernel.ServiceFactory;
import org.apache.xbean.kernel.ServiceMonitor;
import org.apache.xbean.kernel.ServiceName;
import org.apache.xbean.kernel.ServiceNotFoundException;
import org.apache.xbean.kernel.ServiceRegistrationException;
import org.apache.xbean.kernel.ServiceState;
import org.apache.xbean.kernel.StartStrategies;
import org.apache.xbean.kernel.StartStrategy;
import org.apache.xbean.kernel.StopStrategies;
import org.apache.xbean.kernel.StopStrategy;
import org.apache.xbean.kernel.UnregisterServiceException;
import org.apache.xbean.kernel.UnsatisfiedConditionsException;
import org.apache.xbean.kernel.KernelFactory;
/**
* The standard kernel implementation.
*
* @author Dain Sundstrom
* @version $Id$
* @since 2.0
*/
public class StandardKernel implements Kernel {
/**
* The unique name of this kernel.
*/
private final String kernelName;
/**
* The registered service managers.
*/
private final ServiceManagerRegistry serviceManagerRegistry;
/**
* Tracks and broadcasts kernel evnents to the registered listeners.
*/
private final KernelMonitorBroadcaster kernelMonitor = new KernelMonitorBroadcaster();
/**
* This monitor broadcasts events to the listeners registered for service.
*/
private final ServiceMonitorBroadcaster serviceMonitor = new ServiceMonitorBroadcaster(kernelMonitor);
/**
* If true, the kernel is still running.
*/
private boolean running = true;
/**
* Lock that should be acquired before accessing the running boolean flag.
*/
private final Lock destroyLock = new ReentrantLock();
/**
* The condition that is notified when the kernel has been destroyed.
*/
private final Condition destroyCondition = destroyLock.newCondition();
/**
* Creates the service managers with handle service lifecycle.
*/
private ServiceManagerFactory serviceManagerFactory;
/**
* The service executor for this kernel
*/
private ExecutorService serviceExecutor;
/**
* True if the executor is owned by this kernel and should be shutdown
* when the kernel is destroyed
*/
private boolean ownsServiceExecutor;
/**
* Creates a kernel using the specified name.
*
* @param kernelName the unique name of this kernel
*/
public StandardKernel(String kernelName) {
this(kernelName, Executors.newCachedThreadPool(), 30, TimeUnit.SECONDS);
ownsServiceExecutor = true;
}
/**
* Creates a kernel using the specified name.
*
* @param kernelName the unique name of this kernel
* @param serviceExecutor the executor to use for asynchronous service operations
* @param timeoutDuration the maximum duration to wait for a service event to complete
* @param timeoutUnits the unit of measure for the timeoutDuration
*/
public StandardKernel(String kernelName, ExecutorService serviceExecutor, long timeoutDuration, TimeUnit timeoutUnits) {
if (kernelName == null) throw new NullPointerException("kernelName is null");
if (kernelName.length() ==0) throw new IllegalArgumentException("kernelName must be atleast one character long");
if (serviceExecutor == null) throw new NullPointerException("serviceExecutor is null");
if (timeoutUnits == null) throw new NullPointerException("timeoutUnits is null");
this.kernelName = kernelName;
this.serviceExecutor = serviceExecutor;
serviceManagerFactory = new ServiceManagerFactory(this, serviceMonitor, serviceExecutor, timeoutDuration, timeoutUnits);
serviceManagerRegistry = new ServiceManagerRegistry(serviceManagerFactory);
}
/**
* {@inheritDoc}
*/
public void destroy() throws KernelErrorsError {
destroyLock.lock();
try {
// if we are already stopped simply return
if (!running) {
return;
}
running = false;
} finally {
destroyLock.unlock();
}
// destroy all services
serviceManagerRegistry.destroy();
// shutdown service executor
if (ownsServiceExecutor) {
serviceExecutor.shutdown();
}
// remove this kernel from the kernel factory registry
KernelFactory.destroyInstance(this);
// notify threads waiting for destroy to complete
destroyLock.lock();
try {
destroyCondition.signalAll();
} finally {
destroyLock.unlock();
}
}
/**
* {@inheritDoc}
*/
public void waitForDestruction() {
destroyLock.lock();
try {
// if we are already stopped simply return
if (!running) {
return;
}
// wait until destroy completes
destroyCondition.awaitUninterruptibly();
} finally {
destroyLock.unlock();
}
}
/**
* {@inheritDoc}
*/
public boolean isRunning() {
destroyLock.lock();
try {
return running;
} finally {
destroyLock.unlock();
}
}
/**
* {@inheritDoc}
*/
public String getKernelName() {
return kernelName;
}
/**
* {@inheritDoc}
*/
public void registerService(ServiceName serviceName, ServiceFactory serviceFactory) throws ServiceAlreadyExistsException, ServiceRegistrationException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (serviceFactory == null) throw new NullPointerException("serviceFactory is null");
if (!isRunning()) {
throw new ServiceRegistrationException(serviceName, new IllegalStateException("Kernel is destroyed"));
}
serviceManagerRegistry.registerService(serviceName, serviceFactory);
}
/**
* {@inheritDoc}
*/
public void unregisterService(ServiceName serviceName) throws ServiceNotFoundException, ServiceRegistrationException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
unregisterService(serviceName, StopStrategies.SYNCHRONOUS);
}
/**
* {@inheritDoc}
*/
public void unregisterService(ServiceName serviceName, StopStrategy stopStrategy) throws ServiceNotFoundException, ServiceRegistrationException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (stopStrategy == null) throw new NullPointerException("stopStrategy is null");
if (!isRunning()) {
return;
}
serviceManagerRegistry.unregisterService(serviceName, stopStrategy);
}
/**
* {@inheritDoc}
*/
public boolean isRegistered(ServiceName serviceName) {
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (!isRunning()) {
return false;
}
return serviceManagerRegistry.isRegistered(serviceName);
}
/**
* {@inheritDoc}
*/
public ServiceState getServiceState(ServiceName serviceName) throws ServiceNotFoundException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
return serviceManager.getState();
}
/**
* {@inheritDoc}
*/
public long getServiceStartTime(ServiceName serviceName) throws ServiceNotFoundException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
return serviceManager.getStartTime();
}
/**
* {@inheritDoc}
*/
public void startService(ServiceName serviceName) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception {
if (serviceName == null) throw new NullPointerException("serviceName is null");
startService(serviceName, false, StartStrategies.SYNCHRONOUS);
}
/**
* {@inheritDoc}
*/
public void startService(ServiceName serviceName, StartStrategy startStrategy) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception {
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (startStrategy == null) throw new NullPointerException("startStrategy is null");
startService(serviceName, false, startStrategy);
}
/**
* {@inheritDoc}
*/
public void startServiceRecursive(ServiceName serviceName) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception {
if (serviceName == null) throw new NullPointerException("serviceName is null");
startService(serviceName, true, StartStrategies.SYNCHRONOUS);
}
/**
* {@inheritDoc}
*/
public void startServiceRecursive(ServiceName serviceName, StartStrategy startStrategy) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception {
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (startStrategy == null) throw new NullPointerException("startStrategy is null");
startService(serviceName, true, startStrategy);
}
private void startService(ServiceName serviceName, boolean recursive, StartStrategy startStrategy) throws Exception {
if (startStrategy == null) throw new NullPointerException("startStrategy is null");
ServiceManager serviceManager = getServiceManager(serviceName);
try {
serviceManager.start(recursive, startStrategy);
} catch (UnregisterServiceException e) {
try {
unregisterService(serviceName, StopStrategies.FORCE);
} catch (ServiceNotFoundException ignored) {
// that is weird, but what ever
} catch (ServiceRegistrationException ignored) {
// we are alredy throwing an exception so ignore this one
}
Throwable cause = e.getCause();
if (cause instanceof Exception) {
throw (Exception) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
} else {
throw new AssertionError(cause);
}
}
}
/**
* {@inheritDoc}
*/
public void stopService(ServiceName serviceName) throws ServiceNotFoundException, UnsatisfiedConditionsException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
stopService(serviceName, StopStrategies.SYNCHRONOUS);
}
/**
* {@inheritDoc}
*/
public void stopService(ServiceName serviceName, StopStrategy stopStrategy) throws ServiceNotFoundException, UnsatisfiedConditionsException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (stopStrategy == null) throw new NullPointerException("stopStrategy is null");
ServiceManager serviceManager = getServiceManager(serviceName);
serviceManager.stop(stopStrategy);
}
/**
* {@inheritDoc}
*/
public boolean isServiceEnabled(ServiceName serviceName) throws ServiceNotFoundException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
ServiceFactory serviceFactory = serviceManager.getServiceFactory();
return serviceFactory.isEnabled();
}
/**
* {@inheritDoc}
*/
public void setServiceEnabled(ServiceName serviceName, boolean enabled) throws ServiceNotFoundException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
ServiceFactory serviceFactory = serviceManager.getServiceFactory();
serviceFactory.setEnabled(enabled);
}
/**
* {@inheritDoc}
*/
public Object getService(ServiceName serviceName) throws ServiceNotFoundException, IllegalArgumentException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
return serviceManager.getService();
}
/**
* {@inheritDoc}
*/
public Object getService(Class type) {
if (type == null) throw new NullPointerException("type is null");
if (!isRunning()) {
return null;
}
Object service = serviceManagerRegistry.getService(type);
return service;
}
/**
* {@inheritDoc}
*/
public List getServices(Class type) {
if (type == null) throw new NullPointerException("type is null");
if (!isRunning()) {
return null;
}
List services = serviceManagerRegistry.getServices(type);
return services;
}
/**
* {@inheritDoc}
*/
public ServiceFactory getServiceFactory(ServiceName serviceName) throws ServiceNotFoundException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
return serviceManager.getServiceFactory();
}
/**
* {@inheritDoc}
*/
public ServiceFactory getServiceFactory(Class type) {
if (type == null) throw new NullPointerException("type is null");
if (!isRunning()) {
return null;
}
ServiceManager serviceManager = serviceManagerRegistry.getServiceManager(type);
return serviceManager.getServiceFactory();
}
/**
* {@inheritDoc}
*/
public List getServiceFactories(Class type) {
if (type == null) throw new NullPointerException("type is null");
if (!isRunning()) {
return null;
}
List serviceManagers = serviceManagerRegistry.getServiceManagers(type);
List serviceFactories = new ArrayList(serviceManagers.size());
for (Iterator iterator = serviceManagers.iterator(); iterator.hasNext();) {
ServiceManager serviceManager = (ServiceManager) iterator.next();
serviceFactories.add(serviceManager.getServiceFactory());
}
return serviceFactories;
}
/**
* {@inheritDoc}
*/
public ClassLoader getClassLoaderFor(ServiceName serviceName) throws ServiceNotFoundException {
if (serviceName == null) throw new NullPointerException("serviceName is null");
ServiceManager serviceManager = getServiceManager(serviceName);
return serviceManager.getClassLoader();
}
private ServiceManager getServiceManager(ServiceName serviceName) throws ServiceNotFoundException {
if (!isRunning()) {
throw new ServiceNotFoundException(serviceName);
}
ServiceManager serviceManager = serviceManagerRegistry.getServiceManager(serviceName);
return serviceManager;
}
/**
* {@inheritDoc}
*/
public void addKernelMonitor(KernelMonitor kernelMonitor) {
if (kernelMonitor == null) throw new NullPointerException("kernelMonitor is null");
if (!isRunning()) {
throw new IllegalStateException("Kernel is stopped");
}
this.kernelMonitor.addKernelMonitor(kernelMonitor);
}
/**
* {@inheritDoc}
*/
public void removeKernelMonitor(KernelMonitor kernelMonitor) {
if (kernelMonitor == null) throw new NullPointerException("kernelMonitor is null");
this.kernelMonitor.removeKernelMonitor(kernelMonitor);
}
/**
* {@inheritDoc}
*/
public void addServiceMonitor(ServiceMonitor serviceMonitor) {
if (serviceMonitor == null) throw new NullPointerException("serviceMonitor is null");
if (!isRunning()) {
throw new IllegalStateException("Kernel is stopped");
}
addServiceMonitor(serviceMonitor, null);
}
/**
* {@inheritDoc}
*/
public void addServiceMonitor(ServiceMonitor serviceMonitor, ServiceName serviceName) {
if (serviceMonitor == null) throw new NullPointerException("serviceMonitor is null");
if (serviceName == null) throw new NullPointerException("serviceName is null");
if (!isRunning()) {
throw new IllegalStateException("Kernel is stopped");
}
this.serviceMonitor.addServiceMonitor(serviceMonitor, serviceName);
}
/**
* {@inheritDoc}
*/
public void removeServiceMonitor(ServiceMonitor serviceMonitor) {
if (serviceMonitor == null) throw new NullPointerException("serviceMonitor is null");
this.serviceMonitor.removeServiceMonitor(serviceMonitor);
}
}