/*
 This file is part of the software framework JStatCom, 
 a library for building applications for data based analysis.

 Copyright (C) 2000-2005  Markus Kraetzig

 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 USA
 */

package com.jstatcom.engine;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javolution37.javolution.xml.ObjectReader;
import javolution37.javolution.xml.ObjectWriter;
import javolution37.javolution.xml.XmlElement;
import javolution37.javolution.xml.XmlFormat;

import org.apache.log4j.Logger;

import com.jstatcom.component.StdMessages;

/**
 * This class is used by Engine instances to get all information
 * that is necessary to run a specific engine. The types of configuration
 * settings are defined in the ConfigKeys implementation for the
 * underlying engine type. Instances of this class store information according
 * to the respective configuration keys.
 * 

* For every engine type there exists only one instance of this class. Instances * for engine types are created or referenced by the static factory method * valueOf. *

* All information is stored permanently in an XML file defined in the * respective engine type. * * @author Markus Kraetzig * * @see com.jstatcom.engine.EngineTypes * @see com.jstatcom.engine.ConfigKeys */ public final class ConfigHolder { private static final Logger log = Logger.getLogger(ConfigHolder.class); /** * Contains the configuration information. */ private final Map configMap = new HashMap(); /** * To make sure, that there is only one ConfigHolder for a certain * EngineType. */ private static final Map configHoldersMap = new HashMap(); /** * Reference to the EngineType. */ private final EngineTypes engineType; /** * XML format field for (de)serialization. */ public static final XmlFormat ConfigHolder_XML = new XmlFormat( ConfigHolder.class) { public void format(ConfigHolder data, XmlElement xml) { xml.setAttribute("engine", data.engineType.name); for (Iterator it = data.configMap.keySet().iterator(); it.hasNext();) { ConfigKeys key = (ConfigKeys) it.next(); Object value = data.configMap.get(key); xml.add(new KeyValPair(key.name(), value.toString())); } } public ConfigHolder parse(XmlElement xml) { Object oNam = xml.getAttribute("engine", (String) null); if (oNam == null) return null; EngineTypes type = EngineTypes.valueOf(oNam.toString() .toUpperCase()); if (type == null) return null; ConfigHolder conf = null; // If instance already exists, use it. if (configHoldersMap.containsKey(type)) conf = configHoldersMap.get(type); if (conf == null) conf = new ConfigHolder(type); Map confKeys = type.getConfigKeys(); if (confKeys == null) return conf; while (xml.hasNext()) { KeyValPair pair = (KeyValPair) xml.getNext(); Object o = confKeys.get(pair.key); if (o instanceof ConfigKeys) conf.setConfig((ConfigKeys) o, pair.value); } configHoldersMap.put(type, conf); return conf; } }; /** * Inner class for storing key value pairs of this collection as XML * elements. */ public static class KeyValPair { // Fields are directly accessed by enclosing class. final String key; final String value; /** * XML format field for (de)serialization. */ public static final XmlFormat KeyValPair_XML = new XmlFormat( KeyValPair.class) { public void format(KeyValPair data, XmlElement xml) { xml.setAttribute("key", data.key); xml.setAttribute("value", data.value); } public KeyValPair parse(XmlElement xml) { String nkey = xml.getAttribute("key") + ""; String nvalue = xml.getAttribute("value") + ""; return new KeyValPair(nkey, nvalue); } }; public KeyValPair(String key, String value) { if (key == null || value == null) throw new IllegalArgumentException("Argument was null"); this.value = value; this.key = key; } }; /** * Creates a ConfigHolder and initializes it with default * values. * * @param engineType * @throws IllegalArgumentException * if (engineType == null) * @throws IllegalStateException * if another instance of this class has already been created * for engineType */ private ConfigHolder(EngineTypes engineType) { if (engineType == null) throw new IllegalArgumentException("Argument was null"); this.engineType = engineType; if (configHoldersMap.containsKey(engineType)) throw new IllegalStateException("Instance for " + engineType + " already exists."); Map confKeys = engineType.getConfigKeys(); if (confKeys == null) return; Collection allKeys = confKeys.values(); for (Iterator it = allKeys.iterator(); it.hasNext();) { ConfigKeys key = (ConfigKeys) it.next(); setConfig(key, key.defaultVal()); } } /** * Creates a dialog to change the configuration settings for the respective * engine. It updates the XML configuration file if the changes were * successful. */ public void adjustConfig() { if (ConfigDialog.showConfigDialog(this)) saveConfig(); // Update XML file. } /** * Get a configuration value for a key. * * @param key * that defines type of setting * @return a string containing the setting associated with key * or null if the key is not contained * @throws IllegalArgumentException * if (key == null) */ public String getConfig(ConfigKeys key) { if (key == null) throw new IllegalArgumentException("Argument was null."); if (configMap.containsKey(key)) { Object o = configMap.get(key); if (o != null) return o.toString(); } return null; } /** * Gets a Set of all available ConfigKeys. * * @return a set of all keys */ public Set getConfigKeys() { return configMap.keySet(); } /** * Returns the engine type associated with this. * * @return the engine type */ public final EngineTypes getEngineType() { return engineType; } /** * Serializes this to an XML file. */ private void saveConfig() { try { OutputStream out = new BufferedOutputStream(new FileOutputStream( new File(engineType.getConfigFile()))); ObjectWriter objectWriter = new ObjectWriter(); objectWriter.setPackagePrefix("", "com.jstatcom.engine"); objectWriter.setPackagePrefix("jstatcom", "com.jstatcom"); objectWriter.write(this, out); // Uses UTF-8 encoding. } catch (IOException ivjExc) { log.error("XML serialization failed", ivjExc); } } /** * Set a key value pair to be stored by the config holder. * * @param configKey * the key * @param value * the value * @throws IllegalArgumentException * if (configKey == null) or if * configKey is not valid for the underlying * engine type */ public void setConfig(ConfigKeys configKey, String value) { if (configKey == null) throw new IllegalArgumentException("Argument was null."); Map confKeys = engineType.getConfigKeys(); if (confKeys == null) throw new IllegalArgumentException(configKey + " is not valid for " + engineType + "."); if (confKeys.containsValue(configKey)) configMap.put(configKey, value); else throw new IllegalArgumentException(configKey + " is not valid for " + engineType + "."); } /** * Static initializer to return an instance of ConfigHolder. * It parses the XML config file if it exists and tries to get all necessary * configuration information. If the config file does not exist or if * something is wrong with the settings, an input dialog is shown. The * configuration file is updated if something has changed. * * @param engineType * to define a specific engine * @return the initialized instance * @throws IllegalArgumentException * if (engineType == null) * @throws IllegalStateException * if the user input dialog is cancelled but the settings are * still invalid */ public static ConfigHolder valueOf(EngineTypes engineType) { if (engineType == null) throw new IllegalArgumentException("Argument was null."); if (configHoldersMap.containsKey(engineType)) return configHoldersMap.get(engineType); // Create configHolder from configFile if it is there. // Otherwise create empty config holder. ConfigHolder configHolder = null; File file = new File(engineType.getConfigFile()); if (file.isFile()) { ObjectReader constructor = new ObjectReader(); try { configHolder = (ConfigHolder) constructor .read(new FileInputStream(file)); } catch (Throwable ex) { configHolder = null; } } if (configHolder == null) configHolder = new ConfigHolder(engineType); // Check input and ask user if something is missing or wrong. String error = null; if ((error = engineType.checkConfig(configHolder)) != null) { StdMessages.error(error, "Error in " + engineType + " Settings"); // Initialization failed because of invalid config info. if (!ConfigDialog.showConfigDialog(configHolder)) { configHoldersMap.remove(engineType); throw new IllegalStateException( "Config settings are not in a legal state for " + engineType + "."); } configHolder.saveConfig(); // Update XML file. } configHoldersMap.put(engineType, configHolder); return configHolder; } }

Ads help maintain this website.