[Git][java-team/dom4j][master] 6 commits: New upstream version 2.1.2

Emmanuel Bourg gitlab at salsa.debian.org
Wed Sep 16 14:03:48 BST 2020



Emmanuel Bourg pushed to branch master at Debian Java Maintainers / dom4j


Commits:
966a9f55 by Emmanuel Bourg at 2020-09-16T14:51:33+02:00
New upstream version 2.1.2
- - - - -
1dd79ab7 by Emmanuel Bourg at 2020-09-16T14:51:53+02:00
New upstream version 2.1.3
- - - - -
0160e500 by Emmanuel Bourg at 2020-09-16T14:51:55+02:00
Update upstream source from tag 'upstream/2.1.3'

Update to upstream version '2.1.3'
with Debian dir 1c36221492011de95735d78eaab679eca7028cc9
- - - - -
9258d03d by Emmanuel Bourg at 2020-09-16T15:01:29+02:00
Refreshed the patches

- - - - -
7b9d554a by Emmanuel Bourg at 2020-09-16T15:01:34+02:00
Wrap and sort

- - - - -
9bc317b7 by Emmanuel Bourg at 2020-09-16T15:03:06+02:00
Upload to unstable

- - - - -


10 changed files:

- .gitignore
- README.md
- build.gradle
- debian/changelog
- debian/control
- debian/patches/08_disable-jacoco.patch
- debian/patches/09_disable-publish-plugin.patch
- src/main/java/org/dom4j/DocumentHelper.java
- src/main/java/org/dom4j/io/SAXHelper.java
- src/main/java/org/dom4j/io/SAXReader.java


Changes:

=====================================
.gitignore
=====================================
@@ -2,8 +2,4 @@
 /out
 /.gradle
 /gradle.properties
-/.idea/workspace.xml
-/.idea/tasks.xml
-/.idea/gradle.xml
-/.idea/libraries/
-/*.gpg
\ No newline at end of file
+/*.gpg


=====================================
README.md
=====================================
@@ -1,8 +1,35 @@
 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.dom4j/dom4j/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.dom4j/dom4j)
 [![codecov.io](https://codecov.io/github/dom4j/dom4j/coverage.svg?branch=master)](https://codecov.io/github/dom4j/dom4j?branch=master)
 [![Build Status](https://travis-ci.org/dom4j/dom4j.svg?branch=master)](https://travis-ci.org/dom4j/dom4j)
-[![Javadocs](http://javadoc.io/badge/org.dom4j/dom4j.svg)](http://javadoc.io/doc/org.dom4j/dom4j)
+[![Javadocs](https://javadoc.io/badge/org.dom4j/dom4j.svg)](https://javadoc.io/doc/org.dom4j/dom4j)
 
-# DOM4J
+# dom4j
 
-DOM4J is an open source framework for processing XML which is integrated with XPath and fully supports DOM, SAX, JAXP and the Java platform such as Java 2 Collections.
+`dom4j` is an open source framework for processing XML which is integrated with XPath and fully supports DOM, SAX, JAXP and the Java platform such as Java 2 Collections.
+
+# News
+
+## Version 2.0.3 and 2.1.3 released
+
+(Version 2.1.2 has been skipped.)
+
+### Improvements
+* Added new factory method `org.dom4j.io.SAXReader.createDefault()`. It hase more secure defaults than `new SAXReader()`, which uses system
+ `XMLReaderFactory.createXMLReader()` or `SAXParserFactory.newInstance().newSAXParser()`. `SAXReader.createDefault()` disable parsing of external entities
+  in the SAX parser.
+
+## Version 2.1.1 released
+Bug fix release.
+
+### Potential breaking changes
+* If you use some optional dependency of dom4j (for example Jaxen, xsdlib etc.), you need to specify an explicit dependency on it in your project. They are no longer marked as a mandatory transitive dependency by dom4j.
+
+### Fixed issues
+* #28 Possible vulnerability of `DocumentHelper.parseText()` to XML injection (reported by @s0m30ne)
+* #34 CVS directories left in the source tree (reported by @ebourg)
+* #38 XMLWriter does not escape supplementary unicode characters correctly (reported by @abenkovskii)
+* #39 writer.writeOpen(x) doesn't write namespaces (reported by @borissmidt)
+* #40 concurrency problem with `QNameCache`  (@jbennett2091)
+* #43 and #46 all dependencies are optional (reported by @Zardoz89 and @vmassol)
+* #44 SAXReader: hardcoded namespace features (reported by @philippeu)
+* #48 validate `QName`s (reported by @mario-areias)


=====================================
build.gradle
=====================================
@@ -116,6 +116,9 @@ if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')
         repositories {
             maven {
                 url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
+                authentication {
+                    basic(BasicAuthentication)
+                }
                 credentials {
                     username = ossrhUsername
                     password = ossrhPassword
@@ -132,6 +135,6 @@ if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')
 
 if (project.hasProperty('signing.keyId')) {
     signing {
-        sign configurations.archives
+        sign publishing.publications.mavenJava
     }
-}
\ No newline at end of file
+}


=====================================
debian/changelog
=====================================
@@ -1,3 +1,12 @@
+dom4j (2.1.3-1) unstable; urgency=medium
+
+  * New upstream release
+    - Fixes CVE-2020-10683: XML External Entity vulnerability in the default
+      SAX parser (Closes: #958055)
+    - Refreshed the patches
+
+ -- Emmanuel Bourg <ebourg at apache.org>  Wed, 16 Sep 2020 15:03:01 +0200
+
 dom4j (2.1.1-4) unstable; urgency=medium
 
   * Team upload


=====================================
debian/control
=====================================
@@ -1,23 +1,25 @@
 Source: dom4j
-Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.org>
-Uploaders: Marcus Better <marcus at better.se>,
-           Emmanuel Bourg <ebourg at apache.org>
 Section: java
 Priority: optional
-Build-Depends: antlr,
-               debhelper-compat (= 13),
-               default-jdk,
-               default-jdk-doc,
-               gradle-debian-helper,
-               junit,
-               libjaxb-api-java,
-               libjaxen-java,
-               libmsv-java,
-               libxalan2-java,
-               libxerces2-java,
-               libxpp2-java (>= 2.1.10-8~),
-               libxpp3-java,
-               maven-repo-helper
+Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.org>
+Uploaders:
+ Marcus Better <marcus at better.se>,
+ Emmanuel Bourg <ebourg at apache.org>
+Build-Depends:
+ antlr,
+ debhelper-compat (= 13),
+ default-jdk,
+ default-jdk-doc,
+ gradle-debian-helper,
+ junit,
+ libjaxb-api-java,
+ libjaxen-java,
+ libmsv-java,
+ libxalan2-java,
+ libxerces2-java,
+ libxpp2-java (>= 2.1.10-8~),
+ libxpp3-java,
+ maven-repo-helper
 Standards-Version: 4.5.0
 Vcs-Browser: https://salsa.debian.org/java-team/dom4j
 Vcs-Git: https://salsa.debian.org/java-team/dom4j.git
@@ -26,12 +28,12 @@ Rules-Requires-Root: no
 
 Package: libdom4j-java
 Architecture: all
-Depends: ${misc:Depends},
-         libjaxen-java
-Suggests: libdom4j-java-doc,
-          libmsv-java,
-          libxpp2-java (>= 2.1.10-8~),
-          libxpp3-java
+Depends: ${misc:Depends}, libjaxen-java
+Suggests:
+ libdom4j-java-doc,
+ libmsv-java,
+ libxpp2-java (>= 2.1.10-8~),
+ libxpp3-java
 Description: Flexible XML framework for Java
  dom4j is a library for working with XML, XPath and XSLT on the Java
  platform using the Java Collections Framework and with full support


=====================================
debian/patches/08_disable-jacoco.patch
=====================================
@@ -24,10 +24,3 @@ Forwarded: not-needed
  if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) {
      publishing {
          repositories {
-@@ -134,4 +125,4 @@
-     signing {
-         sign configurations.archives
-     }
--}
-\ No newline at end of file
-+}


=====================================
debian/patches/09_disable-publish-plugin.patch
=====================================
@@ -9,7 +9,7 @@ Forwarded: not-needed
  apply plugin: 'signing'
  
  group = 'org.dom4j'
-@@ -52,75 +51,10 @@
+@@ -52,78 +51,10 @@
      from javadoc.destinationDir
  }
  
@@ -68,6 +68,9 @@ Forwarded: not-needed
 -        repositories {
 -            maven {
 -                url 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
+-                authentication {
+-                    basic(BasicAuthentication)
+-                }
 -                credentials {
 -                    username = ossrhUsername
 -                    password = ossrhPassword
@@ -84,4 +87,4 @@ Forwarded: not-needed
 -
  if (project.hasProperty('signing.keyId')) {
      signing {
-         sign configurations.archives
+         sign publishing.publications.mavenJava


=====================================
src/main/java/org/dom4j/DocumentHelper.java
=====================================
@@ -107,12 +107,12 @@ public final class DocumentHelper {
      * XPath <code>XPath</code> instance using the singleton {@link
      * DocumentFactory}.
      * </p>
-     * 
+     *
      * @param xpathExpression
      *            is the XPath expression to create
-     * 
+     *
      * @return a new <code>XPath</code> instance
-     * 
+     *
      * @throws InvalidXPathException
      *             if the XPath expression is invalid
      */
@@ -127,14 +127,14 @@ public final class DocumentHelper {
      * XPath <code>XPath</code> instance using the singleton {@link
      * DocumentFactory}.
      * </p>
-     * 
+     *
      * @param xpathExpression
      *            is the XPath expression to create
      * @param context
      *            is the variable context to use when evaluating the XPath
-     * 
+     *
      * @return a new <code>XPath</code> instance
-     * 
+     *
      * @throws InvalidXPathException
      *             if the XPath expression is invalid
      */
@@ -150,10 +150,10 @@ public final class DocumentHelper {
      * filter expressions occur within XPath expressions such as
      * <code>self::node()[ filterExpression ]</code>
      * </p>
-     * 
+     *
      * @param xpathFilterExpression
      *            is the XPath filter expression to create
-     * 
+     *
      * @return a new <code>NodeFilter</code> instance
      */
     public static NodeFilter createXPathFilter(String xpathFilterExpression) {
@@ -166,10 +166,10 @@ public final class DocumentHelper {
      * an XSLT style {@link Pattern}instance which can then be used in an XSLT
      * processing model.
      * </p>
-     * 
+     *
      * @param xpathPattern
      *            is the XPath pattern expression to create
-     * 
+     *
      * @return a new <code>Pattern</code> instance
      */
     public static Pattern createPattern(String xpathPattern) {
@@ -182,12 +182,12 @@ public final class DocumentHelper {
      * {@link List}of {@link Node}instances appending all the results together
      * into a single list.
      * </p>
-     * 
+     *
      * @param xpathFilterExpression
      *            is the XPath filter expression to evaluate
      * @param nodes
      *            is the list of nodes on which to evalute the XPath
-     * 
+     *
      * @return the results of all the XPath evaluations as a single list
      */
     public static List<Node> selectNodes(String xpathFilterExpression, List<Node> nodes) {
@@ -202,12 +202,12 @@ public final class DocumentHelper {
      * {@link List}of {@link Node}instances appending all the results together
      * into a single list.
      * </p>
-     * 
+     *
      * @param xpathFilterExpression
      *            is the XPath filter expression to evaluate
      * @param node
      *            is the Node on which to evalute the XPath
-     * 
+     *
      * @return the results of all the XPath evaluations as a single list
      */
     public static List<Node> selectNodes(String xpathFilterExpression, Node node) {
@@ -221,7 +221,7 @@ public final class DocumentHelper {
      * <code>sort</code> sorts the given List of Nodes using an XPath
      * expression as a {@link java.util.Comparator}.
      * </p>
-     * 
+     *
      * @param list
      *            is the list of Nodes to sort
      * @param xpathExpression
@@ -238,7 +238,7 @@ public final class DocumentHelper {
      * expression as a {@link java.util.Comparator}and optionally removing
      * duplicates.
      * </p>
-     * 
+     *
      * @param list
      *            is the list of Nodes to sort
      * @param expression
@@ -259,24 +259,17 @@ public final class DocumentHelper {
      * </p>
      *
      * Loading external DTD and entities is disabled (if it is possible) for security reasons.
-     * 
+     *
      * @param text
      *            the XML text to be parsed
-     * 
+     *
      * @return a newly parsed Document
-     * 
+     *
      * @throws DocumentException
      *             if the document could not be parsed
      */
     public static Document parseText(String text) throws DocumentException {
-        SAXReader reader = new SAXReader();
-        try {
-            reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
-            reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
-            reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
-        } catch (SAXException e) {
-            //Parse with external resources downloading allowed.
-        }
+        SAXReader reader = SAXReader.createDefault();
 
         String encoding = getEncoding(text);
 
@@ -330,14 +323,14 @@ public final class DocumentHelper {
      * get the first child <a> element, which would be created if it did
      * not exist, then the next child <b> and so on until finally a
      * <c> element is returned.
-     * 
+     *
      * @param source
      *            is the Element or Document to start navigating from
      * @param path
      *            is a simple path expression, seperated by '/' which denotes
      *            the path from the source to the resulting element such as
      *            a/b/c
-     * 
+     *
      * @return the first Element on the given path which either already existed
      *         on the path or were created by this method.
      */
@@ -386,24 +379,24 @@ public final class DocumentHelper {
  * Redistribution and use of this software and associated documentation
  * ("Software"), with or without modification, are permitted provided that the
  * following conditions are met:
- * 
+ *
  * 1. Redistributions of source code must retain copyright statements and
  * notices. Redistributions must also contain a copy of this document.
- * 
+ *
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  * this list of conditions and the following disclaimer in the documentation
  * and/or other materials provided with the distribution.
- * 
+ *
  * 3. The name "DOM4J" must not be used to endorse or promote products derived
  * from this Software without prior written permission of MetaStuff, Ltd. For
  * written permission, please contact dom4j-info at metastuff.com.
- * 
+ *
  * 4. Products derived from this Software may not be called "DOM4J" nor may
  * "DOM4J" appear in their names without prior written permission of MetaStuff,
  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
- * 
+ *
  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -415,6 +408,6 @@ public final class DocumentHelper {
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
- * 
+ *
  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
  */


=====================================
src/main/java/org/dom4j/io/SAXHelper.java
=====================================
@@ -13,12 +13,14 @@ import org.xml.sax.SAXNotSupportedException;
 import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.XMLReaderFactory;
 
+import javax.xml.parsers.SAXParserFactory;
+
 /**
  * <p>
  * <code>SAXHelper</code> contains some helper methods for working with SAX
  * and XMLReader objects.
  * </p>
- * 
+ *
  * @author <a href="mailto:james.strachan at metastuff.com">James Strachan </a>
  * @version $Revision: 1.18 $
  */
@@ -61,12 +63,21 @@ class SAXHelper {
     /**
      * Creats a default XMLReader via the org.xml.sax.driver system property or
      * JAXP if the system property is not set.
-     * 
+     *
+     * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
+     * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
+     *
+     * <pre>
+     * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+     * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+     * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+     * </pre>
+     *
      * @param validating
      *            DOCUMENT ME!
-     * 
+     *
      * @return DOCUMENT ME!
-     * 
+     *
      * @throws SAXException
      *             DOCUMENT ME!
      */
@@ -125,12 +136,12 @@ class SAXHelper {
      * This method attempts to use JAXP to locate the SAX2 XMLReader
      * implementation. This method uses reflection to avoid being dependent
      * directly on the JAXP classes.
-     * 
+     *
      * @param validating
      *            DOCUMENT ME!
      * @param namespaceAware
      *            DOCUMENT ME!
-     * 
+     *
      * @return DOCUMENT ME!
      */
     protected static XMLReader createXMLReaderViaJAXP(boolean validating,
@@ -176,24 +187,24 @@ class SAXHelper {
  * Redistribution and use of this software and associated documentation
  * ("Software"), with or without modification, are permitted provided that the
  * following conditions are met:
- * 
+ *
  * 1. Redistributions of source code must retain copyright statements and
  * notices. Redistributions must also contain a copy of this document.
- * 
+ *
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  * this list of conditions and the following disclaimer in the documentation
  * and/or other materials provided with the distribution.
- * 
+ *
  * 3. The name "DOM4J" must not be used to endorse or promote products derived
  * from this Software without prior written permission of MetaStuff, Ltd. For
  * written permission, please contact dom4j-info at metastuff.com.
- * 
+ *
  * 4. Products derived from this Software may not be called "DOM4J" nor may
  * "DOM4J" appear in their names without prior written permission of MetaStuff,
  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
- * 
+ *
  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -205,6 +216,6 @@ class SAXHelper {
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
- * 
+ *
  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
  */


=====================================
src/main/java/org/dom4j/io/SAXReader.java
=====================================
@@ -30,32 +30,34 @@ import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.DefaultHandler;
 import org.xml.sax.helpers.XMLReaderFactory;
 
+import javax.xml.parsers.SAXParserFactory;
+
 /**
  * <code>SAXReader</code> creates a DOM4J tree from SAX parsing events.
- *
+ * <p>
  * The actual SAX parser that is used by this class is configurable so you can
  * use your favourite SAX parser if you wish. DOM4J comes configured with its
  * own SAX parser so you do not need to worry about configuring the SAX parser.
- *
+ * <p>
  * To explicitly configure the SAX parser that is used via Java code you can use
  * a constructor or use the {@link #setXMLReader(XMLReader)}or {@link
  * #setXMLReaderClassName(String)} methods.
- *
+ * <p>
  * If the parser is not specified explicitly then the standard SAX policy of
  * using the <code>org.xml.sax.driver</code> system property is used to
  * determine the implementation class of {@link XMLReader}.
- *
+ * <p>
  * If the <code>org.xml.sax.driver</code> system property is not defined then
  * JAXP is used via reflection (so that DOM4J is not explicitly dependent on the
  * JAXP classes) to load the JAXP configured SAXParser. If there is any error
  * creating a JAXP SAXParser an informational message is output and then the
  * default (Aelfred) SAX parser is used instead.
- *
+ * <p>
  * If you are trying to use JAXP to explicitly set your SAX parser and are
  * experiencing problems, you can turn on verbose error reporting by defining
  * the system property <code>org.dom4j.verbose</code> to be "true" which will
  * output a more detailed description of why JAXP could not find a SAX parser
- *
+ * <p>
  * For more information on JAXP please go to <a
  * href="http://java.sun.com/xml/">Sun's Java & XML site </a>
  *
@@ -63,932 +65,946 @@ import org.xml.sax.helpers.XMLReaderFactory;
  * @version $Revision: 1.58 $
  */
 public class SAXReader {
-    private static final String SAX_STRING_INTERNING = 
-            "http://xml.org/sax/features/string-interning";
-    private static final String SAX_DECL_HANDLER =
-            "http://xml.org/sax/properties/declaration-handler";
-    private static final String SAX_LEXICAL_HANDLER = 
-            "http://xml.org/sax/properties/lexical-handler";
-    private static final String SAX_LEXICALHANDLER = 
-            "http://xml.org/sax/handlers/LexicalHandler";
-
-    /** <code>DocumentFactory</code> used to create new document objects */
-    private DocumentFactory factory;
-
-    /** <code>XMLReader</code> used to parse the SAX events */
-    private XMLReader xmlReader;
-
-    /** Whether validation should occur */
-    private boolean validating;
-
-    /** DispatchHandler to call when each <code>Element</code> is encountered */
-    private DispatchHandler dispatchHandler;
-
-    /** ErrorHandler class to use */
-    private ErrorHandler errorHandler;
-
-    /** The entity resolver */
-    private EntityResolver entityResolver;
-
-    /** Should element & attribute names and namespace URIs be interned? */
-    private boolean stringInternEnabled = true;
-
-    /** Should internal DTD declarations be expanded into a List in the DTD */
-    private boolean includeInternalDTDDeclarations = false;
-
-    /** Should external DTD declarations be expanded into a List in the DTD */
-    private boolean includeExternalDTDDeclarations = false;
-
-    /** Whether adjacent text nodes should be merged */
-    private boolean mergeAdjacentText = false;
-
-    /** Holds value of property stripWhitespaceText. */
-    private boolean stripWhitespaceText = false;
-
-    /** Should we ignore comments */
-    private boolean ignoreComments = false;
-
-    /** Encoding of InputSource - null means system default encoding */
-    private String encoding = null;
-
-    // private boolean includeExternalGeneralEntities = false;
-    // private boolean includeExternalParameterEntities = false;
-
-    /** The SAX filter used to filter SAX events */
-    private XMLFilter xmlFilter;
-
-    public SAXReader() {
-    }
-
-    public SAXReader(boolean validating) {
-        this.validating = validating;
-    }
-
-    public SAXReader(DocumentFactory factory) {
-        this.factory = factory;
-    }
-
-    public SAXReader(DocumentFactory factory, boolean validating) {
-        this.factory = factory;
-        this.validating = validating;
-    }
-
-    public SAXReader(XMLReader xmlReader) {
-        this.xmlReader = xmlReader;
-    }
-
-    public SAXReader(XMLReader xmlReader, boolean validating) {
-        this.xmlReader = xmlReader;
-        this.validating = validating;
-    }
-
-    public SAXReader(String xmlReaderClassName) throws SAXException {
-        if (xmlReaderClassName != null) {
-            this.xmlReader = XMLReaderFactory
-                    .createXMLReader(xmlReaderClassName);
+  private static final String SAX_STRING_INTERNING =
+          "http://xml.org/sax/features/string-interning";
+  private static final String SAX_DECL_HANDLER =
+          "http://xml.org/sax/properties/declaration-handler";
+  private static final String SAX_LEXICAL_HANDLER =
+          "http://xml.org/sax/properties/lexical-handler";
+  private static final String SAX_LEXICALHANDLER =
+          "http://xml.org/sax/handlers/LexicalHandler";
+
+  /**
+   * <code>DocumentFactory</code> used to create new document objects
+   */
+  private DocumentFactory factory;
+
+  /**
+   * <code>XMLReader</code> used to parse the SAX events
+   */
+  private XMLReader xmlReader;
+
+  /**
+   * Whether validation should occur
+   */
+  private boolean validating;
+
+  /**
+   * DispatchHandler to call when each <code>Element</code> is encountered
+   */
+  private DispatchHandler dispatchHandler;
+
+  /**
+   * ErrorHandler class to use
+   */
+  private ErrorHandler errorHandler;
+
+  /**
+   * The entity resolver
+   */
+  private EntityResolver entityResolver;
+
+  /**
+   * Should element & attribute names and namespace URIs be interned?
+   */
+  private boolean stringInternEnabled = true;
+
+  /**
+   * Should internal DTD declarations be expanded into a List in the DTD
+   */
+  private boolean includeInternalDTDDeclarations = false;
+
+  /**
+   * Should external DTD declarations be expanded into a List in the DTD
+   */
+  private boolean includeExternalDTDDeclarations = false;
+
+  /**
+   * Whether adjacent text nodes should be merged
+   */
+  private boolean mergeAdjacentText = false;
+
+  /**
+   * Holds value of property stripWhitespaceText.
+   */
+  private boolean stripWhitespaceText = false;
+
+  /**
+   * Should we ignore comments
+   */
+  private boolean ignoreComments = false;
+
+  /**
+   * Encoding of InputSource - null means system default encoding
+   */
+  private String encoding = null;
+
+  // private boolean includeExternalGeneralEntities = false;
+  // private boolean includeExternalParameterEntities = false;
+
+  /**
+   * The SAX filter used to filter SAX events
+   *
+   * @since 2.1.2
+   */
+  private XMLFilter xmlFilter;
+
+  public static SAXReader createDefault() {
+    SAXReader reader = new SAXReader();
+    try {
+      reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+      reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+      reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+    } catch (SAXException e) {
+      // nothing to do, incompatible reader
+    }
+    return reader;
+  }
+
+  /**
+   * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
+   * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
+   *
+   * <pre>
+   * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+   * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+   * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+   * </pre>
+   */
+  public SAXReader() {
+  }
+
+  /**
+   * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
+   * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
+   *
+   * <pre>
+   * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+   * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+   * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+   * </pre>
+   *
+   * @param validating
+   */
+  public SAXReader(boolean validating) {
+    this.validating = validating;
+  }
+
+  /**
+   * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
+   * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
+   *
+   * <pre>
+   * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+   * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+   * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+   * </pre>
+   *
+   * @param factory
+   */
+  public SAXReader(DocumentFactory factory) {
+    this.factory = factory;
+  }
+
+  /**
+   * This method internally calls {@link SAXParserFactory}{@code .newInstance().newSAXParser().getXMLReader()} or {@link XMLReaderFactory#createXMLReader()}.
+   * Be sure to configure returned reader if the default configuration does not suit you. Consider setting the following properties:
+   *
+   * <pre>
+   * reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+   * reader.setFeature("http://xml.org/sax/features/external-general-entities", false);
+   * reader.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
+   * </pre>
+   *
+   * @param factory
+   * @param validating
+   */
+  public SAXReader(DocumentFactory factory, boolean validating) {
+    this.factory = factory;
+    this.validating = validating;
+  }
+
+  public SAXReader(XMLReader xmlReader) {
+    this.xmlReader = xmlReader;
+  }
+
+  public SAXReader(XMLReader xmlReader, boolean validating) {
+    this.xmlReader = xmlReader;
+    this.validating = validating;
+  }
+
+  public SAXReader(String xmlReaderClassName) throws SAXException {
+    if (xmlReaderClassName != null) {
+      this.xmlReader = XMLReaderFactory
+              .createXMLReader(xmlReaderClassName);
+    }
+  }
+
+  public SAXReader(String xmlReaderClassName, boolean validating)
+          throws SAXException {
+    if (xmlReaderClassName != null) {
+      this.xmlReader = XMLReaderFactory
+              .createXMLReader(xmlReaderClassName);
+    }
+
+    this.validating = validating;
+  }
+
+  /**
+   * Allows a SAX property to be set on the underlying SAX parser. This can be
+   * useful to set parser-specific properties such as the location of schema
+   * or DTD resources. Though use this method with caution as it has the
+   * possibility of breaking the standard behaviour. An alternative to calling
+   * this method is to correctly configure an XMLReader object instance and
+   * call the {@link #setXMLReader(XMLReader)}method
+   *
+   * @param name  is the SAX property name
+   * @param value is the value of the SAX property
+   * @throws SAXException if the XMLReader could not be created or the property could
+   *                      not be changed.
+   */
+  public void setProperty(String name, Object value) throws SAXException {
+    getXMLReader().setProperty(name, value);
+  }
+
+  /**
+   * Sets a SAX feature on the underlying SAX parser. This can be useful to
+   * set parser-specific features. Though use this method with caution as it
+   * has the possibility of breaking the standard behaviour. An alternative to
+   * calling this method is to correctly configure an XMLReader object
+   * instance and call the {@link #setXMLReader(XMLReader)}method
+   *
+   * @param name  is the SAX feature name
+   * @param value is the value of the SAX feature
+   * @throws SAXException if the XMLReader could not be created or the feature could
+   *                      not be changed.
+   */
+  public void setFeature(String name, boolean value) throws SAXException {
+    getXMLReader().setFeature(name, value);
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given <code>File</code>
+   * </p>
+   *
+   * @param file is the <code>File</code> to read from.
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(File file) throws DocumentException {
+    try {
+      /*
+       * We cannot convert the file to an URL because if the filename
+       * contains '#' characters, there will be problems with the URL in
+       * the InputSource (because a URL like
+       * http://myhost.com/index#anchor is treated the same as
+       * http://myhost.com/index) Thanks to Christian Oetterli
+       */
+      InputSource source = new InputSource(new FileInputStream(file));
+      if (this.encoding != null) {
+        source.setEncoding(this.encoding);
+      }
+      String path = file.getAbsolutePath();
+
+      if (path != null) {
+        // Code taken from Ant FileUtils
+        StringBuffer sb = new StringBuffer("file://");
+
+        // add an extra slash for filesystems with drive-specifiers
+        if (!path.startsWith(File.separator)) {
+          sb.append("/");
         }
-    }
 
-    public SAXReader(String xmlReaderClassName, boolean validating)
-            throws SAXException {
-        if (xmlReaderClassName != null) {
-            this.xmlReader = XMLReaderFactory
-                    .createXMLReader(xmlReaderClassName);
+        path = path.replace('\\', '/');
+        sb.append(path);
+
+        source.setSystemId(sb.toString());
+      }
+
+      return read(source);
+    } catch (FileNotFoundException e) {
+      throw new DocumentException(e.getMessage(), e);
+    }
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given <code>URL</code> using SAX
+   * </p>
+   *
+   * @param url <code>URL</code> to read from.
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(URL url) throws DocumentException {
+    String systemID = url.toExternalForm();
+
+    InputSource source = new InputSource(systemID);
+    if (this.encoding != null) {
+      source.setEncoding(this.encoding);
+    }
+
+    return read(source);
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given URL or filename using SAX.
+   * </p>
+   *
+   * <p>
+   * If the systemId contains a <code>':'</code> character then it is
+   * assumed to be a URL otherwise its assumed to be a file name. If you want
+   * finer grained control over this mechansim then please explicitly pass in
+   * either a {@link URL}or a {@link File}instance instead of a {@link
+   * String} to denote the source of the document.
+   * </p>
+   *
+   * @param systemId is a URL for a document or a file name.
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(String systemId) throws DocumentException {
+    InputSource source = new InputSource(systemId);
+    if (this.encoding != null) {
+      source.setEncoding(this.encoding);
+    }
+
+    return read(source);
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given stream using SAX
+   * </p>
+   *
+   * @param in <code>InputStream</code> to read from.
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(InputStream in) throws DocumentException {
+    InputSource source = new InputSource(in);
+    if (this.encoding != null) {
+      source.setEncoding(this.encoding);
+    }
+
+    return read(source);
+  }
+
+  /**
+   * Reads a Document from the given <code>Reader</code> using SAX
+   *
+   * @param reader is the reader for the input
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(Reader reader) throws DocumentException {
+    InputSource source = new InputSource(reader);
+    if (this.encoding != null) {
+      source.setEncoding(this.encoding);
+    }
+
+    return read(source);
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given stream using SAX
+   * </p>
+   *
+   * @param in       <code>InputStream</code> to read from.
+   * @param systemId is the URI for the input
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(InputStream in, String systemId)
+          throws DocumentException {
+    InputSource source = new InputSource(in);
+    source.setSystemId(systemId);
+    if (this.encoding != null) {
+      source.setEncoding(this.encoding);
+    }
+
+    return read(source);
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given <code>Reader</code> using SAX
+   * </p>
+   *
+   * @param reader   is the reader for the input
+   * @param systemId is the URI for the input
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(Reader reader, String systemId)
+          throws DocumentException {
+    InputSource source = new InputSource(reader);
+    source.setSystemId(systemId);
+    if (this.encoding != null) {
+      source.setEncoding(this.encoding);
+    }
+
+    return read(source);
+  }
+
+  /**
+   * <p>
+   * Reads a Document from the given <code>InputSource</code> using SAX
+   * </p>
+   *
+   * @param in <code>InputSource</code> to read from.
+   * @return the newly created Document instance
+   * @throws DocumentException if an error occurs during parsing.
+   */
+  public Document read(InputSource in) throws DocumentException {
+    try {
+      XMLReader reader = getXMLReader();
+
+      reader = installXMLFilter(reader);
+
+      EntityResolver thatEntityResolver = this.entityResolver;
+
+      if (thatEntityResolver == null) {
+        thatEntityResolver = createDefaultEntityResolver(in
+                .getSystemId());
+        this.entityResolver = thatEntityResolver;
+      }
+
+      reader.setEntityResolver(thatEntityResolver);
+
+      SAXContentHandler contentHandler = createContentHandler(reader);
+      contentHandler.setEntityResolver(thatEntityResolver);
+      contentHandler.setInputSource(in);
+
+      boolean internal = isIncludeInternalDTDDeclarations();
+      boolean external = isIncludeExternalDTDDeclarations();
+
+      contentHandler.setIncludeInternalDTDDeclarations(internal);
+      contentHandler.setIncludeExternalDTDDeclarations(external);
+      contentHandler.setMergeAdjacentText(isMergeAdjacentText());
+      contentHandler.setStripWhitespaceText(isStripWhitespaceText());
+      contentHandler.setIgnoreComments(isIgnoreComments());
+      reader.setContentHandler(contentHandler);
+
+      configureReader(reader, contentHandler);
+
+      reader.parse(in);
+
+      return contentHandler.getDocument();
+    } catch (Exception e) {
+      if (e instanceof SAXParseException) {
+        // e.printStackTrace();
+        SAXParseException parseException = (SAXParseException) e;
+        String systemId = parseException.getSystemId();
+
+        if (systemId == null) {
+          systemId = "";
         }
 
-        this.validating = validating;
-    }
-
-    /**
-     * Allows a SAX property to be set on the underlying SAX parser. This can be
-     * useful to set parser-specific properties such as the location of schema
-     * or DTD resources. Though use this method with caution as it has the
-     * possibility of breaking the standard behaviour. An alternative to calling
-     * this method is to correctly configure an XMLReader object instance and
-     * call the {@link #setXMLReader(XMLReader)}method
-     * 
-     * @param name
-     *            is the SAX property name
-     * @param value
-     *            is the value of the SAX property
-     * 
-     * @throws SAXException
-     *             if the XMLReader could not be created or the property could
-     *             not be changed.
-     */
-    public void setProperty(String name, Object value) throws SAXException {
-        getXMLReader().setProperty(name, value);
-    }
-
-    /**
-     * Sets a SAX feature on the underlying SAX parser. This can be useful to
-     * set parser-specific features. Though use this method with caution as it
-     * has the possibility of breaking the standard behaviour. An alternative to
-     * calling this method is to correctly configure an XMLReader object
-     * instance and call the {@link #setXMLReader(XMLReader)}method
-     * 
-     * @param name
-     *            is the SAX feature name
-     * @param value
-     *            is the value of the SAX feature
-     * 
-     * @throws SAXException
-     *             if the XMLReader could not be created or the feature could
-     *             not be changed.
-     */
-    public void setFeature(String name, boolean value) throws SAXException {
-        getXMLReader().setFeature(name, value);
-    }
-
-    /**
-     * <p>
-     * Reads a Document from the given <code>File</code>
-     * </p>
-     * 
-     * @param file
-     *            is the <code>File</code> to read from.
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(File file) throws DocumentException {
-        try {
-            /*
-             * We cannot convert the file to an URL because if the filename
-             * contains '#' characters, there will be problems with the URL in
-             * the InputSource (because a URL like
-             * http://myhost.com/index#anchor is treated the same as
-             * http://myhost.com/index) Thanks to Christian Oetterli
-             */
-            InputSource source = new InputSource(new FileInputStream(file));
-            if (this.encoding != null) {
-                source.setEncoding(this.encoding);
-            }
-            String path = file.getAbsolutePath();
-
-            if (path != null) {
-                // Code taken from Ant FileUtils
-                StringBuffer sb = new StringBuffer("file://");
-
-                // add an extra slash for filesystems with drive-specifiers
-                if (!path.startsWith(File.separator)) {
-                    sb.append("/");
-                }
-
-                path = path.replace('\\', '/');
-                sb.append(path);
-
-                source.setSystemId(sb.toString());
-            }
-
-            return read(source);
-        } catch (FileNotFoundException e) {
-            throw new DocumentException(e.getMessage(), e);
+        String message = "Error on line "
+                + parseException.getLineNumber() + " of document "
+                + systemId + " : " + parseException.getMessage();
+
+        throw new DocumentException(message, e);
+      } else {
+        throw new DocumentException(e.getMessage(), e);
+      }
+    }
+  }
+
+  // Properties
+  // -------------------------------------------------------------------------
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return the validation mode, true if validating will be done otherwise
+   * false.
+   */
+  public boolean isValidating() {
+    return validating;
+  }
+
+  /**
+   * Sets the validation mode.
+   *
+   * @param validation indicates whether or not validation should occur.
+   */
+  public void setValidation(boolean validation) {
+    this.validating = validation;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return whether internal DTD declarations should be expanded into the
+   * DocumentType object or not.
+   */
+  public boolean isIncludeInternalDTDDeclarations() {
+    return includeInternalDTDDeclarations;
+  }
+
+  /**
+   * Sets whether internal DTD declarations should be expanded into the
+   * DocumentType object or not.
+   *
+   * @param include whether or not DTD declarations should be expanded and
+   *                included into the DocumentType object.
+   */
+  public void setIncludeInternalDTDDeclarations(boolean include) {
+    this.includeInternalDTDDeclarations = include;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return whether external DTD declarations should be expanded into the
+   * DocumentType object or not.
+   */
+  public boolean isIncludeExternalDTDDeclarations() {
+    return includeExternalDTDDeclarations;
+  }
+
+  /**
+   * Sets whether DTD external declarations should be expanded into the
+   * DocumentType object or not.
+   *
+   * @param include whether or not DTD declarations should be expanded and
+   *                included into the DocumentType object.
+   */
+  public void setIncludeExternalDTDDeclarations(boolean include) {
+    this.includeExternalDTDDeclarations = include;
+  }
+
+  /**
+   * Sets whether String interning is enabled or disabled for element &
+   * attribute names and namespace URIs. This proprety is enabled by default.
+   *
+   * @return DOCUMENT ME!
+   */
+  public boolean isStringInternEnabled() {
+    return stringInternEnabled;
+  }
+
+  /**
+   * Sets whether String interning is enabled or disabled for element &
+   * attribute names and namespace URIs
+   *
+   * @param stringInternEnabled DOCUMENT ME!
+   */
+  public void setStringInternEnabled(boolean stringInternEnabled) {
+    this.stringInternEnabled = stringInternEnabled;
+  }
+
+  /**
+   * Returns whether adjacent text nodes should be merged together.
+   *
+   * @return Value of property mergeAdjacentText.
+   */
+  public boolean isMergeAdjacentText() {
+    return mergeAdjacentText;
+  }
+
+  /**
+   * Sets whether or not adjacent text nodes should be merged together when
+   * parsing.
+   *
+   * @param mergeAdjacentText New value of property mergeAdjacentText.
+   */
+  public void setMergeAdjacentText(boolean mergeAdjacentText) {
+    this.mergeAdjacentText = mergeAdjacentText;
+  }
+
+  /**
+   * Sets whether whitespace between element start and end tags should be
+   * ignored
+   *
+   * @return Value of property stripWhitespaceText.
+   */
+  public boolean isStripWhitespaceText() {
+    return stripWhitespaceText;
+  }
+
+  /**
+   * Sets whether whitespace between element start and end tags should be
+   * ignored.
+   *
+   * @param stripWhitespaceText New value of property stripWhitespaceText.
+   */
+  public void setStripWhitespaceText(boolean stripWhitespaceText) {
+    this.stripWhitespaceText = stripWhitespaceText;
+  }
+
+  /**
+   * Returns whether we should ignore comments or not.
+   *
+   * @return boolean
+   */
+  public boolean isIgnoreComments() {
+    return ignoreComments;
+  }
+
+  /**
+   * Sets whether we should ignore comments or not.
+   *
+   * @param ignoreComments whether we should ignore comments or not.
+   */
+  public void setIgnoreComments(boolean ignoreComments) {
+    this.ignoreComments = ignoreComments;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return the <code>DocumentFactory</code> used to create document
+   * objects
+   */
+  public DocumentFactory getDocumentFactory() {
+    if (factory == null) {
+      factory = DocumentFactory.getInstance();
+    }
+
+    return factory;
+  }
+
+  /**
+   * <p>
+   * This sets the <code>DocumentFactory</code> used to create new
+   * documents. This method allows the building of custom DOM4J tree objects
+   * to be implemented easily using a custom derivation of
+   * {@link DocumentFactory}
+   * </p>
+   *
+   * @param documentFactory <code>DocumentFactory</code> used to create DOM4J objects
+   */
+  public void setDocumentFactory(DocumentFactory documentFactory) {
+    this.factory = documentFactory;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return the <code>ErrorHandler</code> used by SAX
+   */
+  public ErrorHandler getErrorHandler() {
+    return errorHandler;
+  }
+
+  /**
+   * Sets the <code>ErrorHandler</code> used by the SAX
+   * <code>XMLReader</code>.
+   *
+   * @param errorHandler is the <code>ErrorHandler</code> used by SAX
+   */
+  public void setErrorHandler(ErrorHandler errorHandler) {
+    this.errorHandler = errorHandler;
+  }
+
+  /**
+   * Returns the current entity resolver used to resolve entities
+   *
+   * @return DOCUMENT ME!
+   */
+  public EntityResolver getEntityResolver() {
+    return entityResolver;
+  }
+
+  /**
+   * Sets the entity resolver used to resolve entities.
+   *
+   * @param entityResolver DOCUMENT ME!
+   */
+  public void setEntityResolver(EntityResolver entityResolver) {
+    this.entityResolver = entityResolver;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return the <code>XMLReader</code> used to parse SAX events
+   * @throws SAXException DOCUMENT ME!
+   */
+  public XMLReader getXMLReader() throws SAXException {
+    if (xmlReader == null) {
+      xmlReader = createXMLReader();
+    }
+
+    return xmlReader;
+  }
+
+  /**
+   * Sets the <code>XMLReader</code> used to parse SAX events
+   *
+   * @param reader is the <code>XMLReader</code> to parse SAX events
+   */
+  public void setXMLReader(XMLReader reader) {
+    this.xmlReader = reader;
+  }
+
+  /**
+   * Returns encoding used for InputSource (null means system default
+   * encoding)
+   *
+   * @return encoding used for InputSource
+   */
+  public String getEncoding() {
+    return encoding;
+  }
+
+  /**
+   * Sets encoding used for InputSource (null means system default encoding)
+   *
+   * @param encoding is encoding used for InputSource
+   */
+  public void setEncoding(String encoding) {
+    this.encoding = encoding;
+  }
+
+  /**
+   * Sets the class name of the <code>XMLReader</code> to be used to parse
+   * SAX events.
+   *
+   * @param xmlReaderClassName is the class name of the <code>XMLReader</code> to parse SAX
+   *                           events
+   * @throws SAXException DOCUMENT ME!
+   */
+  public void setXMLReaderClassName(String xmlReaderClassName)
+          throws SAXException {
+    setXMLReader(XMLReaderFactory.createXMLReader(xmlReaderClassName));
+  }
+
+  /**
+   * Adds the <code>ElementHandler</code> to be called when the specified
+   * path is encounted.
+   *
+   * @param path    is the path to be handled
+   * @param handler is the <code>ElementHandler</code> to be called by the event
+   *                based processor.
+   */
+  public void addHandler(String path, ElementHandler handler) {
+    getDispatchHandler().addHandler(path, handler);
+  }
+
+  /**
+   * Removes the <code>ElementHandler</code> from the event based processor,
+   * for the specified path.
+   *
+   * @param path is the path to remove the <code>ElementHandler</code> for.
+   */
+  public void removeHandler(String path) {
+    getDispatchHandler().removeHandler(path);
+  }
+
+  /**
+   * When multiple <code>ElementHandler</code> instances have been
+   * registered, this will set a default <code>ElementHandler</code> to be
+   * called for any path which does <b>NOT </b> have a handler registered.
+   *
+   * @param handler is the <code>ElementHandler</code> to be called by the event
+   *                based processor.
+   */
+  public void setDefaultHandler(ElementHandler handler) {
+    getDispatchHandler().setDefaultHandler(handler);
+  }
+
+  /**
+   * This method clears out all the existing handlers and default handler
+   * setting things back as if no handler existed. Useful when reusing an
+   * object instance.
+   */
+  public void resetHandlers() {
+    getDispatchHandler().resetHandlers();
+  }
+
+  /**
+   * Returns the SAX filter being used to filter SAX events.
+   *
+   * @return the SAX filter being used or null if no SAX filter is installed
+   */
+  public XMLFilter getXMLFilter() {
+    return xmlFilter;
+  }
+
+  /**
+   * Sets the SAX filter to be used when filtering SAX events
+   *
+   * @param filter is the SAX filter to use or null to disable filtering
+   */
+  public void setXMLFilter(XMLFilter filter) {
+    this.xmlFilter = filter;
+  }
+
+  // Implementation methods
+  // -------------------------------------------------------------------------
+
+  /**
+   * Installs any XMLFilter objects required to allow the SAX event stream to
+   * be filtered and preprocessed before it gets to dom4j.
+   *
+   * @param reader DOCUMENT ME!
+   * @return the new XMLFilter if applicable or the original XMLReader if no
+   * filter is being used.
+   */
+  protected XMLReader installXMLFilter(XMLReader reader) {
+    XMLFilter filter = getXMLFilter();
+
+    if (filter != null) {
+      // find the root XMLFilter
+      XMLFilter root = filter;
+
+      while (true) {
+        XMLReader parent = root.getParent();
+
+        if (parent instanceof XMLFilter) {
+          root = (XMLFilter) parent;
+        } else {
+          break;
         }
+      }
+
+      root.setParent(reader);
+
+      return filter;
     }
 
-    /**
-     * <p>
-     * Reads a Document from the given <code>URL</code> using SAX
-     * </p>
-     * 
-     * @param url
-     *            <code>URL</code> to read from.
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(URL url) throws DocumentException {
-        String systemID = url.toExternalForm();
-
-        InputSource source = new InputSource(systemID);
-        if (this.encoding != null) {
-            source.setEncoding(this.encoding);
-        }
+    return reader;
+  }
 
-        return read(source);
-    }
-
-    /**
-     * <p>
-     * Reads a Document from the given URL or filename using SAX.
-     * </p>
-     * 
-     * <p>
-     * If the systemId contains a <code>':'</code> character then it is
-     * assumed to be a URL otherwise its assumed to be a file name. If you want
-     * finer grained control over this mechansim then please explicitly pass in
-     * either a {@link URL}or a {@link File}instance instead of a {@link
-     * String} to denote the source of the document.
-     * </p>
-     * 
-     * @param systemId
-     *            is a URL for a document or a file name.
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(String systemId) throws DocumentException {
-        InputSource source = new InputSource(systemId);
-        if (this.encoding != null) {
-            source.setEncoding(this.encoding);
-        }
-
-        return read(source);
-    }
-
-    /**
-     * <p>
-     * Reads a Document from the given stream using SAX
-     * </p>
-     * 
-     * @param in
-     *            <code>InputStream</code> to read from.
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(InputStream in) throws DocumentException {
-        InputSource source = new InputSource(in);
-        if (this.encoding != null) {
-            source.setEncoding(this.encoding);
-        }
-
-        return read(source);
-    }
-
-    /**
-     * Reads a Document from the given <code>Reader</code> using SAX
-     *
-     * @param reader
-     *            is the reader for the input
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(Reader reader) throws DocumentException {
-        InputSource source = new InputSource(reader);
-        if (this.encoding != null) {
-            source.setEncoding(this.encoding);
-        }
-
-        return read(source);
-    }
-
-    /**
-     * <p>
-     * Reads a Document from the given stream using SAX
-     * </p>
-     * 
-     * @param in
-     *            <code>InputStream</code> to read from.
-     * @param systemId
-     *            is the URI for the input
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(InputStream in, String systemId)
-            throws DocumentException {
-        InputSource source = new InputSource(in);
-        source.setSystemId(systemId);
-        if (this.encoding != null) {
-            source.setEncoding(this.encoding);
-        }
-
-        return read(source);
-    }
-
-    /**
-     * <p>
-     * Reads a Document from the given <code>Reader</code> using SAX
-     * </p>
-     * 
-     * @param reader
-     *            is the reader for the input
-     * @param systemId
-     *            is the URI for the input
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(Reader reader, String systemId)
-            throws DocumentException {
-        InputSource source = new InputSource(reader);
-        source.setSystemId(systemId);
-        if (this.encoding != null) {
-            source.setEncoding(this.encoding);
-        }
-
-        return read(source);
-    }
-
-    /**
-     * <p>
-     * Reads a Document from the given <code>InputSource</code> using SAX
-     * </p>
-     * 
-     * @param in
-     *            <code>InputSource</code> to read from.
-     * 
-     * @return the newly created Document instance
-     * 
-     * @throws DocumentException
-     *             if an error occurs during parsing.
-     */
-    public Document read(InputSource in) throws DocumentException {
-        try {
-            XMLReader reader = getXMLReader();
-
-            reader = installXMLFilter(reader);
-
-            EntityResolver thatEntityResolver = this.entityResolver;
-
-            if (thatEntityResolver == null) {
-                thatEntityResolver = createDefaultEntityResolver(in
-                        .getSystemId());
-                this.entityResolver = thatEntityResolver;
-            }
-
-            reader.setEntityResolver(thatEntityResolver);
-
-            SAXContentHandler contentHandler = createContentHandler(reader);
-            contentHandler.setEntityResolver(thatEntityResolver);
-            contentHandler.setInputSource(in);
-
-            boolean internal = isIncludeInternalDTDDeclarations();
-            boolean external = isIncludeExternalDTDDeclarations();
-
-            contentHandler.setIncludeInternalDTDDeclarations(internal);
-            contentHandler.setIncludeExternalDTDDeclarations(external);
-            contentHandler.setMergeAdjacentText(isMergeAdjacentText());
-            contentHandler.setStripWhitespaceText(isStripWhitespaceText());
-            contentHandler.setIgnoreComments(isIgnoreComments());
-            reader.setContentHandler(contentHandler);
-
-            configureReader(reader, contentHandler);
-
-            reader.parse(in);
-
-            return contentHandler.getDocument();
-        } catch (Exception e) {
-            if (e instanceof SAXParseException) {
-                // e.printStackTrace();
-                SAXParseException parseException = (SAXParseException) e;
-                String systemId = parseException.getSystemId();
-
-                if (systemId == null) {
-                    systemId = "";
-                }
-
-                String message = "Error on line "
-                        + parseException.getLineNumber() + " of document "
-                        + systemId + " : " + parseException.getMessage();
-
-                throw new DocumentException(message, e);
-            } else {
-                throw new DocumentException(e.getMessage(), e);
-            }
+  protected DispatchHandler getDispatchHandler() {
+    if (dispatchHandler == null) {
+      dispatchHandler = new DispatchHandler();
+    }
+
+    return dispatchHandler;
+  }
+
+  protected void setDispatchHandler(DispatchHandler dispatchHandler) {
+    this.dispatchHandler = dispatchHandler;
+  }
+
+  /**
+   * Factory Method to allow alternate methods of creating and configuring
+   * XMLReader objects
+   *
+   * @return DOCUMENT ME!
+   * @throws SAXException DOCUMENT ME!
+   */
+  protected XMLReader createXMLReader() throws SAXException {
+    return SAXHelper.createXMLReader(isValidating());
+  }
+
+  /**
+   * Configures the XMLReader before use
+   *
+   * @param reader  DOCUMENT ME!
+   * @param handler DOCUMENT ME!
+   * @throws DocumentException DOCUMENT ME!
+   */
+  protected void configureReader(XMLReader reader, DefaultHandler handler)
+          throws DocumentException {
+    // configure lexical handling
+    SAXHelper.setParserProperty(reader, SAX_LEXICALHANDLER, handler);
+
+    // try alternate property just in case
+    SAXHelper.setParserProperty(reader, SAX_LEXICAL_HANDLER, handler);
+
+    // register the DeclHandler
+    if (includeInternalDTDDeclarations || includeExternalDTDDeclarations) {
+      SAXHelper.setParserProperty(reader, SAX_DECL_HANDLER, handler);
+    }
+
+    // string interning
+    SAXHelper.setParserFeature(reader, SAX_STRING_INTERNING,
+            isStringInternEnabled());
+
+    try {
+      // configure validation support
+      reader.setFeature("http://xml.org/sax/features/validation",
+              isValidating());
+
+      if (errorHandler != null) {
+        reader.setErrorHandler(errorHandler);
+      } else {
+        reader.setErrorHandler(handler);
+      }
+    } catch (Exception e) {
+      if (isValidating()) {
+        throw new DocumentException("Validation not supported for"
+                + " XMLReader: " + reader, e);
+      }
+    }
+  }
+
+  /**
+   * Factory Method to allow user derived SAXContentHandler objects to be used
+   *
+   * @param reader DOCUMENT ME!
+   * @return DOCUMENT ME!
+   */
+  protected SAXContentHandler createContentHandler(XMLReader reader) {
+    return new SAXContentHandler(getDocumentFactory(), dispatchHandler);
+  }
+
+  protected EntityResolver createDefaultEntityResolver(String systemId) {
+    String prefix = null;
+
+    if ((systemId != null) && (systemId.length() > 0)) {
+      int idx = systemId.lastIndexOf('/');
+
+      if (idx > 0) {
+        prefix = systemId.substring(0, idx + 1);
+      }
+    }
+
+    return new SAXEntityResolver(prefix);
+  }
+
+  protected static class SAXEntityResolver implements EntityResolver,
+          Serializable {
+    protected String uriPrefix;
+
+    public SAXEntityResolver(String uriPrefix) {
+      this.uriPrefix = uriPrefix;
+    }
+
+    public InputSource resolveEntity(String publicId, String systemId) {
+      // try create a relative URI reader...
+      if ((systemId != null) && (systemId.length() > 0)) {
+        if ((uriPrefix != null) && (systemId.indexOf(':') <= 0)) {
+          systemId = uriPrefix + systemId;
         }
-    }
-
-    // Properties
-    // -------------------------------------------------------------------------
-
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return the validation mode, true if validating will be done otherwise
-     *         false.
-     */
-    public boolean isValidating() {
-        return validating;
-    }
-
-    /**
-     * Sets the validation mode.
-     * 
-     * @param validation
-     *            indicates whether or not validation should occur.
-     */
-    public void setValidation(boolean validation) {
-        this.validating = validation;
-    }
+      }
 
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return whether internal DTD declarations should be expanded into the
-     *         DocumentType object or not.
-     */
-    public boolean isIncludeInternalDTDDeclarations() {
-        return includeInternalDTDDeclarations;
-    }
-
-    /**
-     * Sets whether internal DTD declarations should be expanded into the
-     * DocumentType object or not.
-     * 
-     * @param include
-     *            whether or not DTD declarations should be expanded and
-     *            included into the DocumentType object.
-     */
-    public void setIncludeInternalDTDDeclarations(boolean include) {
-        this.includeInternalDTDDeclarations = include;
-    }
-
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return whether external DTD declarations should be expanded into the
-     *         DocumentType object or not.
-     */
-    public boolean isIncludeExternalDTDDeclarations() {
-        return includeExternalDTDDeclarations;
-    }
-
-    /**
-     * Sets whether DTD external declarations should be expanded into the
-     * DocumentType object or not.
-     * 
-     * @param include
-     *            whether or not DTD declarations should be expanded and
-     *            included into the DocumentType object.
-     */
-    public void setIncludeExternalDTDDeclarations(boolean include) {
-        this.includeExternalDTDDeclarations = include;
-    }
-
-    /**
-     * Sets whether String interning is enabled or disabled for element &
-     * attribute names and namespace URIs. This proprety is enabled by default.
-     * 
-     * @return DOCUMENT ME!
-     */
-    public boolean isStringInternEnabled() {
-        return stringInternEnabled;
-    }
-
-    /**
-     * Sets whether String interning is enabled or disabled for element &
-     * attribute names and namespace URIs
-     * 
-     * @param stringInternEnabled
-     *            DOCUMENT ME!
-     */
-    public void setStringInternEnabled(boolean stringInternEnabled) {
-        this.stringInternEnabled = stringInternEnabled;
-    }
-
-    /**
-     * Returns whether adjacent text nodes should be merged together.
-     * 
-     * @return Value of property mergeAdjacentText.
-     */
-    public boolean isMergeAdjacentText() {
-        return mergeAdjacentText;
-    }
-
-    /**
-     * Sets whether or not adjacent text nodes should be merged together when
-     * parsing.
-     * 
-     * @param mergeAdjacentText
-     *            New value of property mergeAdjacentText.
-     */
-    public void setMergeAdjacentText(boolean mergeAdjacentText) {
-        this.mergeAdjacentText = mergeAdjacentText;
-    }
-
-    /**
-     * Sets whether whitespace between element start and end tags should be
-     * ignored
-     * 
-     * @return Value of property stripWhitespaceText.
-     */
-    public boolean isStripWhitespaceText() {
-        return stripWhitespaceText;
-    }
-
-    /**
-     * Sets whether whitespace between element start and end tags should be
-     * ignored.
-     * 
-     * @param stripWhitespaceText
-     *            New value of property stripWhitespaceText.
-     */
-    public void setStripWhitespaceText(boolean stripWhitespaceText) {
-        this.stripWhitespaceText = stripWhitespaceText;
-    }
-
-    /**
-     * Returns whether we should ignore comments or not.
-     * 
-     * @return boolean
-     */
-    public boolean isIgnoreComments() {
-        return ignoreComments;
-    }
-
-    /**
-     * Sets whether we should ignore comments or not.
-     * 
-     * @param ignoreComments
-     *            whether we should ignore comments or not.
-     */
-    public void setIgnoreComments(boolean ignoreComments) {
-        this.ignoreComments = ignoreComments;
-    }
-
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return the <code>DocumentFactory</code> used to create document
-     *         objects
-     */
-    public DocumentFactory getDocumentFactory() {
-        if (factory == null) {
-            factory = DocumentFactory.getInstance();
-        }
-
-        return factory;
-    }
-
-    /**
-     * <p>
-     * This sets the <code>DocumentFactory</code> used to create new
-     * documents. This method allows the building of custom DOM4J tree objects
-     * to be implemented easily using a custom derivation of
-     * {@link DocumentFactory}
-     * </p>
-     * 
-     * @param documentFactory
-     *            <code>DocumentFactory</code> used to create DOM4J objects
-     */
-    public void setDocumentFactory(DocumentFactory documentFactory) {
-        this.factory = documentFactory;
-    }
-
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return the <code>ErrorHandler</code> used by SAX
-     */
-    public ErrorHandler getErrorHandler() {
-        return errorHandler;
-    }
-
-    /**
-     * Sets the <code>ErrorHandler</code> used by the SAX
-     * <code>XMLReader</code>.
-     * 
-     * @param errorHandler
-     *            is the <code>ErrorHandler</code> used by SAX
-     */
-    public void setErrorHandler(ErrorHandler errorHandler) {
-        this.errorHandler = errorHandler;
-    }
-
-    /**
-     * Returns the current entity resolver used to resolve entities
-     * 
-     * @return DOCUMENT ME!
-     */
-    public EntityResolver getEntityResolver() {
-        return entityResolver;
-    }
-
-    /**
-     * Sets the entity resolver used to resolve entities.
-     * 
-     * @param entityResolver
-     *            DOCUMENT ME!
-     */
-    public void setEntityResolver(EntityResolver entityResolver) {
-        this.entityResolver = entityResolver;
-    }
-
-    /**
-     * DOCUMENT ME!
-     * 
-     * @return the <code>XMLReader</code> used to parse SAX events
-     * 
-     * @throws SAXException
-     *             DOCUMENT ME!
-     */
-    public XMLReader getXMLReader() throws SAXException {
-        if (xmlReader == null) {
-            xmlReader = createXMLReader();
-        }
-
-        return xmlReader;
-    }
-
-    /**
-     * Sets the <code>XMLReader</code> used to parse SAX events
-     * 
-     * @param reader
-     *            is the <code>XMLReader</code> to parse SAX events
-     */
-    public void setXMLReader(XMLReader reader) {
-        this.xmlReader = reader;
-    }
-
-    /**
-     * Returns encoding used for InputSource (null means system default
-     * encoding)
-     * 
-     * @return encoding used for InputSource
-     * 
-     */
-    public String getEncoding() {
-        return encoding;
-    }
-
-    /**
-     * Sets encoding used for InputSource (null means system default encoding)
-     * 
-     * @param encoding
-     *            is encoding used for InputSource
-     */
-    public void setEncoding(String encoding) {
-        this.encoding = encoding;
-    }
-
-    /**
-     * Sets the class name of the <code>XMLReader</code> to be used to parse
-     * SAX events.
-     * 
-     * @param xmlReaderClassName
-     *            is the class name of the <code>XMLReader</code> to parse SAX
-     *            events
-     * 
-     * @throws SAXException
-     *             DOCUMENT ME!
-     */
-    public void setXMLReaderClassName(String xmlReaderClassName)
-            throws SAXException {
-        setXMLReader(XMLReaderFactory.createXMLReader(xmlReaderClassName));
-    }
-
-    /**
-     * Adds the <code>ElementHandler</code> to be called when the specified
-     * path is encounted.
-     * 
-     * @param path
-     *            is the path to be handled
-     * @param handler
-     *            is the <code>ElementHandler</code> to be called by the event
-     *            based processor.
-     */
-    public void addHandler(String path, ElementHandler handler) {
-        getDispatchHandler().addHandler(path, handler);
-    }
-
-    /**
-     * Removes the <code>ElementHandler</code> from the event based processor,
-     * for the specified path.
-     * 
-     * @param path
-     *            is the path to remove the <code>ElementHandler</code> for.
-     */
-    public void removeHandler(String path) {
-        getDispatchHandler().removeHandler(path);
-    }
-
-    /**
-     * When multiple <code>ElementHandler</code> instances have been
-     * registered, this will set a default <code>ElementHandler</code> to be
-     * called for any path which does <b>NOT </b> have a handler registered.
-     * 
-     * @param handler
-     *            is the <code>ElementHandler</code> to be called by the event
-     *            based processor.
-     */
-    public void setDefaultHandler(ElementHandler handler) {
-        getDispatchHandler().setDefaultHandler(handler);
-    }
-
-    /**
-     * This method clears out all the existing handlers and default handler
-     * setting things back as if no handler existed. Useful when reusing an
-     * object instance.
-     */
-    public void resetHandlers() {
-        getDispatchHandler().resetHandlers();
-    }
-
-    /**
-     * Returns the SAX filter being used to filter SAX events.
-     * 
-     * @return the SAX filter being used or null if no SAX filter is installed
-     */
-    public XMLFilter getXMLFilter() {
-        return xmlFilter;
-    }
-
-    /**
-     * Sets the SAX filter to be used when filtering SAX events
-     * 
-     * @param filter
-     *            is the SAX filter to use or null to disable filtering
-     */
-    public void setXMLFilter(XMLFilter filter) {
-        this.xmlFilter = filter;
-    }
-
-    // Implementation methods
-    // -------------------------------------------------------------------------
-
-    /**
-     * Installs any XMLFilter objects required to allow the SAX event stream to
-     * be filtered and preprocessed before it gets to dom4j.
-     * 
-     * @param reader
-     *            DOCUMENT ME!
-     * 
-     * @return the new XMLFilter if applicable or the original XMLReader if no
-     *         filter is being used.
-     */
-    protected XMLReader installXMLFilter(XMLReader reader) {
-        XMLFilter filter = getXMLFilter();
-
-        if (filter != null) {
-            // find the root XMLFilter
-            XMLFilter root = filter;
-
-            while (true) {
-                XMLReader parent = root.getParent();
-
-                if (parent instanceof XMLFilter) {
-                    root = (XMLFilter) parent;
-                } else {
-                    break;
-                }
-            }
-
-            root.setParent(reader);
-
-            return filter;
-        }
-
-        return reader;
-    }
-
-    protected DispatchHandler getDispatchHandler() {
-        if (dispatchHandler == null) {
-            dispatchHandler = new DispatchHandler();
-        }
-
-        return dispatchHandler;
-    }
-
-    protected void setDispatchHandler(DispatchHandler dispatchHandler) {
-        this.dispatchHandler = dispatchHandler;
-    }
-
-    /**
-     * Factory Method to allow alternate methods of creating and configuring
-     * XMLReader objects
-     * 
-     * @return DOCUMENT ME!
-     * 
-     * @throws SAXException
-     *             DOCUMENT ME!
-     */
-    protected XMLReader createXMLReader() throws SAXException {
-        return SAXHelper.createXMLReader(isValidating());
-    }
-
-    /**
-     * Configures the XMLReader before use
-     * 
-     * @param reader
-     *            DOCUMENT ME!
-     * @param handler
-     *            DOCUMENT ME!
-     * 
-     * @throws DocumentException
-     *             DOCUMENT ME!
-     */
-    protected void configureReader(XMLReader reader, DefaultHandler handler)
-            throws DocumentException {
-        // configure lexical handling
-        SAXHelper.setParserProperty(reader, SAX_LEXICALHANDLER, handler);
-
-        // try alternate property just in case
-        SAXHelper.setParserProperty(reader, SAX_LEXICAL_HANDLER, handler);
-
-        // register the DeclHandler
-        if (includeInternalDTDDeclarations || includeExternalDTDDeclarations) {
-            SAXHelper.setParserProperty(reader, SAX_DECL_HANDLER, handler);
-        }
-
-        // string interning
-        SAXHelper.setParserFeature(reader, SAX_STRING_INTERNING,
-                isStringInternEnabled());
-
-        try {
-            // configure validation support
-            reader.setFeature("http://xml.org/sax/features/validation",
-                    isValidating());
-
-            if (errorHandler != null) {
-                reader.setErrorHandler(errorHandler);
-            } else {
-                reader.setErrorHandler(handler);
-            }
-        } catch (Exception e) {
-            if (isValidating()) {
-                throw new DocumentException("Validation not supported for"
-                        + " XMLReader: " + reader, e);
-            }
-        }
-    }
-
-    /**
-     * Factory Method to allow user derived SAXContentHandler objects to be used
-     * 
-     * @param reader
-     *            DOCUMENT ME!
-     * 
-     * @return DOCUMENT ME!
-     */
-    protected SAXContentHandler createContentHandler(XMLReader reader) {
-        return new SAXContentHandler(getDocumentFactory(), dispatchHandler);
-    }
-
-    protected EntityResolver createDefaultEntityResolver(String systemId) {
-        String prefix = null;
-
-        if ((systemId != null) && (systemId.length() > 0)) {
-            int idx = systemId.lastIndexOf('/');
-
-            if (idx > 0) {
-                prefix = systemId.substring(0, idx + 1);
-            }
-        }
-
-        return new SAXEntityResolver(prefix);
-    }
-
-    protected static class SAXEntityResolver implements EntityResolver,
-            Serializable {
-        protected String uriPrefix;
-
-        public SAXEntityResolver(String uriPrefix) {
-            this.uriPrefix = uriPrefix;
-        }
-
-        public InputSource resolveEntity(String publicId, String systemId) {
-            // try create a relative URI reader...
-            if ((systemId != null) && (systemId.length() > 0)) {
-                if ((uriPrefix != null) && (systemId.indexOf(':') <= 0)) {
-                    systemId = uriPrefix + systemId;
-                }
-            }
-
-            return new InputSource(systemId);
-        }
+      return new InputSource(systemId);
     }
+  }
 }
 
 /*
  * Redistribution and use of this software and associated documentation
  * ("Software"), with or without modification, are permitted provided that the
  * following conditions are met:
- * 
+ *
  * 1. Redistributions of source code must retain copyright statements and
  * notices. Redistributions must also contain a copy of this document.
- * 
+ *
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  * this list of conditions and the following disclaimer in the documentation
  * and/or other materials provided with the distribution.
- * 
+ *
  * 3. The name "DOM4J" must not be used to endorse or promote products derived
  * from this Software without prior written permission of MetaStuff, Ltd. For
  * written permission, please contact dom4j-info at metastuff.com.
- * 
+ *
  * 4. Products derived from this Software may not be called "DOM4J" nor may
  * "DOM4J" appear in their names without prior written permission of MetaStuff,
  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
- * 
+ *
  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -1000,6 +1016,6 @@ public class SAXReader {
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
- * 
+ *
  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
  */



View it on GitLab: https://salsa.debian.org/java-team/dom4j/-/compare/f7a3749308e084d90399dcc5ba38e7461d9b841a...9bc317b76f0a42ea16cd42b5cf8a6656e73b1516

-- 
View it on GitLab: https://salsa.debian.org/java-team/dom4j/-/compare/f7a3749308e084d90399dcc5ba38e7461d9b841a...9bc317b76f0a42ea16cd42b5cf8a6656e73b1516
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20200916/c0affb59/attachment.html>


More information about the pkg-java-commits mailing list