/* * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.sun.org.apache.xerces.internal.jaxp.validation; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.validation.EntityState; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator; import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XMLString; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; import java.io.IOException; import java.util.Enumeration; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.Entity; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; import org.xml.sax.SAXException; /** *
A validator helper for DOMSource
s.
DOMResult
.
*/
private void setupDOMResultHandler(DOMSource source, DOMResult result) throws SAXException {
// If there's no DOMResult, unset the validator handler
if (result == null) {
fDOMValidatorHandler = null;
fSchemaValidator.setDocumentHandler(null);
return;
}
final Node nodeResult = result.getNode();
// If the source node and result node are the same use the DOMResultAugmentor.
// Otherwise use the DOMResultBuilder.
if (source.getNode() == nodeResult) {
fDOMValidatorHandler = fDOMResultAugmentor;
fDOMResultAugmentor.setDOMResult(result);
fSchemaValidator.setDocumentHandler(fDOMResultAugmentor);
return;
}
if (result.getNode() == null) {
try {
DocumentBuilderFactory factory = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ?
DocumentBuilderFactory.newInstance() : new DocumentBuilderFactoryImpl();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
result.setNode(builder.newDocument());
}
catch (ParserConfigurationException e) {
throw new SAXException(e);
}
}
fDOMValidatorHandler = fDOMResultBuilder;
fDOMResultBuilder.setDOMResult(result);
fSchemaValidator.setDocumentHandler(fDOMResultBuilder);
}
private void fillQName(QName toFill, Node node) {
final String prefix = node.getPrefix();
final String localName = node.getLocalName();
final String rawName = node.getNodeName();
final String namespace = node.getNamespaceURI();
toFill.uri = (namespace != null && namespace.length() > 0) ? fSymbolTable.addSymbol(namespace) : null;
toFill.rawname = (rawName != null) ? fSymbolTable.addSymbol(rawName) : XMLSymbols.EMPTY_STRING;
// Is this a DOM level1 document?
if (localName == null) {
int k = rawName.indexOf(':');
if (k > 0) {
toFill.prefix = fSymbolTable.addSymbol(rawName.substring(0, k));
toFill.localpart = fSymbolTable.addSymbol(rawName.substring(k + 1));
}
else {
toFill.prefix = XMLSymbols.EMPTY_STRING;
toFill.localpart = toFill.rawname;
}
}
else {
toFill.prefix = (prefix != null) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING;
toFill.localpart = (localName != null) ? fSymbolTable.addSymbol(localName) : XMLSymbols.EMPTY_STRING;
}
}
private void processAttributes(NamedNodeMap attrMap) {
final int attrCount = attrMap.getLength();
fAttributes.removeAllAttributes();
for (int i = 0; i < attrCount; ++i) {
Attr attr = (Attr) attrMap.item(i);
String value = attr.getValue();
if (value == null) {
value = XMLSymbols.EMPTY_STRING;
}
fillQName(fAttributeQName, attr);
// REVISIT: Assuming all attributes are of type CDATA. The actual type may not matter. -- mrglavas
fAttributes.addAttributeNS(fAttributeQName, XMLSymbols.fCDATASymbol, value);
fAttributes.setSpecified(i, attr.getSpecified());
// REVISIT: Should we be looking at non-namespace attributes
// for additional mappings? Should we detect illegal namespace
// declarations and exclude them from the context? -- mrglavas
if (fAttributeQName.uri == NamespaceContext.XMLNS_URI) {
// process namespace attribute
if (fAttributeQName.prefix == XMLSymbols.PREFIX_XMLNS) {
fNamespaceContext.declarePrefix(fAttributeQName.localpart, value.length() != 0 ? fSymbolTable.addSymbol(value) : null);
}
else {
fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value.length() != 0 ? fSymbolTable.addSymbol(value) : null);
}
}
}
}
private void sendCharactersToValidator(String str) {
if (str != null) {
final int length = str.length();
final int remainder = length & CHUNK_MASK;
if (remainder > 0) {
str.getChars(0, remainder, fCharBuffer, 0);
fTempString.setValues(fCharBuffer, 0, remainder);
fSchemaValidator.characters(fTempString, null);
}
int i = remainder;
while (i < length) {
str.getChars(i, i += CHUNK_SIZE, fCharBuffer, 0);
fTempString.setValues(fCharBuffer, 0, CHUNK_SIZE);
fSchemaValidator.characters(fTempString, null);
}
}
}
Node getCurrentElement() {
return fCurrentElement;
}
/**
* NamespaceContext for the DOMSource, includes context for ancestor nodes.
*/
final class DOMNamespaceContext implements NamespaceContext {
//
// Data
//
/**
* Namespace binding information. This array is composed of a
* series of tuples containing the namespace binding information:
* <prefix, uri>.
*/
protected String[] fNamespace = new String[16 * 2];
/** The size of the namespace information array. */
protected int fNamespaceSize = 0;
/**
* Flag indicating whether the namespace context
* has been from the root node's ancestors.
*/
protected boolean fDOMContextBuilt = false;
//
// Methods
//
public void pushContext() {
fNamespaceContext.pushContext();
}
public void popContext() {
fNamespaceContext.popContext();
}
public boolean declarePrefix(String prefix, String uri) {
return fNamespaceContext.declarePrefix(prefix, uri);
}
public String getURI(String prefix) {
String uri = fNamespaceContext.getURI(prefix);
if (uri == null) {
if (!fDOMContextBuilt) {
fillNamespaceContext();
fDOMContextBuilt = true;
}
if (fNamespaceSize > 0 &&
!fNamespaceContext.containsPrefix(prefix)) {
uri = getURI0(prefix);
}
}
return uri;
}
public String getPrefix(String uri) {
return fNamespaceContext.getPrefix(uri);
}
public int getDeclaredPrefixCount() {
return fNamespaceContext.getDeclaredPrefixCount();
}
public String getDeclaredPrefixAt(int index) {
return fNamespaceContext.getDeclaredPrefixAt(index);
}
public Enumeration