Package net.sf.xbus.base.core.config

Source Code of net.sf.xbus.base.core.config.Configuration

package net.sf.xbus.base.core.config;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;

import net.sf.xbus.base.core.Constants;
import net.sf.xbus.base.core.XException;
import net.sf.xbus.base.core.strings.XStringSupport;

/**
* This class reads program parameters from different sources and makes them
* accessible. The entries of the configuration are organized in a three-level
* hierarchie:
* <p>
* <ul>
* <li>The <b>chapter </b> is the top level. Often you will find names of
* components or classes at this level.</li>
* <li>Every chapter contains one or more <b>sections </b></li>
* <li><b>Keys </b> are at the bottom of the hierarchie, beyond the sections.
* </ul>
*
* The <code>Configuration</code> implements the <b>Singleton </b>
* Design-Pattern.
* <p>
*
* Up to now, only the Java- <code>Properties</code> can be used as a source
* for the configuration. Other sources like XML-files or a database are
* prepared.
*/
public class Configuration
{
  public static final String STANDARD_CONFIG = "standard";
  private static final String XBUS_HOME = "$XBUS_HOME$";

  public static final String VARIABLE_PREFIX = "$VARIABLE_";
  public static final String VARIABLE_END = "$";
  public static final String MAPPING_DEFAULT = "Default";

  // private static Configuration mSingleInstance = null;
  private static Hashtable mInstances = new Hashtable();

  private static final Object classLock = Configuration.class;

  private Hashtable mCache = null;
  private ConfigSource mSource = null;

  /**
   * The constructor is private. Instances of <code>Configuration</code> can
   * only be accessed via the method <code>getInstance()</code>.
   *
   * @param source the source of the properties.
   * @exception XException if any error occurs
   */
  private Configuration(String source)
  {
    /*
     * Check if XBUS_HOME is set. This is done here, because loading the
     * configuration will be the first point, where XBUS_HOME is used.
     */
    if (Constants.XBUS_HOME == null)
    {
      System.out.println("I_00_000_2 XBUS_HOME has not been set!");
      System.exit(1);
    }

    /*
     * Initialize the source of the configuration entries.
     */
    mSource = new PropertiesSource(source);
  } // Configuration(String source)

  /**
   * Returns an instance of the standard <code>Configuration</code>.
   * <p>
   * The first call creates a new <code>Configuration</code> and reads all
   * entries. Following calls will return the object, that has been created by
   * the first call.
   *
   * @return Configuration - instance of the standard
   *         <code>Configuration</code>
   * @exception XException if any error occurs
   */
  public static Configuration getInstance() throws XException
  {
    return getInstance(STANDARD_CONFIG);
  } // getInstance()

  /**
   * Returns a named instance of the <code>Configuration</code>.
   * <p>
   * The first call creates a new <code>Configuration</code> and reads all
   * entries. Following calls will return the object, that has been created by
   * the first call.
   *
   * @param source the source of the properties.
   * @return Configuration - instance of the standard
   *         <code>Configuration</code>
   * @exception XException if any error occurs
   */
  public static Configuration getInstance(String source) throws XException
  {
    synchronized (classLock)
    {
      Configuration instance = (Configuration) mInstances.get(source);
      if (instance == null)
      {
        instance = new Configuration(source);
        instance.readCache();
        mInstances.put(source, instance);
      } // if (instance == null)
      return instance;
    }
  } // getInstance(String source)

  /**
   * Creates an updated instance of the standard <code>Configuration</code>.
   *
   * @exception XException if any error occurs
   */
  public static void refresh() throws XException
  {
    refresh(STANDARD_CONFIG);
  } // refresh()

  /**
   * Creates an updated instance of the named <code>Configuration</code>.
   *
   * @param source the source of the properties
   * @exception XException if any error occurs
   */
  public static void refresh(String source) throws XException
  {
    mInstances.remove(source);
        getInstance(source);
  } // refresh(String source)

  /**
   * Returns the value of an entry. All three parameters have to contain
   * values.
   * <p>
   * If the desired entry can not be found, a <code>XException</code> is
   * thrown.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as String for the given chapter, section and key
   * @exception XException if the entry in configuration is not exist or any
   *                error occurs
   */
  public String getValue(String chapter, String section, String key)
      throws XException
  {
    String returnString = getValueInternal(chapter, section, key);
    if (returnString == null)
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "1", params);
    } // if (returnString == null)

    return returnString;
  } // getValue(String chapter, String section, String key)

  /**
   * Returns the value of an entry as an integer. All three parameters have to
   * contain values.
   * <p>
   * If the desired entry can not be found or the value is not an integer, a
   * <code>XException</code> is thrown.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as <i>int </i> for the given chapter, section and key *
   * @exception XException if the entry in configuratiuon is not exist or it
   *                is not an integer
   */
  public int getValueAsInt(String chapter, String section, String key)
      throws XException
  {
    String returnString = getValueInternal(chapter, section, key);
    if (returnString == null)
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "1", params);
    } // if (returnString == null)

    try
    // for casting to XException
    {
      int retInt = Integer.parseInt(returnString);
      return retInt;
    }
    catch (NumberFormatException e)
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "3", params);
    } // catch (NumberFormatException e)
  } // getValueAsInt(String chapter, String section, String key)

  /**
   * Returns the optional value of an entry as an integer. All three
   * parameters have to contain values.
   * <p>
   * If the desired entry is not an integer, a <code>XException</code> is
   * thrown.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as <i>int </i> for the given chapter, section and key <br>
   *         If the entry in the configuration is not found, <code>0</code>
   *         is returned.
   * @exception XException if the entry is not an integer
   */
  public int getValueAsIntOptional(String chapter, String section, String key)
      throws XException
  {
    String returnString = getValueInternal(chapter, section, key);
    if (returnString == null)
    {
      return 0;
    } // if (returnString == null)

    try
    {
      int retInt = Integer.parseInt(returnString);
      return retInt;
    }
    catch (NumberFormatException e)
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "3", params);
    } // catch (NumberFormatException e)
  } // getValueAsIntOptional(String chapter, String section, String key)

  /**
   * Returns the optional value of an entry as an long value. All three
   * parameters have to contain values.
   * <p>
   * If the desired entry is not an long value, a <code>XException</code> is
   * thrown.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as <i>int </i> for the given chapter, section and key <br>
   *         If the entry in the configuration is not found, <code>0</code>
   *         is returned.
   * @exception XException if the entry is not an integer
   */
  public long getValueAsLongOptional(String chapter, String section,
      String key) throws XException
  {
    String returnString = getValueInternal(chapter, section, key);
    if (returnString == null)
    {
      return 0;
    } // if (returnString == null)

    try
    {
      long retLong = Long.parseLong(returnString);
      return retLong;
    }
    catch (NumberFormatException e)
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "5", params);
    } // catch (NumberFormatException e)
  } // getValueAsLongOptional(String chapter, String section, String key)

  /**
   * Returns the value of an entry as a boolean. All three parameters have to
   * contain values.
   * <p>
   * If the desired entry can not be found or the value is not a boolean, a
   * <code>XException</code> is thrown.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as <i>boolean </i> for the given chapter, section and key
   * @exception XException if the entry in the configuration is not exist or
   *                it is not a boolean value
   */
  public boolean getValueAsBoolean(String chapter, String section, String key)
      throws XException
  {
    String returnString = getValueInternal(chapter, section, key);
    if (returnString == null)
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "1", params);
    }

    if (Constants.CONFIGURATION_TRUE.toUpperCase().equals(
        returnString.toUpperCase()))
    {
      return true;
    } // then
    // (Constants.CONFIGURATION_TRUE.toUpperCase().equals(returnString.toUpperCase()))
    else if (Constants.CONFIGURATION_FALSE.toUpperCase().equals(
        returnString.toUpperCase()))
    {
      return false;
    } // else then
    // (Constants.CONFIGURATION_FALSE.toUpperCase().equals(returnString.toUpperCase()))
    else
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "7", params);
    } // else
    // (Constants.CONFIGURATION_FALSE.toUpperCase().equals(returnString.toUpperCase()))
  } // getValueAsBoolean(String chapter,String section,String key)

  /**
   * Returns the optional value of an entry as a boolean. All three parameters
   * have to contain values.
   * <p>
   * If the desired entry can not be found, false is returned. If the value is
   * not a boolean, a <code>XException</code> is thrown.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as boolean for the given chapter, section and key. <br>
   *         If the entry in the configuration is not found, false is
   *         returned.
   * @exception XException if the entry is not a boolean value or any error
   *                occurs
   */
  public boolean getValueAsBooleanOptional(String chapter, String section,
      String key) throws XException
  {
    String returnString = getValueInternal(chapter, section, key);
    if (returnString == null)
    {
      return false;
    }

    if (Constants.CONFIGURATION_TRUE.toUpperCase().equals(
        returnString.toUpperCase()))
    {
      return true;
    } // then
    // (Constants.CONFIGURATION_TRUE.toUpperCase().equals(returnString.toUpperCase()))
    else if (Constants.CONFIGURATION_FALSE.toUpperCase().equals(
        returnString.toUpperCase()))
    {
      return false;
    } // else then
    // (Constants.CONFIGURATION_FALSE.toUpperCase().equals(returnString.toUpperCase()))
    else
    {
      List params = new Vector();
      params.add(chapter);
      params.add(section);
      params.add(key);
      throw new XException(Constants.LOCATION_INTERN,
          Constants.LAYER_COREBASE,
          Constants.PACKAGE_COREBASE_COREBASE, "7", params);
    } // else
    // (Constants.CONFIGURATION_FALSE.toUpperCase().equals(returnString.toUpperCase()))
  } // getValueAsBooleanOptional(String chapter,String section,String key)

  /**
   * Returns the value of an entry. All three parameters have to contain
   * values.
   * <p>
   * If the desired entry is not in the configuration, <code>null</code>
   * will be returned.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as string for the given chapter,section and key or null if
   *         the desired value is not found in the configuration
   */
  public String getValueOptional(String chapter, String section, String key)
  {
    return getValueInternal(chapter, section, key);
  } // getValueOptional(String chapter, String section, String key)

  /**
   * Returns a list of all chapters.
   *
   * @return List with chapters
   * @exception XException if any error occurs
   */
  public List getChapters()
  {
    TreeSet chapters = new TreeSet(mCache.keySet());
    return new Vector(chapters);
  } // getChapters()

  /**
   * Returns a list of all sections for the given chapter
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @return List of all sections for the given chapter or null wenn no
   *         sections are found
   * @exception XException if any error occurs
   */
  public List getSections(String chapter)
  {
    Hashtable sections = (Hashtable) mCache.get(chapter);
    if (sections == null)
    {
      return null;
    } // if (sections == null)

    TreeSet sectionSet = new TreeSet(sections.keySet());
    return new Vector(sectionSet);
  } // getSections(String chapter)

  /**
   * Returns a map of all keys and their values for the given chapter and
   * section.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @return Map of all keys and their values for the given chapter and
   *         section or <i>null </i> wenn no keys are found
   * @exception XException if any error occurs
   */
  public Map getKeysAndValues(String chapter, String section)
  {
    Hashtable sections = (Hashtable) mCache.get(chapter);
    if (sections == null)
    {
      return null;
    } // if (sections == null)

    Hashtable keys = (Hashtable) sections.get(section);

    if (keys != null)
    {
      return new TreeMap(keys);
    }
    else
    {
      return null;
    }
  } // getKeysAndValues(String chapter, String section)

  /**
   * Returns a value for the given chapter, section and key.
   *
   * @param chapter The first level from the three-level hierarchie hashtable
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to this chapter
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to these chapter and section
   * @return Value as String for the given chapter, section and key
   * @exception XException if any error occurs
   */
  private String getValueInternal(String chapter, String section, String key)
  {
    Hashtable sectTable = (Hashtable) mCache.get(chapter);
    if (sectTable == null)
    {
      return null;
    } // if (sectTable == null)

    Hashtable keyTable = (Hashtable) sectTable.get(section);
    if (keyTable == null)
    {
      return null;
    } // if (keyTable == null)

    return (String) keyTable.get(key);
  } // getValueInternal(String chapter, String section, String key)

  /**
   * This method is used by {@link #getInstance()}and by
   * {@link #getInstance(String)}for reading all entries from a source and
   * filling a three-level hierarchie hashtable.
   *
   * @see net.sf.xbus.base.core.config.PropertiesSource#readCache()
   * @exception XException if any error occurs
   */
  private void readCache() throws XException
  {
    mCache = mSource.readCache();
    replaceVariables(mCache);
  } // readCache()

  /**
   * Replaces XBUS_HOME and variables with the key
   * <code>Base_Variable_xxx</code> in all entries of the current
   * configuration.
   */
  private void replaceVariables(Hashtable cache) throws XException
  {
    Map variables = getVariables(cache);

    for (Enumeration chapters = cache.elements(); chapters
        .hasMoreElements();)
    {
      Hashtable chapter = (Hashtable) chapters.nextElement();
      for (Enumeration sections = chapter.elements(); sections
          .hasMoreElements();)
      {
        Hashtable section = (Hashtable) sections.nextElement();
        for (Enumeration keys = section.keys(); keys.hasMoreElements();)
        {
          String key = (String) keys.nextElement();
          String value = (String) section.get(key);

          /*
           * Replace further variables
           */
          int variablePosNew = value.indexOf(VARIABLE_PREFIX);
          if (variablePosNew >= 0)
          {
            int variablePosOld = -99999;
            String variable = null;
            Set variablesKeySet = null;
            while ((variablePosNew >= 0)
                && (variablePosOld != variablePosNew))
            {
              variablePosOld = variablePosNew;
              if (variables == null)
              {
                throw new XException(Constants.LOCATION_INTERN,
                    Constants.LAYER_BASE,
                    Constants.PACKAGE_BASE_XBUSSYSTEM, "4");
              }
              variablesKeySet = variables.keySet();
              if (variablesKeySet == null)
              {
                throw new XException(Constants.LOCATION_INTERN,
                    Constants.LAYER_BASE,
                    Constants.PACKAGE_BASE_XBUSSYSTEM, "4");
              }
              String variablesKey = null;
              for (Iterator it = variablesKeySet.iterator(); it
                  .hasNext();)
              {
                variablesKey = (String) it.next();
                variable = (String) variables.get(variablesKey);
                if (value.indexOf(variablesKey) >= 0)
                {
                  value = XStringSupport.replaceAll(value,
                      variablesKey, variable);
                }
              }
              variablePosNew = value.indexOf(VARIABLE_PREFIX);
            }
            if (variablePosOld == variablePosNew)
            {
              /*
               * Found same variable again => variable cannot be
               * replaced
               */
              List params = new Vector();
              params.add(new Integer(variablePosOld));
              params.add(value);
              throw new XException(Constants.LOCATION_INTERN,
                  Constants.LAYER_BASE,
                  Constants.PACKAGE_BASE_XBUSSYSTEM, "3",
                  params);
            }
          }

          /*
           * Replace XBUS_HOME
           */
          if (value.indexOf(XBUS_HOME) >= 0)
          {
            value = XStringSupport.replaceAll(value, XBUS_HOME,
                Constants.XBUS_HOME);
          }

          section.put(key, value);
        }
      }
    }

  }

  private Map getVariables(Hashtable cache)
  {
    Hashtable sections = (Hashtable) cache.get(Constants.CHAPTER_BASE);

    Map variablesConf = null;
    if (sections == null)
    {
      return null;
    } // if (sections == null)

    Hashtable keys = (Hashtable) sections.get("Variable");

    if (keys != null)
    {
      variablesConf = new TreeMap(keys);
    }
    else
    {
      return null;
    }

    Map variablesNew = new Hashtable();

    if (variablesConf != null)
    {
      String key = null;
      String variable = null;
      for (Iterator it = variablesConf.keySet().iterator(); it.hasNext();)
      {
        key = (String) it.next();
        variable = (String) variablesConf.get(key);
        key = new StringBuffer(VARIABLE_PREFIX).append(key).append(
            VARIABLE_END).toString();
        variablesNew.put(key, variable);
      }
    }

    return variablesNew;
  }
  /**
   * Returns an entry of the class table.
   *
   * @see #getValue(String, String, String)
   * @param type The second level from the three-level hierarchie hashtable
   *            that belongs to the chapter: <b><i>Class </i> </b>
   * @param name The bottom level from the three-level hierarchie hashtable
   *            that belongs to the chapter: <b><i>Class </i> </b> and this
   *            section
   * @return Value as String for the given type and name
   * @exception XException if the entry is not found or any error occurs
   */
  public static String getClass(String type, String name) throws XException
  {
    return Configuration.getInstance("xbus").getValue("Class", type, name);
  } // getClass(String type, String name)

  /**
   * Returns an entry of the mapping table.
   *
   * @see #getValue(String, String, String)
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to the chapter: <b><i>Mapping </i> </b>
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to the chapter: <b><i>Mapping </i> </b> and this
   *            section
   * @return Value for the given section and key
   * @exception XException if the entry is not found or any error occurs
   */
  public static String getMapping(String section, String key)
      throws XException
  {
    return Configuration.getInstance("mapping").getValue("Mapping",
        section, key);
  } // getMapping(String section, String key)

  /**
   * Returns an entry of the mapping table or <code>null</code> if it
   * doesn't exist.
   *
   * @param section The second level from the three-level hierarchie hashtable
   *            that belongs to the chapter: <b><i>Mapping </i> </b>
   * @param key The bottom level from the three-level hierarchie hashtable
   *            that belongs to the chapter: <b><i>Mapping </i> </b> and this
   *            section
   * @return value for the given section and key
   * @exception XException if the entry is not found or any error occurs
   */
  public static String getMappingOptional(String section, String key)
      throws XException
  {
    return Configuration.getInstance("mapping").getValueOptional("Mapping",
        section, key);
  }

  /**
   * @param section
   */
  public static String getMappingDefault(String section) throws XException
  {
    return getMapping(section, Configuration.MAPPING_DEFAULT);
  } // getMapping(String section, String key)

} // Configuration
TOP

Related Classes of net.sf.xbus.base.core.config.Configuration

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.