1 /*
2 * $Id: FactoryFinder.java,v 1.5 2004/04/02 01:24:17 ofung Exp $
3 * $Revision: 1.5 $
4 * $Date: 2004/04/02 01:24:17 $
5 */
6
7 /*
8 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
9 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10 *
11 * This code is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License version 2 only, as
13 * published by the Free Software Foundation. Sun designates this
14 * particular file as subject to the "Classpath" exception as provided
15 * by Sun in the LICENSE file that accompanied this code.
16 *
17 * This code is distributed in the hope that it will be useful, but WITHOUT
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * version 2 for more details (a copy is included in the LICENSE file that
21 * accompanied this code).
22 *
23 * You should have received a copy of the GNU General Public License version
24 * 2 along with this work; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
28 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * have any questions.
30 */
31
32 package javax.xml.soap;
33
34 import java.io;
35 import java.util.Properties;
36
37
38 class FactoryFinder {
39
40 /**
41 * Creates an instance of the specified class using the specified
42 * <code>ClassLoader</code> object.
43 *
44 * @exception SOAPException if the given class could not be found
45 * or could not be instantiated
46 */
47 private static Object newInstance(String className,
48 ClassLoader classLoader)
49 throws SOAPException
50 {
51 try {
52 Class spiClass;
53 if (classLoader == null) {
54 spiClass = Class.forName(className);
55 } else {
56 spiClass = classLoader.loadClass(className);
57 }
58 return spiClass.newInstance();
59 } catch (ClassNotFoundException x) {
60 throw new SOAPException(
61 "Provider " + className + " not found", x);
62 } catch (Exception x) {
63 throw new SOAPException(
64 "Provider " + className + " could not be instantiated: " + x,
65 x);
66 }
67 }
68
69 /**
70 * Finds the implementation <code>Class</code> object for the given
71 * factory name, or null if that fails.
72 * <P>
73 * This method is package private so that this code can be shared.
74 *
75 * @return the <code>Class</code> object of the specified message factory;
76 * or <code>null</code>
77 *
78 * @param factoryId the name of the factory to find, which is
79 * a system property
80 * @exception SOAPException if there is a SOAP error
81 */
82 static Object find(String factoryId)
83 throws SOAPException
84 {
85 ClassLoader classLoader;
86 try {
87 classLoader = Thread.currentThread().getContextClassLoader();
88 } catch (Exception x) {
89 throw new SOAPException(x.toString(), x);
90 }
91
92 // Use the system property first
93 try {
94 String systemProp =
95 System.getProperty( factoryId );
96 if( systemProp!=null) {
97 return newInstance(systemProp, classLoader);
98 }
99 } catch (SecurityException se) {
100 }
101
102 // try to read from $java.home/lib/jaxm.properties
103 try {
104 String javah=System.getProperty( "java.home" );
105 String configFile = javah + File.separator +
106 "lib" + File.separator + "jaxm.properties";
107 File f=new File( configFile );
108 if( f.exists()) {
109 Properties props=new Properties();
110 props.load( new FileInputStream(f));
111 String factoryClassName = props.getProperty(factoryId);
112 return newInstance(factoryClassName, classLoader);
113 }
114 } catch(Exception ex ) {
115 }
116
117 String serviceId = "META-INF/services/" + factoryId;
118 // try to find services in CLASSPATH
119 try {
120 InputStream is=null;
121 if (classLoader == null) {
122 is=ClassLoader.getSystemResourceAsStream(serviceId);
123 } else {
124 is=classLoader.getResourceAsStream(serviceId);
125 }
126
127 if( is!=null ) {
128 BufferedReader rd =
129 new BufferedReader(new InputStreamReader(is, "UTF-8"));
130
131 String factoryClassName = rd.readLine();
132 rd.close();
133
134 if (factoryClassName != null &&
135 ! "".equals(factoryClassName)) {
136 return newInstance(factoryClassName, classLoader);
137 }
138 }
139 } catch( Exception ex ) {
140 }
141
142 return null;
143 }
144
145 /**
146 * Finds the implementation <code>Class</code> object for the given
147 * factory name, or if that fails, finds the <code>Class</code> object
148 * for the given fallback class name. The arguments supplied must be
149 * used in order. If using the first argument is successful, the second
150 * one will not be used.
151 * <P>
152 * This method is package private so that this code can be shared.
153 *
154 * @return the <code>Class</code> object of the specified message factory;
155 * may not be <code>null</code>
156 *
157 * @param factoryId the name of the factory to find, which is
158 * a system property
159 * @param fallbackClassName the implementation class name, which is
160 * to be used only if nothing else
161 * is found; <code>null</code> to indicate that
162 * there is no fallback class name
163 * @exception SOAPException if there is a SOAP error
164 */
165 static Object find(String factoryId, String fallbackClassName)
166 throws SOAPException
167 {
168
169 Object obj = find(factoryId);
170 if (obj != null)
171 return obj;
172
173 ClassLoader classLoader;
174 try {
175 classLoader = Thread.currentThread().getContextClassLoader();
176 } catch (Exception x) {
177 throw new SOAPException(x.toString(), x);
178 }
179
180 if (fallbackClassName == null) {
181 throw new SOAPException(
182 "Provider for " + factoryId + " cannot be found", null);
183 }
184
185 return newInstance(fallbackClassName, classLoader);
186 }
187 }