| /** |
| * |
| * Copyright 2005 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.gbean.kernel.standard; |
| |
| import edu.emory.mathcs.backport.java.util.concurrent.Executor; |
| import edu.emory.mathcs.backport.java.util.concurrent.Executors; |
| import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit; |
| import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean; |
| import org.gbean.kernel.IllegalServiceStateException; |
| import org.gbean.kernel.Kernel; |
| import org.gbean.kernel.KernelErrorsError; |
| import org.gbean.kernel.KernelMonitor; |
| import org.gbean.kernel.KernelMonitorBroadcaster; |
| import org.gbean.kernel.ServiceAlreadyExistsException; |
| import org.gbean.kernel.ServiceFactory; |
| import org.gbean.kernel.ServiceMonitor; |
| import org.gbean.kernel.ServiceMonitorBroadcaster; |
| import org.gbean.kernel.ServiceName; |
| import org.gbean.kernel.ServiceNotFoundException; |
| import org.gbean.kernel.ServiceRegistrationException; |
| import org.gbean.kernel.ServiceState; |
| import org.gbean.kernel.StartStrategies; |
| import org.gbean.kernel.StartStrategy; |
| import org.gbean.kernel.StopStrategies; |
| import org.gbean.kernel.StopStrategy; |
| import org.gbean.kernel.UnregisterServiceException; |
| import org.gbean.kernel.UnsatisfiedConditionsException; |
| |
| /** |
| * The standard kernel implementation. |
| * |
| * @author Dain Sundstrom |
| * @version $Id$ |
| * @since 1.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 final AtomicBoolean running = new AtomicBoolean(true); |
| private ServiceManagerFactory serviceManagerFactory; |
| |
| /** |
| * 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); |
| } |
| |
| /** |
| * 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, Executor serviceExecutor, long timeoutDuration, TimeUnit timeoutUnits) { |
| this.kernelName = kernelName; |
| serviceManagerFactory = new ServiceManagerFactory(this, serviceMonitor, serviceExecutor, timeoutDuration, timeoutUnits); |
| serviceManagerRegistry = new ServiceManagerRegistry(serviceManagerFactory); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void destroy() throws KernelErrorsError { |
| // if we are already stopped return |
| if (!running.compareAndSet(true, false)) { |
| return; |
| } |
| |
| serviceManagerRegistry.destroy(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isRunning() { |
| return running.get(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public String getKernelName() { |
| return kernelName; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void registerService(ServiceName serviceName, ServiceFactory serviceFactory, ClassLoader classLoader) throws ServiceAlreadyExistsException, ServiceRegistrationException { |
| if (serviceName == null) throw new NullPointerException("serviceName is null"); |
| if (serviceFactory == null) throw new NullPointerException("serviceFactory is null"); |
| if (classLoader == null) throw new NullPointerException("classLoader is null"); |
| if (!isRunning()) { |
| throw new ServiceRegistrationException(serviceName, new IllegalStateException("Kernel is destroyed")); |
| } |
| |
| serviceManagerRegistry.registerService(serviceName, serviceFactory, classLoader); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void unregisterService(ServiceName serviceName) throws ServiceNotFoundException, ServiceRegistrationException { |
| 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 { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| return serviceManager.getState(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public long getServiceStartTime(ServiceName serviceName) throws ServiceNotFoundException { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| return serviceManager.getStartTime(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void startService(ServiceName serviceName) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception { |
| startService(serviceName, false, StartStrategies.SYNCHRONOUS); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void startService(ServiceName serviceName, StartStrategy startStrategy) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception { |
| startService(serviceName, false, startStrategy); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void startServiceRecursive(ServiceName serviceName) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception { |
| startService(serviceName, true, StartStrategies.SYNCHRONOUS); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void startServiceRecursive(ServiceName serviceName, StartStrategy startStrategy) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception { |
| 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 { |
| stopService(serviceName, StopStrategies.SYNCHRONOUS); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void stopService(ServiceName serviceName, StopStrategy stopStrategy) throws ServiceNotFoundException, UnsatisfiedConditionsException { |
| if (stopStrategy == null) throw new NullPointerException("stopStrategy is null"); |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| serviceManager.stop(stopStrategy); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public boolean isServiceEnabled(ServiceName serviceName) throws ServiceNotFoundException { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| ServiceFactory serviceFactory = serviceManager.getServiceFactory(); |
| return serviceFactory.isEnabled(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void setServiceEnabled(ServiceName serviceName, boolean enabled) throws ServiceNotFoundException { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| ServiceFactory serviceFactory = serviceManager.getServiceFactory(); |
| serviceFactory.setEnabled(enabled); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public Object getService(ServiceName serviceName) throws ServiceNotFoundException, IllegalArgumentException { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| return serviceManager.getService(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public ServiceFactory getServiceFactory(ServiceName serviceName) throws ServiceNotFoundException { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| return serviceManager.getServiceFactory(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public ClassLoader getClassLoaderFor(ServiceName serviceName) throws ServiceNotFoundException { |
| ServiceManager serviceManager = getServiceManager(serviceName); |
| return serviceManager.getClassLoader(); |
| } |
| |
| private ServiceManager getServiceManager(ServiceName serviceName) throws ServiceNotFoundException { |
| if (serviceName == null) throw new NullPointerException("serviceName is null"); |
| 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"); |
| checkKernelState(); |
| 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"); |
| checkKernelState(); |
| addServiceMonitor(serviceMonitor, null); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void addServiceMonitor(ServiceMonitor serviceMonitor, ServiceName serviceName) { |
| if (serviceMonitor == null) throw new NullPointerException("serviceMonitor is null"); |
| checkKernelState(); |
| this.serviceMonitor.removeServiceMonitor(serviceMonitor); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void removeServiceMonitor(ServiceMonitor serviceMonitor) { |
| if (serviceMonitor == null) throw new NullPointerException("serviceMonitor is null"); |
| this.serviceMonitor.removeServiceMonitor(serviceMonitor); |
| } |
| |
| private void checkKernelState() { |
| if (!running.get()) { |
| throw new IllegalStateException("Kernel is stopped"); |
| } |
| } |
| } |