1 43 44 package org.jfree.base.modules; 45 46 import java.io.PrintStream ; 47 import java.util.ArrayList ; 48 import java.util.Arrays ; 49 import java.util.HashMap ; 50 import java.util.Iterator ; 51 52 import org.jfree.base.AbstractBoot; 53 import org.jfree.base.config.HierarchicalConfiguration; 54 import org.jfree.base.config.PropertyFileConfiguration; 55 import org.jfree.base.log.PadMessage; 56 import org.jfree.util.Configuration; 57 import org.jfree.util.Log; 58 import org.jfree.util.ObjectUtilities; 59 60 74 public final class PackageManager { 75 80 public static class PackageConfiguration extends PropertyFileConfiguration { 81 84 public PackageConfiguration() { 85 } 87 88 94 public void insertConfiguration(final HierarchicalConfiguration config) { 95 super.insertConfiguration(config); 96 } 97 } 98 99 100 103 private static final int RETURN_MODULE_LOADED = 0; 104 107 private static final int RETURN_MODULE_UNKNOWN = 1; 108 111 private static final int RETURN_MODULE_ERROR = 2; 112 113 114 119 private final PackageConfiguration packageConfiguration; 120 121 124 private final ArrayList modules; 125 128 private final ArrayList initSections; 129 130 131 private AbstractBoot booter; 132 133 134 private static HashMap instances; 135 136 142 public static PackageManager createInstance(final AbstractBoot booter) { 143 PackageManager manager; 144 if (instances == null) { 145 instances = new HashMap (); 146 manager = new PackageManager(booter); 147 instances.put(booter, manager); 148 return manager; 149 } 150 manager = (PackageManager) instances.get(booter); 151 if (manager == null) { 152 manager = new PackageManager(booter); 153 instances.put(booter, manager); 154 } 155 return manager; 156 } 157 158 163 private PackageManager(final AbstractBoot booter) { 164 if (booter == null) { 165 throw new NullPointerException (); 166 } 167 this.booter = booter; 168 this.packageConfiguration = new PackageConfiguration(); 169 this.modules = new ArrayList (); 170 this.initSections = new ArrayList (); 171 } 172 173 180 public boolean isModuleAvailable(final ModuleInfo moduleDescription) { 181 final PackageState[] packageStates = 182 (PackageState[]) this.modules.toArray(new PackageState[this.modules.size()]); 183 for (int i = 0; i < packageStates.length; i++) { 184 final PackageState state = packageStates[i]; 185 if (state.getModule().getModuleClass().equals(moduleDescription.getModuleClass())) { 186 return (state.getState() == PackageState.STATE_INITIALIZED); 187 } 188 } 189 return false; 190 } 191 192 199 public void load(final String modulePrefix) { 200 if (this.initSections.contains(modulePrefix)) { 201 return; 202 } 203 this.initSections.add(modulePrefix); 204 205 final Configuration config = this.booter.getGlobalConfig(); 206 final Iterator it = config.findPropertyKeys(modulePrefix); 207 int count = 0; 208 while (it.hasNext()) { 209 final String key = (String ) it.next(); 210 if (key.endsWith(".Module")) { 211 final String moduleClass = config.getConfigProperty(key); 212 if (moduleClass != null && moduleClass.length() > 0) { 213 addModule(moduleClass); 214 count++; 215 } 216 } 217 } 218 Log.debug("Loaded a total of " + count + " modules under prefix: " + modulePrefix); 219 } 220 221 225 public synchronized void initializeModules() { 226 PackageSorter.sort(this.modules); 228 229 for (int i = 0; i < this.modules.size(); i++) { 230 final PackageState mod = (PackageState) this.modules.get(i); 231 if (mod.configure(this.booter)) { 232 Log.debug(new Log.SimpleMessage("Conf: ", 233 new PadMessage(mod.getModule().getModuleClass(), 70), 234 " [", mod.getModule().getSubSystem(), "]")); 235 } 236 } 237 238 for (int i = 0; i < this.modules.size(); i++) { 239 final PackageState mod = (PackageState) this.modules.get(i); 240 if (mod.initialize(this.booter)) { 241 Log.debug(new Log.SimpleMessage("Init: ", 242 new PadMessage(mod.getModule().getModuleClass(), 70), 243 " [", mod.getModule().getSubSystem(), "]")); 244 } 245 } 246 } 247 248 255 public synchronized void addModule(final String modClass) { 256 final ArrayList loadModules = new ArrayList (); 257 final ModuleInfo modInfo = new DefaultModuleInfo 258 (modClass, null, null, null); 259 if (loadModule(modInfo, new ArrayList (), loadModules, false)) { 260 for (int i = 0; i < loadModules.size(); i++) { 261 final Module mod = (Module) loadModules.get(i); 262 this.modules.add(new PackageState(mod)); 263 } 264 } 265 } 266 267 276 private int containsModule(final ArrayList tempModules, final ModuleInfo module) { 277 if (tempModules != null) { 278 final ModuleInfo[] mods = (ModuleInfo[]) 279 tempModules.toArray(new ModuleInfo[tempModules.size()]); 280 for (int i = 0; i < mods.length; i++) { 281 if (mods[i].getModuleClass().equals(module.getModuleClass())) { 282 return RETURN_MODULE_LOADED; 283 } 284 } 285 } 286 287 final PackageState[] packageStates = 288 (PackageState[]) this.modules.toArray(new PackageState[this.modules.size()]); 289 for (int i = 0; i < packageStates.length; i++) { 290 if (packageStates[i].getModule().getModuleClass().equals(module.getModuleClass())) { 291 if (packageStates[i].getState() == PackageState.STATE_ERROR) { 292 return RETURN_MODULE_ERROR; 293 } 294 else { 295 return RETURN_MODULE_LOADED; 296 } 297 } 298 } 299 return RETURN_MODULE_UNKNOWN; 300 } 301 302 309 private void dropFailedModule(final PackageState state) { 310 if (this.modules.contains(state) == false) { 311 this.modules.add(state); 312 } 313 } 314 315 330 private boolean loadModule(final ModuleInfo moduleInfo, final ArrayList incompleteModules, 331 final ArrayList modules, final boolean fatal) { 332 try { 333 334 final Class c = ObjectUtilities.getClassLoader(getClass()).loadClass(moduleInfo.getModuleClass()); 335 final Module module = (Module) c.newInstance(); 336 337 if (acceptVersion(moduleInfo, module) == false) { 338 Log.warn("Module " + module.getName() + ": required version: " 340 + moduleInfo + ", but found Version: \n" + module); 341 final PackageState state = new PackageState(module, PackageState.STATE_ERROR); 342 dropFailedModule(state); 343 return false; 344 } 345 346 final int moduleContained = containsModule(modules, module); 347 if (moduleContained == RETURN_MODULE_ERROR) { 348 Log.debug("Indicated failure for module: " + module.getModuleClass()); 350 final PackageState state = new PackageState(module, PackageState.STATE_ERROR); 351 dropFailedModule(state); 352 return false; 353 } 354 else if (moduleContained == RETURN_MODULE_UNKNOWN) { 355 if (incompleteModules.contains(module)) { 356 Log.error(new Log.SimpleMessage 358 ("Circular module reference: This module definition is invalid: ", 359 module.getClass())); 360 final PackageState state = new PackageState(module, PackageState.STATE_ERROR); 361 dropFailedModule(state); 362 return false; 363 } 364 incompleteModules.add(module); 365 final ModuleInfo[] required = module.getRequiredModules(); 366 for (int i = 0; i < required.length; i++) { 367 if (loadModule(required[i], incompleteModules, modules, true) == false) { 368 Log.debug("Indicated failure for module: " + module.getModuleClass()); 369 final PackageState state = new PackageState(module, PackageState.STATE_ERROR); 370 dropFailedModule(state); 371 return false; 372 } 373 } 374 375 final ModuleInfo[] optional = module.getOptionalModules(); 376 for (int i = 0; i < optional.length; i++) { 377 if (loadModule(optional[i], incompleteModules, modules, true) == false) { 378 Log.debug(new Log.SimpleMessage("Optional module: ", 379 optional[i].getModuleClass(), " was not loaded.")); 380 } 381 } 382 if (containsModule(modules, module) == RETURN_MODULE_UNKNOWN) { 384 modules.add(module); 385 } 386 incompleteModules.remove(module); 387 } 388 return true; 389 } 390 catch (ClassNotFoundException cnfe) { 391 if (fatal) { 392 Log.warn(new Log.SimpleMessage 393 ("Unresolved dependency for package: ", moduleInfo.getModuleClass())); 394 } 395 Log.debug(new Log.SimpleMessage("ClassNotFound: ", cnfe.getMessage())); 396 return false; 397 } 398 catch (Exception e) { 399 Log.warn(new Log.SimpleMessage("Exception while loading module: ", moduleInfo), e); 400 return false; 401 } 402 } 403 404 412 private boolean acceptVersion(final ModuleInfo moduleRequirement, final Module module) { 413 if (moduleRequirement.getMajorVersion() == null) { 414 return true; 415 } 416 if (module.getMajorVersion() == null) { 417 Log.warn("Module " + module.getName() + " does not define a major version."); 418 } 419 else { 420 final int compare = acceptVersion(moduleRequirement.getMajorVersion(), 421 module.getMajorVersion()); 422 if (compare > 0) { 423 return false; 424 } 425 else if (compare < 0) { 426 return true; 427 } 428 } 429 430 if (moduleRequirement.getMinorVersion() == null) { 431 return true; 432 } 433 if (module.getMinorVersion() == null) { 434 Log.warn("Module " + module.getName() + " does not define a minor version."); 435 } 436 else { 437 final int compare = acceptVersion(moduleRequirement.getMinorVersion(), 438 module.getMinorVersion()); 439 if (compare > 0) { 440 return false; 441 } 442 else if (compare < 0) { 443 return true; 444 } 445 } 446 447 if (moduleRequirement.getPatchLevel() == null) { 448 return true; 449 } 450 if (module.getPatchLevel() == null) { 451 Log.debug("Module " + module.getName() + " does not define a patch level."); 452 } 453 else { 454 if (acceptVersion(moduleRequirement.getPatchLevel(), 455 module.getPatchLevel()) > 0) { 456 Log.debug("Did not accept patchlevel: " 457 + moduleRequirement.getPatchLevel() + " - " 458 + module.getPatchLevel()); 459 return false; 460 } 461 } 462 return true; 463 464 } 465 466 476 private int acceptVersion(final String modVer, final String depModVer) { 477 final int mLength = Math.max(modVer.length(), depModVer.length()); 478 final char[] modVerArray; 479 final char[] depVerArray; 480 if (modVer.length() > depModVer.length()) { 481 modVerArray = modVer.toCharArray(); 482 depVerArray = new char[mLength]; 483 final int delta = modVer.length() - depModVer.length(); 484 Arrays.fill(depVerArray, 0, delta, ' '); 485 System.arraycopy(depVerArray, delta, depModVer.toCharArray(), 0, depModVer.length()); 486 } 487 else if (modVer.length() < depModVer.length()) { 488 depVerArray = depModVer.toCharArray(); 489 modVerArray = new char[mLength]; 490 final char[] b1 = new char[mLength]; 491 final int delta = depModVer.length() - modVer.length(); 492 Arrays.fill(b1, 0, delta, ' '); 493 System.arraycopy(b1, delta, modVer.toCharArray(), 0, modVer.length()); 494 } 495 else { 496 depVerArray = depModVer.toCharArray(); 497 modVerArray = modVer.toCharArray(); 498 } 499 return new String (modVerArray).compareTo(new String (depVerArray)); 500 } 501 502 509 public PackageConfiguration getPackageConfiguration() { 510 return this.packageConfiguration; 511 } 512 513 520 public Module[] getAllModules() { 521 final Module[] mods = new Module[this.modules.size()]; 522 for (int i = 0; i < this.modules.size(); i++) { 523 final PackageState state = (PackageState) this.modules.get(i); 524 mods[i] = state.getModule(); 525 } 526 return mods; 527 } 528 529 535 public Module[] getActiveModules() { 536 final ArrayList mods = new ArrayList (); 537 for (int i = 0; i < this.modules.size(); i++) { 538 final PackageState state = (PackageState) this.modules.get(i); 539 if (state.getState() == PackageState.STATE_INITIALIZED) { 540 mods.add(state.getModule()); 541 } 542 } 543 return (Module[]) mods.toArray(new Module[mods.size()]); 544 } 545 546 551 public void printUsedModules(final PrintStream p) { 552 final Module[] allMods = getAllModules(); 553 final ArrayList activeModules = new ArrayList (); 554 final ArrayList failedModules = new ArrayList (); 555 556 for (int i = 0; i < allMods.length; i++) { 557 if (isModuleAvailable(allMods[i])) { 558 activeModules.add(allMods[i]); 559 } 560 else { 561 failedModules.add(allMods[i]); 562 } 563 } 564 565 p.print("Active modules: "); 566 p.println(activeModules.size()); 567 p.println("----------------------------------------------------------"); 568 for (int i = 0; i < activeModules.size(); i++) { 569 final Module mod = (Module) activeModules.get(i); 570 p.print(new PadMessage(mod.getModuleClass(), 70)); 571 p.print(" ["); 572 p.print(mod.getSubSystem()); 573 p.println("]"); 574 p.print(" Version: "); 575 p.print(mod.getMajorVersion()); 576 p.print("-"); 577 p.print(mod.getMinorVersion()); 578 p.print("-"); 579 p.print(mod.getPatchLevel()); 580 p.print(" Producer: "); 581 p.println(mod.getProducer()); 582 p.print(" Description: "); 583 p.println(mod.getDescription()); 584 } 585 } 586 } 587 | Popular Tags |