From a232c2954a9451aed25c0bdcf7c7a5b93878e913 Mon Sep 17 00:00:00 2001 From: "Yuan.Wang" <1536296691@qq.com> Date: Fri, 9 Jun 2023 14:01:48 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-95578=20dom4j=E5=8D=87=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/org/dom4j/dtd/Decl.java | 7 + .../java/org/dom4j/io/DOMDocumentResult.java | 102 ++++ .../org/dom4j/io/DOMSAXContentHandler.java | 548 ++++++++++++++++++ .../main/java/org/dom4j/util/StringUtils.java | 44 ++ 4 files changed, 701 insertions(+) create mode 100644 fine-org-dom4j/src/main/java/org/dom4j/dtd/Decl.java create mode 100644 fine-org-dom4j/src/main/java/org/dom4j/io/DOMDocumentResult.java create mode 100644 fine-org-dom4j/src/main/java/org/dom4j/io/DOMSAXContentHandler.java create mode 100644 fine-org-dom4j/src/main/java/org/dom4j/util/StringUtils.java diff --git a/fine-org-dom4j/src/main/java/org/dom4j/dtd/Decl.java b/fine-org-dom4j/src/main/java/org/dom4j/dtd/Decl.java new file mode 100644 index 000000000..f05d32df5 --- /dev/null +++ b/fine-org-dom4j/src/main/java/org/dom4j/dtd/Decl.java @@ -0,0 +1,7 @@ +package org.dom4j.dtd; + +/** + * Created by filip on 5.7.15. + */ +public interface Decl { +} diff --git a/fine-org-dom4j/src/main/java/org/dom4j/io/DOMDocumentResult.java b/fine-org-dom4j/src/main/java/org/dom4j/io/DOMDocumentResult.java new file mode 100644 index 000000000..5f579bbe3 --- /dev/null +++ b/fine-org-dom4j/src/main/java/org/dom4j/io/DOMDocumentResult.java @@ -0,0 +1,102 @@ +/* + * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved. + * + * This software is open source. + * See the bottom of this file for the licence. + */ + +package org.dom4j.io; + +import javax.xml.transform.sax.SAXResult; + +import org.w3c.dom.Document; + +import org.xml.sax.ContentHandler; +import org.xml.sax.ext.LexicalHandler; + +/** + *

+ * DOMDocumentResult implements a JAXP {@link SAXResult} for a + * {@link org.w3c.dom.Document}. + *

+ * + * @author James Strachan + * @author Todd Wolff + * @version $Revision: 1.1 $ + */ +public class DOMDocumentResult extends SAXResult { + private DOMSAXContentHandler contentHandler; + + public DOMDocumentResult() { + this(new DOMSAXContentHandler()); + } + + public DOMDocumentResult(DOMSAXContentHandler contentHandler) { + this.contentHandler = contentHandler; + super.setHandler(this.contentHandler); + super.setLexicalHandler(this.contentHandler); + } + + /** + * Retrieves w3c dom object generated via transformation + * + * @return the Document created by the transformation + */ + public Document getDocument() { + return contentHandler.getDocument(); + } + + // Overloaded methods + // ------------------------------------------------------------------------- + public void setHandler(ContentHandler handler) { + if (handler instanceof DOMSAXContentHandler) { + this.contentHandler = (DOMSAXContentHandler) handler; + super.setHandler(this.contentHandler); + } + } + + public void setLexicalHandler(LexicalHandler handler) { + if (handler instanceof DOMSAXContentHandler) { + this.contentHandler = (DOMSAXContentHandler) handler; + super.setLexicalHandler(this.contentHandler); + } + } + +} + +/* + * 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@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 + * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * 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. + */ diff --git a/fine-org-dom4j/src/main/java/org/dom4j/io/DOMSAXContentHandler.java b/fine-org-dom4j/src/main/java/org/dom4j/io/DOMSAXContentHandler.java new file mode 100644 index 000000000..821590c9b --- /dev/null +++ b/fine-org-dom4j/src/main/java/org/dom4j/io/DOMSAXContentHandler.java @@ -0,0 +1,548 @@ +/* + * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved. + * + * This software is open source. + * See the bottom of this file for the licence. + */ + +package org.dom4j.io; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.dom4j.Branch; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.Namespace; +import org.dom4j.QName; +import org.dom4j.dom.DOMAttribute; +import org.dom4j.dom.DOMCDATA; +import org.dom4j.dom.DOMComment; +import org.dom4j.dom.DOMDocumentFactory; +import org.dom4j.dom.DOMElement; +import org.dom4j.dom.DOMText; +import org.dom4j.tree.NamespaceStack; +import org.w3c.dom.ProcessingInstruction; +import org.xml.sax.Attributes; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.ext.LexicalHandler; +import org.xml.sax.ext.Locator2; +import org.xml.sax.helpers.DefaultHandler; + +/** + *

+ * SAXContentHandler builds W3C DOM object via SAX events. + * + * @author James Strachan + * @author Todd Wolff + * + *

+ */ +public class DOMSAXContentHandler extends DefaultHandler implements LexicalHandler { + + /** The factory used to create new Document instances */ + private DOMDocumentFactory documentFactory; + + /** The document that is being built */ + private Document document; + + /** stack of Element objects */ + private ElementStack elementStack; + + /** stack of Namespace and QName objects */ + private NamespaceStack namespaceStack; + + /** the Locator */ + private Locator locator; + + /** Flag used to indicate that we are inside a CDATA section */ + private boolean insideCDATASection; + + /** + * buffer to hold contents of cdata section across multiple characters + * events + */ + private StringBuffer cdataText; + + /** The number of namespaces that are declared in the current scope */ + private int declaredNamespaceIndex; + + private InputSource inputSource; + + /** The current element we are on */ + private Element currentElement; + + /** The entity resolver */ + private EntityResolver entityResolver; + + /** Whether adjacent text nodes should be merged */ + private boolean mergeAdjacentText = false; + + /** Have we added text to the buffer */ + private boolean textInTextBuffer = false; + + /** Should we ignore comments */ + private boolean ignoreComments = false; + + /** Buffer used to concatenate text together */ + private StringBuffer textBuffer; + + /** Holds value of property stripWhitespaceText. */ + private boolean stripWhitespaceText = false; + + public DOMSAXContentHandler() { + this((DOMDocumentFactory)DOMDocumentFactory.getInstance()); + } + + public DOMSAXContentHandler(DOMDocumentFactory documentFactory) { + this.documentFactory = documentFactory; + this.elementStack = createElementStack(); + this.namespaceStack = new NamespaceStack(documentFactory); + } + + /** + * Retrieves w3c document object built via generated sax events. + * + * @return the document that has been or is being built + */ + public org.w3c.dom.Document getDocument() { + if (document == null) { + document = createDocument(); + } + + return (org.w3c.dom.Document)document; + } + + // ContentHandler interface + // ------------------------------------------------------------------------- + public void setDocumentLocator(Locator documentLocator) { + this.locator = documentLocator; + } + + public void processingInstruction(String target, String data) + throws SAXException { + if (mergeAdjacentText && textInTextBuffer) { + completeCurrentTextNode(); + } + ProcessingInstruction pi = (ProcessingInstruction)documentFactory.createProcessingInstruction(target, data); + if (currentElement != null) { + ((org.w3c.dom.Element)currentElement).appendChild(pi); + } else { + getDocument().appendChild(pi); + } + } + + public void startPrefixMapping(String prefix, String uri) + throws SAXException { + namespaceStack.push(prefix, uri); + } + + public void endPrefixMapping(String prefix) throws SAXException { + namespaceStack.pop(prefix); + declaredNamespaceIndex = namespaceStack.size(); + } + + public void startDocument() throws SAXException { + document = null; + currentElement = null; + + elementStack.clear(); + + namespaceStack.clear(); + declaredNamespaceIndex = 0; + + if (mergeAdjacentText && (textBuffer == null)) { + textBuffer = new StringBuffer(); + } + + textInTextBuffer = false; + } + + public void endDocument() throws SAXException { + namespaceStack.clear(); + elementStack.clear(); + currentElement = null; + textBuffer = null; + } + + public void startElement(String namespaceURI, String localName, + String qualifiedName, Attributes attributes) throws SAXException { + if (mergeAdjacentText && textInTextBuffer) { + completeCurrentTextNode(); + } + + QName qName = namespaceStack.getQName(namespaceURI, localName, + qualifiedName); + + Branch branch = currentElement; + + if (branch == null) { + branch = (org.dom4j.Document)getDocument(); + } + + Element element = new DOMElement(qName); + branch.add(element); + + // add all declared namespaces + addDeclaredNamespaces(element); + + // now lets add all attribute values + addAttributes(element, attributes); + + elementStack.pushElement(element); + currentElement = element; + + } + + public void endElement(String namespaceURI, String localName, String qName) + throws SAXException { + if (mergeAdjacentText && textInTextBuffer) { + completeCurrentTextNode(); + } + + elementStack.popElement(); + currentElement = elementStack.peekElement(); + } + + public void characters(char[] ch, int start, int end) throws SAXException { + if (end == 0) { + return; + } + + if (currentElement != null) { + if (insideCDATASection) { + if (mergeAdjacentText && textInTextBuffer) { + completeCurrentTextNode(); + } + cdataText.append(new String(ch, start, end)); + } else { + if (mergeAdjacentText) { + textBuffer.append(ch, start, end); + textInTextBuffer = true; + } else { + DOMText text = new DOMText(new String(ch, start, end)); + ((DOMElement)currentElement).add(text); + } + } + } + } + + // ErrorHandler interface + // ------------------------------------------------------------------------- + + /** + * This method is called when a warning occurs during the parsing of the + * document. This method does nothing. + * + * @param exception + * DOCUMENT ME! + * + * @throws SAXException + * DOCUMENT ME! + */ + public void warning(SAXParseException exception) throws SAXException { + // ignore warnings by default + } + + /** + * This method is called when an error is detected during parsing such as a + * validation error. This method rethrows the exception + * + * @param exception + * DOCUMENT ME! + * + * @throws SAXException + * DOCUMENT ME! + */ + public void error(SAXParseException exception) throws SAXException { + throw exception; + } + + /** + * This method is called when a fatal error occurs during parsing. This + * method rethrows the exception + * + * @param exception + * DOCUMENT ME! + * + * @throws SAXException + * DOCUMENT ME! + */ + public void fatalError(SAXParseException exception) throws SAXException { + throw exception; + } + + // LexicalHandler interface + // ------------------------------------------------------------------------- + public void startDTD(String name, String publicId, String systemId) + throws SAXException { + // not supported + } + + public void endDTD() throws SAXException { + // not supported + } + + public void startEntity(String name) throws SAXException { + // not supported + } + + public void endEntity(String name) throws SAXException { + // not supported + } + + public void startCDATA() throws SAXException { + insideCDATASection = true; + cdataText = new StringBuffer(); + } + + public void endCDATA() throws SAXException { + insideCDATASection = false; + DOMCDATA cdata = new DOMCDATA(cdataText.toString()); + ((DOMElement)currentElement).add(cdata); + } + + public void comment(char[] ch, int start, int end) throws SAXException { + if (!ignoreComments) { + if (mergeAdjacentText && textInTextBuffer) { + completeCurrentTextNode(); + } + + String text = new String(ch, start, end); + + if (text.length() > 0) { + DOMComment domComment = new DOMComment(text); + if (currentElement != null) { + ((DOMElement)currentElement).add(domComment); + } else { + getDocument().appendChild(domComment); + } + } + } + } + + // Properties + // ------------------------------------------------------------------------- + public ElementStack getElementStack() { + return elementStack; + } + + public void setElementStack(ElementStack elementStack) { + this.elementStack = elementStack; + } + + public EntityResolver getEntityResolver() { + return entityResolver; + } + + public void setEntityResolver(EntityResolver entityResolver) { + this.entityResolver = entityResolver; + } + + public InputSource getInputSource() { + return inputSource; + } + + public void setInputSource(InputSource inputSource) { + this.inputSource = inputSource; + } + + /** + * 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; + } + + // Implementation methods + // ------------------------------------------------------------------------- + + protected void completeCurrentTextNode() { + if (stripWhitespaceText) { + boolean whitespace = true; + for (int i = 0, size = textBuffer.length(); i < size; i++) { + if (!Character.isWhitespace(textBuffer.charAt(i))) { + whitespace = false; + + break; + } + } + if (!whitespace) { + DOMText domText = new DOMText(textBuffer.toString()); + ((DOMElement)currentElement).add(domText); + } + } else { + DOMText domText = new DOMText(textBuffer.toString()); + ((DOMElement)currentElement).add(domText); + } + + textBuffer.setLength(0); + textInTextBuffer = false; + } + + protected Document createDocument() { + String encoding = getEncoding(); + Document doc = documentFactory.createDocument(encoding); + + // set the EntityResolver + doc.setEntityResolver(entityResolver); + + if (inputSource != null) { + doc.setName(inputSource.getSystemId()); + } + + return doc; + } + + private String getEncoding() { + if (locator == null) { + return null; + } + + if (locator instanceof Locator2) { + return ((Locator2) locator).getEncoding(); + } + + // couldn't determine encoding, returning null... + return null; + } + + protected void addDeclaredNamespaces(Element element) { + for (int size = namespaceStack.size(); declaredNamespaceIndex < size; + declaredNamespaceIndex++) { + Namespace namespace = namespaceStack + .getNamespace(declaredNamespaceIndex); + String attributeName = attributeNameForNamespace(namespace); + ((DOMElement)element).setAttribute(attributeName, namespace.getURI()); + } + } + + protected void addAttributes(Element element, Attributes attributes) { + int size = attributes.getLength(); + for (int i = 0; i < size; i++) { + String attributeQName = attributes.getQName(i); + if (!attributeQName.startsWith("xmlns")) { + String attributeURI = attributes.getURI(i); + String attributeLocalName = attributes.getLocalName(i); + String attributeValue = attributes.getValue(i); + QName qName = namespaceStack.getAttributeQName( + attributeURI, attributeLocalName, attributeQName); + DOMAttribute domAttribute = new DOMAttribute(qName, attributeValue); + ((DOMElement)element).setAttributeNode(domAttribute); + } + } + } + + protected ElementStack createElementStack() { + return new ElementStack(); + } + + protected String attributeNameForNamespace(Namespace namespace) { + String xmlns = "xmlns"; + String prefix = namespace.getPrefix(); + + if (prefix.length() > 0) { + return xmlns + ":" + prefix; + } + + return xmlns; + } + +} + +/* + * 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@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 + * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * 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. + */ diff --git a/fine-org-dom4j/src/main/java/org/dom4j/util/StringUtils.java b/fine-org-dom4j/src/main/java/org/dom4j/util/StringUtils.java new file mode 100644 index 000000000..694e3b99e --- /dev/null +++ b/fine-org-dom4j/src/main/java/org/dom4j/util/StringUtils.java @@ -0,0 +1,44 @@ +package org.dom4j.util; + +/** + * Contains utilities related to strings. + * + * @author Marián Petráš + */ +public final class StringUtils { + + private StringUtils() {} + + /** + * Finds out if the given character sequence starts with a whitespace + * character. + * + * @return {@code true} if the given character sequence is not empty + * and starts with a whitespace character; {@code false} otherwise + * @exception NullPointerException if the given character sequence is + * {@code null} + */ + public static boolean startsWithWhitespace(final CharSequence charSeq) { + if (charSeq.length() == 0) { + return false; + } + return Character.isWhitespace(charSeq.charAt(0)); + } + + /** + * Finds out if the given character sequence ends with a whitespace + * character. + * + * @return {@code true} if the given character sequence is not empty + * and ends with a whitespace character; {@code false} otherwise + * @exception NullPointerException if the given character sequence is + * {@code null} + */ + public static boolean endsWithWhitespace(final CharSequence charSeq) { + if (charSeq.length() == 0) { + return false; + } + return Character.isWhitespace(charSeq.charAt(charSeq.length() - 1)); + } + +}