blob: f3905601bb9ec03c482da970f68c5915d8b99f5f [file] [log] [blame]
/**
*
* 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.simple;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Set;
import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gbean.kernel.DependencyManager;
import org.gbean.kernel.Kernel;
import org.gbean.kernel.KernelRegistry;
import org.gbean.kernel.LifecycleListener;
import org.gbean.kernel.ServiceAlreadyExistsException;
import org.gbean.kernel.ServiceNotFoundException;
import org.gbean.kernel.runtime.ServiceInstance;
import org.gbean.service.AbstractServiceFactory;
import org.gbean.service.ServiceContext;
import org.gbean.service.ServiceFactory;
/**
* @version $Rev: 154947 $ $Date: 2005-02-22 20:10:45 -0800 (Tue, 22 Feb 2005) $
*/
public class SimpleKernel implements Kernel {
/**
* Name of this kernel
*/
private final String kernelName;
/**
* The log
*/
private Log log;
/**
* Is this kernel running?
*/
private boolean running;
/**
* The timestamp when the kernel was started
*/
private Date bootTime;
/**
* The simple registry
*/
private final SimpleRegistry registry;
/**
* Listeners for when the kernel shutdown
*/
private final LinkedList shutdownHooks = new LinkedList();
/**
* This manager is used by the kernel to manage dependencies between services
*/
private final DependencyManager dependencyManager;
/**
* Monitors the lifecycle of all services.
*/
private final SimpleLifecycleMonitor lifecycleMonitor;
/**
* Construct a Kernel with the specified name.
*
* @param kernelName the name of the kernel
*/
public SimpleKernel(String kernelName) {
if (kernelName.indexOf(':') >= 0 || kernelName.indexOf('*') >= 0 || kernelName.indexOf('?') >= 0) {
throw new IllegalArgumentException("Kernel name may not contain a ':', '*' or '?' character");
}
this.kernelName = kernelName;
lifecycleMonitor = new SimpleLifecycleMonitor();
this.registry = new SimpleRegistry(kernelName);
dependencyManager = new SimpleDependencyManager(this);
}
public String getKernelName() {
return kernelName;
}
/**
* @deprecated Do not use. This is only here for the geronimo bridge and will go away as soon as possible.
*/
public DependencyManager getDependencyManager() {
return dependencyManager;
}
public boolean isLoaded(ObjectName name) {
return registry.isRegistered(name);
}
public void loadService(ObjectName objectName, ServiceFactory serviceFactory, ClassLoader classLoader) throws ServiceAlreadyExistsException {
ServiceInstance serviceInstance = new ServiceInstance(objectName,
serviceFactory,
this,
dependencyManager,
lifecycleMonitor.createLifecycleBroadcaster(objectName),
classLoader);
registry.register(objectName, serviceInstance);
serviceInstance.init();
}
public void startService(ObjectName name) throws ServiceNotFoundException, IllegalStateException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
serviceInstance.start();
}
public void startRecursiveService(ObjectName name) throws ServiceNotFoundException, IllegalStateException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
serviceInstance.startRecursive();
}
public void stopService(ObjectName name) throws ServiceNotFoundException, IllegalStateException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
serviceInstance.stop();
}
public void unloadService(ObjectName name) throws ServiceNotFoundException, IllegalStateException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
serviceInstance.destroy();
registry.unregister(name);
}
public Object getService(ObjectName name) throws ServiceNotFoundException, IllegalStateException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
Object instance = serviceInstance.getInstance();
if (instance == null) {
throw new IllegalStateException("Service is not running: " + name);
}
return instance;
}
public ServiceFactory getServiceFactory(ObjectName name) throws ServiceNotFoundException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
return serviceInstance.getServiceFactory();
}
public int getServiceState(ObjectName name) throws ServiceNotFoundException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
return serviceInstance.getState();
}
public long getServiceStartTime(ObjectName name) throws ServiceNotFoundException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
return serviceInstance.getStartTime();
}
public boolean isServiceEnabled(ObjectName name) throws ServiceNotFoundException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
return serviceInstance.isEnabled();
}
public void setServiceEnabled(ObjectName name, boolean enabled) throws ServiceNotFoundException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
serviceInstance.setEnabled(enabled);
}
public Collection listServices(ObjectName pattern) {
Set serviceInstances = registry.listServiceInstances(pattern);
ArrayList services = new ArrayList(serviceInstances.size());
for (Iterator iterator = serviceInstances.iterator(); iterator.hasNext();) {
ServiceInstance serviceInstance = (ServiceInstance) iterator.next();
Object service = serviceInstance.getInstance();
if (service != null) {
services.add(service);
}
}
return services;
}
public Set listServices(Set patterns) {
Set services = new HashSet();
for (Iterator iterator = patterns.iterator(); iterator.hasNext();) {
ObjectName pattern = (ObjectName) iterator.next();
services.addAll(listServices(pattern));
}
return services;
}
public Set listServiceNames(ObjectName pattern) {
return registry.listServiceNames(pattern);
}
public Set listServiceNames(Set patterns) {
Set services = new HashSet();
for (Iterator iterator = patterns.iterator(); iterator.hasNext();) {
ObjectName pattern = (ObjectName) iterator.next();
services.addAll(listServiceNames(pattern));
}
return services;
}
public void addLifecycleListener(LifecycleListener lifecycleListener, ObjectName pattern) {
addLifecycleListener(lifecycleListener, Collections.singleton(pattern));
}
public void addLifecycleListener(LifecycleListener lifecycleListener, Set patterns) {
lifecycleMonitor.addLifecycleListener(lifecycleListener, patterns);
}
public void removeLifecycleListener(LifecycleListener lifecycleListener) {
lifecycleMonitor.removeLifecycleListener(lifecycleListener);
}
/**
* Boot this Kernel
*
* @throws Exception if the boot fails
*/
public void boot() throws Exception {
if (running) {
return;
}
bootTime = new Date();
log = LogFactory.getLog(SimpleKernel.class.getName());
log.info("Starting boot");
lifecycleMonitor.start();
registry.start();
dependencyManager.start();
// mount the kernel into the kernel itself so it can be accessed just like
// any other service in the system
ServiceFactory kernelServiceFactory = new AbstractServiceFactory() {
public Object createService(ServiceContext serviceContext) throws Exception {
return SimpleKernel.this;
}
};
loadService(KERNEL, kernelServiceFactory, getClass().getClassLoader());
startService(KERNEL);
running = true;
log.info("Booted");
KernelRegistry.registerKernel(this);
}
public Date getBootTime() {
return bootTime;
}
public void registerShutdownHook(Runnable hook) {
assert hook != null : "Shutdown hook was null";
synchronized (shutdownHooks) {
shutdownHooks.add(hook);
}
}
public void unregisterShutdownHook(Runnable hook) {
synchronized (shutdownHooks) {
shutdownHooks.remove(hook);
}
}
/**
* Shutdown this kernel
*/
public void shutdown() {
if (!running) {
return;
}
running = false;
log.info("Starting kernel shutdown");
notifyShutdownHooks();
dependencyManager.stop();
registry.stop();
lifecycleMonitor.stop();
synchronized (this) {
notify();
}
KernelRegistry.unregisterKernel(this);
log.info("Kernel shutdown complete");
}
private void notifyShutdownHooks() {
while (!shutdownHooks.isEmpty()) {
Runnable hook;
synchronized (shutdownHooks) {
hook = (Runnable) shutdownHooks.removeLast();
}
try {
hook.run();
} catch (Throwable e) {
log.warn("Error from kernel shutdown hook", e);
}
}
}
public boolean isRunning() {
return running;
}
public ClassLoader getClassLoaderFor(ObjectName name) throws ServiceNotFoundException {
ServiceInstance serviceInstance = registry.getServiceInstance(name);
return serviceInstance.getClassLoader();
}
}