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

org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller 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.internal.oxm.record;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.ValidatorHandler;

import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.helper.XMLHelper;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.Context;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.MediaType;
import org.eclipse.persistence.internal.oxm.Root;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.UnmarshallerHandler;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.UnmarshalKeepAsElementPolicy;
import org.eclipse.persistence.internal.oxm.record.json.JsonStructureReader;
import org.eclipse.persistence.platform.xml.DefaultErrorHandler;
import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * INTERNAL:
 * 

Purpose:Provide an implementation of PlatformUnmarshaller that makes use of the SAX parser * to build Java Objects from SAX Events. *

Responsibilities:

    *
  • Implement the required unmarshal methods from PlatformUnmarshaller
  • *
  • Check to see if document preservation is enabled, and if so, always unmarshal from a node
  • *
* * @author bdoughan * @see org.eclipse.persistence.oxm.platform.SAXPlatform */ public class SAXUnmarshaller implements PlatformUnmarshaller { private static final String VALIDATING = "http://xml.org/sax/features/validation"; private static final String SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; private static final String SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource"; private static final String XML_SCHEMA = "http://www.w3.org/2001/XMLSchema"; private static final UnmarshalKeepAsElementPolicy KEEP_UNKNOWN_AS_ELEMENT = new UnmarshalKeepAsElementPolicy() { @Override public boolean isKeepAllAsElement() { return false; } @Override public boolean isKeepNoneAsElement() { return false; } @Override public boolean isKeepUnknownAsElement() { return true; } }; private int validationMode = XMLParser.NONVALIDATING; private Schema schema; private Object[] schemas; private EntityResolver entityResolver; private ErrorHandler errorHandler = DefaultErrorHandler.getInstance(); private SAXParser saxParser; private XMLReader xmlReader; private Unmarshaller xmlUnmarshaller; private XMLParser xmlParser; private boolean isResultAlwaysXMLRoot, isWhitespacePreserving; private SAXParserFactory saxParserFactory; private String systemId = null; private Map parserFeatures; private boolean disableSecureProcessing = false; private boolean shouldReset = true; private XMLPlatform xmlPLatform; public SAXUnmarshaller(Unmarshaller xmlUnmarshaller, Map parserFeatures) throws XMLMarshalException { super(); this.parserFeatures = parserFeatures; try { this.xmlUnmarshaller = xmlUnmarshaller; } catch (Exception e) { throw XMLMarshalException.errorInstantiatingSchemaPlatform(e); } } private SAXParserFactory getSAXParserFactory() throws XMLMarshalException { if (null == saxParserFactory || shouldReset) { try { saxParserFactory = XMLHelper.createParserFactory(isSecureProcessingDisabled());; saxParserFactory.setFeature(XMLReader.NAMESPACE_PREFIXES_FEATURE, true); try { saxParserFactory.setFeature(XMLReader.REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE_FEATURE, true); } catch (org.xml.sax.SAXNotRecognizedException ex) { // ignore if the parser doesn't recognize or support this feature } catch (org.xml.sax.SAXNotSupportedException ex) { } if (null != parserFeatures) { for (Map.Entry parserFeature : parserFeatures.entrySet()) { try { saxParserFactory.setFeature(parserFeature.getKey(), parserFeature.getValue()); } catch (org.xml.sax.SAXNotRecognizedException ex) { // ignore if the parser doesn't recognize or support this feature } catch (org.xml.sax.SAXNotSupportedException ex) { } } } return saxParserFactory; } catch (Exception e) { throw XMLMarshalException.errorInstantiatingSchemaPlatform(e); } } return saxParserFactory; } private SAXParser getSAXParser() { if (null == saxParser) { try { saxParser = getSAXParserFactory().newSAXParser(); } catch (Exception e) { throw XMLMarshalException.errorInstantiatingSchemaPlatform(e); } } return saxParser; } private XMLParser getXMLParser() { if (xmlParser == null || shouldReset) { XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform(); xmlPlatform.setDisableSecureProcessing(isSecureProcessingDisabled()); xmlParser = xmlPlatform.newXMLParser(); xmlParser.setNamespaceAware(true); if (null != errorHandler) { xmlParser.setErrorHandler(errorHandler); } if (null != entityResolver) { xmlParser.setEntityResolver(entityResolver); } xmlParser.setValidationMode(validationMode); xmlParser.setWhitespacePreserving(isWhitespacePreserving); shouldReset = false; } return xmlParser; } private XMLReader getXMLReader() { return getXMLReader(null); } private XMLReader getXMLReader(Class clazz) { if (null == xmlReader) { xmlReader = getNewXMLReader(clazz, xmlUnmarshaller.getMediaType()); } return xmlReader; } private XMLReader getNewXMLReader(MediaType mediaType) { return getNewXMLReader(null, mediaType); } private XMLReader getNewXMLReader(Class clazz, MediaType mediaType) { if (null != mediaType && mediaType.isApplicationJSON()) { return new JsonStructureReader(xmlUnmarshaller, clazz); } try { XMLReader xmlReader = new XMLReader(getSAXParser().getXMLReader()); if (null != errorHandler) { xmlReader.setErrorHandler(errorHandler); } if (null != entityResolver) { xmlReader.setEntityResolver(entityResolver); } setValidationMode(xmlReader, getValidationMode()); if (null != getSchema()) { xmlReader.setFeature(VALIDATING, xmlReader.getFeature(VALIDATING)); } return xmlReader; } catch (Exception e) { throw XMLMarshalException.errorInstantiatingSchemaPlatform(e); } } @Override public EntityResolver getEntityResolver() { return entityResolver; } @Override public void setEntityResolver(EntityResolver entityResolver) { if (null != xmlReader) { xmlReader.setEntityResolver(entityResolver); } if (null != xmlParser) { xmlParser.setEntityResolver(entityResolver); } this.entityResolver = entityResolver; } @Override public ErrorHandler getErrorHandler() { return errorHandler; } @Override public void setErrorHandler(ErrorHandler errorHandler) { if (null != xmlReader) { xmlReader.setErrorHandler(errorHandler); } if (null != xmlParser) { xmlParser.setErrorHandler(errorHandler); } this.errorHandler = errorHandler; } @Override public int getValidationMode() { return validationMode; } @Override public void setValidationMode(int validationMode) { setValidationMode(xmlReader, validationMode); } public void setValidationMode(XMLReader xmlReader, int validationMode) { try { this.validationMode = validationMode; if (null != xmlParser) { xmlParser.setValidationMode(validationMode); } if (null == xmlReader) { return; } switch (validationMode) { case XMLParser.NONVALIDATING: { xmlReader.setFeature(VALIDATING, false); break; } case XMLParser.DTD_VALIDATION: { xmlReader.setFeature(VALIDATING, true); XMLHelper.allowExternalDTDAccess(xmlReader, "all", false); break; } case XMLParser.SCHEMA_VALIDATION: { try { xmlReader.setFeature(VALIDATING, true); XMLHelper.allowExternalAccess(xmlReader, "all", false); saxParser.setProperty(SCHEMA_LANGUAGE, XML_SCHEMA); saxParser.setProperty(SCHEMA_SOURCE, schemas); } catch (Exception e) { xmlReader.setFeature(VALIDATING, false); } break; } } } catch (Exception e) { // Don't change the validation mode. } } @Override public void setWhitespacePreserving(boolean isWhitespacePreserving) { this.isWhitespacePreserving = isWhitespacePreserving; if (null != xmlParser) { xmlParser.setWhitespacePreserving(isWhitespacePreserving); } } @Override public void setSchemas(Object[] schemas) { this.schemas = schemas; } @Override public void setSchema(Schema schema) { this.schema = schema; if (null != xmlParser) { xmlParser.setXMLSchema(schema); } } @Override public Schema getSchema() { return schema; } @Override public Object unmarshal(File file) { try { if (xmlUnmarshaller.getContext().hasDocumentPreservation()) { Node domElement = getXMLParser().parse(file).getDocumentElement(); return unmarshal(domElement); } this.systemId = file.toURI().toURL().toExternalForm(); FileInputStream inputStream = new FileInputStream(file); try { return unmarshal(inputStream); } finally { inputStream.close(); } } catch (FileNotFoundException e) { throw XMLMarshalException.unmarshalException(e); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } @Override public Object unmarshal(File file, Class clazz) { try { if (xmlUnmarshaller.getContext().hasDocumentPreservation()) { Node domElement = getXMLParser().parse(file).getDocumentElement(); return unmarshal(domElement, clazz); } this.systemId = file.toURI().toURL().toExternalForm(); FileInputStream inputStream = new FileInputStream(file); try { return unmarshal(inputStream, clazz); } finally { inputStream.close(); } } catch (FileNotFoundException e) { throw XMLMarshalException.unmarshalException(e); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } @Override public Object unmarshal(InputStream inputStream) { if (xmlUnmarshaller.getContext().hasDocumentPreservation()) { Node domElement = getXMLParser().parse(inputStream).getDocumentElement(); return unmarshal(domElement); } InputSource inputSource = new InputSource(inputStream); return unmarshal(inputSource); } @Override public Object unmarshal(InputStream inputStream, Class clazz) { if (xmlUnmarshaller.getContext().hasDocumentPreservation()) { Node domElement = getXMLParser().parse(inputStream).getDocumentElement(); return unmarshal(domElement, clazz); } InputSource inputSource = new InputSource(inputStream); return unmarshal(inputSource, clazz); } @Override public Object unmarshal(InputSource inputSource) { if (inputSource != null && null == inputSource.getSystemId()) { inputSource.setSystemId(this.systemId); } if (xmlUnmarshaller.isAutoDetectMediaType()) { BufferedReader bufferedReader = getBufferedReaderForInputSource(inputSource); MediaType mediaType = getMediaType(bufferedReader); return unmarshal(getNewXMLReader(mediaType), new InputSource(bufferedReader)); } return unmarshal(getXMLReader(), inputSource); } public Object unmarshal(InputSource inputSource, XMLReader xmlReader) { try { if (inputSource != null && null == inputSource.getSystemId()) { inputSource.setSystemId(this.systemId); } SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); saxUnmarshallerHandler.setXMLReader(xmlReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); setContentHandler(xmlReader, saxUnmarshallerHandler); xmlReader.parse(inputSource); // resolve any mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } @Override public Object unmarshal(InputSource inputSource, Class clazz) { if (inputSource != null && null == inputSource.getSystemId()) { inputSource.setSystemId(this.systemId); } if (xmlUnmarshaller.isAutoDetectMediaType()) { BufferedReader bufferedReader = getBufferedReaderForInputSource(inputSource); MediaType mediaType = getMediaType(bufferedReader); return unmarshal(getNewXMLReader(clazz, mediaType), new InputSource(bufferedReader), clazz); } return unmarshal(getXMLReader(clazz), inputSource, clazz); } public Object unmarshal(InputSource inputSource, Class clazz, XMLReader xmlReader) { if (inputSource != null && null == inputSource.getSystemId()) { inputSource.setSystemId(this.systemId); } UnmarshalRecord unmarshalRecord = null; Descriptor xmlDescriptor = null; // for XMLObjectReferenceMappings we need a non-shared cache, so // try and get a Unit Of Work from the XMLContext CoreAbstractSession session = null; // check for case where the reference class is a primitive wrapper - in this case, we // need to use the conversion manager to convert the node's value to the primitive // wrapper class, then create, populate and return an XMLRoot. This will be done // via XMLRootRecord. boolean isPrimitiveWrapper = false; if (clazz == CoreClassConstants.OBJECT) { try { SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); saxUnmarshallerHandler.setXMLReader(xmlReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); saxUnmarshallerHandler.setKeepAsElementPolicy(KEEP_UNKNOWN_AS_ELEMENT); setContentHandler(xmlReader, saxUnmarshallerHandler); xmlReader.parse(inputSource); // resolve any mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } } else { // for XMLObjectReferenceMappings we need a non-shared cache, so // try and get a Unit Of Work from the XMLContext try { session = xmlUnmarshaller.getContext().getSession(clazz); xmlDescriptor = (Descriptor) session.getDescriptor(clazz); unmarshalRecord = xmlUnmarshaller.createUnmarshalRecord(xmlDescriptor, session); } catch (XMLMarshalException xme) { if (xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT) { isPrimitiveWrapper = isPrimitiveWrapper(clazz); if (isPrimitiveWrapper) { unmarshalRecord = xmlUnmarshaller.createRootUnmarshalRecord(clazz); } else { throw xme; } } else { throw xme; } } } try { unmarshalRecord.setXMLReader(xmlReader); unmarshalRecord.setUnmarshaller(xmlUnmarshaller); setContentHandler(xmlReader, unmarshalRecord); xmlReader.setLexicalHandler(unmarshalRecord); xmlReader.parse(inputSource); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } // resolve mapping references unmarshalRecord.resolveReferences(session, xmlUnmarshaller.getIDResolver()); if (isPrimitiveWrapper) { return unmarshalRecord.getCurrentObject(); } return xmlDescriptor.wrapObjectInXMLRoot(unmarshalRecord, this.isResultAlwaysXMLRoot); } @Override public Object unmarshal(Node node) { DOMReader reader = new DOMReader(xmlUnmarshaller); return unmarshal(reader, node); } public Object unmarshal(DOMReader reader, Node node) { try { SAXUnmarshallerHandler handler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); setContentHandler(reader, handler); handler.setXMLReader(reader); handler.setUnmarshaller(xmlUnmarshaller); reader.parse(node); handler.resolveReferences(); return handler.getObject(); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } @Override public Object unmarshal(Node node, Class clazz) { DOMReader reader = new DOMReader(xmlUnmarshaller); return unmarshal(reader, node, clazz); } public Object unmarshal(DOMReader domReader, Node node, Class clazz) { UnmarshalRecord unmarshalRecord = null; Descriptor xmlDescriptor = null; CoreAbstractSession session = null; // check for case where the reference class is a primitive wrapper - in this case, we // need to use the conversion manager to convert the node's value to the primitive // wrapper class, then create, populate and return an XMLRoot. This will be done // via XMLRootRecord. boolean isPrimitiveWrapper = false; if (clazz == CoreClassConstants.OBJECT) { SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); saxUnmarshallerHandler.setXMLReader(domReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); saxUnmarshallerHandler.setKeepAsElementPolicy(KEEP_UNKNOWN_AS_ELEMENT); setContentHandler(domReader, saxUnmarshallerHandler); try { domReader.parse(node); } catch (SAXException e) { throw convertSAXException(e); } // resolve any mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } else { // for XMLObjectReferenceMappings we need a non-shared cache, so // try and get a Unit Of Work from the XMLContext try { session = xmlUnmarshaller.getContext().getSession(clazz); xmlDescriptor = (Descriptor) session.getDescriptor(clazz); unmarshalRecord = xmlUnmarshaller.createUnmarshalRecord(xmlDescriptor, session); } catch (XMLMarshalException xme) { if (xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT) { isPrimitiveWrapper = isPrimitiveWrapper(clazz); if (isPrimitiveWrapper) { unmarshalRecord = xmlUnmarshaller.createRootUnmarshalRecord(clazz); } else if (Node.class.isAssignableFrom(clazz)) { return createXMLRootForNode(node); } else { throw xme; } } else { throw xme; } } } try { unmarshalRecord.setXMLReader(domReader); unmarshalRecord.setUnmarshaller(xmlUnmarshaller); setContentHandler(domReader, unmarshalRecord); domReader.setLexicalHandler(unmarshalRecord); domReader.parse(node); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } // resolve mapping references unmarshalRecord.resolveReferences(session, xmlUnmarshaller.getIDResolver()); if (isPrimitiveWrapper) { return unmarshalRecord.getCurrentObject(); } return xmlDescriptor.wrapObjectInXMLRoot(unmarshalRecord, this.isResultAlwaysXMLRoot); } private Object createXMLRootForNode(Node node) { Root xmlRoot = xmlUnmarshaller.createRoot(); xmlRoot.setObject(node); if (node != null) { xmlRoot.setLocalName(node.getLocalName()); xmlRoot.setNamespaceURI(node.getNamespaceURI()); } return xmlRoot; } @Override public Object unmarshal(Reader reader) { if (xmlUnmarshaller.getContext().hasDocumentPreservation()) { Node domElement = getXMLParser().parse(reader).getDocumentElement(); return unmarshal(domElement); } InputSource inputSource = new InputSource(reader); return unmarshal(inputSource); } @Override public Object unmarshal(Reader reader, Class clazz) { if (xmlUnmarshaller.getContext().hasDocumentPreservation()) { Node domElement = getXMLParser().parse(reader).getDocumentElement(); return unmarshal(domElement, clazz); } InputSource inputSource = new InputSource(reader); return unmarshal(inputSource, clazz); } @Override public Object unmarshal(Source source) { try { if (source instanceof SAXSource) { SAXSource saxSource = (SAXSource) source; XMLReader xmlReader = null; if (saxSource.getXMLReader() != null) { if (saxSource.getXMLReader() instanceof XMLReader) { xmlReader = (XMLReader) saxSource.getXMLReader(); } else { xmlReader = new XMLReader(saxSource.getXMLReader()); } setValidatorHandler(xmlReader); } if (null == xmlReader) { return unmarshal(saxSource.getInputSource()); } else { return unmarshal(saxSource.getInputSource(), xmlReader); } } else if (source instanceof DOMSource) { DOMSource domSource = (DOMSource) source; return unmarshal(domSource.getNode()); } else if (source instanceof StreamSource) { StreamSource streamSource = (StreamSource) source; if (null != streamSource.getReader()) { return unmarshal(streamSource.getReader()); } else if (null != streamSource.getInputStream()) { return unmarshal(streamSource.getInputStream()); } else { return unmarshal(streamSource.getSystemId()); } } else if (source instanceof ExtendedSource) { ExtendedSource extendedSource = (ExtendedSource) source; return unmarshal(null, extendedSource.createReader(xmlUnmarshaller)); } else { UnmarshallerHandler handler = this.xmlUnmarshaller.getUnmarshallerHandler(); XMLPlatform xmlPlat = XMLPlatformFactory.getInstance().getXMLPlatform(); xmlPlat.setDisableSecureProcessing(isSecureProcessingDisabled()); XMLTransformer transformer = xmlPLatform.newXMLTransformer(); SAXResult result = new SAXResult(handler); transformer.transform(source, result); return handler.getResult(); } } finally { xmlUnmarshaller.getStringBuffer().reset(); } } @Override public Object unmarshal(Source source, Class clazz) { if (source instanceof SAXSource) { SAXSource saxSource = (SAXSource) source; XMLReader xmlReader = null; if (saxSource.getXMLReader() != null) { if (saxSource.getXMLReader() instanceof XMLReader) { xmlReader = (XMLReader) saxSource.getXMLReader(); } else { xmlReader = new XMLReader(saxSource.getXMLReader()); } setValidatorHandler(xmlReader); } if (null == saxSource.getXMLReader()) { return unmarshal(saxSource.getInputSource(), clazz); } else { return unmarshal(saxSource.getInputSource(), clazz, xmlReader); } } else if (source instanceof DOMSource) { DOMSource domSource = (DOMSource) source; return unmarshal(domSource.getNode(), clazz); } else if (source instanceof StreamSource) { StreamSource streamSource = (StreamSource) source; if (null != streamSource.getReader()) { return unmarshal(streamSource.getReader(), clazz); } else if (null != streamSource.getInputStream()) { return unmarshal(streamSource.getInputStream(), clazz); } else { return unmarshal(streamSource.getSystemId(), clazz); } } else if (source instanceof ExtendedSource) { ExtendedSource extendedSource = (ExtendedSource) source; return unmarshal(null, clazz, extendedSource.createReader(xmlUnmarshaller, clazz)); } else { DOMResult result = new DOMResult(); XMLPlatform xmlPlat = XMLPlatformFactory.getInstance().getXMLPlatform(); xmlPlat.setDisableSecureProcessing(isSecureProcessingDisabled()); XMLTransformer transformer = xmlPLatform.newXMLTransformer(); transformer.transform(source, result); return unmarshal(result.getNode(), clazz); } } @Override public Object unmarshal(URL url) { InputStream inputStream = null; try { inputStream = url.openStream(); } catch (Exception e) { throw XMLMarshalException.unmarshalException(e); } this.systemId = url.toExternalForm(); boolean hasThrownException = false; try { return unmarshal(inputStream); } catch (RuntimeException runtimeException) { hasThrownException = true; throw runtimeException; } finally { xmlUnmarshaller.getStringBuffer().reset(); try { inputStream.close(); } catch (IOException e) { if (!hasThrownException) { throw XMLMarshalException.unmarshalException(e); } } } } @Override public Object unmarshal(URL url, Class clazz) { InputStream inputStream = null; try { inputStream = url.openStream(); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } this.systemId = url.toExternalForm(); try { return unmarshal(inputStream, clazz); } finally { xmlUnmarshaller.getStringBuffer().reset(); try { inputStream.close(); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } } } public Object unmarshal(String systemId) { try { if (xmlUnmarshaller.isAutoDetectMediaType()) { InputSource inputSource = new InputSource(systemId); return unmarshal(inputSource); } XMLReader xmlReader = getXMLReader(); SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); saxUnmarshallerHandler.setXMLReader(xmlReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); setContentHandler(xmlReader, saxUnmarshallerHandler); xmlReader.parse(systemId); // resolve mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } public Object unmarshal(String systemId, Class clazz) { if (xmlUnmarshaller.isAutoDetectMediaType()) { return unmarshal(new InputSource(systemId), clazz); } UnmarshalRecord unmarshalRecord = null; boolean isPrimitiveWrapper = false; Descriptor xmlDescriptor = null; CoreAbstractSession session = null; // check for case where the reference class is a primitive wrapper - in this case, we // need to use the conversion manager to convert the node's value to the primitive // wrapper class, then create, populate and return an XMLRoot. This will be done // via XMLRootRecord. if (clazz == CoreClassConstants.OBJECT) { SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); try { XMLReader xmlReader = getXMLReader(clazz); saxUnmarshallerHandler.setXMLReader(xmlReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); saxUnmarshallerHandler.setKeepAsElementPolicy(KEEP_UNKNOWN_AS_ELEMENT); setContentHandler(xmlReader, saxUnmarshallerHandler); xmlReader.parse(systemId); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } // resolve any mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } else { // for XMLObjectReferenceMappings we need a non-shared cache, so // try and get a Unit Of Work from the XMLContext try { session = xmlUnmarshaller.getContext().getSession(clazz); xmlDescriptor = (Descriptor) session.getDescriptor(clazz); unmarshalRecord = xmlUnmarshaller.createUnmarshalRecord(xmlDescriptor, session); } catch (XMLMarshalException xme) { if (xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT) { isPrimitiveWrapper = isPrimitiveWrapper(clazz); if (isPrimitiveWrapper) { unmarshalRecord = xmlUnmarshaller.createRootUnmarshalRecord(clazz); } else { throw xme; } } else { throw xme; } } } try { XMLReader xmlReader = getXMLReader(clazz); unmarshalRecord.setXMLReader(xmlReader); unmarshalRecord.setUnmarshaller(xmlUnmarshaller); setContentHandler(xmlReader, unmarshalRecord); xmlReader.setLexicalHandler(unmarshalRecord); xmlReader.parse(systemId); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } // resolve mapping references unmarshalRecord.resolveReferences(session, xmlUnmarshaller.getIDResolver()); if (isPrimitiveWrapper) { return unmarshalRecord.getCurrentObject(); } return xmlDescriptor.wrapObjectInXMLRoot(unmarshalRecord, this.isResultAlwaysXMLRoot); } @Override public Object unmarshal(org.xml.sax.XMLReader xmlReader, InputSource inputSource) { try { Context xmlContext = xmlUnmarshaller.getContext(); if (xmlContext.hasDocumentPreservation()) { SAXDocumentBuilder saxDocumentBuilder = new SAXDocumentBuilder(); xmlReader.setContentHandler(saxDocumentBuilder); xmlReader.parse(inputSource); return unmarshal(saxDocumentBuilder.getDocument().getDocumentElement()); } XMLReader extendedXMLReader; if (xmlReader instanceof XMLReader) { extendedXMLReader = (XMLReader) xmlReader; } else { extendedXMLReader = new XMLReader(xmlReader); } SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlContext); saxUnmarshallerHandler.setXMLReader(extendedXMLReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); setContentHandler(extendedXMLReader, saxUnmarshallerHandler); extendedXMLReader.parse(inputSource); // resolve any mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } @Override public Object unmarshal(org.xml.sax.XMLReader xmlReader, InputSource inputSource, Class clazz) { try { Context xmlContext = xmlUnmarshaller.getContext(); if (xmlContext.hasDocumentPreservation() || (Node.class.isAssignableFrom(clazz) && xmlUnmarshaller.isApplicationXML())) { SAXDocumentBuilder saxDocumentBuilder = new SAXDocumentBuilder(); xmlReader.setContentHandler(saxDocumentBuilder); xmlReader.parse(inputSource); return unmarshal(saxDocumentBuilder.getDocument().getDocumentElement(), clazz); } UnmarshalRecord unmarshalRecord = null; Descriptor xmlDescriptor = null; CoreAbstractSession session = null; boolean isPrimitiveWrapper = false; // check for case where the reference class is a primitive wrapper - in this case, we // need to use the conversion manager to convert the node's value to the primitive // wrapper class, then create, populate and return an XMLRoot. This will be done // via XMLRootRecord. if (clazz == CoreClassConstants.OBJECT) { SAXUnmarshallerHandler saxUnmarshallerHandler = new SAXUnmarshallerHandler(xmlUnmarshaller.getContext()); saxUnmarshallerHandler.setXMLReader((XMLReader) xmlReader); saxUnmarshallerHandler.setUnmarshaller(xmlUnmarshaller); saxUnmarshallerHandler.setKeepAsElementPolicy(KEEP_UNKNOWN_AS_ELEMENT); xmlReader.setContentHandler(saxUnmarshallerHandler); xmlReader.parse(inputSource); // resolve any mapping references saxUnmarshallerHandler.resolveReferences(); return saxUnmarshallerHandler.getObject(); } else { // for XMLObjectReferenceMappings we need a non-shared cache, so // try and get a Unit Of Work from the XMLContext try { session = xmlContext.getSession(clazz); xmlDescriptor = (Descriptor) session.getDescriptor(clazz); unmarshalRecord = xmlUnmarshaller.createUnmarshalRecord(xmlDescriptor, session); } catch (XMLMarshalException xme) { if (xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT) { isPrimitiveWrapper = isPrimitiveWrapper(clazz); if (isPrimitiveWrapper) { unmarshalRecord = xmlUnmarshaller.createRootUnmarshalRecord(clazz); } else { throw xme; } } else { throw xme; } } } XMLReader extendedXMLReader; if (xmlReader instanceof XMLReader) { extendedXMLReader = (XMLReader) xmlReader; } else { extendedXMLReader = new XMLReader(xmlReader); } unmarshalRecord.setXMLReader(extendedXMLReader); unmarshalRecord.setUnmarshaller(xmlUnmarshaller); setContentHandler(extendedXMLReader, unmarshalRecord); extendedXMLReader.setLexicalHandler(unmarshalRecord); extendedXMLReader.parse(inputSource); // resolve mapping references unmarshalRecord.resolveReferences(session, xmlUnmarshaller.getIDResolver()); if (isPrimitiveWrapper || clazz == CoreClassConstants.OBJECT) { return unmarshalRecord.getCurrentObject(); } return xmlDescriptor.wrapObjectInXMLRoot(unmarshalRecord, this.isResultAlwaysXMLRoot); } catch (IOException e) { throw XMLMarshalException.unmarshalException(e); } catch (SAXException e) { throw convertSAXException(e); } finally { xmlUnmarshaller.getStringBuffer().reset(); } } private EclipseLinkException convertSAXException(SAXException saxException) { Exception internalException = saxException.getException(); if (internalException != null) { if (EclipseLinkException.class.isAssignableFrom(internalException.getClass())) { return (EclipseLinkException) internalException; } else { return XMLMarshalException.unmarshalException(internalException); } } return XMLMarshalException.unmarshalException(saxException); } @Override public boolean isResultAlwaysXMLRoot() { return this.isResultAlwaysXMLRoot; } @Override public void setResultAlwaysXMLRoot(boolean alwaysReturnRoot) { this.isResultAlwaysXMLRoot = alwaysReturnRoot; } private boolean isPrimitiveWrapper(Class clazz) { return ((ConversionManager) xmlUnmarshaller.getContext().getSession().getDatasourcePlatform().getConversionManager()).schemaType(clazz) != null || CoreClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(clazz) || CoreClassConstants.DURATION.isAssignableFrom(clazz); } /** * If a Schema was set on the unmarshaller then wrap the ContentHandler in * a ValidatorHandler. */ private void setContentHandler(XMLReader xmlReader, ContentHandler contentHandler) { setValidatorHandler(xmlReader); xmlReader.setContentHandler(contentHandler); } private void setValidatorHandler(XMLReader xmlReader) { Schema schema = getSchema(); if (null != schema) { ValidatorHandler validatorHandler = schema.newValidatorHandler(); xmlReader.setValidatorHandler(validatorHandler); validatorHandler.setErrorHandler(getErrorHandler()); } } @Override public void mediaTypeChanged() { xmlReader = null; } private InputStream getInputStreamFromString(String stringValue) { if (stringValue.length() == 0) { throw org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalFromStringException(stringValue, null); } URL url = null; try { url = new URL(stringValue); if (url != null) { try { return url.openStream(); } catch (IOException e) { throw org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalFromStringException(stringValue, e); } } } catch (MalformedURLException ex) { try { return new FileInputStream(stringValue); } catch (FileNotFoundException e) { throw org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalFromStringException(stringValue, e); } } throw org.eclipse.persistence.exceptions.XMLMarshalException.unmarshalFromStringException(stringValue, null); } private BufferedReader getBufferedReaderForInputSource(InputSource inputSource) { if (inputSource.getByteStream() != null) { return new BufferedReader(new InputStreamReader(inputSource.getByteStream())); } else if (inputSource.getCharacterStream() != null) { return new BufferedReader(inputSource.getCharacterStream()); } else if (inputSource.getSystemId() != null) { InputStream is = getInputStreamFromString(inputSource.getSystemId()); return new BufferedReader(new InputStreamReader(is)); } throw XMLMarshalException.unmarshalException(); } private MediaType getMediaType(BufferedReader br) { int READ_AHEAD_LIMIT = 25; try { br.mark(READ_AHEAD_LIMIT); try { char c = 0; for (int i = 0; c != -1 && i < READ_AHEAD_LIMIT; i++) { c = (char) br.read(); if (c == '[' || c == '{') { return Constants.APPLICATION_JSON; } else if (c == '<') { return Constants.APPLICATION_XML; } } } finally { br.reset(); } } catch (IOException ioException) { throw XMLMarshalException.unmarshalException(ioException); } return xmlUnmarshaller.getMediaType(); } @Override public final boolean isSecureProcessingDisabled() { return disableSecureProcessing; } @Override public final void setDisableSecureProcessing(boolean disableSecureProcessing) { shouldReset = this.disableSecureProcessing ^ disableSecureProcessing; this.disableSecureProcessing = disableSecureProcessing; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy