Frames | No Frames |
1: /* ======================================================================== 2: * JCommon : a free general purpose class library for the Java(tm) platform 3: * ======================================================================== 4: * 5: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jcommon/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ----------------- 28: * AbstractBoot.java 29: * ----------------- 30: * (C)opyright 2004, 2005, by Thomas Morgner and Contributors. 31: * 32: * Original Author: Thomas Morgner; 33: * Contributor(s): David Gilbert (for Object Refinery Limited); 34: * 35: * $Id: AbstractBoot.java,v 1.18 2006/06/20 18:43:15 taqua Exp $ 36: * 37: * Changes 38: * ------- 39: * 07-Jun-2004 : Added source headers (DG); 40: * 18-Aug-2005 : Added casts to suppress compiler warnings, as suggested in 41: * patch 1260622 (DG); 42: * 43: */ 44: 45: package org.jfree.base; 46: 47: import java.io.IOException; 48: import java.io.InputStream; 49: import java.lang.reflect.Method; 50: import java.net.URL; 51: import java.util.ArrayList; 52: import java.util.Enumeration; 53: 54: import org.jfree.base.config.HierarchicalConfiguration; 55: import org.jfree.base.config.PropertyFileConfiguration; 56: import org.jfree.base.config.SystemPropertyConfiguration; 57: import org.jfree.base.modules.PackageManager; 58: import org.jfree.base.modules.SubSystem; 59: import org.jfree.util.Configuration; 60: import org.jfree.util.ExtendedConfiguration; 61: import org.jfree.util.ExtendedConfigurationWrapper; 62: import org.jfree.util.Log; 63: import org.jfree.util.ObjectUtilities; 64: 65: /** 66: * The common base for all Boot classes. 67: * <p> 68: * This initializes the subsystem and all dependent subsystems. 69: * Implementors of this class have to provide a public static 70: * getInstance() method which returns a singleton instance of the 71: * booter implementation. 72: * <p> 73: * Further creation of Boot object should be prevented using 74: * protected or private constructors in that class, or proper 75: * initialzation cannot be guaranteed. 76: * 77: * @author Thomas Morgner 78: */ 79: public abstract class AbstractBoot implements SubSystem { 80: 81: /** The configuration wrapper around the plain configuration. */ 82: private ExtendedConfigurationWrapper extWrapper; 83: 84: /** A packageManager instance of the package manager. */ 85: private PackageManager packageManager; 86: 87: /** Global configuration. */ 88: private Configuration globalConfig; 89: 90: /** A flag indicating whether the booting is currenly in progress. */ 91: private boolean bootInProgress; 92: 93: /** A flag indicating whether the booting is complete. */ 94: private boolean bootDone; 95: 96: /** 97: * Default constructor. 98: */ 99: protected AbstractBoot() { 100: } 101: 102: /** 103: * Returns the packageManager instance of the package manager. 104: * 105: * @return The package manager. 106: */ 107: public synchronized PackageManager getPackageManager() { 108: if (this.packageManager == null) { 109: this.packageManager = PackageManager.createInstance(this); 110: } 111: return this.packageManager; 112: } 113: 114: /** 115: * Returns the global configuration. 116: * 117: * @return The global configuration. 118: */ 119: public synchronized Configuration getGlobalConfig() { 120: if (this.globalConfig == null) { 121: this.globalConfig = loadConfiguration(); 122: } 123: return this.globalConfig; 124: } 125: 126: /** 127: * Checks, whether the booting is in progress. 128: * 129: * @return true, if the booting is in progress, false otherwise. 130: */ 131: public final synchronized boolean isBootInProgress() { 132: return this.bootInProgress; 133: } 134: 135: /** 136: * Checks, whether the booting is complete. 137: * 138: * @return true, if the booting is complete, false otherwise. 139: */ 140: public final synchronized boolean isBootDone() { 141: return this.bootDone; 142: } 143: 144: /** 145: * Loads the configuration. This will be called exactly once. 146: * 147: * @return The configuration. 148: */ 149: protected abstract Configuration loadConfiguration(); 150: 151: /** 152: * Starts the boot process. 153: */ 154: public final void start() { 155: 156: synchronized (this) { 157: if (isBootDone()) { 158: return; 159: } 160: while (isBootInProgress()) { 161: try { 162: wait(); 163: } 164: catch (InterruptedException e) { 165: // ignore .. 166: } 167: } 168: this.bootInProgress = true; 169: } 170: 171: // boot dependent libraries ... 172: final BootableProjectInfo info = getProjectInfo(); 173: if (info != null) { 174: final BootableProjectInfo[] childs = info.getDependencies(); 175: for (int i = 0; i < childs.length; i++) { 176: final AbstractBoot boot = loadBooter(childs[i].getBootClass()); 177: if (boot != null) { 178: // but we're waiting until the booting is complete ... 179: synchronized(boot) { 180: boot.start(); 181: while (boot.isBootDone() == false) { 182: try { 183: boot.wait(); 184: } 185: catch (InterruptedException e) { 186: // ignore it .. 187: } 188: } 189: } 190: } 191: } 192: } 193: 194: performBoot(); 195: if (info != null) 196: { 197: Log.info (info.getName() + " " + info.getVersion() + " started."); 198: } 199: else 200: { 201: Log.info (getClass() + " started."); 202: } 203: 204: synchronized (this) { 205: this.bootInProgress = false; 206: this.bootDone = true; 207: notifyAll(); 208: } 209: } 210: 211: /** 212: * Performs the boot. 213: */ 214: protected abstract void performBoot(); 215: 216: /** 217: * Returns the project info. 218: * 219: * @return The project info. 220: */ 221: protected abstract BootableProjectInfo getProjectInfo(); 222: 223: /** 224: * Loads the specified booter implementation. 225: * 226: * @param classname the class name. 227: * 228: * @return The boot class. 229: */ 230: protected AbstractBoot loadBooter(final String classname) { 231: if (classname == null) { 232: return null; 233: } 234: try { 235: final Class c = ObjectUtilities.getClassLoader( 236: getClass()).loadClass(classname); 237: final Method m = c.getMethod("getInstance", (Class[]) null); 238: return (AbstractBoot) m.invoke(null, (Object[]) null); 239: } 240: catch (Exception e) { 241: Log.info ("Unable to boot dependent class: " + classname); 242: return null; 243: } 244: } 245: 246: /** 247: * Creates a default configuration setup, which loads its settings from 248: * the static configuration (defaults provided by the developers of the 249: * library) and the user configuration (settings provided by the deployer). 250: * The deployer's settings override the developer's settings. 251: * 252: * If the parameter <code>addSysProps</code> is set to true, the system 253: * properties will be added as third configuration layer. The system 254: * properties configuration allows to override all other settings. 255: * 256: * @param staticConfig the resource name of the developers configuration 257: * @param userConfig the resource name of the deployers configuration 258: * @param addSysProps a flag defining whether to include the system 259: * properties into the configuration. 260: * @return the configured Configuration instance. 261: */ 262: protected Configuration createDefaultHierarchicalConfiguration 263: (final String staticConfig, final String userConfig, 264: final boolean addSysProps) 265: { 266: final HierarchicalConfiguration globalConfig 267: = new HierarchicalConfiguration(); 268: 269: if (staticConfig != null) { 270: final PropertyFileConfiguration rootProperty 271: = new PropertyFileConfiguration(); 272: rootProperty.load(staticConfig); 273: globalConfig.insertConfiguration(rootProperty); 274: globalConfig.insertConfiguration( 275: getPackageManager().getPackageConfiguration()); 276: } 277: if (userConfig != null) { 278: String userConfigStripped; 279: if (userConfig.startsWith("/")) { 280: userConfigStripped = userConfig.substring(1); 281: } 282: else { 283: userConfigStripped = userConfig; 284: } 285: try { 286: final Enumeration userConfigs = ObjectUtilities.getClassLoader 287: (getClass()).getResources(userConfigStripped); 288: final ArrayList configs = new ArrayList(); 289: while (userConfigs.hasMoreElements()) { 290: final URL url = (URL) userConfigs.nextElement(); 291: try { 292: final PropertyFileConfiguration baseProperty = 293: new PropertyFileConfiguration(); 294: final InputStream in = url.openStream(); 295: baseProperty.load(in); 296: in.close(); 297: configs.add(baseProperty); 298: } 299: catch(IOException ioe) { 300: Log.warn ("Failed to load the user configuration at " + url, ioe); 301: } 302: } 303: 304: for (int i = configs.size() - 1; i >= 0; i--) { 305: final PropertyFileConfiguration baseProperty = 306: (PropertyFileConfiguration) configs.get(i); 307: globalConfig.insertConfiguration(baseProperty); 308: } 309: } 310: catch (IOException e) { 311: Log.warn ("Failed to lookup the user configurations.", e); 312: } 313: } 314: final SystemPropertyConfiguration systemConfig 315: = new SystemPropertyConfiguration(); 316: globalConfig.insertConfiguration(systemConfig); 317: return globalConfig; 318: } 319: 320: /** 321: * Returns the global configuration as extended configuration. 322: * 323: * @return the extended configuration. 324: */ 325: public synchronized ExtendedConfiguration getExtendedConfig () 326: { 327: if (extWrapper == null) { 328: extWrapper = new ExtendedConfigurationWrapper(getGlobalConfig()); 329: } 330: return extWrapper; 331: } 332: }