View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package javax.xml.soap;
20  
21  import java.io.BufferedReader;
22  import java.io.File;
23  import java.io.FileInputStream;
24  import java.io.InputStream;
25  import java.io.InputStreamReader;
26  import java.util.Properties;
27  
28  /**
29   * This class is used to locate factory classes for javax.xml.soap. It has package scope since it is
30   * not part of JAXM and should not be accessed from other packages.
31   */
32  class FactoryFinder {
33      /**
34       * instantiates an object go the given classname.
35       *
36       * @param factoryClassName
37       * @return a factory object
38       * @throws SOAPException
39       */
40      private static Object newInstance(String factoryClassName) throws SOAPException {
41          ClassLoader classloader = null;
42          try {
43              classloader = Thread.currentThread().getContextClassLoader();
44          } catch (Exception exception) {
45              throw new SOAPException(exception.toString(), exception);
46          }
47  
48          try {
49              Class factory = null;
50              if (classloader == null) {
51                  factory = Class.forName(factoryClassName);
52              } else {
53                  try {
54                      factory = classloader.loadClass(factoryClassName);
55                  } catch (ClassNotFoundException cnfe) {
56                  }
57              }
58              if (factory == null) {
59                  classloader = FactoryFinder.class.getClassLoader();
60                  factory = classloader.loadClass(factoryClassName);
61              }
62              return factory.newInstance();
63          } catch (ClassNotFoundException classnotfoundexception) {
64              throw new SOAPException(
65                      "Provider " + factoryClassName + " not found",
66                      classnotfoundexception);
67          } catch (Exception exception) {
68              throw new SOAPException(
69                      "Provider " + factoryClassName +
70                              " could not be instantiated: " +
71                              exception,
72                      exception);
73          }
74      }
75  
76      /**
77       * Instantiates a factory object given the factory's property name and the default class name.
78       *
79       * @param factoryPropertyName
80       * @param defaultFactoryClassName
81       * @return a factory object
82       * @throws SOAPException
83       */
84      static Object find(String factoryPropertyName,
85                         String defaultFactoryClassName) throws SOAPException {
86          Object factory = find(factoryPropertyName);
87          if (factory != null) {
88              return factory;
89          }
90  
91          if (defaultFactoryClassName == null) {
92              throw new SOAPException(
93                      "Provider for " + factoryPropertyName + " cannot be found",
94                      null);
95          } else {
96              return newInstance(defaultFactoryClassName);
97          }
98      }
99  
100     /**
101      * Instantiates a factory object given the factory's property name.
102      *
103      * @param factoryPropertyName
104      * @return a factory object
105      * @throws SOAPException
106      */
107     static Object find(String factoryPropertyName) throws SOAPException {
108         try {
109             String factoryClassName = System.getProperty(factoryPropertyName);
110             if (factoryClassName != null) {
111                 return newInstance(factoryClassName);
112             }
113         } catch (SecurityException securityexception) {
114         }
115 
116         try {
117             String propertiesFileName = System.getProperty("java.home")
118                     + File.separator + "lib"
119                     + File.separator + "jaxm.properties";
120             File file = new File(propertiesFileName);
121             if (file.exists()) {
122                 FileInputStream fileInput = new FileInputStream(file);
123                 Properties properties = new Properties();
124                 properties.load(fileInput);
125                 fileInput.close();
126                 String factoryClassName = properties.getProperty(
127                         factoryPropertyName);
128                 return newInstance(factoryClassName);
129             }
130         } catch (Exception exception1) {
131         }
132 
133         String factoryResource = "META-INF/services/" + factoryPropertyName;
134         try {
135             InputStream inputstream = getResource(factoryResource);
136             if (inputstream != null) {
137                 BufferedReader bufferedreader = new BufferedReader(
138                         new InputStreamReader(inputstream, "UTF-8"));
139                 String factoryClassName = bufferedreader.readLine();
140                 bufferedreader.close();
141                 if ((factoryClassName != null) && !"".equals(factoryClassName)) {
142                     return newInstance(factoryClassName);
143                 }
144             }
145         } catch (Exception exception2) {
146         }
147 
148         return null;
149     }
150 
151     /**
152      * Returns an input stream for the specified resource.
153      * <p/>
154      * <p>This method will firstly try <code>ClassLoader.getSystemResourceAsStream()</code> then the
155      * class loader of the current thread with <code>getResourceAsStream()</code> and finally
156      * attempt <code>getResourceAsStream()</code> on <code>FactoryFinder.class.getClassLoader()</code>.
157      *
158      * @param factoryResource the resource name
159      * @return an InputStream that can be used to read that resource, or <code>null</code> if the
160      *         resource could not be resolved
161      */
162     private static InputStream getResource(String factoryResource) {
163         ClassLoader classloader = null;
164         try {
165             classloader = Thread.currentThread().getContextClassLoader();
166         } catch (SecurityException securityexception) {
167         }
168 
169         InputStream inputstream;
170         if (classloader == null) {
171             inputstream =
172                     ClassLoader.getSystemResourceAsStream(factoryResource);
173         } else {
174             inputstream = classloader.getResourceAsStream(factoryResource);
175         }
176 
177         if (inputstream == null) {
178             inputstream =
179                     FactoryFinder.class.getClassLoader().getResourceAsStream(
180                             factoryResource);
181         }
182         return inputstream;
183     }
184 }