|
1 /* |
|
2 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 |
|
26 // XMLReaderFactory.java - factory for creating a new reader. |
|
27 // http://www.saxproject.org |
|
28 // Written by David Megginson |
|
29 // and by David Brownell |
|
30 // NO WARRANTY! This class is in the Public Domain. |
|
31 // $Id: XMLReaderFactory.java,v 1.2.2.1 2005/07/31 22:48:08 jeffsuttor Exp $ |
|
32 |
|
33 package org.xml.sax.helpers; |
|
34 import java.io.BufferedReader; |
|
35 import java.io.InputStream; |
|
36 import java.io.InputStreamReader; |
|
37 import org.xml.sax.XMLReader; |
|
38 import org.xml.sax.SAXException; |
|
39 |
|
40 |
|
41 /** |
|
42 * Factory for creating an XML reader. |
|
43 * |
|
44 * <blockquote> |
|
45 * <em>This module, both source code and documentation, is in the |
|
46 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em> |
|
47 * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a> |
|
48 * for further information. |
|
49 * </blockquote> |
|
50 * |
|
51 * <p>This class contains static methods for creating an XML reader |
|
52 * from an explicit class name, or based on runtime defaults:</p> |
|
53 * |
|
54 * <pre> |
|
55 * try { |
|
56 * XMLReader myReader = XMLReaderFactory.createXMLReader(); |
|
57 * } catch (SAXException e) { |
|
58 * System.err.println(e.getMessage()); |
|
59 * } |
|
60 * </pre> |
|
61 * |
|
62 * <p><strong>Note to Distributions bundled with parsers:</strong> |
|
63 * You should modify the implementation of the no-arguments |
|
64 * <em>createXMLReader</em> to handle cases where the external |
|
65 * configuration mechanisms aren't set up. That method should do its |
|
66 * best to return a parser when one is in the class path, even when |
|
67 * nothing bound its class name to <code>org.xml.sax.driver</code> so |
|
68 * those configuration mechanisms would see it.</p> |
|
69 * |
|
70 * @since SAX 2.0 |
|
71 * @author David Megginson, David Brownell |
|
72 */ |
|
73 final public class XMLReaderFactory |
|
74 { |
|
75 /** |
|
76 * Private constructor. |
|
77 * |
|
78 * <p>This constructor prevents the class from being instantiated.</p> |
|
79 */ |
|
80 private XMLReaderFactory () |
|
81 { |
|
82 } |
|
83 |
|
84 private static final String property = "org.xml.sax.driver"; |
|
85 |
|
86 /** |
|
87 * Attempt to create an XMLReader from system defaults. |
|
88 * In environments which can support it, the name of the XMLReader |
|
89 * class is determined by trying each these options in order, and |
|
90 * using the first one which succeeds:</p> <ul> |
|
91 * |
|
92 * <li>If the system property <code>org.xml.sax.driver</code> |
|
93 * has a value, that is used as an XMLReader class name. </li> |
|
94 * |
|
95 * <li>The JAR "Services API" is used to look for a class name |
|
96 * in the <em>META-INF/services/org.xml.sax.driver</em> file in |
|
97 * jarfiles available to the runtime.</li> |
|
98 * |
|
99 * <li> SAX parser distributions are strongly encouraged to provide |
|
100 * a default XMLReader class name that will take effect only when |
|
101 * previous options (on this list) are not successful.</li> |
|
102 * |
|
103 * <li>Finally, if {@link ParserFactory#makeParser()} can |
|
104 * return a system default SAX1 parser, that parser is wrapped in |
|
105 * a {@link ParserAdapter}. (This is a migration aid for SAX1 |
|
106 * environments, where the <code>org.xml.sax.parser</code> system |
|
107 * property will often be usable.) </li> |
|
108 * |
|
109 * </ul> |
|
110 * |
|
111 * <p> In environments such as small embedded systems, which can not |
|
112 * support that flexibility, other mechanisms to determine the default |
|
113 * may be used. </p> |
|
114 * |
|
115 * <p>Note that many Java environments allow system properties to be |
|
116 * initialized on a command line. This means that <em>in most cases</em> |
|
117 * setting a good value for that property ensures that calls to this |
|
118 * method will succeed, except when security policies intervene. |
|
119 * This will also maximize application portability to older SAX |
|
120 * environments, with less robust implementations of this method. |
|
121 * </p> |
|
122 * |
|
123 * @return A new XMLReader. |
|
124 * @exception org.xml.sax.SAXException If no default XMLReader class |
|
125 * can be identified and instantiated. |
|
126 * @see #createXMLReader(java.lang.String) |
|
127 */ |
|
128 public static XMLReader createXMLReader () |
|
129 throws SAXException |
|
130 { |
|
131 String className = null; |
|
132 ClassLoader loader = NewInstance.getClassLoader (); |
|
133 |
|
134 // 1. try the JVM-instance-wide system property |
|
135 try { className = System.getProperty (property); } |
|
136 catch (RuntimeException e) { /* normally fails for applets */ } |
|
137 |
|
138 // 2. if that fails, try META-INF/services/ |
|
139 if (className == null) { |
|
140 try { |
|
141 String service = "META-INF/services/" + property; |
|
142 InputStream in; |
|
143 BufferedReader reader; |
|
144 |
|
145 if (loader == null) |
|
146 in = ClassLoader.getSystemResourceAsStream (service); |
|
147 else |
|
148 in = loader.getResourceAsStream (service); |
|
149 |
|
150 if (in != null) { |
|
151 reader = new BufferedReader ( |
|
152 new InputStreamReader (in, "UTF8")); |
|
153 className = reader.readLine (); |
|
154 in.close (); |
|
155 } |
|
156 } catch (Exception e) { |
|
157 } |
|
158 } |
|
159 |
|
160 // 3. Distro-specific fallback |
|
161 if (className == null) { |
|
162 // BEGIN DISTRIBUTION-SPECIFIC |
|
163 |
|
164 // EXAMPLE: |
|
165 // className = "com.example.sax.XmlReader"; |
|
166 // or a $JAVA_HOME/jre/lib/*properties setting... |
|
167 className = "com.sun.org.apache.xerces.internal.parsers.SAXParser"; |
|
168 |
|
169 // END DISTRIBUTION-SPECIFIC |
|
170 } |
|
171 |
|
172 // do we know the XMLReader implementation class yet? |
|
173 if (className != null) |
|
174 return loadClass (loader, className); |
|
175 |
|
176 // 4. panic -- adapt any SAX1 parser |
|
177 try { |
|
178 return new ParserAdapter (ParserFactory.makeParser ()); |
|
179 } catch (Exception e) { |
|
180 throw new SAXException ("Can't create default XMLReader; " |
|
181 + "is system property org.xml.sax.driver set?"); |
|
182 } |
|
183 } |
|
184 |
|
185 |
|
186 /** |
|
187 * Attempt to create an XML reader from a class name. |
|
188 * |
|
189 * <p>Given a class name, this method attempts to load |
|
190 * and instantiate the class as an XML reader.</p> |
|
191 * |
|
192 * <p>Note that this method will not be usable in environments where |
|
193 * the caller (perhaps an applet) is not permitted to load classes |
|
194 * dynamically.</p> |
|
195 * |
|
196 * @return A new XML reader. |
|
197 * @exception org.xml.sax.SAXException If the class cannot be |
|
198 * loaded, instantiated, and cast to XMLReader. |
|
199 * @see #createXMLReader() |
|
200 */ |
|
201 public static XMLReader createXMLReader (String className) |
|
202 throws SAXException |
|
203 { |
|
204 return loadClass (NewInstance.getClassLoader (), className); |
|
205 } |
|
206 |
|
207 private static XMLReader loadClass (ClassLoader loader, String className) |
|
208 throws SAXException |
|
209 { |
|
210 try { |
|
211 return (XMLReader) NewInstance.newInstance (loader, className); |
|
212 } catch (ClassNotFoundException e1) { |
|
213 throw new SAXException("SAX2 driver class " + className + |
|
214 " not found", e1); |
|
215 } catch (IllegalAccessException e2) { |
|
216 throw new SAXException("SAX2 driver class " + className + |
|
217 " found but cannot be loaded", e2); |
|
218 } catch (InstantiationException e3) { |
|
219 throw new SAXException("SAX2 driver class " + className + |
|
220 " loaded but cannot be instantiated (no empty public constructor?)", |
|
221 e3); |
|
222 } catch (ClassCastException e4) { |
|
223 throw new SAXException("SAX2 driver class " + className + |
|
224 " does not implement XMLReader", e4); |
|
225 } |
|
226 } |
|
227 } |