提交 5be21323 编写于 作者: J joehw

8222743: Xerces 2.12.0: DOM Implementation

Reviewed-by: lancea
上级 75be47d5
/*
* 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
......
......@@ -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,
......
......@@ -40,8 +40,6 @@ public abstract class ChildNode
/** Serialization version. */
static final long serialVersionUID = -6112455738802414002L;
transient StringBuffer fBufferStr = null;
//
// Data
//
......
......@@ -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
......
/*
* 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);
......
/*
* 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;
......
......@@ -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
......
/*
* 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<length;i++) {
Node attr = map.item(i);
String attrPrefix = attr.getPrefix();
String value = attr.getNodeValue();
namespace = attr.getNamespaceURI();
if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
String attrPrefix = attr.getPrefix();
String value = attr.getNodeValue();
// at this point we are dealing with DOM Level 2 nodes only
if (specifiedPrefix == null &&
attr.getNodeName().equals("xmlns")) {
// default namespace
return value;
return value.length() > 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;i<length;i++) {
Node attr = map.item(i);
String attrPrefix = attr.getPrefix();
String value = attr.getNodeValue();
namespace = attr.getNamespaceURI();
if (namespace !=null && namespace.equals("http://www.w3.org/2000/xmlns/")) {
String attrPrefix = attr.getPrefix();
String value = attr.getNodeValue();
// DOM Level 2 nodes
if (((attr.getNodeName().equals("xmlns")) ||
(attrPrefix !=null && attrPrefix.equals("xmlns")) &&
......@@ -1687,9 +1688,6 @@ public abstract class NodeImpl
* <code>Text</code> 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 <code>true</code>, recursively compare the subtrees; if
* <code>false</code>, compare only the nodes themselves (and its
* attributes, if it is an <code>Element</code>).
* @return If the nodes, and possibly subtrees are equal,
* <code>true</code> otherwise <code>false</code>.
* @since DOM Level 3
......
......@@ -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. <p>
*
* 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.<p>
*
* 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
/*
* 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;
......
/*
* 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;
......
/*
* 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<String> fRecognizedProperties;
protected List<String> fRecognizedProperties;
/** Properties. */
protected Map<String, Object> fProperties;
/** Recognized features. */
protected Set<String> fRecognizedFeatures;
protected List<String> fRecognizedFeatures;
/** Features. */
protected Map<String, Boolean> 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;
......
/*
* 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 = "<root><oldNode oldAttrib1=\"old value 1\" oldAttrib2=\"old value 2\"></oldNode></root>";
private static final String XML2 = "<root><newNode newAttrib=\"new value\"></newNode></root>";
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 = "<root><oldNode oldAttrib1=\"old value 1\" oldAttrib2=\"old value 2\"></oldNode></root>";
String xml2 = "<root><newNode newAttrib=\"new value\"></newNode></root>";
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 = "<?xml version='1.1'?>"
+ "<root><e1 xmlns='' xmlns:p1='' xmlns:p2='uri2'><e2/></e1></root>";
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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<root><a a_attr=\"a_attr_value\"/></root>";
String xml2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<root><b b_attr=\"b_attr_value\"/></root>";
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));
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册