📄 packagemanager.java
字号:
/* ========================================================================
* JCommon : a free general purpose class library for the Java(tm) platform
* ========================================================================
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -------------------
* PackageManager.java
* -------------------
* (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
*
* Original Author: Thomas Morgner;
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* $Id: PackageManager.java,v 1.8 2005/11/03 09:55:27 mungady Exp $
*
* Changes
* -------
* 26-Jun-2003 : Initial version
* 07-Jun-2004 : Added JCommon header (DG);
*
*/
package org.jfree.base.modules;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import org.jfree.base.AbstractBoot;
import org.jfree.base.config.HierarchicalConfiguration;
import org.jfree.base.config.PropertyFileConfiguration;
import org.jfree.base.log.PadMessage;
import org.jfree.util.Configuration;
import org.jfree.util.Log;
import org.jfree.util.ObjectUtilities;
/**
* The PackageManager is used to load and configure the modules of JFreeReport.
* Modules are used to extend the basic capabilities of JFreeReport by providing
* a simple plugin-interface.
* <p/>
* Modules provide a simple capability to remove unneeded functionality from the
* JFreeReport system and to reduce the overall code size. The modularisation provides
* a very strict way of removing unnecessary dependencies beween the various packages.
* <p/>
* The package manager can be used to add new modules to the system or to check
* the existence and state of installed modules.
*
* @author Thomas Morgner
*/
public final class PackageManager {
/**
* The PackageConfiguration handles the module level configuration.
*
* @author Thomas Morgner
*/
public static class PackageConfiguration extends PropertyFileConfiguration {
/**
* DefaultConstructor. Creates a new package configuration.
*/
public PackageConfiguration() {
// nothing required
}
/**
* The new configuartion will be inserted into the list of report configuration,
* so that this configuration has the given report configuration instance as parent.
*
* @param config the new report configuration.
*/
public void insertConfiguration(final HierarchicalConfiguration config) {
super.insertConfiguration(config);
}
}
/**
* An internal constant declaring that the specified module was already loaded.
*/
private static final int RETURN_MODULE_LOADED = 0;
/**
* An internal constant declaring that the specified module is not known.
*/
private static final int RETURN_MODULE_UNKNOWN = 1;
/**
* An internal constant declaring that the specified module produced an error while loading.
*/
private static final int RETURN_MODULE_ERROR = 2;
/**
* The module configuration instance that should be used to store module
* properties. This separates the user defined properties from the implementation
* defined properties.
*/
private final PackageConfiguration packageConfiguration;
/**
* A list of all defined modules.
*/
private final ArrayList modules;
/**
* A list of module name definitions.
*/
private final ArrayList initSections;
/** The boot implementation for which the modules are managed. */
private AbstractBoot booter;
/** The instances of all modules for all booters. */
private static HashMap instances;
/**
* Creates a package manager instance.
*
* @param booter the booter.
* @return A package manager.
*/
public static PackageManager createInstance(final AbstractBoot booter) {
PackageManager manager;
if (instances == null) {
instances = new HashMap();
manager = new PackageManager(booter);
instances.put(booter, manager);
return manager;
}
manager = (PackageManager) instances.get(booter);
if (manager == null) {
manager = new PackageManager(booter);
instances.put(booter, manager);
}
return manager;
}
/**
* Creates a new package manager.
*
* @param booter the booter (<code>null</code> not permitted).
*/
private PackageManager(final AbstractBoot booter) {
if (booter == null) {
throw new NullPointerException();
}
this.booter = booter;
this.packageConfiguration = new PackageConfiguration();
this.modules = new ArrayList();
this.initSections = new ArrayList();
}
/**
* Checks, whether a certain module is available.
*
* @param moduleDescription the module description of the desired module.
* @return true, if the module is available and the version of the module
* is compatible, false otherwise.
*/
public boolean isModuleAvailable(final ModuleInfo moduleDescription) {
final PackageState[] packageStates =
(PackageState[]) this.modules.toArray(new PackageState[this.modules.size()]);
for (int i = 0; i < packageStates.length; i++) {
final PackageState state = packageStates[i];
if (state.getModule().getModuleClass().equals(moduleDescription.getModuleClass())) {
return (state.getState() == PackageState.STATE_INITIALIZED);
}
}
return false;
}
/**
* Loads all modules mentioned in the report configuration starting with
* the given prefix. This method is used during the boot process of
* JFreeReport. You should never need to call this method directly.
*
* @param modulePrefix the module prefix.
*/
public void load(final String modulePrefix) {
if (this.initSections.contains(modulePrefix)) {
return;
}
this.initSections.add(modulePrefix);
final Configuration config = this.booter.getGlobalConfig();
final Iterator it = config.findPropertyKeys(modulePrefix);
while (it.hasNext()) {
final String key = (String) it.next();
if (key.endsWith(".Module")) {
addModule(config.getConfigProperty(key));
}
}
Log.debug("Loaded a total of " + this.modules.size() + " modules under prefix: " + modulePrefix);
}
/**
* Initializes all previously uninitialized modules. Once a module is initialized,
* it is not re-initialized a second time.
*/
public synchronized void initializeModules() {
// sort by subsystems and dependency
PackageSorter.sort(this.modules);
for (int i = 0; i < this.modules.size(); i++) {
final PackageState mod = (PackageState) this.modules.get(i);
if (mod.configure(this.booter)) {
Log.debug(new Log.SimpleMessage("Conf: ",
new PadMessage(mod.getModule().getModuleClass(), 70),
" [", mod.getModule().getSubSystem(), "]"));
}
}
for (int i = 0; i < this.modules.size(); i++) {
final PackageState mod = (PackageState) this.modules.get(i);
if (mod.initialize(this.booter)) {
Log.debug(new Log.SimpleMessage("Init: ",
new PadMessage(mod.getModule().getModuleClass(), 70),
" [", mod.getModule().getSubSystem(), "]"));
}
}
}
/**
* Adds a module to the package manager.
* Once all modules are added, you have to call initializeModules()
* to configure and initialize the new modules.
*
* @param modClass the module class
*/
public synchronized void addModule(final String modClass) {
final ArrayList loadModules = new ArrayList();
final ModuleInfo modInfo = new DefaultModuleInfo
(modClass, null, null, null);
if (loadModule(modInfo, new ArrayList(), loadModules, false)) {
for (int i = 0; i < loadModules.size(); i++) {
final Module mod = (Module) loadModules.get(i);
this.modules.add(new PackageState(mod));
}
}
}
/**
* Checks, whether the given module is already loaded in either the given
* tempModules list or the global package registry. If tmpModules is null,
* only the previously installed modules are checked.
*
* @param tempModules a list of previously loaded modules.
* @param module the module specification that is checked.
* @return true, if the module is already loaded, false otherwise.
*/
private int containsModule(final ArrayList tempModules, final ModuleInfo module) {
if (tempModules != null) {
final ModuleInfo[] mods = (ModuleInfo[])
tempModules.toArray(new ModuleInfo[tempModules.size()]);
for (int i = 0; i < mods.length; i++) {
if (mods[i].getModuleClass().equals(module.getModuleClass())) {
return RETURN_MODULE_LOADED;
}
}
}
final PackageState[] packageStates =
(PackageState[]) this.modules.toArray(new PackageState[this.modules.size()]);
for (int i = 0; i < packageStates.length; i++) {
if (packageStates[i].getModule().getModuleClass().equals(module.getModuleClass())) {
if (packageStates[i].getState() == PackageState.STATE_ERROR) {
return RETURN_MODULE_ERROR;
}
else {
return RETURN_MODULE_LOADED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -