diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java index 33823e22e5f09cb688f8bd240465b18b4a0cd35b..5894424ed6fac52b67d29348ac7c6862682cc4a6 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -110,6 +110,7 @@ import org.w3c.dom.Text; * @author Joe Kesselman, IBM * @author Andy Clark, IBM * @since PR-DOM-Level-1-19980818. + * @LastModified: Apr 2019 * */ public class AttrImpl @@ -140,8 +141,6 @@ public class AttrImpl // REVISIT: we are losing the type information in DOM during serialization transient Object type; - protected TextImpl textNode = null; - // // Constructors // @@ -192,14 +191,14 @@ public class AttrImpl * NON-DOM * set the ownerDocument of this node and its children */ - void setOwnerDocument(CoreDocumentImpl doc) { + protected void setOwnerDocument(CoreDocumentImpl doc) { if (needsSyncChildren()) { synchronizeChildren(); } super.setOwnerDocument(doc); if (!hasStringValue()) { for (ChildNode child = (ChildNode) value; - child != null; child = child.nextSibling) { + child != null; child = child.nextSibling) { child.setOwnerDocument(doc); } } @@ -349,6 +348,8 @@ public class AttrImpl Element ownerElement = getOwnerElement(); String oldvalue = ""; + TextImpl textNode = null; + if (needsSyncData()) { synchronizeData(); } @@ -363,13 +364,7 @@ public class AttrImpl oldvalue = (String) value; // create an actual text node as our child so // that we can use it in the event - if (textNode == null) { - textNode = (TextImpl) - ownerDocument.createTextNode((String) value); - } - else { - textNode.data = (String) value; - } + textNode = (TextImpl) ownerDocument.createTextNode((String) value); value = textNode; textNode.isFirstChild(true); textNode.previousSibling = textNode; @@ -414,9 +409,16 @@ public class AttrImpl // since we need to combine the remove and insert. isSpecified(true); if (ownerDocument.getMutationEvents()) { - // if there are any event handlers create a real node - internalInsertBefore(ownerDocument.createTextNode(newvalue), - null, true); + // if there are any event handlers create a real node or + // reuse the one we synthesized for the remove notifications + // if it exists. + if (textNode == null) { + textNode = (TextImpl) ownerDocument.createTextNode(newvalue); + } + else { + textNode.data = newvalue; + } + internalInsertBefore(textNode, null, true); hasStringValue(false); // notify document ownerDocument.modifiedAttrValue(this, oldvalue); @@ -1034,7 +1036,7 @@ public class AttrImpl * NodeList method: Return the Nth immediate child of this node, or * null if the index is out of bounds. * @return org.w3c.dom.Node - * @param Index int + * @param index int */ public Node item(int index) { @@ -1076,12 +1078,12 @@ public class AttrImpl * Checks if a type is derived from another by restriction. See: * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom * - * @param ancestorNS + * @param typeNamespaceArg * The namspace of the ancestor type declaration - * @param ancestorName + * @param typeNameArg * The name of the ancestor type declaration - * @param type - * The reference type definition + * @param derivationMethod + * The derivation method * * @return boolean True if the type is derived by restriciton for the * reference type diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java index 0eba0744c27fe15b70a8a2bfad2be73b908ef34c..09a5355072b9e000eee639d4ceeb289731aa5546 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/AttrNSImpl.java @@ -147,30 +147,6 @@ public class AttrNSImpl setName(namespaceURI, qualifiedName); } - /** - * NON-DOM: resets this node and sets specified values for the node - * - * @param ownerDocument - * @param namespaceURI - * @param qualifiedName - * @param localName - */ - public void setValues (CoreDocumentImpl ownerDocument, - String namespaceURI, - String qualifiedName, - String localName){ - - super.textNode = null; - super.flags = 0; - isSpecified(true); - hasStringValue(true); - super.setOwnerDocument(ownerDocument); - this.localName = localName; - this.namespaceURI = namespaceURI; - super.name = qualifiedName; - super.value = null; - } - // // DOM2: Namespace methods // @@ -314,14 +290,14 @@ public class AttrNSImpl * Checks if a type is derived from another by restriction. See: * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom * - * @param ancestorNS + * @param typeNamespaceArg * The namspace of the ancestor type declaration - * @param ancestorName + * @param typeNameArg * The name of the ancestor type declaration - * @param type - * The reference type definition + * @param derivationMethod + * The derivation method * - * @return boolean True if the type is derived by restriciton for the + * @return boolean True if the type is derived by restriction for the * reference type */ public boolean isDerivedFrom(String typeNamespaceArg, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java index c8c2f3e2f8343659c37d3b66f7d192353598183c..cb2f609d562add7d3790b7ae7da57b0c5364049d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ChildNode.java @@ -40,8 +40,6 @@ public abstract class ChildNode /** Serialization version. */ static final long serialVersionUID = -6112455738802414002L; - transient StringBuffer fBufferStr = null; - // // Data // diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java index b3c6a360fd8db87b58e8a2768e8f946fc0002191..130b169a8de04b2cb3d608499bee3fe38c5e4733 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDOMImplementationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,11 +20,18 @@ package com.sun.org.apache.xerces.internal.dom; import com.sun.org.apache.xerces.internal.impl.RevalidationHandler; +import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDProcessor; +import com.sun.org.apache.xerces.internal.impl.dtd.XML11DTDValidator; +import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader; +import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator; +import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.parsers.DOMParserImpl; import com.sun.org.apache.xerces.internal.parsers.DTDConfiguration; import com.sun.org.apache.xerces.internal.parsers.XIncludeAwareParserConfiguration; +import com.sun.org.apache.xerces.internal.parsers.XML11DTDConfiguration; import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; +import java.lang.ref.SoftReference; import org.w3c.dom.DOMException; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; @@ -51,21 +58,39 @@ import org.w3c.dom.ls.LSSerializer; * @xerces.internal * * @since PR-DOM-Level-1-19980818. + * @LastModified: Apr 2019 */ +@SuppressWarnings({"rawtypes", "unchecked"}) //SoftReference array public class CoreDOMImplementationImpl implements DOMImplementation, DOMImplementationLS { - // - // Data - // - // validators pool + // + // Data + // + + // validator pools private static final int SIZE = 2; - private RevalidationHandler validators[] = new RevalidationHandler[SIZE]; - private RevalidationHandler dtdValidators[] = new RevalidationHandler[SIZE]; - private int freeValidatorIndex = -1; - private int freeDTDValidatorIndex = -1; - private int currentSize = SIZE; + private SoftReference schemaValidators[] = new SoftReference[SIZE]; + private SoftReference xml10DTDValidators[] = new SoftReference[SIZE]; + private SoftReference xml11DTDValidators[] = new SoftReference[SIZE]; + + private int freeSchemaValidatorIndex = -1; + private int freeXML10DTDValidatorIndex = -1; + private int freeXML11DTDValidatorIndex = -1; + + private int schemaValidatorsCurrentSize = SIZE; + private int xml10DTDValidatorsCurrentSize = SIZE; + private int xml11DTDValidatorsCurrentSize = SIZE; + + private SoftReference xml10DTDLoaders[] = new SoftReference[SIZE]; + private SoftReference xml11DTDLoaders[] = new SoftReference[SIZE]; + + private int freeXML10DTDLoaderIndex = -1; + private int freeXML11DTDLoaderIndex = -1; + + private int xml10DTDLoaderCurrentSize = SIZE; + private int xml11DTDLoaderCurrentSize = SIZE; // Document and doctype counter. Used to assign order to documents and // doctypes without owners, on an demand basis. Used for @@ -74,8 +99,8 @@ public class CoreDOMImplementationImpl // static /** Dom implementation singleton. */ - static CoreDOMImplementationImpl singleton = - new CoreDOMImplementationImpl(); + static final CoreDOMImplementationImpl singleton = new CoreDOMImplementationImpl(); + // // Public methods // @@ -109,21 +134,25 @@ public class CoreDOMImplementationImpl feature = feature.substring(1); } return (feature.equalsIgnoreCase("Core") - && (anyVersion - || version.equals("1.0") - || version.equals("2.0") - || version.equals("3.0"))) - || (feature.equalsIgnoreCase("XML") - && (anyVersion - || version.equals("1.0") - || version.equals("2.0") - || version.equals("3.0"))) - || (feature.equalsIgnoreCase("LS") - && (anyVersion - || version.equals("3.0"))) - || (feature.equalsIgnoreCase("ElementTraversal") - && (anyVersion - || version.equals("1.0"))); + && (anyVersion + || version.equals("1.0") + || version.equals("2.0") + || version.equals("3.0"))) + || (feature.equalsIgnoreCase("XML") + && (anyVersion + || version.equals("1.0") + || version.equals("2.0") + || version.equals("3.0"))) + || (feature.equalsIgnoreCase("XMLVersion") + && (anyVersion + || version.equals("1.0") + || version.equals("1.1"))) + || (feature.equalsIgnoreCase("LS") + && (anyVersion + || version.equals("3.0"))) + || (feature.equalsIgnoreCase("ElementTraversal") + && (anyVersion + || version.equals("1.0"))); } // hasFeature(String,String):boolean @@ -244,19 +273,26 @@ public class CoreDOMImplementationImpl null); throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg); } - CoreDocumentImpl doc = new CoreDocumentImpl(doctype); - Element e = doc.createElementNS(namespaceURI, qualifiedName); - doc.appendChild(e); + CoreDocumentImpl doc = createDocument(doctype); + // If namespaceURI and qualifiedName are null return a Document with no document element. + if (qualifiedName != null || namespaceURI != null) { + Element e = doc.createElementNS(namespaceURI, qualifiedName); + doc.appendChild(e); + } return doc; } + protected CoreDocumentImpl createDocument(DocumentType doctype) { + return new CoreDocumentImpl(doctype); + } + /** * DOM Level 3 WD - Experimental. */ public Object getFeature(String feature, String version) { if (singleton.hasFeature(feature, version)) { - return singleton; - } + return singleton; + } return null; } @@ -304,7 +340,7 @@ public class CoreDOMImplementationImpl * NOT_SUPPORTED_ERR: Raised if the requested mode or schema type is * not supported. */ - public LSParser createLSParser(short mode, String schemaType) + public LSParser createLSParser(short mode, String schemaType) throws DOMException { if (mode != DOMImplementationLS.MODE_SYNCHRONOUS || (schemaType !=null && !"http://www.w3.org/2001/XMLSchema".equals(schemaType) && @@ -318,7 +354,7 @@ public class CoreDOMImplementationImpl } if (schemaType != null && schemaType.equals("http://www.w3.org/TR/REC-xml")) { - return new DOMParserImpl(new DTDConfiguration(), + return new DOMParserImpl(new XML11DTDConfiguration(), schemaType); } else { @@ -328,20 +364,20 @@ public class CoreDOMImplementationImpl } } - /** - * DOM Level 3 LS CR - Experimental. - * Create a new LSSerializer object. - * @return The newly created LSSerializer object. - *

Note: By default, the newly created - * LSSerializer has no DOMErrorHandler, - * i.e. the value of the "error-handler" configuration - * parameter is null. However, implementations may - * provide a default error handler at creation time. In that case, the - * initial value of the "error-handler" configuration - * parameter on the new created LSSerializer contains a - * reference to the default error handler. - */ - public LSSerializer createLSSerializer() { + /** + * DOM Level 3 LS CR - Experimental. + * Create a new LSSerializer object. + * @return The newly created LSSerializer object. + *

Note: By default, the newly created + * LSSerializer has no DOMErrorHandler, + * i.e. the value of the "error-handler" configuration + * parameter is null. However, implementations may + * provide a default error handler at creation time. In that case, the + * initial value of the "error-handler" configuration + * parameter on the new created LSSerializer contains a + * reference to the default error handler. + */ + public LSSerializer createLSSerializer() { return new com.sun.org.apache.xml.internal.serializer.dom3.LSSerializerImpl(); } @@ -358,68 +394,217 @@ public class CoreDOMImplementationImpl // Protected methods // /** NON-DOM: retrieve validator. */ - synchronized RevalidationHandler getValidator(String schemaType) { - // REVISIT: implement retrieving DTD validator + synchronized RevalidationHandler getValidator(String schemaType, String xmlVersion) { if (schemaType == XMLGrammarDescription.XML_SCHEMA) { // create new validator - we should not attempt // to restrict the number of validation handlers being // requested - if(freeValidatorIndex < 0) { - return new com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator(); + while (freeSchemaValidatorIndex >= 0) { + // return first available validator + SoftReference ref = schemaValidators[freeSchemaValidatorIndex]; + RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get(); + if (holder != null && holder.handler != null) { + RevalidationHandler val = holder.handler; + holder.handler = null; + --freeSchemaValidatorIndex; + return val; + } + schemaValidators[freeSchemaValidatorIndex--] = null; } - // return first available validator - RevalidationHandler val = validators[freeValidatorIndex]; - validators[freeValidatorIndex--] = null; - return val; + return new XMLSchemaValidator(); } else if(schemaType == XMLGrammarDescription.XML_DTD) { - if(freeDTDValidatorIndex < 0) { - return new com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator(); + // return an instance of XML11DTDValidator + if ("1.1".equals(xmlVersion)) { + while (freeXML11DTDValidatorIndex >= 0) { + // return first available validator + SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex]; + RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get(); + if (holder != null && holder.handler != null) { + RevalidationHandler val = holder.handler; + holder.handler = null; + --freeXML11DTDValidatorIndex; + return val; + } + xml11DTDValidators[freeXML11DTDValidatorIndex--] = null; + } + return new XML11DTDValidator(); + } + // return an instance of XMLDTDValidator + else { + while (freeXML10DTDValidatorIndex >= 0) { + // return first available validator + SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex]; + RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get(); + if (holder != null && holder.handler != null) { + RevalidationHandler val = holder.handler; + holder.handler = null; + --freeXML10DTDValidatorIndex; + return val; + } + xml10DTDValidators[freeXML10DTDValidatorIndex--] = null; + } + return new XMLDTDValidator(); } - // return first available validator - RevalidationHandler val = dtdValidators[freeDTDValidatorIndex]; - dtdValidators[freeDTDValidatorIndex--] = null; - return val; } return null; } /** NON-DOM: release validator */ - synchronized void releaseValidator(String schemaType, - RevalidationHandler validator) { - // REVISIT: implement support for DTD validators as well - if(schemaType == XMLGrammarDescription.XML_SCHEMA) { - ++freeValidatorIndex; - if (validators.length == freeValidatorIndex ){ - // resize size of the validators - currentSize+=SIZE; - RevalidationHandler newarray[] = new RevalidationHandler[currentSize]; - System.arraycopy(validators, 0, newarray, 0, validators.length); - validators = newarray; - } - validators[freeValidatorIndex]=validator; - } - else if(schemaType == XMLGrammarDescription.XML_DTD) { - ++freeDTDValidatorIndex; - if (dtdValidators.length == freeDTDValidatorIndex ){ - // resize size of the validators - currentSize+=SIZE; - RevalidationHandler newarray[] = new RevalidationHandler[currentSize]; - System.arraycopy(dtdValidators, 0, newarray, 0, dtdValidators.length); - dtdValidators = newarray; - } - dtdValidators[freeDTDValidatorIndex]=validator; - } + synchronized void releaseValidator(String schemaType, String xmlVersion, + RevalidationHandler validator) { + if (schemaType == XMLGrammarDescription.XML_SCHEMA) { + ++freeSchemaValidatorIndex; + if (schemaValidators.length == freeSchemaValidatorIndex) { + // resize size of the validators + schemaValidatorsCurrentSize += SIZE; + SoftReference newarray[] = new SoftReference[schemaValidatorsCurrentSize]; + System.arraycopy(schemaValidators, 0, newarray, 0, schemaValidators.length); + schemaValidators = newarray; + } + SoftReference ref = schemaValidators[freeSchemaValidatorIndex]; + if (ref != null) { + RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get(); + if (holder != null) { + holder.handler = validator; + return; + } + } + schemaValidators[freeSchemaValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator)); + } + else if (schemaType == XMLGrammarDescription.XML_DTD) { + // release an instance of XML11DTDValidator + if ("1.1".equals(xmlVersion)) { + ++freeXML11DTDValidatorIndex; + if (xml11DTDValidators.length == freeXML11DTDValidatorIndex) { + // resize size of the validators + xml11DTDValidatorsCurrentSize += SIZE; + SoftReference [] newarray = new SoftReference[xml11DTDValidatorsCurrentSize]; + System.arraycopy(xml11DTDValidators, 0, newarray, 0, xml11DTDValidators.length); + xml11DTDValidators = newarray; + } + SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex]; + if (ref != null) { + RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get(); + if (holder != null) { + holder.handler = validator; + return; + } + } + xml11DTDValidators[freeXML11DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator)); + } + // release an instance of XMLDTDValidator + else { + ++freeXML10DTDValidatorIndex; + if (xml10DTDValidators.length == freeXML10DTDValidatorIndex) { + // resize size of the validators + xml10DTDValidatorsCurrentSize += SIZE; + SoftReference [] newarray = new SoftReference[xml10DTDValidatorsCurrentSize]; + System.arraycopy(xml10DTDValidators, 0, newarray, 0, xml10DTDValidators.length); + xml10DTDValidators = newarray; + } + SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex]; + if (ref != null) { + RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get(); + if (holder != null) { + holder.handler = validator; + return; + } + } + xml10DTDValidators[freeXML10DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator)); + } + } } - /** NON-DOM: increment document/doctype counter */ - protected synchronized int assignDocumentNumber() { - return ++docAndDoctypeCounter; - } - /** NON-DOM: increment document/doctype counter */ - protected synchronized int assignDocTypeNumber() { - return ++docAndDoctypeCounter; - } + /** NON-DOM: retrieve DTD loader */ + synchronized final XMLDTDLoader getDTDLoader(String xmlVersion) { + // return an instance of XML11DTDProcessor + if ("1.1".equals(xmlVersion)) { + while (freeXML11DTDLoaderIndex >= 0) { + // return first available DTD loader + SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex]; + XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get(); + if (holder != null && holder.loader != null) { + XMLDTDLoader val = holder.loader; + holder.loader = null; + --freeXML11DTDLoaderIndex; + return val; + } + xml11DTDLoaders[freeXML11DTDLoaderIndex--] = null; + } + return new XML11DTDProcessor(); + } + // return an instance of XMLDTDLoader + else { + while (freeXML10DTDLoaderIndex >= 0) { + // return first available DTD loader + SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex]; + XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get(); + if (holder != null && holder.loader != null) { + XMLDTDLoader val = holder.loader; + holder.loader = null; + --freeXML10DTDLoaderIndex; + return val; + } + xml10DTDLoaders[freeXML10DTDLoaderIndex--] = null; + } + return new XMLDTDLoader(); + } + } + + /** NON-DOM: release DTD loader */ + synchronized final void releaseDTDLoader(String xmlVersion, XMLDTDLoader loader) { + // release an instance of XMLDTDLoader + if ("1.1".equals(xmlVersion)) { + ++freeXML11DTDLoaderIndex; + if (xml11DTDLoaders.length == freeXML11DTDLoaderIndex) { + // resize size of the DTD loaders + xml11DTDLoaderCurrentSize += SIZE; + SoftReference [] newarray = new SoftReference[xml11DTDLoaderCurrentSize]; + System.arraycopy(xml11DTDLoaders, 0, newarray, 0, xml11DTDLoaders.length); + xml11DTDLoaders = newarray; + } + SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex]; + if (ref != null) { + XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get(); + if (holder != null) { + holder.loader = loader; + return; + } + } + xml11DTDLoaders[freeXML11DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader)); + } + // release an instance of XMLDTDLoader + else { + ++freeXML10DTDLoaderIndex; + if (xml10DTDLoaders.length == freeXML10DTDLoaderIndex) { + // resize size of the DTD loaders + xml10DTDLoaderCurrentSize += SIZE; + SoftReference [] newarray = new SoftReference[xml10DTDLoaderCurrentSize]; + System.arraycopy(xml10DTDLoaders, 0, newarray, 0, xml10DTDLoaders.length); + xml10DTDLoaders = newarray; + } + SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex]; + if (ref != null) { + XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get(); + if (holder != null) { + holder.loader = loader; + return; + } + } + xml10DTDLoaders[freeXML10DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader)); + } + } + + /** NON-DOM: increment document/doctype counter */ + protected synchronized int assignDocumentNumber() { + return ++docAndDoctypeCounter; + } + + /** NON-DOM: increment document/doctype counter */ + protected synchronized int assignDocTypeNumber() { + return ++docAndDoctypeCounter; + } /* DOM Level 3 LS CR - Experimental. * @@ -427,11 +612,33 @@ public class CoreDOMImplementationImpl * LSOutput.characterStream, * LSOutput.byteStream, LSOutput.systemId, * LSOutput.encoding are null. - * @return The newly created output object. + */ + public LSOutput createLSOutput() { + return new DOMOutputImpl(); + } + + /** + * A holder for RevalidationHandlers. This allows us to reuse + * SoftReferences which haven't yet been cleared by the garbage + * collector. */ - public LSOutput createLSOutput() { - return new DOMOutputImpl(); - } + static final class RevalidationHandlerHolder { + RevalidationHandlerHolder(RevalidationHandler handler) { + this.handler = handler; + } + RevalidationHandler handler; + } + + /** + * A holder for XMLDTDLoaders. This allows us to reuse SoftReferences + * which haven't yet been cleared by the garbage collector. + */ + static final class XMLDTDLoaderHolder { + XMLDTDLoaderHolder(XMLDTDLoader loader) { + this.loader = loader; + } + XMLDTDLoader loader; + } } // class DOMImplementationImpl diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java index f012ccca0c23498b71de86573ab7cc66da0a4d94..ab3dc578d5a8bc4c81d2c253fefd5ae5cf80ed90 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,7 +32,6 @@ import com.sun.org.apache.xerces.internal.util.MessageFormatter; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.utils.ObjectFactory; import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; @@ -52,6 +51,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.StringTokenizer; import javax.xml.XMLConstants; import javax.xml.catalog.CatalogFeatures; import jdk.xml.internal.JdkXmlUtils; @@ -70,7 +70,7 @@ import org.w3c.dom.ls.LSResourceResolver; * * @author Elena Litani, IBM * @author Neeraj Bajaj, Sun Microsystems. - * @LastModified: Oct 2017 + * @LastModified: Apr 2019 */ public class DOMConfigurationImpl extends ParserConfigurationSettings implements XMLParserConfiguration, DOMConfiguration { @@ -79,6 +79,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings // Constants // + protected static final String XML11_DATATYPE_VALIDATOR_FACTORY = + "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl"; + // feature identifiers /** Feature identifier: validation. */ @@ -101,12 +104,41 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings protected static final String NORMALIZE_DATA = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE; + /** Feature identifier: send element default value via characters() */ + protected static final String SCHEMA_ELEMENT_DEFAULT = + Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT; + /** sending psvi in the pipeline */ protected static final String SEND_PSVI = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI; - protected final static String DTD_VALIDATOR_FACTORY_PROPERTY = - Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; + /** Feature: generate synthetic annotations */ + protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = + Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE; + + /** Feature identifier: validate annotations */ + protected static final String VALIDATE_ANNOTATIONS = + Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE; + + /** Feature identifier: honour all schemaLocations */ + protected static final String HONOUR_ALL_SCHEMALOCATIONS = + Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE; + + /** Feature identifier: use grammar pool only */ + protected static final String USE_GRAMMAR_POOL_ONLY = + Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE; + + /** Feature identifier: load external DTD. */ + protected static final String DISALLOW_DOCTYPE_DECL_FEATURE = + Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE; + + /** Feature identifier: balance syntax trees. */ + protected static final String BALANCE_SYNTAX_TREES = + Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES; + + /** Feature identifier: warn on duplicate attribute definition. */ + protected static final String WARN_ON_DUPLICATE_ATTDEF = + Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; /** Feature identifier: namespace growth */ protected static final String NAMESPACE_GROWTH = @@ -133,9 +165,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings protected static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; - /** Property id: Grammar pool*/ + /** Property id: Grammar pool. */ protected static final String GRAMMAR_POOL = - Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; + Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; /** Property identifier: error handler. */ protected static final String ERROR_HANDLER = @@ -147,15 +179,31 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings /** Property identifier: JAXP schema language / DOM schema-type. */ protected static final String JAXP_SCHEMA_LANGUAGE = - Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE; + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE; /** Property identifier: JAXP schema source/ DOM schema-location. */ protected static final String JAXP_SCHEMA_SOURCE = - Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; + + /** Property identifier: DTD validator. */ + protected final static String DTD_VALIDATOR_PROPERTY = + Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY; + + /** Property identifier: datatype validator factory. */ + protected static final String DTD_VALIDATOR_FACTORY_PROPERTY = + Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; + /** Property identifier: schema location. */ + protected static final String SCHEMA_LOCATION = + Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION; + + /** Property identifier: no namespace schema location. */ + protected static final String SCHEMA_NONS_LOCATION = + Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION; + /** Property identifier: Schema DV Factory */ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; @@ -209,8 +257,18 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings protected final DOMErrorHandlerWrapper fErrorHandlerWrapper = new DOMErrorHandlerWrapper(); + /** Current Datatype validator factory. */ + protected DTDDVFactory fCurrentDVFactory; + + /** The XML 1.0 Datatype validator factory. */ + protected DTDDVFactory fDatatypeValidatorFactory; + + /** The XML 1.1 Datatype validator factory. **/ + protected DTDDVFactory fXML11DatatypeFactory; + // private data + private String fSchemaLocation = null; private DOMStringList fRecognizedParameters; @@ -256,7 +314,16 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings SCHEMA_FULL_CHECKING, DYNAMIC_VALIDATION, NORMALIZE_DATA, + SCHEMA_ELEMENT_DEFAULT, SEND_PSVI, + GENERATE_SYNTHETIC_ANNOTATIONS, + VALIDATE_ANNOTATIONS, + HONOUR_ALL_SCHEMALOCATIONS, + USE_GRAMMAR_POOL_ONLY, + DISALLOW_DOCTYPE_DECL_FEATURE, + BALANCE_SYNTAX_TREES, + WARN_ON_DUPLICATE_ATTDEF, + PARSER_SETTINGS, NAMESPACE_GROWTH, TOLERATE_DUPLICATES, XMLConstants.USE_CATALOG, @@ -270,9 +337,19 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings setFeature(SCHEMA_FULL_CHECKING, false); setFeature(DYNAMIC_VALIDATION, false); setFeature(NORMALIZE_DATA, false); + setFeature(SCHEMA_ELEMENT_DEFAULT, false); setFeature(XERCES_NAMESPACES, true); setFeature(SEND_PSVI, true); + setFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false); + setFeature(VALIDATE_ANNOTATIONS, false); + setFeature(HONOUR_ALL_SCHEMALOCATIONS, false); + setFeature(USE_GRAMMAR_POOL_ONLY, false); + setFeature(DISALLOW_DOCTYPE_DECL_FEATURE, false); + setFeature(BALANCE_SYNTAX_TREES, false); + setFeature(WARN_ON_DUPLICATE_ATTDEF, false); + setFeature(PARSER_SETTINGS, true); setFeature(NAMESPACE_GROWTH, false); + setFeature(TOLERATE_DUPLICATES, false); setFeature(XMLConstants.USE_CATALOG, JdkXmlUtils.USE_CATALOG_DEFAULT); setFeature(JdkXmlUtils.OVERRIDE_PARSER, JdkXmlUtils.OVERRIDE_PARSER_DEFAULT); @@ -288,6 +365,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings GRAMMAR_POOL, JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, + SCHEMA_LOCATION, + SCHEMA_NONS_LOCATION, + DTD_VALIDATOR_PROPERTY, DTD_VALIDATOR_FACTORY_PROPERTY, SCHEMA_DV_FACTORY, SECURITY_MANAGER, @@ -321,7 +401,10 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings setProperty(ERROR_REPORTER, fErrorReporter); addComponent(fErrorReporter); - setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, DTDDVFactory.getInstance()); + fDatatypeValidatorFactory = DTDDVFactory.getInstance(); + fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY); + fCurrentDVFactory = fDatatypeValidatorFactory; + setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, fCurrentDVFactory); XMLEntityManager manager = new XMLEntityManager(); setProperty(ENTITY_MANAGER, manager); @@ -348,8 +431,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings if (fErrorReporter.getMessageFormatter("http://www.w3.org/TR/xml-schema-1") == null) { MessageFormatter xmft = null; try { - xmft = (MessageFormatter)( - ObjectFactory.newInstance("com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter", true)); + xmft = new com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter(); } catch (Exception exception){ } @@ -396,8 +478,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings * has ended. If a client application wants to terminate * parsing early, it should throw an exception. * - * @param source The input source for the top-level of the - * XML document. + * @param inputSource The input source for the top-level of the + * XML document. * * @exception XNIException Any XNI exception, possibly wrapping * another exception. @@ -462,9 +544,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings * uninstall the currently installed resolver. */ public void setEntityResolver(XMLEntityResolver resolver) { - if (resolver !=null) { - fProperties.put(ENTITY_RESOLVER, resolver); - } + fProperties.put(ENTITY_RESOLVER, resolver); } // setEntityResolver(XMLEntityResolver) /** @@ -513,6 +593,26 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings return (XMLErrorHandler)fProperties.get(ERROR_HANDLER); } // getErrorHandler():XMLErrorHandler + /** + * Returns the state of a feature. + * + * @param featureId The feature identifier. + * @return true if the feature is supported + * + * @throws XMLConfigurationException Thrown for configuration error. + * In general, components should + * only throw this exception if + * it is really + * a critical error. + */ + public boolean getFeature(String featureId) + throws XMLConfigurationException { + if (featureId.equals(PARSER_SETTINGS)) { + return true; + } + return super.getFeature(featureId); + } + /** * Set the state of a feature. * @@ -576,8 +676,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings // REVISIT: Recognizes DOM L3 default features only. // Does not yet recognize Xerces features. - if(value instanceof Boolean){ - boolean state = ((Boolean)value).booleanValue(); + if(value instanceof Boolean){ + boolean state = ((Boolean)value).booleanValue(); if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) { features = (short) (state ? features | COMMENTS : features & ~COMMENTS); @@ -625,22 +725,12 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) ) { if (state) { // true is not supported - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "FEATURE_NOT_SUPPORTED", - new Object[] { name }); - throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); + throw newFeatureNotSupportedError(name); } } else if ( name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) { if (!state) { // false is not supported - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "FEATURE_NOT_SUPPORTED", - new Object[] { name }); - throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); + throw newFeatureNotSupportedError(name); } } else if (name.equalsIgnoreCase(SEND_PSVI) ){ @@ -648,12 +738,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings // because in this case we won't be able to retrieve element // default value. if (!state) { // false is not supported - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "FEATURE_NOT_SUPPORTED", - new Object[] { name }); - throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); + throw newFeatureNotSupportedError(name); } } else if (name.equalsIgnoreCase(Constants.DOM_PSVI)){ @@ -673,23 +758,16 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings } - if (!found || !(value instanceof Boolean)) { // set properties - found = true; + if (!found || !(value instanceof Boolean)) { // set properties + found = true; if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { if (value instanceof DOMErrorHandler || value == null) { fErrorHandlerWrapper.setErrorHandler((DOMErrorHandler)value); setErrorHandler(fErrorHandlerWrapper); } - else { - // REVISIT: type mismatch - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "TYPE_MISMATCH_ERR", - new Object[] { name }); - throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + throw newTypeMismatchError(name); } } else if (name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) { @@ -700,36 +778,45 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings catch (XMLConfigurationException e) {} } else { - // REVISIT: type mismatch - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "TYPE_MISMATCH_ERR", - new Object[] { name }); - throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + throw newTypeMismatchError(name); } - } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) { if (value instanceof String || value == null) { try { - // map DOM schema-location to JAXP schemaSource property - setProperty( - Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE, - value); + if (value == null) { + fSchemaLocation = null; + setProperty ( + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE, + null); + } + else { + fSchemaLocation = (String) value; + // map DOM schema-location to JAXP schemaSource property + // tokenize location string + StringTokenizer t = new StringTokenizer(fSchemaLocation, " \n\t\r"); + if (t.hasMoreTokens()) { + List locations = new ArrayList<>(); + locations.add(t.nextToken()); + while (t.hasMoreTokens()) { + locations.add (t.nextToken()); + } + setProperty ( + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE, + locations.toArray(new String[locations.size()])); + } + else { + setProperty ( + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE, + new String [] {(String) value}); + } + } } catch (XMLConfigurationException e) {} } else { - // REVISIT: type mismatch - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "TYPE_MISMATCH_ERR", - new Object[] { name }); - throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + throw newTypeMismatchError(name); } - } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { if (value instanceof String || value == null) { @@ -754,57 +841,43 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings catch (XMLConfigurationException e) {} } else { - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "TYPE_MISMATCH_ERR", - new Object[] { name }); - throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + throw newTypeMismatchError(name); } - } - else if (name.equalsIgnoreCase(SYMBOL_TABLE)){ + else if (name.equalsIgnoreCase(ENTITY_RESOLVER)) { + if (value instanceof XMLEntityResolver || value == null) { + try { + setEntityResolver((XMLEntityResolver) value); + } + catch (XMLConfigurationException e) {} + } + else { + throw newTypeMismatchError(name); + } + } + else if (name.equalsIgnoreCase(SYMBOL_TABLE)) { // Xerces Symbol Table if (value instanceof SymbolTable){ setProperty(SYMBOL_TABLE, value); } else { - // REVISIT: type mismatch - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "TYPE_MISMATCH_ERR", - new Object[] { name }); - throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + throw newTypeMismatchError(name); } } - else if (name.equalsIgnoreCase (GRAMMAR_POOL)){ - if (value instanceof XMLGrammarPool){ + else if (name.equalsIgnoreCase (GRAMMAR_POOL)) { + if (value instanceof XMLGrammarPool || value == null) { setProperty(GRAMMAR_POOL, value); } else { - // REVISIT: type mismatch - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "TYPE_MISMATCH_ERR", - new Object[] { name }); - throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + throw newTypeMismatchError(name); } - } - else { + else { // REVISIT: check if this is a boolean parameter -- type mismatch should be thrown. //parameter is not recognized - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "FEATURE_NOT_FOUND", - new Object[] { name }); - throw new DOMException(DOMException.NOT_FOUND_ERR, msg); + throw newFeatureNotFoundError(name); } } - } @@ -878,23 +951,23 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings return getProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE); } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) { - return getProperty(Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE); + return fSchemaLocation; } - else if (name.equalsIgnoreCase(SYMBOL_TABLE)){ + else if (name.equalsIgnoreCase(ENTITY_RESOLVER)) { + return getEntityResolver(); + } + else if (name.equalsIgnoreCase(SYMBOL_TABLE)) { return getProperty(SYMBOL_TABLE); } - else if (name.equalsIgnoreCase(GRAMMAR_POOL)){ + else if (name.equalsIgnoreCase(GRAMMAR_POOL)) { return getProperty(GRAMMAR_POOL); + } + else if (name.equalsIgnoreCase(SECURITY_MANAGER)) { + return getProperty(SECURITY_MANAGER); } else { - String msg = - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "FEATURE_NOT_FOUND", - new Object[] { name }); - throw new DOMException(DOMException.NOT_FOUND_ERR, msg); + throw newFeatureNotFoundError(name); } - } /** @@ -966,15 +1039,19 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { // REVISIT: should null value be supported? - //as of now we are only supporting W3C XML Schema - return ( (value instanceof String) && value.equals(Constants.NS_XMLSCHEMA) ) ? true : false ; + // as of now we are only supporting W3C XML Schema and DTD. + return ((value instanceof String) && + (value.equals(Constants.NS_XMLSCHEMA) || value.equals(Constants.NS_DTD))) ? true : false; + } + else if (name.equalsIgnoreCase(ENTITY_RESOLVER)) { + return (value instanceof XMLEntityResolver) ? true : false; } - else if (name.equalsIgnoreCase(SYMBOL_TABLE)){ + else if (name.equalsIgnoreCase(SYMBOL_TABLE)) { // Xerces Symbol Table - return (value instanceof SymbolTable) ? true : false ; + return (value instanceof SymbolTable) ? true : false; } - else if (name.equalsIgnoreCase (GRAMMAR_POOL)){ - return (value instanceof XMLGrammarPool) ? true : false ; + else if (name.equalsIgnoreCase (GRAMMAR_POOL)) { + return (value instanceof XMLGrammarPool) ? true : false; } else { //false if the parameter is not recognized or the requested value is not supported. @@ -991,46 +1068,49 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings * can be set by the application. Note that this list can also contain * parameter names defined outside this specification. */ - public DOMStringList getParameterNames() { - if (fRecognizedParameters == null){ + public DOMStringList getParameterNames() { + if (fRecognizedParameters == null){ List parameters = new ArrayList<>(); - //Add DOM recognized parameters - //REVISIT: Would have been nice to have a list of - //recognized paramters. - parameters.add(Constants.DOM_COMMENTS); - parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); - parameters.add(Constants.DOM_CDATA_SECTIONS); - parameters.add(Constants.DOM_ENTITIES); - parameters.add(Constants.DOM_SPLIT_CDATA); - parameters.add(Constants.DOM_NAMESPACES); - parameters.add(Constants.DOM_VALIDATE); - - parameters.add(Constants.DOM_INFOSET); - parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); - parameters.add(Constants.DOM_CANONICAL_FORM); - parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); - parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); - parameters.add(Constants.DOM_WELLFORMED); - - parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); - parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); - - parameters.add(Constants.DOM_ERROR_HANDLER); - parameters.add(Constants.DOM_SCHEMA_TYPE); - parameters.add(Constants.DOM_SCHEMA_LOCATION); - parameters.add(Constants.DOM_RESOURCE_RESOLVER); - - //Add recognized xerces features and properties - parameters.add(GRAMMAR_POOL); - parameters.add(SYMBOL_TABLE); - parameters.add(SEND_PSVI); - - fRecognizedParameters = new DOMStringListImpl(parameters); - } + //Add DOM recognized parameters + //REVISIT: Would have been nice to have a list of + //recognized paramters. + parameters.add(Constants.DOM_COMMENTS); + parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); + parameters.add(Constants.DOM_CDATA_SECTIONS); + parameters.add(Constants.DOM_ENTITIES); + parameters.add(Constants.DOM_SPLIT_CDATA); + parameters.add(Constants.DOM_NAMESPACES); + parameters.add(Constants.DOM_VALIDATE); + + parameters.add(Constants.DOM_INFOSET); + parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); + parameters.add(Constants.DOM_CANONICAL_FORM); + parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); + parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); + parameters.add(Constants.DOM_WELLFORMED); + + parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); + parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); + + parameters.add(Constants.DOM_ERROR_HANDLER); + parameters.add(Constants.DOM_SCHEMA_TYPE); + parameters.add(Constants.DOM_SCHEMA_LOCATION); + parameters.add(Constants.DOM_RESOURCE_RESOLVER); + + //Add recognized xerces features and properties + parameters.add(ENTITY_RESOLVER); + parameters.add(GRAMMAR_POOL); + parameters.add(SECURITY_MANAGER); + parameters.add(SYMBOL_TABLE); + parameters.add(SEND_PSVI); + + fRecognizedParameters = new DOMStringListImpl(parameters); - return fRecognizedParameters; - }//getParameterNames + } + + return fRecognizedParameters; + }//getParameterNames // // Protected methods @@ -1061,6 +1141,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the * requested feature is not known or supported. */ + @Override protected PropertyState checkProperty(String propertyId) throws XMLConfigurationException { @@ -1115,4 +1196,44 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings return new ValidationManager(); } -} // class XMLParser + protected final void setDTDValidatorFactory(String version) { + if ("1.1".equals(version)) { + if (fCurrentDVFactory != fXML11DatatypeFactory) { + fCurrentDVFactory = fXML11DatatypeFactory; + setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, fCurrentDVFactory); + } + } + else if (fCurrentDVFactory != fDatatypeValidatorFactory) { + fCurrentDVFactory = fDatatypeValidatorFactory; + setProperty(DTD_VALIDATOR_FACTORY_PROPERTY, fCurrentDVFactory); + } + } + + private static DOMException newFeatureNotSupportedError(String name) { + String msg = + DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "FEATURE_NOT_SUPPORTED", + new Object[] { name }); + return new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); + } + + private static DOMException newFeatureNotFoundError(String name) { + String msg = + DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "FEATURE_NOT_FOUND", + new Object[] { name }); + return new DOMException(DOMException.NOT_FOUND_ERR, msg); + } + + private static DOMException newTypeMismatchError(String name) { + String msg = + DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "TYPE_MISMATCH_ERR", + new Object[] { name }); + return new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); + } + +} // class DOMConfigurationImpl diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java index 3dacb16ee48e8fff3e33da4e40942de3b419dda2..4903448394b59e0e02c3a198191d5859eb644aed 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DOMNormalizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -22,21 +22,17 @@ package com.sun.org.apache.xerces.internal.dom; -import com.sun.org.apache.xerces.internal.dom.AbortException; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.RevalidationHandler; -import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar; -import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDDescription; +import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader; import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator; import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; import com.sun.org.apache.xerces.internal.impl.xs.util.SimpleLocator; -import com.sun.org.apache.xerces.internal.parsers.XMLGrammarPreparser; import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; 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.XML11Char; import com.sun.org.apache.xerces.internal.util.XMLChar; -import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; @@ -48,15 +44,12 @@ import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; 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.grammars.XMLGrammarDescription; -import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; -import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xs.AttributePSVI; import com.sun.org.apache.xerces.internal.xs.ElementPSVI; import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; import java.io.IOException; -import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.Vector; @@ -96,7 +89,7 @@ import org.w3c.dom.Text; * * @author Elena Litani, IBM * @author Neeraj Bajaj, Sun Microsystems, inc. - * @LastModified: Nov 2017 + * @LastModified: Apr 2019 */ public class DOMNormalizer implements XMLDocumentHandler { @@ -155,7 +148,7 @@ public class DOMNormalizer implements XMLDocumentHandler { /** for setting the PSVI */ protected Node fCurrentNode = null; - private QName fAttrQName = new QName(); + private final QName fAttrQName = new QName(); // attribute value normalization final XMLString fNormalizedValue = new XMLString(new char[16], 0, 0); @@ -163,8 +156,11 @@ public class DOMNormalizer implements XMLDocumentHandler { //DTD validator private XMLDTDValidator fDTDValidator; - //Check if element content is all "ignorable whitespace" - private boolean allWhitespace = false; + /** Empty string to pass to the validator. **/ + public static final XMLString EMPTY_STRING = new XMLString(); + + // Check if element content is all "ignorable whitespace" + private boolean fAllWhitespace = false; // Constructor // @@ -177,24 +173,30 @@ public class DOMNormalizer implements XMLDocumentHandler { * Normalizes document. * Note: reset() must be called before this method. */ - protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) { + protected void normalizeDocument(CoreDocumentImpl document, DOMConfigurationImpl config) { + + fDocument = document; + fConfiguration = config; + fAllWhitespace = false; + fNamespaceValidation = false; - fDocument = document; - fConfiguration = config; + String xmlVersion = fDocument.getXmlVersion(); + String schemaType = null; + String [] schemaLocations = null; - // intialize and reset DOMNormalizer component - // - fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE); - // reset namespace context - fNamespaceContext.reset(); - fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); + // intialize and reset DOMNormalizer component + // + fSymbolTable = (SymbolTable) fConfiguration.getProperty(DOMConfigurationImpl.SYMBOL_TABLE); + // reset namespace context + fNamespaceContext.reset(); + fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, null); - if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) { + if ((fConfiguration.features & DOMConfigurationImpl.VALIDATE) != 0) { String schemaLang = (String)fConfiguration.getProperty(DOMConfigurationImpl.JAXP_SCHEMA_LANGUAGE); - if(schemaLang != null && schemaLang.equals(Constants.NS_XMLSCHEMA)) { - fValidationHandler = - CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_SCHEMA); + if (schemaLang != null && schemaLang.equals(Constants.NS_XMLSCHEMA)) { + schemaType = XMLGrammarDescription.XML_SCHEMA; + fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(schemaType, xmlVersion); fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA, true); fConfiguration.setFeature(DOMConfigurationImpl.SCHEMA_FULL_CHECKING, true); // report fatal error on DOM Level 1 nodes @@ -203,49 +205,74 @@ public class DOMNormalizer implements XMLDocumentHandler { // check if we need to fill in PSVI fPSVI = ((fConfiguration.features & DOMConfigurationImpl.PSVI) !=0)?true:false; } + else { + schemaType = XMLGrammarDescription.XML_DTD; + if (schemaLang != null) { + schemaLocations = (String []) fConfiguration.getProperty(DOMConfigurationImpl.JAXP_SCHEMA_SOURCE); + } + fConfiguration.setDTDValidatorFactory(xmlVersion); + fValidationHandler = CoreDOMImplementationImpl.singleton.getValidator(schemaType, xmlVersion); + fPSVI = false; + } - fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true); + fConfiguration.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true); // reset ID table fDocument.clearIdentifiers(); - if(fValidationHandler != null) - // reset schema validator + if (fValidationHandler != null) { + // reset the validation handler ((XMLComponent) fValidationHandler).reset(fConfiguration); + } + } + else { + fValidationHandler = null; + } - } - - fErrorHandler = (DOMErrorHandler) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER); - if (fValidationHandler != null) { - fValidationHandler.setDocumentHandler(this); - fValidationHandler.startDocument( + fErrorHandler = (DOMErrorHandler) fConfiguration.getParameter(Constants.DOM_ERROR_HANDLER); + if (fValidationHandler != null) { + fValidationHandler.setDocumentHandler(this); + fValidationHandler.startDocument( new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, - -1, -1 ), fDocument.encoding, fNamespaceContext, null); - - } - try { - Node kid, next; - for (kid = fDocument.getFirstChild(); kid != null; kid = next) { - next = kid.getNextSibling(); - kid = normalizeNode(kid); - if (kid != null) { // don't advance - next = kid; - } - } + -1, -1 ), fDocument.encoding, fNamespaceContext, null); + fValidationHandler.xmlDecl(fDocument.getXmlVersion(), + fDocument.getXmlEncoding(), fDocument.getXmlStandalone() ? "yes" : "no", null); + } + try { + if (schemaType == XMLGrammarDescription.XML_DTD) { + processDTD(xmlVersion, schemaLocations != null ? schemaLocations[0] : null); + } - // release resources - if (fValidationHandler != null) { - fValidationHandler.endDocument(null); - CoreDOMImplementationImpl.singleton.releaseValidator( - XMLGrammarDescription.XML_SCHEMA, fValidationHandler); - fValidationHandler = null; - } - } catch (AbortException e) { - return; + Node kid, next; + for (kid = fDocument.getFirstChild(); kid != null; kid = next) { + next = kid.getNextSibling(); + kid = normalizeNode(kid); + if (kid != null) { // don't advance + next = kid; } + } + // release resources + if (fValidationHandler != null) { + fValidationHandler.endDocument(null); + fValidationHandler.setDocumentHandler(null); + CoreDOMImplementationImpl.singleton.releaseValidator(schemaType, xmlVersion, fValidationHandler); + fValidationHandler = null; + } } - + catch (RuntimeException e) { + // release resources + if (fValidationHandler != null) { + fValidationHandler.setDocumentHandler(null); + CoreDOMImplementationImpl.singleton.releaseValidator(schemaType, xmlVersion, fValidationHandler); + fValidationHandler = null; + } + if (e instanceof AbortException) { + return; // processing aborted by the user + } + throw e; // otherwise re-throw. + } + } /** * @@ -273,16 +300,7 @@ public class DOMNormalizer implements XMLDocumentHandler { if (DEBUG_ND) { System.out.println("==>normalizeNode:{doctype}"); } - DocumentTypeImpl docType = (DocumentTypeImpl)node; - fDTDValidator = (XMLDTDValidator)CoreDOMImplementationImpl.singleton.getValidator(XMLGrammarDescription.XML_DTD); - fDTDValidator.setDocumentHandler(this); - fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, createGrammarPool(docType)); - fDTDValidator.reset(fConfiguration); - fDTDValidator.startDocument( - new SimpleLocator(fDocument.fDocumentURI, fDocument.fDocumentURI, - -1, -1 ), fDocument.encoding, fNamespaceContext, null); - fDTDValidator.doctypeDecl(docType.getName(), docType.getPublicId(), docType.getSystemId(), null); - //REVISIT: well-formness encoding info + // REVISIT: well-formedness encoding info break; } @@ -297,7 +315,7 @@ public class DOMNormalizer implements XMLDocumentHandler { if ( ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) && fDocument.isXMLVersionChanged()){ if (fNamespaceValidation){ - wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version()) ; + wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), fDocument.isXML11Version()); } else { wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version()); @@ -329,13 +347,21 @@ public class DOMNormalizer implements XMLDocumentHandler { // remove default attributes namespaceFixUp(elem, attributes); - if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0 && attributes != null ) { - for (int i = 0; i < attributes.getLength(); ++i) { - Attr att = (Attr)attributes.getItem(i); - if (XMLSymbols.PREFIX_XMLNS.equals(att.getPrefix()) || - XMLSymbols.PREFIX_XMLNS.equals(att.getName())) { - elem.removeAttributeNode(att); - --i; + if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) { + // Namespace declarations may have been added by namespace fix-up. Need + // to fetch the AttributeMap again if it contained no attributes prior + // to namespace fix-up. + if (attributes == null) { + attributes = (elem.hasAttributes()) ? (AttributeMap) elem.getAttributes() : null; + } + if (attributes != null) { + for (int i = 0; i < attributes.getLength(); ++i) { + Attr att = (Attr)attributes.getItem(i); + if (XMLSymbols.PREFIX_XMLNS.equals(att.getPrefix()) || + XMLSymbols.PREFIX_XMLNS.equals(att.getName())) { + elem.removeAttributeNode(att); + --i; + } } } } @@ -347,16 +373,21 @@ public class DOMNormalizer implements XMLDocumentHandler { //removeDefault(attr, attributes); attr.normalize(); if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)){ - isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version()); - if (fDocument.isXMLVersionChanged()){ - wellformed=CoreDocumentImpl.isXMLName(node.getNodeName() , fDocument.isXML11Version()); - if (!wellformed){ - String msg = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "wf-invalid-character-in-node-name", - new Object[]{"Attr",node.getNodeName()}); - reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, - "wf-invalid-character-in-node-name"); + isAttrValueWF(fErrorHandler, fError, fLocator, attributes, attr, attr.getValue(), fDocument.isXML11Version()); + if (fDocument.isXMLVersionChanged()) { + if (fNamespaceValidation){ + wellformed = CoreDocumentImpl.isValidQName(node.getPrefix(), node.getLocalName(), fDocument.isXML11Version()); + } + else { + wellformed = CoreDocumentImpl.isXMLName(node.getNodeName(), fDocument.isXML11Version()); + } + if (!wellformed) { + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "wf-invalid-character-in-node-name", + new Object[]{"Attr",node.getNodeName()}); + reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, + "wf-invalid-character-in-node-name"); } } } @@ -379,26 +410,12 @@ public class DOMNormalizer implements XMLDocumentHandler { fValidationHandler.startElement(fQName, fAttrProxy, null); } - if (fDTDValidator != null) { - // REVISIT: possible solutions to discard default content are: - // either we pass some flag to XML Schema validator - // or rely on the PSVI information. - fAttrProxy.setAttributes(attributes, fDocument, elem); - updateQName(elem, fQName); // updates global qname - // set error node in the dom error wrapper - // so if error occurs we can report an error node - fConfiguration.fErrorHandlerWrapper.fCurrentNode = node; - fCurrentNode = node; - // call re-validation handler - fDTDValidator.startElement(fQName, fAttrProxy, null); - } - // normalize children Node kid, next; for (kid = elem.getFirstChild(); kid != null; kid = next) { next = kid.getNextSibling(); kid = normalizeNode(kid); - if (kid !=null) { + if (kid != null) { next = kid; // don't advance } } @@ -412,7 +429,6 @@ public class DOMNormalizer implements XMLDocumentHandler { } - if (fValidationHandler != null) { updateQName(elem, fQName); // updates global qname // @@ -423,16 +439,6 @@ public class DOMNormalizer implements XMLDocumentHandler { fValidationHandler.endElement(fQName, null); } - if (fDTDValidator != null) { - updateQName(elem, fQName); // updates global qname - // - // set error node in the dom error wrapper - // so if error occurs we can report an error node - fConfiguration.fErrorHandlerWrapper.fCurrentNode = node; - fCurrentNode = node; - fDTDValidator.endElement(fQName, null); - } - // pop namespace context fNamespaceContext.popContext(); @@ -465,6 +471,13 @@ public class DOMNormalizer implements XMLDocumentHandler { // of the document isCommentWF(fErrorHandler, fError, fLocator, commentdata, fDocument.isXML11Version()); } + if (fValidationHandler != null) { + // Don't bother filling an XMLString with the text of the comment. + // We only send the comment event to the validator handler so that + // when the schema-type is DTD an error will be reported for a + // comment appearing in EMPTY content. + fValidationHandler.comment(EMPTY_STRING, null); + } }//end-else if comment node is not to be removed. break; } @@ -531,16 +544,6 @@ public class DOMNormalizer implements XMLDocumentHandler { fValidationHandler.characterData(node.getNodeValue(), null); fValidationHandler.endCDATA(null); } - - if (fDTDValidator != null) { - // set error node in the dom error wrapper - // so if error occurs we can report an error node - fConfiguration.fErrorHandlerWrapper.fCurrentNode = node; - fCurrentNode = node; - fDTDValidator.startCDATA(null); - fDTDValidator.characterData(node.getNodeValue(), null); - fDTDValidator.endCDATA(null); - } String value = node.getNodeValue(); if ((fConfiguration.features & DOMConfigurationImpl.SPLITCDATA) != 0) { @@ -605,42 +608,37 @@ public class DOMNormalizer implements XMLDocumentHandler { short nextType = (next != null)?next.getNodeType():-1; if (nextType == -1 || !(((fConfiguration.features & DOMConfigurationImpl.ENTITIES) == 0 && - nextType == Node.ENTITY_NODE) || - ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 && - nextType == Node.COMMENT_NODE) || - ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) && - nextType == Node.CDATA_SECTION_NODE)) { - if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){ - isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version()); - } - if (fValidationHandler != null) { - fConfiguration.fErrorHandlerWrapper.fCurrentNode = node; - fCurrentNode = node; - fValidationHandler.characterData(node.getNodeValue(), null); - if (DEBUG_ND) { - System.out.println("=====>characterData(),"+nextType); - - } - } - if (fDTDValidator != null) { - fConfiguration.fErrorHandlerWrapper.fCurrentNode = node; - fCurrentNode = node; - fDTDValidator.characterData(node.getNodeValue(), null); - if (DEBUG_ND) { - System.out.println("=====>characterData(),"+nextType); - - } - if(allWhitespace) { - allWhitespace = false; - ((TextImpl)node).setIgnorableWhitespace(true); - } - } + nextType == Node.ENTITY_NODE) || + ((fConfiguration.features & DOMConfigurationImpl.COMMENTS) == 0 && + nextType == Node.COMMENT_NODE) || + ((fConfiguration.features & DOMConfigurationImpl.CDATA) == 0) && + nextType == Node.CDATA_SECTION_NODE)) { + if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) ){ + isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), fDocument.isXML11Version()); + } + if (fValidationHandler != null) { + fConfiguration.fErrorHandlerWrapper.fCurrentNode = node; + fCurrentNode = node; + fValidationHandler.characterData(node.getNodeValue(), null); + if (!fNamespaceValidation) { + if (fAllWhitespace) { + fAllWhitespace = false; + ((TextImpl)node).setIgnorableWhitespace(true); + } + else { + ((TextImpl)node).setIgnorableWhitespace(false); + } + } + if (DEBUG_ND) { + System.out.println("=====>characterData(),"+nextType); + } + } } else { - if (DEBUG_ND) { - System.out.println("=====>don't send characters(),"+nextType); + if (DEBUG_ND) { + System.out.println("=====>don't send characters(),"+nextType); - } + } } } break; @@ -674,42 +672,66 @@ public class DOMNormalizer implements XMLDocumentHandler { //which may not be valid XML character isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), fDocument.isXML11Version()); } + + if (fValidationHandler != null) { + // Don't bother filling an XMLString with the data section of the + // processing instruction. We only send the processing instruction + // event to the validator handler so that when the schema-type is + // DTD an error will be reported for a processing instruction + // appearing in EMPTY content. + fValidationHandler.processingInstruction(((ProcessingInstruction) node).getTarget(), EMPTY_STRING, null); + } }//end case Node.PROCESSING_INSTRUCTION_NODE }//end of switch return null; }//normalizeNode - private XMLGrammarPool createGrammarPool(DocumentTypeImpl docType) { - - XMLGrammarPoolImpl pool = new XMLGrammarPoolImpl(); + private void processDTD(String xmlVersion, String schemaLocation) { - XMLGrammarPreparser preParser = new XMLGrammarPreparser(fSymbolTable); - preParser.registerPreparser(XMLGrammarDescription.XML_DTD, null); - preParser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE, true); - preParser.setFeature(Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATION_FEATURE, true); - preParser.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY, pool); + String rootName = null; + String publicId = null; + String systemId = schemaLocation; + String baseSystemId = fDocument.getDocumentURI(); + String internalSubset = null; - String internalSubset = docType.getInternalSubset(); - XMLInputSource is = new XMLInputSource(docType.getPublicId(), docType.getSystemId(), null, false); + DocumentType docType = fDocument.getDoctype(); + if (docType != null) { + rootName = docType.getName(); + publicId = docType.getPublicId(); + if (systemId == null || systemId.length() == 0) { + systemId = docType.getSystemId(); + } + internalSubset = docType.getInternalSubset(); + } + // If the DOM doesn't have a DocumentType node we may still + // be able to fetch a DTD if the application provided a URI + else { + Element elem = fDocument.getDocumentElement(); + if (elem == null) return; + rootName = elem.getNodeName(); + if (systemId == null || systemId.length() == 0) return; + } - if(internalSubset != null) - is.setCharacterStream(new StringReader(internalSubset)); + XMLDTDLoader loader = null; try { - DTDGrammar g = (DTDGrammar)preParser.preparseGrammar(XMLGrammarDescription.XML_DTD, is); - ((XMLDTDDescription)g.getGrammarDescription()).setRootName(docType.getName()); - is.setCharacterStream(null); - g = (DTDGrammar)preParser.preparseGrammar(XMLGrammarDescription.XML_DTD, is); - ((XMLDTDDescription)g.getGrammarDescription()).setRootName(docType.getName()); - - } catch (XNIException e) { - } catch (IOException e) { + fValidationHandler.doctypeDecl(rootName, publicId, systemId, null); + loader = CoreDOMImplementationImpl.singleton.getDTDLoader(xmlVersion); + loader.setFeature(DOMConfigurationImpl.XERCES_VALIDATION, true); + loader.setEntityResolver(fConfiguration.getEntityResolver()); + loader.setErrorHandler(fConfiguration.getErrorHandler()); + loader.loadGrammarWithContext((XMLDTDValidator) fValidationHandler, rootName, + publicId, systemId, baseSystemId, internalSubset); } - - return pool; - } - - + // REVISIT: Should probably report this exception to the error handler. + catch (IOException e) { + } + finally { + if (loader != null) { + CoreDOMImplementationImpl.singleton.releaseDTDLoader(xmlVersion, loader); + } + } + } // processDTD(String, String) protected final void expandEntityRef (Node parent, Node reference){ Node kid, next; @@ -740,30 +762,15 @@ public class DOMNormalizer implements XMLDocumentHandler { // // ------------------------------------ - String value, name, uri, prefix; + String value, uri, prefix; if (attributes != null) { // Record all valid local declarations for (int k = 0; k < attributes.getLength(); ++k) { Attr attr = (Attr)attributes.getItem(k); - - //do the name check only when version of the document was changed & - //application has set the value of well-formed features to true - if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0) && - fDocument.isXMLVersionChanged()) { - //checkQName does checking based on the version of the document - fDocument.checkQName(attr.getPrefix() , attr.getLocalName()) ; - } - uri = attr.getNamespaceURI(); if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) { // namespace attribute - - // "namespace-declarations" == false; Discard all namespace declaration attributes - if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) { - continue; - } - value = attr.getNodeValue(); if (value == null) { value=XMLSymbols.EMPTY_STRING; @@ -798,7 +805,7 @@ public class DOMNormalizer implements XMLDocumentHandler { } else { // (localpart == fXmlnsSymbol && prefix == fEmptySymbol) -- xmlns // empty prefix is always bound ("" or some string) value = fSymbolTable.addSymbol(value); - fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value); + fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, value.length() != 0 ? value : null); //removeDefault (attr, attributes); continue; } @@ -826,12 +833,7 @@ public class DOMNormalizer implements XMLDocumentHandler { uri = element.getNamespaceURI(); prefix = element.getPrefix(); - - // "namespace-declarations" == false? Discard all namespace declaration attributes - if ((fConfiguration.features & DOMConfigurationImpl.NSDECL) == 0) { - // no namespace declaration == no namespace URI, semantics are to keep prefix - uri = null; - } else if (uri != null) { // Element has a namespace + if (uri != null) { // Element has a namespace uri = fSymbolTable.addSymbol(uri); prefix = (prefix == null || prefix.length() == 0) ? XMLSymbols.EMPTY_STRING :fSymbolTable.addSymbol(prefix); @@ -870,8 +872,8 @@ public class DOMNormalizer implements XMLDocumentHandler { // undeclare default namespace declaration (before that element // bound to non-zero length uir), but adding xmlns="" decl addNamespaceDecl (XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING, element); - fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); - fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, XMLSymbols.EMPTY_STRING); + fLocalNSBinder.declarePrefix(XMLSymbols.EMPTY_STRING, null); + fNamespaceContext.declarePrefix(XMLSymbols.EMPTY_STRING, null); } } } @@ -894,12 +896,35 @@ public class DOMNormalizer implements XMLDocumentHandler { // normalize attribute value attr.normalize(); value = attr.getValue(); - name = attr.getNodeName(); uri = attr.getNamespaceURI(); // make sure that value is never null. if (value == null) { - value=XMLSymbols.EMPTY_STRING; + value = XMLSymbols.EMPTY_STRING; + } + + //--------------------------------------- + // check if value of the attribute is namespace well-formed + //--------------------------------------- + if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)) { + isAttrValueWF(fErrorHandler, fError, fLocator, attributes, attr, value, fDocument.isXML11Version()); + if (fDocument.isXMLVersionChanged()) { + boolean wellformed; + if (fNamespaceValidation){ + wellformed = CoreDocumentImpl.isValidQName(attr.getPrefix(), attr.getLocalName(), fDocument.isXML11Version()); + } + else { + wellformed = CoreDocumentImpl.isXMLName(attr.getNodeName(), fDocument.isXML11Version()); + } + if (!wellformed) { + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "wf-invalid-character-in-node-name", + new Object[]{"Attr", attr.getNodeName()}); + reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, + "wf-invalid-character-in-node-name"); + } + } } if (uri != null) { // attribute has namespace !=null @@ -916,23 +941,6 @@ public class DOMNormalizer implements XMLDocumentHandler { if (uri != null && uri.equals(NamespaceContext.XMLNS_URI)) { continue; } - //--------------------------------------- - // check if value of the attribute is namespace well-formed - //--------------------------------------- - if (fDocument.errorChecking && ((fConfiguration.features & DOMConfigurationImpl.WELLFORMED) != 0)) { - isAttrValueWF(fErrorHandler, fError, fLocator, attributes, (AttrImpl)attr, attr.getValue(), fDocument.isXML11Version()); - if (fDocument.isXMLVersionChanged()){ - boolean wellformed=CoreDocumentImpl.isXMLName(attr.getNodeName() , fDocument.isXML11Version()); - if (!wellformed){ - String msg = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "wf-invalid-character-in-node-name", - new Object[]{"Attribute", attr.getNodeName()}); - reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_ERROR, - "wf-invalid-character-in-node-name"); - } - } - } // --------------------------------------- // remove default attributes @@ -948,7 +956,6 @@ public class DOMNormalizer implements XMLDocumentHandler { // reset id-attributes ((AttrImpl)attr).setIdAttribute(false); - uri = fSymbolTable.addSymbol(uri); // find if for this prefix a URI was already declared @@ -962,7 +969,6 @@ public class DOMNormalizer implements XMLDocumentHandler { // conflict: attribute has a prefix that conficlicts with a binding // already active in scope - name = attr.getNodeName(); // Find if any prefix for attributes namespace URI is available // in the scope String declaredPrefix = fNamespaceContext.getPrefix(uri); @@ -1447,8 +1453,8 @@ public class DOMNormalizer implements XMLDocumentHandler { protected CoreDocumentImpl fDocument; protected ElementImpl fElement; - protected final Vector fAugmentations = new Vector<>(5); - + protected Vector fDTDTypes = new Vector<>(5); + protected Vector fAugmentations = new Vector<>(5); public void setAttributes(AttributeMap attributes, CoreDocumentImpl doc, ElementImpl elem) { fDocument = doc; @@ -1456,7 +1462,7 @@ public class DOMNormalizer implements XMLDocumentHandler { fElement = elem; if (attributes != null) { int length = attributes.getLength(); - + fDTDTypes.setSize(length); fAugmentations.setSize(length); // REVISIT: this implementation does not store any value in augmentations // and basically not keeping augs in parallel to attributes map @@ -1464,34 +1470,37 @@ public class DOMNormalizer implements XMLDocumentHandler { for (int i = 0; i < length; i++) { fAugmentations.setElementAt(new AugmentationsImpl(), i); } - } else { + } + else { + fDTDTypes.setSize(0); fAugmentations.setSize(0); } } - /** + /** * This method adds default declarations * @see com.sun.org.apache.xerces.internal.xni.XMLAttributes#addAttribute(QName, String, String) - */ - public int addAttribute(QName qname, String attrType, String attrValue) { - int index = fElement.getXercesAttribute(qname.uri, qname.localpart); - // add defaults to the tree - if (index < 0) { + */ + public int addAttribute(QName qname, String attrType, String attrValue) { + int index = fElement.getXercesAttribute(qname.uri, qname.localpart); + // add defaults to the tree + if (index < 0) { // the default attribute was removed by a user and needed to // be added back - AttrImpl attr = (AttrImpl) - ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS( - qname.uri, - qname.rawname, - qname.localpart); + AttrImpl attr = (AttrImpl) + ((CoreDocumentImpl) fElement.getOwnerDocument()).createAttributeNS( + qname.uri, + qname.rawname, + qname.localpart); // REVISIT: the following should also update ID table attr.setNodeValue(attrValue); index = fElement.setXercesAttributeNode(attr); + fDTDTypes.insertElementAt(attrType, index); fAugmentations.insertElementAt(new AugmentationsImpl(), index); attr.setSpecified(false); - } - else { + } + else { // default attribute is in the tree // we don't need to do anything since prefix was already fixed // at the namespace fixup time and value must be same value, otherwise @@ -1500,7 +1509,7 @@ public class DOMNormalizer implements XMLDocumentHandler { } return index; - } + } public void removeAllAttributes(){ @@ -1523,41 +1532,58 @@ public class DOMNormalizer implements XMLDocumentHandler { return -1; } - public int getIndex(String uri, String localPart){ + public int getIndex(String uri, String localPart) { // REVISIT: implement return -1; } - public void setName(int attrIndex, QName attrName){ + public void setName(int attrIndex, QName attrName) { // REVISIT: implement } - public void getName(int attrIndex, QName attrName){ - if (fAttributes !=null) { + public void getName(int attrIndex, QName attrName) { + if (fAttributes != null) { updateQName((Node)fAttributes.getItem(attrIndex), attrName); } } - public String getPrefix(int index){ - // REVISIT: implement + public String getPrefix(int index) { + if (fAttributes != null) { + Node node = (Node) fAttributes.getItem(index); + String prefix = node.getPrefix(); + prefix = (prefix != null && prefix.length() != 0) ? fSymbolTable.addSymbol(prefix) : null; + return prefix; + } return null; } - - public String getURI(int index){ - // REVISIT: implement + public String getURI(int index) { + if (fAttributes != null) { + Node node = (Node) fAttributes.getItem(index); + String namespace = node.getNamespaceURI(); + namespace = (namespace != null) ? fSymbolTable.addSymbol(namespace) : null; + return namespace; + } return null; } - public String getLocalName(int index){ - // REVISIT: implement + public String getLocalName(int index) { + if (fAttributes != null) { + Node node = (Node) fAttributes.getItem(index); + String localName = node.getLocalName(); + localName = (localName != null) ? fSymbolTable.addSymbol(localName) : null; + return localName; + } return null; } - - public String getQName(int index){ - // REVISIT: implement + public String getQName(int index) { + if (fAttributes != null) { + Node node = (Node) fAttributes.getItem(index); + String rawname = fSymbolTable.addSymbol(node.getNodeName()); + return rawname; + } return null; } @@ -1566,27 +1592,31 @@ public class DOMNormalizer implements XMLDocumentHandler { return null; } - public void setType(int attrIndex, String attrType){ - // REVISIT: implement + public void setType(int attrIndex, String attrType) { + fDTDTypes.setElementAt(attrType, attrIndex); } - - public String getType(int index){ - return "CDATA"; + public String getType(int index) { + String type = fDTDTypes.elementAt(index); + return (type != null) ? getReportableType(type) : "CDATA"; } - - public String getType(String qName){ + public String getType(String qName) { return "CDATA"; } - - public String getType(String uri, String localName){ + public String getType(String uri, String localName) { return "CDATA"; } + private String getReportableType(String type) { + if (type.charAt(0) == '(') { + return "NMTOKEN"; + } + return type; + } - public void setValue(int attrIndex, String attrValue){ + public void setValue(int attrIndex, String attrValue) { // REVISIT: is this desired behaviour? // The values are updated in the case datatype-normalization is turned on // in this case we need to make sure that specified attributes stay specified @@ -1609,13 +1639,11 @@ public class DOMNormalizer implements XMLDocumentHandler { } - public String getValue(String qName){ // REVISIT: implement return null; } - public String getValue(String uri, String localName){ if (fAttributes != null) { Node node = fAttributes.getNamedItemNS(uri, localName); @@ -1624,19 +1652,16 @@ public class DOMNormalizer implements XMLDocumentHandler { return null; } - public void setNonNormalizedValue(int attrIndex, String attrValue){ // REVISIT: implement } - public String getNonNormalizedValue(int attrIndex){ // REVISIT: implement return null; } - public void setSpecified(int attrIndex, boolean specified){ AttrImpl attr = (AttrImpl)fAttributes.getItem(attrIndex); attr.setSpecified(specified); @@ -1788,58 +1813,85 @@ public class DOMNormalizer implements XMLDocumentHandler { * @exception XNIException * Thrown by handler to signal an error. */ - public void startElement(QName element, XMLAttributes attributes, Augmentations augs) - throws XNIException { - Element currentElement = (Element) fCurrentNode; - int attrCount = attributes.getLength(); + public void startElement(QName element, XMLAttributes attributes, Augmentations augs) + throws XNIException { + Element currentElement = (Element) fCurrentNode; + int attrCount = attributes.getLength(); if (DEBUG_EVENTS) { System.out.println("==>startElement: " +element+ - " attrs.length="+attrCount); + " attrs.length="+attrCount); } - for (int i = 0; i < attrCount; i++) { - attributes.getName(i, fAttrQName); - Attr attr = null; + for (int i = 0; i < attrCount; i++) { + attributes.getName(i, fAttrQName); + Attr attr = null; - attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart); + attr = currentElement.getAttributeNodeNS(fAttrQName.uri, fAttrQName.localpart); + if (attr == null) { + // Must be a non-namespace aware DOM Level 1 node. + attr = currentElement.getAttributeNode(fAttrQName.rawname); + } AttributePSVI attrPSVI = - (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI); + (AttributePSVI) attributes.getAugmentations(i).getItem(Constants.ATTRIBUTE_PSVI); - if (attrPSVI != null) { + if (attrPSVI != null) { //REVISIT: instead we should be using augmentations: // to set/retrieve Id attributes XSTypeDefinition decl = attrPSVI.getMemberTypeDefinition(); boolean id = false; - if (decl != null){ + if (decl != null) { id = ((XSSimpleType)decl).isIDType(); - } else{ + } + else { decl = attrPSVI.getTypeDefinition(); - if (decl !=null){ - id = ((XSSimpleType)decl).isIDType(); + if (decl != null) { + id = ((XSSimpleType)decl).isIDType(); } } - if (id){ + if (id) { ((ElementImpl)currentElement).setIdAttributeNode(attr, true); } - if (fPSVI) { - ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI); - } - if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) { - // datatype-normalization - // NOTE: The specified value MUST be set after we set - // the node value because that turns the "specified" - // flag to "true" which may overwrite a "false" - // value from the attribute list. - boolean specified = attr.getSpecified(); - attr.setValue(attrPSVI.getSchemaValue().getNormalizedValue()); - if (!specified) { - ((AttrImpl) attr).setSpecified(specified); - } - } + if (fPSVI) { + ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI); + } + + // Updating the TypeInfo for this attribute. + ((AttrImpl) attr).setType(decl); + + if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) { + // datatype-normalization + // NOTE: The specified value MUST be set after we set + // the node value because that turns the "specified" + // flag to "true" which may overwrite a "false" + // value from the attribute list. + final String normalizedValue = attrPSVI.getSchemaValue().getNormalizedValue(); + if (normalizedValue != null) { + boolean specified = attr.getSpecified(); + attr.setValue(normalizedValue); + if (!specified) { + ((AttrImpl) attr).setSpecified(specified); } + } + } + } + else { // DTD + String type = null; + boolean isDeclared = Boolean.TRUE.equals(attributes.getAugmentations(i).getItem (Constants.ATTRIBUTE_DECLARED)); + // For DOM Level 3 TypeInfo, the type name must + // be null if this attribute has not been declared + // in the DTD. + if (isDeclared) { + type = attributes.getType(i); + if ("ID".equals (type)) { + ((ElementImpl) currentElement).setIdAttributeNode(attr, true); + } } + // Updating the TypeInfo for this attribute. + ((AttrImpl) attr).setType(type); + } } + } /** @@ -1948,7 +2000,7 @@ public class DOMNormalizer implements XMLDocumentHandler { * Thrown by handler to signal an error. */ public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException{ - allWhitespace = true; + fAllWhitespace = true; } /** @@ -1960,38 +2012,51 @@ public class DOMNormalizer implements XMLDocumentHandler { * @exception XNIException * Thrown by handler to signal an error. */ - public void endElement(QName element, Augmentations augs) throws XNIException { - if (DEBUG_EVENTS) { - System.out.println("==>endElement: " + element); - } + public void endElement(QName element, Augmentations augs) throws XNIException { + if (DEBUG_EVENTS) { + System.out.println("==>endElement: " + element); + } - if(augs != null) { - ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI); - if (elementPSVI != null) { - ElementImpl elementNode = (ElementImpl) fCurrentNode; - if (fPSVI) { - ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI); - } - // include element default content (if one is available) - String normalizedValue = elementPSVI.getSchemaValue().getNormalizedValue(); - if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) { + if (augs != null) { + ElementPSVI elementPSVI = (ElementPSVI) augs.getItem(Constants.ELEMENT_PSVI); + if (elementPSVI != null) { + ElementImpl elementNode = (ElementImpl) fCurrentNode; + if (fPSVI) { + ((PSVIElementNSImpl) fCurrentNode).setPSVI(elementPSVI); + } + // Updating the TypeInfo for this element. + if (elementNode instanceof ElementNSImpl) { + XSTypeDefinition type = elementPSVI.getMemberTypeDefinition(); + if (type == null) { + type = elementPSVI.getTypeDefinition(); + } + ((ElementNSImpl) elementNode).setType(type); + } + // include element default content (if one is available) + String normalizedValue = elementPSVI.getSchemaValue().getNormalizedValue(); + if ((fConfiguration.features & DOMConfigurationImpl.DTNORMALIZATION) != 0) { if (normalizedValue !=null) - elementNode.setTextContent(normalizedValue); - } - else { - // NOTE: this is a hack: it is possible that DOM had an empty element - // and validator sent default value using characters(), which we don't - // implement. Thus, here we attempt to add the default value. - String text = elementNode.getTextContent(); - if (text.length() == 0) { - // default content could be provided + elementNode.setTextContent(normalizedValue); + } + else { + // NOTE: this is a hack: it is possible that DOM had an empty element + // and validator sent default value using characters(), which we don't + // implement. Thus, here we attempt to add the default value. + String text = elementNode.getTextContent(); + if (text.length() == 0) { + // default content could be provided if (normalizedValue !=null) elementNode.setTextContent(normalizedValue); - } - } + } } + return; + } } + // DTD; elements have no type. + if (fCurrentNode instanceof ElementNSImpl) { + ((ElementNSImpl) fCurrentNode).setType(null); } + } /** diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java index c8cc9c2bcd93f7d33d3c48bce72edb92d2b1e2aa..e9b2fb37337a5bb272e3ab8f8ce9f08e36b0043d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java @@ -69,7 +69,7 @@ public class DeferredDocumentImpl // protected /** Chunk shift. */ - protected static final int CHUNK_SHIFT = 8; // 2^8 = 256 + protected static final int CHUNK_SHIFT = 11; // 2^11 = 2k /** Chunk size. */ protected static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); @@ -78,7 +78,7 @@ public class DeferredDocumentImpl protected static final int CHUNK_MASK = CHUNK_SIZE - 1; /** Initial chunk size. */ - protected static final int INITIAL_CHUNK_COUNT = (1 << (13 - CHUNK_SHIFT)); // 32 + protected static final int INITIAL_CHUNK_COUNT = (1 << (16 - CHUNK_SHIFT)); // 2^16 = 64k // // Data diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java index 6bec51bbca8aff0bf1ab27c85ab7176e1190f830..ca2a5b198edcde13979ddec8969ed2d8f4968a67 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/DocumentTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -56,6 +56,7 @@ import org.w3c.dom.UserDataHandler; * @author Joe Kesselman, IBM * @author Andy Clark, IBM * @since PR-DOM-Level-1-19980818. + * @LastModified: Apr 2019 */ public class DocumentTypeImpl extends ParentNode @@ -324,7 +325,7 @@ public class DocumentTypeImpl Node entNode2 = argEntities.getNamedItem(entNode1.getNodeName()); - if (!((NodeImpl) entNode1).isEqualNode((NodeImpl) entNode2)) + if (!((NodeImpl) entNode1).isEqualNode(entNode2)) return false; } } @@ -344,7 +345,7 @@ public class DocumentTypeImpl Node noteNode2 = argNotations.getNamedItem(noteNode1.getNodeName()); - if (!((NodeImpl) noteNode1).isEqualNode((NodeImpl) noteNode2)) + if (!((NodeImpl) noteNode1).isEqualNode(noteNode2)) return false; } } @@ -357,7 +358,7 @@ public class DocumentTypeImpl * NON-DOM * set the ownerDocument of this node and its children */ - void setOwnerDocument(CoreDocumentImpl doc) { + protected void setOwnerDocument(CoreDocumentImpl doc) { super.setOwnerDocument(doc); entities.setOwnerDocument(doc); notations.setOwnerDocument(doc); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java index 35c3e81698d7f4964a49c52d2871b5a499708bfe..a71e7088f81dfa96cf540c1a7045285573e2c739 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementImpl.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -55,38 +54,33 @@ import com.sun.org.apache.xerces.internal.util.URI; * @author Andy Clark, IBM * @author Ralf Pfeiffer, IBM * @since PR-DOM-Level-1-19980818. + * @LastModified: Apr 2019 */ public class ElementImpl - extends ParentNode - implements Element, ElementTraversal, TypeInfo { + extends ParentNode + implements Element, ElementTraversal, TypeInfo { // // Constants // - /** - * Serialization version. - */ + + /** Serialization version. */ static final long serialVersionUID = 3717253516652722278L; // // Data // - /** - * Element name. - */ + /** Element name. */ protected String name; - /** - * Attributes. - */ + /** Attributes. */ protected AttributeMap attributes; // // Constructors // - /** - * Factory constructor. - */ + + /** Factory constructor. */ public ElementImpl(CoreDocumentImpl ownerDoc, String name) { super(ownerDoc); this.name = name; @@ -94,8 +88,7 @@ public class ElementImpl } // for ElementNSImpl - protected ElementImpl() { - } + protected ElementImpl() {} // Support for DOM Level 3 renameNode method. // Note: This only deals with part of the pb. CoreDocumentImpl @@ -109,9 +102,9 @@ public class ElementImpl if (colon1 != -1) { String msg = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "NAMESPACE_ERR", - null); + DOMMessageFormatter.DOM_DOMAIN, + "NAMESPACE_ERR", + null); throw new DOMException(DOMException.NAMESPACE_ERR, msg); } if (!CoreDocumentImpl.isXMLName(name, ownerDocument.isXML11Version())) { @@ -287,7 +280,7 @@ public class ElementImpl if (attributes == null) { return ""; } - Attr attr = (Attr) (attributes.getNamedItem(name)); + Attr attr = (Attr)(attributes.getNamedItem(name)); return (attr == null) ? "" : attr.getValue(); } // getAttribute(String):String @@ -307,7 +300,7 @@ public class ElementImpl if (attributes == null) { return null; } - return (Attr) attributes.getNamedItem(name); + return (Attr)attributes.getNamedItem(name); } // getAttributeNode(String):Attr @@ -453,7 +446,7 @@ public class ElementImpl * readonly. */ public Attr removeAttributeNode(Attr oldAttr) - throws DOMException { + throws DOMException { if (ownerDocument.errorChecking && isReadOnly()) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); @@ -491,36 +484,35 @@ public class ElementImpl * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if the node is * readonly. */ - public void setAttribute(String name, String value) { - - if (ownerDocument.errorChecking && isReadOnly()) { - String msg - = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "NO_MODIFICATION_ALLOWED_ERR", - null); - throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); - } + public void setAttribute(String name, String value) { + + if (ownerDocument.errorChecking && isReadOnly()) { + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "NO_MODIFICATION_ALLOWED_ERR", + null); + throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); + } - if (needsSyncData()) { - synchronizeData(); - } + if (needsSyncData()) { + synchronizeData(); + } - Attr newAttr = getAttributeNode(name); - if (newAttr == null) { - newAttr = getOwnerDocument().createAttribute(name); + Attr newAttr = getAttributeNode(name); + if (newAttr == null) { + newAttr = getOwnerDocument().createAttribute(name); - if (attributes == null) { - attributes = new AttributeMap(this, null); - } + if (attributes == null) { + attributes = new AttributeMap(this, null); + } - newAttr.setNodeValue(value); - attributes.setNamedItem(newAttr); - } else { - newAttr.setNodeValue(value); - } + newAttr.setNodeValue(value); + attributes.setNamedItem(newAttr); + } else { + newAttr.setNodeValue(value); + } - } // setAttribute(String,String) + } // setAttribute(String,String) /** * Add a new attribute/value pair, or replace the value of the existing @@ -546,13 +538,13 @@ public class ElementImpl if (isReadOnly()) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); throw new DOMException( - DOMException.NO_MODIFICATION_ALLOWED_ERR, - msg); + DOMException.NO_MODIFICATION_ALLOWED_ERR, + msg); } if (newAttr.getOwnerDocument() != ownerDocument) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null); - throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg); + throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg); } } @@ -589,7 +581,7 @@ public class ElementImpl return ""; } - Attr attr = (Attr) (attributes.getNamedItemNS(namespaceURI, localName)); + Attr attr = (Attr)(attributes.getNamedItemNS(namespaceURI, localName)); return (attr == null) ? "" : attr.getValue(); } // getAttributeNS(String,String):String @@ -633,41 +625,38 @@ public class ElementImpl * @since WD-DOM-Level-2-19990923 */ public void setAttributeNS(String namespaceURI, String qualifiedName, - String value) { - if (ownerDocument.errorChecking && isReadOnly()) { - String msg - = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "NO_MODIFICATION_ALLOWED_ERR", - null); - throw new DOMException( - DOMException.NO_MODIFICATION_ALLOWED_ERR, - msg); - } - if (needsSyncData()) { - synchronizeData(); - } - int index = qualifiedName.indexOf(':'); - String prefix, localName; - if (index < 0) { - prefix = null; - localName = qualifiedName; - } else { - prefix = qualifiedName.substring(0, index); - localName = qualifiedName.substring(index + 1); - } - Attr newAttr = getAttributeNodeNS(namespaceURI, localName); - if (newAttr == null) { + String value) { + if (ownerDocument.errorChecking && isReadOnly()) { + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, + "NO_MODIFICATION_ALLOWED_ERR", + null); + throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); + } + if (needsSyncData()) { + synchronizeData(); + } + int index = qualifiedName.indexOf(':'); + String prefix, localName; + if (index < 0) { + prefix = null; + localName = qualifiedName; + } else { + prefix = qualifiedName.substring(0, index); + localName = qualifiedName.substring(index + 1); + } + Attr newAttr = getAttributeNodeNS(namespaceURI, localName); + if (newAttr == null) { // REVISIT: this is not efficient, we are creating twice the same // strings for prefix and localName. - newAttr = getOwnerDocument().createAttributeNS( - namespaceURI, - qualifiedName); - if (attributes == null) { - attributes = new AttributeMap(this, null); - } - newAttr.setNodeValue(value); - attributes.setNamedItemNS(newAttr); + newAttr = getOwnerDocument().createAttributeNS( + namespaceURI, + qualifiedName); + if (attributes == null) { + attributes = new AttributeMap(this, null); + } + newAttr.setNodeValue(value); + attributes.setNamedItemNS(newAttr); } else { if (newAttr instanceof AttrNSImpl){ @@ -693,12 +682,12 @@ public class ElementImpl // This case is not defined by the DOM spec, we choose // to create a new attribute in this case and remove an old one from the tree // note this might cause events to be propagated or user data to be lost - newAttr = new AttrNSImpl((CoreDocumentImpl)getOwnerDocument(), namespaceURI, qualifiedName, localName); + newAttr = ((CoreDocumentImpl)getOwnerDocument()).createAttributeNS(namespaceURI, qualifiedName, localName); attributes.setNamedItemNS(newAttr); } - newAttr.setNodeValue(value); - } + newAttr.setNodeValue(value); + } } // setAttributeNS(String,String,String) @@ -753,7 +742,7 @@ public class ElementImpl if (attributes == null) { return null; } - return (Attr) attributes.getNamedItemNS(namespaceURI, localName); + return (Attr)attributes.getNamedItemNS(namespaceURI, localName); } // getAttributeNodeNS(String,String):Attr @@ -788,9 +777,9 @@ public class ElementImpl if (ownerDocument.errorChecking) { if (isReadOnly()) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); - throw new DOMException( - DOMException.NO_MODIFICATION_ALLOWED_ERR, - msg); + throw new DOMException( + DOMException.NO_MODIFICATION_ALLOWED_ERR, + msg); } if (newAttr.getOwnerDocument() != ownerDocument) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null); @@ -807,8 +796,8 @@ public class ElementImpl } // setAttributeNodeNS(Attr):Attr /** - * NON-DOM: sets attribute node for this element - */ + * NON-DOM: sets attribute node for this element + */ protected int setXercesAttributeNode(Attr attr) { if (needsSyncData()) { @@ -823,8 +812,8 @@ public class ElementImpl } /** - * NON-DOM: get inded of an attribute - */ + * NON-DOM: get inded of an attribute + */ protected int getXercesAttribute(String namespaceURI, String localName) { if (needsSyncData()) { @@ -879,7 +868,7 @@ public class ElementImpl * @since WD-DOM-Level-2-19990923 */ public NodeList getElementsByTagNameNS(String namespaceURI, - String localName) { + String localName) { return new DeepNodeListImpl(this, namespaceURI, localName); } @@ -911,7 +900,7 @@ public class ElementImpl } } else { Node n2 = map2.getNamedItemNS(n1.getNamespaceURI(), - n1.getLocalName()); + n1.getLocalName()); if (n2 == null || !((NodeImpl) n1).isEqualNode(n2)) { return false; } @@ -930,14 +919,15 @@ public class ElementImpl } if (ownerDocument.errorChecking) { if (isReadOnly()) { - String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); throw new DOMException( - DOMException.NO_MODIFICATION_ALLOWED_ERR, - msg); + DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); } if (at.getOwnerElement() != this) { - String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); throw new DOMException(DOMException.NOT_FOUND_ERR, msg); } } @@ -959,22 +949,21 @@ public class ElementImpl Attr at = getAttributeNode(name); if (at == null) { - String msg = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "NOT_FOUND_ERR", null); + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); throw new DOMException(DOMException.NOT_FOUND_ERR, msg); - } + } if (ownerDocument.errorChecking) { if (isReadOnly()) { - String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); - throw new DOMException( - DOMException.NO_MODIFICATION_ALLOWED_ERR, - msg); + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); + throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg); } if (at.getOwnerElement() != this) { - String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); throw new DOMException(DOMException.NOT_FOUND_ERR, msg); } } @@ -991,7 +980,7 @@ public class ElementImpl * DOM Level 3: register the given attribute node as an ID attribute */ public void setIdAttributeNS(String namespaceURI, String localName, - boolean makeId) { + boolean makeId) { if (needsSyncData()) { synchronizeData(); } @@ -1002,19 +991,18 @@ public class ElementImpl Attr at = getAttributeNodeNS(namespaceURI, localName); if (at == null) { - String msg = DOMMessageFormatter.formatMessage( - DOMMessageFormatter.DOM_DOMAIN, - "NOT_FOUND_ERR", null); + String msg = DOMMessageFormatter.formatMessage( + DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null); throw new DOMException(DOMException.NOT_FOUND_ERR, msg); - } + } - if (ownerDocument.errorChecking) { + if (ownerDocument.errorChecking) { if (isReadOnly()) { String msg = DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null); throw new DOMException( - DOMException.NO_MODIFICATION_ALLOWED_ERR, - msg); + DOMException.NO_MODIFICATION_ALLOWED_ERR, + msg); } if (at.getOwnerElement() != this) { @@ -1029,14 +1017,14 @@ public class ElementImpl } else { ownerDocument.putIdentifier(at.getValue(), this); } - } + } /** * @see org.w3c.dom.TypeInfo#getTypeName() */ - public String getTypeName() { + public String getTypeName() { return null; - } + } /** * @see org.w3c.dom.TypeInfo#getTypeNamespace() @@ -1059,17 +1047,16 @@ public class ElementImpl * reference type */ public boolean isDerivedFrom(String typeNamespaceArg, - String typeNameArg, - int derivationMethod) { + String typeNameArg, + int derivationMethod) { return false; } - /** - * Method getSchemaTypeInfo. - * - * @return TypeInfo - */ + /** + * Method getSchemaTypeInfo. + * @return TypeInfo + */ public TypeInfo getSchemaTypeInfo() { if (needsSyncData()) { synchronizeData(); @@ -1159,8 +1146,7 @@ public class ElementImpl if (doctype == null) { return null; } - ElementDefinitionImpl eldef - = (ElementDefinitionImpl) doctype.getElements() + ElementDefinitionImpl eldef = (ElementDefinitionImpl)doctype.getElements() .getNamedItem(getNodeName()); if (eldef == null) { return null; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java index 6a76152555d686208efd95689d93d2926a97d620..ea1a49d5a242571481d03136a640cc4bbd2f4466 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ElementNSImpl.java @@ -86,13 +86,13 @@ public class ElementNSImpl private void setName(String namespaceURI, String qname) { - String prefix; - // DOM Level 3: namespace URI is never empty string. - this.namespaceURI = namespaceURI; - if (namespaceURI != null) { + String prefix; + // DOM Level 3: namespace URI is never empty string. + this.namespaceURI = namespaceURI; + if (namespaceURI != null) { //convert the empty string to 'null' - this.namespaceURI = (namespaceURI.length() == 0) ? null : namespaceURI; - } + this.namespaceURI = (namespaceURI.length() == 0) ? null : namespaceURI; + } int colon1, colon2 ; @@ -190,37 +190,6 @@ public class ElementNSImpl reconcileDefaultAttributes(); } - /** - * NON-DOM: resets this node and sets specified values for the node - * - * @param ownerDocument - * @param namespaceURI - * @param qualifiedName - * @param localName - */ - protected void setValues (CoreDocumentImpl ownerDocument, - String namespaceURI, String qualifiedName, - String localName){ - - // remove children first - firstChild = null; - previousSibling = null; - nextSibling = null; - fNodeListCache = null; - - // set owner document - attributes = null; - super.flags = 0; - setOwnerDocument(ownerDocument); - - // synchronizeData will initialize attributes - needsSyncData(true); - super.name = qualifiedName; - this.localName = localName; - this.namespaceURI = namespaceURI; - - } - // // Node methods // @@ -340,88 +309,13 @@ public class ElementNSImpl return localName; } - - /** - * DOM Level 3 WD - Experimental. - * Retrieve baseURI + /** + * NON-DOM + * Returns the xml:base attribute. */ - public String getBaseURI() { - - if (needsSyncData()) { - synchronizeData(); - } - // Absolute base URI is computed according to XML Base (http://www.w3.org/TR/xmlbase/#granularity) - - // 1. the base URI specified by an xml:base attribute on the element, if one exists - - if (attributes != null) { - Attr attrNode = (Attr)attributes.getNamedItemNS("http://www.w3.org/XML/1998/namespace", "base"); - if (attrNode != null) { - String uri = attrNode.getNodeValue(); - if (uri.length() != 0 ) {// attribute value is always empty string - try { - uri = new URI(uri).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e) { - // This may be a relative URI. - - // Start from the base URI of the parent, or if this node has no parent, the owner node. - NodeImpl parentOrOwner = (parentNode() != null) ? parentNode() : ownerNode; - - // Make any parentURI into a URI object to use with the URI(URI, String) constructor. - String parentBaseURI = (parentOrOwner != null) ? parentOrOwner.getBaseURI() : null; - - if (parentBaseURI != null) { - try { - uri = new URI(new URI(parentBaseURI), uri).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException ex){ - // This should never happen: parent should have checked the URI and returned null if invalid. - return null; - } - return uri; - } - // REVISIT: what should happen in this case? - return null; - } - return uri; - } - } - } - - //2.the base URI of the element's parent element within the document or external entity, - //if one exists - String parentElementBaseURI = (this.parentNode() != null) ? this.parentNode().getBaseURI() : null ; - //base URI of parent element is not null - if(parentElementBaseURI != null){ - try { - //return valid absolute base URI - return new URI(parentElementBaseURI).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){ - // REVISIT: what should happen in this case? - return null; - } - } - //3. the base URI of the document entity or external entity containing the element - - String baseURI = (this.ownerNode != null) ? this.ownerNode.getBaseURI() : null ; - - if(baseURI != null){ - try { - //return valid absolute base URI - return new URI(baseURI).toString(); - } - catch (com.sun.org.apache.xerces.internal.util.URI.MalformedURIException e){ - // REVISIT: what should happen in this case? - return null; - } - } - - return null; - - } - + protected Attr getXMLBaseAttribute() { + return (Attr) attributes.getNamedItemNS("http://www.w3.org/XML/1998/namespace", "base"); + } // getXMLBaseAttribute():Attr /** * @see org.w3c.dom.TypeInfo#getTypeName() @@ -452,12 +346,12 @@ public class ElementNSImpl * Checks if a type is derived from another by restriction. See: * http://www.w3.org/TR/DOM-Level-3-Core/core.html#TypeInfo-isDerivedFrom * - * @param ancestorNS + * @param typeNamespaceArg * The namspace of the ancestor type declaration - * @param ancestorName + * @param typeNameArg * The name of the ancestor type declaration - * @param type - * The reference type definition + * @param derivationMethod + * The derivation method * * @return boolean True if the type is derived by restriciton for the * reference type diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java index d158f18170b54a6eb0fc976d883480879929bf26..e0f808dbd83ef242e196d37a8e5b5c038abf6382 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/NodeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -27,6 +27,7 @@ import java.util.Map; import org.w3c.dom.DOMException; 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; @@ -78,6 +79,7 @@ import org.w3c.dom.events.EventTarget; * @author Arnaud Le Hors, IBM * @author Joe Kesselman, IBM * @since PR-DOM-Level-1-19980818. + * @LastModified: Apr 2019 */ public abstract class NodeImpl implements Node, NodeList, EventTarget, Cloneable, Serializable{ @@ -122,15 +124,6 @@ public abstract class NodeImpl */ public static final short TREE_POSITION_DISCONNECTED = 0x00; - - // DocumentPosition - public static final short DOCUMENT_POSITION_DISCONNECTED = 0x01; - public static final short DOCUMENT_POSITION_PRECEDING = 0x02; - public static final short DOCUMENT_POSITION_FOLLOWING = 0x04; - public static final short DOCUMENT_POSITION_CONTAINS = 0x08; - public static final short DOCUMENT_POSITION_IS_CONTAINED = 0x10; - public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - /** Serialization version. */ static final long serialVersionUID = -6316591992167219696L; @@ -324,7 +317,7 @@ public abstract class NodeImpl * NON-DOM * set the ownerDocument of this node */ - void setOwnerDocument(CoreDocumentImpl doc) { + protected void setOwnerDocument(CoreDocumentImpl doc) { if (needsSyncData()) { synchronizeData(); } @@ -559,7 +552,7 @@ public abstract class NodeImpl * @see ParentNode * * @return org.w3c.dom.Node - * @param Index int + * @param index int */ public Node item(int index) { return null; @@ -976,9 +969,7 @@ public abstract class NodeImpl return 0; // check if other is from a different implementation - try { - NodeImpl node = (NodeImpl) other; - } catch (ClassCastException e) { + if (other != null && !(other instanceof NodeImpl)) { // other comes from a different implementation String msg = DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null); @@ -1041,7 +1032,7 @@ public abstract class NodeImpl otherDepth +=1; if (node == this) // The other node is a descendent of the reference node. - return (DOCUMENT_POSITION_IS_CONTAINED | + return (DOCUMENT_POSITION_CONTAINED_BY | DOCUMENT_POSITION_FOLLOWING); otherAncestor = node; } @@ -1131,7 +1122,7 @@ public abstract class NodeImpl case Node.NOTATION_NODE: case Node.ENTITY_NODE: { DocumentType container = thisOwnerDoc.getDoctype(); - if (container == this) return (DOCUMENT_POSITION_IS_CONTAINED | + if (container == this) return (DOCUMENT_POSITION_CONTAINED_BY | DOCUMENT_POSITION_FOLLOWING); otherNode = otherAncestor = thisOwnerDoc; break; @@ -1139,7 +1130,7 @@ public abstract class NodeImpl case Node.DOCUMENT_TYPE_NODE: { if (thisNode == otherOwnerDoc) return (DOCUMENT_POSITION_FOLLOWING | - DOCUMENT_POSITION_IS_CONTAINED); + DOCUMENT_POSITION_CONTAINED_BY); else if (otherOwnerDoc!=null && thisOwnerDoc==otherOwnerDoc) return (DOCUMENT_POSITION_PRECEDING); break; @@ -1153,7 +1144,7 @@ public abstract class NodeImpl // The other node is a descendent of the reference // node's element return DOCUMENT_POSITION_FOLLOWING | - DOCUMENT_POSITION_IS_CONTAINED; + DOCUMENT_POSITION_CONTAINED_BY; otherAncestor = node; } @@ -1302,8 +1293,8 @@ public abstract class NodeImpl return getNodeValue(); // overriden in some subclasses } - // internal method taking a StringBuffer in parameter - void getTextContent(StringBuffer buf) throws DOMException { + // internal method taking a StringBuilder in parameter + void getTextContent(StringBuilder buf) throws DOMException { String content = getNodeValue(); if (content != null) { buf.append(content); @@ -1425,7 +1416,11 @@ public abstract class NodeImpl return false; } case Node.DOCUMENT_NODE:{ - return((NodeImpl)((Document)this).getDocumentElement()).isDefaultNamespace(namespaceURI); + Element docElement = ((Document)this).getDocumentElement(); + if (docElement != null) { + return docElement.isDefaultNamespace(namespaceURI); + } + return false; } case Node.ENTITY_NODE : @@ -1475,12 +1470,15 @@ public abstract class NodeImpl switch (type) { case Node.ELEMENT_NODE: { - - String namespace = this.getNamespaceURI(); // to flip out children + this.getNamespaceURI(); // to flip out children return lookupNamespacePrefix(namespaceURI, (ElementImpl)this); } case Node.DOCUMENT_NODE:{ - return((NodeImpl)((Document)this).getDocumentElement()).lookupPrefix(namespaceURI); + Element docElement = ((Document)this).getDocumentElement(); + if (docElement != null) { + return docElement.lookupPrefix(namespaceURI); + } + return null; } case Node.ENTITY_NODE : @@ -1511,8 +1509,8 @@ public abstract class NodeImpl * Look up the namespace URI associated to the given prefix, starting from this node. * Use lookupNamespaceURI(null) to lookup the default namespace * - * @param namespaceURI - * @return th URI for the namespace + * @param specifiedPrefix + * @return the URI for the namespace * @since DOM Level 3 */ public String lookupNamespaceURI(String specifiedPrefix) { @@ -1537,20 +1535,20 @@ public abstract class NodeImpl int length = map.getLength(); for (int i=0;i 0 ? value : null; } else if (attrPrefix !=null && attrPrefix.equals("xmlns") && attr.getLocalName().equals(specifiedPrefix)) { // non default namespace - return value; + return value.length() > 0 ? value : null; } } } @@ -1565,7 +1563,11 @@ public abstract class NodeImpl } case Node.DOCUMENT_NODE : { - return((NodeImpl)((Document)this).getDocumentElement()).lookupNamespaceURI(specifiedPrefix); + Element docElement = ((Document)this).getDocumentElement(); + if (docElement != null) { + return docElement.lookupNamespaceURI(specifiedPrefix); + } + return null; } case Node.ENTITY_NODE : case Node.NOTATION_NODE: @@ -1591,15 +1593,14 @@ public abstract class NodeImpl } } - - Node getElementAncestor (Node currentNode){ + Node getElementAncestor(Node currentNode) { Node parent = currentNode.getParentNode(); - if (parent != null) { + while (parent != null) { short type = parent.getNodeType(); if (type == Node.ELEMENT_NODE) { return parent; } - return getElementAncestor(parent); + parent = parent.getParentNode(); } return null; } @@ -1624,10 +1625,10 @@ public abstract class NodeImpl int length = map.getLength(); for (int i=0;iText nodes, as well as any user data or event listeners * registered on the nodes. * @param arg The node to compare equality with. - * @param deep If true, recursively compare the subtrees; if - * false, compare only the nodes themselves (and its - * attributes, if it is an Element). * @return If the nodes, and possibly subtrees are equal, * true otherwise false. * @since DOM Level 3 diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java index 2fae8652ef55550fe818d35c02888a0fb41cfdfd..9a74c607d3b67a746486e95d04ddc867b0fbc28f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/PSVIDOMImplementationImpl.java @@ -21,11 +21,8 @@ package com.sun.org.apache.xerces.internal.dom; -import org.w3c.dom.DOMException; import org.w3c.dom.DOMImplementation; -import org.w3c.dom.Document; import org.w3c.dom.DocumentType; -import org.w3c.dom.Element; /** * The DOMImplementation class is description of a particular @@ -40,7 +37,7 @@ import org.w3c.dom.Element; * * @since PR-DOM-Level-1-19980818. */ -public class PSVIDOMImplementationImpl extends CoreDOMImplementationImpl { +public class PSVIDOMImplementationImpl extends DOMImplementationImpl { // // Data @@ -49,7 +46,7 @@ public class PSVIDOMImplementationImpl extends CoreDOMImplementationImpl { // static /** Dom implementation singleton. */ - static PSVIDOMImplementationImpl singleton = new PSVIDOMImplementationImpl(); + static final PSVIDOMImplementationImpl singleton = new PSVIDOMImplementationImpl(); // // Public methods @@ -84,42 +81,12 @@ public class PSVIDOMImplementationImpl extends CoreDOMImplementationImpl { feature.equalsIgnoreCase("psvi"); } // hasFeature(String,String):boolean - /** - * Introduced in DOM Level 2.

- * - * Creates an XML Document object of the specified type with its document - * element. - * - * @param namespaceURI The namespace URI of the document - * element to create, or null. - * @param qualifiedName The qualified name of the document - * element to create. - * @param doctype The type of document to be created or null.

- * - * When doctype is not null, its - * Node.ownerDocument attribute is set to - * the document being created. - * @return Document A new Document object. - * @throws DOMException WRONG_DOCUMENT_ERR: Raised if doctype has - * already been used with a different document. - * @since WD-DOM-Level-2-19990923 - */ - public Document createDocument(String namespaceURI, - String qualifiedName, - DocumentType doctype) - throws DOMException - { - if (doctype != null && doctype.getOwnerDocument() != null) { - throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, - DOMMessageFormatter.formatMessage( - DOMMessageFormatter.XML_DOMAIN, - "WRONG_DOCUMENT_ERR", null)); - } - DocumentImpl doc = new PSVIDocumentImpl(doctype); - Element e = doc.createElementNS( namespaceURI, qualifiedName); - doc.appendChild(e); - return doc; - } + // + // Protected methods + // + protected CoreDocumentImpl createDocument(DocumentType doctype) { + return new PSVIDocumentImpl(doctype); + } -} // class DOMImplementationImpl +} // class PSVIDOMImplementationImpl diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java index 3949063a5abd83aa1e98cde91ca83222c3edb8f1..342b4b7ea3e1004b17bb0b2d83b8a11e348341e2 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/ParentNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -68,6 +68,7 @@ import org.w3c.dom.UserDataHandler; * @author Arnaud Le Hors, IBM * @author Joe Kesselman, IBM * @author Andy Clark, IBM + * @LastModified: Apr 2019 */ public abstract class ParentNode extends ChildNode { @@ -174,18 +175,16 @@ public abstract class ParentNode * NON-DOM * set the ownerDocument of this node and its children */ - void setOwnerDocument(CoreDocumentImpl doc) { + protected void setOwnerDocument(CoreDocumentImpl doc) { if (needsSyncChildren()) { synchronizeChildren(); } - for (ChildNode child = firstChild; - child != null; child = child.nextSibling) { - child.setOwnerDocument(doc); - } - /* setting the owner document of self, after it's children makes the - data of children available to the new document. */ super.setOwnerDocument(doc); ownerDocument = doc; + for (ChildNode child = firstChild; + child != null; child = child.nextSibling) { + child.setOwnerDocument(doc); + } } /** @@ -368,16 +367,14 @@ public abstract class ParentNode // Prevent cycles in the tree // newChild cannot be ancestor of this Node, // and actually cannot be this - if (ownerDocument.ancestorChecking) { - boolean treeSafe = true; - for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode()) - { - treeSafe = newChild != a; - } - if(!treeSafe) { - throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, - DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null)); - } + boolean treeSafe = true; + for (NodeImpl a = this; treeSafe && a != null; a = a.parentNode()) + { + treeSafe = newChild != a; + } + if(!treeSafe) { + throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, + DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null)); } } @@ -509,6 +506,9 @@ public abstract class ParentNode // notify document ownerDocument.removingNode(this, oldInternal, replace); + // Save previous sibling for normalization checking. + final ChildNode oldPreviousSibling = oldInternal.previousSibling(); + // update cached length if we have any if (fNodeListCache != null) { if (fNodeListCache.fLength != -1) { @@ -519,7 +519,7 @@ public abstract class ParentNode // move the cache to its (soon former) previous sibling if (fNodeListCache.fChild == oldInternal) { fNodeListCache.fChildIndex--; - fNodeListCache.fChild = oldInternal.previousSibling(); + fNodeListCache.fChild = oldPreviousSibling; } else { // otherwise just invalidate the cache fNodeListCache.fChildIndex = -1; @@ -550,9 +550,6 @@ public abstract class ParentNode } } - // Save previous sibling for normalization checking. - ChildNode oldPreviousSibling = oldInternal.previousSibling(); - // Remove oldInternal's references to tree oldInternal.ownerNode = ownerDocument; oldInternal.isOwned(false); @@ -624,20 +621,15 @@ public abstract class ParentNode if (next == null) { return hasTextContent(child) ? ((NodeImpl) child).getTextContent() : ""; } - if (fBufferStr == null){ - fBufferStr = new StringBuffer(); - } - else { - fBufferStr.setLength(0); - } - getTextContent(fBufferStr); - return fBufferStr.toString(); + StringBuilder buf = new StringBuilder(); + getTextContent(buf); + return buf.toString(); } return ""; } - // internal method taking a StringBuffer in parameter - void getTextContent(StringBuffer buf) throws DOMException { + // internal method taking a StringBuilder in parameter + void getTextContent(StringBuilder buf) throws DOMException { Node child = getFirstChild(); while (child != null) { if (hasTextContent(child)) { @@ -684,6 +676,9 @@ public abstract class ParentNode private int nodeListGetLength() { if (fNodeListCache == null) { + if (needsSyncChildren()) { + synchronizeChildren(); + } // get rid of trivial cases if (firstChild == null) { return 0; @@ -733,6 +728,9 @@ public abstract class ParentNode private Node nodeListItem(int index) { if (fNodeListCache == null) { + if (needsSyncChildren()) { + synchronizeChildren(); + } // get rid of trivial case if (firstChild == lastChild()) { return index == 0 ? firstChild : null; @@ -870,7 +868,7 @@ public abstract class ParentNode Node child1 = getFirstChild(); Node child2 = arg.getFirstChild(); while (child1 != null && child2 != null) { - if (!((NodeImpl) child1).isEqualNode(child2)) { + if (!child1.isEqualNode(child2)) { return false; } child1 = child1.getNextSibling(); @@ -997,7 +995,7 @@ public abstract class ParentNode /** Serialize object. */ private void writeObject(ObjectOutputStream out) throws IOException { - // synchronize chilren + // synchronize children if (needsSyncChildren()) { synchronizeChildren(); } @@ -1022,7 +1020,7 @@ public abstract class ParentNode /* * a class to store some user data along with its handler */ - protected class UserDataRecord implements Serializable { + class UserDataRecord implements Serializable { /** Serialization version. */ private static final long serialVersionUID = 3258126977134310455L; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java index 19cb05dd0fc37b47ceb144cd0a98687ab9c5c57e..028c3e610f4c027329de4329402b0261901787e2 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/TextImpl.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,6 +41,7 @@ import org.w3c.dom.Text; * @xerces.internal * * @since PR-DOM-Level-1-19980818. + * @LastModified: Apr 2019 */ public class TextImpl extends CharacterDataImpl @@ -146,37 +146,32 @@ public class TextImpl synchronizeData(); } - if (fBufferStr == null){ - fBufferStr = new StringBuffer(); - } - else { - fBufferStr.setLength(0); - } + StringBuilder buffer = new StringBuilder(); if (data != null && data.length() != 0) { - fBufferStr.append(data); + buffer.append(data); } - //concatenate text of logically adjacent text nodes to the left of this node in the tree - getWholeTextBackward(this.getPreviousSibling(), fBufferStr, this.getParentNode()); - String temp = fBufferStr.toString(); + // concatenate text of logically adjacent text nodes to the left of this node in the tree + getWholeTextBackward(this.getPreviousSibling(), buffer, this.getParentNode()); + String temp = buffer.toString(); - //clear buffer - fBufferStr.setLength(0); + // clear buffer + buffer.setLength(0); - //concatenate text of logically adjacent text nodes to the right of this node in the tree - getWholeTextForward(this.getNextSibling(), fBufferStr, this.getParentNode()); + // concatenate text of logically adjacent text nodes to the right of this node in the tree + getWholeTextForward(this.getNextSibling(), buffer, this.getParentNode()); - return temp + fBufferStr.toString(); + return temp + buffer.toString(); } /** - * internal method taking a StringBuffer in parameter and inserts the + * internal method taking a StringBuilder in parameter and inserts the * text content at the start of the buffer * * @param buf */ - protected void insertTextContent(StringBuffer buf) throws DOMException { + protected void insertTextContent(StringBuilder buf) throws DOMException { String content = getNodeValue(); if (content != null) { buf.insert(0, content); @@ -193,7 +188,7 @@ public class TextImpl * other than EntityRef, Text, CDATA is encountered, otherwise * return false */ - private boolean getWholeTextForward(Node node, StringBuffer buffer, Node parent){ + private boolean getWholeTextForward(Node node, StringBuilder buffer, Node parent){ // boolean to indicate whether node is a child of an entity reference boolean inEntRef = false; @@ -240,7 +235,7 @@ public class TextImpl * other than EntityRef, Text, CDATA is encountered, otherwise * return false */ - private boolean getWholeTextBackward(Node node, StringBuffer buffer, Node parent){ + private boolean getWholeTextBackward(Node node, StringBuilder buffer, Node parent){ // boolean to indicate whether node is a child of an entity reference boolean inEntRef = false; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java index 7eca1d312da83233367a6f775761238fe0cb223e..377bb108750bebd228dddb5f32e39c25d38de307 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/util/ParserConfigurationSettings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -23,11 +23,11 @@ package com.sun.org.apache.xerces.internal.util; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; -import java.util.HashSet; +import java.util.List; import java.util.Map; -import java.util.Set; /** * This class implements the basic operations for managing parser @@ -42,6 +42,7 @@ import java.util.Set; * * @author Andy Clark, IBM * + * @LastModified: Apr 2019 */ public class ParserConfigurationSettings implements XMLComponentManager { @@ -56,13 +57,13 @@ public class ParserConfigurationSettings // data /** Recognized properties. */ - protected Set fRecognizedProperties; + protected List fRecognizedProperties; /** Properties. */ protected Map fProperties; /** Recognized features. */ - protected Set fRecognizedFeatures; + protected List fRecognizedFeatures; /** Features. */ protected Map fFeatures; @@ -86,8 +87,8 @@ public class ParserConfigurationSettings public ParserConfigurationSettings(XMLComponentManager parent) { // create storage for recognized features and properties - fRecognizedFeatures = new HashSet<>(); - fRecognizedProperties = new HashSet<>(); + fRecognizedFeatures = new ArrayList<>(); + fRecognizedProperties = new ArrayList<>(); // create table for features and properties fFeatures = new HashMap<>(); @@ -195,7 +196,7 @@ public class ParserConfigurationSettings * a critical error. */ @Override - public final boolean getFeature(String featureId) + public boolean getFeature(String featureId) throws XMLConfigurationException { FeatureState state = getFeatureState(featureId); @@ -222,7 +223,7 @@ public class ParserConfigurationSettings FeatureState checkState = checkFeature(featureId); if (checkState.isExceptional()) { return checkState; - } + } return FeatureState.is(false); } return FeatureState.is(state); @@ -241,7 +242,7 @@ public class ParserConfigurationSettings * a critical error. */ @Override - public final Object getProperty(String propertyId) + public Object getProperty(String propertyId) throws XMLConfigurationException { PropertyState state = getPropertyState(propertyId); @@ -270,7 +271,7 @@ public class ParserConfigurationSettings PropertyState state = checkProperty(propertyId); if (state.isExceptional()) { return state; - } + } } return PropertyState.is(propertyValue); @@ -325,7 +326,7 @@ public class ParserConfigurationSettings PropertyState state = fParentSettings.getPropertyState(propertyId); if (state.isExceptional()) { return state; - } + } } else { return PropertyState.NOT_RECOGNIZED; diff --git a/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java b/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java index 59e1ffdaf446780a01bd69f9fd8a25202e4c6e14..bd8cb264141aadd9f3df82959996e403d69f2e4f 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/dom/DocumentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,8 +22,12 @@ */ package dom; +import com.sun.org.apache.xerces.internal.dom.AttrImpl; +import com.sun.org.apache.xerces.internal.dom.DocumentImpl; +import com.sun.org.apache.xerces.internal.dom.ElementImpl; +import com.sun.org.apache.xerces.internal.dom.events.MutationEventImpl; +import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl; import java.io.ByteArrayInputStream; -import java.io.IOException; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -33,20 +37,24 @@ import org.testng.annotations.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; -import org.xml.sax.SAXException; +import org.w3c.dom.events.Event; +import org.w3c.dom.events.EventListener; /* * @test - * @bug 8213117 + * @bug 8213117 8222743 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest + * @modules java.xml + * @modules java.xml/com.sun.org.apache.xerces.internal.dom + * @modules java.xml/com.sun.org.apache.xerces.internal.dom.events + * @modules java.xml/com.sun.org.apache.xerces.internal.jaxp * @run testng dom.DocumentTest * @summary Tests functionalities for Document. */ @Listeners({jaxp.library.BasePolicy.class}) public class DocumentTest { - - private static final String XML1 = ""; - private static final String XML2 = ""; + static final int DOC1 = 1; + static final int DOC2 = 2; /** * Verifies the adoptNode method. Before a node from a deferred DOM can be @@ -54,12 +62,11 @@ public class DocumentTest { */ @Test public void testAdoptNode() throws Exception { + String xml1 = ""; + String xml2 = ""; - DocumentBuilder builder = DocumentBuilderFactory.newInstance() - .newDocumentBuilder(); - - Document doc1 = getDocument(builder, XML1); - Document doc2 = getDocument(builder, XML2); + Document doc1 = getDocument(xml1); + Document doc2 = getDocument(xml2); Element newNode = (Element) doc2.getFirstChild().getFirstChild(); Element replacementNode = (Element) doc1.adoptNode(newNode); @@ -72,10 +79,118 @@ public class DocumentTest { Assert.assertEquals(attrValue, "new value"); } - private static Document getDocument(DocumentBuilder builder, String xml) throws SAXException, IOException { + /** + * Verifies that the lookupNamespaceURI method returns null (not empty string) + * for unbound prefix. + * + * Specification for lookupNamespaceURI: + * Returns the associated namespace URI or null if none is found. + * + * @throws Exception + */ + @Test + public void testUnboundNamespaceURI() throws Exception { + String xml = "" + + ""; + + DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + Document doc = getDocument(xml); + Element e1 = doc.getDocumentElement(); + Element e2 = (Element)e1.getFirstChild().getFirstChild(); + + Assert.assertEquals(e1.lookupNamespaceURI(null), null); + Assert.assertEquals(e2.lookupNamespaceURI(null), null); + + Assert.assertEquals(e1.lookupNamespaceURI("p1"), null); + Assert.assertEquals(e2.lookupNamespaceURI("p1"), null); + + Assert.assertEquals(e1.lookupNamespaceURI("p2"), null); + Assert.assertEquals(e2.lookupNamespaceURI("p2"), "uri2"); + } + + /** + * Verifies that calling namespace methods on an empty document won't result + * in a NPE. + * @throws Exception + */ + @Test + public void testNamespaceNPE() throws Exception { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + document.lookupNamespaceURI("prefix"); + document.lookupPrefix("uri"); + document.isDefaultNamespace("uri"); + } + + /** + * Verifies that manipulating an independent document from within a mutation + * listener does not modify the original event object. + */ + @Test + public void testMutation() throws Exception { + String xml1 = "" + + ""; + String xml2 = "" + + ""; + DocumentBuilder db = DocumentBuilderFactoryImpl.newInstance().newDocumentBuilder(); + DocumentImpl doc1 = (DocumentImpl)getDocument(xml1); + DocumentImpl doc2 = (DocumentImpl)getDocument(xml2); + ElementImpl a = (ElementImpl) doc1.getDocumentElement().getFirstChild(); + AttrImpl attr = (AttrImpl) a.getAttributeNode("a_attr"); + attr.addEventListener(MutationEventImpl.DOM_NODE_REMOVED, new MyEventListener(DOC1, doc2), false); + doc2.addEventListener(MutationEventImpl.DOM_ATTR_MODIFIED, new MyEventListener(DOC2), true); + + // make a change to doc1 to trigger the event + Element a1 = (Element) doc1.getDocumentElement().getFirstChild(); + a1.setAttribute("a_attr", "a_attr_newvalue"); + } + + private static Document getDocument(String xml) throws Exception { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); InputStream a = new ByteArrayInputStream(xml.getBytes()); - Document out = builder.parse(a); + Document out = db.parse(a); return out; } + // EventListener that mutates an unrelated document when an event is received. + static class MyEventListener implements EventListener { + + private int docId; + private Document doc = null; + + public MyEventListener(int docId) { + this.docId = docId; + } + + public MyEventListener(int docId, Document doc) { + this.docId = docId; + this.doc = doc; + } + + public void handleEvent(Event evt) { + if (docId == DOC1) { + //check the related node before making changes + checkRelatedNode(evt, "a_attr_value"); + //make a change to doc2 + Element ele = (Element)doc.getDocumentElement().getFirstChild(); + ele.setAttribute("b_attr", "value for b_attr in doc2"); + //check the related node again after the change + checkRelatedNode(evt, "a_attr_value"); + } else { //DOC2 + checkRelatedNode(evt, "value for b_attr in doc2"); + } + } + + } + + // Utility method to display an event + public static void checkRelatedNode(Event evt, String expected) { + //System.out.println(" Event: " + evt + ", on " + evt.getTarget()); + if (evt instanceof MutationEventImpl) { + MutationEventImpl mutation = (MutationEventImpl) evt; + //System.out.println(" + Related: " + mutation.getRelatedNode()); + Assert.assertTrue(mutation.getRelatedNode().toString().contains(expected)); + } + } }