📄 server.java
字号:
package net.sf.dz.daemon;import java.net.URL;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.NoSuchElementException;import java.util.Set;import java.util.Stack;import java.util.TreeMap;import java.util.TreeSet;import org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.conf.ConfigurationFactory;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.sem.EventSemaphore;import org.freehold.jukebox.sem.SemaphoreGroup;import org.freehold.jukebox.service.PassiveService;import net.sf.dz.util.ObjectFactory;/** * A generic server. * * @author Copyright © <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2002 * @version $Id: Server.java,v 1.6 2004/06/28 20:35:46 vtt Exp $ */public class Server extends PassiveService { public static final LogChannel CH_SERVER = new LogChannel("Server"); /** * Environment variable to read the configuration from. * * The value of this variable contains the URL or set of URLs to read * the configuration from. */ public static final String ENV_CF_URL = "conf.URL"; /** * Module map. * * The key is the module name, the value is the module itself. The * modules are put here as soon as they are operational. */ private Map moduleMap = new TreeMap(); /** * Module stack. * * The module name is added to the module stack as soon as it is * operational. The purpose is to preserve the order for proper * shutdown. */ private Stack moduleStack = new Stack(); /** * Get the module map. * * @return A clone of the module map. */ public Map getModuleMap() { return new TreeMap(moduleMap); } protected void startup() throws Throwable { String cfURL = System.getProperty(ENV_CF_URL); if ( cfURL == null ) { throw new IllegalArgumentException("Please define " + ENV_CF_URL + " environment property"); } Configuration cf = (new ConfigurationFactory()).getConfiguration(new URL(cfURL)); if ( cf == null ) { throw new IllegalArgumentException("Configuration couldn't be created from " + cfURL); } List modules = cf.getList("server.module"); complain(LOG_DEBUG, CH_SERVER, "Module list: " + modules); // Let's make sure there are no duplicates // VT: FIXME: there's an issue with the way the configuration is // read, so currently it is not possible to check for duplicates. // Let's just remember this. // Time to figure out dependencies. // // Let's create a set of started modules (initially empty), then // browse the list of modules, move the modules with no unsatisfied // dependencies into a different list, and start them. Repeat until // done or until failed. int count = 0; while ( true ) { // Modules with no unresolved dependencies Set modulesReady = new HashSet(); if ( modules.isEmpty() ) { break; } for ( Iterator i = modules.iterator(); i.hasNext(); ) { String name = i.next().toString(); try { // Need to create a clone because otherwise the // configuration will be screwed up? List dep = new LinkedList(cf.getList("server.module." + name + ".requires")); if ( dep.isEmpty() ) { complain(LOG_DEBUG, CH_SERVER, "No dependencies for '" + name + "'"); modulesReady.add(name); i.remove(); } else { complain(LOG_DEBUG, CH_SERVER, "Dependencies for '" + name + "': " + dep); // Let's see if the dependencies were already resolved for ( Iterator di = dep.iterator(); di.hasNext(); ) { String depName = di.next().toString(); if ( moduleMap.containsKey(depName) ) { // One more down complain(LOG_DEBUG, CH_SERVER, name + ": dependency '" + depName + "' started"); di.remove(); } } if ( dep.isEmpty() ) { complain(LOG_DEBUG, CH_SERVER, name + ": all dependencies started"); modulesReady.add(name); i.remove(); } } } catch ( NoSuchElementException nseex ) { // Good, this one doesn't have dependencies. Let's start // it complain(LOG_DEBUG, CH_SERVER, "No dependencies for '" + name + "'", nseex); modulesReady.add(name); i.remove(); } } if ( modulesReady.isEmpty() ) { throw new IllegalStateException("No module dependencies were resolved for " + modules + ", check configuration"); } complain(LOG_DEBUG, CH_SERVER, "Pass " + (count++) + " ready: " + modulesReady); SemaphoreGroup start = new SemaphoreGroup(); Map justStarted = new TreeMap(); for ( Iterator i = modulesReady.iterator(); i.hasNext(); ) { String name = i.next().toString(); try { PassiveService module = instantiate(cf, name); justStarted.put(name, module); start.add(module.start()); } catch ( Throwable t ) { // Oops... Most probably failed to instantiate - there's // basically nothing to fail in start() complain(LOG_WARNING, CH_SERVER, "Failed to instantiate module '" + name + "', cause:", t); } } if ( !start.waitForAll(true) ) { throw new IllegalStateException("Failed to start, check the logs"); } for ( Iterator i = justStarted.keySet().iterator(); i.hasNext(); ) { Object key = i.next(); moduleMap.put(key, justStarted.get(key)); moduleStack.push(key); } } } /** * Instantiate and configure the module. * * @param cf Configuration to use. * * @param name Name of the module to instantiate. * * @return Module instance. */ private PassiveService instantiate(Configuration cf, String name) throws Throwable { complain(LOG_INFO, CH_SERVER, "Instantiating: '" + name + "'"); String moduleClass = cf.getString("server.module." + name + ".class"); PassiveService module = (PassiveService)ObjectFactory.instantiate(moduleClass, PassiveService.class); module.setLogger(getLogger()); module.configure("server.module." + name, cf); ((ServerModule)module).attach(this); return module; } protected void shutdown(Throwable cause) throws Throwable { while ( !moduleStack.isEmpty() ) { String name = moduleStack.pop().toString(); complain(LOG_INFO, CH_SERVER, "Shutting down " + name); PassiveService module = (PassiveService)moduleMap.get(name); module.stop().waitFor(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -