001: /*
002: * $Id: ResourceLoader.java,v 1.4 2003/11/25 07:48:13 jonesde Exp $
003: *
004: * Copyright (c) 2002 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: *
024: */
025: package org.ofbiz.base.config;
026:
027: import java.io.InputStream;
028: import java.net.URL;
029: import java.util.HashMap;
030: import java.util.Map;
031:
032: import org.ofbiz.base.util.Debug;
033: import org.ofbiz.base.util.UtilCache;
034: import org.ofbiz.base.util.UtilURL;
035: import org.ofbiz.base.util.UtilXml;
036: import org.w3c.dom.Document;
037: import org.w3c.dom.Element;
038:
039: /**
040: * Loads resources using dynamically specified resource loader classes
041: *
042: *@author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
043: *@version $Revision: 1.4 $
044: *@since 2.0
045: */
046: public abstract class ResourceLoader {
047:
048: public static final String module = ResourceLoader.class.getName();
049: protected static UtilCache loaderCache = new UtilCache(
050: "resource.ResourceLoaders", 0, 0);
051: protected static Map docSaveMap = new HashMap();
052:
053: protected String name;
054: protected String prefix;
055: protected String envName;
056:
057: public static InputStream loadResource(String xmlFilename,
058: String location, String loaderName)
059: throws GenericConfigException {
060: ResourceLoader loader = getLoader(xmlFilename, loaderName);
061: if (loader == null) {
062: throw new IllegalArgumentException(
063: "ResourceLoader not found with name [" + loaderName
064: + "] in " + xmlFilename);
065: }
066: return loader.loadResource(location);
067: }
068:
069: public static URL getURL(String xmlFilename, String location,
070: String loaderName) throws GenericConfigException {
071: ResourceLoader loader = getLoader(xmlFilename, loaderName);
072: if (loader == null) {
073: throw new IllegalArgumentException(
074: "ResourceLoader not found with name [" + loaderName
075: + "] in " + xmlFilename);
076: }
077: return loader.getURL(location);
078: }
079:
080: public static ResourceLoader getLoader(String xmlFilename,
081: String loaderName) throws GenericConfigException {
082: ResourceLoader loader = (ResourceLoader) loaderCache
083: .get(xmlFilename + "::" + loaderName);
084:
085: if (loader == null) {
086: synchronized (ResourceLoader.class) {
087: loader = (ResourceLoader) loaderCache.get(xmlFilename
088: + "::" + loaderName);
089: if (loader == null) {
090: Element rootElement = getXmlRootElement(xmlFilename);
091:
092: Element loaderElement = UtilXml.firstChildElement(
093: rootElement, "resource-loader", "name",
094: loaderName);
095:
096: loader = makeLoader(loaderElement);
097:
098: if (loader != null) {
099: loaderCache
100: .put(xmlFilename + "::" + loaderName,
101: loader);
102: }
103: }
104: }
105: }
106:
107: return loader;
108: }
109:
110: public static Element getXmlRootElement(String xmlFilename)
111: throws GenericConfigException {
112: Document document = ResourceLoader.getXmlDocument(xmlFilename);
113:
114: if (document != null) {
115: return document.getDocumentElement();
116: } else {
117: return null;
118: }
119: }
120:
121: public static void invalidateDocument(String xmlFilename)
122: throws GenericConfigException {
123: synchronized (ResourceLoader.class) {
124: docSaveMap.remove(xmlFilename);
125: }
126: }
127:
128: public static Document getXmlDocument(String xmlFilename)
129: throws GenericConfigException {
130: Document document = (Document) docSaveMap.get(xmlFilename);
131:
132: if (document == null) {
133: synchronized (ResourceLoader.class) {
134: document = (Document) docSaveMap.get(xmlFilename);
135: if (document == null) {
136: URL confUrl = UtilURL.fromResource(xmlFilename);
137:
138: if (confUrl == null) {
139: throw new GenericConfigException(
140: "ERROR: could not find the ["
141: + xmlFilename
142: + "] XML file on the classpath");
143: }
144:
145: try {
146: document = UtilXml.readXmlDocument(confUrl);
147: } catch (org.xml.sax.SAXException e) {
148: throw new GenericConfigException(
149: "Error reading " + xmlFilename + "", e);
150: } catch (javax.xml.parsers.ParserConfigurationException e) {
151: throw new GenericConfigException(
152: "Error reading " + xmlFilename + "", e);
153: } catch (java.io.IOException e) {
154: throw new GenericConfigException(
155: "Error reading " + xmlFilename + "", e);
156: }
157:
158: if (document != null) {
159: docSaveMap.put(xmlFilename, document);
160: }
161: }
162: }
163: }
164: return document;
165: }
166:
167: public static ResourceLoader makeLoader(Element loaderElement)
168: throws GenericConfigException {
169: if (loaderElement == null)
170: return null;
171:
172: String loaderName = loaderElement.getAttribute("name");
173: String className = loaderElement.getAttribute("class");
174: ResourceLoader loader = null;
175:
176: try {
177: Class lClass = null;
178:
179: if (className != null && className.length() > 0) {
180: try {
181: ClassLoader classLoader = Thread.currentThread()
182: .getContextClassLoader();
183: lClass = classLoader.loadClass(className);
184: } catch (ClassNotFoundException e) {
185: throw new GenericConfigException(
186: "Error loading Resource Loader class \""
187: + className + "\"", e);
188: }
189: }
190:
191: try {
192: loader = (ResourceLoader) lClass.newInstance();
193: } catch (IllegalAccessException e) {
194: throw new GenericConfigException(
195: "Error loading Resource Loader class \""
196: + className + "\"", e);
197: } catch (InstantiationException e) {
198: throw new GenericConfigException(
199: "Error loading Resource Loader class \""
200: + className + "\"", e);
201: }
202: } catch (SecurityException e) {
203: throw new GenericConfigException(
204: "Error loading Resource Loader class \""
205: + className + "\"", e);
206: }
207:
208: if (loader != null) {
209: loader.init(loaderName, loaderElement
210: .getAttribute("prefix"), loaderElement
211: .getAttribute("prepend-env"));
212: }
213:
214: return loader;
215: }
216:
217: protected ResourceLoader() {
218: }
219:
220: public void init(String name, String prefix, String envName) {
221: this .name = name;
222: this .prefix = prefix;
223: this .envName = envName;
224: }
225:
226: /** Just a utility method to be used in loadResource by the implementing class * @param location
227: * @param location
228: * @return
229: */
230: public String fullLocation(String location) {
231: StringBuffer buf = new StringBuffer();
232:
233: if (envName != null && envName.length() > 0) {
234: String propValue = System.getProperty(envName);
235: if (propValue == null) {
236: String errMsg = "The Java environment (-Dxxx=yyy) variable with name "
237: + envName
238: + " is not set, cannot load resource.";
239: Debug.logError(errMsg, module);
240: throw new IllegalArgumentException(errMsg);
241: }
242: buf.append(propValue);
243: }
244: if (prefix != null && prefix.length() > 0) {
245: buf.append(prefix);
246: }
247: buf.append(location);
248: return buf.toString();
249: }
250:
251: public abstract InputStream loadResource(String location)
252: throws GenericConfigException;
253:
254: public abstract URL getURL(String location)
255: throws GenericConfigException;
256: }
|