blob: 8274707ead26a040c449cea19412dd39dbdf9053 [file] [log] [blame]
/*
* Copyright (c) 2011, 2021 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:
// Blaise Doughan = 2.1 - Initial implementation
// Juan Pablo Gardella = 2.7.4 - Fix for the bug #543063
package org.eclipse.persistence.internal.oxm.record;
import javax.xml.validation.Schema;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
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.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.ext.LexicalHandler;
/**
* A common super class for all non SAX based XMLReaders.
*/
public abstract class XMLReaderAdapter extends XMLReader {
protected ExtendedContentHandler contentHandler;
private DTDHandler dtdHandler;
private EntityResolver entityResolver;
private ErrorHandler errorHandler;
protected LexicalHandler lexicalHandler;
protected XMLReaderAdapter() {
super();
}
protected XMLReaderAdapter(Unmarshaller xmlUnmarshaller) {
super();
if(null != xmlUnmarshaller) {
Schema schema = xmlUnmarshaller.getSchema();
if(null != schema) {
validatingContentHandler = new ValidatingContentHandler(schema.newValidatorHandler());
this.contentHandler = new ExtendedContentHandlerAdapter(validatingContentHandler);
}
setErrorHandler(xmlUnmarshaller.getErrorHandler());
}
}
@Override
public ExtendedContentHandler getContentHandler() {
return contentHandler;
}
@Override
public void setContentHandler(ContentHandler contentHandler) {
if(null == validatingContentHandler) {
if(contentHandler instanceof ExtendedContentHandler) {
this.contentHandler = (ExtendedContentHandler) contentHandler;
} else {
this.contentHandler = new ExtendedContentHandlerAdapter(contentHandler);
}
} else {
validatingContentHandler.setContentHandler(contentHandler);
}
}
@Override
public DTDHandler getDTDHandler() {
return dtdHandler;
}
@Override
public void setDTDHandler(DTDHandler dtdHandler) {
this.dtdHandler = dtdHandler;
}
@Override
public EntityResolver getEntityResolver() {
return entityResolver;
}
@Override
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
@Override
public ErrorHandler getErrorHandler() {
return errorHandler;
}
@Override
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
if(null != validatingContentHandler) {
validatingContentHandler.setErrorHandler(errorHandler);
}
}
@Override
public LexicalHandler getLexicalHandler() {
return lexicalHandler;
}
@Override
public void setLexicalHandler(LexicalHandler lexicalHandler) {
this.lexicalHandler = lexicalHandler;
}
@Override
public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
return false;
}
@Override
public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
}
@Override
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
if(Constants.LEXICAL_HANDLER_PROPERTY.equals(name)) {
return getLexicalHandler();
}
return null;
}
@Override
public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
if(Constants.LEXICAL_HANDLER_PROPERTY.equals(name)) {
setLexicalHandler((LexicalHandler) value);
}
}
@Override
public void parse(String systemId) {
}
/**
* Convert a ContentHandler to an ExtendedContentHandler
*/
public static class ExtendedContentHandlerAdapter implements ExtendedContentHandler {
private ContentHandler contentHandler;
public ExtendedContentHandlerAdapter(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
}
public ContentHandler getContentHandler() {
return contentHandler;
}
@Override
public void setDocumentLocator(Locator locator) {
contentHandler.setDocumentLocator(locator);
}
@Override
public void startDocument() throws SAXException {
contentHandler.startDocument();
}
@Override
public void endDocument() throws SAXException {
contentHandler.endDocument();
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
contentHandler.startPrefixMapping(prefix, uri);
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
contentHandler.endPrefixMapping(prefix);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
contentHandler.startElement(uri, localName, qName, atts);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
contentHandler.endElement(uri, localName, qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
contentHandler.characters(ch, start, length);
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
contentHandler.ignorableWhitespace(ch, start, length);
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
contentHandler.processingInstruction(target, data);
}
@Override
public void skippedEntity(String name) throws SAXException {
contentHandler.skippedEntity(name);
}
@Override
public void characters(CharSequence characters) throws SAXException {
if(null == characters) {
return;
}
contentHandler.characters(characters.toString().toCharArray(), 0, characters.length());
}
@Override
public void setNil(boolean isNil) {}
}
protected static abstract class IndexedAttributeList implements Attributes {
protected static final Attribute[] NO_ATTRIBUTES = new Attribute[0];
protected Attribute[] attributes;
protected abstract Attribute[] attributes();
@Override
public int getIndex(String qName) {
if(null == qName) {
return -1;
}
int index = 0;
for(Attribute attribute : attributes()) {
if(qName.equals(attribute.getName())) {
return index;
}
index++;
}
return -1;
}
@Override
public int getIndex(String uri, String localName) {
if(null == localName) {
return -1;
}
int index = 0;
for(Attribute attribute : attributes()) {
if(localName.equals(attribute.getLocalName()) && uri.equals(attribute.getUri())){
return index;
}
index++;
}
return -1;
}
@Override
public int getLength() {
return attributes().length;
}
@Override
public String getLocalName(int index) {
return attributes()[index].getLocalName();
}
@Override
public String getQName(int index) {
return attributes()[index].getName();
}
@Override
public String getType(int index) {
return Constants.CDATA;
}
@Override
public String getType(String name) {
return Constants.CDATA;
}
@Override
public String getType(String uri, String localName) {
return Constants.CDATA;
}
@Override
public String getURI(int index) {
return attributes()[index].getUri();
}
@Override
public String getValue(int index) {
return attributes()[index].getValue();
}
@Override
public String getValue(String qName) {
int index = getIndex(qName);
if(-1 == index) {
return null;
}
return attributes()[index].getValue();
}
@Override
public String getValue(String uri, String localName) {
int index = getIndex(uri, localName);
if(-1 == index) {
return null;
}
return attributes()[index].getValue();
}
public IndexedAttributeList reset() {
attributes = null;
return this;
}
}
protected static class Attribute {
private String localName;
private String uri;
private String name;
private String value;
public Attribute(String uri, String localName, String name, String value) {
this.localName = localName;
if(uri == null){
this.uri = Constants.EMPTY_STRING;
}else{
this.uri = uri;
}
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public String getValue() {
return value;
}
public String getLocalName() {
return localName;
}
public String getUri() {
return uri;
}
}
}