001: /* ====================================================================
002: * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
003: *
004: * Copyright (c) 1995-2003 Jcorporate Ltd. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution,
019: * if any, must include the following acknowledgment:
020: * "This product includes software developed by Jcorporate Ltd.
021: * (http://www.jcorporate.com/)."
022: * Alternately, this acknowledgment may appear in the software itself,
023: * if and wherever such third-party acknowledgments normally appear.
024: *
025: * 4. "Jcorporate" and product names such as "Expresso" must
026: * not be used to endorse or promote products derived from this
027: * software without prior written permission. For written permission,
028: * please contact info@jcorporate.com.
029: *
030: * 5. Products derived from this software may not be called "Expresso",
031: * or other Jcorporate product names; nor may "Expresso" or other
032: * Jcorporate product names appear in their name, without prior
033: * written permission of Jcorporate Ltd.
034: *
035: * 6. No product derived from this software may compete in the same
036: * market space, i.e. framework, without prior written permission
037: * of Jcorporate Ltd. For written permission, please contact
038: * partners@jcorporate.com.
039: *
040: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
041: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
042: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
043: * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
044: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
045: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
046: * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
047: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
048: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
049: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
050: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
051: * SUCH DAMAGE.
052: * ====================================================================
053: *
054: * This software consists of voluntary contributions made by many
055: * individuals on behalf of the Jcorporate Ltd. Contributions back
056: * to the project(s) are encouraged when you make modifications.
057: * Please send them to support@jcorporate.com. For more information
058: * on Jcorporate Ltd. and its products, please see
059: * <http://www.jcorporate.com/>.
060: *
061: * Portions of this software are based upon other open source
062: * products and are subject to their respective licenses.
063: */
064: package com.jcorporate.expresso.kernel.digester;
065:
066: import com.jcorporate.expresso.kernel.util.ClassLocator;
067: import org.apache.log4j.Logger;
068: import org.xml.sax.SAXException;
069:
070: /**
071: * Class that sets the current SAX parser properties for the use by the
072: * javax.*Factory methods. This is basically used once before the Digester
073: * is loaded and used.
074: *
075: * @author Michael Rimov, Shash Chatterjee
076: */
077:
078: public class SaxParserConfigurer {
079: static boolean configured = false;
080:
081: private static final Logger log = Logger
082: .getLogger(SaxParserConfigurer.class);
083:
084: public SaxParserConfigurer() {
085: setSAXParser();
086: }
087:
088: /*
089: * Goes through a pre-determined list of SAX parsers,
090: * the first one found is used to parse XML config files.
091: */
092: synchronized void setSAXParser() {
093: synchronized (SaxParserConfigurer.class) {
094: if (configured) {
095: return;
096: }
097:
098: //
099: //Check for previously explicitly defined parsers. If they're set,
100: //obey the law of the land.
101: //
102: String curParser = System.getProperty(
103: "javax.xml.parsers.SAXParserFactory", null);
104: if (curParser == null) {
105: curParser = System.getProperty("org.xml.sax.parser",
106: null);
107: }
108:
109: if (curParser != null && curParser.length() > 0) {
110: System.out
111: .println("SAX Parser already explicitly defined. It is: "
112: + curParser);
113: configured = true;
114: return;
115: }
116:
117: // The class names and descriptions of parsers to look for
118: MySAXParser[] parserList = {
119: new MySAXParser(
120: "org.apache.xerces.jaxp.SAXParserFactoryImpl",
121: "org.apache.xerces.parsers.SAXParser",
122: "Apache Xerces"),
123:
124: new MySAXParser(
125: "org.apache.crimson.jaxp.SAXParserFactoryImpl",
126: "org.apache.crimson.parser.XMLReaderImpl",
127: "Apache Crimson"),
128:
129: //
130: //http://www.xmlmind.com/xpforjaxp.html
131: //JAXP Capable modification to James Clark's XP
132: //
133: new MySAXParser(
134: "com.jclark.xml.jaxp.SAXParserFactoryImpl",
135: "com.jclark.xml.sax.Driver",
136: "James Clark's XP with SAX Additions"),
137:
138: //
139: //GNU JAXP Implementation
140: //
141: new MySAXParser("gnu.xml.aelfred2.JAXPFactory",
142: "gnu.xml.dom.JAXPFactory", "GNU JAXP"),
143:
144: };
145:
146: // Search through each element of parser list to see
147: // if parser exists in classpath
148: int idx = 0;
149: while ((idx < parserList.length)
150: && (!parserList[idx].existsInClasspath())) {
151: idx++;
152: }
153:
154: // If parser found set the system property that SAX uses to load the parser
155: // otherwise, print an error message
156: if (idx < parserList.length) {
157: log.info("Setting default XML parser factory to "
158: + parserList[idx].getDesc());
159: System.setProperty(
160: "javax.xml.parsers.SAXParserFactory",
161: parserList[idx].getName());
162: System.setProperty("org.xml.sax.driver",
163: parserList[idx].getSAXDriverName());
164: } else {
165: log
166: .info("Couldn't find a suitable SAX/JAXP-compliant XML parser");
167: log
168: .info("Please put Apache Crimson or Xerces in classpath");
169: }
170:
171: configured = true;
172: }
173: }
174:
175: /*
176: * A small class to hold the name/desc pair of SAXParsers
177: * Provides utility function to check if specified parser is in classpath
178: * Added By Shash Chatterjee 7/20/02
179: */
180: class MySAXParser {
181: // The classname of the class
182: private String className = null;
183:
184: // The classname of the class
185: private String saxDriverClassName = null;
186:
187: // The description of the Parser
188: private String classDesc = null;
189:
190: // Only public constructor
191: public MySAXParser(String cName, String sdcName, String cDesc) {
192: className = cName;
193: saxDriverClassName = sdcName;
194: classDesc = cDesc;
195: }
196:
197: // Disallow use of the default constructor
198: private MySAXParser() {
199: }
200:
201: public String getName() {
202: return className;
203: }
204:
205: public String getSAXDriverName() {
206: return saxDriverClassName;
207: }
208:
209: public String getDesc() {
210: return classDesc;
211: }
212:
213: // Check if this SAX parser exists in the classpath
214: public boolean existsInClasspath() {
215: boolean returnValue = true;
216: String oldProperty = null;
217: try {
218: Class clazz = ClassLocator.loadClass(getName());
219:
220: //
221: //Ok so far, now let's try actually getting a parser factory with
222: //this information and see what happens
223: //
224: //
225: //Ok so far, now let's try actually getting a parser factory with
226: //this information and see what happens
227: //
228: if (oldProperty == null) {
229: oldProperty = System
230: .getProperty("javax.xml.parsers.SAXParserFactory");
231: }
232: try {
233: System.setProperty(
234: "javax.xml.parsers.SAXParserFactory",
235: getName());
236: javax.xml.parsers.SAXParserFactory spf = javax.xml.parsers.SAXParserFactory
237: .newInstance();
238: javax.xml.parsers.SAXParser sp = spf.newSAXParser();
239: } catch (java.security.AccessControlException ex) {
240: log
241: .warn("App Server would not let us set the SAX Parser to another parser.");
242: }
243: } catch (ClassNotFoundException cnfe) {
244: returnValue = false;
245: } catch (javax.xml.parsers.ParserConfigurationException ex) {
246: System.err.println("Found class " + getName()
247: + " but unable to instantiate SAX Parser "
248: + ex.getMessage());
249: ex.printStackTrace(System.err);
250: returnValue = false;
251: } catch (SAXException ex) {
252: System.err.println("Found class " + getName()
253: + " but unable to instantiate SAX Parser "
254: + ex.getMessage());
255: ex.printStackTrace(System.err);
256: returnValue = false;
257: } catch (javax.xml.parsers.FactoryConfigurationError ex) {
258: System.err.println("Found class " + getName()
259: + " but unable to instantiate ClassFactory "
260: + ex.getMessage());
261: ex.printStackTrace(System.err);
262: returnValue = false;
263: }
264:
265: //Ok, we've done mucking with things, set the old SAXParserFactory
266: //back
267: if (oldProperty != null) {
268: System.setProperty(
269: "javax.xml.parsers.SAXParserFactory",
270: oldProperty);
271: }
272:
273: return returnValue;
274: }
275: }
276: }
|