001: /*
002: * Copyright (c) 1998-2007 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.soap;
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.soap.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 && log.isLoggable(Level.FINEST)) {
092: log.finest(_factoryId
093: + ": got factory className from System property: "
094: + className);
095: }
096:
097: if (className == null) {
098:
099: String fileName = (System.getProperty("java.home")
100: + File.separatorChar + "lib" + File.separatorChar + "jaxm.properties");
101:
102: FileInputStream is = null;
103: try {
104: is = new FileInputStream(new File(fileName));
105:
106: Properties props = new Properties();
107: props.load(is);
108:
109: className = props.getProperty(_factoryId);
110:
111: if (className != null && log.isLoggable(Level.FINEST)) {
112: log.finest(_factoryId
113: + ": got factory className from "
114: + "jaxm.properties: " + className);
115: }
116:
117: } catch (IOException e) {
118: log.log(Level.FINEST, "ignoring exception", e);
119: } finally {
120: if (is != null)
121: try {
122: is.close();
123: } catch (IOException e) {
124: log.log(Level.FINER, "ignoring exception", e);
125: }
126: }
127: }
128:
129: if (className == null) {
130: Class cl = createFactoryClass("META-INF/services/"
131: + _factoryId, classLoader);
132: if (cl != null) {
133: if (log.isLoggable(Level.FINEST)) {
134: log.finest(_factoryId
135: + ": got factory className from "
136: + "META-INF/services/: " + cl.getName());
137: }
138:
139: return cl;
140: }
141: }
142:
143: if (className != null) {
144: try {
145: return classLoader.loadClass(className);
146: } catch (Exception e) {
147: throw new FactoryConfigurationError(e);
148: }
149: }
150:
151: return null;
152: }
153:
154: public Class createFactoryClass(String name, ClassLoader loader) {
155: Class[] providers = getProviderList(name, loader);
156:
157: for (int i = 0; i < providers.length; i++) {
158: Class factory;
159:
160: factory = providers[i];
161:
162: if (factory != null)
163: return factory;
164: }
165:
166: return null;
167: }
168:
169: private Class[] getProviderList(String service, ClassLoader loader) {
170: Class[] providers = _providerMap.get(loader);
171:
172: if (providers != null)
173: return providers;
174:
175: ArrayList<Class> list = new ArrayList<Class>();
176:
177: try {
178: Enumeration e = loader.getResources(service);
179:
180: while (e.hasMoreElements()) {
181: URL url = (URL) e.nextElement();
182:
183: Class provider = loadProvider(url, loader);
184:
185: if (provider != null)
186: list.add(provider);
187: }
188: } catch (Throwable e) {
189: log.log(Level.WARNING, e.toString(), e);
190: }
191:
192: providers = new Class[list.size()];
193: list.toArray(providers);
194:
195: _providerMap.put(loader, providers);
196:
197: return providers;
198: }
199:
200: private Class loadProvider(URL url, ClassLoader loader) {
201: InputStream is = null;
202: try {
203: is = url.openStream();
204: int ch;
205:
206: while ((ch = is.read()) >= 0) {
207: if (Character.isWhitespace((char) ch)) {
208: } else if (ch == '#') {
209: for (; ch >= 0 && ch != '\n' && ch != '\r'; ch = is
210: .read()) {
211: }
212: } else {
213: StringBuilder sb = new StringBuilder();
214:
215: for (; ch >= 0
216: && !Character.isWhitespace((char) ch); ch = is
217: .read()) {
218: sb.append((char) ch);
219: }
220:
221: String className = sb.toString();
222:
223: Class cl = Class.forName(className, false, loader);
224:
225: return cl;
226: }
227: }
228: } catch (Exception e) {
229: log.log(Level.WARNING, e.toString(), e);
230: } finally {
231: try {
232: if (is != null)
233: is.close();
234: } catch (IOException e) {
235: }
236: }
237:
238: return null;
239: }
240: }
|