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

org.eclipse.persistence.platform.xml.jaxp.JAXPPlatform Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * Copyright (c) 1998, 2018 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.jaxp;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.eclipse.persistence.internal.helper.XMLHelper;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.platform.xml.XMLNamespaceResolver;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformException;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;

/**
 * 

Purpose: An implementation of XMLPlatform using JAXP 1.3 APIs.

*/ public class JAXPPlatform implements XMLPlatform { private XPathFactory xPathFactory; private SchemaFactory schemaFactory; private DocumentBuilderFactory documentBuilderFactory; private boolean disableSecureProcessing = false; public JAXPPlatform() { super(); } private DocumentBuilderFactory getDocumentBuilderFactory() { if(null == documentBuilderFactory) { documentBuilderFactory = XMLHelper.createDocumentBuilderFactory(isSecureProcessingDisabled()); } return documentBuilderFactory; } public XPathFactory getXPathFactory() { if(null == xPathFactory) { xPathFactory = XMLHelper.createXPathFactory(isSecureProcessingDisabled()); } return xPathFactory; } public SchemaFactory getSchemaFactory() { if(null == schemaFactory) { schemaFactory = XMLHelper.createSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI, isSecureProcessingDisabled()); } return schemaFactory; } /** * Execute advanced XPath statements that are required for TopLink EIS. * @param contextNode the node relative to which the XPath * statement will be executed. * xPath the XPath statement * namespaceResolver used to resolve namespace prefixes * to the corresponding namespace URI * @return the XPath result * @throws XMLPlatformException */ @Override public NodeList selectNodesAdvanced(Node contextNode, String xPathString, XMLNamespaceResolver xmlNamespaceResolver) throws XMLPlatformException { try { XPath xPath = getXPathFactory().newXPath(); if(null != xmlNamespaceResolver) { JAXPNamespaceContext namespaceContext = new JAXPNamespaceContext(xmlNamespaceResolver); xPath.setNamespaceContext(namespaceContext); } XPathExpression xPathExpression = xPath.compile(xPathString); return (NodeList) xPathExpression.evaluate(contextNode, XPathConstants.NODESET); } catch(XPathException e) { throw XMLPlatformException.xmlPlatformInvalidXPath(e); } } /** * Execute advanced XPath statements that are required for TopLink EIS. * @param contextNode * @param xPathString * @param xmlNamespaceResolver * @return * @throws XMLPlatformException */ @Override public Node selectSingleNodeAdvanced(Node contextNode, String xPathString, XMLNamespaceResolver xmlNamespaceResolver) throws XMLPlatformException { try { XPath xPath = getXPathFactory().newXPath(); if(null != xmlNamespaceResolver) { JAXPNamespaceContext namespaceContext = new JAXPNamespaceContext(xmlNamespaceResolver); xPath.setNamespaceContext(namespaceContext); } XPathExpression xPathExpression = xPath.compile(xPathString); return (Node) xPathExpression.evaluate(contextNode, XPathConstants.NODE); } catch(XPathException e) { throw XMLPlatformException.xmlPlatformInvalidXPath(e); } } @Override public boolean isWhitespaceNode(Text text) { String value = text.getNodeValue(); if (null == value) { return false; } else { return value.trim().equals(""); } } @Override public XMLParser newXMLParser() { return new JAXPParser(); } @Override public XMLParser newXMLParser(Map parserFeatures) { return new JAXPParser(parserFeatures); } @Override public XMLTransformer newXMLTransformer() { return new JAXPTransformer(); } @Override public Document createDocument() throws XMLPlatformException { try { DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder(); return documentBuilder.newDocument(); } catch (Exception e) { throw XMLPlatformException.xmlPlatformCouldNotCreateDocument(e); } } @Override public Document createDocumentWithPublicIdentifier(String name, String publicIdentifier, String systemIdentifier) throws XMLPlatformException { try { if (null == publicIdentifier) { return createDocumentWithSystemIdentifier(name, systemIdentifier); } DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder(); DOMImplementation domImpl = documentBuilder.getDOMImplementation(); DocumentType docType = domImpl.createDocumentType(name, publicIdentifier, systemIdentifier); Document document = domImpl.createDocument(null, name, docType); return document; } catch (Exception e) { throw XMLPlatformException.xmlPlatformCouldNotCreateDocument(e); } } @Override public Document createDocumentWithSystemIdentifier(String name, String systemIdentifier) throws XMLPlatformException { try { Document document = null; if (null == systemIdentifier) { document = createDocument(); Element rootElement = document.createElement(name); document.appendChild(rootElement); return document; } DocumentBuilder documentBuilder = getDocumentBuilderFactory().newDocumentBuilder(); DOMImplementation domImpl = documentBuilder.getDOMImplementation(); DocumentType docType = domImpl.createDocumentType(name, null, systemIdentifier); document = domImpl.createDocument(null, name, docType); return document; } catch (Exception e) { throw XMLPlatformException.xmlPlatformCouldNotCreateDocument(e); } } @Override public String resolveNamespacePrefix(Node contextNode, String namespacePrefix) throws XMLPlatformException { if (null == namespacePrefix) { if (null == contextNode.getPrefix()) { return contextNode.getNamespaceURI(); } } else if (namespacePrefix.equals(contextNode.getPrefix())) { return contextNode.getNamespaceURI(); } if (contextNode.getNodeType() == Node.ELEMENT_NODE) { Element contextElement = (Element)contextNode; Attr namespaceDeclaration = null; if(namespacePrefix != null) { namespaceDeclaration = contextElement.getAttributeNode("xmlns:" + namespacePrefix); } else { //look for default namespace declaration for null prefix namespaceDeclaration = contextElement.getAttributeNode(javax.xml.XMLConstants.XMLNS_ATTRIBUTE); } if (null != namespaceDeclaration) { return namespaceDeclaration.getValue(); } } Node parentNode = contextNode.getParentNode(); if (parentNode!=null && parentNode.getNodeType() == Node.ELEMENT_NODE) { return resolveNamespacePrefix(parentNode, namespacePrefix); } return null; } @Override public boolean validateDocument(Document document, URL xmlSchemaURL, ErrorHandler errorHandler) throws XMLPlatformException { Schema xmlSchema; try { xmlSchema = getSchemaFactory().newSchema(xmlSchemaURL); } catch(SAXException e) { throw XMLPlatformException.xmlPlatformErrorResolvingXMLSchema(xmlSchemaURL, e); } try { Validator validator = xmlSchema.newValidator(); validator.setErrorHandler(errorHandler); validator.validate(new DOMSource(document)); } catch(Exception e) { throw XMLPlatformException.xmlPlatformValidationException(e); } return true; } @Override public boolean validate(Element elem, org.eclipse.persistence.oxm.XMLDescriptor xmlDescriptor, ErrorHandler handler) throws XMLPlatformException { return true; } @Override public void namespaceQualifyFragment(Element next) { namespaceQualifyFragment(next, new ArrayList()); } //pass list of prefixes declared and encountered private void namespaceQualifyFragment(Element next, List declaredPrefixes) { String elementUri = next.getNamespaceURI(); String elementPrefix = next.getPrefix(); if (elementPrefix != null) { //see if this prefix is already declared if yes - do nothing, if no declare Attr namespaceDeclaration = next.getAttributeNode(javax.xml.XMLConstants.XMLNS_ATTRIBUTE+":" + elementPrefix); if ((null == namespaceDeclaration) && !declaredPrefixes.contains(elementPrefix)) { (next).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE+ ":" + elementPrefix, elementUri); declaredPrefixes.add(elementPrefix); } } //check all attributes prefixes and if any of them arent declared add them also. NamedNodeMap attributes = next.getAttributes(); int attributesSize = attributes.getLength(); for (int i = 0; i < attributesSize; i++) { Attr nextAttribute = (Attr)attributes.item(i); String attributePrefix = nextAttribute.getPrefix(); if (attributePrefix != null) { //if attribute is a namespace declaration add to declared list if (javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(nextAttribute.getNamespaceURI())) { declaredPrefixes.add(nextAttribute.getLocalName()); } else { Attr namespaceDeclaration = next.getAttributeNode(javax.xml.XMLConstants.XMLNS_ATTRIBUTE +":" + attributePrefix); if ((null == namespaceDeclaration) && !declaredPrefixes.contains(attributePrefix)) { String attributeUri = nextAttribute.getNamespaceURI(); (next).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + ":" + attributePrefix, attributeUri); declaredPrefixes.add(attributePrefix); } //if xsi:type declaration deal with that value if (javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(nextAttribute.getNamespaceURI()) && Constants.SCHEMA_TYPE_ATTRIBUTE.equals(nextAttribute.getLocalName())) { String value = nextAttribute.getValue(); int colonIndex = value.indexOf(':'); if (colonIndex > -1) { String prefix = value.substring(0, colonIndex); namespaceDeclaration = next.getAttributeNode(javax.xml.XMLConstants.XMLNS_ATTRIBUTE +":" + prefix); if ((null == namespaceDeclaration) && !declaredPrefixes.contains(prefix)) { String uri = XMLPlatformFactory.getInstance().getXMLPlatform().resolveNamespacePrefix(next, prefix); (next).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix, uri); declaredPrefixes.add(prefix); } } } } } } NodeList children = next.getChildNodes(); int numberOfNodes = children.getLength(); for (int i = 0; i < numberOfNodes; i++) { Node nextNode = children.item(i); if (nextNode.getNodeType() == Node.ELEMENT_NODE) { Element child = (Element)nextNode; namespaceQualifyFragment(child, declaredPrefixes); } } } @Override public void setDisableSecureProcessing(boolean disableSecureProcessing) { boolean shouldReset = this.disableSecureProcessing ^ disableSecureProcessing; this.disableSecureProcessing = disableSecureProcessing; if (shouldReset) { documentBuilderFactory = null; schemaFactory = null; xPathFactory = null; } } @Override public boolean isSecureProcessingDisabled() { return disableSecureProcessing; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy