package org.jconfig;
import java.util.HashMap;
import org.jconfig.error.ErrorReporter;
import org.jconfig.event.FileListener;
import org.jconfig.event.FileListenerEvent;
import org.jconfig.handler.AbstractHandler;
import org.jconfig.handler.ConfigurationHandler;
import org.jconfig.handler.InputStreamHandler;
import org.jconfig.bootstrap.*;
/**
* This class manages all configurations. This is the main entry point.
* You can get the configurations from the ConfigurationManager.
* The simple way is: <BR/>
* public static final Configuration config = ConfigurationManager.getConfiguration();<BR/>
* or: <BR/>
* public static final Configuration config = ConfigurationManager.getConfiguration("myconfig");<BR/>
* <BR />
* If you use the getConfiguration() the ConfigurationManager will return the configuration
* with the name "default". If there is no configuration wit the given name then
* the ConfigurationManager will use the InputStreamHandler and will try to read the
* file "config.xml". This file has to be in the classpath.
*
*@author Andreas Mecky andreas.mecky@xcom.de
*@author Terry Dye terry.dye@xcom.de
*/
public class ConfigurationManager {
// the one and only instance
private static ConfigurationManager cm = null;
// all instances of the Configurations
private static HashMap configurations = null;
// a mapping of associated handlers and configurations
private static HashMap handlerMapping;
/**
* Constructor for the ConfigurationManager object
*
*/
private ConfigurationManager() {
configurations = new HashMap();
handlerMapping = new HashMap();
BootstrapLoader bl = BootstrapLoaderFactory.getLoader();
try {
LoadedItem[] configs = bl.load();
for ( int i = 0; i < configs.length;i++) {
LoadedItem li = configs[i];
Configuration config = li.getConfig();
ConfigurationHandler handler = li.getHandler();
String name = li.getName();
configurations.put(name, config);
handlerMapping.put(name, handler);
}
}
catch (Exception e) {
ErrorReporter.getErrorHandler().reportError("Exception while trying to load configuratins at startup:",e);
}
}
/**
* This method returns the one and only instance of the
* ConfigurationManager.
*
* @return the instance of the ConfigurationManager
*/
public static synchronized ConfigurationManager getInstance() {
if (cm == null) {
cm = new ConfigurationManager();
}
return cm;
}
/**
* This method returns the configuration with the name "default".
* It calls getConfiguration("default").
*
* @return the configuration
*/
public static Configuration getConfiguration() {
return getConfiguration("default");
}
/**
* This method returns the configuration for the specific name.
* If there is no configuration then it will use the InputStreamHandler
* and take "config.xml" as filename.<BR /><BR />
*
* Implementation detail: A new instance of the ConfigurationManager
* will be created/instantiated if one does not exist.<BR /><BR />
*
* An empty Configuration will be returned if the Configuration sought
* after is not found.<BR /><BR />
*
* This method will first look for a file called "name"_config.xml.
* If this file does not exist it will look for the default config.xml
* file.<BR /><BR />
* Note that if the name is "default" then the method will directly
* look for the config.xml file since this is the reserved name
* for the default configuration.
*
* @param name the name of the configuration
* @return the configuration
*/
public static Configuration getConfiguration(String name) {
getInstance();
if ( name == null ) {
return new DefaultConfiguration(name);
}
if (configurations.containsKey(name)) {
return (Configuration) configurations.get(name);
} else {
String fileName = "config.xml";
if ( !name.equals("default") ) {
fileName = name+"_config.xml";
}
InputStreamHandler ish = new InputStreamHandler(fileName);
try {
Configuration config = ish.load(name);
if ( config != null ) {
//config.setConfigName(name);
configurations.put(name, config);
handlerMapping.put(name, ish);
getInstance().addFileListener(name,new ConfigurationFileListener(name));
}
return config;
} catch (ConfigurationManagerException e) {
ErrorReporter.getErrorHandler().reportError("Problem while trying to read configuration. Returning new configuration.",e);
return new DefaultConfiguration(name);
}
}
}
/**
* This method will load a configuration with the specific ConfigurationHandler
* and store it in the internal map with the given name.
*
* @param configHandler an implementation of the ConfigurationHandler
* @param configurationName the name of the configuration
*/
public void load(ConfigurationHandler configurationHandler,String configurationName) throws ConfigurationManagerException {
Configuration config = configurationHandler.load(configurationName);
if(configurationHandler instanceof AbstractHandler) {
((AbstractHandler)configurationHandler).addFileListener(new ConfigurationFileListener(configurationName));
}
if (config != null) {
//config.setConfigName(configurationName);
configurations.put(configurationName, config);
handlerMapping.put(configurationName, configurationHandler);
}
}
public void setConfiguration(Configuration configuration,ConfigurationHandler handler) throws ConfigurationManagerException {
if (configuration != null) {
configurations.put(configuration.getConfigName(), configuration);
handlerMapping.put(configuration.getConfigName(), handler);
}
}
/**
* This method will store the configuration for the given name using the associated
* handler that was used when the configuration was loaded.
*
* @param configName the name of the configuration
* @throws ConfigurationManagerException
*/
public void save(String configName) throws ConfigurationManagerException {
ConfigurationHandler handler = (ConfigurationHandler)handlerMapping.get(configName);
if ( handler == null ) {
throw new ConfigurationManagerException("No handler assigned to this configuration");
}
Configuration config = (Configuration)configurations.get(configName);
if ( config == null ) {
throw new ConfigurationManagerException("No configuration found with the given name");
}
save(handler, config);
}
public void addFileListener(String configName,FileListener fl) {
ConfigurationHandler handler = (ConfigurationHandler)handlerMapping.get(configName);
if ( handler != null ) {
((AbstractHandler)handler).addFileListener(fl);
}
}
/**
* This method will save a configuration using the defined ConfigurationHandler. In
* most cases it is simpler to use the save(String configName) method since the ConfigurationManager
* stores the handler that is asscociated with the configuration. Use this method if you want to
* use a different handler. For example you have used the URLHandler to download a configuration
* from a webserver and now want to save the file to a local directory
*
* @param handler the ConfigurationHandler that will be used to store the configuration
* @param config the configuration to store
* @throws ConfigurationManagerException
*/
public void save(ConfigurationHandler handler, Configuration config) throws ConfigurationManagerException {
handler.store(config);
configurations.put(config.getConfigName(), config);
handlerMapping.put(config.getConfigName(), handler);
}
/**
* This method removes a configuration from the ConfigurationManager
*
* @param configName the name of the configuration
*/
public void removeConfiguration(String configName) {
if ( configName != null ) {
configurations.remove(configName);
handlerMapping.remove(configName);
}
}
/**
* This method will reload a configuration with the same handler that
* was used for the initially loading.
*
* @param name name of the configuration
*/
public void reload(String name) throws ConfigurationManagerException {
if (configurations.containsKey(name)) {
Configuration cfg = getConfiguration(name);
ConfigurationHandler handler = getConfigurationHandler(name);
if (handler == null) {
throw new ConfigurationManagerException("There is no handler associated for this configuration");
}
cfg = handler.load(name);
configurations.put(name, cfg);
} else {
throw new ConfigurationManagerException("There is no configuration with this name");
}
}
/**
* Returns the handler used during the creation of the Configuration.
*
* @param name
* @return
* @since Aug 26, 2003 2:35:20 PM
*/
public ConfigurationHandler getConfigurationHandler(String name) {
ConfigurationHandler handler =
(ConfigurationHandler) handlerMapping.get(name);
return handler;
}
/**
* This method will return all configurations names
*
* @return a String[] containing all configuration names
*/
public String[] getConfigurationNames() {
return (String[]) configurations.keySet().toArray(new String[configurations.size()]);
}
/**
* This method returns the current version of jConfig taken from the Manifest file
*
* @return the version of jConfig
*/
public static String getVersion() {
String version = "unknown";
Package[] allPackages = Package.getPackages();
for(int i=0; i < allPackages.length; i++) {
if ( allPackages[i].getName().equals("org.jconfig") ) {
version = allPackages[i].getImplementationVersion();
}
}
return version;
}
}
class ConfigurationFileListener implements FileListener {
private String config = null;
ConfigurationFileListener(String configurationName) {
config = configurationName;
}
/**
* @see org.jconfig.event.FileListener#fileChanged(org.jconfig.event.FileListenerEvent)
*/
public void fileChanged(FileListenerEvent e) {
try {
ConfigurationManager.getInstance().reload(config);
} catch (ConfigurationManagerException e1) {
System.out.println("Problem with reloading the file after file was saved.");
}
}
}