001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Adam Megacz
028: */
029:
030: package javax.xml.stream;
031:
032: import java.io.File;
033: import java.io.FileInputStream;
034: import java.io.IOException;
035: import java.io.InputStream;
036: import java.net.URL;
037: import java.util.ArrayList;
038: import java.util.Enumeration;
039: import java.util.HashMap;
040: import java.util.Properties;
041: import java.util.WeakHashMap;
042: import java.util.logging.Level;
043: import java.util.logging.Logger;
044:
045: class FactoryLoader {
046: private static Logger log = Logger
047: .getLogger("javax.xml.stream.FactoryLoader");
048:
049: private static HashMap<String, FactoryLoader> _factoryLoaders = new HashMap<String, FactoryLoader>();
050:
051: private String _factoryId;
052:
053: private WeakHashMap<ClassLoader, Class[]> _providerMap = new WeakHashMap<ClassLoader, Class[]>();
054:
055: public static FactoryLoader getFactoryLoader(String factoryId) {
056: FactoryLoader ret = _factoryLoaders.get(factoryId);
057:
058: if (ret == null) {
059: ret = new FactoryLoader(factoryId);
060: _factoryLoaders.put(factoryId, ret);
061: }
062:
063: return ret;
064: }
065:
066: private FactoryLoader(String factoryId) {
067: this ._factoryId = factoryId;
068: }
069:
070: public Object newInstance(ClassLoader classLoader)
071: throws FactoryConfigurationError {
072: Class cl = newClass(classLoader);
073:
074: if (cl != null) {
075: try {
076: return cl.newInstance();
077: } catch (Exception e) {
078: throw new FactoryConfigurationError(e);
079: }
080: }
081:
082: return null;
083: }
084:
085: public Class newClass(ClassLoader classLoader)
086: throws FactoryConfigurationError {
087: String className = null;
088:
089: className = System.getProperty(_factoryId);
090:
091: if (className == null) {
092:
093: String fileName = (System.getProperty("java.home")
094: + File.separatorChar + "lib" + File.separatorChar + "stax.properties");
095:
096: FileInputStream is = null;
097: try {
098: is = new FileInputStream(new File(fileName));
099:
100: Properties props = new Properties();
101: props.load(is);
102:
103: className = props.getProperty(_factoryId);
104: } catch (IOException e) {
105: log.log(Level.FINEST, "ignoring exception", e);
106: } finally {
107: if (is != null)
108: try {
109: is.close();
110: } catch (IOException e) {
111: log.log(Level.FINER, "ignoring exception", e);
112: }
113: }
114: }
115:
116: if (className == null) {
117: Class cl = createFactoryClass("META-INF/services/"
118: + _factoryId, classLoader);
119: if (cl != null)
120: return cl;
121: }
122:
123: if (className != null) {
124: try {
125: return classLoader.loadClass(className);
126: } catch (Exception e) {
127: throw new FactoryConfigurationError(e);
128: }
129: }
130:
131: return null;
132: }
133:
134: public Class createFactoryClass(String name, ClassLoader loader) {
135: Class[] providers = getProviderList(name, loader);
136:
137: for (int i = 0; i < providers.length; i++) {
138: Class factory;
139:
140: factory = providers[i];
141:
142: if (factory != null)
143: return factory;
144: }
145:
146: return null;
147: }
148:
149: private Class[] getProviderList(String service, ClassLoader loader) {
150: Class[] providers = _providerMap.get(loader);
151:
152: if (providers != null)
153: return providers;
154:
155: ArrayList<Class> list = new ArrayList<Class>();
156:
157: try {
158: Enumeration e = loader.getResources(service);
159:
160: while (e.hasMoreElements()) {
161: URL url = (URL) e.nextElement();
162:
163: Class provider = loadProvider(url, loader);
164:
165: if (provider != null)
166: list.add(provider);
167: }
168: } catch (Throwable e) {
169: log.log(Level.WARNING, e.toString(), e);
170: }
171:
172: providers = new Class[list.size()];
173: list.toArray(providers);
174:
175: _providerMap.put(loader, providers);
176:
177: return providers;
178: }
179:
180: private Class loadProvider(URL url, ClassLoader loader) {
181: InputStream is = null;
182: try {
183: is = url.openStream();
184: int ch;
185:
186: while ((ch = is.read()) >= 0) {
187: if (Character.isWhitespace((char) ch)) {
188: } else if (ch == '#') {
189: for (; ch >= 0 && ch != '\n' && ch != '\r'; ch = is
190: .read()) {
191: }
192: } else {
193: StringBuilder sb = new StringBuilder();
194:
195: for (; ch >= 0
196: && !Character.isWhitespace((char) ch); ch = is
197: .read()) {
198: sb.append((char) ch);
199: }
200:
201: String className = sb.toString();
202:
203: Class cl = Class.forName(className, false, loader);
204:
205: return cl;
206: }
207: }
208: } catch (Exception e) {
209: log.log(Level.WARNING, e.toString(), e);
210: } finally {
211: try {
212: if (is != null)
213: is.close();
214: } catch (IOException e) {
215: }
216: }
217:
218: return null;
219: }
220: }
|