001 /* ======================================================================== 002 * JCommon : a free general purpose class library for the Java(tm) platform 003 * ======================================================================== 004 * 005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jcommon/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 025 * in the United States and other countries.] 026 * 027 * ----------------- 028 * AbstractBoot.java 029 * ----------------- 030 * (C)opyright 2004, 2005, by Thomas Morgner and Contributors. 031 * 032 * Original Author: Thomas Morgner; 033 * Contributor(s): David Gilbert (for Object Refinery Limited); 034 * 035 * $Id: AbstractBoot.java,v 1.13 2005/11/03 09:54:59 mungady Exp $ 036 * 037 * Changes 038 * ------- 039 * 07-Jun-2004 : Added source headers (DG); 040 * 18-Aug-2005 : Added casts to suppress compiler warnings, as suggested in 041 * patch 1260622 (DG); 042 * 043 */ 044 045 package org.jfree.base; 046 047 import java.lang.reflect.Method; 048 049 import org.jfree.base.config.HierarchicalConfiguration; 050 import org.jfree.base.config.PropertyFileConfiguration; 051 import org.jfree.base.config.SystemPropertyConfiguration; 052 import org.jfree.base.modules.PackageManager; 053 import org.jfree.base.modules.SubSystem; 054 import org.jfree.util.Configuration; 055 import org.jfree.util.Log; 056 import org.jfree.util.ObjectUtilities; 057 import org.jfree.util.ExtendedConfiguration; 058 import org.jfree.util.ExtendedConfigurationWrapper; 059 060 /** 061 * The common base for all Boot classes. 062 * <p> 063 * This initializes the subsystem and all dependent subsystems. 064 * Implementors of this class have to provide a public static 065 * getInstance() method which returns a singleton instance of the 066 * booter implementation. 067 * <p> 068 * Further creation of Boot object should be prevented using 069 * protected or private constructors in that class, or proper 070 * initialzation cannot be guaranteed. 071 * 072 * @author Thomas Morgner 073 */ 074 public abstract class AbstractBoot implements SubSystem { 075 076 /** The configuration wrapper around the plain configuration. */ 077 private ExtendedConfigurationWrapper extWrapper; 078 079 /** A packageManager instance of the package manager. */ 080 private PackageManager packageManager; 081 082 /** Global configuration. */ 083 private Configuration globalConfig; 084 085 /** A flag indicating whether the booting is currenly in progress. */ 086 private boolean bootInProgress; 087 088 /** A flag indicating whether the booting is complete. */ 089 private boolean bootDone; 090 091 /** 092 * Default constructor. 093 */ 094 protected AbstractBoot() { 095 } 096 097 /** 098 * Returns the packageManager instance of the package manager. 099 * 100 * @return The package manager. 101 */ 102 public synchronized PackageManager getPackageManager() { 103 if (this.packageManager == null) { 104 this.packageManager = PackageManager.createInstance(this); 105 } 106 return this.packageManager; 107 } 108 109 /** 110 * Returns the global configuration. 111 * 112 * @return The global configuration. 113 */ 114 public synchronized Configuration getGlobalConfig() { 115 if (this.globalConfig == null) { 116 this.globalConfig = loadConfiguration(); 117 start(); 118 } 119 return this.globalConfig; 120 } 121 122 /** 123 * Checks, whether the booting is in progress. 124 * 125 * @return true, if the booting is in progress, false otherwise. 126 */ 127 public final synchronized boolean isBootInProgress() { 128 return this.bootInProgress; 129 } 130 131 /** 132 * Checks, whether the booting is complete. 133 * 134 * @return true, if the booting is complete, false otherwise. 135 */ 136 public final synchronized boolean isBootDone() { 137 return this.bootDone; 138 } 139 140 /** 141 * Loads the configuration. This will be called exactly once. 142 * 143 * @return The configuration. 144 */ 145 protected abstract Configuration loadConfiguration(); 146 147 /** 148 * Starts the boot process. 149 */ 150 public final void start() { 151 152 synchronized (this) { 153 if (isBootInProgress() || isBootDone()) { 154 return; 155 } 156 this.bootInProgress = true; 157 } 158 159 // boot dependent libraries ... 160 final BootableProjectInfo info = getProjectInfo(); 161 if (info != null) { 162 Log.info (info.getName() + " " + info.getVersion()); 163 final BootableProjectInfo[] childs = info.getDependencies(); 164 for (int i = 0; i < childs.length; i++) { 165 final AbstractBoot boot = loadBooter(childs[i].getBootClass()); 166 if (boot != null) { 167 boot.start(); 168 } 169 } 170 } 171 performBoot(); 172 173 synchronized (this) { 174 this.bootInProgress = false; 175 this.bootDone = true; 176 } 177 } 178 179 /** 180 * Performs the boot. 181 */ 182 protected abstract void performBoot(); 183 184 /** 185 * Returns the project info. 186 * 187 * @return The project info. 188 */ 189 protected abstract BootableProjectInfo getProjectInfo(); 190 191 /** 192 * Loads the specified booter implementation. 193 * 194 * @param classname the class name. 195 * 196 * @return The boot class. 197 */ 198 protected AbstractBoot loadBooter(final String classname) { 199 if (classname == null) { 200 return null; 201 } 202 try { 203 final Class c = ObjectUtilities.getClassLoader( 204 getClass()).loadClass(classname); 205 final Method m = c.getMethod("getInstance", (Class[]) null); 206 return (AbstractBoot) m.invoke(null, (Object[]) null); 207 } 208 catch (Exception e) { 209 Log.info ("Unable to boot dependent class: " + classname); 210 return null; 211 } 212 } 213 214 /** 215 * Creates a default configuration setup, which loads its settings from 216 * the static configuration (defaults provided by the developers of the 217 * library) and the user configuration (settings provided by the deployer). 218 * The deployer's settings override the developer's settings. 219 * 220 * If the parameter <code>addSysProps</code> is set to true, the system 221 * properties will be added as third configuration layer. The system 222 * properties configuration allows to override all other settings. 223 * 224 * @param staticConfig the resource name of the developers configuration 225 * @param userConfig the resource name of the deployers configuration 226 * @param addSysProps a flag defining whether to include the system 227 * properties into the configuration. 228 * @return the configured Configuration instance. 229 */ 230 protected Configuration createDefaultHierarchicalConfiguration 231 (final String staticConfig, final String userConfig, 232 final boolean addSysProps) 233 { 234 final HierarchicalConfiguration globalConfig 235 = new HierarchicalConfiguration(); 236 237 if (staticConfig != null) { 238 final PropertyFileConfiguration rootProperty 239 = new PropertyFileConfiguration(); 240 rootProperty.load(staticConfig); 241 globalConfig.insertConfiguration(rootProperty); 242 globalConfig.insertConfiguration( 243 getPackageManager().getPackageConfiguration()); 244 } 245 if (userConfig != null) 246 { 247 final PropertyFileConfiguration baseProperty 248 = new PropertyFileConfiguration(); 249 baseProperty.load(userConfig); 250 globalConfig.insertConfiguration(baseProperty); 251 } 252 final SystemPropertyConfiguration systemConfig 253 = new SystemPropertyConfiguration(); 254 globalConfig.insertConfiguration(systemConfig); 255 return globalConfig; 256 } 257 258 /** 259 * Returns the global configuration as extended configuration. 260 * 261 * @return the extended configuration. 262 */ 263 public synchronized ExtendedConfiguration getExtendedConfig () 264 { 265 if (extWrapper == null) 266 { 267 extWrapper = new ExtendedConfigurationWrapper(getGlobalConfig()); 268 } 269 return extWrapper; 270 } 271 }