001/*
002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
003 * 
004 * This software is open source. 
005 * See the bottom of this file for the licence.
006 * 
007 * $Id: SAXHelper.java,v 1.9 2001/10/12 11:05:14 jstrachan Exp $
008 */
009
010package org.dom4j.io;
011
012import java.lang.reflect.InvocationTargetException;
013import java.lang.reflect.Method;
014
015import org.dom4j.io.aelfred.SAXDriver;
016
017import org.xml.sax.SAXException;
018import org.xml.sax.SAXNotRecognizedException;
019import org.xml.sax.SAXNotSupportedException;
020import org.xml.sax.XMLReader;
021import org.xml.sax.helpers.XMLReaderFactory;
022
023/** <p><code>SAXHelper</code> contains some helper methods for working with 
024  * SAX and XMLReader objects.
025  *
026  * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
027  * @version $Revision: 1.9 $
028  */
029class SAXHelper {
030
031    private static boolean loggedWarning = false;
032    
033    public static boolean setParserProperty(XMLReader reader, String propertyName, Object value) {    
034        try {
035            reader.setProperty(propertyName, value);
036            return true;
037        } 
038        catch (SAXNotSupportedException e) {
039            // ignore
040        } 
041        catch (SAXNotRecognizedException e) {
042            // ignore
043        }
044        return false;
045    }
046
047    public static boolean setParserFeature(XMLReader reader, String featureName, boolean value) {    
048        try {
049            reader.setFeature(featureName, value);
050            return true;
051        } 
052        catch (SAXNotSupportedException e) {
053            // ignore
054        } 
055        catch (SAXNotRecognizedException e) {
056            // ignore
057        }
058        return false;
059    }
060
061    /** Creats a default XMLReader via the org.xml.sax.driver system property 
062      * or JAXP if the system property is not set.
063      */
064    public static XMLReader createXMLReader(boolean validating) throws SAXException {
065        XMLReader reader = createXMLReaderViaJAXP( validating, true );
066        if ( reader == null ) {
067            String className = null;
068            try {
069                className = System.getProperty( "org.xml.sax.driver" );
070            }
071            catch (Exception e) {
072            }
073            if ( className != null && className.trim().length() > 0 && classNameAvailable( className ) ) {
074                reader = XMLReaderFactory.createXMLReader();
075            }
076            if ( reader == null ) {
077                reader = new SAXDriver();
078            }
079        }
080        return reader;
081    }
082
083    /** This method attempts to use JAXP to locate the  
084      * SAX2 XMLReader implementation.  
085      * This method uses reflection to avoid being dependent directly
086      * on the JAXP classes.
087      */
088    protected static XMLReader createXMLReaderViaJAXP(boolean validating, boolean namespaceAware) {
089        if ( ! classNameAvailable( "javax.xml.parsers.SAXParserFactory" ) ) {
090            // don't attempt to use JAXP if it is not in the ClassPath
091            return null;
092        }
093        
094        // try use JAXP to load the XMLReader...
095        try {
096            return JAXPHelper.createXMLReader( validating, namespaceAware );
097        }
098        catch (Throwable e) {
099            if ( ! loggedWarning ) {                    
100                loggedWarning = true;
101                if ( isVerboseErrorReporting() ) {
102                    // log all exceptions as warnings and carry
103                    // on as we have a default SAX parser we can use
104                    System.out.println( 
105                        "Warning: Caught exception attempting to use JAXP to "
106                         + "load a SAX XMLReader " 
107                    );
108                    System.out.println( "Warning: Exception was: " + e );
109                    System.out.println( 
110                        "Warning: I will print the stack trace then carry on "
111                         + "using the default SAX parser" 
112                     );
113                    e.printStackTrace();
114                }
115                else {
116                    System.out.println( 
117                        "Warning: Error occurred using JAXP to load a SAXParser. Will use Aelfred instead" 
118                    );
119                }
120            }
121        }
122        return null;
123    }
124
125    /** @return true if the given class could be found using the class loader which loaded this 
126      * class
127      */
128    protected static boolean classNameAvailable( String className ) {
129        try {            
130            Class.forName( className, true, SAXHelper.class.getClassLoader() );
131            return true;
132        }
133        catch (Exception e) {
134            return false;
135        }
136    }
137    
138    protected static boolean isVerboseErrorReporting() {
139        try {
140            String flag = System.getProperty( "org.dom4j.verbose" );
141            if ( flag != null && flag.equalsIgnoreCase( "true" ) ) {
142                return true;
143            }
144        }
145        catch (Exception e) {
146            // in case a security exception
147            // happens in an applet or similar JVM
148        }
149        return false;
150    }
151}
152
153
154
155
156/*
157 * Redistribution and use of this software and associated documentation
158 * ("Software"), with or without modification, are permitted provided
159 * that the following conditions are met:
160 *
161 * 1. Redistributions of source code must retain copyright
162 *    statements and notices.  Redistributions must also contain a
163 *    copy of this document.
164 *
165 * 2. Redistributions in binary form must reproduce the
166 *    above copyright notice, this list of conditions and the
167 *    following disclaimer in the documentation and/or other
168 *    materials provided with the distribution.
169 *
170 * 3. The name "DOM4J" must not be used to endorse or promote
171 *    products derived from this Software without prior written
172 *    permission of MetaStuff, Ltd.  For written permission,
173 *    please contact dom4j-info@metastuff.com.
174 *
175 * 4. Products derived from this Software may not be called "DOM4J"
176 *    nor may "DOM4J" appear in their names without prior written
177 *    permission of MetaStuff, Ltd. DOM4J is a registered
178 *    trademark of MetaStuff, Ltd.
179 *
180 * 5. Due credit should be given to the DOM4J Project
181 *    (http://dom4j.org/).
182 *
183 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
184 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
185 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
186 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
187 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
188 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
189 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
190 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
191 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
192 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
193 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
194 * OF THE POSSIBILITY OF SUCH DAMAGE.
195 *
196 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
197 *
198 * $Id: SAXHelper.java,v 1.9 2001/10/12 11:05:14 jstrachan Exp $
199 */