[Git][java-team/dom4j][upstream] 2 commits: New upstream version 2.1.2
Emmanuel Bourg
gitlab at salsa.debian.org
Wed Sep 16 14:04:11 BST 2020
Emmanuel Bourg pushed to branch upstream 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
- - - - -
6 changed files:
- .gitignore
- README.md
- build.gradle
- 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
+}
=====================================
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/fc1e5d4e924148668e94a9d48263a180b7231875...1dd79ab75cf83e218c667baa3a652689219b08d4
--
View it on GitLab: https://salsa.debian.org/java-team/dom4j/-/compare/fc1e5d4e924148668e94a9d48263a180b7231875...1dd79ab75cf83e218c667baa3a652689219b08d4
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/6e0322ef/attachment.html>
More information about the pkg-java-commits
mailing list