All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy