001: /*
002: * $Id: FactoryFinder.java,v 1.7 2006/03/30 00:59:38 ofung Exp $
003: * $Revision: 1.7 $
004: * $Date: 2006/03/30 00:59:38 $
005: */
006:
007: /*
008: * The contents of this file are subject to the terms
009: * of the Common Development and Distribution License
010: * (the License). You may not use this file except in
011: * compliance with the License.
012: *
013: * You can obtain a copy of the license at
014: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * See the License for the specific language governing
016: * permissions and limitations under the License.
017: *
018: * When distributing Covered Code, include this CDDL
019: * Header Notice in each file and include the License file
020: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
021: * If applicable, add the following below the CDDL Header,
022: * with the fields enclosed by brackets [] replaced by
023: * you own identifying information:
024: * "Portions Copyrighted [year] [name of copyright owner]"
025: *
026: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
027: */
028:
029: package javax.xml.soap;
030:
031: import java.io.*;
032: import java.util.Properties;
033:
034: class FactoryFinder {
035:
036: /**
037: * Creates an instance of the specified class using the specified
038: * <code>ClassLoader</code> object.
039: *
040: * @exception SOAPException if the given class could not be found
041: * or could not be instantiated
042: */
043: private static Object newInstance(String className,
044: ClassLoader classLoader) throws SOAPException {
045: try {
046: Class spiClass;
047: if (classLoader == null) {
048: spiClass = Class.forName(className);
049: } else {
050: spiClass = classLoader.loadClass(className);
051: }
052: return spiClass.newInstance();
053: } catch (ClassNotFoundException x) {
054: throw new SOAPException("Provider " + className
055: + " not found", x);
056: } catch (Exception x) {
057: throw new SOAPException("Provider " + className
058: + " could not be instantiated: " + x, x);
059: }
060: }
061:
062: /**
063: * Finds the implementation <code>Class</code> object for the given
064: * factory name, or null if that fails.
065: * <P>
066: * This method is package private so that this code can be shared.
067: *
068: * @return the <code>Class</code> object of the specified message factory;
069: * or <code>null</code>
070: *
071: * @param factoryId the name of the factory to find, which is
072: * a system property
073: * @exception SOAPException if there is a SOAP error
074: */
075: static Object find(String factoryId) throws SOAPException {
076: ClassLoader classLoader;
077: try {
078: classLoader = Thread.currentThread()
079: .getContextClassLoader();
080: } catch (Exception x) {
081: throw new SOAPException(x.toString(), x);
082: }
083:
084: // Use the system property first
085: try {
086: String systemProp = System.getProperty(factoryId);
087: if (systemProp != null) {
088: return newInstance(systemProp, classLoader);
089: }
090: } catch (SecurityException se) {
091: }
092:
093: // try to read from $java.home/lib/jaxm.properties
094: try {
095: String javah = System.getProperty("java.home");
096: String configFile = javah + File.separator + "lib"
097: + File.separator + "jaxm.properties";
098: File f = new File(configFile);
099: if (f.exists()) {
100: Properties props = new Properties();
101: props.load(new FileInputStream(f));
102: String factoryClassName = props.getProperty(factoryId);
103: return newInstance(factoryClassName, classLoader);
104: }
105: } catch (Exception ex) {
106: }
107:
108: String serviceId = "META-INF/services/" + factoryId;
109: // try to find services in CLASSPATH
110: try {
111: InputStream is = null;
112: if (classLoader == null) {
113: is = ClassLoader.getSystemResourceAsStream(serviceId);
114: } else {
115: is = classLoader.getResourceAsStream(serviceId);
116: }
117:
118: if (is != null) {
119: BufferedReader rd = new BufferedReader(
120: new InputStreamReader(is, "UTF-8"));
121:
122: String factoryClassName = rd.readLine();
123: rd.close();
124:
125: if (factoryClassName != null
126: && !"".equals(factoryClassName)) {
127: return newInstance(factoryClassName, classLoader);
128: }
129: }
130: } catch (Exception ex) {
131: }
132:
133: return null;
134: }
135:
136: /**
137: * Finds the implementation <code>Class</code> object for the given
138: * factory name, or if that fails, finds the <code>Class</code> object
139: * for the given fallback class name. The arguments supplied must be
140: * used in order. If using the first argument is successful, the second
141: * one will not be used.
142: * <P>
143: * This method is package private so that this code can be shared.
144: *
145: * @return the <code>Class</code> object of the specified message factory;
146: * may not be <code>null</code>
147: *
148: * @param factoryId the name of the factory to find, which is
149: * a system property
150: * @param fallbackClassName the implementation class name, which is
151: * to be used only if nothing else
152: * is found; <code>null</code> to indicate that
153: * there is no fallback class name
154: * @exception SOAPException if there is a SOAP error
155: */
156: static Object find(String factoryId, String fallbackClassName)
157: throws SOAPException {
158:
159: Object obj = find(factoryId);
160: if (obj != null)
161: return obj;
162:
163: ClassLoader classLoader;
164: try {
165: classLoader = Thread.currentThread()
166: .getContextClassLoader();
167: } catch (Exception x) {
168: throw new SOAPException(x.toString(), x);
169: }
170:
171: if (fallbackClassName == null) {
172: throw new SOAPException("Provider for " + factoryId
173: + " cannot be found", null);
174: }
175:
176: return newInstance(fallbackClassName, classLoader);
177: }
178: }
|