001: /*
002: * $Header: /export/home/cvsroot/MyPersonalizerRepository/MyPersonalizer/Subsystems/Kernel/Sources/es/udc/mypersonalizer/kernel/util/config/ConfigurationManager.java,v 1.1.1.1 2004/03/25 12:08:38 fbellas Exp $
003: * $Revision: 1.1.1.1 $
004: * $Date: 2004/03/25 12:08:38 $
005: *
006: * =============================================================================
007: *
008: * Copyright (c) 2003, The MyPersonalizer Development Group
009: * (http://www.tic.udc.es/~fbellas/mypersonalizer/index.html) at
010: * University Of A Coruna
011: * All rights reserved.
012: *
013: * Redistribution and use in source and binary forms, with or without
014: * modification, are permitted provided that the following conditions are met:
015: *
016: * - Redistributions of source code must retain the above copyright notice,
017: * this list of conditions and the following disclaimer.
018: *
019: * - Redistributions in binary form must reproduce the above copyright notice,
020: * this list of conditions and the following disclaimer in the documentation
021: * and/or other materials provided with the distribution.
022: *
023: * - Neither the name of the University Of A Coruna nor the names of its
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
028: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
029: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
030: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
031: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
032: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
033: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
034: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
035: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
036: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
037: * POSSIBILITY OF SUCH DAMAGE.
038: *
039: */
040:
041: package es.udc.mypersonalizer.kernel.util.config;
042:
043: import es.udc.mypersonalizer.kernel.util.exceptions.InternalErrorException;
044: import java.io.BufferedInputStream;
045: import java.io.FileNotFoundException;
046: import java.io.InputStream;
047: import java.net.URL;
048: import java.util.HashMap;
049: import java.util.Map;
050:
051: import org.apache.commons.digester.Digester;
052: import org.apache.commons.digester.xmlrules.DigesterLoader;
053: import org.xml.sax.EntityResolver;
054:
055: /**
056: * This class is responsible for providing each part of the system with its
057: * configuration data. For that, it maintains a cache of configurations
058: * (Kernel, Portal, Database...) and triggers the reading of the adequate XML
059: * configuration file when it is necessary.<p>
060: *
061: * The XML files are processed using Jakarta Digester, and turned into a tree
062: * of configuration beans.
063: * @author Daniel Fernandez
064: * @author Fernando Bellas
065: * @since 1.0
066: */
067: public class ConfigurationManager {
068:
069: /**
070: * The suffix for the configuration files. This is <code>.xml</code>.
071: */
072: private static String CONFIGURATION_FILE_SUFFIX = ".xml";
073:
074: /**
075: * Suffix for the Digester rules files. Set to <code>-rules.xml</code>.
076: */
077: private static String CONFIGURATION_RULES_FILE_SUFFIX = "-rules.xml";
078:
079: /**
080: * The cache of configuration objects.
081: */
082: private static Map configurations = null;
083:
084: static {
085: configurations = new HashMap();
086: }
087:
088: /** Creates a new instance of ConfigurationManager */
089: private ConfigurationManager() {
090: }
091:
092: /**
093: * Returns the configuration identified by <code>configurationName</code>.
094: *
095: * @param configurationName the configuration name.
096: * @param entityResolver entity resolver to be used for XML entities.
097: * @throws InternalErrorException if any fatal errors happen.
098: * @return the wanted Configuration.
099: */
100: public static Configuration getConfiguration(
101: String configurationName, EntityResolver entityResolver)
102: throws InternalErrorException {
103: return getConfiguration(configurationName, configurationName,
104: entityResolver);
105: }
106:
107: /**
108: * Returns the configuration identified by <code>configurationName</code>.
109: * It allows to specify the name of the rules file (without suffix, see
110: * above).
111: *
112: * @param configurationName the name of the configuration
113: * @param configurationRulesName the name of the configuration rules file
114: * @param entityResolver entity resolver to be used for XML entities.
115: * @throws InternalErrorException if any fatal errors happen.
116: * @return the wanted Configuration.
117: */
118: public static Configuration getConfiguration(
119: String configurationName, String configurationRulesName,
120: EntityResolver entityResolver)
121: throws InternalErrorException {
122:
123: Configuration configuration = ((Configuration) configurations
124: .get(configurationName));
125:
126: if (configuration == null) {
127:
128: try {
129: String configFile = getConfigurationFileName(configurationName);
130: String rulesFile = getConfigurationRulesFileName(configurationRulesName);
131:
132: ClassLoader loader = ConfigurationManager.class
133: .getClassLoader();
134:
135: /* First, make sure the config file is there. */
136: URL configFileURL = loader.getResource(configFile);
137: if (configFileURL != null) {
138: /* We get an InputStream on the configuration file */
139: InputStream configFileStrm = new BufferedInputStream(
140: configFileURL.openStream());
141: /* The rules file is turned into an URL */
142: URL rules = loader.getResource(rulesFile);
143:
144: /*
145: * The Digester object is created and initialised with
146: * the rules.
147: */
148: Digester digester = DigesterLoader
149: .createDigester(rules);
150:
151: /* The XML parsing will be validating */
152: digester.setValidating(true);
153:
154: /*
155: * We set the entity resolver during the parsing to be the
156: * one provided as a parameter. This way we allow a
157: * LocalEntityResolver to be used.
158: */
159: digester.setEntityResolver(entityResolver);
160:
161: /* The configuration is parsed by Digester */
162: configuration = (Configuration) digester
163: .parse(configFileStrm);
164:
165: /* ...and it gets into the cache */
166: configurations
167: .put(configurationName, configuration);
168: } else {
169: /* this will be caught and wrapped in an
170: * InternalErrorException.
171: */
172: throw new FileNotFoundException(configFile
173: + " is not on the ClassPath.");
174: }
175: } catch (Exception e) {
176: throw new InternalErrorException("Config-Name: "
177: + configurationName + ", Config-Rules-Name: "
178: + configurationRulesName, e);
179: }
180:
181: }
182:
183: return configuration;
184: }
185:
186: /**
187: * Build the configuration file name from the configuration name.
188: *
189: * @param configurationName name of the configuration
190: * @return a String being the configuration file name.
191: */
192: protected static String getConfigurationFileName(
193: String configurationName) {
194:
195: String result = configurationName.toLowerCase()
196: + CONFIGURATION_FILE_SUFFIX;
197: return result;
198:
199: }
200:
201: /**
202: * Builds the configuration rules file name from the configuration name.
203: *
204: * @param configurationName the name of the configuration.
205: * @return a String being the name of the configuration rules file.
206: */
207: protected static String getConfigurationRulesFileName(
208: String configurationName) {
209:
210: String result = configurationName.toLowerCase()
211: + CONFIGURATION_RULES_FILE_SUFFIX;
212: return result;
213:
214: }
215:
216: }
|