All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.platform.xml.SAXDocumentBuilder Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.platform.xml;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.StrBuffer;
import org.eclipse.persistence.internal.oxm.record.ExtendedContentHandler;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;

/**
 * 

Purpose: Build a DOM from SAX events.

*/ public class SAXDocumentBuilder implements ExtendedContentHandler, LexicalHandler { protected Document document; protected List nodes; protected XMLPlatform xmlPlatform; protected Map namespaceDeclarations; protected StrBuffer stringBuffer; protected Locator locator; public SAXDocumentBuilder() { super(); nodes = new ArrayList<>(); xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform(); stringBuffer = new StrBuffer(); namespaceDeclarations = new HashMap(); } public Document getDocument() { return document; } public Document getInitializedDocument() throws SAXException { if (document == null) { try { document = xmlPlatform.createDocument(); nodes.add(document); } catch (Exception e) { throw new SAXException(e); } } return document; } @Override public void setDocumentLocator(Locator locator) { this.locator = locator; } @Override public void startDocument() throws SAXException { try { document = xmlPlatform.createDocument(); nodes.add(document); } catch (Exception e) { throw new SAXException(e); } } @Override public void endDocument() throws SAXException { nodes.remove(nodes.size() - 1); } @Override public void startPrefixMapping(String prefix, String uri) throws SAXException { if(null == prefix) { prefix = Constants.EMPTY_STRING; } if(null == uri) { uri = Constants.EMPTY_STRING; } if (namespaceDeclarations == null) { namespaceDeclarations = new HashMap(); } namespaceDeclarations.put(prefix, uri); } @Override public void endPrefixMapping(String prefix) throws SAXException { } @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { if (null != namespaceURI && namespaceURI.length() == 0) { namespaceURI = null; } Element element = getInitializedDocument().createElementNS(namespaceURI, qName); Node parentNode = nodes.get(nodes.size()-1); if ((stringBuffer.length() > 0) && !(nodes.size() == 1)) { Text text = getInitializedDocument().createTextNode(stringBuffer.toString()); parentNode.appendChild(text); stringBuffer.reset(); } appendChildNode(parentNode, element); nodes.add(element); if (namespaceDeclarations != null) { Iterator> namespaceEntries = namespaceDeclarations.entrySet().iterator(); String prefix; String uri; while (namespaceEntries.hasNext()) { Entry nextEntry = namespaceEntries.next(); prefix = nextEntry.getKey(); uri = nextEntry.getValue(); boolean prefixEmpty = prefix.length() == 0; String elemNamespaceURI = element.getNamespaceURI(); boolean elementNamespaceNull = elemNamespaceURI == null; boolean elementNamespaceEmpty = elemNamespaceURI != null && elemNamespaceURI.length() == 0; boolean isRootElement = element.getParentNode().getNodeType() == Node.DOCUMENT_NODE; if (prefixEmpty && isRootElement && (elementNamespaceEmpty || elementNamespaceNull)) { // Don't add namespace } else { addNamespaceDeclaration(element, prefix, uri); } } namespaceDeclarations = null; } int numberOfAttributes = atts.getLength(); String attributeNamespaceURI; for (int x = 0; x < numberOfAttributes; x++) { attributeNamespaceURI = atts.getURI(x); if (null != attributeNamespaceURI && attributeNamespaceURI.length() == 0) { attributeNamespaceURI = null; } // Handle case where prefix/uri are not set on an xmlns prefixed attribute if (attributeNamespaceURI == null && (atts.getQName(x).startsWith(javax.xml.XMLConstants.XMLNS_ATTRIBUTE + ":") || atts.getQName(x).equals(javax.xml.XMLConstants.XMLNS_ATTRIBUTE))) { attributeNamespaceURI = javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI; } String value = atts.getValue(x); element.setAttributeNS(attributeNamespaceURI, atts.getQName(x), value); } } @Override public void endElement(String namespaceURI, String localName, String qName) throws SAXException { Element endedElement = (Element)nodes.remove(nodes.size()-1); if (stringBuffer.length() > 0) { Text text = getInitializedDocument().createTextNode(stringBuffer.toString()); endedElement.appendChild(text); stringBuffer.reset(); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { stringBuffer.append(ch, start, length); } @Override public void characters(CharSequence characters) { stringBuffer.append(characters.toString()); } @Override public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { } @Override public void processingInstruction(String target, String data) throws SAXException { ProcessingInstruction pi = getInitializedDocument().createProcessingInstruction(target, data); Node parentNode = nodes.get(nodes.size() -1); parentNode.appendChild(pi); } @Override public void skippedEntity(String name) throws SAXException { } protected void addNamespaceDeclaration(Element parentElement, String prefix, String uri) { if (prefix.length() == 0 || javax.xml.XMLConstants.XMLNS_ATTRIBUTE.equals(prefix)) { //handle default/target namespaces parentElement.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE, uri); } else { parentElement.setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + prefix, uri); } } public void appendChildNode(Node parentNode, Node childNode) { parentNode.appendChild(childNode); } @Override public void setNil(boolean isNil) {} @Override public void startDTD(String name, String publicId, String systemId) throws SAXException {} @Override public void endDTD() throws SAXException {} @Override public void startEntity(String name) throws SAXException {} @Override public void endEntity(String name) throws SAXException {} @Override public void startCDATA() throws SAXException { CDATASection cdata = document.createCDATASection(null); Node parentNode = nodes.get(nodes.size() -1); parentNode.appendChild(cdata); } @Override public void endCDATA() throws SAXException { CDATASection cdata = (CDATASection)nodes.get(nodes.size()-1).getFirstChild(); if (stringBuffer.length() > 0) { cdata.setData(stringBuffer.toString()); stringBuffer.reset(); } } @Override public void comment(char[] ch, int start, int length) throws SAXException {} }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy