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

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

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.ext.LexicalHandler;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.validation.ValidatorHandler;

import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.MediaType;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;

/**
 * INTERNAL:
 * 

Purpose:Provide a wrapper for an org.xml.sax.XMLReader instance and define some extra * event methods that can be used by TopLink during the unmarshal process. These events are no ops * in this class, but may be overridden in subclasses. *

Responsibilities

    *
  • Wrap an instance of org.xml.sax.XMLReader and provide all the required API
  • *
  • Provide empty implementations of some callback methods that can be overridden in subclasses
  • * * @see org.eclipse.persistence.internal.oxm.record.DOMReader * @author mmacivor * @since release specific (what release of product did this appear in) */ public class XMLReader implements org.xml.sax.XMLReader { public static final String NAMESPACE_PREFIXES_FEATURE = "http://xml.org/sax/features/namespace-prefixes"; public static final String REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE_FEATURE = "http://java.sun.com/xml/schema/features/report-ignored-element-content-whitespace"; private org.xml.sax.XMLReader reader; private boolean supportsLexicalHandler; private LexicalHandlerWrapper lexicalHandlerWrapper; protected ValidatingContentHandler validatingContentHandler; private boolean namespaceAware; private char namespaceSeparator; protected Locator locator; public XMLReader(org.xml.sax.XMLReader internalReader) { this(); this.reader = internalReader; } public XMLReader() { this.supportsLexicalHandler = true; namespaceAware = true; namespaceSeparator = Constants.COLON; } /** * INTERNAL: * return the Locator object associated with this reader * @since 2.4 */ public Locator getLocator(){ return locator; } /** * INTERNAL: * set the Locator object to associate with this reader * @since 2.4 */ public void setLocator(Locator newLocator){ locator = newLocator; } public ContentHandler getContentHandler () { return reader.getContentHandler(); } public void setContentHandler (ContentHandler handler) { if(validatingContentHandler != null) { validatingContentHandler.setContentHandler(handler); } else { reader.setContentHandler(handler); } } /** * INTERNAL: * Determine if namespaces will be considered during marshal/unmarshal operations. * @since 2.4 */ public boolean isNamespaceAware() { return namespaceAware; } /** * If set to true, the reader will be aware of namespaces during marshal/unmarsal operations. * * @param namespaceAware if reader should be namespace aware * @since 2.6.0 */ public void setNamespaceAware(boolean namespaceAware) { this.namespaceAware = namespaceAware; } /** * INTERNAL: * The character used to separate the prefix and uri portions when namespaces are present * @since 2.4 */ public char getNamespaceSeparator(){ return namespaceSeparator; } /** * Sets namespace separator. * * @param namespaceSeparator namespace separator * @since 2.6.0 */ public void setNamespaceSeparator(char namespaceSeparator) { this.namespaceSeparator = namespaceSeparator; } /** * INTERNAL: * @return The MediaType associated with this reader */ public MediaType getMediaType(){ return Constants.APPLICATION_XML; } /** * INTERNAL: * @since 2.4 */ public Object convertValueBasedOnSchemaType(Field xmlField, Object value, ConversionManager conversionManager, AbstractUnmarshalRecord record) { return xmlField.convertValueBasedOnSchemaType(value, conversionManager, record); } public DTDHandler getDTDHandler () { return reader.getDTDHandler(); } public void setDTDHandler (DTDHandler handler) { reader.setDTDHandler(handler); } public void setEntityResolver (EntityResolver resolver) { reader.setEntityResolver(resolver); } public EntityResolver getEntityResolver () { return reader.getEntityResolver(); } public ErrorHandler getErrorHandler () { return reader.getErrorHandler(); } public void setErrorHandler (ErrorHandler handler) { if(validatingContentHandler != null) { validatingContentHandler.setErrorHandler(handler); } else { reader.setErrorHandler(handler); } } public LexicalHandler getLexicalHandler() { if(supportsLexicalHandler) { try { return (LexicalHandler) reader.getProperty(Constants.LEXICAL_HANDLER_PROPERTY); } catch (SAXException e) { supportsLexicalHandler = false; } } return null; } public void setLexicalHandler(LexicalHandler lexicalHandler) { if(supportsLexicalHandler) { if(null == lexicalHandlerWrapper) { try { lexicalHandlerWrapper = new LexicalHandlerWrapper(lexicalHandler); reader.setProperty(Constants.LEXICAL_HANDLER_PROPERTY, lexicalHandlerWrapper); } catch (SAXException e) { supportsLexicalHandler = false; } } else { lexicalHandlerWrapper.setLexicalHandler(lexicalHandler); } } } public boolean getFeature (String name) throws SAXNotRecognizedException, SAXNotSupportedException { return reader.getFeature(name); } public void setFeature (String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { reader.setFeature(name, value); } public Object getProperty (String name) throws SAXNotRecognizedException, SAXNotSupportedException { if(Constants.LEXICAL_HANDLER_PROPERTY.equals(name)) { return getLexicalHandler(); } else { return reader.getProperty(name); } } public void setProperty (String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException { if(Constants.LEXICAL_HANDLER_PROPERTY.equals(name)) { setLexicalHandler((LexicalHandler) value); } else { reader.setProperty(name, value); } } public void parse(InputSource input) throws IOException, SAXException { try { reader.parse(input); } catch(SAXNotSupportedException e) { String message = e.getMessage(); if(message != null && message.contains("namespace-prefix")) { reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false); reader.parse(input); } else { throw e; } } } public void parse (String systemId) throws IOException, SAXException { try { reader.parse(systemId); } catch(SAXNotSupportedException e) { String message = e.getMessage(); if(message != null && message.contains("namespace-prefix")) { reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false); reader.parse(systemId); } else { throw e; } } } public void setValidatorHandler(ValidatorHandler validatorHandler) { ErrorHandler errorHandler = getErrorHandler(); ContentHandler contentHandler; if(null == this.validatingContentHandler) { contentHandler = getContentHandler(); } else { contentHandler = validatorHandler.getContentHandler(); this.validatingContentHandler = null; } ValidatingContentHandler validatingContentHandler = null; if(null != validatorHandler) { validatingContentHandler = new ValidatingContentHandler(validatorHandler); validatingContentHandler.setContentHandler(contentHandler); contentHandler = validatingContentHandler; } if(null != reader) { reader.setContentHandler(contentHandler); } setContentHandler(contentHandler); this.validatingContentHandler = validatingContentHandler; setErrorHandler(errorHandler); } public ValidatorHandler getValidatorHandler() { if(null == validatingContentHandler) { return null; } return this.validatingContentHandler.getValidatorHandler(); } public void newObjectEvent(Object object, Object parent, Mapping selfRecordMapping) { //no op in this class. } public Object getCurrentObject(CoreAbstractSession session, Mapping selfRecordMapping) { return null; } /** * This call back mechanism provides an opportunity for the XMLReader to * provide an alternate conversion. This optimization is currently only * leveraged for properties annotated with @XmlInlineBinaryData. * @param characters The characters to be converted. * @param dataType The type to be converted to. * @return The converted value */ public Object getValue(CharSequence characters, Class dataType) { return null; } public boolean isNullRepresentedByXsiNil(AbstractNullPolicy nullPolicy){ return nullPolicy.isNullRepresentedByXsiNil(); } public boolean isNullRecord(AbstractNullPolicy nullPolicy, Attributes atts, UnmarshalRecord record) { boolean isNil = isNullRepresentedByXsiNil(nullPolicy) && record.isNil(); if (!nullPolicy.ignoreAttributesForNil()) { return isNil && !hasAttributes(atts); } return isNil; } private boolean hasAttributes(Attributes attributes) { QName nilAttrName = new QName(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_NIL_ATTRIBUTE); for (int i = 0; i < attributes.getLength(); i++) { if (!(nilAttrName.getNamespaceURI().equals(attributes.getURI(i)) && nilAttrName.getLocalPart().equals(attributes.getLocalName(i))) && !XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(attributes.getURI(i))) { return true; } } return false; } public boolean isInCollection(){ return true; } /** * Performance Optimization: * It is expensive to change the LexicalHandler on the underlying XMLReader * constantly through the setProperty(String, Object) mechanism. So instead * the LexicalHandlerWrapper is set once this way, and the "real" * LexicalHandler is changed on the LexicalHandlerWrapper. */ private static class LexicalHandlerWrapper implements LexicalHandler { private LexicalHandler lexicalHandler; public LexicalHandlerWrapper(LexicalHandler lexicalHandler) { this.lexicalHandler = lexicalHandler; } public void setLexicalHandler(LexicalHandler lexicalHandler) { this.lexicalHandler = lexicalHandler; } public void comment(char[] ch, int start, int length) throws SAXException { if(null != lexicalHandler) { lexicalHandler.comment(ch, start, length); } } public void endCDATA() throws SAXException { if(null != lexicalHandler) { lexicalHandler.endCDATA(); } } public void endDTD() throws SAXException { if(null != lexicalHandler) { lexicalHandler.endDTD(); } } public void endEntity(String name) throws SAXException { if(null != lexicalHandler) { lexicalHandler.endEntity(name); } } public void startCDATA() throws SAXException { if(null != lexicalHandler) { lexicalHandler.startCDATA(); } } public void startDTD(String name, String publicId, String systemId) throws SAXException { if(null != lexicalHandler) { lexicalHandler.startCDATA(); } } public void startEntity(String name) throws SAXException { if(null != lexicalHandler) { lexicalHandler.startEntity(name); } } } /** * Validate the SAX events reported to the ContentHandler. This class is * being used rather than a ValidatorHandler in order to prevent default * values from being populated. */ protected static class ValidatingContentHandler implements ContentHandler { private ValidatorHandler validatorHandler; private ContentHandler contentHandler; public ValidatingContentHandler(ValidatorHandler validatorHandler) { this.validatorHandler = validatorHandler; } public ContentHandler getContentHandler() { return contentHandler; } public void setContentHandler(ContentHandler contentHandler) { this.contentHandler = contentHandler; } public void setErrorHandler(ErrorHandler errorHandler) { validatorHandler.setErrorHandler(errorHandler); } public ValidatorHandler getValidatorHandler() { return validatorHandler; } public void setValidatorHandler(ValidatorHandler validatorHandler) { this.validatorHandler = validatorHandler; } public void setDocumentLocator(Locator locator) { validatorHandler.setDocumentLocator(locator); contentHandler.setDocumentLocator(locator); } public void startDocument() throws SAXException { validatorHandler.startDocument(); contentHandler.startDocument(); } public void endDocument() throws SAXException { validatorHandler.endDocument(); contentHandler.endDocument(); } public void startPrefixMapping(String prefix, String uri) throws SAXException { validatorHandler.startPrefixMapping(prefix, uri); contentHandler.startPrefixMapping(prefix, uri); } public void endPrefixMapping(String prefix) throws SAXException { validatorHandler.endPrefixMapping(prefix); contentHandler.endPrefixMapping(prefix); } public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { validatorHandler.startElement(uri, localName, qName, atts); contentHandler.startElement(uri, localName, qName, atts); } public void endElement(String uri, String localName, String qName) throws SAXException { validatorHandler.endElement(uri, localName, qName); contentHandler.endElement(uri, localName, qName); } public void characters(char[] ch, int start, int length) throws SAXException { validatorHandler.characters(ch, start, length); contentHandler.characters(ch, start, length); } public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { validatorHandler.ignorableWhitespace(ch, start, length); contentHandler.characters(ch, start, length); } public void processingInstruction(String target, String data) throws SAXException { validatorHandler.processingInstruction(target, data); contentHandler.processingInstruction(target, data); } public void skippedEntity(String name) throws SAXException { validatorHandler.skippedEntity(name); contentHandler.skippedEntity(name); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy