feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2016, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.org.apache.xerces.internal.dom;
public class AbortException extends RuntimeException {
private static final long serialVersionUID = 2608302175475740417L;
/**
* Constructor AbortException
*/
public AbortException() { super(null, null, false, false); }
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,352 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
import org.w3c.dom.DOMException;
/**
* AttrNSImpl inherits from AttrImpl and adds namespace support.
* <P>
* The qualified name is the node name, and we store localName which is also
* used in all queries. On the other hand we recompute the prefix when
* necessary.
*
* @xerces.internal
*
* @author Arnaud Le Hors, IBM
* @author Andy Clark, IBM
* @author Ralf Pfeiffer, IBM
*/
public class AttrNSImpl
extends AttrImpl {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -781906615369795414L;
static final String xmlnsURI = "http://www.w3.org/2000/xmlns/";
static final String xmlURI = "http://www.w3.org/XML/1998/namespace";
//
// Data
//
/** DOM2: Namespace URI. */
protected String namespaceURI;
/** DOM2: localName. */
protected String localName;
/*
* Default constructor
*/
public AttrNSImpl(){}
/**
* DOM2: Constructor for Namespace implementation.
*/
protected AttrNSImpl(CoreDocumentImpl ownerDocument,
String namespaceURI,
String qualifiedName) {
super(ownerDocument, qualifiedName);
setName(namespaceURI, qualifiedName);
}
private void setName(String namespaceURI, String qname){
CoreDocumentImpl ownerDocument = ownerDocument();
String prefix;
// DOM Level 3: namespace URI is never empty string.
this.namespaceURI = namespaceURI;
if (namespaceURI !=null) {
this.namespaceURI = (namespaceURI.length() == 0)? null
: namespaceURI;
}
int colon1 = qname.indexOf(':');
int colon2 = qname.lastIndexOf(':');
ownerDocument.checkNamespaceWF(qname, colon1, colon2);
if (colon1 < 0) {
// there is no prefix
localName = qname;
if (ownerDocument.errorChecking) {
ownerDocument.checkQName(null, localName);
if (qname.equals("xmlns") && (namespaceURI == null
|| !namespaceURI.equals(NamespaceContext.XMLNS_URI))
|| (namespaceURI!=null && namespaceURI.equals(NamespaceContext.XMLNS_URI)
&& !qname.equals("xmlns"))) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NAMESPACE_ERR",
null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
}
}
else {
prefix = qname.substring(0, colon1);
localName = qname.substring(colon2+1);
ownerDocument.checkQName(prefix, localName);
ownerDocument.checkDOMNSErr(prefix, namespaceURI);
}
}
// when local name is known
public AttrNSImpl(CoreDocumentImpl ownerDocument,
String namespaceURI,
String qualifiedName,
String localName) {
super(ownerDocument, qualifiedName);
this.localName = localName;
this.namespaceURI = namespaceURI;
}
// for DeferredAttrImpl
protected AttrNSImpl(CoreDocumentImpl ownerDocument,
String value) {
super(ownerDocument, value);
}
// Support for DOM Level 3 renameNode method.
// Note: This only deals with part of the pb. It is expected to be
// called after the Attr has been detached for one thing.
// CoreDocumentImpl does all the work.
void rename(String namespaceURI, String qualifiedName) {
if (needsSyncData()) {
synchronizeData();
}
this.name = qualifiedName;
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
//
/**
* Introduced in DOM Level 2. <p>
*
* The namespace URI of this node, or null if it is unspecified.<p>
*
* This is not a computed value that is the result of a namespace lookup
* based on an examination of the namespace declarations in scope. It is
* merely the namespace URI given at creation time.<p>
*
* For nodes created with a DOM Level 1 method, such as createElement
* from the Document interface, this is null.
* @since WD-DOM-Level-2-19990923
*/
public String getNamespaceURI()
{
if (needsSyncData()) {
synchronizeData();
}
// REVIST: This code could/should be done at a lower-level, such that
// the namespaceURI is set properly upon creation. However, there still
// seems to be some DOM spec interpretation grey-area.
return namespaceURI;
}
/**
* Introduced in DOM Level 2. <p>
*
* The namespace prefix of this node, or null if it is unspecified. <p>
*
* For nodes created with a DOM Level 1 method, such as createElement
* from the Document interface, this is null. <p>
*
* @since WD-DOM-Level-2-19990923
*/
public String getPrefix()
{
if (needsSyncData()) {
synchronizeData();
}
int index = name.indexOf(':');
return index < 0 ? null : name.substring(0, index);
}
/**
* Introduced in DOM Level 2. <p>
*
* Note that setting this attribute changes the nodeName attribute, which
* holds the qualified name, as well as the tagName and name attributes of
* the Element and Attr interfaces, when applicable.<p>
*
* @param prefix The namespace prefix of this node, or null(empty string) if it is unspecified.
*
* @exception INVALID_CHARACTER_ERR
* Raised if the specified
* prefix contains an invalid character.
* @exception DOMException
* @since WD-DOM-Level-2-19990923
*/
public void setPrefix(String prefix)
throws DOMException
{
if (needsSyncData()) {
synchronizeData();
}
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);
}
if (prefix != null && prefix.length() != 0) {
if (!CoreDocumentImpl.isXMLName(prefix,ownerDocument().isXML11Version())) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
}
if (namespaceURI == null || prefix.indexOf(':') >=0) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
if (prefix.equals("xmlns")) {
if (!namespaceURI.equals(xmlnsURI)){
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
} else if (prefix.equals("xml")) {
if (!namespaceURI.equals(xmlURI)) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
}else if (name.equals("xmlns")) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
}
}
// update node name with new qualifiedName
if (prefix !=null && prefix.length() != 0) {
name = prefix + ":" + localName;
}
else {
name = localName;
}
}
/**
* Introduced in DOM Level 2. <p>
*
* Returns the local part of the qualified name of this node.
* @since WD-DOM-Level-2-19990923
*/
public String getLocalName()
{
if (needsSyncData()) {
synchronizeData();
}
return localName;
}
/**
* @see org.w3c.dom.TypeInfo#getTypeName()
*/
public String getTypeName() {
if (type !=null){
if (type instanceof XSSimpleTypeDecl){
return ((XSSimpleTypeDecl)type).getName();
}
return (String)type;
}
return null;
}
/**
* Introduced in DOM Level 3. <p>
* 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
* The namspace of the ancestor type declaration
* @param ancestorName
* The name of the ancestor type declaration
* @param type
* The reference type definition
*
* @return boolean True if the type is derived by restriciton for the
* reference type
*/
public boolean isDerivedFrom(String typeNamespaceArg,
String typeNameArg,
int derivationMethod) {
if (type != null) {
if (type instanceof XSSimpleTypeDecl) {
return ((XSSimpleTypeDecl) type).isDOMDerivedFrom(
typeNamespaceArg, typeNameArg, derivationMethod);
}
}
return false;
}
/**
* @see org.w3c.dom.TypeInfo#getTypeNamespace()
*/
public String getTypeNamespace() {
if (type !=null) {
if (type instanceof XSSimpleTypeDecl){
return ((XSSimpleTypeDecl)type).getNamespace();
}
return DTD_URI;
}
return null;
}
}

View File

@@ -0,0 +1,606 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
/**
* AttributeMap inherits from NamedNodeMapImpl and extends it to deal with the
* specifics of storing attributes. These are:
* <ul>
* <li>managing ownership of attribute nodes
* <li>managing default attributes
* <li>firing mutation events
* </ul>
* <p>
* This class doesn't directly support mutation events, however, it notifies
* the document when mutations are performed so that the document class do so.
*
* @xerces.internal
*
*/
public class AttributeMap extends NamedNodeMapImpl {
/** Serialization version. */
static final long serialVersionUID = 8872606282138665383L;
//
// Constructors
//
/** Constructs a named node map. */
protected AttributeMap(ElementImpl ownerNode, NamedNodeMapImpl defaults) {
super(ownerNode);
if (defaults != null) {
// initialize map with the defaults
cloneContent(defaults);
if (nodes != null) {
hasDefaults(true);
}
}
}
/**
* Adds an attribute using its nodeName attribute.
* @see org.w3c.dom.NamedNodeMap#setNamedItem
* @return If the new Node replaces an existing node the replaced Node is
* returned, otherwise null is returned.
* @param arg
* An Attr node to store in this map.
* @exception org.w3c.dom.DOMException The exception description.
*/
public Node setNamedItem(Node arg)
throws DOMException {
boolean errCheck = ownerNode.ownerDocument().errorChecking;
if (errCheck) {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
}
if (arg.getOwnerDocument() != ownerNode.ownerDocument()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
if (arg.getNodeType() != Node.ATTRIBUTE_NODE) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null);
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, msg);
}
}
AttrImpl argn = (AttrImpl)arg;
if (argn.isOwned()){
if (errCheck && argn.getOwnerElement() != ownerNode) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INUSE_ATTRIBUTE_ERR", null);
throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, msg);
}
// replacing an Attribute with itself does nothing
return arg;
}
// set owner
argn.ownerNode = ownerNode;
argn.isOwned(true);
int i = findNamePoint(argn.getNodeName(),0);
AttrImpl previous = null;
if (i >= 0) {
previous = (AttrImpl) nodes.get(i);
nodes.set(i, arg);
previous.ownerNode = ownerNode.ownerDocument();
previous.isOwned(false);
// make sure it won't be mistaken with defaults in case it's reused
previous.isSpecified(true);
} else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new ArrayList(5);
}
nodes.add(i, arg);
}
// notify document
ownerNode.ownerDocument().setAttrNode(argn, previous);
// If the new attribute is not normalized,
// the owning element is inherently not normalized.
if (!argn.isNormalized()) {
ownerNode.isNormalized(false);
}
return previous;
} // setNamedItem(Node):Node
/**
* Adds an attribute using its namespaceURI and localName.
* @see org.w3c.dom.NamedNodeMap#setNamedItem
* @return If the new Node replaces an existing node the replaced Node is
* returned, otherwise null is returned.
* @param arg A node to store in a named node map.
*/
public Node setNamedItemNS(Node arg)
throws DOMException {
boolean errCheck = ownerNode.ownerDocument().errorChecking;
if (errCheck) {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
}
if(arg.getOwnerDocument() != ownerNode.ownerDocument()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
if (arg.getNodeType() != Node.ATTRIBUTE_NODE) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "HIERARCHY_REQUEST_ERR", null);
throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, msg);
}
}
AttrImpl argn = (AttrImpl)arg;
if (argn.isOwned()){
if (errCheck && argn.getOwnerElement() != ownerNode) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INUSE_ATTRIBUTE_ERR", null);
throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, msg);
}
// replacing an Attribute with itself does nothing
return arg;
}
// set owner
argn.ownerNode = ownerNode;
argn.isOwned(true);
int i = findNamePoint(argn.getNamespaceURI(), argn.getLocalName());
AttrImpl previous = null;
if (i >= 0) {
previous = (AttrImpl) nodes.get(i);
nodes.set(i, arg);
previous.ownerNode = ownerNode.ownerDocument();
previous.isOwned(false);
// make sure it won't be mistaken with defaults in case it's reused
previous.isSpecified(true);
} else {
// If we can't find by namespaceURI, localName, then we find by
// nodeName so we know where to insert.
i = findNamePoint(arg.getNodeName(),0);
if (i >=0) {
previous = (AttrImpl) nodes.get(i);
nodes.add(i, arg);
} else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new ArrayList(5);
}
nodes.add(i, arg);
}
}
// changed(true);
// notify document
ownerNode.ownerDocument().setAttrNode(argn, previous);
// If the new attribute is not normalized,
// the owning element is inherently not normalized.
if (!argn.isNormalized()) {
ownerNode.isNormalized(false);
}
return previous;
} // setNamedItemNS(Node):Node
/**
* Removes an attribute specified by name.
* @param name
* The name of a node to remove. If the
* removed attribute is known to have a default value, an
* attribute immediately appears containing the default value
* as well as the corresponding namespace URI, local name,
* and prefix when applicable.
* @return The node removed from the map if a node with such a name exists.
* @throws NOT_FOUND_ERR: Raised if there is no node named
* name in the map.
*/
/***/
public Node removeNamedItem(String name)
throws DOMException {
return internalRemoveNamedItem(name, true);
}
/**
* Same as removeNamedItem except that it simply returns null if the
* specified name is not found.
*/
Node safeRemoveNamedItem(String name) {
return internalRemoveNamedItem(name, false);
}
/**
* NON-DOM: Remove the node object
*
* NOTE: Specifically removes THIS NODE -- not the node with this
* name, nor the node with these contents. If node does not belong to
* this named node map, we throw a DOMException.
*
* @param item The node to remove
* @param addDefault true -- magically add default attribute
* @return Removed node
* @exception DOMException
*/
protected Node removeItem(Node item, boolean addDefault)
throws DOMException {
int index = -1;
if (nodes != null) {
final int size = nodes.size();
for (int i = 0; i < size; ++i) {
if (nodes.get(i) == item) {
index = i;
break;
}
}
}
if (index < 0) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
}
return remove((AttrImpl)item, index, addDefault);
}
/**
* Internal removeNamedItem method allowing to specify whether an exception
* must be thrown if the specified name is not found.
*/
final protected Node internalRemoveNamedItem(String name, boolean raiseEx){
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
}
int i = findNamePoint(name,0);
if (i < 0) {
if (raiseEx) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
} else {
return null;
}
}
return remove((AttrImpl)nodes.get(i), i, true);
} // internalRemoveNamedItem(String,boolean):Node
private final Node remove(AttrImpl attr, int index,
boolean addDefault) {
CoreDocumentImpl ownerDocument = ownerNode.ownerDocument();
String name = attr.getNodeName();
if (attr.isIdAttribute()) {
ownerDocument.removeIdentifier(attr.getValue());
}
if (hasDefaults() && addDefault) {
// If there's a default, add it instead
NamedNodeMapImpl defaults =
((ElementImpl) ownerNode).getDefaultAttributes();
Node d;
if (defaults != null &&
(d = defaults.getNamedItem(name)) != null &&
findNamePoint(name, index+1) < 0) {
NodeImpl clone = (NodeImpl)d.cloneNode(true);
if (d.getLocalName() !=null){
// we must rely on the name to find a default attribute
// ("test:attr"), but while copying it from the DOCTYPE
// we should not loose namespace URI that was assigned
// to the attribute in the instance document.
((AttrNSImpl)clone).namespaceURI = attr.getNamespaceURI();
}
clone.ownerNode = ownerNode;
clone.isOwned(true);
clone.isSpecified(false);
nodes.set(index, clone);
if (attr.isIdAttribute()) {
ownerDocument.putIdentifier(clone.getNodeValue(),
(ElementImpl)ownerNode);
}
} else {
nodes.remove(index);
}
} else {
nodes.remove(index);
}
// changed(true);
// remove reference to owner
attr.ownerNode = ownerDocument;
attr.isOwned(false);
// make sure it won't be mistaken with defaults in case it's
// reused
attr.isSpecified(true);
attr.isIdAttribute(false);
// notify document
ownerDocument.removedAttrNode(attr, ownerNode, name);
return attr;
}
/**
* Introduced in DOM Level 2. <p>
* Removes an attribute specified by local name and namespace URI.
* @param namespaceURI
* The namespace URI of the node to remove.
* When it is null or an empty string, this
* method behaves like removeNamedItem.
* @param name The local name of the node to remove. If the
* removed attribute is known to have a default
* value, an attribute immediately appears
* containing the default value.
* @return Node The node removed from the map if a node with such
* a local name and namespace URI exists.
* @throws NOT_FOUND_ERR: Raised if there is no node named
* name in the map.
*/
public Node removeNamedItemNS(String namespaceURI, String name)
throws DOMException {
return internalRemoveNamedItemNS(namespaceURI, name, true);
}
/**
* Same as removeNamedItem except that it simply returns null if the
* specified local name and namespace URI is not found.
*/
Node safeRemoveNamedItemNS(String namespaceURI, String name) {
return internalRemoveNamedItemNS(namespaceURI, name, false);
}
/**
* Internal removeNamedItemNS method allowing to specify whether an
* exception must be thrown if the specified local name and namespace URI
* is not found.
*/
final protected Node internalRemoveNamedItemNS(String namespaceURI,
String name,
boolean raiseEx) {
CoreDocumentImpl ownerDocument = ownerNode.ownerDocument();
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);
}
int i = findNamePoint(namespaceURI, name);
if (i < 0) {
if (raiseEx) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
} else {
return null;
}
}
AttrImpl n = (AttrImpl)nodes.get(i);
if (n.isIdAttribute()) {
ownerDocument.removeIdentifier(n.getValue());
}
// If there's a default, add it instead
String nodeName = n.getNodeName();
if (hasDefaults()) {
NamedNodeMapImpl defaults = ((ElementImpl) ownerNode).getDefaultAttributes();
Node d;
if (defaults != null
&& (d = defaults.getNamedItem(nodeName)) != null)
{
int j = findNamePoint(nodeName,0);
if (j>=0 && findNamePoint(nodeName, j+1) < 0) {
NodeImpl clone = (NodeImpl)d.cloneNode(true);
clone.ownerNode = ownerNode;
if (d.getLocalName() != null) {
// we must rely on the name to find a default attribute
// ("test:attr"), but while copying it from the DOCTYPE
// we should not loose namespace URI that was assigned
// to the attribute in the instance document.
((AttrNSImpl)clone).namespaceURI = namespaceURI;
}
clone.isOwned(true);
clone.isSpecified(false);
nodes.set(i, clone);
if (clone.isIdAttribute()) {
ownerDocument.putIdentifier(clone.getNodeValue(),
(ElementImpl)ownerNode);
}
} else {
nodes.remove(i);
}
} else {
nodes.remove(i);
}
} else {
nodes.remove(i);
}
// changed(true);
// remove reference to owner
n.ownerNode = ownerDocument;
n.isOwned(false);
// make sure it won't be mistaken with defaults in case it's
// reused
n.isSpecified(true);
// update id table if needed
n.isIdAttribute(false);
// notify document
ownerDocument.removedAttrNode(n, ownerNode, name);
return n;
} // internalRemoveNamedItemNS(String,String,boolean):Node
//
// Public methods
//
/**
* Cloning a NamedNodeMap is a DEEP OPERATION; it always clones
* all the nodes contained in the map.
*/
public NamedNodeMapImpl cloneMap(NodeImpl ownerNode) {
AttributeMap newmap =
new AttributeMap((ElementImpl) ownerNode, null);
newmap.hasDefaults(hasDefaults());
newmap.cloneContent(this);
return newmap;
} // cloneMap():AttributeMap
/**
* Override parent's method to set the ownerNode correctly
*/
protected void cloneContent(NamedNodeMapImpl srcmap) {
List srcnodes = srcmap.nodes;
if (srcnodes != null) {
int size = srcnodes.size();
if (size != 0) {
if (nodes == null) {
nodes = new ArrayList(size);
}
else {
nodes.clear();
}
for (int i = 0; i < size; ++i) {
NodeImpl n = (NodeImpl) srcnodes.get(i);
NodeImpl clone = (NodeImpl) n.cloneNode(true);
clone.isSpecified(n.isSpecified());
nodes.add(clone);
clone.ownerNode = ownerNode;
clone.isOwned(true);
}
}
}
} // cloneContent():AttributeMap
/**
* Move specified attributes from the given map to this one
*/
void moveSpecifiedAttributes(AttributeMap srcmap) {
int nsize = (srcmap.nodes != null) ? srcmap.nodes.size() : 0;
for (int i = nsize - 1; i >= 0; i--) {
AttrImpl attr = (AttrImpl) srcmap.nodes.get(i);
if (attr.isSpecified()) {
srcmap.remove(attr, i, false);
if (attr.getLocalName() != null) {
setNamedItem(attr);
}
else {
setNamedItemNS(attr);
}
}
}
} // moveSpecifiedAttributes(AttributeMap):void
/**
* Get this AttributeMap in sync with the given "defaults" map.
* @param defaults The default attributes map to sync with.
*/
protected void reconcileDefaults(NamedNodeMapImpl defaults) {
// remove any existing default
int nsize = (nodes != null) ? nodes.size() : 0;
for (int i = nsize - 1; i >= 0; --i) {
AttrImpl attr = (AttrImpl) nodes.get(i);
if (!attr.isSpecified()) {
remove(attr, i, false);
}
}
// add the new defaults
if (defaults == null) {
return;
}
if (nodes == null || nodes.size() == 0) {
cloneContent(defaults);
}
else {
int dsize = defaults.nodes.size();
for (int n = 0; n < dsize; ++n) {
AttrImpl d = (AttrImpl) defaults.nodes.get(n);
int i = findNamePoint(d.getNodeName(), 0);
if (i < 0) {
i = -1 - i;
NodeImpl clone = (NodeImpl) d.cloneNode(true);
clone.ownerNode = ownerNode;
clone.isOwned(true);
clone.isSpecified(false);
nodes.add(i, clone);
}
}
}
} // reconcileDefaults()
protected final int addItem (Node arg) {
final AttrImpl argn = (AttrImpl) arg;
// set owner
argn.ownerNode = ownerNode;
argn.isOwned(true);
int i = findNamePoint(argn.getNamespaceURI(), argn.getLocalName());
if (i >= 0) {
nodes.set(i, arg);
}
else {
// If we can't find by namespaceURI, localName, then we find by
// nodeName so we know where to insert.
i = findNamePoint(argn.getNodeName(),0);
if (i >= 0) {
nodes.add(i, arg);
}
else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new ArrayList(5);
}
nodes.add(i, arg);
}
}
// notify document
ownerNode.ownerDocument().setAttrNode(argn, null);
return i;
}
} // class AttributeMap

View File

@@ -0,0 +1,90 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Node;
/**
* XML provides the CDATA markup to allow a region of text in which
* most of the XML delimiter recognition does not take place. This is
* intended to ease the task of quoting XML fragments and other
* programmatic information in a document's text without needing to
* escape these special characters. It's primarily a convenience feature
* for those who are hand-editing XML.
* <P>
* CDATASection is an Extended DOM feature, and is not used in HTML
* contexts.
* <P>
* Within the DOM, CDATASections are treated essentially as Text
* blocks. Their distinct type is retained in order to allow us to
* properly recreate the XML syntax when we write them out.
* <P>
* Reminder: CDATA IS NOT A COMPLETELY GENERAL SOLUTION; it can't
* quote its own end-of-block marking. If you need to write out a
* CDATA that contains the ]]> sequence, it's your responsibility to
* split that string over two successive CDATAs at that time.
* <P>
* CDATA does not participate in Element.normalize() processing.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class CDATASectionImpl
extends TextImpl
implements CDATASection {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 2372071297878177780L;
//
// Constructors
//
/** Factory constructor for creating a CDATA section. */
public CDATASectionImpl(CoreDocumentImpl ownerDoc, String data) {
super(ownerDoc, data);
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.CDATA_SECTION_NODE;
}
/** Returns the node name. */
public String getNodeName() {
return "#cdata-section";
}
} // class CDATASectionImpl

View File

@@ -0,0 +1,426 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* CharacterData is an abstract Node that can carry character data as its
* Value. It provides shared behavior for Text, CData, and
* possibly other node types. All offsets are 0-based.
* <p>
* Since ProcessingInstructionImpl inherits from this class to reuse the
* setNodeValue method, this class isn't declared as implementing the interface
* CharacterData. This is done by relevant subclasses (TexImpl, CommentImpl).
* <p>
* This class doesn't directly support mutation events, however, it notifies
* the document when mutations are performed so that the document class do so.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public abstract class CharacterDataImpl
extends ChildNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 7931170150428474230L;
//
// Data
//
protected String data;
/** Empty child nodes. */
private static transient NodeList singletonNodeList = new NodeList() {
public Node item(int index) { return null; }
public int getLength() { return 0; }
};
//
// Constructors
//
public CharacterDataImpl(){}
/** Factory constructor. */
protected CharacterDataImpl(CoreDocumentImpl ownerDocument, String data) {
super(ownerDocument);
this.data = data;
}
//
// Node methods
//
/** Returns an empty node list. */
public NodeList getChildNodes() {
return singletonNodeList;
}
/*
* returns the content of this node
*/
public String getNodeValue() {
if (needsSyncData()) {
synchronizeData();
}
return data;
}
/** Convenience wrapper for calling setNodeValueInternal when
* we are not performing a replacement operation
*/
protected void setNodeValueInternal (String value) {
setNodeValueInternal(value, false);
}
/** This function added so that we can distinguish whether
* setNodeValue has been called from some other DOM functions.
* or by the client.<p>
* This is important, because we do one type of Range fix-up,
* from the high-level functions in CharacterData, and another
* type if the client simply calls setNodeValue(value).
*/
protected void setNodeValueInternal(String value, boolean replace) {
CoreDocumentImpl ownerDocument = ownerDocument();
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);
}
// revisit: may want to set the value in ownerDocument.
// Default behavior, overridden in some subclasses
if (needsSyncData()) {
synchronizeData();
}
// keep old value for document notification
String oldvalue = this.data;
// notify document
ownerDocument.modifyingCharacterData(this, replace);
this.data = value;
// notify document
ownerDocument.modifiedCharacterData(this, oldvalue, value, replace);
}
/**
* Sets the content, possibly firing related events,
* and updating ranges (via notification to the document)
*/
public void setNodeValue(String value) {
setNodeValueInternal(value);
// notify document
ownerDocument().replacedText(this);
}
//
// CharacterData methods
//
/**
* Retrieve character data currently stored in this node.
*
* @throws DOMExcpetion(DOMSTRING_SIZE_ERR) In some implementations,
* the stored data may exceed the permitted length of strings. If so,
* getData() will throw this DOMException advising the user to
* instead retrieve the data in chunks via the substring() operation.
*/
public String getData() {
if (needsSyncData()) {
synchronizeData();
}
return data;
}
/**
* Report number of characters currently stored in this node's
* data. It may be 0, meaning that the value is an empty string.
*/
public int getLength() {
if (needsSyncData()) {
synchronizeData();
}
return data.length();
}
/**
* Concatenate additional characters onto the end of the data
* stored in this node. Note that this, and insert(), are the paths
* by which a DOM could wind up accumulating more data than the
* language's strings can easily handle. (See above discussion.)
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is readonly.
*/
public void appendData(String data) {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, msg);
}
if (data == null) {
return;
}
if (needsSyncData()) {
synchronizeData();
}
setNodeValue(this.data + data);
} // appendData(String)
/**
* Remove a range of characters from the node's value. Throws a
* DOMException if the offset is beyond the end of the
* string. However, a deletion _count_ that exceeds the available
* data is accepted as a delete-to-end request.
*
* @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
* greater than length, or if count is negative.
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is
* readonly.
*/
public void deleteData(int offset, int count)
throws DOMException {
internalDeleteData(offset, count, false);
} // deleteData(int,int)
/** NON-DOM INTERNAL: Within DOM actions, we sometimes need to be able
* to control which mutation events are spawned. This version of the
* deleteData operation allows us to do so. It is not intended
* for use by application programs.
*/
void internalDeleteData (int offset, int count, boolean replace)
throws DOMException {
CoreDocumentImpl ownerDocument = ownerDocument();
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);
}
if (count < 0) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null);
throw new DOMException(DOMException.INDEX_SIZE_ERR, msg);
}
}
if (needsSyncData()) {
synchronizeData();
}
int tailLength = Math.max(data.length() - count - offset, 0);
try {
String value = data.substring(0, offset) +
(tailLength > 0 ? data.substring(offset + count, offset + count + tailLength) : "");
setNodeValueInternal(value, replace);
// notify document
ownerDocument.deletedText(this, offset, count);
}
catch (StringIndexOutOfBoundsException e) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null);
throw new DOMException(DOMException.INDEX_SIZE_ERR, msg);
}
} // internalDeleteData(int,int,boolean)
/**
* Insert additional characters into the data stored in this node,
* at the offset specified.
*
* @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
* greater than length.
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is readonly.
*/
public void insertData(int offset, String data)
throws DOMException {
internalInsertData(offset, data, false);
} // insertData(int,int)
/** NON-DOM INTERNAL: Within DOM actions, we sometimes need to be able
* to control which mutation events are spawned. This version of the
* insertData operation allows us to do so. It is not intended
* for use by application programs.
*/
void internalInsertData (int offset, String data, boolean replace)
throws DOMException {
CoreDocumentImpl ownerDocument = ownerDocument();
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();
}
try {
String value =
new StringBuffer(this.data).insert(offset, data).toString();
setNodeValueInternal(value, replace);
// notify document
ownerDocument.insertedText(this, offset, data.length());
}
catch (StringIndexOutOfBoundsException e) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null);
throw new DOMException(DOMException.INDEX_SIZE_ERR, msg);
}
} // internalInsertData(int,String,boolean)
/**
* Replace a series of characters at the specified (zero-based)
* offset with a new string, NOT necessarily of the same
* length. Convenience method, equivalent to a delete followed by an
* insert. Throws a DOMException if the specified offset is beyond
* the end of the existing data.
*
* @param offset The offset at which to begin replacing.
*
* @param count The number of characters to remove,
* interpreted as in the delete() method.
*
* @param data The new string to be inserted at offset in place of
* the removed data. Note that the entire string will
* be inserted -- the count parameter does not affect
* insertion, and the new data may be longer or shorter
* than the substring it replaces.
*
* @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
* greater than length, or if count is negative.
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is
* readonly.
*/
public void replaceData(int offset, int count, String data)
throws DOMException {
CoreDocumentImpl ownerDocument = ownerDocument();
// The read-only check is done by deleteData()
// ***** This could be more efficient w/r/t Mutation Events,
// specifically by aggregating DOMAttrModified and
// DOMSubtreeModified. But mutation events are
// underspecified; I don't feel compelled
// to deal with it right now.
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();
}
//notify document
ownerDocument.replacingData(this);
// keep old value for document notification
String oldvalue = this.data;
internalDeleteData(offset, count, true);
internalInsertData(offset, data, true);
ownerDocument.replacedCharacterData(this, oldvalue, this.data);
} // replaceData(int,int,String)
/**
* Store character data into this node.
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is readonly.
*/
public void setData(String value)
throws DOMException {
setNodeValue(value);
}
/**
* Substring is more than a convenience function. In some
* implementations of the DOM, where the stored data may exceed the
* length that can be returned in a single string, the only way to
* read it all is to extract it in chunks via this method.
*
* @param offset Zero-based offset of first character to retrieve.
* @param count Number of characters to retrieve.
*
* If the sum of offset and count exceeds the length, all characters
* to end of data are returned.
*
* @throws DOMException(INDEX_SIZE_ERR) if offset is negative or
* greater than length, or if count is negative.
*
* @throws DOMException(WSTRING_SIZE_ERR) In some implementations,
* count may exceed the permitted length of strings. If so,
* substring() will throw this DOMException advising the user to
* instead retrieve the data in smaller chunks.
*/
public String substringData(int offset, int count)
throws DOMException {
if (needsSyncData()) {
synchronizeData();
}
int length = data.length();
if (count < 0 || offset < 0 || offset > length - 1) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null);
throw new DOMException(DOMException.INDEX_SIZE_ERR, msg);
}
int tailIndex = Math.min(offset + count, length);
return data.substring(offset, tailIndex);
} // substringData(int,int):String
} // class CharacterDataImpl

View File

@@ -0,0 +1,151 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Node;
/**
* ChildNode inherits from NodeImpl and adds the capability of being a child by
* having references to its previous and next siblings.
*
* @xerces.internal
*
*/
public abstract class ChildNode
extends NodeImpl {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -6112455738802414002L;
transient StringBuffer fBufferStr = null;
//
// Data
//
/** Previous sibling. */
protected ChildNode previousSibling;
/** Next sibling. */
protected ChildNode nextSibling;
//
// Constructors
//
/**
* No public constructor; only subclasses of Node should be
* instantiated, and those normally via a Document's factory methods
* <p>
* Every Node knows what Document it belongs to.
*/
protected ChildNode(CoreDocumentImpl ownerDocument) {
super(ownerDocument);
} // <init>(CoreDocumentImpl)
/** Constructor for serialization. */
public ChildNode() {}
//
// Node methods
//
/**
* Returns a duplicate of a given node. You can consider this a
* generic "copy constructor" for nodes. The newly returned object should
* be completely independent of the source object's subtree, so changes
* in one after the clone has been made will not affect the other.
* <P>
* Note: since we never have any children deep is meaningless here,
* ParentNode overrides this behavior.
* @see ParentNode
*
* <p>
* Example: Cloning a Text node will copy both the node and the text it
* contains.
* <p>
* Example: Cloning something that has children -- Element or Attr, for
* example -- will _not_ clone those children unless a "deep clone"
* has been requested. A shallow clone of an Attr node will yield an
* empty Attr of the same name.
* <p>
* NOTE: Clones will always be read/write, even if the node being cloned
* is read-only, to permit applications using only the DOM API to obtain
* editable copies of locked portions of the tree.
*/
public Node cloneNode(boolean deep) {
ChildNode newnode = (ChildNode) super.cloneNode(deep);
// Need to break the association w/ original kids
newnode.previousSibling = null;
newnode.nextSibling = null;
newnode.isFirstChild(false);
return newnode;
} // cloneNode(boolean):Node
/**
* Returns the parent node of this node
*/
public Node getParentNode() {
// if we have an owner, ownerNode is our parent, otherwise it's
// our ownerDocument and we don't have a parent
return isOwned() ? ownerNode : null;
}
/*
* same as above but returns internal type
*/
final NodeImpl parentNode() {
// if we have an owner, ownerNode is our parent, otherwise it's
// our ownerDocument and we don't have a parent
return isOwned() ? ownerNode : null;
}
/** The next child of this node's parent, or null if none */
public Node getNextSibling() {
return nextSibling;
}
/** The previous child of this node's parent, or null if none */
public Node getPreviousSibling() {
// if we are the firstChild, previousSibling actually refers to our
// parent's lastChild, but we hide that
return isFirstChild() ? null : previousSibling;
}
/*
* same as above but returns internal type
*/
final ChildNode previousSibling() {
// if we are the firstChild, previousSibling actually refers to our
// parent's lastChild, but we hide that
return isFirstChild() ? null : previousSibling;
}
} // class ChildNode

View File

@@ -0,0 +1,72 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.Node;
/**
* Represents an XML (or HTML) comment.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class CommentImpl
extends CharacterDataImpl
implements CharacterData, Comment {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -2685736833408134044L;
//
// Constructors
//
/** Factory constructor. */
public CommentImpl(CoreDocumentImpl ownerDoc, String data) {
super(ownerDoc, data);
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.COMMENT_NODE;
}
/** Returns the node name. */
public String getNodeName() {
return "#comment";
}
} // class CommentImpl

View File

@@ -0,0 +1,487 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
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.util.XMLChar;
import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
import com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl;
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;
import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
/**
* The DOMImplementation class is description of a particular
* implementation of the Document Object Model. As such its data is
* static, shared by all instances of this implementation.
* <P>
* The DOM API requires that it be a real object rather than static
* methods. However, there's nothing that says it can't be a singleton,
* so that's how I've implemented it.
* <P>
* This particular class, along with CoreDocumentImpl, supports the DOM
* Core and Load/Save (Experimental). Optional modules are supported by
* the more complete DOMImplementation class along with DocumentImpl.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class CoreDOMImplementationImpl
implements DOMImplementation, DOMImplementationLS {
//
// Data
//
// validators pool
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;
// Document and doctype counter. Used to assign order to documents and
// doctypes without owners, on an demand basis. Used for
// compareDocumentPosition
private int docAndDoctypeCounter = 0;
// static
/** Dom implementation singleton. */
static CoreDOMImplementationImpl singleton =
new CoreDOMImplementationImpl();
//
// Public methods
//
/** NON-DOM: Obtain and return the single shared object */
public static DOMImplementation getDOMImplementation() {
return singleton;
}
//
// DOMImplementation methods
//
/**
* Test if the DOM implementation supports a specific "feature" --
* currently meaning language and level thereof.
*
* @param feature The package name of the feature to test.
* In Level 1, supported values are "HTML" and "XML" (case-insensitive).
* At this writing, com.sun.org.apache.xerces.internal.dom supports only XML.
*
* @param version The version number of the feature being tested.
* This is interpreted as "Version of the DOM API supported for the
* specified Feature", and in Level 1 should be "1.0"
*
* @return true iff this implementation is compatable with the specified
* feature and version.
*/
public boolean hasFeature(String feature, String version) {
boolean anyVersion = version == null || version.length() == 0;
// check if Xalan implementation is around and if yes report true for supporting
// XPath API
// if a plus sign "+" is prepended to any feature name, implementations
// are considered in which the specified feature may not be directly
// castable DOMImplementation.getFeature(feature, version). Without a
// plus, only features whose interfaces are directly castable are considered.
if ((feature.equalsIgnoreCase("+XPath"))
&& (anyVersion || version.equals("3.0"))) {
try {
Class xpathClass = ObjectFactory.findProviderClass(
"com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", true);
// Check if the DOM XPath implementation implements
// the interface org.w3c.dom.XPathEvaluator
Class interfaces[] = xpathClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i].getName().equals(
"org.w3c.dom.xpath.XPathEvaluator")) {
return true;
}
}
} catch (Exception e) {
return false;
}
return true;
}
if (feature.startsWith("+")) {
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")));
} // hasFeature(String,String):boolean
/**
* Introduced in DOM Level 2. <p>
*
* Creates an empty DocumentType node.
*
* @param qualifiedName The qualified name of the document type to be created.
* @param publicID The document type public identifier.
* @param systemID The document type system identifier.
* @since WD-DOM-Level-2-19990923
*/
public DocumentType createDocumentType( String qualifiedName,
String publicID, String systemID) {
// REVISIT: this might allow creation of invalid name for DOCTYPE
// xmlns prefix.
// also there is no way for a user to turn off error checking.
checkQName(qualifiedName);
return new DocumentTypeImpl(null, qualifiedName, publicID, systemID);
}
final void checkQName(String qname){
int index = qname.indexOf(':');
int lastIndex = qname.lastIndexOf(':');
int length = qname.length();
// it is an error for NCName to have more than one ':'
// check if it is valid QName [Namespace in XML production 6]
if (index == 0 || index == length - 1 || lastIndex != index) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NAMESPACE_ERR",
null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
int start = 0;
// Namespace in XML production [6]
if (index > 0) {
// check that prefix is NCName
if (!XMLChar.isNCNameStart(qname.charAt(start))) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"INVALID_CHARACTER_ERR",
null);
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
}
for (int i = 1; i < index; i++) {
if (!XMLChar.isNCName(qname.charAt(i))) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"INVALID_CHARACTER_ERR",
null);
throw new DOMException(
DOMException.INVALID_CHARACTER_ERR,
msg);
}
}
start = index + 1;
}
// check local part
if (!XMLChar.isNCNameStart(qname.charAt(start))) {
// REVISIT: add qname parameter to the message
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"INVALID_CHARACTER_ERR",
null);
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
}
for (int i = start + 1; i < length; i++) {
if (!XMLChar.isNCName(qname.charAt(i))) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"INVALID_CHARACTER_ERR",
null);
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
}
}
}
/**
* 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) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"WRONG_DOCUMENT_ERR",
null);
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
CoreDocumentImpl doc = new CoreDocumentImpl(doctype);
Element e = doc.createElementNS(namespaceURI, qualifiedName);
doc.appendChild(e);
return doc;
}
/**
* DOM Level 3 WD - Experimental.
*/
public Object getFeature(String feature, String version) {
if (singleton.hasFeature(feature, version)) {
if ((feature.equalsIgnoreCase("+XPath"))) {
try {
Class xpathClass = ObjectFactory.findProviderClass(
"com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl", true);
// Check if the DOM XPath implementation implements
// the interface org.w3c.dom.XPathEvaluator
Class interfaces[] = xpathClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
if (interfaces[i].getName().equals(
"org.w3c.dom.xpath.XPathEvaluator")) {
return xpathClass.newInstance();
}
}
} catch (Exception e) {
return null;
}
} else {
return singleton;
}
}
return null;
}
// DOM L3 LS
/**
* DOM Level 3 LS CR - Experimental.
* Create a new <code>LSParser</code>. The newly constructed parser may
* then be configured by means of its <code>DOMConfiguration</code>
* object, and used to parse documents by means of its <code>parse</code>
* method.
* @param mode The <code>mode</code> argument is either
* <code>MODE_SYNCHRONOUS</code> or <code>MODE_ASYNCHRONOUS</code>, if
* <code>mode</code> is <code>MODE_SYNCHRONOUS</code> then the
* <code>LSParser</code> that is created will operate in synchronous
* mode, if it's <code>MODE_ASYNCHRONOUS</code> then the
* <code>LSParser</code> that is created will operate in asynchronous
* mode.
* @param schemaType An absolute URI representing the type of the schema
* language used during the load of a <code>Document</code> using the
* newly created <code>LSParser</code>. Note that no lexical checking
* is done on the absolute URI. In order to create a
* <code>LSParser</code> for any kind of schema types (i.e. the
* LSParser will be free to use any schema found), use the value
* <code>null</code>.
* <p ><b>Note:</b> For W3C XML Schema [<a href='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>]
* , applications must use the value
* <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD [<a href='http://www.w3.org/TR/2000/REC-xml-20001006'>XML 1.0</a>],
* applications must use the value
* <code>"http://www.w3.org/TR/REC-xml"</code>. Other Schema languages
* are outside the scope of the W3C and therefore should recommend an
* absolute URI in order to use this method.
* @return The newly created <code>LSParser</code> object. This
* <code>LSParser</code> is either synchronous or asynchronous
* depending on the value of the <code>mode</code> argument.
* <p ><b>Note:</b> By default, the newly created <code>LSParser</code>
* does not contain a <code>DOMErrorHandler</code>, i.e. the value of
* the "<a href='http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030609/core.html#parameter-error-handler'>
* error-handler</a>" configuration parameter is <code>null</code>. However, implementations
* may provide a default error handler at creation time. In that case,
* the initial value of the <code>"error-handler"</code> configuration
* parameter on the new created <code>LSParser</code> contains a
* reference to the default error handler.
* @exception DOMException
* NOT_SUPPORTED_ERR: Raised if the requested mode or schema type is
* not supported.
*/
public LSParser createLSParser(short mode, String schemaType)
throws DOMException {
if (mode != DOMImplementationLS.MODE_SYNCHRONOUS || (schemaType !=null &&
!"http://www.w3.org/2001/XMLSchema".equals(schemaType) &&
!"http://www.w3.org/TR/REC-xml".equals(schemaType))) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NOT_SUPPORTED_ERR",
null);
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
if (schemaType != null
&& schemaType.equals("http://www.w3.org/TR/REC-xml")) {
return new DOMParserImpl(new DTDConfiguration(),
schemaType);
}
else {
// create default parser configuration validating against XMLSchemas
return new DOMParserImpl(new XIncludeAwareParserConfiguration(),
schemaType);
}
}
/**
* DOM Level 3 LS CR - Experimental.
* Create a new <code>LSSerializer</code> object.
* @return The newly created <code>LSSerializer</code> object.
* <p ><b>Note:</b> By default, the newly created
* <code>LSSerializer</code> has no <code>DOMErrorHandler</code>,
* i.e. the value of the <code>"error-handler"</code> configuration
* parameter is <code>null</code>. However, implementations may
* provide a default error handler at creation time. In that case, the
* initial value of the <code>"error-handler"</code> configuration
* parameter on the new created <code>LSSerializer</code> contains a
* reference to the default error handler.
*/
public LSSerializer createLSSerializer() {
return new DOMSerializerImpl();
}
/**
* DOM Level 3 LS CR - Experimental.
* Create a new empty input source.
* @return The newly created input object.
*/
public LSInput createLSInput() {
return new DOMInputImpl();
}
//
// Protected methods
//
/** NON-DOM: retrieve validator. */
synchronized RevalidationHandler getValidator(String schemaType) {
// REVISIT: implement retrieving DTD validator
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 (RevalidationHandler) (ObjectFactory
.newInstance(
"com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator",
ObjectFactory.findClassLoader(),
true));
}
// return first available validator
RevalidationHandler val = validators[freeValidatorIndex];
validators[freeValidatorIndex--] = null;
return val;
}
else if(schemaType == XMLGrammarDescription.XML_DTD) {
if(freeDTDValidatorIndex < 0) {
return (RevalidationHandler) (ObjectFactory
.newInstance(
"com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator",
ObjectFactory.findClassLoader(),
true));
}
// 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;
}
}
/** 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.
*
* Create a new empty output destination object where
* <code>LSOutput.characterStream</code>,
* <code>LSOutput.byteStream</code>, <code>LSOutput.systemId</code>,
* <code>LSOutput.encoding</code> are null.
* @return The newly created output object.
*/
public LSOutput createLSOutput() {
return new DOMOutputImpl();
}
} // class DOMImplementationImpl

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,137 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMLocator;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
/**
* <code>DOMErrorImpl</code> is an implementation that describes an error.
* <strong>Note:</strong> The error object that describes the error
* might be reused by Xerces implementation, across multiple calls to the
* handleEvent method on DOMErrorHandler interface.
*
*
* <p>See also the <a href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010913'>Document Object Model (DOM) Level 3 Core Specification</a>.
*
* @xerces.internal
*
* @author Gopal Sharma, SUN Microsystems Inc.
* @author Elena Litani, IBM
*
*/
// REVISIT: the implementation of ErrorReporter.
// we probably should not pass XMLParseException
//
public class DOMErrorImpl implements DOMError {
//
// Data
//
public short fSeverity = DOMError.SEVERITY_WARNING;
public String fMessage = null;
public DOMLocatorImpl fLocator = new DOMLocatorImpl();
public Exception fException = null;
public String fType;
public Object fRelatedData;
//
// Constructors
//
/** Default constructor. */
public DOMErrorImpl () {
}
/** Exctracts information from XMLParserException) */
public DOMErrorImpl (short severity, XMLParseException exception) {
fSeverity = severity;
fException = exception;
fLocator = createDOMLocator (exception);
}
/**
* The severity of the error, either <code>SEVERITY_WARNING</code>,
* <code>SEVERITY_ERROR</code>, or <code>SEVERITY_FATAL_ERROR</code>.
*/
public short getSeverity() {
return fSeverity;
}
/**
* An implementation specific string describing the error that occured.
*/
public String getMessage() {
return fMessage;
}
/**
* The location of the error.
*/
public DOMLocator getLocation() {
return fLocator;
}
// method to get the DOMLocator Object
private DOMLocatorImpl createDOMLocator(XMLParseException exception) {
// assuming DOMLocator wants the *expanded*, not the literal, URI of the doc... - neilg
return new DOMLocatorImpl(exception.getLineNumber(),
exception.getColumnNumber(),
exception.getCharacterOffset(),
exception.getExpandedSystemId());
} // createDOMLocator()
/**
* The related platform dependent exception if any.exception is a reserved
* word, we need to rename it.Change to "relatedException". (F2F 26 Sep
* 2001)
*/
public Object getRelatedException(){
return fException;
}
public void reset(){
fSeverity = DOMError.SEVERITY_WARNING;
fException = null;
}
public String getType(){
return fType;
}
public Object getRelatedData(){
return fRelatedData;
}
}// class DOMErrorImpl

View File

@@ -0,0 +1,152 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.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
* implementation of the Document Object Model. As such its data is
* static, shared by all instances of this implementation.
* <P>
* The DOM API requires that it be a real object rather than static
* methods. However, there's nothing that says it can't be a singleton,
* so that's how I've implemented it.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DOMImplementationImpl extends CoreDOMImplementationImpl
implements DOMImplementation {
//
// Data
//
// static
/** Dom implementation singleton. */
static DOMImplementationImpl singleton = new DOMImplementationImpl();
//
// Public methods
//
/** NON-DOM: Obtain and return the single shared object */
public static DOMImplementation getDOMImplementation() {
return singleton;
}
//
// DOMImplementation methods
//
/**
* Test if the DOM implementation supports a specific "feature" --
* currently meaning language and level thereof.
*
* @param feature The package name of the feature to test.
* In Level 1, supported values are "HTML" and "XML" (case-insensitive).
* At this writing, com.sun.org.apache.xerces.internal.dom supports only XML.
*
* @param version The version number of the feature being tested.
* This is interpreted as "Version of the DOM API supported for the
* specified Feature", and in Level 1 should be "1.0"
*
* @return true iff this implementation is compatable with the
* specified feature and version.
*/
public boolean hasFeature(String feature, String version) {
boolean result = super.hasFeature(feature, version);
if (!result) {
boolean anyVersion = version == null || version.length() == 0;
if (feature.startsWith("+")) {
feature = feature.substring(1);
}
return (
(feature.equalsIgnoreCase("Events")
&& (anyVersion || version.equals("2.0")))
|| (feature.equalsIgnoreCase("MutationEvents")
&& (anyVersion || version.equals("2.0")))
|| (feature.equalsIgnoreCase("Traversal")
&& (anyVersion || version.equals("2.0")))
|| (feature.equalsIgnoreCase("Range")
&& (anyVersion || version.equals("2.0")))
|| (feature.equalsIgnoreCase("MutationEvents")
&& (anyVersion || version.equals("2.0"))));
}
return result;
} // 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(namespaceURI == null && qualifiedName == null && doctype == null){
//if namespaceURI, qualifiedName and doctype are null, returned document is empty with
//no document element
return new DocumentImpl();
}
else if (doctype != null && doctype.getOwnerDocument() != null) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
DocumentImpl doc = new DocumentImpl(doctype);
Element e = doc.createElementNS( namespaceURI, qualifiedName);
doc.appendChild(e);
return doc;
}
} // class DOMImplementationImpl

View File

@@ -0,0 +1,76 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.util.Vector;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementation;
/**
* <p>This class implements the DOM Level 3 Core interface DOMImplementationList.</p>
*
* @xerces.internal
*
* @author Neil Delima, IBM
* @since DOM Level 3 Core
*/
public class DOMImplementationListImpl implements DOMImplementationList {
//A collection of DOMImplementations
private Vector fImplementations;
/**
* Construct an empty list of DOMImplementations
*/
public DOMImplementationListImpl() {
fImplementations = new Vector();
}
/**
* Construct an empty list of DOMImplementations
*/
public DOMImplementationListImpl(Vector params) {
fImplementations = params;
}
/**
* Returns the indexth item in the collection.
*
* @param index The index of the DOMImplemetation from the list to return.
*/
public DOMImplementation item(int index) {
try {
return (DOMImplementation) fImplementations.elementAt(index);
} catch (ArrayIndexOutOfBoundsException e) {
return null;
}
}
/**
* Returns the number of DOMImplementations in the list.
*
* @return An integer indicating the number of DOMImplementations.
*/
public int getLength() {
return fImplementations.size();
}
}

View File

@@ -0,0 +1,137 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.util.StringTokenizer;
import java.util.Vector;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementationSource;
import org.w3c.dom.DOMImplementation;
import com.sun.org.apache.xerces.internal.dom.DOMImplementationListImpl;
/**
* Supply one the right implementation, based upon requested features. Each
* implemented <code>DOMImplementationSource</code> object is listed in the
* binding-specific list of available sources so that its
* <code>DOMImplementation</code> objects are made available.
*
* <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMImplementationSource'>Document Object Model (DOM) Level 3 Core Specification</a>.
*
* @xerces.internal
*
*/
public class DOMImplementationSourceImpl
implements DOMImplementationSource {
/**
* A method to request a DOM implementation.
* @param features A string that specifies which features are required.
* This is a space separated list in which each feature is specified
* by its name optionally followed by a space and a version number.
* This is something like: "XML 1.0 Traversal Events 2.0"
* @return An implementation that has the desired features, or
* <code>null</code> if this source has none.
*/
public DOMImplementation getDOMImplementation(String features) {
// first check whether the CoreDOMImplementation would do
DOMImplementation impl =
CoreDOMImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
return impl;
}
// if not try the DOMImplementation
impl = DOMImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
return impl;
}
return null;
}
/**
* A method to request a list of DOM implementations that support the
* specified features and versions, as specified in .
* @param features A string that specifies which features and versions
* are required. This is a space separated list in which each feature
* is specified by its name optionally followed by a space and a
* version number. This is something like: "XML 3.0 Traversal +Events
* 2.0"
* @return A list of DOM implementations that support the desired
* features.
*/
public DOMImplementationList getDOMImplementationList(String features) {
// first check whether the CoreDOMImplementation would do
DOMImplementation impl = CoreDOMImplementationImpl.getDOMImplementation();
final Vector implementations = new Vector();
if (testImpl(impl, features)) {
implementations.addElement(impl);
}
impl = DOMImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
implementations.addElement(impl);
}
return new DOMImplementationListImpl(implementations);
}
boolean testImpl(DOMImplementation impl, String features) {
StringTokenizer st = new StringTokenizer(features);
String feature = null;
String version = null;
if (st.hasMoreTokens()) {
feature = st.nextToken();
}
while (feature != null) {
boolean isVersion = false;
if (st.hasMoreTokens()) {
char c;
version = st.nextToken();
c = version.charAt(0);
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
isVersion = true;
}
} else {
version = null;
}
if (isVersion) {
if (!impl.hasFeature(feature, version)) {
return false;
}
if (st.hasMoreTokens()) {
feature = st.nextToken();
} else {
feature = null;
}
} else {
if (!impl.hasFeature(feature, null)) {
return false;
}
feature = version;
}
}
return true;
}
}

View File

@@ -0,0 +1,392 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.ls.LSInput;
import java.io.Reader;
import java.io.InputStream;
/**
* This Class <code>DOMInputImpl</code> represents a single input source for an XML entity.
* <p> This Class allows an application to encapsulate information about
* an input source in a single object, which may include a public
* identifier, a system identifier, a byte stream (possibly with a specified
* encoding), and/or a character stream.
* <p> The exact definitions of a byte stream and a character stream are
* binding dependent.
* <p> There are two places that the application will deliver this input
* source to the parser: as the argument to the <code>parse</code> method,
* or as the return value of the <code>DOMResourceResolver.resolveEntity</code>
* method.
* <p> The <code>DOMParser</code> will use the <code>LSInput</code>
* object to determine how to read XML input. If there is a character stream
* available, the parser will read that stream directly; if not, the parser
* will use a byte stream, if available; if neither a character stream nor a
* byte stream is available, the parser will attempt to open a URI
* connection to the resource identified by the system identifier.
* <p> An <code>LSInput</code> object belongs to the application: the
* parser shall never modify it in any way (it may modify a copy if
* necessary). Eventhough all attributes in this interface are writable the
* DOM implementation is expected to never mutate a LSInput.
* <p>See also the <a href='http://www.w3.org/TR/2001/WD-DOM-Level-3-ASLS-20011025'>Document Object Model (DOM) Level 3 Abstract Schemas and Load
and Save Specification</a>.
*
* @xerces.internal
*
* @author Gopal Sharma, SUN Microsystems Inc.
*/
// REVISIT:
// 1. it should be possible to do the following
// DOMInputImpl extends XMLInputSource implements LSInput
// 2. we probably need only the default constructor. -- el
public class DOMInputImpl implements LSInput {
//
// Data
//
protected String fPublicId = null;
protected String fSystemId = null;
protected String fBaseSystemId = null;
protected InputStream fByteStream = null;
protected Reader fCharStream = null;
protected String fData = null;
protected String fEncoding = null;
protected boolean fCertifiedText = false;
/**
* Default Constructor, constructs an input source
*
*
*/
public DOMInputImpl() {}
/**
* Constructs an input source from just the public and system
* identifiers, leaving resolution of the entity and opening of
* the input stream up to the caller.
*
* @param publicId The public identifier, if known.
* @param systemId The system identifier. This value should
* always be set, if possible, and can be
* relative or absolute. If the system identifier
* is relative, then the base system identifier
* should be set.
* @param baseSystemId The base system identifier. This value should
* always be set to the fully expanded URI of the
* base system identifier, if possible.
*/
public DOMInputImpl(String publicId, String systemId,
String baseSystemId) {
fPublicId = publicId;
fSystemId = systemId;
fBaseSystemId = baseSystemId;
} // DOMInputImpl(String,String,String)
/**
* Constructs an input source from a byte stream.
*
* @param publicId The public identifier, if known.
* @param systemId The system identifier. This value should
* always be set, if possible, and can be
* relative or absolute. If the system identifier
* is relative, then the base system identifier
* should be set.
* @param baseSystemId The base system identifier. This value should
* always be set to the fully expanded URI of the
* base system identifier, if possible.
* @param byteStream The byte stream.
* @param encoding The encoding of the byte stream, if known.
*/
public DOMInputImpl(String publicId, String systemId,
String baseSystemId, InputStream byteStream,
String encoding) {
fPublicId = publicId;
fSystemId = systemId;
fBaseSystemId = baseSystemId;
fByteStream = byteStream;
fEncoding = encoding;
} // DOMInputImpl(String,String,String,InputStream,String)
/**
* Constructs an input source from a character stream.
*
* @param publicId The public identifier, if known.
* @param systemId The system identifier. This value should
* always be set, if possible, and can be
* relative or absolute. If the system identifier
* is relative, then the base system identifier
* should be set.
* @param baseSystemId The base system identifier. This value should
* always be set to the fully expanded URI of the
* base system identifier, if possible.
* @param charStream The character stream.
* @param encoding The original encoding of the byte stream
* used by the reader, if known.
*/
public DOMInputImpl(String publicId, String systemId,
String baseSystemId, Reader charStream,
String encoding) {
fPublicId = publicId;
fSystemId = systemId;
fBaseSystemId = baseSystemId;
fCharStream = charStream;
fEncoding = encoding;
} // DOMInputImpl(String,String,String,Reader,String)
/**
* Constructs an input source from a String.
*
* @param publicId The public identifier, if known.
* @param systemId The system identifier. This value should
* always be set, if possible, and can be
* relative or absolute. If the system identifier
* is relative, then the base system identifier
* should be set.
* @param baseSystemId The base system identifier. This value should
* always be set to the fully expanded URI of the
* base system identifier, if possible.
* @param data The String Data.
* @param encoding The original encoding of the byte stream
* used by the reader, if known.
*/
public DOMInputImpl(String publicId, String systemId,
String baseSystemId, String data,
String encoding) {
fPublicId = publicId;
fSystemId = systemId;
fBaseSystemId = baseSystemId;
fData = data;
fEncoding = encoding;
} // DOMInputImpl(String,String,String,String,String)
/**
* An attribute of a language-binding dependent type that represents a
* stream of bytes.
* <br>The parser will ignore this if there is also a character stream
* specified, but it will use a byte stream in preference to opening a
* URI connection itself.
* <br>If the application knows the character encoding of the byte stream,
* it should set the encoding property. Setting the encoding in this way
* will override any encoding specified in the XML declaration itself.
*/
public InputStream getByteStream(){
return fByteStream;
}
/**
* An attribute of a language-binding dependent type that represents a
* stream of bytes.
* <br>The parser will ignore this if there is also a character stream
* specified, but it will use a byte stream in preference to opening a
* URI connection itself.
* <br>If the application knows the character encoding of the byte stream,
* it should set the encoding property. Setting the encoding in this way
* will override any encoding specified in the XML declaration itself.
*/
public void setByteStream(InputStream byteStream){
fByteStream = byteStream;
}
/**
* An attribute of a language-binding dependent type that represents a
* stream of 16-bit units. Application must encode the stream using
* UTF-16 (defined in and Amendment 1 of ).
* <br>If a character stream is specified, the parser will ignore any byte
* stream and will not attempt to open a URI connection to the system
* identifier.
*/
public Reader getCharacterStream(){
return fCharStream;
}
/**
* An attribute of a language-binding dependent type that represents a
* stream of 16-bit units. Application must encode the stream using
* UTF-16 (defined in and Amendment 1 of ).
* <br>If a character stream is specified, the parser will ignore any byte
* stream and will not attempt to open a URI connection to the system
* identifier.
*/
public void setCharacterStream(Reader characterStream){
fCharStream = characterStream;
}
/**
* A string attribute that represents a sequence of 16 bit units (utf-16
* encoded characters).
* <br>If string data is available in the input source, the parser will
* ignore the character stream and the byte stream and will not attempt
* to open a URI connection to the system identifier.
*/
public String getStringData(){
return fData;
}
/**
* A string attribute that represents a sequence of 16 bit units (utf-16
* encoded characters).
* <br>If string data is available in the input source, the parser will
* ignore the character stream and the byte stream and will not attempt
* to open a URI connection to the system identifier.
*/
public void setStringData(String stringData){
fData = stringData;
}
/**
* The character encoding, if known. The encoding must be a string
* acceptable for an XML encoding declaration ( section 4.3.3 "Character
* Encoding in Entities").
* <br>This attribute has no effect when the application provides a
* character stream. For other sources of input, an encoding specified
* by means of this attribute will override any encoding specified in
* the XML claration or the Text Declaration, or an encoding obtained
* from a higher level protocol, such as HTTP .
*/
public String getEncoding(){
return fEncoding;
}
/**
* The character encoding, if known. The encoding must be a string
* acceptable for an XML encoding declaration ( section 4.3.3 "Character
* Encoding in Entities").
* <br>This attribute has no effect when the application provides a
* character stream. For other sources of input, an encoding specified
* by means of this attribute will override any encoding specified in
* the XML claration or the Text Declaration, or an encoding obtained
* from a higher level protocol, such as HTTP .
*/
public void setEncoding(String encoding){
fEncoding = encoding;
}
/**
* The public identifier for this input source. The public identifier is
* always optional: if the application writer includes one, it will be
* provided as part of the location information.
*/
public String getPublicId(){
return fPublicId;
}
/**
* The public identifier for this input source. The public identifier is
* always optional: if the application writer includes one, it will be
* provided as part of the location information.
*/
public void setPublicId(String publicId){
fPublicId = publicId;
}
/**
* The system identifier, a URI reference , for this input source. The
* system identifier is optional if there is a byte stream or a
* character stream, but it is still useful to provide one, since the
* application can use it to resolve relative URIs and can include it in
* error messages and warnings (the parser will attempt to fetch the
* ressource identifier by the URI reference only if there is no byte
* stream or character stream specified).
* <br>If the application knows the character encoding of the object
* pointed to by the system identifier, it can register the encoding by
* setting the encoding attribute.
* <br>If the system ID is a relative URI reference (see section 5 in ),
* the behavior is implementation dependent.
*/
public String getSystemId(){
return fSystemId;
}
/**
* The system identifier, a URI reference , for this input source. The
* system identifier is optional if there is a byte stream or a
* character stream, but it is still useful to provide one, since the
* application can use it to resolve relative URIs and can include it in
* error messages and warnings (the parser will attempt to fetch the
* ressource identifier by the URI reference only if there is no byte
* stream or character stream specified).
* <br>If the application knows the character encoding of the object
* pointed to by the system identifier, it can register the encoding by
* setting the encoding attribute.
* <br>If the system ID is a relative URI reference (see section 5 in ),
* the behavior is implementation dependent.
*/
public void setSystemId(String systemId){
fSystemId = systemId;
}
/**
* The base URI to be used (see section 5.1.4 in ) for resolving relative
* URIs to absolute URIs. If the baseURI is itself a relative URI, the
* behavior is implementation dependent.
*/
public String getBaseURI(){
return fBaseSystemId;
}
/**
* The base URI to be used (see section 5.1.4 in ) for resolving relative
* URIs to absolute URIs. If the baseURI is itself a relative URI, the
* behavior is implementation dependent.
*/
public void setBaseURI(String baseURI){
fBaseSystemId = baseURI;
}
/**
* If set to true, assume that the input is certified (see section 2.13
* in [<a href='http://www.w3.org/TR/2002/CR-xml11-20021015/'>XML 1.1</a>]) when
* parsing [<a href='http://www.w3.org/TR/2002/CR-xml11-20021015/'>XML 1.1</a>].
*/
public boolean getCertifiedText(){
return fCertifiedText;
}
/**
* If set to true, assume that the input is certified (see section 2.13
* in [<a href='http://www.w3.org/TR/2002/CR-xml11-20021015/'>XML 1.1</a>]) when
* parsing [<a href='http://www.w3.org/TR/2002/CR-xml11-20021015/'>XML 1.1</a>].
*/
public void setCertifiedText(boolean certifiedText){
fCertifiedText = certifiedText;
}
}// class DOMInputImpl

View File

@@ -0,0 +1,163 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DOMLocator;
import org.w3c.dom.Node;
/**
* <code>DOMLocatorImpl</code> is an implementaion that describes a location (e.g.
* where an error occured).
* <p>See also the <a href='http://www.w3.org/TR/2001/WD-DOM-Level-3-Core-20010913'>Document Object Model (DOM) Level 3 Core Specification</a>.
*
* @xerces.internal
*
* @author Gopal Sharma, SUN Microsystems Inc.
*/
public class DOMLocatorImpl implements DOMLocator {
//
// Data
//
/**
* The column number where the error occured,
* or -1 if there is no column number available.
*/
public int fColumnNumber = -1;
/**
* The line number where the error occured,
* or -1 if there is no line number available.
*/
public int fLineNumber = -1;
/** related data node*/
public Node fRelatedNode = null;
/**
* The URI where the error occured,
* or null if there is no URI available.
*/
public String fUri = null;
/**
* The byte offset into the input source this locator is pointing to or -1
* if there is no byte offset available
*/
public int fByteOffset = -1;
/**
* The UTF-16, as defined in [Unicode] and Amendment 1 of [ISO/IEC 10646],
* offset into the input source this locator is pointing to or -1 if there
* is no UTF-16 offset available.
*/
public int fUtf16Offset = -1;
//
// Constructors
//
public DOMLocatorImpl(){
}
public DOMLocatorImpl (int lineNumber, int columnNumber, String uri ){
fLineNumber = lineNumber ;
fColumnNumber = columnNumber ;
fUri = uri;
} // DOMLocatorImpl (int lineNumber, int columnNumber, String uri )
public DOMLocatorImpl (int lineNumber, int columnNumber, int utf16Offset, String uri ){
fLineNumber = lineNumber ;
fColumnNumber = columnNumber ;
fUri = uri;
fUtf16Offset = utf16Offset;
} // DOMLocatorImpl (int lineNumber, int columnNumber, int utf16Offset, String uri )
public DOMLocatorImpl (int lineNumber, int columnNumber, int byteoffset, Node relatedData, String uri ){
fLineNumber = lineNumber ;
fColumnNumber = columnNumber ;
fByteOffset = byteoffset ;
fRelatedNode = relatedData ;
fUri = uri;
} // DOMLocatorImpl (int lineNumber, int columnNumber, int offset, Node errorNode, String uri )
public DOMLocatorImpl (int lineNumber, int columnNumber, int byteoffset, Node relatedData, String uri, int utf16Offset ){
fLineNumber = lineNumber ;
fColumnNumber = columnNumber ;
fByteOffset = byteoffset ;
fRelatedNode = relatedData ;
fUri = uri;
fUtf16Offset = utf16Offset;
} // DOMLocatorImpl (int lineNumber, int columnNumber, int offset, Node errorNode, String uri )
/**
* The line number where the error occured, or -1 if there is no line
* number available.
*/
public int getLineNumber(){
return fLineNumber;
}
/**
* The column number where the error occured, or -1 if there is no column
* number available.
*/
public int getColumnNumber(){
return fColumnNumber;
}
/**
* The URI where the error occured, or null if there is no URI available.
*/
public String getUri(){
return fUri;
}
public Node getRelatedNode(){
return fRelatedNode;
}
/**
* The byte offset into the input source this locator is pointing to or -1
* if there is no byte offset available
*/
public int getByteOffset(){
return fByteOffset;
}
/**
* The UTF-16, as defined in [Unicode] and Amendment 1 of [ISO/IEC 10646],
* offset into the input source this locator is pointing to or -1 if there
* is no UTF-16 offset available.
*/
public int getUtf16Offset(){
return fUtf16Offset;
}
}// class DOMLocatorImpl

View File

@@ -0,0 +1,143 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
/**
* Used to format DOM error messages, using the system locale.
*
* @xerces.internal
*
* @author Sandy Gao, IBM
*/
public class DOMMessageFormatter {
public static final String DOM_DOMAIN = "http://www.w3.org/dom/DOMTR";
public static final String XML_DOMAIN = "http://www.w3.org/TR/1998/REC-xml-19980210";
public static final String SERIALIZER_DOMAIN = "http://apache.org/xml/serializer";
private static ResourceBundle domResourceBundle = null;
private static ResourceBundle xmlResourceBundle = null;
private static ResourceBundle serResourceBundle = null;
private static Locale locale = null;
DOMMessageFormatter(){
locale = Locale.getDefault();
}
/**
* Formats a message with the specified arguments using the given
* locale information.
*
* @param domain domain from which error string is to come.
* @param key The message key.
* @param arguments The message replacement text arguments. The order
* of the arguments must match that of the placeholders
* in the actual message.
*
* @return the formatted message.
*
* @throws MissingResourceException Thrown if the message with the
* specified key cannot be found.
*/
public static String formatMessage(String domain,
String key, Object[] arguments)
throws MissingResourceException {
ResourceBundle resourceBundle = getResourceBundle(domain);
if(resourceBundle == null){
init();
resourceBundle = getResourceBundle(domain);
if(resourceBundle == null)
throw new MissingResourceException("Unknown domain" + domain, null, key);
}
// format message
String msg;
try {
msg = key + ": " + resourceBundle.getString(key);
if (arguments != null) {
try {
msg = java.text.MessageFormat.format(msg, arguments);
}
catch (Exception e) {
msg = resourceBundle.getString("FormatFailed");
msg += " " + resourceBundle.getString(key);
}
}
} // error
catch (MissingResourceException e) {
msg = resourceBundle.getString("BadMessageKey");
throw new MissingResourceException(key, msg, key);
}
// no message
if (msg == null) {
msg = key;
if (arguments.length > 0) {
StringBuffer str = new StringBuffer(msg);
str.append('?');
for (int i = 0; i < arguments.length; i++) {
if (i > 0) {
str.append('&');
}
str.append(String.valueOf(arguments[i]));
}
}
}
return msg;
}
static ResourceBundle getResourceBundle(String domain){
if(domain == DOM_DOMAIN || domain.equals(DOM_DOMAIN))
return domResourceBundle;
else if( domain == XML_DOMAIN || domain.equals(XML_DOMAIN))
return xmlResourceBundle;
else if(domain == SERIALIZER_DOMAIN || domain.equals(SERIALIZER_DOMAIN))
return serResourceBundle;
return null;
}
/**
* Initialize Message Formatter.
*/
public static void init(){
if (locale != null) {
domResourceBundle = SecuritySupport.getResourceBundle("com.sun.org.apache.xerces.internal.impl.msg.DOMMessages", locale);
serResourceBundle = SecuritySupport.getResourceBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLSerializerMessages", locale);
xmlResourceBundle = SecuritySupport.getResourceBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLMessages", locale);
}else{
domResourceBundle = SecuritySupport.getResourceBundle("com.sun.org.apache.xerces.internal.impl.msg.DOMMessages");
serResourceBundle = SecuritySupport.getResourceBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLSerializerMessages");
xmlResourceBundle = SecuritySupport.getResourceBundle("com.sun.org.apache.xerces.internal.impl.msg.XMLMessages");
}
}
/**
* setLocale to be used by the formatter.
* @param locale
*/
public static void setLocale(Locale dlocale){
locale = dlocale;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.ls.LSOutput;
import java.io.Writer;
import java.io.OutputStream;
/**
* This class represents an output destination for data.
* This interface allows an application to encapsulate information about an
* output destination in a single object, which may include a URI, a byte stream
* (possibly with a specifiedencoding), a base URI, and/or a character stream.
* The exact definitions of a byte stream and a character stream are binding
* dependent.
* The application is expected to provide objects that implement this interface
* whenever such objects are needed. The application can either provide its
* own objects that implement this interface, or it can use the generic factory
* method DOMImplementationLS.createLSOutput() to create objects that
* implement this interface.
* The DOMSerializer will use the LSOutput object to determine where to
* serialize the output to. The DOMSerializer will look at the different
* outputs specified in the LSOutput in the following order to know which one
* to output to, the first one that data can be output to will be used:
* 1.LSOutput.characterStream
* 2.LSOutput.byteStream
* 3.LSOutput.systemId
* LSOutput objects belong to the application. The DOM implementation will
* never modify them (though it may make copies and modify the copies,
* if necessary).
*
* @xerces.internal
*
* @author Arun Yadav, Sun Microsytems
* @author Gopal Sharma, Sun Microsystems
**/
public class DOMOutputImpl implements LSOutput {
protected Writer fCharStream = null;
protected OutputStream fByteStream = null;
protected String fSystemId = null;
protected String fEncoding = null;
/**
* Default Constructor
*/
public DOMOutputImpl() {}
/**
* An attribute of a language and binding dependent type that represents a
* writable stream of bytes. If the application knows the character encoding
* of the byte stream, it should set the encoding attribute. Setting the
* encoding in this way will override any encoding specified in an XML
* declaration in the data.
*/
public Writer getCharacterStream(){
return fCharStream;
};
/**
* An attribute of a language and binding dependent type that represents a
* writable stream of bytes. If the application knows the character encoding
* of the byte stream, it should set the encoding attribute. Setting the
* encoding in this way will override any encoding specified in an XML
* declaration in the data.
*/
public void setCharacterStream(Writer characterStream){
fCharStream = characterStream;
};
/**
* Depending on the language binding in use, this attribute may not be
* available. An attribute of a language and binding dependent type that
* represents a writable stream to which 16-bit units can be output. The
* application must encode the stream using UTF-16 (defined in [Unicode] and
* Amendment 1 of [ISO/IEC 10646]).
*/
public OutputStream getByteStream(){
return fByteStream;
};
/**
* Depending on the language binding in use, this attribute may not be
* available. An attribute of a language and binding dependent type that
* represents a writable stream to which 16-bit units can be output. The
* application must encode the stream using UTF-16 (defined in [Unicode] and
* Amendment 1 of [ISO/IEC 10646]).
*/
public void setByteStream(OutputStream byteStream){
fByteStream = byteStream;
};
/**
* The system identifier, a URI reference [IETF RFC 2396], for this output
* destination. If the application knows the character encoding of the
* object pointed to by the system identifier, it can set the encoding
* using the encoding attribute. If the system ID is a relative URI
* reference (see section 5 in [IETF RFC 2396]), the behavior is
* implementation dependent.
*/
public String getSystemId(){
return fSystemId;
};
/**
* The system identifier, a URI reference [IETF RFC 2396], for this output
* destination. If the application knows the character encoding of the
* object pointed to by the system identifier, it can set the encoding
* using the encoding attribute. If the system ID is a relative URI
* reference (see section 5 in [IETF RFC 2396]), the behavior is
* implementation dependent.
*/
public void setSystemId(String systemId){
fSystemId = systemId;
};
/**
* The character encoding, if known. The encoding must be a string
* acceptable for an XML encoding declaration ([XML 1.0] section 4.3.3
* "Character Encoding in Entities"). This attribute has no effect when the
* application provides a character stream or string data. For other sources
* of input, an encoding specified by means of this attribute will override
* any encoding specified in the XML declaration or the Text declaration, or
* an encoding obtained from a higher level protocol, such as HTTP
* [IETF RFC 2616].
*/
public String getEncoding(){
return fEncoding;
};
/**
* The character encoding, if known. The encoding must be a string
* acceptable for an XML encoding declaration ([XML 1.0] section 4.3.3
* "Character Encoding in Entities"). This attribute has no effect when the
* application provides a character stream or string data. For other sources
* of input, an encoding specified by means of this attribute will override
* any encoding specified in the XML declaration or the Text declaration, or
* an encoding obtained from a higher level protocol, such as HTTP
* [IETF RFC 2616].
*/
public void setEncoding(String encoding){
fEncoding = encoding;
};
}//DOMOutputImpl

View File

@@ -0,0 +1,99 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.util.ArrayList;
import java.util.Vector;
import org.w3c.dom.DOMStringList;
/**
* DOM Level 3
*
* This class implements the DOM Level 3 Core interface DOMStringList.
*
* @xerces.internal
*
* @author Neil Delima, IBM
*/
public class DOMStringListImpl implements DOMStringList {
// A collection of DOMString values
private final ArrayList fStrings;
/**
* Construct an empty list of DOMStringListImpl
*/
public DOMStringListImpl() {
fStrings = new ArrayList();
}
/**
* Construct a DOMStringListImpl from an ArrayList
*/
public DOMStringListImpl(ArrayList params) {
fStrings = params;
}
/**
* Construct a DOMStringListImpl from a Vector
*/
public DOMStringListImpl(Vector params) {
fStrings = new ArrayList(params);
}
/**
* @see org.w3c.dom.DOMStringList#item(int)
*/
public String item(int index) {
final int length = getLength();
if (index >= 0 && index < length) {
return (String) fStrings.get(index);
}
return null;
}
/**
* @see org.w3c.dom.DOMStringList#getLength()
*/
public int getLength() {
return fStrings.size();
}
/**
* @see org.w3c.dom.DOMStringList#contains(String)
*/
public boolean contains(String param) {
return fStrings.contains(param);
}
/**
* DOM Internal:
* Add a <code>DOMString</code> to the list.
*
* @param domString A string to add to the list
*/
public void add(String param) {
fStrings.add(param);
}
}

View File

@@ -0,0 +1,101 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.impl.xs.XSImplementationImpl;
import org.w3c.dom.DOMImplementationList;
import org.w3c.dom.DOMImplementation;
import java.util.Vector;
/**
* Allows to retrieve <code>XSImplementation</code>, DOM Level 3 Core and LS implementations
* and PSVI implementation.
* <p>See also the <a href='http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#DOMImplementationSource'>Document Object Model (DOM) Level 3 Core Specification</a>.
*
* @xerces.internal
*
* @author Elena Litani, IBM
*/
public class DOMXSImplementationSourceImpl
extends DOMImplementationSourceImpl {
/**
* A method to request a DOM implementation.
* @param features A string that specifies which features are required.
* This is a space separated list in which each feature is specified
* by its name optionally followed by a space and a version number.
* This is something like: "XML 1.0 Traversal Events 2.0"
* @return An implementation that has the desired features, or
* <code>null</code> if this source has none.
*/
public DOMImplementation getDOMImplementation(String features) {
DOMImplementation impl = super.getDOMImplementation(features);
if (impl != null){
return impl;
}
// if not try the PSVIDOMImplementation
impl = PSVIDOMImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
return impl;
}
// if not try the XSImplementation
impl = XSImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
return impl;
}
return null;
}
/**
* A method to request a list of DOM implementations that support the
* specified features and versions, as specified in .
* @param features A string that specifies which features and versions
* are required. This is a space separated list in which each feature
* is specified by its name optionally followed by a space and a
* version number. This is something like: "XML 3.0 Traversal +Events
* 2.0"
* @return A list of DOM implementations that support the desired
* features.
*/
public DOMImplementationList getDOMImplementationList(String features) {
final Vector implementations = new Vector();
// first check whether the CoreDOMImplementation would do
DOMImplementationList list = super.getDOMImplementationList(features);
//Add core DOMImplementations
for (int i=0; i < list.getLength(); i++ ) {
implementations.addElement(list.item(i));
}
DOMImplementation impl = PSVIDOMImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
implementations.addElement(impl);
}
impl = XSImplementationImpl.getDOMImplementation();
if (testImpl(impl, features)) {
implementations.addElement(impl);
}
return new DOMImplementationListImpl(implementations);
}
}

View File

@@ -0,0 +1,248 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.Vector;
/**
* This class implements the DOM's NodeList behavior for
* Element.getElementsByTagName()
* <P>
* The DOM describes NodeList as follows:
* <P>
* 1) It may represent EITHER nodes scattered through a subtree (when
* returned by Element.getElementsByTagName), or just the immediate
* children (when returned by Node.getChildNodes). The latter is easy,
* but the former (which this class addresses) is more challenging.
* <P>
* 2) Its behavior is "live" -- that is, it always reflects the
* current state of the document tree. To put it another way, the
* NodeLists obtained before and after a series of insertions and
* deletions are effectively identical (as far as the user is
* concerned, the former has been dynamically updated as the changes
* have been made).
* <P>
* 3) Its API accesses individual nodes via an integer index, with the
* listed nodes numbered sequentially in the order that they were
* found during a preorder depth-first left-to-right search of the tree.
* (Of course in the case of getChildNodes, depth is not involved.) As
* nodes are inserted or deleted in the tree, and hence the NodeList,
* the numbering of nodes that follow them in the NodeList will
* change.
* <P>
* It is rather painful to support the latter two in the
* getElementsByTagName case. The current solution is for Nodes to
* maintain a change count (eventually that may be a Digest instead),
* which the NodeList tracks and uses to invalidate itself.
* <P>
* Unfortunately, this does _not_ respond efficiently in the case that
* the dynamic behavior was supposed to address: scanning a tree while
* it is being extended. That requires knowing which subtrees have
* changed, which can become an arbitrarily complex problem.
* <P>
* We save some work by filling the vector only as we access the
* item()s... but I suspect the same users who demanded index-based
* access will also start by doing a getLength() to control their loop,
* blowing this optimization out of the water.
* <P>
* NOTE: Level 2 of the DOM will probably _not_ use NodeList for its
* extended search mechanisms, partly for the reasons just discussed.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeepNodeListImpl
implements NodeList {
//
// Data
//
protected NodeImpl rootNode; // Where the search started
protected String tagName; // Or "*" to mean all-tags-acceptable
protected int changes=0;
protected Vector nodes;
protected String nsName;
protected boolean enableNS = false;
//
// Constructors
//
/** Constructor. */
public DeepNodeListImpl(NodeImpl rootNode, String tagName) {
this.rootNode = rootNode;
this.tagName = tagName;
nodes = new Vector();
}
/** Constructor for Namespace support. */
public DeepNodeListImpl(NodeImpl rootNode,
String nsName, String tagName) {
this(rootNode, tagName);
this.nsName = (nsName != null && !nsName.equals("")) ? nsName : null;
enableNS = true;
}
//
// NodeList methods
//
/** Returns the length of the node list. */
public int getLength() {
// Preload all matching elements. (Stops when we run out of subtree!)
item(java.lang.Integer.MAX_VALUE);
return nodes.size();
}
/** Returns the node at the specified index. */
public Node item(int index) {
Node thisNode;
// Tree changed. Do it all from scratch!
if(rootNode.changes() != changes) {
nodes = new Vector();
changes = rootNode.changes();
}
// In the cache
if (index < nodes.size())
return (Node)nodes.elementAt(index);
// Not yet seen
else {
// Pick up where we left off (Which may be the beginning)
if (nodes.size() == 0)
thisNode = rootNode;
else
thisNode=(NodeImpl)(nodes.lastElement());
// Add nodes up to the one we're looking for
while(thisNode != null && index >= nodes.size()) {
thisNode=nextMatchingElementAfter(thisNode);
if (thisNode != null)
nodes.addElement(thisNode);
}
// Either what we want, or null (not avail.)
return thisNode;
}
} // item(int):Node
//
// Protected methods (might be overridden by an extending DOM)
//
/**
* Iterative tree-walker. When you have a Parent link, there's often no
* need to resort to recursion. NOTE THAT only Element nodes are matched
* since we're specifically supporting getElementsByTagName().
*/
protected Node nextMatchingElementAfter(Node current) {
Node next;
while (current != null) {
// Look down to first child.
if (current.hasChildNodes()) {
current = (current.getFirstChild());
}
// Look right to sibling (but not from root!)
else if (current != rootNode && null != (next = current.getNextSibling())) {
current = next;
}
// Look up and right (but not past root!)
else {
next = null;
for (; current != rootNode; // Stop when we return to starting point
current = current.getParentNode()) {
next = current.getNextSibling();
if (next != null)
break;
}
current = next;
}
// Have we found an Element with the right tagName?
// ("*" matches anything.)
if (current != rootNode
&& current != null
&& current.getNodeType() == Node.ELEMENT_NODE) {
if (!enableNS) {
if (tagName.equals("*") ||
((ElementImpl) current).getTagName().equals(tagName))
{
return current;
}
} else {
// DOM2: Namespace logic.
if (tagName.equals("*")) {
if (nsName != null && nsName.equals("*")) {
return current;
} else {
ElementImpl el = (ElementImpl) current;
if ((nsName == null
&& el.getNamespaceURI() == null)
|| (nsName != null
&& nsName.equals(el.getNamespaceURI())))
{
return current;
}
}
} else {
ElementImpl el = (ElementImpl) current;
if (el.getLocalName() != null
&& el.getLocalName().equals(tagName)) {
if (nsName != null && nsName.equals("*")) {
return current;
} else {
if ((nsName == null
&& el.getNamespaceURI() == null)
|| (nsName != null &&
nsName.equals(el.getNamespaceURI())))
{
return current;
}
}
}
}
}
}
// Otherwise continue walking the tree
}
// Fell out of tree-walk; no more instances found
return null;
} // nextMatchingElementAfter(int):Node
} // class DeepNodeListImpl

View File

@@ -0,0 +1,146 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* WARNING: because java doesn't support multi-inheritance some code is
* duplicated. If you're changing this file you probably want to change
* DeferredAttrNSImpl.java at the same time.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* Attribute represents an XML-style attribute of an
* Element. Typically, the allowable values are controlled by its
* declaration in the Document Type Definition (DTD) governing this
* kind of document.
* <P>
* If the attribute has not been explicitly assigned a value, but has
* been declared in the DTD, it will exist and have that default. Only
* if neither the document nor the DTD specifies a value will the
* Attribute really be considered absent and have no value; in that
* case, querying the attribute will return null.
* <P>
* Attributes may have multiple children that contain their data. (XML
* allows attributes to contain entity references, and tokenized
* attribute types such as NMTOKENS may have a child for each token.)
* For convenience, the Attribute object's getValue() method returns
* the string version of the attribute's value.
* <P>
* Attributes are not children of the Elements they belong to, in the
* usual sense, and have no valid Parent reference. However, the spec
* says they _do_ belong to a specific Element, and an INUSE exception
* is to be thrown if the user attempts to explicitly share them
* between elements.
* <P>
* Note that Elements do not permit attributes to appear to be shared
* (see the INUSE exception), so this object's mutability is
* officially not an issue.
* <P>
* DeferredAttrImpl inherits from AttrImpl which does not support
* Namespaces. DeferredAttrNSImpl, which inherits from AttrNSImpl, does.
* @see DeferredAttrNSImpl
*
* @xerces.internal
*
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
* @since PR-DOM-Level-1-19980818.
*/
public final class DeferredAttrImpl
extends AttrImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 6903232312469148636L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredAttrImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
needsSyncChildren(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
name = ownerDocument.getNodeName(fNodeIndex);
int extra = ownerDocument.getNodeExtra(fNodeIndex);
isSpecified((extra & SPECIFIED) != 0);
isIdAttribute((extra & ID) != 0);
int extraNode = ownerDocument.getLastChild(fNodeIndex);
type = ownerDocument.getTypeInfo(extraNode);
} // synchronizeData()
/**
* Synchronizes the node's children with the internal structure.
* Fluffing the children at once solves a lot of work to keep
* the two structures in sync. The problem gets worse when
* editing the tree -- this makes it a lot easier.
*/
protected void synchronizeChildren() {
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
ownerDocument.synchronizeChildren(this, fNodeIndex);
} // synchronizeChildren()
} // class DeferredAttrImpl

View File

@@ -0,0 +1,131 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* WARNING: because java doesn't support multi-inheritance some code is
* duplicated. If you're changing this file you probably want to change
* DeferredAttrImpl.java at the same time.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* DeferredAttrNSImpl is to AttrNSImpl, what DeferredAttrImpl is to
* AttrImpl.
*
* @xerces.internal
*
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
* @see DeferredAttrImpl
*/
public final class DeferredAttrNSImpl
extends AttrNSImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 6074924934945957154L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredAttrNSImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
needsSyncChildren(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
name = ownerDocument.getNodeName(fNodeIndex);
// extract prefix and local part from QName
int index = name.indexOf(':');
if (index < 0) {
localName = name;
}
else {
localName = name.substring(index + 1);
}
int extra = ownerDocument.getNodeExtra(fNodeIndex);
isSpecified((extra & SPECIFIED) != 0);
isIdAttribute((extra & ID) != 0);
namespaceURI = ownerDocument.getNodeURI(fNodeIndex);
int extraNode = ownerDocument.getLastChild(fNodeIndex);
type = ownerDocument.getTypeInfo(extraNode);
} // synchronizeData()
/**
* Synchronizes the node's children with the internal structure.
* Fluffing the children at once solves a lot of work to keep
* the two structures in sync. The problem gets worse when
* editing the tree -- this makes it a lot easier.
*/
protected void synchronizeChildren() {
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
ownerDocument.synchronizeChildren(this, fNodeIndex);
} // synchronizeChildren()
} // class DeferredAttrImpl

View File

@@ -0,0 +1,110 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* XML provides the CDATA markup to allow a region of text in which
* most of the XML delimiter recognition does not take place. This is
* intended to ease the task of quoting XML fragments and other
* programmatic information in a document's text without needing to
* escape these special characters. It's primarily a convenience feature
* for those who are hand-editing XML.
* <P>
* CDATASection is an Extended DOM feature, and is not used in HTML
* contexts.
* <P>
* Within the DOM, CDATASections are treated essentially as Text
* blocks. Their distinct type is retained in order to allow us to
* properly recreate the XML syntax when we write them out.
* <P>
* Reminder: CDATA IS NOT A COMPLETELY GENERAL SOLUTION; it can't
* quote its own end-of-block marking. If you need to write out a
* CDATA that contains the ]]> sequence, it's your responsibility to
* split that string over two successive CDATAs at that time.
* <P>
* CDATA does not participate in Element.normalize() processing.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredCDATASectionImpl
extends CDATASectionImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 1983580632355645726L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here. All other data,
* can be requested from the ownerDocument via the index.
*/
DeferredCDATASectionImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) this.ownerDocument();
data = ownerDocument.getNodeValueString(fNodeIndex);
} // synchronizeData()
} // class DeferredCDATASectionImpl

View File

@@ -0,0 +1,91 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* Represents an XML (or HTML) comment.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredCommentImpl
extends CommentImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 6498796371083589338L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here. All other data,
* can be requested from the ownerDocument via the index.
*/
DeferredCommentImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) this.ownerDocument();
data = ownerDocument.getNodeValueString(fNodeIndex);
} // synchronizeData()
} // class DeferredCommentImpl

View File

@@ -0,0 +1,60 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DOMImplementation;
/**
* <p>This DOMImplementation class is description of a particular
* implementation of the Document Object Model. As such its data is
* static, shared by all instances of this implementation.</p>
*
* <p>This implementation simply extends DOMImplementationImpl to differentiate
* between the Deferred DOM Implementations and Non-Deferred DOM Implementations.</p>
*
* @xerces.internal
*
* @author Neil Delima, IBM
*
*/
public class DeferredDOMImplementationImpl
extends DOMImplementationImpl {
//
// Data
//
// static
/** Dom implementation singleton. */
static DeferredDOMImplementationImpl singleton = new DeferredDOMImplementationImpl();
//
// Public methods
//
/** NON-DOM: Obtain and return the single shared object */
public static DOMImplementation getDOMImplementation() {
return singleton;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,188 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Node;
/**
* This class represents a Document Type <em>declaraction</em> in
* the document itself, <em>not</em> a Document Type Definition (DTD).
* An XML document may (or may not) have such a reference.
* <P>
* DocumentType is an Extended DOM feature, used in XML documents but
* not in HTML.
* <P>
* Note that Entities and Notations are no longer children of the
* DocumentType, but are parentless nodes hung only in their
* appropriate NamedNodeMaps.
* <P>
* This area is UNDERSPECIFIED IN REC-DOM-Level-1-19981001
* Most notably, absolutely no provision was made for storing
* and using Element and Attribute information. Nor was the linkage
* between Entities and Entity References nailed down solidly.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredDocumentTypeImpl
extends DocumentTypeImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -2172579663227313509L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredDocumentTypeImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
needsSyncChildren(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
name = ownerDocument.getNodeName(fNodeIndex);
// public and system ids
publicID = ownerDocument.getNodeValue(fNodeIndex);
systemID = ownerDocument.getNodeURI(fNodeIndex);
int extraDataIndex = ownerDocument.getNodeExtra(fNodeIndex);
internalSubset = ownerDocument.getNodeValue(extraDataIndex);
} // synchronizeData()
/** Synchronizes the entities, notations, and elements. */
protected void synchronizeChildren() {
// we don't want to generate any event for this so turn them off
boolean orig = ownerDocument().getMutationEvents();
ownerDocument().setMutationEvents(false);
// no need to synchronize again
needsSyncChildren(false);
// create new node maps
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
entities = new NamedNodeMapImpl(this);
notations = new NamedNodeMapImpl(this);
elements = new NamedNodeMapImpl(this);
// fill node maps
DeferredNode last = null;
for (int index = ownerDocument.getLastChild(fNodeIndex);
index != -1;
index = ownerDocument.getPrevSibling(index)) {
DeferredNode node = ownerDocument.getNodeObject(index);
int type = node.getNodeType();
switch (type) {
// internal, external, and unparsed entities
case Node.ENTITY_NODE: {
entities.setNamedItem(node);
break;
}
// notations
case Node.NOTATION_NODE: {
notations.setNamedItem(node);
break;
}
// element definitions
case NodeImpl.ELEMENT_DEFINITION_NODE: {
elements.setNamedItem(node);
break;
}
// elements
case Node.ELEMENT_NODE: {
if (((DocumentImpl)getOwnerDocument()).allowGrammarAccess){
insertBefore(node, last);
last = node;
break;
}
}
// NOTE: Should never get here! -Ac
default: {
System.out.println("DeferredDocumentTypeImpl" +
"#synchronizeInfo: " +
"node.getNodeType() = " +
node.getNodeType() +
", class = " +
node.getClass().getName());
}
}
}
// set mutation events flag back to its original value
ownerDocument().setMutationEvents(orig);
// set entities and notations read_only per DOM spec
setReadOnly(true, false);
} // synchronizeChildren()
} // class DeferredDocumentTypeImpl

View File

@@ -0,0 +1,127 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Node;
/**
* NON-DOM CLASS: Describe one of the Elements (and its associated
* Attributes) defined in this Document Type.
* <p>
* I've included this in Level 1 purely as an anchor point for default
* attributes. In Level 2 it should enable the ChildRule support.
*
* @xerces.internal
*
*/
public class DeferredElementDefinitionImpl
extends ElementDefinitionImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 6703238199538041591L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredElementDefinitionImpl(DeferredDocumentImpl ownerDocument,
int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
needsSyncChildren(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
name = ownerDocument.getNodeName(fNodeIndex);
} // synchronizeData()
/** Synchronizes the default attribute values. */
protected void synchronizeChildren() {
// we don't want to generate any event for this so turn them off
boolean orig = ownerDocument.getMutationEvents();
ownerDocument.setMutationEvents(false);
// attributes are now synced
needsSyncChildren(false);
// create attributes node map
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
attributes = new NamedNodeMapImpl(ownerDocument);
// Default attributes dangle as children of the element
// definition "node" in the internal fast table.
for (int nodeIndex = ownerDocument.getLastChild(fNodeIndex);
nodeIndex != -1;
nodeIndex = ownerDocument.getPrevSibling(nodeIndex)) {
Node attr = ownerDocument.getNodeObject(nodeIndex);
attributes.setNamedItem(attr);
}
// set mutation events flag back to its original value
ownerDocument.setMutationEvents(orig);
} // synchronizeChildren()
} // class DeferredElementDefinitionImpl

View File

@@ -0,0 +1,139 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* WARNING: because java doesn't support multi-inheritance some code is
* duplicated. If you're changing this file you probably want to change
* DeferredElementNSImpl.java at the same time.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.NamedNodeMap;
/**
* Elements represent most of the "markup" and structure of the
* document. They contain both the data for the element itself
* (element name and attributes), and any contained nodes, including
* document text (as children).
* <P>
* Elements may have Attributes associated with them; the API for this is
* defined in Node, but the function is implemented here. In general, XML
* applications should retrive Attributes as Nodes, since they may contain
* entity references and hence be a fairly complex sub-tree. HTML users will
* be dealing with simple string values, and convenience methods are provided
* to work in terms of Strings.
* <P>
* DeferredElementImpl inherits from ElementImpl which does not support
* Namespaces. DeferredElementNSImpl, which inherits from ElementNSImpl, does.
* @see DeferredElementNSImpl
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredElementImpl
extends ElementImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -7670981133940934842L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here. All
* other data, can be requested from the ownerDocument via the index.
*/
DeferredElementImpl(DeferredDocumentImpl ownerDoc, int nodeIndex) {
super(ownerDoc, null);
fNodeIndex = nodeIndex;
needsSyncChildren(true);
} // <init>(DocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public final int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected final void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
// we don't want to generate any event for this so turn them off
boolean orig = ownerDocument.mutationEvents;
ownerDocument.mutationEvents = false;
name = ownerDocument.getNodeName(fNodeIndex);
// attributes
setupDefaultAttributes();
int index = ownerDocument.getNodeExtra(fNodeIndex);
if (index != -1) {
NamedNodeMap attrs = getAttributes();
do {
NodeImpl attr = (NodeImpl)ownerDocument.getNodeObject(index);
attrs.setNamedItem(attr);
index = ownerDocument.getPrevSibling(index);
} while (index != -1);
}
// set mutation events flag back to its original value
ownerDocument.mutationEvents = orig;
} // synchronizeData()
protected final void synchronizeChildren() {
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
ownerDocument.synchronizeChildren(this, fNodeIndex);
} // synchronizeChildren()
} // class DeferredElementImpl

View File

@@ -0,0 +1,162 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* WARNING: because java doesn't support multi-inheritance some code is
* duplicated. If you're changing this file you probably want to change
* DeferredElementImpl.java at the same time.
*
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
import org.w3c.dom.NamedNodeMap;
/**
* DeferredElementNSImpl is to ElementNSImpl, what DeferredElementImpl is to
* ElementImpl.
*
* @xerces.internal
*
* @see DeferredElementImpl
*/
public class DeferredElementNSImpl
extends ElementNSImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -5001885145370927385L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here. All
* other data, can be requested from the ownerDocument via the index.
*/
DeferredElementNSImpl(DeferredDocumentImpl ownerDoc, int nodeIndex) {
super(ownerDoc, null);
fNodeIndex = nodeIndex;
needsSyncChildren(true);
} // <init>(DocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public final int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data (name and value) for fast nodes. */
protected final void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) this.ownerDocument;
// we don't want to generate any event for this so turn them off
boolean orig = ownerDocument.mutationEvents;
ownerDocument.mutationEvents = false;
name = ownerDocument.getNodeName(fNodeIndex);
// extract local part from QName
int index = name.indexOf(':');
if (index < 0) {
localName = name;
}
else {
localName = name.substring(index + 1);
}
namespaceURI = ownerDocument.getNodeURI(fNodeIndex);
type = (XSTypeDefinition)ownerDocument.getTypeInfo(fNodeIndex);
// attributes
setupDefaultAttributes();
int attrIndex = ownerDocument.getNodeExtra(fNodeIndex);
if (attrIndex != -1) {
NamedNodeMap attrs = getAttributes();
boolean seenSchemaDefault = false;
do {
AttrImpl attr = (AttrImpl) ownerDocument.getNodeObject(attrIndex);
// Take special care of schema defaulted attributes. Calling the
// non-namespace aware setAttributeNode() method could overwrite
// another attribute with the same local name.
if (!attr.getSpecified() && (seenSchemaDefault ||
(attr.getNamespaceURI() != null &&
attr.getNamespaceURI() != NamespaceContext.XMLNS_URI &&
attr.getName().indexOf(':') < 0))) {
seenSchemaDefault = true;
attrs.setNamedItemNS(attr);
}
else {
attrs.setNamedItem(attr);
}
attrIndex = ownerDocument.getPrevSibling(attrIndex);
} while (attrIndex != -1);
}
// set mutation events flag back to its original value
ownerDocument.mutationEvents = orig;
} // synchronizeData()
/**
* Synchronizes the node's children with the internal structure.
* Fluffing the children at once solves a lot of work to keep
* the two structures in sync. The problem gets worse when
* editing the tree -- this makes it a lot easier.
*/
protected final void synchronizeChildren() {
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
ownerDocument.synchronizeChildren(this, fNodeIndex);
} // synchronizeChildren()
} // class DeferredElementImpl

View File

@@ -0,0 +1,154 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* Entity nodes hold the reference data for an XML Entity -- either
* parsed or unparsed. The nodeName (inherited from Node) will contain
* the name (if any) of the Entity. Its data will be contained in the
* Entity's children, in exactly the structure which an
* EntityReference to this name will present within the document's
* body.
* <P>
* Note that this object models the actual entity, _not_ the entity
* declaration or the entity reference.
* <P>
* An XML processor may choose to completely expand entities before
* the structure model is passed to the DOM; in this case, there will
* be no EntityReferences in the DOM tree.
* <P>
* Quoting the 10/01 DOM Proposal,
* <BLOCKQUOTE>
* "The DOM Level 1 does not support editing Entity nodes; if a user
* wants to make changes to the contents of an Entity, every related
* EntityReference node has to be replaced in the structure model by
* a clone of the Entity's contents, and then the desired changes
* must be made to each of those clones instead. All the
* descendants of an Entity node are readonly."
* </BLOCKQUOTE>
* I'm interpreting this as: It is the parser's responsibilty to call
* the non-DOM operation setReadOnly(true,true) after it constructs
* the Entity. Since the DOM explicitly decided not to deal with this,
* _any_ answer will involve a non-DOM operation, and this is the
* simplest solution.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredEntityImpl
extends EntityImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 4760180431078941638L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredEntityImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
needsSyncChildren(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/**
* Synchronize the entity data. This is special because of the way
* that the "fast" version stores the information.
*/
protected void synchronizeData() {
// no need to sychronize again
needsSyncData(false);
// get the node data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
name = ownerDocument.getNodeName(fNodeIndex);
// get the entity data
publicId = ownerDocument.getNodeValue(fNodeIndex);
systemId = ownerDocument.getNodeURI(fNodeIndex);
int extraDataIndex = ownerDocument.getNodeExtra(fNodeIndex);
ownerDocument.getNodeType(extraDataIndex);
notationName = ownerDocument.getNodeName(extraDataIndex);
// encoding and version DOM L3
version = ownerDocument.getNodeValue(extraDataIndex);
encoding = ownerDocument.getNodeURI(extraDataIndex);
// baseURI, actualEncoding DOM L3
int extraIndex2 = ownerDocument.getNodeExtra(extraDataIndex);
baseURI = ownerDocument.getNodeName(extraIndex2);
inputEncoding = ownerDocument.getNodeValue(extraIndex2);
} // synchronizeData()
/** Synchronize the children. */
protected void synchronizeChildren() {
// no need to synchronize again
needsSyncChildren(false);
isReadOnly(false);
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
ownerDocument.synchronizeChildren(this, fNodeIndex);
setReadOnly(true, true);
} // synchronizeChildren()
} // class DeferredEntityImpl

View File

@@ -0,0 +1,156 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* EntityReference models the XML &entityname; syntax, when used for
* entities defined by the DOM. Entities hardcoded into XML, such as
* character entities, should instead have been translated into text
* by the code which generated the DOM tree.
* <P>
* An XML processor has the alternative of fully expanding Entities
* into the normal document tree. If it does so, no EntityReference nodes
* will appear.
* <P>
* Similarly, non-validating XML processors are not required to read
* or process entity declarations made in the external subset or
* declared in external parameter entities. Hence, some applications
* may not make the replacement value available for Parsed Entities
* of these types.
* <P>
* EntityReference behaves as a read-only node, and the children of
* the EntityReference (which reflect those of the Entity, and should
* also be read-only) give its replacement value, if any. They are
* supposed to automagically stay in synch if the DocumentType is
* updated with new values for the Entity.
* <P>
* The defined behavior makes efficient storage difficult for the DOM
* implementor. We can't just look aside to the Entity's definition
* in the DocumentType since those nodes have the wrong parent (unless
* we can come up with a clever "imaginary parent" mechanism). We
* must at least appear to clone those children... which raises the
* issue of keeping the reference synchronized with its parent.
* This leads me back to the "cached image of centrally defined data"
* solution, much as I dislike it.
* <P>
* For now I have decided, since REC-DOM-Level-1-19980818 doesn't
* cover this in much detail, that synchronization doesn't have to be
* considered while the user is deep in the tree. That is, if you're
* looking within one of the EntityReferennce's children and the Entity
* changes, you won't be informed; instead, you will continue to access
* the same object -- which may or may not still be part of the tree.
* This is the same behavior that obtains elsewhere in the DOM if the
* subtree you're looking at is deleted from its parent, so it's
* acceptable here. (If it really bothers folks, we could set things
* up so deleted subtrees are walked and marked invalid, but that's
* not part of the DOM's defined behavior.)
* <P>
* As a result, only the EntityReference itself has to be aware of
* changes in the Entity. And it can take advantage of the same
* structure-change-monitoring code I implemented to support
* DeepNodeList.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredEntityReferenceImpl
extends EntityReferenceImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 390319091370032223L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredEntityReferenceImpl(DeferredDocumentImpl ownerDocument,
int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/**
* Synchronize the entity data. This is special because of the way
* that the "fast" version stores the information.
*/
protected void synchronizeData() {
// no need to sychronize again
needsSyncData(false);
// get the node data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
name = ownerDocument.getNodeName(fNodeIndex);
baseURI = ownerDocument.getNodeValue(fNodeIndex);
} // synchronizeData()
/** Synchronize the children. */
protected void synchronizeChildren() {
// no need to synchronize again
needsSyncChildren(false);
// get children
isReadOnly(false);
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) ownerDocument();
ownerDocument.synchronizeChildren(this, fNodeIndex);
setReadOnly(true, true);
} // synchronizeChildren()
} // class DeferredEntityReferenceImpl

View File

@@ -0,0 +1,44 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Node;
/**
* An interface for deferred node object.
*
* @xerces.internal
*
*/
public interface DeferredNode extends Node {
public static final short TYPE_NODE = 20;
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex();
} // interface DeferredNode

View File

@@ -0,0 +1,118 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* Notations are how the Document Type Description (DTD) records hints
* about the format of an XML "unparsed entity" -- in other words,
* non-XML data bound to this document type, which some applications
* may wish to consult when manipulating the document. A Notation
* represents a name-value pair, with its nodeName being set to the
* declared name of the notation.
* <P>
* Notations are also used to formally declare the "targets" of
* Processing Instructions.
* <P>
* Note that the Notation's data is non-DOM information; the DOM only
* records what and where it is.
* <P>
* See the XML 1.0 spec, sections 4.7 and 2.6, for more info.
* <P>
* Level 1 of the DOM does not support editing Notation contents.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredNotationImpl
extends NotationImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 5705337172887990848L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredNotationImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/**
* Synchronizes the data. This is special because of the way
* that the "fast" notation stores its information internally.
*/
protected void synchronizeData() {
// no need to synchronize again
needsSyncData(false);
// name
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument();
name = ownerDocument.getNodeName(fNodeIndex);
ownerDocument.getNodeType(fNodeIndex);
// public and system ids
publicId = ownerDocument.getNodeValue(fNodeIndex);
systemId = ownerDocument.getNodeURI(fNodeIndex);
int extraDataIndex = ownerDocument.getNodeExtra(fNodeIndex);
ownerDocument.getNodeType(extraDataIndex);
baseURI = ownerDocument.getNodeName(extraDataIndex);
} // synchronizeData()
} // class DeferredNotationImpl

View File

@@ -0,0 +1,95 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* Processing Instructions (PIs) permit documents to carry
* processor-specific information alongside their actual content. PIs
* are most common in XML, but they are supported in HTML as well.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredProcessingInstructionImpl
extends ProcessingInstructionImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -4643577954293565388L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredProcessingInstructionImpl(DeferredDocumentImpl ownerDocument,
int nodeIndex) {
super(ownerDocument, null, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the data. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff data
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) this.ownerDocument();
target = ownerDocument.getNodeName(fNodeIndex);
data = ownerDocument.getNodeValueString(fNodeIndex);
} // synchronizeData()
} // class DeferredProcessingInstructionImpl

View File

@@ -0,0 +1,108 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/**
* Text nodes hold the non-markup, non-Entity content of
* an Element or Attribute.
* <P>
* When a document is first made available to the DOM, there is only
* one Text object for each block of adjacent plain-text. Users (ie,
* applications) may create multiple adjacent Texts during editing --
* see {@link org.w3c.dom.Element#normalize} for discussion.
* <P>
* Note that CDATASection is a subclass of Text. This is conceptually
* valid, since they're really just two different ways of quoting
* characters when they're written out as part of an XML stream.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredTextImpl
extends TextImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 2310613872100393425L;
//
// Data
//
/** Node index. */
protected transient int fNodeIndex;
//
// Constructors
//
/**
* This is the deferred constructor. Only the fNodeIndex is given here.
* All other data, can be requested from the ownerDocument via the index.
*/
DeferredTextImpl(DeferredDocumentImpl ownerDocument, int nodeIndex) {
super(ownerDocument, null);
fNodeIndex = nodeIndex;
needsSyncData(true);
} // <init>(DeferredDocumentImpl,int)
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return fNodeIndex;
}
//
// Protected methods
//
/** Synchronizes the underlying data. */
protected void synchronizeData() {
// no need for future synchronizations
needsSyncData(false);
// get initial text value
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl) this.ownerDocument();
data = ownerDocument.getNodeValueString(fNodeIndex);
// NOTE: We used to normalize adjacent text node values here.
// This code has moved to the DeferredDocumentImpl
// getNodeValueString() method. -Ac
// ignorable whitespace
isIgnorableWhitespace(ownerDocument.getNodeExtra(fNodeIndex) == 1);
} // synchronizeData()
} // class DeferredTextImpl

View File

@@ -0,0 +1,156 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
/**
* DocumentFragment is a "lightweight" or "minimal" Document
* object. It is very common to want to be able to extract a portion
* of a document's tree or to create a new fragment of a
* document. Imagine implementing a user command like cut or
* rearranging a document by moving fragments around. It is desirable
* to have an object which can hold such fragments and it is quite
* natural to use a Node for this purpose. While it is true that a
* Document object could fulfil this role, a Document object can
* potentially be a heavyweight object, depending on the underlying
* implementation... and in DOM Level 1, nodes aren't allowed to cross
* Document boundaries anyway. What is really needed for this is a
* very lightweight object. DocumentFragment is such an object.
* <P>
* Furthermore, various operations -- such as inserting nodes as
* children of another Node -- may take DocumentFragment objects as
* arguments; this results in all the child nodes of the
* DocumentFragment being moved to the child list of this node.
* <P>
* The children of a DocumentFragment node are zero or more nodes
* representing the tops of any sub-trees defining the structure of
* the document. DocumentFragment do not need to be well-formed XML
* documents (although they do need to follow the rules imposed upon
* well-formed XML parsed entities, which can have multiple top
* nodes). For example, a DocumentFragment might have only one child
* and that child node could be a Text node. Such a structure model
* represents neither an HTML document nor a well-formed XML document.
* <P>
* When a DocumentFragment is inserted into a Document (or indeed any
* other Node that may take children) the children of the
* DocumentFragment and not the DocumentFragment itself are inserted
* into the Node. This makes the DocumentFragment very useful when the
* user wishes to create nodes that are siblings; the DocumentFragment
* acts as the parent of these nodes so that the user can use the
* standard methods from the Node interface, such as insertBefore()
* and appendChild().
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class DocumentFragmentImpl
extends ParentNode
implements DocumentFragment {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -7596449967279236746L;
//
// Constructors
//
/** Factory constructor. */
public DocumentFragmentImpl(CoreDocumentImpl ownerDoc) {
super(ownerDoc);
}
/** Constructor for serialization. */
public DocumentFragmentImpl() {}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.DOCUMENT_FRAGMENT_NODE;
}
/** Returns the node name. */
public String getNodeName() {
return "#document-fragment";
}
/**
* Override default behavior to call normalize() on this Node's
* children. It is up to implementors or Node to override normalize()
* to take action.
*/
public void normalize() {
// No need to normalize if already normalized.
if (isNormalized()) {
return;
}
if (needsSyncChildren()) {
synchronizeChildren();
}
ChildNode kid, next;
for (kid = firstChild; kid != null; kid = next) {
next = kid.nextSibling;
// If kid is a text node, we need to check for one of two
// conditions:
// 1) There is an adjacent text node
// 2) There is no adjacent text node, but kid is
// an empty text node.
if ( kid.getNodeType() == Node.TEXT_NODE )
{
// If an adjacent text node, merge it with kid
if ( next!=null && next.getNodeType() == Node.TEXT_NODE )
{
((Text)kid).appendData(next.getNodeValue());
removeChild( next );
next = kid; // Don't advance; there might be another.
}
else
{
// If kid is empty, remove it
if ( kid.getNodeValue() == null || kid.getNodeValue().length() == 0 ) {
removeChild( kid );
}
}
}
kid.normalize();
}
isNormalized(true);
}
} // class DocumentFragmentImpl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,558 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import org.w3c.dom.DOMException;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.UserDataHandler;
/**
* This class represents a Document Type <em>declaraction</em> in
* the document itself, <em>not</em> a Document Type Definition (DTD).
* An XML document may (or may not) have such a reference.
* <P>
* DocumentType is an Extended DOM feature, used in XML documents but
* not in HTML.
* <P>
* Note that Entities and Notations are no longer children of the
* DocumentType, but are parentless nodes hung only in their
* appropriate NamedNodeMaps.
* <P>
* This area is UNDERSPECIFIED IN REC-DOM-Level-1-19981001
* Most notably, absolutely no provision was made for storing
* and using Element and Attribute information. Nor was the linkage
* between Entities and Entity References nailed down solidly.
*
* @xerces.internal
*
* @author Arnaud Le Hors, IBM
* @author Joe Kesselman, IBM
* @author Andy Clark, IBM
* @since PR-DOM-Level-1-19980818.
*/
public class DocumentTypeImpl
extends ParentNode
implements DocumentType {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 7751299192316526485L;
//
// Data
//
/** Document type name. */
protected String name;
/** Entities. */
protected NamedNodeMapImpl entities;
/** Notations. */
protected NamedNodeMapImpl notations;
// NON-DOM
/** Elements. */
protected NamedNodeMapImpl elements;
// DOM2: support public ID.
protected String publicID;
// DOM2: support system ID.
protected String systemID;
// DOM2: support internal subset.
protected String internalSubset;
/** The following are required for compareDocumentPosition
*/
// Doctype number. Doc types which have no owner may be assigned
// a number, on demand, for ordering purposes for compareDocumentPosition
private int doctypeNumber=0;
private Map<String, UserDataRecord> userData = null;
/**
* @serialField name String document type name
* @serialField entities NamedNodeMapImpl entities
* @serialField notations NamedNodeMapImpl notations
* @serialField elements NamedNodeMapImpl elements
* @serialField publicID String support public ID
* @serialField systemID String support system ID
* @serialField internalSubset String support internal subset
* @serialField doctypeNumber int Doctype number
* @serialField userData Hashtable user data
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[] {
new ObjectStreamField("name", String.class),
new ObjectStreamField("entities", NamedNodeMapImpl.class),
new ObjectStreamField("notations", NamedNodeMapImpl.class),
new ObjectStreamField("elements", NamedNodeMapImpl.class),
new ObjectStreamField("publicID", String.class),
new ObjectStreamField("systemID", String.class),
new ObjectStreamField("internalSubset", String.class),
new ObjectStreamField("doctypeNumber", int.class),
new ObjectStreamField("userData", Hashtable.class),
};
//
// Constructors
//
/** Factory method for creating a document type node. */
public DocumentTypeImpl(CoreDocumentImpl ownerDocument, String name) {
super(ownerDocument);
this.name = name;
// DOM
entities = new NamedNodeMapImpl(this);
notations = new NamedNodeMapImpl(this);
// NON-DOM
elements = new NamedNodeMapImpl(this);
} // <init>(CoreDocumentImpl,String)
/** Factory method for creating a document type node. */
public DocumentTypeImpl(CoreDocumentImpl ownerDocument,
String qualifiedName,
String publicID, String systemID) {
this(ownerDocument, qualifiedName);
this.publicID = publicID;
this.systemID = systemID;
} // <init>(CoreDocumentImpl,String)
//
// DOM2: methods.
//
/**
* Introduced in DOM Level 2. <p>
*
* Return the public identifier of this Document type.
* @since WD-DOM-Level-2-19990923
*/
public String getPublicId() {
if (needsSyncData()) {
synchronizeData();
}
return publicID;
}
/**
* Introduced in DOM Level 2. <p>
*
* Return the system identifier of this Document type.
* @since WD-DOM-Level-2-19990923
*/
public String getSystemId() {
if (needsSyncData()) {
synchronizeData();
}
return systemID;
}
/**
* NON-DOM. <p>
*
* Set the internalSubset given as a string.
*/
public void setInternalSubset(String internalSubset) {
if (needsSyncData()) {
synchronizeData();
}
this.internalSubset = internalSubset;
}
/**
* Introduced in DOM Level 2. <p>
*
* Return the internalSubset given as a string.
* @since WD-DOM-Level-2-19990923
*/
public String getInternalSubset() {
if (needsSyncData()) {
synchronizeData();
}
return internalSubset;
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.DOCUMENT_TYPE_NODE;
}
/**
* Returns the document type name
*/
public String getNodeName() {
if (needsSyncData()) {
synchronizeData();
}
return name;
}
/** Clones the node. */
public Node cloneNode(boolean deep) {
DocumentTypeImpl newnode = (DocumentTypeImpl)super.cloneNode(deep);
// NamedNodeMaps must be cloned explicitly, to avoid sharing them.
newnode.entities = entities.cloneMap(newnode);
newnode.notations = notations.cloneMap(newnode);
newnode.elements = elements.cloneMap(newnode);
return newnode;
} // cloneNode(boolean):Node
/*
* Get Node text content
* @since DOM Level 3
*/
public String getTextContent() throws DOMException {
return null;
}
/*
* Set Node text content
* @since DOM Level 3
*/
public void setTextContent(String textContent)
throws DOMException {
// no-op
}
/**
* DOM Level 3 WD- Experimental.
* Override inherited behavior from ParentNodeImpl to support deep equal.
*/
public boolean isEqualNode(Node arg) {
if (!super.isEqualNode(arg)) {
return false;
}
if (needsSyncData()) {
synchronizeData();
}
DocumentTypeImpl argDocType = (DocumentTypeImpl) arg;
//test if the following string attributes are equal: publicId,
//systemId, internalSubset.
if ((getPublicId() == null && argDocType.getPublicId() != null)
|| (getPublicId() != null && argDocType.getPublicId() == null)
|| (getSystemId() == null && argDocType.getSystemId() != null)
|| (getSystemId() != null && argDocType.getSystemId() == null)
|| (getInternalSubset() == null
&& argDocType.getInternalSubset() != null)
|| (getInternalSubset() != null
&& argDocType.getInternalSubset() == null)) {
return false;
}
if (getPublicId() != null) {
if (!getPublicId().equals(argDocType.getPublicId())) {
return false;
}
}
if (getSystemId() != null) {
if (!getSystemId().equals(argDocType.getSystemId())) {
return false;
}
}
if (getInternalSubset() != null) {
if (!getInternalSubset().equals(argDocType.getInternalSubset())) {
return false;
}
}
//test if NamedNodeMaps entities and notations are equal
NamedNodeMapImpl argEntities = argDocType.entities;
if ((entities == null && argEntities != null)
|| (entities != null && argEntities == null))
return false;
if (entities != null && argEntities != null) {
if (entities.getLength() != argEntities.getLength())
return false;
for (int index = 0; entities.item(index) != null; index++) {
Node entNode1 = entities.item(index);
Node entNode2 =
argEntities.getNamedItem(entNode1.getNodeName());
if (!((NodeImpl) entNode1).isEqualNode((NodeImpl) entNode2))
return false;
}
}
NamedNodeMapImpl argNotations = argDocType.notations;
if ((notations == null && argNotations != null)
|| (notations != null && argNotations == null))
return false;
if (notations != null && argNotations != null) {
if (notations.getLength() != argNotations.getLength())
return false;
for (int index = 0; notations.item(index) != null; index++) {
Node noteNode1 = notations.item(index);
Node noteNode2 =
argNotations.getNamedItem(noteNode1.getNodeName());
if (!((NodeImpl) noteNode1).isEqualNode((NodeImpl) noteNode2))
return false;
}
}
return true;
} //end isEqualNode
/**
* NON-DOM
* set the ownerDocument of this node and its children
*/
void setOwnerDocument(CoreDocumentImpl doc) {
super.setOwnerDocument(doc);
entities.setOwnerDocument(doc);
notations.setOwnerDocument(doc);
elements.setOwnerDocument(doc);
}
/** NON-DOM
Get the number associated with this doctype.
*/
protected int getNodeNumber() {
// If the doctype has a document owner, get the node number
// relative to the owner doc
if (getOwnerDocument()!=null)
return super.getNodeNumber();
// The doctype is disconnected and not associated with any document.
// Assign the doctype a number relative to the implementation.
if (doctypeNumber==0) {
CoreDOMImplementationImpl cd = (CoreDOMImplementationImpl)CoreDOMImplementationImpl.getDOMImplementation();
doctypeNumber = cd.assignDocTypeNumber();
}
return doctypeNumber;
}
//
// DocumentType methods
//
/**
* Name of this document type. If we loaded from a DTD, this should
* be the name immediately following the DOCTYPE keyword.
*/
public String getName() {
if (needsSyncData()) {
synchronizeData();
}
return name;
} // getName():String
/**
* Access the collection of general Entities, both external and
* internal, defined in the DTD. For example, in:
* <p>
* <pre>
* &lt;!doctype example SYSTEM "ex.dtd" [
* &lt;!ENTITY foo "foo"&gt;
* &lt;!ENTITY bar "bar"&gt;
* &lt;!ENTITY % baz "baz"&gt;
* ]&gt;
* </pre>
* <p>
* The Entities map includes foo and bar, but not baz. It is promised that
* only Nodes which are Entities will exist in this NamedNodeMap.
* <p>
* For HTML, this will always be null.
* <p>
* Note that "built in" entities such as &amp; and &lt; should be
* converted to their actual characters before being placed in the DOM's
* contained text, and should be converted back when the DOM is rendered
* as XML or HTML, and hence DO NOT appear here.
*/
public NamedNodeMap getEntities() {
if (needsSyncChildren()) {
synchronizeChildren();
}
return entities;
}
/**
* Access the collection of Notations defined in the DTD. A
* notation declares, by name, the format of an XML unparsed entity
* or is used to formally declare a Processing Instruction target.
*/
public NamedNodeMap getNotations() {
if (needsSyncChildren()) {
synchronizeChildren();
}
return notations;
}
//
// Public methods
//
/**
* NON-DOM: Subclassed to flip the entities' and notations' readonly switch
* as well.
* @see NodeImpl#setReadOnly
*/
public void setReadOnly(boolean readOnly, boolean deep) {
if (needsSyncChildren()) {
synchronizeChildren();
}
super.setReadOnly(readOnly, deep);
// set read-only property
elements.setReadOnly(readOnly, true);
entities.setReadOnly(readOnly, true);
notations.setReadOnly(readOnly, true);
} // setReadOnly(boolean,boolean)
/**
* NON-DOM: Access the collection of ElementDefinitions.
* @see ElementDefinitionImpl
*/
public NamedNodeMap getElements() {
if (needsSyncChildren()) {
synchronizeChildren();
}
return elements;
}
public Object setUserData(String key,
Object data, UserDataHandler handler) {
if(userData == null)
userData = new HashMap<>();
if (data == null) {
if (userData != null) {
UserDataRecord udr = userData.remove(key);
if (udr != null) {
return udr.fData;
}
}
return null;
}
else {
UserDataRecord udr = userData.put(key, new UserDataRecord(data, handler));
if (udr != null) {
return udr.fData;
}
}
return null;
}
public Object getUserData(String key) {
if (userData == null) {
return null;
}
UserDataRecord udr = userData.get(key);
if (udr != null) {
return udr.fData;
}
return null;
}
@Override
protected Map<String, UserDataRecord> getUserDataRecord(){
return userData;
}
/**
* @serialData Serialized fields. Convert Map to Hashtable for backward
* compatibility.
*/
private void writeObject(ObjectOutputStream out) throws IOException {
// Convert the HashMap to Hashtable
Hashtable<String, UserDataRecord> ud = (userData == null)? null : new Hashtable<>(userData);
// Write serialized fields
ObjectOutputStream.PutField pf = out.putFields();
pf.put("name", name);
pf.put("entities", entities);
pf.put("notations", notations);
pf.put("elements", elements);
pf.put("publicID", publicID);
pf.put("systemID", systemID);
pf.put("internalSubset", internalSubset);
pf.put("doctypeNumber", doctypeNumber);
pf.put("userData", ud);
out.writeFields();
}
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
// We have to read serialized fields first.
ObjectInputStream.GetField gf = in.readFields();
name = (String)gf.get("name", null);
entities = (NamedNodeMapImpl)gf.get("entities", null);
notations = (NamedNodeMapImpl)gf.get("notations", null);
elements = (NamedNodeMapImpl)gf.get("elements", null);
publicID = (String)gf.get("publicID", null);
systemID = (String)gf.get("systemID", null);
internalSubset = (String)gf.get("internalSubset", null);
doctypeNumber = gf.get("doctypeNumber", 0);
Hashtable<String, UserDataRecord> ud =
(Hashtable<String, UserDataRecord>)gf.get("userData", null);
//convert the Hashtable back to HashMap
if (ud != null) userData = new HashMap<>(ud);
}
} // class DocumentTypeImpl

View File

@@ -0,0 +1,122 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* NON-DOM CLASS: Describe one of the Elements (and its associated
* Attributes) defined in this Document Type.
* <p>
* I've included this in Level 1 purely as an anchor point for default
* attributes. In Level 2 it should enable the ChildRule support.
*
* @xerces.internal
*
*/
public class ElementDefinitionImpl
extends ParentNode {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -8373890672670022714L;
//
// Data
//
/** Element definition name. */
protected String name;
/** Default attributes. */
protected NamedNodeMapImpl attributes;
//
// Constructors
//
/** Factory constructor. */
public ElementDefinitionImpl(CoreDocumentImpl ownerDocument, String name) {
super(ownerDocument);
this.name = name;
attributes = new NamedNodeMapImpl(ownerDocument);
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return NodeImpl.ELEMENT_DEFINITION_NODE;
}
/**
* Returns the element definition name
*/
public String getNodeName() {
if (needsSyncData()) {
synchronizeData();
}
return name;
}
/**
* Replicate this object.
*/
public Node cloneNode(boolean deep) {
ElementDefinitionImpl newnode =
(ElementDefinitionImpl) super.cloneNode(deep);
// NamedNodeMap must be explicitly replicated to avoid sharing
newnode.attributes = attributes.cloneMap(newnode);
return newnode;
} // cloneNode(boolean):Node
/**
* Query the attributes defined on this Element.
* <p>
* In the base implementation this Map simply contains Attribute objects
* representing the defaults. In a more serious implementation, it would
* contain AttributeDefinitionImpl objects for all declared Attributes,
* indicating which are Default, DefaultFixed, Implicit and/or Required.
*
* @return org.w3c.dom.NamedNodeMap containing org.w3c.dom.Attribute
*/
public NamedNodeMap getAttributes() {
if (needsSyncChildren()) {
synchronizeChildren();
}
return attributes;
} // getAttributes():NamedNodeMap
} // class ElementDefinitionImpl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,489 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.xs.XSSimpleTypeDefinition;
import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
import com.sun.org.apache.xerces.internal.impl.dv.xs.XSSimpleTypeDecl;
import com.sun.org.apache.xerces.internal.impl.xs.XSComplexTypeDecl;
import com.sun.org.apache.xerces.internal.util.URI;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
/**
* ElementNSImpl inherits from ElementImpl and adds namespace support.
* <P>
* The qualified name is the node name, and we store localName which is also
* used in all queries. On the other hand we recompute the prefix when
* necessary.
*
* @xerces.internal
*
* @author Elena litani, IBM
* @author Neeraj Bajaj, Sun Microsystems
*/
public class ElementNSImpl
extends ElementImpl {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -9142310625494392642L;
static final String xmlURI = "http://www.w3.org/XML/1998/namespace";
//
// Data
//
/** DOM2: Namespace URI. */
protected String namespaceURI;
/** DOM2: localName. */
protected String localName;
/** DOM3: type information */
// REVISIT: we are losing the type information in DOM during serialization
transient XSTypeDefinition type;
protected ElementNSImpl() {
super();
}
/**
* DOM2: Constructor for Namespace implementation.
*/
protected ElementNSImpl(CoreDocumentImpl ownerDocument,
String namespaceURI,
String qualifiedName)
throws DOMException
{
super(ownerDocument, qualifiedName);
setName(namespaceURI, qualifiedName);
}
private void setName(String namespaceURI, String qname) {
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;
}
int colon1, colon2 ;
//NAMESPACE_ERR:
//1. if the qualified name is 'null' it is malformed.
//2. or if the qualifiedName is null and the namespaceURI is different from null,
// We dont need to check for namespaceURI != null, if qualified name is null throw DOMException.
if(qname == null){
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NAMESPACE_ERR",
null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
else{
colon1 = qname.indexOf(':');
colon2 = qname.lastIndexOf(':');
}
ownerDocument.checkNamespaceWF(qname, colon1, colon2);
if (colon1 < 0) {
// there is no prefix
localName = qname;
if (ownerDocument.errorChecking) {
ownerDocument.checkQName(null, localName);
if (qname.equals("xmlns")
&& (namespaceURI == null
|| !namespaceURI.equals(NamespaceContext.XMLNS_URI))
|| (namespaceURI!=null && namespaceURI.equals(NamespaceContext.XMLNS_URI)
&& !qname.equals("xmlns"))) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NAMESPACE_ERR",
null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
}
}//there is a prefix
else {
prefix = qname.substring(0, colon1);
localName = qname.substring(colon2 + 1);
//NAMESPACE_ERR:
//1. if the qualifiedName has a prefix and the namespaceURI is null,
//2. or if the qualifiedName has a prefix that is "xml" and the namespaceURI
//is different from " http://www.w3.org/XML/1998/namespace"
if (ownerDocument.errorChecking) {
if( namespaceURI == null || ( prefix.equals("xml") && !namespaceURI.equals(NamespaceContext.XML_URI) )){
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NAMESPACE_ERR",
null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
ownerDocument.checkQName(prefix, localName);
ownerDocument.checkDOMNSErr(prefix, namespaceURI);
}
}
}
// when local name is known
protected ElementNSImpl(CoreDocumentImpl ownerDocument,
String namespaceURI, String qualifiedName,
String localName)
throws DOMException
{
super(ownerDocument, qualifiedName);
this.localName = localName;
this.namespaceURI = namespaceURI;
}
// for DeferredElementImpl
protected ElementNSImpl(CoreDocumentImpl ownerDocument,
String value) {
super(ownerDocument, value);
}
// Support for DOM Level 3 renameNode method.
// Note: This only deals with part of the pb. CoreDocumentImpl
// does all the work.
void rename(String namespaceURI, String qualifiedName)
{
if (needsSyncData()) {
synchronizeData();
}
this.name = qualifiedName;
setName(namespaceURI, qualifiedName);
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
//
//
//DOM2: Namespace methods.
//
/**
* Introduced in DOM Level 2. <p>
*
* The namespace URI of this node, or null if it is unspecified.<p>
*
* This is not a computed value that is the result of a namespace lookup based on
* an examination of the namespace declarations in scope. It is merely the
* namespace URI given at creation time.<p>
*
* For nodes created with a DOM Level 1 method, such as createElement
* from the Document interface, this is null.
* @since WD-DOM-Level-2-19990923
*/
public String getNamespaceURI()
{
if (needsSyncData()) {
synchronizeData();
}
return namespaceURI;
}
/**
* Introduced in DOM Level 2. <p>
*
* The namespace prefix of this node, or null if it is unspecified. <p>
*
* For nodes created with a DOM Level 1 method, such as createElement
* from the Document interface, this is null. <p>
*
* @since WD-DOM-Level-2-19990923
*/
public String getPrefix()
{
if (needsSyncData()) {
synchronizeData();
}
int index = name.indexOf(':');
return index < 0 ? null : name.substring(0, index);
}
/**
* Introduced in DOM Level 2. <p>
*
* Note that setting this attribute changes the nodeName attribute, which holds the
* qualified name, as well as the tagName and name attributes of the Element
* and Attr interfaces, when applicable.<p>
*
* @param prefix The namespace prefix of this node, or null(empty string) if it is unspecified.
*
* @exception INVALID_CHARACTER_ERR
* Raised if the specified
* prefix contains an invalid character.
* @exception DOMException
* @since WD-DOM-Level-2-19990923
*/
public void setPrefix(String prefix)
throws DOMException
{
if (needsSyncData()) {
synchronizeData();
}
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);
}
if (prefix != null && prefix.length() != 0) {
if (!CoreDocumentImpl.isXMLName(prefix,ownerDocument.isXML11Version())) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_CHARACTER_ERR", null);
throw new DOMException(DOMException.INVALID_CHARACTER_ERR, msg);
}
if (namespaceURI == null || prefix.indexOf(':') >=0) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
} else if (prefix.equals("xml")) {
if (!namespaceURI.equals(xmlURI)) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR", null);
throw new DOMException(DOMException.NAMESPACE_ERR, msg);
}
}
}
}
// update node name with new qualifiedName
if (prefix !=null && prefix.length() != 0) {
name = prefix + ":" + localName;
}
else {
name = localName;
}
}
/**
* Introduced in DOM Level 2. <p>
*
* Returns the local part of the qualified name of this node.
* @since WD-DOM-Level-2-19990923
*/
public String getLocalName()
{
if (needsSyncData()) {
synchronizeData();
}
return localName;
}
/**
* DOM Level 3 WD - Experimental.
* Retrieve baseURI
*/
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;
}
/**
* @see org.w3c.dom.TypeInfo#getTypeName()
*/
public String getTypeName() {
if (type !=null){
if (type instanceof XSSimpleTypeDecl) {
return ((XSSimpleTypeDecl) type).getTypeName();
} else if (type instanceof XSComplexTypeDecl) {
return ((XSComplexTypeDecl) type).getTypeName();
}
}
return null;
}
/**
* @see org.w3c.dom.TypeInfo#getTypeNamespace()
*/
public String getTypeNamespace() {
if (type !=null){
return type.getNamespace();
}
return null;
}
/**
* Introduced in DOM Level 2. <p>
* 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
* The namspace of the ancestor type declaration
* @param ancestorName
* The name of the ancestor type declaration
* @param type
* The reference type definition
*
* @return boolean True if the type is derived by restriciton for the
* reference type
*/
public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg,
int derivationMethod) {
if(needsSyncData()) {
synchronizeData();
}
if (type != null) {
if (type instanceof XSSimpleTypeDecl) {
return ((XSSimpleTypeDecl) type).isDOMDerivedFrom(
typeNamespaceArg, typeNameArg, derivationMethod);
} else if (type instanceof XSComplexTypeDecl) {
return ((XSComplexTypeDecl) type).isDOMDerivedFrom(
typeNamespaceArg, typeNameArg, derivationMethod);
}
}
return false;
}
/**
* NON-DOM: setting type used by the DOM parser
* @see NodeImpl#setReadOnly
*/
public void setType(XSTypeDefinition type) {
this.type = type;
}
}

View File

@@ -0,0 +1,368 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Entity;
import org.w3c.dom.Node;
import org.w3c.dom.DOMException;
/**
* Entity nodes hold the reference data for an XML Entity -- either
* parsed or unparsed. The nodeName (inherited from Node) will contain
* the name (if any) of the Entity. Its data will be contained in the
* Entity's children, in exactly the structure which an
* EntityReference to this name will present within the document's
* body.
* <P>
* Note that this object models the actual entity, _not_ the entity
* declaration or the entity reference.
* <P>
* An XML processor may choose to completely expand entities before
* the structure model is passed to the DOM; in this case, there will
* be no EntityReferences in the DOM tree.
* <P>
* Quoting the 10/01 DOM Proposal,
* <BLOCKQUOTE>
* "The DOM Level 1 does not support editing Entity nodes; if a user
* wants to make changes to the contents of an Entity, every related
* EntityReference node has to be replaced in the structure model by
* a clone of the Entity's contents, and then the desired changes
* must be made to each of those clones instead. All the
* descendants of an Entity node are readonly."
* </BLOCKQUOTE>
* I'm interpreting this as: It is the parser's responsibilty to call
* the non-DOM operation setReadOnly(true,true) after it constructs
* the Entity. Since the DOM explicitly decided not to deal with this,
* _any_ answer will involve a non-DOM operation, and this is the
* simplest solution.
*
* @xerces.internal
*
* @author Elena Litani, IBM
* @since PR-DOM-Level-1-19980818.
*/
public class EntityImpl
extends ParentNode
implements Entity {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -3575760943444303423L;
//
// Data
//
/** Entity name. */
protected String name;
/** Public identifier. */
protected String publicId;
/** System identifier. */
protected String systemId;
/** Encoding */
protected String encoding;
/** Input Encoding */
protected String inputEncoding;
/** Version */
protected String version;
/** Notation name. */
protected String notationName;
/** base uri*/
protected String baseURI;
//
// Constructors
//
/** Factory constructor. */
public EntityImpl(CoreDocumentImpl ownerDoc, String name) {
super(ownerDoc);
this.name = name;
isReadOnly(true);
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.ENTITY_NODE;
}
/**
* Returns the entity name
*/
public String getNodeName() {
if (needsSyncData()) {
synchronizeData();
}
return name;
}
/**
* Sets the node value.
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR)
*/
public void setNodeValue(String x)
throws DOMException {
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);
}
}
/**
* The namespace prefix of this node
* @exception DOMException
* <br>NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
*/
public void setPrefix(String prefix)
throws DOMException
{
if (ownerDocument.errorChecking && isReadOnly()) {
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN,
"NO_MODIFICATION_ALLOWED_ERR", null));
}
}
/** Clone node. */
public Node cloneNode(boolean deep) {
EntityImpl newentity = (EntityImpl)super.cloneNode(deep);
newentity.setReadOnly(true, deep);
return newentity;
}
//
// Entity methods
//
/**
* The public identifier associated with the entity. If not specified,
* this will be null.
*/
public String getPublicId() {
if (needsSyncData()) {
synchronizeData();
}
return publicId;
} // getPublicId():String
/**
* The system identifier associated with the entity. If not specified,
* this will be null.
*/
public String getSystemId() {
if (needsSyncData()) {
synchronizeData();
}
return systemId;
} // getSystemId():String
/**
* DOM Level 3 WD - experimental
* the version number of this entity, when it is an external parsed entity.
*/
public String getXmlVersion() {
if (needsSyncData()) {
synchronizeData();
}
return version;
} // getVersion():String
/**
* DOM Level 3 WD - experimental
* the encoding of this entity, when it is an external parsed entity.
*/
public String getXmlEncoding() {
if (needsSyncData()) {
synchronizeData();
}
return encoding;
} // getVersion():String
/**
* Unparsed entities -- which contain non-XML data -- have a
* "notation name" which tells applications how to deal with them.
* Parsed entities, which <em>are</em> in XML format, don't need this and
* set it to null.
*/
public String getNotationName() {
if (needsSyncData()) {
synchronizeData();
}
return notationName;
} // getNotationName():String
//
// Public methods
//
/**
* DOM Level 2: The public identifier associated with the entity. If not specified,
* this will be null. */
public void setPublicId(String id) {
if (needsSyncData()) {
synchronizeData();
}
publicId = id;
} // setPublicId(String)
/**
* NON-DOM
* encoding - An attribute specifying, as part of the text declaration,
* the encoding of this entity, when it is an external parsed entity.
* This is null otherwise
*
*/
public void setXmlEncoding(String value) {
if (needsSyncData()) {
synchronizeData();
}
encoding = value;
} // setEncoding (String)
/**
* An attribute specifying the encoding used for this entity at the tiome
* of parsing, when it is an external parsed entity. This is
* <code>null</code> if it an entity from the internal subset or if it
* is not known..
* @since DOM Level 3
*/
public String getInputEncoding(){
if (needsSyncData()) {
synchronizeData();
}
return inputEncoding;
}
/**
* NON-DOM, used to set the input encoding.
*/
public void setInputEncoding(String inputEncoding){
if (needsSyncData()) {
synchronizeData();
}
this.inputEncoding = inputEncoding;
}
/**
* NON-DOM
* version - An attribute specifying, as part of the text declaration,
* the version number of this entity, when it is an external parsed entity.
* This is null otherwise
*/
public void setXmlVersion(String value) {
if (needsSyncData()) {
synchronizeData();
}
version = value;
} // setVersion (String)
/**
* DOM Level 2: The system identifier associated with the entity. If not
* specified, this will be null.
*/
public void setSystemId(String id) {
if (needsSyncData()) {
synchronizeData();
}
systemId = id;
} // setSystemId(String)
/**
* DOM Level 2: Unparsed entities -- which contain non-XML data -- have a
* "notation name" which tells applications how to deal with them.
* Parsed entities, which <em>are</em> in XML format, don't need this and
* set it to null.
*/
public void setNotationName(String name) {
if (needsSyncData()) {
synchronizeData();
}
notationName = name;
} // setNotationName(String)
/**
* Returns the absolute base URI of this node or null if the implementation
* wasn't able to obtain an absolute URI. Note: If the URI is malformed, a
* null is returned.
*
* @return The absolute base URI of this node or null.
* @since DOM Level 3
*/
public String getBaseURI() {
if (needsSyncData()) {
synchronizeData();
}
return (baseURI!=null)?baseURI:((CoreDocumentImpl)getOwnerDocument()).getBaseURI();
}
/** NON-DOM: set base uri*/
public void setBaseURI(String uri){
if (needsSyncData()) {
synchronizeData();
}
baseURI = uri;
}
} // class EntityImpl

View File

@@ -0,0 +1,403 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.util.URI;
import org.w3c.dom.DocumentType;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* EntityReference models the XML &entityname; syntax, when used for
* entities defined by the DOM. Entities hardcoded into XML, such as
* character entities, should instead have been translated into text
* by the code which generated the DOM tree.
* <P>
* An XML processor has the alternative of fully expanding Entities
* into the normal document tree. If it does so, no EntityReference nodes
* will appear.
* <P>
* Similarly, non-validating XML processors are not required to read
* or process entity declarations made in the external subset or
* declared in external parameter entities. Hence, some applications
* may not make the replacement value available for Parsed Entities
* of these types.
* <P>
* EntityReference behaves as a read-only node, and the children of
* the EntityReference (which reflect those of the Entity, and should
* also be read-only) give its replacement value, if any. They are
* supposed to automagically stay in synch if the DocumentType is
* updated with new values for the Entity.
* <P>
* The defined behavior makes efficient storage difficult for the DOM
* implementor. We can't just look aside to the Entity's definition
* in the DocumentType since those nodes have the wrong parent (unless
* we can come up with a clever "imaginary parent" mechanism). We
* must at least appear to clone those children... which raises the
* issue of keeping the reference synchronized with its parent.
* This leads me back to the "cached image of centrally defined data"
* solution, much as I dislike it.
* <P>
* For now I have decided, since REC-DOM-Level-1-19980818 doesn't
* cover this in much detail, that synchronization doesn't have to be
* considered while the user is deep in the tree. That is, if you're
* looking within one of the EntityReferennce's children and the Entity
* changes, you won't be informed; instead, you will continue to access
* the same object -- which may or may not still be part of the tree.
* This is the same behavior that obtains elsewhere in the DOM if the
* subtree you're looking at is deleted from its parent, so it's
* acceptable here. (If it really bothers folks, we could set things
* up so deleted subtrees are walked and marked invalid, but that's
* not part of the DOM's defined behavior.)
* <P>
* As a result, only the EntityReference itself has to be aware of
* changes in the Entity. And it can take advantage of the same
* structure-change-monitoring code I implemented to support
* DeepNodeList.
*
* @xerces.internal
*
* @author Arnaud Le Hors, IBM
* @author Joe Kesselman, IBM
* @author Andy Clark, IBM
* @author Ralf Pfeiffer, IBM
* @since PR-DOM-Level-1-19980818.
*/
public class EntityReferenceImpl
extends ParentNode
implements EntityReference {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -7381452955687102062L;
//
// Data
//
/** Name of Entity referenced */
protected String name;
/** Base URI*/
protected String baseURI;
/** Entity changes. */
//protected int entityChanges = -1;
/** Enable synchronize. */
//protected boolean fEnableSynchronize = false;
//
// Constructors
//
/** Factory constructor. */
public EntityReferenceImpl(CoreDocumentImpl ownerDoc, String name) {
super(ownerDoc);
this.name = name;
isReadOnly(true);
needsSyncChildren(true);
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.ENTITY_REFERENCE_NODE;
}
/**
* Returns the name of the entity referenced
*/
public String getNodeName() {
if (needsSyncData()) {
synchronizeData();
}
return name;
}
/** Clone node. */
public Node cloneNode(boolean deep) {
EntityReferenceImpl er = (EntityReferenceImpl)super.cloneNode(deep);
er.setReadOnly(true, deep);
return er;
}
/**
* Returns the absolute base URI of this node or null if the implementation
* wasn't able to obtain an absolute URI. Note: If the URI is malformed, a
* null is returned.
*
* @return The absolute base URI of this node or null.
* @since DOM Level 3
*/
public String getBaseURI() {
if (needsSyncData()) {
synchronizeData();
}
if (baseURI == null) {
DocumentType doctype;
NamedNodeMap entities;
EntityImpl entDef;
if (null != (doctype = getOwnerDocument().getDoctype()) &&
null != (entities = doctype.getEntities())) {
entDef = (EntityImpl)entities.getNamedItem(getNodeName());
if (entDef !=null) {
return entDef.getBaseURI();
}
}
} else if (baseURI != null && baseURI.length() != 0 ) {// attribute value is always empty string
try {
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 baseURI;
}
/** NON-DOM: set base uri*/
public void setBaseURI(String uri){
if (needsSyncData()) {
synchronizeData();
}
baseURI = uri;
}
/**
* NON-DOM: compute string representation of the entity reference.
* This method is used to retrieve a string value for an attribute node that has child nodes.
* @return String representing a value of this entity ref. or
* null if any node other than EntityReference, Text is encountered
* during computation
*/
protected String getEntityRefValue (){
if (needsSyncChildren()){
synchronizeChildren();
}
String value = "";
if (firstChild != null){
if (firstChild.getNodeType() == Node.ENTITY_REFERENCE_NODE){
value = ((EntityReferenceImpl)firstChild).getEntityRefValue();
}
else if (firstChild.getNodeType() == Node.TEXT_NODE){
value = firstChild.getNodeValue();
}
else {
// invalid to have other types of nodes in attr value
return null;
}
if (firstChild.nextSibling == null){
return value;
}
else {
StringBuffer buff = new StringBuffer(value);
ChildNode next = firstChild.nextSibling;
while (next != null){
if (next.getNodeType() == Node.ENTITY_REFERENCE_NODE){
value = ((EntityReferenceImpl)next).getEntityRefValue();
}
else if (next.getNodeType() == Node.TEXT_NODE){
value = next.getNodeValue();
}
else {
// invalid to have other types of nodes in attr value
return null;
}
buff.append(value);
next = next.nextSibling;
}
return buff.toString();
}
}
return "";
}
/**
* EntityReference's children are a reflection of those defined in the
* named Entity. This method creates them if they haven't been created yet.
* This doesn't support editing the Entity though, since this only called
* once for all.
*/
protected void synchronizeChildren() {
// no need to synchronize again
needsSyncChildren(false);
DocumentType doctype;
NamedNodeMap entities;
EntityImpl entDef;
if (null != (doctype = getOwnerDocument().getDoctype()) &&
null != (entities = doctype.getEntities())) {
entDef = (EntityImpl)entities.getNamedItem(getNodeName());
// No Entity by this name, stop here.
if (entDef == null)
return;
// If entity's definition exists, clone its kids
isReadOnly(false);
for (Node defkid = entDef.getFirstChild();
defkid != null;
defkid = defkid.getNextSibling()) {
Node newkid = defkid.cloneNode(true);
insertBefore(newkid, null);
}
setReadOnly(true, true);
}
}
/**
* NON-DOM: sets the node and its children value.
* <P>
* Note: make sure that entity reference and its kids could be set readonly.
*/
public void setReadOnly(boolean readOnly, boolean deep) {
if (needsSyncData()) {
synchronizeData();
}
if (deep) {
if (needsSyncChildren()) {
synchronizeChildren();
}
// Recursively set kids
for (ChildNode mykid = firstChild;
mykid != null;
mykid = mykid.nextSibling) {
mykid.setReadOnly(readOnly,true);
}
}
isReadOnly(readOnly);
} // setReadOnly(boolean,boolean)
/**
* Enable the synchronize method which may do cloning. This method is enabled
* when the parser is done with an EntityReference.
/***
// revisit: enable editing of Entity
public void enableSynchronize(boolean enableSynchronize) {
fEnableSynchronize= enableSynchronize;
}
/***/
/**
* EntityReference's children are a reflection of those defined in the
* named Entity. This method updates them if the Entity is changed.
* <P>
* It is unclear what the least-cost resynch mechanism is.
* If we expect the kids to be shallow, and/or expect changes
* to the Entity contents to be rare, wiping them all out
* and recloning is simplest.
* <P>
* If we expect them to be deep,
* it might be better to first decide which kids (if any)
* persist, and keep the ones (if any) that are unchanged
* rather than doing all the work of cloning them again.
* But that latter gets into having to convolve the two child lists,
* insert new information in the right order (and possibly reorder
* the existing kids), and a few other complexities that I really
* don't want to deal with in this implementation.
* <P>
* Note that if we decide that we need to update the EntityReference's
* contents, we have to turn off the readOnly flag temporarily to do so.
* When we get around to adding multitasking support, this whole method
* should probably be an atomic operation.
*
* @see DocumentTypeImpl
* @see EntityImpl
*/
// The Xerces parser invokes callbacks for startEnityReference
// the parsed value of the entity EACH TIME, so it is actually
// easier to create the nodes through the callbacks rather than
// clone the Entity.
/***
// revisit: enable editing of Entity
private void synchronize() {
if (!fEnableSynchronize) {
return;
}
DocumentType doctype;
NamedNodeMap entities;
EntityImpl entDef;
if (null != (doctype = getOwnerDocument().getDoctype()) &&
null != (entities = doctype.getEntities())) {
entDef = (EntityImpl)entities.getNamedItem(getNodeName());
// No Entity by this name. If we had a change count, reset it.
if(null==entDef)
entityChanges=-1;
// If no kids availalble, wipe any pre-existing children.
// (See discussion above.)
// Note that we have to use the superclass to avoid recursion
// through Synchronize.
readOnly=false;
if(null==entDef || !entDef.hasChildNodes())
for(Node kid=super.getFirstChild();
kid!=null;
kid=super.getFirstChild())
removeChild(kid);
// If entity's definition changed, clone its kids
// (See discussion above.)
if(null!=entDef && entDef.changes!=entityChanges) {
for(Node defkid=entDef.getFirstChild();
defkid!=null;
defkid=defkid.getNextSibling()) {
NodeImpl newkid=(NodeImpl) defkid.cloneNode(true);
newkid.setReadOnly(true,true);
insertBefore(newkid,null);
}
entityChanges=entDef.changes;
}
readOnly=true;
}
}
/***/
} // class EntityReferenceImpl

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
/** Internal class LCount is used to track the number of
listeners registered for a given event name, as an entry
in a global Map. This should allow us to avoid generating,
or discarding, events for which no listeners are registered.
***** There should undoubtedly be methods here to manipulate
this table. At the moment that code's residing in NodeImpl.
Move it when we have a chance to do so. Sorry; we were
rushed.
*/
/**
* @xerces.internal
*
*/
class LCount
{
static final java.util.Map<String, LCount> lCounts=new java.util.concurrent.ConcurrentHashMap<>();
public int captures=0,bubbles=0,defaults, total=0;
static LCount lookup(String evtName)
{
LCount lc=(LCount)lCounts.get(evtName);
if(lc==null)
lCounts.put(evtName,(lc=new LCount()));
return lc;
}
} // class LCount

View File

@@ -0,0 +1,630 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import org.w3c.dom.DOMException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
/**
* NamedNodeMaps represent collections of Nodes that can be accessed
* by name. Entity and Notation nodes are stored in NamedNodeMaps
* attached to the DocumentType. Attributes are placed in a NamedNodeMap
* attached to the elem they're related too. However, because attributes
* require more work, such as firing mutation events, they are stored in
* a subclass of NamedNodeMapImpl.
* <P>
* Only one Node may be stored per name; attempting to
* store another will replace the previous value.
* <P>
* NOTE: The "primary" storage key is taken from the NodeName attribute of the
* node. The "secondary" storage key is the namespaceURI and localName, when
* accessed by DOM level 2 nodes. All nodes, even DOM Level 2 nodes are stored
* in a single Vector sorted by the primary "nodename" key.
* <P>
* NOTE: item()'s integer index does _not_ imply that the named nodes
* must be stored in an array; that's only an access method. Note too
* that these indices are "live"; if someone changes the map's
* contents, the indices associated with nodes may change.
* <P>
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class NamedNodeMapImpl
implements NamedNodeMap, Serializable {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -7039242451046758020L;
//
// Data
//
protected short flags;
protected final static short READONLY = 0x1<<0;
protected final static short CHANGED = 0x1<<1;
protected final static short HASDEFAULTS = 0x1<<2;
/** Nodes. */
protected List nodes;
protected NodeImpl ownerNode; // the node this map belongs to
//
// Constructors
//
/** Constructs a named node map. */
protected NamedNodeMapImpl(NodeImpl ownerNode) {
this.ownerNode = ownerNode;
}
//
// NamedNodeMap methods
//
/**
* Report how many nodes are currently stored in this NamedNodeMap.
* Caveat: This is a count rather than an index, so the
* highest-numbered node at any time can be accessed via
* item(getLength()-1).
*/
public int getLength() {
return (nodes != null) ? nodes.size() : 0;
}
/**
* Retrieve an item from the map by 0-based index.
*
* @param index Which item to retrieve. Note that indices are just an
* enumeration of the current contents; they aren't guaranteed to be
* stable, nor do they imply any promises about the order of the
* NamedNodeMap's contents. In other words, DO NOT assume either that
* index(i) will always refer to the same entry, or that there is any
* stable ordering of entries... and be prepared for double-reporting
* or skips as insertion and deletion occur.
*
* @return the node which currenly has the specified index, or null if index
* is greater than or equal to getLength().
*/
public Node item(int index) {
return (nodes != null && index < nodes.size()) ?
(Node)(nodes.get(index)) : null;
}
/**
* Retrieve a node by name.
*
* @param name Name of a node to look up.
* @return the Node (of unspecified sub-class) stored with that name, or
* null if no value has been assigned to that name.
*/
public Node getNamedItem(String name) {
int i = findNamePoint(name,0);
return (i < 0) ? null : (Node)(nodes.get(i));
} // getNamedItem(String):Node
/**
* Introduced in DOM Level 2. <p>
* Retrieves a node specified by local name and namespace URI.
*
* @param namespaceURI The namespace URI of the node to retrieve.
* When it is null or an empty string, this
* method behaves like getNamedItem.
* @param localName The local name of the node to retrieve.
* @return Node A Node (of any type) with the specified name, or null if the specified
* name did not identify any node in the map.
*/
public Node getNamedItemNS(String namespaceURI, String localName) {
int i = findNamePoint(namespaceURI, localName);
return (i < 0) ? null : (Node)(nodes.get(i));
} // getNamedItemNS(String,String):Node
/**
* Adds a node using its nodeName attribute.
* As the nodeName attribute is used to derive the name which the node must be
* stored under, multiple nodes of certain types (those that have a "special" string
* value) cannot be stored as the names would clash. This is seen as preferable to
* allowing nodes to be aliased.
* @see org.w3c.dom.NamedNodeMap#setNamedItem
* @return If the new Node replaces an existing node the replaced Node is returned,
* otherwise null is returned.
* @param arg
* A node to store in a named node map. The node will later be
* accessible using the value of the namespaceURI and localName
* attribute of the node. If a node with those namespace URI and
* local name is already present in the map, it is replaced by the new
* one.
* @exception org.w3c.dom.DOMException The exception description.
*/
public Node setNamedItem(Node arg)
throws DOMException {
CoreDocumentImpl ownerDocument = ownerNode.ownerDocument();
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);
}
if (arg.getOwnerDocument() != ownerDocument) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
}
int i = findNamePoint(arg.getNodeName(),0);
NodeImpl previous = null;
if (i >= 0) {
previous = (NodeImpl) nodes.get(i);
nodes.set(i, arg);
} else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new ArrayList(5);
}
nodes.add(i, arg);
}
return previous;
} // setNamedItem(Node):Node
/**
* Adds a node using its namespaceURI and localName.
* @see org.w3c.dom.NamedNodeMap#setNamedItem
* @return If the new Node replaces an existing node the replaced Node is returned,
* otherwise null is returned.
* @param arg A node to store in a named node map. The node will later be
* accessible using the value of the namespaceURI and localName
* attribute of the node. If a node with those namespace URI and
* local name is already present in the map, it is replaced by the new
* one.
*/
public Node setNamedItemNS(Node arg)
throws DOMException {
CoreDocumentImpl ownerDocument = ownerNode.ownerDocument();
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);
}
if(arg.getOwnerDocument() != ownerDocument) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "WRONG_DOCUMENT_ERR", null);
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, msg);
}
}
int i = findNamePoint(arg.getNamespaceURI(), arg.getLocalName());
NodeImpl previous = null;
if (i >= 0) {
previous = (NodeImpl) nodes.get(i);
nodes.set(i, arg);
} else {
// If we can't find by namespaceURI, localName, then we find by
// nodeName so we know where to insert.
i = findNamePoint(arg.getNodeName(),0);
if (i >= 0) {
previous = (NodeImpl) nodes.get(i);
nodes.add(i, arg);
} else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new ArrayList(5);
}
nodes.add(i, arg);
}
}
return previous;
} // setNamedItemNS(Node):Node
/**
* Removes a node specified by name.
* @param name The name of a node to remove.
* @return The node removed from the map if a node with such a name exists.
*/
/***/
public Node removeNamedItem(String name)
throws DOMException {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw
new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
msg);
}
int i = findNamePoint(name,0);
if (i < 0) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
}
NodeImpl n = (NodeImpl)nodes.get(i);
nodes.remove(i);
return n;
} // removeNamedItem(String):Node
/**
* Introduced in DOM Level 2. <p>
* Removes a node specified by local name and namespace URI.
* @param namespaceURI
* The namespace URI of the node to remove.
* When it is null or an empty string, this
* method behaves like removeNamedItem.
* @param name The local name of the node to remove.
* @return Node The node removed from the map if a node with such
* a local name and namespace URI exists.
* @throws NOT_FOUND_ERR: Raised if there is no node named
* name in the map.
*/
public Node removeNamedItemNS(String namespaceURI, String name)
throws DOMException {
if (isReadOnly()) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null);
throw
new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
msg);
}
int i = findNamePoint(namespaceURI, name);
if (i < 0) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR", null);
throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
}
NodeImpl n = (NodeImpl)nodes.get(i);
nodes.remove(i);
return n;
} // removeNamedItem(String):Node
//
// Public methods
//
/**
* Cloning a NamedNodeMap is a DEEP OPERATION; it always clones
* all the nodes contained in the map.
*/
public NamedNodeMapImpl cloneMap(NodeImpl ownerNode) {
NamedNodeMapImpl newmap = new NamedNodeMapImpl(ownerNode);
newmap.cloneContent(this);
return newmap;
}
protected void cloneContent(NamedNodeMapImpl srcmap) {
List srcnodes = srcmap.nodes;
if (srcnodes != null) {
int size = srcnodes.size();
if (size != 0) {
if (nodes == null) {
nodes = new ArrayList(size);
}
else {
nodes.clear();
}
for (int i = 0; i < size; ++i) {
NodeImpl n = (NodeImpl) srcmap.nodes.get(i);
NodeImpl clone = (NodeImpl) n.cloneNode(true);
clone.isSpecified(n.isSpecified());
nodes.add(clone);
}
}
}
} // cloneMap():NamedNodeMapImpl
//
// Package methods
//
/**
* Internal subroutine to allow read-only Nodes to make their contained
* NamedNodeMaps readonly too. I expect that in fact the shallow
* version of this operation will never be
*
* @param readOnly boolean true to make read-only, false to permit editing.
* @param deep boolean true to pass this request along to the contained
* nodes, false to only toggle the NamedNodeMap itself. I expect that
* the shallow version of this operation will never be used, but I want
* to design it in now, while I'm thinking about it.
*/
void setReadOnly(boolean readOnly, boolean deep) {
isReadOnly(readOnly);
if (deep && nodes != null) {
for (int i = nodes.size() - 1; i >= 0; i--) {
((NodeImpl) nodes.get(i)).setReadOnly(readOnly,deep);
}
}
} // setReadOnly(boolean,boolean)
/**
* Internal subroutine returns this NodeNameMap's (shallow) readOnly value.
*
*/
boolean getReadOnly() {
return isReadOnly();
} // getReadOnly()
//
// Protected methods
//
/**
* NON-DOM
* set the ownerDocument of this node, and the attributes it contains
*/
protected void setOwnerDocument(CoreDocumentImpl doc) {
if (nodes != null) {
final int size = nodes.size();
for (int i = 0; i < size; ++i) {
((NodeImpl)item(i)).setOwnerDocument(doc);
}
}
}
final boolean isReadOnly() {
return (flags & READONLY) != 0;
}
final void isReadOnly(boolean value) {
flags = (short) (value ? flags | READONLY : flags & ~READONLY);
}
final boolean changed() {
return (flags & CHANGED) != 0;
}
final void changed(boolean value) {
flags = (short) (value ? flags | CHANGED : flags & ~CHANGED);
}
final boolean hasDefaults() {
return (flags & HASDEFAULTS) != 0;
}
final void hasDefaults(boolean value) {
flags = (short) (value ? flags | HASDEFAULTS : flags & ~HASDEFAULTS);
}
//
// Private methods
//
/**
* Subroutine: Locate the named item, or the point at which said item
* should be added.
*
* @param name Name of a node to look up.
*
* @return If positive or zero, the index of the found item.
* If negative, index of the appropriate point at which to insert
* the item, encoded as -1-index and hence reconvertable by subtracting
* it from -1. (Encoding because I don't want to recompare the strings
* but don't want to burn bytes on a datatype to hold a flagged value.)
*/
protected int findNamePoint(String name, int start) {
// Binary search
int i = 0;
if (nodes != null) {
int first = start;
int last = nodes.size() - 1;
while (first <= last) {
i = (first + last) / 2;
int test = name.compareTo(((Node)(nodes.get(i))).getNodeName());
if (test == 0) {
return i; // Name found
}
else if (test < 0) {
last = i - 1;
}
else {
first = i + 1;
}
}
if (first > i) {
i = first;
}
}
return -1 - i; // not-found has to be encoded.
} // findNamePoint(String):int
/** This findNamePoint is for DOM Level 2 Namespaces.
*/
protected int findNamePoint(String namespaceURI, String name) {
if (nodes == null) return -1;
if (name == null) return -1;
// This is a linear search through the same nodes ArrayList.
// The ArrayList is sorted on the DOM Level 1 nodename.
// The DOM Level 2 NS keys are namespaceURI and Localname,
// so we must linear search thru it.
// In addition, to get this to work with nodes without any namespace
// (namespaceURI and localNames are both null) we then use the nodeName
// as a secondary key.
final int size = nodes.size();
for (int i = 0; i < size; ++i) {
NodeImpl a = (NodeImpl)nodes.get(i);
String aNamespaceURI = a.getNamespaceURI();
String aLocalName = a.getLocalName();
if (namespaceURI == null) {
if (aNamespaceURI == null
&&
(name.equals(aLocalName)
||
(aLocalName == null && name.equals(a.getNodeName()))))
return i;
} else {
if (namespaceURI.equals(aNamespaceURI)
&&
name.equals(aLocalName))
return i;
}
}
return -1;
}
// compare 2 nodes in the map. If a precedes b, return true, otherwise
// return false
protected boolean precedes(Node a, Node b) {
if (nodes != null) {
final int size = nodes.size();
for (int i = 0; i < size; ++i) {
Node n = (Node)nodes.get(i);
if (n==a) return true;
if (n==b) return false;
}
}
return false;
}
/**
* NON-DOM: Remove attribute at specified index
*/
protected void removeItem(int index) {
if (nodes != null && index < nodes.size()){
nodes.remove(index);
}
}
protected Object getItem (int index){
if (nodes != null) {
return nodes.get(index);
}
return null;
}
protected int addItem (Node arg) {
int i = findNamePoint(arg.getNamespaceURI(), arg.getLocalName());
if (i >= 0) {
nodes.set(i, arg);
}
else {
// If we can't find by namespaceURI, localName, then we find by
// nodeName so we know where to insert.
i = findNamePoint(arg.getNodeName(),0);
if (i >= 0) {
nodes.add(i, arg);
}
else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new ArrayList(5);
}
nodes.add(i, arg);
}
}
return i;
}
/**
* NON-DOM: copy content of this map into the specified ArrayList
*
* @param list ArrayList to copy information into.
* @return A copy of this node named map
*/
protected ArrayList cloneMap(ArrayList list) {
if (list == null) {
list = new ArrayList(5);
}
list.clear();
if (nodes != null) {
final int size = nodes.size();
for (int i = 0; i < size; ++i) {
list.add(nodes.get(i));
}
}
return list;
}
protected int getNamedItemIndex(String namespaceURI, String localName) {
return findNamePoint(namespaceURI, localName);
}
/**
* NON-DOM remove all elements from this map
*/
public void removeAll (){
if (nodes != null) {
nodes.clear();
}
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
if (nodes != null) {
// cast to Vector is required
nodes = new ArrayList((Vector)nodes);
}
}
private void writeObject(ObjectOutputStream out) throws IOException {
List oldNodes = this.nodes;
try {
if (oldNodes != null) {
this.nodes = new Vector(oldNodes);
}
out.defaultWriteObject();
}
// If the write fails for some reason ensure
// that we restore the original object.
finally {
this.nodes = oldNodes;
}
}
} // class NamedNodeMapImpl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,375 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
/** DefaultNodeIterator implements a NodeIterator, which iterates a
* DOM tree in the expected depth first way.
*
* <p>The whatToShow and filter functionality is implemented as expected.
*
* <p>This class also has method removeNode to enable iterator "fix-up"
* on DOM remove. It is expected that the DOM implementation call removeNode
* right before the actual DOM transformation. If not called by the DOM,
* the client could call it before doing the removal.
*
* @xerces.internal
*
*/
public class NodeIteratorImpl implements NodeIterator {
//
// Data
//
/** The DocumentImpl which created this iterator, so it can be detached. */
private DocumentImpl fDocument;
/** The root. */
private Node fRoot;
/** The whatToShow mask. */
private int fWhatToShow = NodeFilter.SHOW_ALL;
/** The NodeFilter reference. */
private NodeFilter fNodeFilter;
/** If detach is called, the fDetach flag is true, otherwise flase. */
private boolean fDetach = false;
//
// Iterator state - current node and direction.
//
// Note: The current node and direction are sufficient to implement
// the desired behaviour of the current pointer being _between_
// two nodes. The fCurrentNode is actually the last node returned,
// and the
// direction is whether the pointer is in front or behind this node.
// (usually akin to whether the node was returned via nextNode())
// (eg fForward = true) or previousNode() (eg fForward = false).
// Note also, if removing a Node, the fCurrentNode
// can be placed on a Node which would not pass filters.
/** The last Node returned. */
private Node fCurrentNode;
/** The direction of the iterator on the fCurrentNode.
* <pre>
* nextNode() == fForward = true;
* previousNode() == fForward = false;
* </pre>
*/
private boolean fForward = true;
/** When TRUE, the children of entites references are returned in the iterator. */
private boolean fEntityReferenceExpansion;
//
// Constructor
//
/** Public constructor */
public NodeIteratorImpl( DocumentImpl document,
Node root,
int whatToShow,
NodeFilter nodeFilter,
boolean entityReferenceExpansion) {
fDocument = document;
fRoot = root;
fCurrentNode = null;
fWhatToShow = whatToShow;
fNodeFilter = nodeFilter;
fEntityReferenceExpansion = entityReferenceExpansion;
}
public Node getRoot() {
return fRoot;
}
// Implementation Note: Note that the iterator looks at whatToShow
// and filter values at each call, and therefore one _could_ add
// setters for these values and alter them while iterating!
/** Return the whatToShow value */
public int getWhatToShow() {
return fWhatToShow;
}
/** Return the filter */
public NodeFilter getFilter() {
return fNodeFilter;
}
/** Return whether children entity references are included in the iterator. */
public boolean getExpandEntityReferences() {
return fEntityReferenceExpansion;
}
/** Return the next Node in the Iterator. The node is the next node in
* depth-first order which also passes the filter, and whatToShow.
* If there is no next node which passes these criteria, then return null.
*/
public Node nextNode() {
if( fDetach) {
throw new DOMException(
DOMException.INVALID_STATE_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null));
}
// if root is null there is no next node.
if (fRoot == null) return null;
Node nextNode = fCurrentNode;
boolean accepted = false; // the next node has not been accepted.
accepted_loop:
while (!accepted) {
// if last direction is not forward, repeat node.
if (!fForward && nextNode!=null) {
//System.out.println("nextNode():!fForward:"+fCurrentNode.getNodeName());
nextNode = fCurrentNode;
} else {
// else get the next node via depth-first
if (!fEntityReferenceExpansion
&& nextNode != null
&& nextNode.getNodeType() == Node.ENTITY_REFERENCE_NODE) {
nextNode = nextNode(nextNode, false);
} else {
nextNode = nextNode(nextNode, true);
}
}
fForward = true; //REVIST: should direction be set forward before null check?
// nothing in the list. return null.
if (nextNode == null) return null;
// does node pass the filters and whatToShow?
accepted = acceptNode(nextNode);
if (accepted) {
// if so, then the node is the current node.
fCurrentNode = nextNode;
return fCurrentNode;
} else
continue accepted_loop;
} // while (!accepted) {
// no nodes, or no accepted nodes.
return null;
}
/** Return the previous Node in the Iterator. The node is the next node in
* _backwards_ depth-first order which also passes the filter, and whatToShow.
*/
public Node previousNode() {
if( fDetach) {
throw new DOMException(
DOMException.INVALID_STATE_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INVALID_STATE_ERR", null));
}
// if the root is null, or the current node is null, return null.
if (fRoot == null || fCurrentNode == null) return null;
Node previousNode = fCurrentNode;
boolean accepted = false;
accepted_loop:
while (!accepted) {
if (fForward && previousNode != null) {
//repeat last node.
previousNode = fCurrentNode;
} else {
// get previous node in backwards depth first order.
previousNode = previousNode(previousNode);
}
// we are going backwards
fForward = false;
// if the new previous node is null, we're at head or past the root,
// so return null.
if (previousNode == null) return null;
// check if node passes filters and whatToShow.
accepted = acceptNode(previousNode);
if (accepted) {
// if accepted, update the current node, and return it.
fCurrentNode = previousNode;
return fCurrentNode;
} else
continue accepted_loop;
}
// there are no nodes?
return null;
}
/** The node is accepted if it passes the whatToShow and the filter. */
boolean acceptNode(Node node) {
if (fNodeFilter == null) {
return ( fWhatToShow & (1 << node.getNodeType()-1)) != 0 ;
} else {
return ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 )
&& fNodeFilter.acceptNode(node) == NodeFilter.FILTER_ACCEPT;
}
}
/** Return node, if matches or any parent if matches. */
Node matchNodeOrParent(Node node) {
// Additions and removals in the underlying data structure may occur
// before any iterations, and in this case the reference_node is null.
if (fCurrentNode == null) return null;
// check if the removed node is an _ancestor_ of the
// reference node
for (Node n = fCurrentNode; n != fRoot; n = n.getParentNode()) {
if (node == n) return n;
}
return null;
}
/** The method nextNode(Node, boolean) returns the next node
* from the actual DOM tree.
*
* The boolean visitChildren determines whether to visit the children.
* The result is the nextNode.
*/
Node nextNode(Node node, boolean visitChildren) {
if (node == null) return fRoot;
Node result;
// only check children if we visit children.
if (visitChildren) {
//if hasChildren, return 1st child.
if (node.hasChildNodes()) {
result = node.getFirstChild();
return result;
}
}
if (node == fRoot) { //if Root has no kids
return null;
}
// if hasSibling, return sibling
result = node.getNextSibling();
if (result != null) return result;
// return parent's 1st sibling.
Node parent = node.getParentNode();
while (parent != null && parent != fRoot) {
result = parent.getNextSibling();
if (result != null) {
return result;
} else {
parent = parent.getParentNode();
}
} // while (parent != null && parent != fRoot) {
// end of list, return null
return null;
}
/** The method previousNode(Node) returns the previous node
* from the actual DOM tree.
*/
Node previousNode(Node node) {
Node result;
// if we're at the root, return null.
if (node == fRoot) return null;
// get sibling
result = node.getPreviousSibling();
if (result == null) {
//if 1st sibling, return parent
result = node.getParentNode();
return result;
}
// if sibling has children, keep getting last child of child.
if (result.hasChildNodes()
&& !(!fEntityReferenceExpansion
&& result != null
&& result.getNodeType() == Node.ENTITY_REFERENCE_NODE))
{
while (result.hasChildNodes()) {
result = result.getLastChild();
}
}
return result;
}
/** Fix-up the iterator on a remove. Called by DOM or otherwise,
* before an actual DOM remove.
*/
public void removeNode(Node node) {
// Implementation note: Fix-up means setting the current node properly
// after a remove.
if (node == null) return;
Node deleted = matchNodeOrParent(node);
if (deleted == null) return;
if (fForward) {
fCurrentNode = previousNode(deleted);
} else
// if (!fForward)
{
Node next = nextNode(deleted, false);
if (next!=null) {
// normal case: there _are_ nodes following this in the iterator.
fCurrentNode = next;
} else {
// the last node in the iterator is to be removed,
// so we set the current node to be the previous one.
fCurrentNode = previousNode(deleted);
fForward = true;
}
}
}
public void detach() {
fDetach = true;
fDocument.removeNodeIterator(this);
}
}

View File

@@ -0,0 +1,59 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.io.Serializable;
/**
* This class is used, via a pool managed on CoreDocumentImpl, in ParentNode to
* improve performance of the NodeList accessors, getLength() and item(i).
*
* @xerces.internal
*
* @author Arnaud Le Hors, IBM
*
*/
class NodeListCache implements Serializable {
/** Serialization version. */
private static final long serialVersionUID = -7927529254918631002L;
/** Cached node list length. */
int fLength = -1;
/** Last requested node index. */
int fChildIndex = -1;
/** Last requested node. */
ChildNode fChild;
/** Owner of this cache */
ParentNode fOwner;
/** Pointer to the next object on the list,
only meaningful when actully stored in the free list. */
NodeListCache next;
NodeListCache(ParentNode owner) {
fOwner = owner;
}
}

View File

@@ -0,0 +1,213 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import com.sun.org.apache.xerces.internal.util.URI;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.Notation;
/**
* Notations are how the Document Type Description (DTD) records hints
* about the format of an XML "unparsed entity" -- in other words,
* non-XML data bound to this document type, which some applications
* may wish to consult when manipulating the document. A Notation
* represents a name-value pair, with its nodeName being set to the
* declared name of the notation.
* <P>
* Notations are also used to formally declare the "targets" of
* Processing Instructions.
* <P>
* Note that the Notation's data is non-DOM information; the DOM only
* records what and where it is.
* <P>
* See the XML 1.0 spec, sections 4.7 and 2.6, for more info.
* <P>
* Level 1 of the DOM does not support editing Notation contents.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class NotationImpl
extends NodeImpl
implements Notation {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -764632195890658402L;
//
// Data
//
/** Notation name. */
protected String name;
/** Public identifier. */
protected String publicId;
/** System identifier. */
protected String systemId;
/** Base URI*/
protected String baseURI;
//
// Constructors
//
/** Factory constructor. */
public NotationImpl(CoreDocumentImpl ownerDoc, String name) {
super(ownerDoc);
this.name = name;
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.NOTATION_NODE;
}
/**
* Returns the notation name
*/
public String getNodeName() {
if (needsSyncData()) {
synchronizeData();
}
return name;
}
//
// Notation methods
//
/**
* The Public Identifier for this Notation. If no public identifier
* was specified, this will be null.
*/
public String getPublicId() {
if (needsSyncData()) {
synchronizeData();
}
return publicId;
} // getPublicId():String
/**
* The System Identifier for this Notation. If no system identifier
* was specified, this will be null.
*/
public String getSystemId() {
if (needsSyncData()) {
synchronizeData();
}
return systemId;
} // getSystemId():String
//
// Public methods
//
/**
* NON-DOM: The Public Identifier for this Notation. If no public
* identifier was specified, this will be null.
*/
public void setPublicId(String id) {
if (isReadOnly()) {
throw new DOMException(
DOMException.NO_MODIFICATION_ALLOWED_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
}
if (needsSyncData()) {
synchronizeData();
}
publicId = id;
} // setPublicId(String)
/**
* NON-DOM: The System Identifier for this Notation. If no system
* identifier was specified, this will be null.
*/
public void setSystemId(String id) {
if(isReadOnly()) {
throw new DOMException(
DOMException.NO_MODIFICATION_ALLOWED_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
}
if (needsSyncData()) {
synchronizeData();
}
systemId = id;
} // setSystemId(String)
/**
* Returns the absolute base URI of this node or null if the implementation
* wasn't able to obtain an absolute URI. Note: If the URI is malformed, a
* null is returned.
*
* @return The absolute base URI of this node or null.
* @since DOM Level 3
*/
public String getBaseURI() {
if (needsSyncData()) {
synchronizeData();
}
if (baseURI != null && baseURI.length() != 0 ) {// attribute value is always empty string
try {
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 baseURI;
}
/** NON-DOM: set base uri*/
public void setBaseURI(String uri){
if (needsSyncData()) {
synchronizeData();
}
baseURI = uri;
}
} // class NotationImpl

View File

@@ -0,0 +1,253 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 2002-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
import com.sun.org.apache.xerces.internal.xs.*;
/**
* Attribute namespace implementation; stores PSVI attribute items.
*
* @xerces.internal
*
* @author Sandy Gao, IBM
*
*/
public class PSVIAttrNSImpl extends AttrNSImpl implements AttributePSVI {
/** Serialization version. */
static final long serialVersionUID = -3241738699421018889L;
/**
* Construct an attribute node.
*/
public PSVIAttrNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI,
String qualifiedName, String localName) {
super(ownerDocument, namespaceURI, qualifiedName, localName);
}
/**
* Construct an attribute node.
*/
public PSVIAttrNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI,
String qualifiedName) {
super(ownerDocument, namespaceURI, qualifiedName);
}
/** attribute declaration */
protected XSAttributeDeclaration fDeclaration = null;
/** type of attribute, simpleType */
protected XSTypeDefinition fTypeDecl = null;
/** If this attribute was explicitly given a
* value in the original document, this is true; otherwise, it is false */
protected boolean fSpecified = true;
/** schema normalized value property */
protected String fNormalizedValue = null;
/** schema actual value */
protected Object fActualValue = null;
/** schema actual value type */
protected short fActualValueType = XSConstants.UNAVAILABLE_DT;
/** actual value types if the value is a list */
protected ShortList fItemValueTypes = null;
/** member type definition against which attribute was validated */
protected XSSimpleTypeDefinition fMemberType = null;
/** validation attempted: none, partial, full */
protected short fValidationAttempted = AttributePSVI.VALIDATION_NONE;
/** validity: valid, invalid, unknown */
protected short fValidity = AttributePSVI.VALIDITY_NOTKNOWN;
/** error codes */
protected StringList fErrorCodes = null;
/** validation context: could be QName or XPath expression*/
protected String fValidationContext = null;
//
// AttributePSVI methods
//
/**
* [schema default]
*
* @return The canonical lexical representation of the declaration's {value constraint} value.
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_default>XML Schema Part 1: Structures [schema default]</a>
*/
public String getSchemaDefault() {
return fDeclaration == null ? null : fDeclaration.getConstraintValue();
}
/**
* [schema normalized value]
*
*
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_normalized_value>XML Schema Part 1: Structures [schema normalized value]</a>
* @return the normalized value of this item after validation
*/
public String getSchemaNormalizedValue() {
return fNormalizedValue;
}
/**
* [schema specified]
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_specified">XML Schema Part 1: Structures [schema specified]</a>
* @return false value was specified in schema, true value comes from the infoset
*/
public boolean getIsSchemaSpecified() {
return fSpecified;
}
/**
* Determines the extent to which the document has been validated
*
* @return return the [validation attempted] property. The possible values are
* NO_VALIDATION, PARTIAL_VALIDATION and FULL_VALIDATION
*/
public short getValidationAttempted() {
return fValidationAttempted;
}
/**
* Determine the validity of the node with respect
* to the validation being attempted
*
* @return return the [validity] property. Possible values are:
* UNKNOWN_VALIDITY, INVALID_VALIDITY, VALID_VALIDITY
*/
public short getValidity() {
return fValidity;
}
/**
* A list of error codes generated from validation attempts.
* Need to find all the possible subclause reports that need reporting
*
* @return list of error codes
*/
public StringList getErrorCodes() {
return fErrorCodes;
}
// This is the only information we can provide in a pipeline.
public String getValidationContext() {
return fValidationContext;
}
/**
* An item isomorphic to the type definition used to validate this element.
*
* @return a type declaration
*/
public XSTypeDefinition getTypeDefinition() {
return fTypeDecl;
}
/**
* If and only if that type definition is a simple type definition
* with {variety} union, or a complex type definition whose {content type}
* is a simple thype definition with {variety} union, then an item isomorphic
* to that member of the union's {member type definitions} which actually
* validated the element item's normalized value.
*
* @return a simple type declaration
*/
public XSSimpleTypeDefinition getMemberTypeDefinition() {
return fMemberType;
}
/**
* An item isomorphic to the attribute declaration used to validate
* this attribute.
*
* @return an attribute declaration
*/
public XSAttributeDeclaration getAttributeDeclaration() {
return fDeclaration;
}
/**
* Copy PSVI properties from another psvi item.
*
* @param attr the source of attribute PSVI items
*/
public void setPSVI(AttributePSVI attr) {
this.fDeclaration = attr.getAttributeDeclaration();
this.fValidationContext = attr.getValidationContext();
this.fValidity = attr.getValidity();
this.fValidationAttempted = attr.getValidationAttempted();
this.fErrorCodes = attr.getErrorCodes();
this.fNormalizedValue = attr.getSchemaNormalizedValue();
this.fActualValue = attr.getActualNormalizedValue();
this.fActualValueType = attr.getActualNormalizedValueType();
this.fItemValueTypes = attr.getItemValueTypes();
this.fTypeDecl = attr.getTypeDefinition();
this.fMemberType = attr.getMemberTypeDefinition();
this.fSpecified = attr.getIsSchemaSpecified();
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue()
*/
public Object getActualNormalizedValue() {
return this.fActualValue;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType()
*/
public short getActualNormalizedValueType() {
return this.fActualValueType;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes()
*/
public ShortList getItemValueTypes() {
return this.fItemValueTypes;
}
// REVISIT: Forbid serialization of PSVI DOM until
// we support object serialization of grammars -- mrglavas
private void writeObject(ObjectOutputStream out)
throws IOException {
throw new NotSerializableException(getClass().getName());
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
throw new NotSerializableException(getClass().getName());
}
}

View File

@@ -0,0 +1,125 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.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
* implementation of the Document Object Model. As such its data is
* static, shared by all instances of this implementation.
* <P>
* The DOM API requires that it be a real object rather than static
* methods. However, there's nothing that says it can't be a singleton,
* so that's how I've implemented it.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class PSVIDOMImplementationImpl extends CoreDOMImplementationImpl {
//
// Data
//
// static
/** Dom implementation singleton. */
static PSVIDOMImplementationImpl singleton = new PSVIDOMImplementationImpl();
//
// Public methods
//
/** NON-DOM: Obtain and return the single shared object */
public static DOMImplementation getDOMImplementation() {
return singleton;
}
//
// DOMImplementation methods
//
/**
* Test if the DOM implementation supports a specific "feature" --
* currently meaning language and level thereof.
*
* @param feature The package name of the feature to test.
* In Level 1, supported values are "HTML" and "XML" (case-insensitive).
* At this writing, com.sun.org.apache.xerces.internal.dom supports only XML.
*
* @param version The version number of the feature being tested.
* This is interpreted as "Version of the DOM API supported for the
* specified Feature", and in Level 1 should be "1.0"
*
* @return true iff this implementation is compatable with the specified
* feature and version.
*/
public boolean hasFeature(String feature, String version) {
return super.hasFeature(feature, version) ||
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;
}
} // class DOMImplementationImpl

View File

@@ -0,0 +1,151 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.UserDataHandler;
import org.w3c.dom.*;
/**
* Our own document implementation, which knows how to create an element
* with PSVI information.
*
* @xerces.internal
*
* @author Sandy Gao, IBM
*
*/
public class PSVIDocumentImpl extends DocumentImpl {
/** Serialization version. */
static final long serialVersionUID = -8822220250676434522L;
/**
* Create a document.
*/
public PSVIDocumentImpl() {
super();
}
/**
* For DOM2 support.
* The createDocument factory method is in DOMImplementation.
*/
public PSVIDocumentImpl(DocumentType doctype) {
super(doctype);
}
/**
* Deep-clone a document, including fixing ownerDoc for the cloned
* children. Note that this requires bypassing the WRONG_DOCUMENT_ERR
* protection. I've chosen to implement it by calling importNode
* which is DOM Level 2.
*
* @return org.w3c.dom.Node
* @param deep boolean, iff true replicate children
*/
public Node cloneNode(boolean deep) {
PSVIDocumentImpl newdoc = new PSVIDocumentImpl();
callUserDataHandlers(this, newdoc, UserDataHandler.NODE_CLONED);
cloneNode(newdoc, deep);
// experimental
newdoc.mutationEvents = mutationEvents;
return newdoc;
} // cloneNode(boolean):Node
/**
* Retrieve information describing the abilities of this particular
* DOM implementation. Intended to support applications that may be
* using DOMs retrieved from several different sources, potentially
* with different underlying representations.
*/
public DOMImplementation getImplementation() {
// Currently implemented as a singleton, since it's hardcoded
// information anyway.
return PSVIDOMImplementationImpl.getDOMImplementation();
}
/**
* Create an element with PSVI information
*/
public Element createElementNS(String namespaceURI, String qualifiedName)
throws DOMException {
return new PSVIElementNSImpl(this, namespaceURI, qualifiedName);
}
/**
* Create an element with PSVI information
*/
public Element createElementNS(String namespaceURI, String qualifiedName,
String localpart) throws DOMException {
return new PSVIElementNSImpl(this, namespaceURI, qualifiedName, localpart);
}
/**
* Create an attribute with PSVI information
*/
public Attr createAttributeNS(String namespaceURI, String qualifiedName)
throws DOMException {
return new PSVIAttrNSImpl(this, namespaceURI, qualifiedName);
}
/**
* Create an attribute with PSVI information
*/
public Attr createAttributeNS(String namespaceURI, String qualifiedName,
String localName) throws DOMException {
return new PSVIAttrNSImpl(this, namespaceURI, qualifiedName, localName);
}
/**
*
* The configuration used when <code>Document.normalizeDocument</code> is
* invoked.
* @since DOM Level 3
*/
public DOMConfiguration getDomConfig(){
super.getDomConfig();
return fConfiguration;
}
// REVISIT: Forbid serialization of PSVI DOM until
// we support object serialization of grammars -- mrglavas
private void writeObject(ObjectOutputStream out)
throws IOException {
throw new NotSerializableException(getClass().getName());
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
throw new NotSerializableException(getClass().getName());
}
} // class PSVIDocumentImpl

View File

@@ -0,0 +1,295 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 2002-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
import com.sun.org.apache.xerces.internal.xs.*;
/**
* Element namespace implementation; stores PSVI element items.
*
* @xerces.internal
*
* @author Sandy Gao, IBM
*
*/
public class PSVIElementNSImpl extends ElementNSImpl implements ElementPSVI {
/** Serialization version. */
static final long serialVersionUID = 6815489624636016068L;
/**
* Construct an element node.
*/
public PSVIElementNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI,
String qualifiedName, String localName) {
super(ownerDocument, namespaceURI, qualifiedName, localName);
}
/**
* Construct an element node.
*/
public PSVIElementNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI,
String qualifiedName) {
super(ownerDocument, namespaceURI, qualifiedName);
}
/** element declaration */
protected XSElementDeclaration fDeclaration = null;
/** type of element, could be xsi:type */
protected XSTypeDefinition fTypeDecl = null;
/** true if clause 3.2 of Element Locally Valid (Element) (3.3.4)
* is satisfied, otherwise false
*/
protected boolean fNil = false;
/** false if the element value was provided by the schema; true otherwise.
*/
protected boolean fSpecified = true;
/** schema normalized value property */
protected String fNormalizedValue = null;
/** schema actual value */
protected Object fActualValue = null;
/** schema actual value type */
protected short fActualValueType = XSConstants.UNAVAILABLE_DT;
/** actual value types if the value is a list */
protected ShortList fItemValueTypes = null;
/** http://www.w3.org/TR/xmlschema-1/#e-notation*/
protected XSNotationDeclaration fNotation = null;
/** member type definition against which element was validated */
protected XSSimpleTypeDefinition fMemberType = null;
/** validation attempted: none, partial, full */
protected short fValidationAttempted = ElementPSVI.VALIDATION_NONE;
/** validity: valid, invalid, unknown */
protected short fValidity = ElementPSVI.VALIDITY_NOTKNOWN;
/** error codes */
protected StringList fErrorCodes = null;
/** validation context: could be QName or XPath expression*/
protected String fValidationContext = null;
/** the schema information property */
protected XSModel fSchemaInformation = null;
//
// ElementPSVI methods
//
/**
* [schema default]
*
* @return The canonical lexical representation of the declaration's {value constraint} value.
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_default>XML Schema Part 1: Structures [schema default]</a>
*/
public String getSchemaDefault() {
return fDeclaration == null ? null : fDeclaration.getConstraintValue();
}
/**
* [schema normalized value]
*
*
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_normalized_value>XML Schema Part 1: Structures [schema normalized value]</a>
* @return the normalized value of this item after validation
*/
public String getSchemaNormalizedValue() {
return fNormalizedValue;
}
/**
* [schema specified]
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_specified">XML Schema Part 1: Structures [schema specified]</a>
* @return false value was specified in schema, true value comes from the infoset
*/
public boolean getIsSchemaSpecified() {
return fSpecified;
}
/**
* Determines the extent to which the document has been validated
*
* @return return the [validation attempted] property. The possible values are
* NO_VALIDATION, PARTIAL_VALIDATION and FULL_VALIDATION
*/
public short getValidationAttempted() {
return fValidationAttempted;
}
/**
* Determine the validity of the node with respect
* to the validation being attempted
*
* @return return the [validity] property. Possible values are:
* UNKNOWN_VALIDITY, INVALID_VALIDITY, VALID_VALIDITY
*/
public short getValidity() {
return fValidity;
}
/**
* A list of error codes generated from validation attempts.
* Need to find all the possible subclause reports that need reporting
*
* @return Array of error codes
*/
public StringList getErrorCodes() {
return fErrorCodes;
}
// This is the only information we can provide in a pipeline.
public String getValidationContext() {
return fValidationContext;
}
/**
* [nil]
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-nil>XML Schema Part 1: Structures [nil]</a>
* @return true if clause 3.2 of Element Locally Valid (Element) (3.3.4) above is satisfied, otherwise false
*/
public boolean getNil() {
return fNil;
}
/**
* [notation]
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-notation>XML Schema Part 1: Structures [notation]</a>
* @return The notation declaration.
*/
public XSNotationDeclaration getNotation() {
return fNotation;
}
/**
* An item isomorphic to the type definition used to validate this element.
*
* @return a type declaration
*/
public XSTypeDefinition getTypeDefinition() {
return fTypeDecl;
}
/**
* If and only if that type definition is a simple type definition
* with {variety} union, or a complex type definition whose {content type}
* is a simple thype definition with {variety} union, then an item isomorphic
* to that member of the union's {member type definitions} which actually
* validated the element item's normalized value.
*
* @return a simple type declaration
*/
public XSSimpleTypeDefinition getMemberTypeDefinition() {
return fMemberType;
}
/**
* An item isomorphic to the element declaration used to validate
* this element.
*
* @return an element declaration
*/
public XSElementDeclaration getElementDeclaration() {
return fDeclaration;
}
/**
* [schema information]
* @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_information">XML Schema Part 1: Structures [schema information]</a>
* @return The schema information property if it's the validation root,
* null otherwise.
*/
public XSModel getSchemaInformation() {
return fSchemaInformation;
}
/**
* Copy PSVI properties from another psvi item.
*
* @param attr the source of attribute PSVI items
*/
public void setPSVI(ElementPSVI elem) {
this.fDeclaration = elem.getElementDeclaration();
this.fNotation = elem.getNotation();
this.fValidationContext = elem.getValidationContext();
this.fTypeDecl = elem.getTypeDefinition();
this.fSchemaInformation = elem.getSchemaInformation();
this.fValidity = elem.getValidity();
this.fValidationAttempted = elem.getValidationAttempted();
this.fErrorCodes = elem.getErrorCodes();
this.fNormalizedValue = elem.getSchemaNormalizedValue();
this.fActualValue = elem.getActualNormalizedValue();
this.fActualValueType = elem.getActualNormalizedValueType();
this.fItemValueTypes = elem.getItemValueTypes();
this.fMemberType = elem.getMemberTypeDefinition();
this.fSpecified = elem.getIsSchemaSpecified();
this.fNil = elem.getNil();
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValue()
*/
public Object getActualNormalizedValue() {
return this.fActualValue;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getActualNormalizedValueType()
*/
public short getActualNormalizedValueType() {
return this.fActualValueType;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.ItemPSVI#getItemValueTypes()
*/
public ShortList getItemValueTypes() {
return this.fItemValueTypes;
}
// REVISIT: Forbid serialization of PSVI DOM until
// we support object serialization of grammars -- mrglavas
private void writeObject(ObjectOutputStream out)
throws IOException {
throw new NotSerializableException(getClass().getName());
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
throw new NotSerializableException(getClass().getName());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,162 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
/**
* Processing Instructions (PIs) permit documents to carry
* processor-specific information alongside their actual content. PIs
* are most common in XML, but they are supported in HTML as well.
*
* This class inherits from CharacterDataImpl to reuse its setNodeValue method.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class ProcessingInstructionImpl
extends CharacterDataImpl
implements ProcessingInstruction {
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = 7554435174099981510L;
//
// Data
//
protected String target;
//
// Constructors
//
/** Factory constructor. */
public ProcessingInstructionImpl(CoreDocumentImpl ownerDoc,
String target, String data) {
super(ownerDoc, data);
this.target = target;
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.PROCESSING_INSTRUCTION_NODE;
}
/**
* Returns the target
*/
public String getNodeName() {
if (needsSyncData()) {
synchronizeData();
}
return target;
}
//
// ProcessingInstruction methods
//
/**
* A PI's "target" states what processor channel the PI's data
* should be directed to. It is defined differently in HTML and XML.
* <p>
* In XML, a PI's "target" is the first (whitespace-delimited) token
* following the "<?" token that begins the PI.
* <p>
* In HTML, target is always null.
* <p>
* Note that getNodeName is aliased to getTarget.
*/
public String getTarget() {
if (needsSyncData()) {
synchronizeData();
}
return target;
} // getTarget():String
/**
* A PI's data content tells the processor what we actually want it
* to do. It is defined slightly differently in HTML and XML.
* <p>
* In XML, the data begins with the non-whitespace character
* immediately after the target -- @see getTarget().
* <p>
* In HTML, the data begins with the character immediately after the
* "&lt;?" token that begins the PI.
* <p>
* Note that getNodeValue is aliased to getData
*/
public String getData() {
if (needsSyncData()) {
synchronizeData();
}
return data;
} // getData():String
/**
* Change the data content of this PI.
* Note that setData is aliased to setNodeValue.
* @see #getData().
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if node is read-only.
*/
public void setData(String data) {
// Hand off to setNodeValue for code-reuse reasons (mutation
// events, readonly protection, synchronizing, etc.)
setNodeValue(data);
} // setData(String)
/**
* Returns the absolute base URI of this node or null if the implementation
* wasn't able to obtain an absolute URI. Note: If the URI is malformed, a
* null is returned.
*
* @return The absolute base URI of this node or null.
* @since DOM Level 3
*/
public String getBaseURI() {
if (needsSyncData()) {
synchronizeData();
}
return ownerNode.getBaseURI();
}
} // class ProcessingInstructionImpl

View File

@@ -0,0 +1,39 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.ranges.RangeException;
/**
* @xerces.internal
*
*/
public class RangeExceptionImpl extends RangeException {
/** Serialization version. */
static final long serialVersionUID = -9058052627467240856L;
public RangeExceptionImpl(short code, String message) {
super(code,message);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,666 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.CharacterData;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
/**
* Text nodes hold the non-markup, non-Entity content of
* an Element or Attribute.
* <P>
* When a document is first made available to the DOM, there is only
* one Text object for each block of adjacent plain-text. Users (ie,
* applications) may create multiple adjacent Texts during editing --
* see {@link org.w3c.dom.Element#normalize} for discussion.
* <P>
* Note that CDATASection is a subclass of Text. This is conceptually
* valid, since they're really just two different ways of quoting
* characters when they're written out as part of an XML stream.
*
* @xerces.internal
*
* @since PR-DOM-Level-1-19980818.
*/
public class TextImpl
extends CharacterDataImpl
implements CharacterData, Text {
//
// Private Data members
//
//
// Constants
//
/** Serialization version. */
static final long serialVersionUID = -5294980852957403469L;
//
// Constructors
//
/** Default constructor */
public TextImpl(){}
/** Factory constructor. */
public TextImpl(CoreDocumentImpl ownerDoc, String data) {
super(ownerDoc, data);
}
/**
* NON-DOM: resets node and sets specified values for the current node
*
* @param ownerDoc
* @param data
*/
public void setValues(CoreDocumentImpl ownerDoc, String data){
flags=0;
nextSibling = null;
previousSibling=null;
setOwnerDocument(ownerDoc);
super.data = data;
}
//
// Node methods
//
/**
* A short integer indicating what type of node this is. The named
* constants for this value are defined in the org.w3c.dom.Node interface.
*/
public short getNodeType() {
return Node.TEXT_NODE;
}
/** Returns the node name. */
public String getNodeName() {
return "#text";
}
/**
* NON-DOM: Set whether this Text is ignorable whitespace.
*/
public void setIgnorableWhitespace(boolean ignore) {
if (needsSyncData()) {
synchronizeData();
}
isIgnorableWhitespace(ignore);
} // setIgnorableWhitespace(boolean)
/**
* DOM L3 Core CR - Experimental
*
* Returns whether this text node contains
* element content whitespace</a>, often abusively called "ignorable whitespace".
* The text node is determined to contain whitespace in element content
* during the load of the document or if validation occurs while using
* <code>Document.normalizeDocument()</code>.
* @since DOM Level 3
*/
public boolean isElementContentWhitespace() {
// REVISIT: is this implemenation correct?
if (needsSyncData()) {
synchronizeData();
}
return internalIsIgnorableWhitespace();
}
/**
* DOM Level 3 WD - Experimental.
* Returns all text of <code>Text</code> nodes logically-adjacent text
* nodes to this node, concatenated in document order.
* @since DOM Level 3
*/
public String getWholeText(){
if (needsSyncData()) {
synchronizeData();
}
if (fBufferStr == null){
fBufferStr = new StringBuffer();
}
else {
fBufferStr.setLength(0);
}
if (data != null && data.length() != 0) {
fBufferStr.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();
//clear buffer
fBufferStr.setLength(0);
//concatenate text of logically adjacent text nodes to the right of this node in the tree
getWholeTextForward(this.getNextSibling(), fBufferStr, this.getParentNode());
return temp + fBufferStr.toString();
}
/**
* internal method taking a StringBuffer in parameter and inserts the
* text content at the start of the buffer
*
* @param buf
*/
protected void insertTextContent(StringBuffer buf) throws DOMException {
String content = getNodeValue();
if (content != null) {
buf.insert(0, content);
}
}
/**
* Concatenates the text of all logically-adjacent text nodes to the
* right of this node
* @param node
* @param buffer
* @param parent
* @return true - if execution was stopped because the type of node
* other than EntityRef, Text, CDATA is encountered, otherwise
* return false
*/
private boolean getWholeTextForward(Node node, StringBuffer buffer, Node parent){
// boolean to indicate whether node is a child of an entity reference
boolean inEntRef = false;
if (parent!=null) {
inEntRef = parent.getNodeType()==Node.ENTITY_REFERENCE_NODE;
}
while (node != null) {
short type = node.getNodeType();
if (type == Node.ENTITY_REFERENCE_NODE) {
if (getWholeTextForward(node.getFirstChild(), buffer, node)){
return true;
}
}
else if (type == Node.TEXT_NODE ||
type == Node.CDATA_SECTION_NODE) {
((NodeImpl)node).getTextContent(buffer);
}
else {
return true;
}
node = node.getNextSibling();
}
// if the parent node is an entity reference node, must
// check nodes to the right of the parent entity reference node for logically adjacent
// text nodes
if (inEntRef) {
getWholeTextForward(parent.getNextSibling(), buffer, parent.getParentNode());
return true;
}
return false;
}
/**
* Concatenates the text of all logically-adjacent text nodes to the left of
* the node
* @param node
* @param buffer
* @param parent
* @return true - if execution was stopped because the type of node
* other than EntityRef, Text, CDATA is encountered, otherwise
* return false
*/
private boolean getWholeTextBackward(Node node, StringBuffer buffer, Node parent){
// boolean to indicate whether node is a child of an entity reference
boolean inEntRef = false;
if (parent!=null) {
inEntRef = parent.getNodeType()==Node.ENTITY_REFERENCE_NODE;
}
while (node != null) {
short type = node.getNodeType();
if (type == Node.ENTITY_REFERENCE_NODE) {
if (getWholeTextBackward(node.getLastChild(), buffer, node)){
return true;
}
}
else if (type == Node.TEXT_NODE ||
type == Node.CDATA_SECTION_NODE) {
((TextImpl)node).insertTextContent(buffer);
}
else {
return true;
}
node = node.getPreviousSibling();
}
// if the parent node is an entity reference node, must
// check nodes to the left of the parent entity reference node for logically adjacent
// text nodes
if (inEntRef) {
getWholeTextBackward(parent.getPreviousSibling(), buffer, parent.getParentNode());
return true;
}
return false;
}
/**
* Replaces the text of the current node and all logically-adjacent text
* nodes with the specified text. All logically-adjacent text nodes are
* removed including the current node unless it was the recipient of the
* replacement text.
*
* @param content
* The content of the replacing Text node.
* @return text - The Text node created with the specified content.
* @since DOM Level 3
*/
public Text replaceWholeText(String content) throws DOMException {
if (needsSyncData()) {
synchronizeData();
}
//if the content is null
Node parent = this.getParentNode();
if (content == null || content.length() == 0) {
// remove current node
if (parent != null) { // check if node in the tree
parent.removeChild(this);
}
return null;
}
// make sure we can make the replacement
if (ownerDocument().errorChecking) {
if (!canModifyPrev(this)) {
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NO_MODIFICATION_ALLOWED_ERR", null));
}
// make sure we can make the replacement
if (!canModifyNext(this)) {
throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"NO_MODIFICATION_ALLOWED_ERR", null));
}
}
//replace the text node
Text currentNode = null;
if (isReadOnly()) {
Text newNode = this.ownerDocument().createTextNode(content);
if (parent != null) { // check if node in the tree
parent.insertBefore(newNode, this);
parent.removeChild(this);
currentNode = newNode;
} else {
return newNode;
}
} else {
this.setData(content);
currentNode = this;
}
//check logically-adjacent text nodes
Node prev = currentNode.getPreviousSibling();
while (prev != null) {
//If the logically-adjacent next node can be removed
//remove it. A logically adjacent node can be removed if
//it is a Text or CDATASection node or an EntityReference with
//Text and CDATA only children.
if ((prev.getNodeType() == Node.TEXT_NODE)
|| (prev.getNodeType() == Node.CDATA_SECTION_NODE)
|| (prev.getNodeType() == Node.ENTITY_REFERENCE_NODE && hasTextOnlyChildren(prev))) {
parent.removeChild(prev);
prev = currentNode;
} else {
break;
}
prev = prev.getPreviousSibling();
}
//check logically-adjacent text nodes
Node next = currentNode.getNextSibling();
while (next != null) {
//If the logically-adjacent next node can be removed
//remove it. A logically adjacent node can be removed if
//it is a Text or CDATASection node or an EntityReference with
//Text and CDATA only children.
if ((next.getNodeType() == Node.TEXT_NODE)
|| (next.getNodeType() == Node.CDATA_SECTION_NODE)
|| (next.getNodeType() == Node.ENTITY_REFERENCE_NODE && hasTextOnlyChildren(next))) {
parent.removeChild(next);
next = currentNode;
} else {
break;
}
next = next.getNextSibling();
}
return currentNode;
}
/**
* If any EntityReference to be removed has descendants that are not
* EntityReference, Text, or CDATASection nodes, the replaceWholeText method
* must fail before performing any modification of the document, raising a
* DOMException with the code NO_MODIFICATION_ALLOWED_ERR. Traverse previous
* siblings of the node to be replaced. If a previous sibling is an
* EntityReference node, get it's last child. If the last child was a Text
* or CDATASection node and its previous siblings are neither a replaceable
* EntityReference or Text or CDATASection nodes, return false. IF the last
* child was neither Text nor CDATASection nor a replaceable EntityReference
* Node, then return true. If the last child was a Text or CDATASection node
* any its previous sibling was not or was an EntityReference that did not
* contain only Text or CDATASection nodes, return false. Check this
* recursively for EntityReference nodes.
*
* @param node
* @return true - can replace text false - can't replace exception must be
* raised
*/
private boolean canModifyPrev(Node node) {
boolean textLastChild = false;
Node prev = node.getPreviousSibling();
while (prev != null) {
short type = prev.getNodeType();
if (type == Node.ENTITY_REFERENCE_NODE) {
//If the previous sibling was entityreference
//check if its content is replaceable
Node lastChild = prev.getLastChild();
//if the entity reference has no children
//return false
if (lastChild == null) {
return false;
}
//The replacement text of the entity reference should
//be either only text,cadatsections or replaceable entity
//reference nodes or the last child should be neither of these
while (lastChild != null) {
short lType = lastChild.getNodeType();
if (lType == Node.TEXT_NODE
|| lType == Node.CDATA_SECTION_NODE) {
textLastChild = true;
} else if (lType == Node.ENTITY_REFERENCE_NODE) {
if (!canModifyPrev(lastChild)) {
return false;
} else {
//If the EntityReference child contains
//only text, or non-text or ends with a
//non-text node.
textLastChild = true;
}
} else {
//If the last child was replaceable and others are not
//Text or CDataSection or replaceable EntityRef nodes
//return false.
if (textLastChild) {
return false;
} else {
return true;
}
}
lastChild = lastChild.getPreviousSibling();
}
} else if (type == Node.TEXT_NODE
|| type == Node.CDATA_SECTION_NODE) {
//If the previous sibling was text or cdatasection move to next
} else {
//If the previous sibling was anything but text or
//cdatasection or an entity reference, stop search and
//return true
return true;
}
prev = prev.getPreviousSibling();
}
return true;
}
/**
* If any EntityReference to be removed has descendants that are not
* EntityReference, Text, or CDATASection nodes, the replaceWholeText method
* must fail before performing any modification of the document, raising a
* DOMException with the code NO_MODIFICATION_ALLOWED_ERR. Traverse previous
* siblings of the node to be replaced. If a previous sibling is an
* EntityReference node, get it's last child. If the first child was a Text
* or CDATASection node and its next siblings are neither a replaceable
* EntityReference or Text or CDATASection nodes, return false. IF the first
* child was neither Text nor CDATASection nor a replaceable EntityReference
* Node, then return true. If the first child was a Text or CDATASection
* node any its next sibling was not or was an EntityReference that did not
* contain only Text or CDATASection nodes, return false. Check this
* recursively for EntityReference nodes.
*
* @param node
* @return true - can replace text false - can't replace exception must be
* raised
*/
private boolean canModifyNext(Node node) {
boolean textFirstChild = false;
Node next = node.getNextSibling();
while (next != null) {
short type = next.getNodeType();
if (type == Node.ENTITY_REFERENCE_NODE) {
//If the previous sibling was entityreference
//check if its content is replaceable
Node firstChild = next.getFirstChild();
//if the entity reference has no children
//return false
if (firstChild == null) {
return false;
}
//The replacement text of the entity reference should
//be either only text,cadatsections or replaceable entity
//reference nodes or the last child should be neither of these
while (firstChild != null) {
short lType = firstChild.getNodeType();
if (lType == Node.TEXT_NODE
|| lType == Node.CDATA_SECTION_NODE) {
textFirstChild = true;
} else if (lType == Node.ENTITY_REFERENCE_NODE) {
if (!canModifyNext(firstChild)) {
return false;
} else {
//If the EntityReference child contains
//only text, or non-text or ends with a
//non-text node.
textFirstChild = true;
}
} else {
//If the first child was replaceable text and next
//children are not, then return false
if (textFirstChild) {
return false;
} else {
return true;
}
}
firstChild = firstChild.getNextSibling();
}
} else if (type == Node.TEXT_NODE
|| type == Node.CDATA_SECTION_NODE) {
//If the previous sibling was text or cdatasection move to next
} else {
//If the next sibling was anything but text or
//cdatasection or an entity reference, stop search and
//return true
return true;
}
next = next.getNextSibling();
}
return true;
}
/**
* Check if an EntityReference node has Text Only child nodes
*
* @param node
* @return true - Contains text only children
*/
private boolean hasTextOnlyChildren(Node node) {
Node child = node;
if (child == null) {
return false;
}
child = child.getFirstChild();
while (child != null) {
int type = child.getNodeType();
if (type == Node.ENTITY_REFERENCE_NODE) {
return hasTextOnlyChildren(child);
}
else if (type != Node.TEXT_NODE
&& type != Node.CDATA_SECTION_NODE
&& type != Node.ENTITY_REFERENCE_NODE) {
return false;
}
child = child.getNextSibling();
}
return true;
}
/**
* NON-DOM: Returns whether this Text is ignorable whitespace.
*/
public boolean isIgnorableWhitespace() {
if (needsSyncData()) {
synchronizeData();
}
return internalIsIgnorableWhitespace();
} // isIgnorableWhitespace():boolean
//
// Text methods
//
/**
* Break a text node into two sibling nodes. (Note that if the current node
* has no parent, they won't wind up as "siblings" -- they'll both be
* orphans.)
*
* @param offset
* The offset at which to split. If offset is at the end of the
* available data, the second node will be empty.
*
* @return A reference to the new node (containing data after the offset
* point). The original node will contain data up to that point.
*
* @throws DOMException(INDEX_SIZE_ERR)
* if offset is <0 or >length.
*
* @throws DOMException(NO_MODIFICATION_ALLOWED_ERR)
* if node is read-only.
*/
public Text splitText(int offset)
throws DOMException {
if (isReadOnly()) {
throw new DOMException(
DOMException.NO_MODIFICATION_ALLOWED_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NO_MODIFICATION_ALLOWED_ERR", null));
}
if (needsSyncData()) {
synchronizeData();
}
if (offset < 0 || offset > data.length() ) {
throw new DOMException(DOMException.INDEX_SIZE_ERR,
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "INDEX_SIZE_ERR", null));
}
// split text into two separate nodes
Text newText =
getOwnerDocument().createTextNode(data.substring(offset));
setNodeValue(data.substring(0, offset));
// insert new text node
Node parentNode = getParentNode();
if (parentNode != null) {
parentNode.insertBefore(newText, nextSibling);
}
return newText;
} // splitText(int):Text
/**
* NON-DOM (used by DOMParser): Reset data for the node.
*/
public void replaceData (String value){
data = value;
}
/**
* NON-DOM (used by DOMParser: Sets data to empty string.
* Returns the value the data was set to.
*/
public String removeData (){
String olddata=data;
data = "";
return olddata;
}
} // class TextImpl

View File

@@ -0,0 +1,508 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.TreeWalker;
/** This class implements the TreeWalker interface.
*
* @xerces.internal
*
*/
public class TreeWalkerImpl implements TreeWalker {
//
// Data
//
/** When TRUE, the children of entites references are returned in the iterator. */
private boolean fEntityReferenceExpansion = false;
/** The whatToShow mask. */
int fWhatToShow = NodeFilter.SHOW_ALL;
/** The NodeFilter reference. */
NodeFilter fNodeFilter;
/** The current Node. */
Node fCurrentNode;
/** The root Node. */
Node fRoot;
//
// Implementation Note: No state is kept except the data above
// (fWhatToShow, fNodeFilter, fCurrentNode, fRoot) such that
// setters could be created for these data values and the
// implementation will still work.
//
// Constructor
//
/** Public constructor */
public TreeWalkerImpl(Node root,
int whatToShow,
NodeFilter nodeFilter,
boolean entityReferenceExpansion) {
fCurrentNode = root;
fRoot = root;
fWhatToShow = whatToShow;
fNodeFilter = nodeFilter;
fEntityReferenceExpansion = entityReferenceExpansion;
}
public Node getRoot() {
return fRoot;
}
/** Return the whatToShow value */
public int getWhatToShow() {
return fWhatToShow;
}
public void setWhatShow(int whatToShow){
fWhatToShow = whatToShow;
}
/** Return the NodeFilter */
public NodeFilter getFilter() {
return fNodeFilter;
}
/** Return whether children entity references are included in the iterator. */
public boolean getExpandEntityReferences() {
return fEntityReferenceExpansion;
}
/** Return the current Node. */
public Node getCurrentNode() {
return fCurrentNode;
}
/** Return the current Node. */
public void setCurrentNode(Node node) {
if (node == null) {
String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null);
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
fCurrentNode = node;
}
/** Return the parent Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node parentNode() {
if (fCurrentNode == null) return null;
Node node = getParentNode(fCurrentNode);
if (node !=null) {
fCurrentNode = node;
}
return node;
}
/** Return the first child Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node firstChild() {
if (fCurrentNode == null) return null;
Node node = getFirstChild(fCurrentNode);
if (node !=null) {
fCurrentNode = node;
}
return node;
}
/** Return the last child Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node lastChild() {
if (fCurrentNode == null) return null;
Node node = getLastChild(fCurrentNode);
if (node !=null) {
fCurrentNode = node;
}
return node;
}
/** Return the previous sibling Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node previousSibling() {
if (fCurrentNode == null) return null;
Node node = getPreviousSibling(fCurrentNode);
if (node !=null) {
fCurrentNode = node;
}
return node;
}
/** Return the next sibling Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node nextSibling(){
if (fCurrentNode == null) return null;
Node node = getNextSibling(fCurrentNode);
if (node !=null) {
fCurrentNode = node;
}
return node;
}
/** Return the previous Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node previousNode() {
Node result;
if (fCurrentNode == null) return null;
// get sibling
result = getPreviousSibling(fCurrentNode);
if (result == null) {
result = getParentNode(fCurrentNode);
if (result != null) {
fCurrentNode = result;
return fCurrentNode;
}
return null;
}
// get the lastChild of result.
Node lastChild = getLastChild(result);
Node prev = lastChild ;
while (lastChild != null) {
prev = lastChild ;
lastChild = getLastChild(prev) ;
}
lastChild = prev ;
// if there is a lastChild which passes filters return it.
if (lastChild != null) {
fCurrentNode = lastChild;
return fCurrentNode;
}
// otherwise return the previous sibling.
if (result != null) {
fCurrentNode = result;
return fCurrentNode;
}
// otherwise return null.
return null;
}
/** Return the next Node from the current node,
* after applying filter, whatToshow.
* If result is not null, set the current Node.
*/
public Node nextNode() {
if (fCurrentNode == null) return null;
Node result = getFirstChild(fCurrentNode);
if (result != null) {
fCurrentNode = result;
return result;
}
result = getNextSibling(fCurrentNode);
if (result != null) {
fCurrentNode = result;
return result;
}
// return parent's 1st sibling.
Node parent = getParentNode(fCurrentNode);
while (parent != null) {
result = getNextSibling(parent);
if (result != null) {
fCurrentNode = result;
return result;
} else {
parent = getParentNode(parent);
}
}
// end , return null
return null;
}
/** Internal function.
* Return the parent Node, from the input node
* after applying filter, whatToshow.
* The current node is not consulted or set.
*/
Node getParentNode(Node node) {
if (node == null || node == fRoot) return null;
Node newNode = node.getParentNode();
if (newNode == null) return null;
int accept = acceptNode(newNode);
if (accept == NodeFilter.FILTER_ACCEPT)
return newNode;
else
//if (accept == NodeFilter.SKIP_NODE) // and REJECT too.
{
return getParentNode(newNode);
}
}
/** Internal function.
* Return the nextSibling Node, from the input node
* after applying filter, whatToshow.
* The current node is not consulted or set.
*/
Node getNextSibling(Node node) {
return getNextSibling(node, fRoot);
}
/** Internal function.
* Return the nextSibling Node, from the input node
* after applying filter, whatToshow.
* NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
* The current node is not consulted or set.
*/
Node getNextSibling(Node node, Node root) {
if (node == null || node == root) return null;
Node newNode = node.getNextSibling();
if (newNode == null) {
newNode = node.getParentNode();
if (newNode == null || newNode == root) return null;
int parentAccept = acceptNode(newNode);
if (parentAccept==NodeFilter.FILTER_SKIP) {
return getNextSibling(newNode, root);
}
return null;
}
int accept = acceptNode(newNode);
if (accept == NodeFilter.FILTER_ACCEPT)
return newNode;
else
if (accept == NodeFilter.FILTER_SKIP) {
Node fChild = getFirstChild(newNode);
if (fChild == null) {
return getNextSibling(newNode, root);
}
return fChild;
}
else
//if (accept == NodeFilter.REJECT_NODE)
{
return getNextSibling(newNode, root);
}
} // getNextSibling(Node node) {
/** Internal function.
* Return the previous sibling Node, from the input node
* after applying filter, whatToshow.
* The current node is not consulted or set.
*/
Node getPreviousSibling(Node node) {
return getPreviousSibling(node, fRoot);
}
/** Internal function.
* Return the previousSibling Node, from the input node
* after applying filter, whatToshow.
* NEVER TRAVERSES ABOVE THE SPECIFIED ROOT NODE.
* The current node is not consulted or set.
*/
Node getPreviousSibling(Node node, Node root) {
if (node == null || node == root) return null;
Node newNode = node.getPreviousSibling();
if (newNode == null) {
newNode = node.getParentNode();
if (newNode == null || newNode == root) return null;
int parentAccept = acceptNode(newNode);
if (parentAccept==NodeFilter.FILTER_SKIP) {
return getPreviousSibling(newNode, root);
}
return null;
}
int accept = acceptNode(newNode);
if (accept == NodeFilter.FILTER_ACCEPT)
return newNode;
else
if (accept == NodeFilter.FILTER_SKIP) {
Node fChild = getLastChild(newNode);
if (fChild == null) {
return getPreviousSibling(newNode, root);
}
return fChild;
}
else
//if (accept == NodeFilter.REJECT_NODE)
{
return getPreviousSibling(newNode, root);
}
} // getPreviousSibling(Node node) {
/** Internal function.
* Return the first child Node, from the input node
* after applying filter, whatToshow.
* The current node is not consulted or set.
*/
Node getFirstChild(Node node) {
if (node == null) return null;
if ( !fEntityReferenceExpansion
&& node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
return null;
Node newNode = node.getFirstChild();
if (newNode == null) return null;
int accept = acceptNode(newNode);
if (accept == NodeFilter.FILTER_ACCEPT)
return newNode;
else
if (accept == NodeFilter.FILTER_SKIP
&& newNode.hasChildNodes())
{
Node fChild = getFirstChild(newNode);
if (fChild == null) {
return getNextSibling(newNode, node);
}
return fChild;
}
else
//if (accept == NodeFilter.REJECT_NODE)
{
return getNextSibling(newNode, node);
}
}
/** Internal function.
* Return the last child Node, from the input node
* after applying filter, whatToshow.
* The current node is not consulted or set.
*/
Node getLastChild(Node node) {
if (node == null) return null;
if ( !fEntityReferenceExpansion
&& node.getNodeType() == Node.ENTITY_REFERENCE_NODE)
return null;
Node newNode = node.getLastChild();
if (newNode == null) return null;
int accept = acceptNode(newNode);
if (accept == NodeFilter.FILTER_ACCEPT)
return newNode;
else
if (accept == NodeFilter.FILTER_SKIP
&& newNode.hasChildNodes())
{
Node lChild = getLastChild(newNode);
if (lChild == null) {
return getPreviousSibling(newNode, node);
}
return lChild;
}
else
//if (accept == NodeFilter.REJECT_NODE)
{
return getPreviousSibling(newNode, node);
}
}
/** Internal function.
* The node whatToShow and the filter are combined into one result. */
short acceptNode(Node node) {
/***
7.1.2.4. Filters and whatToShow flags
Iterator and TreeWalker apply whatToShow flags before applying Filters. If a node is rejected by the
active whatToShow flags, a Filter will not be called to evaluate that node. When a node is rejected by
the active whatToShow flags, children of that node will still be considered, and Filters may be called to
evaluate them.
***/
if (fNodeFilter == null) {
if ( ( fWhatToShow & (1 << node.getNodeType()-1)) != 0) {
return NodeFilter.FILTER_ACCEPT;
} else {
return NodeFilter.FILTER_SKIP;
}
} else {
if ((fWhatToShow & (1 << node.getNodeType()-1)) != 0 ) {
return fNodeFilter.acceptNode(node);
} else {
// What to show has failed. See above excerpt from spec.
// Equivalent to FILTER_SKIP.
return NodeFilter.FILTER_SKIP;
}
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom.events;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventTarget;
/**
* EventImpl is an implementation of the basic "generic" DOM Level 2 Event
* object. It may be subclassed by more specialized event sets.
* Note that in our implementation, events are re-dispatchable (dispatch
* clears the stopPropagation and preventDefault flags before it starts);
* I believe that is the DOM's intent but I don't see an explicit statement
* to this effect.
*
* @xerces.internal
*
*/
public class EventImpl implements Event
{
public String type=null;
public EventTarget target;
public EventTarget currentTarget;
public short eventPhase;
public boolean initialized=false, bubbles=true, cancelable=false;
public boolean stopPropagation=false, preventDefault=false;
protected long timeStamp = System.currentTimeMillis();
/** The DOM doesn't deal with constructors, so instead we have an
initializer call to set most of the read-only fields. The
others are set, and reset, by the event subsystem during dispatch.
<p>
Note that init() -- and the subclass-specific initWhatever() calls --
may be reinvoked. At least one initialization is required; repeated
initializations overwrite the event with new values of their
parameters.
*/
public void initEvent(String eventTypeArg, boolean canBubbleArg,
boolean cancelableArg)
{
type=eventTypeArg;
bubbles=canBubbleArg;
cancelable=cancelableArg;
initialized=true;
}
/** @return true iff this Event is of a class and type which supports
bubbling. In the generic case, this is True.
*/
public boolean getBubbles()
{
return bubbles;
}
/** @return true iff this Event is of a class and type which (a) has a
Default Behavior in this DOM, and (b)allows cancellation (blocking)
of that behavior. In the generic case, this is False.
*/
public boolean getCancelable()
{
return cancelable;
}
/** @return the Node (EventTarget) whose EventListeners are currently
being processed. During capture and bubble phases, this may not be
the target node. */
public EventTarget getCurrentTarget()
{
return currentTarget;
}
/** @return the current processing phase for this event --
CAPTURING_PHASE, AT_TARGET, BUBBLING_PHASE. (There may be
an internal DEFAULT_PHASE as well, but the users won't see it.) */
public short getEventPhase()
{
return eventPhase;
}
/** @return the EventTarget (Node) to which the event was originally
dispatched.
*/
public EventTarget getTarget()
{
return target;
}
/** @return event name as a string
*/
public String getType()
{
return type;
}
public long getTimeStamp() {
return timeStamp;
}
/** Causes exit from in-progress event dispatch before the next
currentTarget is selected. Replaces the preventBubble() and
preventCapture() methods which were present in early drafts;
they may be reintroduced in future levels of the DOM. */
public void stopPropagation()
{
stopPropagation=true;
}
/** Prevents any default processing built into the target node from
occurring.
*/
public void preventDefault()
{
preventDefault=true;
}
}

View File

@@ -0,0 +1,113 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.dom.events;
import org.w3c.dom.Node;
import org.w3c.dom.events.MutationEvent;
/**
* @xerces.internal
*
*/
public class MutationEventImpl
extends com.sun.org.apache.xerces.internal.dom.events.EventImpl
implements MutationEvent
{
Node relatedNode=null;
String prevValue=null,newValue=null,attrName=null;
// REVISIT: The DOM Level 2 PR has a bug: the init method should let this
// attribute be specified. Since it doesn't we have to give write access.
public short attrChange;
// NON-DOM CONSTANTS: Storage efficiency, avoid risk of typos.
public static final String DOM_SUBTREE_MODIFIED = "DOMSubtreeModified";
public static final String DOM_NODE_INSERTED = "DOMNodeInserted";
public static final String DOM_NODE_REMOVED = "DOMNodeRemoved";
public static final String DOM_NODE_REMOVED_FROM_DOCUMENT = "DOMNodeRemovedFromDocument";
public static final String DOM_NODE_INSERTED_INTO_DOCUMENT = "DOMNodeInsertedIntoDocument";
public static final String DOM_ATTR_MODIFIED = "DOMAttrModified";
public static final String DOM_CHARACTER_DATA_MODIFIED = "DOMCharacterDataModified";
/** @return the name of the Attr which
changed, for DOMAttrModified events.
Undefined for others.
*/
public String getAttrName()
{
return attrName;
}
/**
* <code>attrChange</code> indicates the type of change which triggered
* the DOMAttrModified event. The values can be <code>MODIFICATION</code>
* , <code>ADDITION</code>, or <code>REMOVAL</code>.
*/
public short getAttrChange()
{
return attrChange;
}
/** @return the new string value of the Attr for DOMAttrModified events, or
of the CharacterData node for DOMCharDataModifed events.
Undefined for others.
*/
public String getNewValue()
{
return newValue;
}
/** @return the previous string value of the Attr for DOMAttrModified events, or
of the CharacterData node for DOMCharDataModifed events.
Undefined for others.
*/
public String getPrevValue()
{
return prevValue;
}
/** @return a Node related to this event, other than the target that the
node was dispatched to. For DOMNodeRemoved, it is the node which
was removed.
No other uses are currently defined.
*/
public Node getRelatedNode()
{
return relatedNode;
}
/** Initialize a mutation event, or overwrite the event's current
settings with new values of the parameters.
*/
public void initMutationEvent(String typeArg, boolean canBubbleArg,
boolean cancelableArg, Node relatedNodeArg, String prevValueArg,
String newValueArg, String attrNameArg, short attrChangeArg)
{
relatedNode=relatedNodeArg;
prevValue=prevValueArg;
newValue=newValueArg;
attrName=attrNameArg;
attrChange=attrChangeArg;
super.initEvent(typeArg,canBubbleArg,cancelableArg);
}
}

View File

@@ -0,0 +1,940 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import java.util.Enumeration;
import java.util.NoSuchElementException;
/**
* Commonly used constants.
*
* @xerces.internal
*
* @author Andy Clark, IBM
*
*/
public final class Constants {
//
// Constants
//
// Schema Types:
public static final String NS_XMLSCHEMA = "http://www.w3.org/2001/XMLSchema".intern();
public static final String NS_DTD = "http://www.w3.org/TR/REC-xml".intern();
// Schema features
public static final String SUN_SCHEMA_FEATURE_PREFIX = "http://java.sun.com/xml/schema/features/";
public static final String SUN_REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE = "report-ignored-element-content-whitespace";
//stax properties
public static final String ZEPHYR_PROPERTY_PREFIX = "http://java.sun.com/xml/stream/properties/" ;
public static final String STAX_PROPERTIES = "stax-properties" ;
public static final String STAX_ENTITY_RESOLVER_PROPERTY = "internal/stax-entity-resolver";
public static final String STAX_REPORT_CDATA_EVENT = "report-cdata-event";
public static final String READER_IN_DEFINED_STATE = ZEPHYR_PROPERTY_PREFIX + "reader-in-defined-state" ;
public static final String ADD_NAMESPACE_DECL_AS_ATTRIBUTE = "add-namespacedecl-as-attrbiute";
public static final String ESCAPE_CHARACTERS = "escapeCharacters";
public static final String REUSE_INSTANCE = "reuse-instance" ;
//DOM properties
public static final String SUN_DOM_PROPERTY_PREFIX = "http://java.sun.com/xml/dom/properties/" ;
public static final String SUN_DOM_ANCESTOR_CHECCK = "ancestor-check";
/**
* If true, ignore DOCTYPE declaration as if it wasn't present at all.
* Note that this is a violation of the XML recommendation.
* The full property name is prefixed by {@link #ZEPHYR_PROPERTY_PREFIX}.
*/
public static final String IGNORE_EXTERNAL_DTD = "ignore-external-dtd";
// sax features
/** SAX feature prefix ("http://xml.org/sax/features/"). */
public static final String SAX_FEATURE_PREFIX = "http://xml.org/sax/features/";
public static final String NAMESPACES_FEATURE = "namespaces";
/** Namespace prefixes feature ("namespace-prefixes"). */
public static final String NAMESPACE_PREFIXES_FEATURE = "namespace-prefixes";
/** String interning feature ("string-interning"). */
public static final String STRING_INTERNING_FEATURE = "string-interning";
/** Validation feature ("validation"). */
public static final String VALIDATION_FEATURE = "validation";
/** External general entities feature ("external-general-entities "). */
public static final String EXTERNAL_GENERAL_ENTITIES_FEATURE = "external-general-entities";
/** External parameter entities feature ("external-parameter-entities "). */
public static final String EXTERNAL_PARAMETER_ENTITIES_FEATURE = "external-parameter-entities";
/** Lexical handler parameter entities feature ("lexical-handler/parameter-entities"). */
public static final String LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE = "lexical-handler/parameter-entities";
/** Is standalone feature ("is-standalone"). */
public static final String IS_STANDALONE_FEATURE = "is-standalone";
/** Resolve DTD URIs feature ("resolve-dtd-uris"). */
public static final String RESOLVE_DTD_URIS_FEATURE = "resolve-dtd-uris";
/** Use Attributes2 feature ("use-attributes2"). */
public static final String USE_ATTRIBUTES2_FEATURE = "use-attributes2";
/** Use Locator2 feature ("use-locator2"). */
public static final String USE_LOCATOR2_FEATURE = "use-locator2";
/** Use EntityResolver2 feature ("use-entity-resolver2"). */
public static final String USE_ENTITY_RESOLVER2_FEATURE = "use-entity-resolver2";
/** Unicode normalization checking feature ("unicode-normalization-checking"). */
public static final String UNICODE_NORMALIZATION_CHECKING_FEATURE = "unicode-normalization-checking";
/** xmlns URIs feature ("xmlns-uris"). */
public static final String XMLNS_URIS_FEATURE = "xmlns-uris";
/** XML 1.1 feature ("xml-1.1"). */
public static final String XML_11_FEATURE = "xml-1.1";
/** Allow unparsed entity and notation declaration events to be sent after the end DTD event ("allow-dtd-events-after-endDTD") */
public static final String ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE = "allow-dtd-events-after-endDTD";
// sax properties
/** SAX property prefix ("http://xml.org/sax/properties/"). */
public static final String SAX_PROPERTY_PREFIX = "http://xml.org/sax/properties/";
/** Declaration handler property ("declaration-handler"). */
public static final String DECLARATION_HANDLER_PROPERTY = "declaration-handler";
/** Lexical handler property ("lexical-handler"). */
public static final String LEXICAL_HANDLER_PROPERTY = "lexical-handler";
/** DOM node property ("dom-node"). */
public static final String DOM_NODE_PROPERTY = "dom-node";
/** XML string property ("xml-string"). */
public static final String XML_STRING_PROPERTY = "xml-string";
public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
// Oracle Feature:
/**
* <p>Use Service Mechanism</p>
*
* <ul>
* <li>
* {@code true} instruct an object to use service mechanism to
* find a service implementation. This is the default behavior.
* </li>
* <li>
* {@code false} instruct an object to skip service mechanism and
* use the default implementation for that service.
* </li>
* </ul>
*/
public static final String ORACLE_FEATURE_SERVICE_MECHANISM = "http://www.oracle.com/feature/use-service-mechanism";
/** Document XML version property ("document-xml-version"). */
public static final String DOCUMENT_XML_VERSION_PROPERTY = "document-xml-version";
//
// JAXP properties
//
/** JAXP property prefix ("http://java.sun.com/xml/jaxp/properties/"). */
public static final String JAXP_PROPERTY_PREFIX =
"http://java.sun.com/xml/jaxp/properties/";
/** JAXP schemaSource property: when used internally may include DTD sources (DOM) */
public static final String SCHEMA_SOURCE = "schemaSource";
/** JAXP schemaSource language: when used internally may include DTD namespace (DOM) */
public static final String SCHEMA_LANGUAGE = "schemaLanguage";
/** JAXP Standard property prefix ("http://javax.xml.XMLConstants/property/"). */
public static final String JAXPAPI_PROPERTY_PREFIX =
"http://javax.xml.XMLConstants/property/";
/** Oracle JAXP property prefix ("http://www.oracle.com/xml/jaxp/properties/"). */
public static final String ORACLE_JAXP_PROPERTY_PREFIX =
"http://www.oracle.com/xml/jaxp/properties/";
public static final String XML_SECURITY_PROPERTY_MANAGER =
ORACLE_JAXP_PROPERTY_PREFIX + "xmlSecurityPropertyManager";
//System Properties corresponding to ACCESS_EXTERNAL_* properties
public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD";
public static final String SP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema";
//all access keyword
public static final String ACCESS_EXTERNAL_ALL = "all";
/**
* Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true
*/
public static final String EXTERNAL_ACCESS_DEFAULT_FSP = "";
/**
* FEATURE_SECURE_PROCESSING (FSP) is true by default
*/
public static final String EXTERNAL_ACCESS_DEFAULT = ACCESS_EXTERNAL_ALL;
/**
* Check if we're in jdk8 or above
*/
public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8);
//
// Implementation limits: corresponding System Properties of the above
// API properties
//
/**
* JDK entity expansion limit; Note that the existing system property
* "entityExpansionLimit" with no prefix is still observed
*/
public static final String JDK_ENTITY_EXPANSION_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "entityExpansionLimit";
/**
* JDK element attribute limit; Note that the existing system property
* "elementAttributeLimit" with no prefix is still observed
*/
public static final String JDK_ELEMENT_ATTRIBUTE_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "elementAttributeLimit";
/**
* JDK maxOccur limit; Note that the existing system property
* "maxOccurLimit" with no prefix is still observed
*/
public static final String JDK_MAX_OCCUR_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "maxOccurLimit";
/**
* JDK total entity size limit
*/
public static final String JDK_TOTAL_ENTITY_SIZE_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "totalEntitySizeLimit";
/**
* JDK maximum general entity size limit
*/
public static final String JDK_GENERAL_ENTITY_SIZE_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "maxGeneralEntitySizeLimit";
/**
* JDK node count limit in entities that limits the total number of nodes
* in all of entity references.
*/
public static final String JDK_ENTITY_REPLACEMENT_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "entityReplacementLimit";
/**
* JDK maximum parameter entity size limit
*/
public static final String JDK_PARAMETER_ENTITY_SIZE_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "maxParameterEntitySizeLimit";
/**
* JDK maximum XML name limit
*/
public static final String JDK_XML_NAME_LIMIT =
ORACLE_JAXP_PROPERTY_PREFIX + "maxXMLNameLimit";
/**
* JDK maxElementDepth limit
*/
public static final String JDK_MAX_ELEMENT_DEPTH =
ORACLE_JAXP_PROPERTY_PREFIX + "maxElementDepth";
/**
* JDK property to allow printing out information from the limit analyzer
*/
public static final String JDK_ENTITY_COUNT_INFO =
ORACLE_JAXP_PROPERTY_PREFIX + "getEntityCountInfo";
//
// Implementation limits: API properties
//
/**
* JDK entity expansion limit; Note that the existing system property
* "entityExpansionLimit" with no prefix is still observed
*/
public static final String SP_ENTITY_EXPANSION_LIMIT = "jdk.xml.entityExpansionLimit";
/**
* JDK element attribute limit; Note that the existing system property
* "elementAttributeLimit" with no prefix is still observed
*/
public static final String SP_ELEMENT_ATTRIBUTE_LIMIT = "jdk.xml.elementAttributeLimit";
/**
* JDK maxOccur limit; Note that the existing system property
* "maxOccurLimit" with no prefix is still observed
*/
public static final String SP_MAX_OCCUR_LIMIT = "jdk.xml.maxOccurLimit";
/**
* JDK total entity size limit
*/
public static final String SP_TOTAL_ENTITY_SIZE_LIMIT = "jdk.xml.totalEntitySizeLimit";
/**
* JDK maximum general entity size limit
*/
public static final String SP_GENERAL_ENTITY_SIZE_LIMIT = "jdk.xml.maxGeneralEntitySizeLimit";
/**
* JDK node count limit in entities that limits the total number of nodes
* in all of entity references.
*/
public static final String SP_ENTITY_REPLACEMENT_LIMIT = "jdk.xml.entityReplacementLimit";
/**
* JDK maximum parameter entity size limit
*/
public static final String SP_PARAMETER_ENTITY_SIZE_LIMIT = "jdk.xml.maxParameterEntitySizeLimit";
/**
* JDK maximum XML name limit
*/
public static final String SP_XML_NAME_LIMIT = "jdk.xml.maxXMLNameLimit";
/**
* JDK maxElementDepth limit
*/
public static final String SP_MAX_ELEMENT_DEPTH = "jdk.xml.maxElementDepth";
//legacy System Properties
public final static String ENTITY_EXPANSION_LIMIT = "entityExpansionLimit";
public static final String ELEMENT_ATTRIBUTE_LIMIT = "elementAttributeLimit" ;
public final static String MAX_OCCUR_LIMIT = "maxOccurLimit";
/**
* A string "yes" that can be used for properties such as getEntityCountInfo
*/
public static final String JDK_YES = "yes";
//
// DOM features
//
/** Comments feature ("include-comments"). */
public static final String INCLUDE_COMMENTS_FEATURE = "include-comments";
/** Create cdata nodes feature ("create-cdata-nodes"). */
public static final String CREATE_CDATA_NODES_FEATURE = "create-cdata-nodes";
/** Feature id: load as infoset. */
public static final String LOAD_AS_INFOSET = "load-as-infoset";
//
// Constants: DOM Level 3 feature ids
//
public static final String DOM_CANONICAL_FORM = "canonical-form";
public static final String DOM_CDATA_SECTIONS ="cdata-sections";
public static final String DOM_COMMENTS = "comments";
// REVISIT: this feature seems to have no effect for Xerces
public static final String DOM_CHARSET_OVERRIDES_XML_ENCODING =
"charset-overrides-xml-encoding";
public static final String DOM_DATATYPE_NORMALIZATION = "datatype-normalization";
public static final String DOM_ENTITIES = "entities";
public static final String DOM_INFOSET = "infoset";
public static final String DOM_NAMESPACES = "namespaces";
public static final String DOM_NAMESPACE_DECLARATIONS = "namespace-declarations";
public static final String DOM_SUPPORTED_MEDIATYPES_ONLY =
"supported-media-types-only";
public static final String DOM_VALIDATE_IF_SCHEMA = "validate-if-schema";
public static final String DOM_VALIDATE = "validate";
public static final String DOM_ELEMENT_CONTENT_WHITESPACE =
"element-content-whitespace";
// DOM Level 3 features defined in Core:
public static final String DOM_DISCARD_DEFAULT_CONTENT = "discard-default-content";
public static final String DOM_NORMALIZE_CHARACTERS = "normalize-characters";
public static final String DOM_CHECK_CHAR_NORMALIZATION = "check-character-normalization";
public static final String DOM_WELLFORMED = "well-formed";
public static final String DOM_SPLIT_CDATA = "split-cdata-sections";
// Load and Save
public static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
public static final String DOM_XMLDECL = "xml-declaration";
public static final String DOM_UNKNOWNCHARS = "unknown-characters";
public static final String DOM_CERTIFIED = "certified";
public static final String DOM_DISALLOW_DOCTYPE = "disallow-doctype";
public static final String DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS = "ignore-unknown-character-denormalizations";
// DOM Properties
public static final String DOM_RESOURCE_RESOLVER = "resource-resolver";
public static final String DOM_ERROR_HANDLER = "error-handler";
public static final String DOM_SCHEMA_TYPE = "schema-type";
public static final String DOM_SCHEMA_LOCATION = "schema-location";
public static final String DOM_ANCESTOR_CHECCK = "ancestor-check";
// XSModel
public static final String DOM_PSVI = "psvi";
// xerces features
/** Xerces features prefix ("http://apache.org/xml/features/"). */
public static final String XERCES_FEATURE_PREFIX = "http://apache.org/xml/features/";
/** Schema validation feature ("validation/schema"). */
public static final String SCHEMA_VALIDATION_FEATURE = "validation/schema";
/** Expose schema normalized values */
public static final String SCHEMA_NORMALIZED_VALUE = "validation/schema/normalized-value";
/** Send schema default value via characters() */
public static final String SCHEMA_ELEMENT_DEFAULT = "validation/schema/element-default";
/** Schema full constraint checking ("validation/schema-full-checking"). */
public static final String SCHEMA_FULL_CHECKING = "validation/schema-full-checking";
/** Augment Post-Schema-Validation-Infoset */
public static final String SCHEMA_AUGMENT_PSVI = "validation/schema/augment-psvi";
/** Dynamic validation feature ("validation/dynamic"). */
public static final String DYNAMIC_VALIDATION_FEATURE = "validation/dynamic";
/** Warn on duplicate attribute declaration feature ("validation/warn-on-duplicate-attdef"). */
public static final String WARN_ON_DUPLICATE_ATTDEF_FEATURE = "validation/warn-on-duplicate-attdef";
/** Warn on undeclared element feature ("validation/warn-on-undeclared-elemdef"). */
public static final String WARN_ON_UNDECLARED_ELEMDEF_FEATURE = "validation/warn-on-undeclared-elemdef";
/** Warn on duplicate entity declaration feature ("warn-on-duplicate-entitydef"). */
public static final String WARN_ON_DUPLICATE_ENTITYDEF_FEATURE = "warn-on-duplicate-entitydef";
/** Allow Java encoding names feature ("allow-java-encodings"). */
public static final String ALLOW_JAVA_ENCODINGS_FEATURE = "allow-java-encodings";
/** Disallow DOCTYPE declaration feature ("disallow-doctype-decl"). */
public static final String DISALLOW_DOCTYPE_DECL_FEATURE = "disallow-doctype-decl";
/** Continue after fatal error feature ("continue-after-fatal-error"). */
public static final String CONTINUE_AFTER_FATAL_ERROR_FEATURE = "continue-after-fatal-error";
/** Load dtd grammar when nonvalidating feature ("nonvalidating/load-dtd-grammar"). */
public static final String LOAD_DTD_GRAMMAR_FEATURE = "nonvalidating/load-dtd-grammar";
/** Load external dtd when nonvalidating feature ("nonvalidating/load-external-dtd"). */
public static final String LOAD_EXTERNAL_DTD_FEATURE = "nonvalidating/load-external-dtd";
/** Defer node expansion feature ("dom/defer-node-expansion"). */
public static final String DEFER_NODE_EXPANSION_FEATURE = "dom/defer-node-expansion";
/** Create entity reference nodes feature ("dom/create-entity-ref-nodes"). */
public static final String CREATE_ENTITY_REF_NODES_FEATURE = "dom/create-entity-ref-nodes";
/** Include ignorable whitespace feature ("dom/include-ignorable-whitespace"). */
public static final String INCLUDE_IGNORABLE_WHITESPACE = "dom/include-ignorable-whitespace";
/** Default attribute values feature ("validation/default-attribute-values"). */
public static final String DEFAULT_ATTRIBUTE_VALUES_FEATURE = "validation/default-attribute-values";
/** Validate content models feature ("validation/validate-content-models"). */
public static final String VALIDATE_CONTENT_MODELS_FEATURE = "validation/validate-content-models";
/** Validate datatypes feature ("validation/validate-datatypes"). */
public static final String VALIDATE_DATATYPES_FEATURE = "validation/validate-datatypes";
/** Balance syntax trees feature ("validation/balance-syntax-trees"). */
public static final String BALANCE_SYNTAX_TREES = "validation/balance-syntax-trees";
/** Notify character references feature (scanner/notify-char-refs"). */
public static final String NOTIFY_CHAR_REFS_FEATURE = "scanner/notify-char-refs";
/** Notify built-in (&amp;amp;, etc.) references feature (scanner/notify-builtin-refs"). */
public static final String NOTIFY_BUILTIN_REFS_FEATURE = "scanner/notify-builtin-refs";
/** Standard URI conformant feature ("standard-uri-conformant"). */
public static final String STANDARD_URI_CONFORMANT_FEATURE = "standard-uri-conformant";
/** Generate synthetic annotations feature ("generate-synthetic-annotations"). */
public static final String GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE = "generate-synthetic-annotations";
/** Validate annotations feature ("validate-annotations"). */
public static final String VALIDATE_ANNOTATIONS_FEATURE = "validate-annotations";
/** Honour all schemaLocations feature ("honour-all-schemaLocations"). */
public static final String HONOUR_ALL_SCHEMALOCATIONS_FEATURE = "honour-all-schemaLocations";
/** Namespace growth feature ("namespace-growth"). */
public static final String NAMESPACE_GROWTH_FEATURE = "namespace-growth";
/** Tolerate duplicates feature ("internal/tolerate-duplicates"). */
public static final String TOLERATE_DUPLICATES_FEATURE = "internal/tolerate-duplicates";
/** XInclude processing feature ("xinclude"). */
public static final String XINCLUDE_FEATURE = "xinclude";
/** XInclude fixup base URIs feature ("xinclude/fixup-base-uris"). */
public static final String XINCLUDE_FIXUP_BASE_URIS_FEATURE = "xinclude/fixup-base-uris";
/** XInclude fixup language feature ("xinclude/fixup-language"). */
public static final String XINCLUDE_FIXUP_LANGUAGE_FEATURE = "xinclude/fixup-language";
/**
* Internal feature. When set to true the schema validator will only use
* schema components from the grammar pool provided.
*/
public static final String USE_GRAMMAR_POOL_ONLY_FEATURE = "internal/validation/schema/use-grammar-pool-only";
/** Internal performance related feature:
* false - the parser settings (features/properties) have not changed between 2 parses
* true - the parser settings have changed between 2 parses
* NOTE: this feature should only be set by the parser configuration.
*/
public static final String PARSER_SETTINGS = "internal/parser-settings";
/** Feature to make XML Processor XInclude Aware */
public static final String XINCLUDE_AWARE = "xinclude-aware";
/** Ignore xsi:schemaLocation and xsi:noNamespaceSchemaLocation. */
public static final String IGNORE_SCHEMA_LOCATION_HINTS = "validation/schema/ignore-schema-location-hints";
/**
* When true, the schema processor will change characters events
* to ignorableWhitespaces events, when characters are expected to
* only contain ignorable whitespaces.
*/
public static final String CHANGE_IGNORABLE_CHARACTERS_INTO_IGNORABLE_WHITESPACES =
"validation/change-ignorable-characters-into-ignorable-whitespaces";
// xerces properties
/** Xerces properties prefix ("http://apache.org/xml/properties/"). */
public static final String XERCES_PROPERTY_PREFIX = "http://apache.org/xml/properties/";
/** Current element node property ("dom/current-element-node"). */
public static final String CURRENT_ELEMENT_NODE_PROPERTY = "dom/current-element-node";
/** Document class name property ("dom/document-class-name"). */
public static final String DOCUMENT_CLASS_NAME_PROPERTY = "dom/document-class-name";
/** Symbol table property ("internal/symbol-table"). */
public static final String SYMBOL_TABLE_PROPERTY = "internal/symbol-table";
/** Error reporter property ("internal/error-reporter"). */
public static final String ERROR_REPORTER_PROPERTY = "internal/error-reporter";
/** Error handler property ("internal/error-handler"). */
public static final String ERROR_HANDLER_PROPERTY = "internal/error-handler";
/** XInclude handler property ("internal/xinclude-handler"). */
public static final String XINCLUDE_HANDLER_PROPERTY = "internal/xinclude-handler";
/** XPointer handler property ("internal/xpointer-handler"). */
public static final String XPOINTER_HANDLER_PROPERTY = "internal/xpointer-handler";
/** Entity manager property ("internal/entity-manager"). */
public static final String ENTITY_MANAGER_PROPERTY = "internal/entity-manager";
/** Input buffer size property ("input-buffer-size"). */
public static final String BUFFER_SIZE_PROPERTY = "input-buffer-size";
/** Security manager property ("security-manager"). */
public static final String SECURITY_MANAGER_PROPERTY = "security-manager";
/** Locale property ("locale"). */
public static final String LOCALE_PROPERTY = "locale";
/** property identifier: security manager. */
public static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
public static final String ENTITY_RESOLVER_PROPERTY = "internal/entity-resolver";
/** Grammar pool property ("internal/grammar-pool"). */
public static final String XMLGRAMMAR_POOL_PROPERTY = "internal/grammar-pool";
/** Datatype validator factory ("internal/datatype-validator-factory"). */
public static final String DATATYPE_VALIDATOR_FACTORY_PROPERTY = "internal/datatype-validator-factory";
/** Document scanner property ("internal/document-scanner"). */
public static final String DOCUMENT_SCANNER_PROPERTY = "internal/document-scanner";
/** DTD scanner property ("internal/dtd-scanner"). */
public static final String DTD_SCANNER_PROPERTY = "internal/dtd-scanner";
/** DTD processor property ("internal/dtd-processor"). */
public static final String DTD_PROCESSOR_PROPERTY = "internal/dtd-processor";
/** Validator property ("internal/validator"). */
public static final String VALIDATOR_PROPERTY = "internal/validator";
/** Validator property ("internal/validator/dtd"). */
public static final String DTD_VALIDATOR_PROPERTY = "internal/validator/dtd";
/** Validator property ("internal/validator/schema"). */
public static final String SCHEMA_VALIDATOR_PROPERTY = "internal/validator/schema";
/** No namespace schema location property ("schema/external-schemaLocation"). */
public static final String SCHEMA_LOCATION = "schema/external-schemaLocation";
/** Schema location property ("schema/external-noNamespaceSchemaLocation"). */
public static final String SCHEMA_NONS_LOCATION = "schema/external-noNamespaceSchemaLocation";
/** Namespace binder property ("internal/namespace-binder"). */
public static final String NAMESPACE_BINDER_PROPERTY = "internal/namespace-binder";
/** Namespace context property ("internal/namespace-context"). */
public static final String NAMESPACE_CONTEXT_PROPERTY = "internal/namespace-context";
/** Validation manager property ("internal/validation-manager"). */
public static final String VALIDATION_MANAGER_PROPERTY = "internal/validation-manager";
/** XPointer Schema property ("xpointer-schema"). */
public static final String XPOINTER_SCHEMA_PROPERTY = "xpointer-schema";
/** Schema element declaration for the root element in a document ("internal/validation/schema/dv-factory"). */
public static final String SCHEMA_DV_FACTORY_PROPERTY = "internal/validation/schema/dv-factory";
// general constants
/** Element PSVI is stored in augmentations using string "ELEMENT_PSVI" */
public final static String ELEMENT_PSVI = "ELEMENT_PSVI";
/** Attribute PSVI is stored in augmentations using string "ATTRIBUTE_PSVI" */
public final static String ATTRIBUTE_PSVI = "ATTRIBUTE_PSVI";
/**
* Boolean indicating whether an attribute is declared in the DTD is stored
* in augmentations using the string "ATTRIBUTE_DECLARED". The absence of this
* augmentation indicates that the attribute was not declared in the DTD.
*/
public final static String ATTRIBUTE_DECLARED = "ATTRIBUTE_DECLARED";
/**
* {@link org.w3c.dom.TypeInfo} associated with current element/attribute
* is stored in augmentations using this string as the key.
*
* This will ultimately controls {@link com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser}
* regarding what object the DOM will return from
* {@link org.w3c.dom.Attr#getSchemaTypeInfo()} and
* {@link org.w3c.dom.Element#getSchemaTypeInfo()} and
*/
public final static String TYPEINFO = "org.w3c.dom.TypeInfo";
/**
* Whether an attribute is an id or not is stored in augmentations
* using this string as the key. The value is {@link Boolean#TRUE}
* or {@link Boolean#FALSE}.
*
* This will ultimately controls {@link com.sun.org.apache.xerces.internal.parsers.AbstractDOMParser}
* about whether it will mark an attribute as ID or not.
*/
public final static String ID_ATTRIBUTE = "ID_ATTRIBUTE";
// XML version constants
/**
* Boolean indicating whether an entity referenced in the document has
* not been read is stored in augmentations using the string "ENTITY_SKIPPED".
* The absence of this augmentation indicates that the entity had a
* declaration and was expanded.
*/
public final static String ENTITY_SKIPPED = "ENTITY_SKIPPED";
/**
* Boolean indicating whether a character is a probable white space
* character (ch <= 0x20) that was the replacement text of a character
* reference is stored in augmentations using the string "CHAR_REF_PROBABLE_WS".
* The absence of this augmentation indicates that the character is not
* probable white space and/or was not included from a character reference.
*/
public final static String CHAR_REF_PROBABLE_WS = "CHAR_REF_PROBABLE_WS";
/** Boolean indicating if this entity is the last opened entity.
*
*@see com.sun.org.apache.xerces.internal.impl.XMLEntityManager#endEntity()
*@see com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl#endEntity()
*@see com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl#endEntity()
*/
public final static String LAST_ENTITY = "LAST_ENTITY";
// XML version constants
public final static short XML_VERSION_ERROR = -1;
public final static short XML_VERSION_1_0 = 1;
public final static short XML_VERSION_1_1 = 2;
// DOM related constants
public final static String ANONYMOUS_TYPE_NAMESPACE =
"http://apache.org/xml/xmlschema/1.0/anonymousTypes";
// Constant to enable Schema 1.1 support
public final static boolean SCHEMA_1_1_SUPPORT = false;
public final static short SCHEMA_VERSION_1_0 = 1;
public final static short SCHEMA_VERSION_1_0_EXTENDED = 2;
// private
/** SAX features. */
private static final String[] fgSAXFeatures = {
NAMESPACES_FEATURE,
NAMESPACE_PREFIXES_FEATURE,
STRING_INTERNING_FEATURE,
VALIDATION_FEATURE,
EXTERNAL_GENERAL_ENTITIES_FEATURE,
EXTERNAL_PARAMETER_ENTITIES_FEATURE,
};
/** SAX properties. */
private static final String[] fgSAXProperties = {
DECLARATION_HANDLER_PROPERTY,
LEXICAL_HANDLER_PROPERTY,
DOM_NODE_PROPERTY,
XML_STRING_PROPERTY,
};
/** Xerces features. */
private static final String[] fgXercesFeatures = {
SCHEMA_VALIDATION_FEATURE,
SCHEMA_FULL_CHECKING,
DYNAMIC_VALIDATION_FEATURE,
WARN_ON_DUPLICATE_ATTDEF_FEATURE,
WARN_ON_UNDECLARED_ELEMDEF_FEATURE,
ALLOW_JAVA_ENCODINGS_FEATURE,
CONTINUE_AFTER_FATAL_ERROR_FEATURE,
LOAD_DTD_GRAMMAR_FEATURE,
LOAD_EXTERNAL_DTD_FEATURE,
//DEFER_NODE_EXPANSION_FEATURE,
CREATE_ENTITY_REF_NODES_FEATURE,
XINCLUDE_AWARE,
INCLUDE_IGNORABLE_WHITESPACE,
//GRAMMAR_ACCESS_FEATURE,
DEFAULT_ATTRIBUTE_VALUES_FEATURE,
VALIDATE_CONTENT_MODELS_FEATURE,
VALIDATE_DATATYPES_FEATURE,
BALANCE_SYNTAX_TREES,
NOTIFY_CHAR_REFS_FEATURE,
NOTIFY_BUILTIN_REFS_FEATURE,
DISALLOW_DOCTYPE_DECL_FEATURE,
STANDARD_URI_CONFORMANT_FEATURE,
GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE,
VALIDATE_ANNOTATIONS_FEATURE,
HONOUR_ALL_SCHEMALOCATIONS_FEATURE,
XINCLUDE_FEATURE,
XINCLUDE_FIXUP_BASE_URIS_FEATURE,
XINCLUDE_FIXUP_LANGUAGE_FEATURE,
NAMESPACE_GROWTH_FEATURE,
TOLERATE_DUPLICATES_FEATURE,
};
/** Xerces properties. */
private static final String[] fgXercesProperties = {
CURRENT_ELEMENT_NODE_PROPERTY,
DOCUMENT_CLASS_NAME_PROPERTY,
SYMBOL_TABLE_PROPERTY,
ERROR_HANDLER_PROPERTY,
ERROR_REPORTER_PROPERTY,
ENTITY_MANAGER_PROPERTY,
ENTITY_RESOLVER_PROPERTY,
XMLGRAMMAR_POOL_PROPERTY,
DATATYPE_VALIDATOR_FACTORY_PROPERTY,
DOCUMENT_SCANNER_PROPERTY,
DTD_SCANNER_PROPERTY,
VALIDATOR_PROPERTY,
SCHEMA_LOCATION,
SCHEMA_NONS_LOCATION,
VALIDATION_MANAGER_PROPERTY,
BUFFER_SIZE_PROPERTY,
SECURITY_MANAGER_PROPERTY,
LOCALE_PROPERTY,
SCHEMA_DV_FACTORY_PROPERTY,
};
/** Empty enumeration. */
private static final Enumeration fgEmptyEnumeration = new ArrayEnumeration(new Object[] {});
//
// Constructors
//
/** This class cannot be instantiated. */
private Constants() {}
//
// Public methods
//
// sax
/** Returns an enumeration of the SAX features. */
public static Enumeration getSAXFeatures() {
return fgSAXFeatures.length > 0
? new ArrayEnumeration(fgSAXFeatures) : fgEmptyEnumeration;
} // getSAXFeatures():Enumeration
/** Returns an enumeration of the SAX properties. */
public static Enumeration getSAXProperties() {
return fgSAXProperties.length > 0
? new ArrayEnumeration(fgSAXProperties) : fgEmptyEnumeration;
} // getSAXProperties():Enumeration
// xerces
/** Returns an enumeration of the Xerces features. */
public static Enumeration getXercesFeatures() {
return fgXercesFeatures.length > 0
? new ArrayEnumeration(fgXercesFeatures) : fgEmptyEnumeration;
} // getXercesFeatures():Enumeration
/** Returns an enumeration of the Xerces properties. */
public static Enumeration getXercesProperties() {
return fgXercesProperties.length > 0
? new ArrayEnumeration(fgXercesProperties) : fgEmptyEnumeration;
} // getXercesProperties():Enumeration
/*
* Check the version of the current JDK against that specified in the
* parameter
*
* There is a proposal to change the java version string to:
* MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL
* This method would work with both the current format and that proposed
*
* @param compareTo a JDK version to be compared to
* @return true if the current version is the same or above that represented
* by the parameter
*/
public static boolean isJavaVersionAtLeast(int compareTo) {
String javaVersion = SecuritySupport.getSystemProperty("java.version");
String versions[] = javaVersion.split("\\.", 3);
if (Integer.parseInt(versions[0]) >= compareTo ||
Integer.parseInt(versions[1]) >= compareTo) {
return true;
}
return false;
}
//
// Classes
//
/**
* An array enumeration.
*
* @author Andy Clark, IBM
*/
static class ArrayEnumeration
implements Enumeration {
//
// Data
//
/** Array. */
private Object[] array;
/** Index. */
private int index;
//
// Constructors
//
/** Constructs an array enumeration. */
public ArrayEnumeration(Object[] array) {
this.array = array;
} // <init>(Object[])
//
// Enumeration methods
//
/**
* Tests if this enumeration contains more elements.
*
* @return <code>true</code> if this enumeration contains more elements;
* <code>false</code> otherwise.
* @since JDK1.0
*/
public boolean hasMoreElements() {
return index < array.length;
} // hasMoreElement():boolean
/**
* Returns the next element of this enumeration.
*
* @return the next element of this enumeration.
* @exception NoSuchElementException if no more elements exist.
* @since JDK1.0
*/
public Object nextElement() {
if (index < array.length) {
return array[index++];
}
throw new NoSuchElementException();
} // nextElement():Object
} // class ArrayEnumeration
//
// MAIN
//
/** Prints all of the constants to standard output. */
public static void main(String[] argv) {
print("SAX features:", SAX_FEATURE_PREFIX, fgSAXFeatures);
print("SAX properties:", SAX_PROPERTY_PREFIX, fgSAXProperties);
print("Xerces features:", XERCES_FEATURE_PREFIX, fgXercesFeatures);
print("Xerces properties:", XERCES_PROPERTY_PREFIX, fgXercesProperties);
} // main(String[])
/** Prints a list of features/properties. */
private static void print(String header, String prefix, Object[] array) {
System.out.print(header);
if (array.length > 0) {
System.out.println();
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(prefix);
System.out.println(array[i]);
}
}
else {
System.out.println(" none.");
}
} // print(String,String,Object[])
} // class Constants

View File

@@ -0,0 +1,67 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLDTDDescription;
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
/**
* <p>This interface extends <code>XMLEntityResolver</code> providing
* a method to resolve external subsets for documents which do not
* explicitly provide one. The application can register an object that
* implements this interface with the parser configuration. If registered,
* it will be queried to locate an external subset when none is provided,
* even for documents that do not contain DOCTYPE declarations. If the
* registered external subset resolver does not provide an external subset
* for a given document, it should return <code>null</code>.</p>
*
* @xerces.internal
*
* @author Michael Glavassevich, IBM
*
*/
public interface ExternalSubsetResolver
extends XMLEntityResolver {
//
// ExternalSubsetResolver methods
//
/**
* <p>Locates an external subset for documents which do not explicitly
* provide one. If no external subset is provided, this method should
* return <code>null</code>.</p>
*
* @param grammarDescription a description of the DTD
*
* @throws XNIException Thrown on general error.
* @throws IOException Thrown if resolved entity stream cannot be
* opened or some other i/o error occurs.
*/
public XMLInputSource getExternalSubset(XMLDTDDescription grammarDescription)
throws XNIException, IOException;
} // interface ExternalSubsetResolver

View File

@@ -0,0 +1,220 @@
/*
* Copyright (c) 2005, 2013, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.xml.internal.stream.StaxEntityResolverWrapper;
import java.util.HashMap;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLResolver;
/**
* This class manages different properties related to Stax specification and its implementation.
* This class constructor also takes itself (PropertyManager object) as parameter and initializes the
* object with the property taken from the object passed.
*
* @author Neeraj Bajaj, neeraj.bajaj@sun.com
* @author K.Venugopal@sun.com
* @author Sunitha Reddy, sunitha.reddy@sun.com
*/
public class PropertyManager {
public static final String STAX_NOTATIONS = "javax.xml.stream.notations";
public static final String STAX_ENTITIES = "javax.xml.stream.entities";
private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
/** Property identifier: Security manager. */
private static final String SECURITY_MANAGER = Constants.SECURITY_MANAGER;
/** Property identifier: Security property manager. */
private static final String XML_SECURITY_PROPERTY_MANAGER =
Constants.XML_SECURITY_PROPERTY_MANAGER;
HashMap supportedProps = new HashMap();
private XMLSecurityManager fSecurityManager;
private XMLSecurityPropertyManager fSecurityPropertyMgr;
public static final int CONTEXT_READER = 1;
public static final int CONTEXT_WRITER = 2;
/** Creates a new instance of PropertyManager */
public PropertyManager(int context) {
switch(context){
case CONTEXT_READER:{
initConfigurableReaderProperties();
break;
}
case CONTEXT_WRITER:{
initWriterProps();
break;
}
}
}
/**
* Initialize this object with the properties taken from passed PropertyManager object.
*/
public PropertyManager(PropertyManager propertyManager){
HashMap properties = propertyManager.getProperties();
supportedProps.putAll(properties);
fSecurityManager = (XMLSecurityManager)getProperty(SECURITY_MANAGER);
fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER);
}
private HashMap getProperties(){
return supportedProps ;
}
/**
* Important point:
* 1. We are not exposing Xerces namespace property. Application should configure namespace through
* Stax specific property.
*
*/
private void initConfigurableReaderProperties(){
//spec default values
supportedProps.put(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
supportedProps.put(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
supportedProps.put(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.TRUE);
supportedProps.put(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.TRUE);
supportedProps.put(XMLInputFactory.IS_COALESCING, Boolean.FALSE);
supportedProps.put(XMLInputFactory.SUPPORT_DTD, Boolean.TRUE);
supportedProps.put(XMLInputFactory.REPORTER, null);
supportedProps.put(XMLInputFactory.RESOLVER, null);
supportedProps.put(XMLInputFactory.ALLOCATOR, null);
supportedProps.put(STAX_NOTATIONS,null );
//zephyr (implementation) specific properties which can be set by the application.
//interning is always done
supportedProps.put(Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE , new Boolean(true));
//recognizing java encoding names by default
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE, new Boolean(true)) ;
//in stax mode, namespace declarations are not added as attributes
supportedProps.put(Constants.ADD_NAMESPACE_DECL_AS_ATTRIBUTE , Boolean.FALSE) ;
supportedProps.put(Constants.READER_IN_DEFINED_STATE, new Boolean(true));
supportedProps.put(Constants.REUSE_INSTANCE, new Boolean(true));
supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.STAX_REPORT_CDATA_EVENT , new Boolean(false));
supportedProps.put(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD, Boolean.FALSE);
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE, new Boolean(false));
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false));
supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false));
fSecurityManager = new XMLSecurityManager(true);
supportedProps.put(SECURITY_MANAGER, fSecurityManager);
fSecurityPropertyMgr = new XMLSecurityPropertyManager();
supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
}
private void initWriterProps(){
supportedProps.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES , Boolean.FALSE);
//default value of escaping characters is 'true'
supportedProps.put(Constants.ESCAPE_CHARACTERS , Boolean.TRUE);
supportedProps.put(Constants.REUSE_INSTANCE, new Boolean(true));
}
/**
* public void reset(){
* supportedProps.clear() ;
* }
*/
public boolean containsProperty(String property){
return supportedProps.containsKey(property) ||
(fSecurityManager != null && fSecurityManager.getIndex(property) > -1) ||
(fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ;
}
public Object getProperty(String property){
return supportedProps.get(property);
}
public void setProperty(String property, Object value){
String equivalentProperty = null ;
if(property == XMLInputFactory.IS_NAMESPACE_AWARE || property.equals(XMLInputFactory.IS_NAMESPACE_AWARE)){
equivalentProperty = Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE ;
}
else if(property == XMLInputFactory.IS_VALIDATING || property.equals(XMLInputFactory.IS_VALIDATING)){
if( (value instanceof Boolean) && ((Boolean)value).booleanValue()){
throw new java.lang.IllegalArgumentException("true value of isValidating not supported") ;
}
}
else if(property == STRING_INTERNING || property.equals(STRING_INTERNING)){
if( (value instanceof Boolean) && !((Boolean)value).booleanValue()){
throw new java.lang.IllegalArgumentException("false value of " + STRING_INTERNING + "feature is not supported") ;
}
}
else if(property == XMLInputFactory.RESOLVER || property.equals(XMLInputFactory.RESOLVER)){
//add internal stax property
supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ;
}
/**
* It's possible for users to set a security manager through the interface.
* If it's the old SecurityManager, convert it to the new XMLSecurityManager
*/
if (property.equals(Constants.SECURITY_MANAGER)) {
fSecurityManager = XMLSecurityManager.convert(value, fSecurityManager);
supportedProps.put(Constants.SECURITY_MANAGER, fSecurityManager);
return;
}
if (property.equals(Constants.XML_SECURITY_PROPERTY_MANAGER)) {
if (value == null) {
fSecurityPropertyMgr = new XMLSecurityPropertyManager();
} else {
fSecurityPropertyMgr = (XMLSecurityPropertyManager)value;
}
supportedProps.put(Constants.XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
return;
}
//check if the property is managed by security manager
if (fSecurityManager == null ||
!fSecurityManager.setLimit(property, XMLSecurityManager.State.APIPROPERTY, value)) {
//check if the property is managed by security property manager
if (fSecurityPropertyMgr == null ||
!fSecurityPropertyMgr.setValue(property, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
//fall back to the existing property manager
supportedProps.put(property, value);
}
}
if(equivalentProperty != null){
supportedProps.put(equivalentProperty, value ) ;
}
}
public String toString(){
return supportedProps.toString();
}
}//PropertyManager

View File

@@ -0,0 +1,44 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter;
/**
* DOM Revalidation handler adds additional functionality to XMLDocumentHandler
*
* @xerces.internal
* @author Elena Litani, IBM
*/
public interface RevalidationHandler extends XMLDocumentFilter {
/**
* Character content.
*
* @param data The character data.
* @param augs Augmentations
* @return True if data is whitespace only
*/
public boolean characterData(String data, Augmentations augs);
} // interface DOMRevalidationHandler

View File

@@ -0,0 +1,101 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xerces" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.apache.org. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package com.sun.org.apache.xerces.internal.impl;
/**
* This class defines the version number of the parser.
*
*/
public class Version {
//
// Data
//
/** Version string.
* @deprecated getVersion() should be used instead. */
public static final String fVersion = getVersion();
private static final String fImmutableVersion = "Xerces-J 2.7.1";
// public methods
/* Print out the version information.
* @return the version of the parser.
*/
public static String getVersion() {
return fImmutableVersion;
} // getVersion(): String
//
// MAIN
//
/**
* Prints out the version number to System.out. This is needed
* for the build system.
*/
public static void main(String argv[]) {
System.out.println(fVersion);
}
} // class Version

View File

@@ -0,0 +1,256 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import java.io.IOException;
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.XMLStringBuffer;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.XNIException;
/**
* This class is responsible for scanning the declarations found
* in the internal and external subsets of a DTD in an XML document.
* The scanner acts as the sources for the DTD information which is
* communicated to the DTD handlers.
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/validation</li>
* <li>http://apache.org/xml/features/scanner/notify-char-refs</li>
* <li>http://apache.org/xml/properties/internal/symbol-table</li>
* <li>http://apache.org/xml/properties/internal/error-reporter</li>
* <li>http://apache.org/xml/properties/internal/entity-manager</li>
* </ul>
*
* @xerces.internal
*
* @author Arnaud Le Hors, IBM
* @author Andy Clark, IBM
* @author Glenn Marcy, IBM
* @author Eric Ye, IBM
*
*/
public class XML11DTDScannerImpl
extends XMLDTDScannerImpl {
/** String buffer. */
private XMLStringBuffer fStringBuffer = new XMLStringBuffer();
//
// Constructors
//
/** Default constructor. */
public XML11DTDScannerImpl() {super();} // <init>()
/** Constructor for he use of non-XMLComponentManagers. */
public XML11DTDScannerImpl(SymbolTable symbolTable,
XMLErrorReporter errorReporter, XMLEntityManager entityManager) {
super(symbolTable, errorReporter, entityManager);
}
//
// XMLDTDScanner methods
//
//
// XMLScanner methods
//
// NOTE: this is a carbon copy of the code in XML11DocumentScannerImpl;
// we need to override these methods in both places. Ah for
// multiple inheritance...
// This needs to be refactored!!! - NG
/**
* Scans public ID literal.
*
* [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
* [13] PubidChar::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
*
* The returned string is normalized according to the following rule,
* from http://www.w3.org/TR/REC-xml#dt-pubid:
*
* Before a match is attempted, all strings of white space in the public
* identifier must be normalized to single space characters (#x20), and
* leading and trailing white space must be removed.
*
* @param literal The string to fill in with the public ID literal.
* @return True on success.
*
* <strong>Note:</strong> This method uses fStringBuffer, anything in it at
* the time of calling is lost.
*/
protected boolean scanPubidLiteral(XMLString literal)
throws IOException, XNIException
{
int quote = fEntityScanner.scanChar(null);
if (quote != '\'' && quote != '"') {
reportFatalError("QuoteRequiredInPublicID", null);
return false;
}
fStringBuffer.clear();
// skip leading whitespace
boolean skipSpace = true;
boolean dataok = true;
while (true) {
int c = fEntityScanner.scanChar(null);
// REVISIT: it could really only be \n or 0x20; all else is normalized, no? - neilg
if (c == ' ' || c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
if (!skipSpace) {
// take the first whitespace as a space and skip the others
fStringBuffer.append(' ');
skipSpace = true;
}
}
else if (c == quote) {
if (skipSpace) {
// if we finished on a space let's trim it
fStringBuffer.length--;
}
literal.setValues(fStringBuffer);
break;
}
else if (XMLChar.isPubid(c)) {
fStringBuffer.append((char)c);
skipSpace = false;
}
else if (c == -1) {
reportFatalError("PublicIDUnterminated", null);
return false;
}
else {
dataok = false;
reportFatalError("InvalidCharInPublicID",
new Object[]{Integer.toHexString(c)});
}
}
return dataok;
}
/**
* Normalize whitespace in an XMLString converting all whitespace
* characters to space characters.
*/
protected void normalizeWhitespace(XMLString value) {
int end = value.offset + value.length;
for (int i = value.offset; i < end; ++i) {
int c = value.ch[i];
if (XMLChar.isSpace(c)) {
value.ch[i] = ' ';
}
}
}
/**
* Normalize whitespace in an XMLString converting all whitespace
* characters to space characters.
*/
protected void normalizeWhitespace(XMLString value, int fromIndex) {
int end = value.offset + value.length;
for (int i = value.offset + fromIndex; i < end; ++i) {
int c = value.ch[i];
if (XMLChar.isSpace(c)) {
value.ch[i] = ' ';
}
}
}
/**
* Checks whether this string would be unchanged by normalization.
*
* @return -1 if the value would be unchanged by normalization,
* otherwise the index of the first whitespace character which
* would be transformed.
*/
protected int isUnchangedByNormalization(XMLString value) {
int end = value.offset + value.length;
for (int i = value.offset; i < end; ++i) {
int c = value.ch[i];
if (XMLChar.isSpace(c)) {
return i - value.offset;
}
}
return -1;
}
// returns true if the given character is not
// valid with respect to the version of
// XML understood by this scanner.
protected boolean isInvalid(int value) {
return (!XML11Char.isXML11Valid(value));
} // isInvalid(int): boolean
// returns true if the given character is not
// valid or may not be used outside a character reference
// with respect to the version of XML understood by this scanner.
protected boolean isInvalidLiteral(int value) {
return (!XML11Char.isXML11ValidLiteral(value));
} // isInvalidLiteral(int): boolean
// returns true if the given character is
// a valid nameChar with respect to the version of
// XML understood by this scanner.
protected boolean isValidNameChar(int value) {
return (XML11Char.isXML11Name(value));
} // isValidNameChar(int): boolean
// returns true if the given character is
// a valid nameStartChar with respect to the version of
// XML understood by this scanner.
protected boolean isValidNameStartChar(int value) {
return (XML11Char.isXML11NameStart(value));
} // isValidNameStartChar(int): boolean
// returns true if the given character is
// a valid NCName character with respect to the version of
// XML understood by this scanner.
protected boolean isValidNCName(int value) {
return (XML11Char.isXML11NCName(value));
} // isValidNCName(int): boolean
// returns true if the given character is
// a valid high surrogate for a nameStartChar
// with respect to the version of XML understood
// by this scanner.
protected boolean isValidNameStartHighSurrogate(int value) {
return XML11Char.isXML11NameHighSurrogate(value);
} // isValidNameStartHighSurrogate(int): boolean
// note that, according to 4.3.4 of the XML 1.1 spec, XML 1.1
// documents may invoke 1.0 entities; thus either version decl (or none!)
// is allowed to appear in this context
protected boolean versionSupported(String version) {
return version.equals("1.1") || version.equals ("1.0");
} // versionSupported(String): boolean
// returns the error message key for unsupported
// versions of XML with respect to the version of
// XML understood by this scanner.
protected String getVersionNotSupportedKey () {
return "VersionNotSupported11";
} // getVersionNotSupportedKey: String
} // class XML11DTDScannerImpl

View File

@@ -0,0 +1,499 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
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.XMLStringBuffer;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import java.io.IOException;
/**
* This class is responsible for scanning XML document structure
* and content. The scanner acts as the source for the document
* information which is communicated to the document handler.
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/namespaces</li>
* <li>http://xml.org/sax/features/validation</li>
* <li>http://apache.org/xml/features/nonvalidating/load-external-dtd</li>
* <li>http://apache.org/xml/features/scanner/notify-char-refs</li>
* <li>http://apache.org/xml/features/scanner/notify-builtin-refs</li>
* <li>http://apache.org/xml/properties/internal/symbol-table</li>
* <li>http://apache.org/xml/properties/internal/error-reporter</li>
* <li>http://apache.org/xml/properties/internal/entity-manager</li>
* <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
* </ul>
*
* @xerces.internal
*
* @author Glenn Marcy, IBM
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
* @author Eric Ye, IBM
* @LastModified: Aug 2021
*/
public class XML11DocumentScannerImpl
extends XMLDocumentScannerImpl {
/** String buffer. */
private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();
private final XMLStringBuffer fStringBuffer2 = new XMLStringBuffer();
private final XMLStringBuffer fStringBuffer3 = new XMLStringBuffer();
//
// Constructors
//
/** Default constructor. */
public XML11DocumentScannerImpl() {super();} // <init>()
//
// overridden methods
//
// XMLDocumentFragmentImpl methods
/**
* Scans element content.
*
* @return Returns the next character on the stream.
*/
protected int scanContent(XMLStringBuffer content) throws IOException, XNIException {
fTempString.length = 0;
int c = fEntityScanner.scanContent(fTempString);
content.append(fTempString);
if (c == '\r' || c == 0x85 || c == 0x2028) {
// happens when there is the character reference &#13;
// but scanContent doesn't do entity expansions...
// is this *really* necessary??? - NG
fEntityScanner.scanChar(null);
content.append((char)c);
c = -1;
}
/*if (fDocumentHandler != null && content.length > 0) {
fDocumentHandler.characters(content, null);
} */
if (c == ']') {
content.append((char)fEntityScanner.scanChar(null));
// remember where we are in case we get an endEntity before we
// could flush the buffer out - this happens when we're parsing an
// entity which ends with a ]
fInScanContent = true;
//
// We work on a single character basis to handle cases such as:
// ']]]>' which we might otherwise miss.
//
if (fEntityScanner.skipChar(']', null)) {
content.append(']');
while (fEntityScanner.skipChar(']', null)) {
content.append(']');
}
if (fEntityScanner.skipChar('>', null)) {
reportFatalError("CDEndInContent", null);
}
}
/*if (fDocumentHandler != null && fStringBuffer.length != 0) {
fDocumentHandler.characters(fStringBuffer, null);
}*/
fInScanContent = false;
c = -1;
}
return c;
} // scanContent():int
/**
* Scans an attribute value and normalizes whitespace converting all
* whitespace characters to space characters.
*
* [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
*
* @param value The XMLString to fill in with the value.
* @param nonNormalizedValue The XMLString to fill in with the
* non-normalized value.
* @param atName The name of the attribute being parsed (for error msgs).
* @param checkEntities true if undeclared entities should be reported as VC violation,
* false if undeclared entities should be reported as WFC violation.
* @param eleName The name of element to which this attribute belongs.
* @param isNSURI The flag indicating whether the content is a namespace URI
*
* @return true if the non-normalized and normalized value are the same
*
* <strong>Note:</strong> This method uses fStringBuffer2, anything in it
* at the time of calling is lost.
**/
protected boolean scanAttributeValue(XMLString value,
XMLString nonNormalizedValue,
String atName,
boolean checkEntities,String eleName, boolean isNSURI)
throws IOException, XNIException
{
// quote
int quote = fEntityScanner.peekChar();
if (quote != '\'' && quote != '"') {
reportFatalError("OpenQuoteExpected", new Object[]{eleName,atName});
}
fEntityScanner.scanChar(NameType.ATTRIBUTE);
int entityDepth = fEntityDepth;
int c = fEntityScanner.scanLiteral(quote, value, isNSURI);
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** scanLiteral -> \""
+ value.toString() + "\"");
}
int fromIndex = 0;
if (c == quote && (fromIndex = isUnchangedByNormalization(value)) == -1) {
/** Both the non-normalized and normalized attribute values are equal. **/
nonNormalizedValue.setValues(value);
int cquote = fEntityScanner.scanChar(NameType.ATTRIBUTE);
if (cquote != quote) {
reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName});
}
return true;
}
fStringBuffer2.clear();
fStringBuffer2.append(value);
normalizeWhitespace(value, fromIndex);
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** normalizeWhitespace -> \""
+ value.toString() + "\"");
}
if (c != quote) {
fScanningAttribute = true;
fStringBuffer.clear();
do {
fStringBuffer.append(value);
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** value2: \""
+ fStringBuffer.toString() + "\"");
}
if (c == '&') {
fEntityScanner.skipChar('&', NameType.REFERENCE);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append('&');
}
if (fEntityScanner.skipChar('#', NameType.REFERENCE)) {
if (entityDepth == fEntityDepth) {
fStringBuffer2.append('#');
}
int ch = scanCharReferenceValue(fStringBuffer, fStringBuffer2);
if (ch != -1) {
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** value3: \""
+ fStringBuffer.toString()
+ "\"");
}
}
}
else {
String entityName = fEntityScanner.scanName(NameType.REFERENCE);
if (entityName == null) {
reportFatalError("NameRequiredInReference", null);
}
else if (entityDepth == fEntityDepth) {
fStringBuffer2.append(entityName);
}
if (!fEntityScanner.skipChar(';', NameType.REFERENCE)) {
reportFatalError("SemicolonRequiredInReference",
new Object []{entityName});
}
else if (entityDepth == fEntityDepth) {
fStringBuffer2.append(';');
}
if (resolveCharacter(entityName, fStringBuffer)) {
checkEntityLimit(false, fEntityScanner.fCurrentEntity.name, 1);
}
else {
if (fEntityManager.isExternalEntity(entityName)) {
reportFatalError("ReferenceToExternalEntity",
new Object[] { entityName });
}
else {
if (!fEntityManager.isDeclaredEntity(entityName)) {
//WFC & VC: Entity Declared
if (checkEntities) {
if (fValidation) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"EntityNotDeclared",
new Object[]{entityName},
XMLErrorReporter.SEVERITY_ERROR);
}
}
else {
reportFatalError("EntityNotDeclared",
new Object[]{entityName});
}
}
fEntityManager.startEntity(true, entityName, true);
}
}
}
}
else if (c == '<') {
reportFatalError("LessthanInAttValue",
new Object[] { eleName, atName });
fEntityScanner.scanChar(null);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append((char)c);
}
}
else if (c == '%' || c == ']') {
fEntityScanner.scanChar(null);
fStringBuffer.append((char)c);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append((char)c);
}
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** valueF: \""
+ fStringBuffer.toString() + "\"");
}
}
else if (c != -1 && XMLChar.isHighSurrogate(c)) {
fStringBuffer3.clear();
if (scanSurrogates(fStringBuffer3)) {
fStringBuffer.append(fStringBuffer3);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append(fStringBuffer3);
}
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** valueI: \""
+ fStringBuffer.toString()
+ "\"");
}
}
}
else if (c != -1 && isInvalidLiteral(c)) {
reportFatalError("InvalidCharInAttValue",
new Object[] {eleName, atName, Integer.toString(c, 16)});
fEntityScanner.scanChar(null);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append((char)c);
}
}
c = fEntityScanner.scanLiteral(quote, value, isNSURI);
if (entityDepth == fEntityDepth) {
fStringBuffer2.append(value);
}
normalizeWhitespace(value);
} while (c != quote || entityDepth != fEntityDepth);
fStringBuffer.append(value);
if (DEBUG_ATTR_NORMALIZATION) {
System.out.println("** valueN: \""
+ fStringBuffer.toString() + "\"");
}
value.setValues(fStringBuffer);
fScanningAttribute = false;
}
nonNormalizedValue.setValues(fStringBuffer2);
// quote
int cquote = fEntityScanner.scanChar(null);
if (cquote != quote) {
reportFatalError("CloseQuoteExpected", new Object[]{eleName,atName});
}
return nonNormalizedValue.equals(value.ch, value.offset, value.length);
} // scanAttributeValue()
//
// XMLScanner methods
//
// NOTE: this is a carbon copy of the code in XML11DTDScannerImpl;
// we need to override these methods in both places.
// this needs to be refactored!!! - NG
/**
* Scans public ID literal.
*
* [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
* [13] PubidChar::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
*
* The returned string is normalized according to the following rule,
* from http://www.w3.org/TR/REC-xml#dt-pubid:
*
* Before a match is attempted, all strings of white space in the public
* identifier must be normalized to single space characters (#x20), and
* leading and trailing white space must be removed.
*
* @param literal The string to fill in with the public ID literal.
* @return True on success.
*
* <strong>Note:</strong> This method uses fStringBuffer, anything in it at
* the time of calling is lost.
*/
protected boolean scanPubidLiteral(XMLString literal)
throws IOException, XNIException
{
int quote = fEntityScanner.scanChar(null);
if (quote != '\'' && quote != '"') {
reportFatalError("QuoteRequiredInPublicID", null);
return false;
}
fStringBuffer.clear();
// skip leading whitespace
boolean skipSpace = true;
boolean dataok = true;
while (true) {
int c = fEntityScanner.scanChar(null);
// REVISIT: none of these except \n and 0x20 should make it past the entity scanner
if (c == ' ' || c == '\n' || c == '\r' || c == 0x85 || c == 0x2028) {
if (!skipSpace) {
// take the first whitespace as a space and skip the others
fStringBuffer.append(' ');
skipSpace = true;
}
}
else if (c == quote) {
if (skipSpace) {
// if we finished on a space let's trim it
fStringBuffer.length--;
}
literal.setValues(fStringBuffer);
break;
}
else if (XMLChar.isPubid(c)) {
fStringBuffer.append((char)c);
skipSpace = false;
}
else if (c == -1) {
reportFatalError("PublicIDUnterminated", null);
return false;
}
else {
dataok = false;
reportFatalError("InvalidCharInPublicID",
new Object[]{Integer.toHexString(c)});
}
}
return dataok;
}
/**
* Normalize whitespace in an XMLString converting all whitespace
* characters to space characters.
*/
protected void normalizeWhitespace(XMLString value) {
int end = value.offset + value.length;
for (int i = value.offset; i < end; ++i) {
int c = value.ch[i];
if (XMLChar.isSpace(c)) {
value.ch[i] = ' ';
}
}
}
/**
* Normalize whitespace in an XMLString converting all whitespace
* characters to space characters.
*/
protected void normalizeWhitespace(XMLString value, int fromIndex) {
int end = value.offset + value.length;
for (int i = value.offset + fromIndex; i < end; ++i) {
int c = value.ch[i];
if (XMLChar.isSpace(c)) {
value.ch[i] = ' ';
}
}
}
/**
* Checks whether this string would be unchanged by normalization.
*
* @return -1 if the value would be unchanged by normalization,
* otherwise the index of the first whitespace character which
* would be transformed.
*/
protected int isUnchangedByNormalization(XMLString value) {
int end = value.offset + value.length;
for (int i = value.offset; i < end; ++i) {
int c = value.ch[i];
if (XMLChar.isSpace(c)) {
return i - value.offset;
}
}
return -1;
}
// returns true if the given character is not
// valid with respect to the version of
// XML understood by this scanner.
protected boolean isInvalid(int value) {
return (XML11Char.isXML11Invalid(value));
} // isInvalid(int): boolean
// returns true if the given character is not
// valid or may not be used outside a character reference
// with respect to the version of XML understood by this scanner.
protected boolean isInvalidLiteral(int value) {
return (!XML11Char.isXML11ValidLiteral(value));
} // isInvalidLiteral(int): boolean
// returns true if the given character is
// a valid nameChar with respect to the version of
// XML understood by this scanner.
protected boolean isValidNameChar(int value) {
return (XML11Char.isXML11Name(value));
} // isValidNameChar(int): boolean
// returns true if the given character is
// a valid nameStartChar with respect to the version of
// XML understood by this scanner.
protected boolean isValidNameStartChar(int value) {
return (XML11Char.isXML11NameStart(value));
} // isValidNameStartChar(int): boolean
// returns true if the given character is
// a valid NCName character with respect to the version of
// XML understood by this scanner.
protected boolean isValidNCName(int value) {
return (XML11Char.isXML11NCName(value));
} // isValidNCName(int): boolean
// returns true if the given character is
// a valid high surrogate for a nameStartChar
// with respect to the version of XML understood
// by this scanner.
protected boolean isValidNameStartHighSurrogate(int value) {
return XML11Char.isXML11NameHighSurrogate(value);
} // isValidNameStartHighSurrogate(int): boolean
protected boolean versionSupported(String version) {
return (version.equals("1.1") || version.equals("1.0"));
} // versionSupported(String): boolean
// returns the error message key for unsupported
// versions of XML with respect to the version of
// XML understood by this scanner.
protected String getVersionNotSupportedKey () {
return "VersionNotSupported11";
} // getVersionNotSupportedKey: String
} // class XML11DocumentScannerImpl

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,892 @@
/*
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidatorFilter;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
import javax.xml.stream.events.XMLEvent;
/**
* The scanner acts as the source for the document
* information which is communicated to the document handler.
*
* This class scans an XML document, checks if document has a DTD, and if
* DTD is not found the scanner will remove the DTD Validator from the pipeline and perform
* namespace binding.
*
* Note: This scanner should only be used when the namespace processing is on!
*
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/namespaces {true} -- if the value of this
* feature is set to false this scanner must not be used.</li>
* <li>http://xml.org/sax/features/validation</li>
* <li>http://apache.org/xml/features/nonvalidating/load-external-dtd</li>
* <li>http://apache.org/xml/features/scanner/notify-char-refs</li>
* <li>http://apache.org/xml/features/scanner/notify-builtin-refs</li>
* <li>http://apache.org/xml/properties/internal/symbol-table</li>
* <li>http://apache.org/xml/properties/internal/error-reporter</li>
* <li>http://apache.org/xml/properties/internal/entity-manager</li>
* <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
* </ul>
*
* @xerces.internal
*
* @author Elena Litani, IBM
* @author Michael Glavassevich, IBM
* @author Sunitha Reddy, Sun Microsystems
*/
public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl {
/**
* If is true, the dtd validator is no longer in the pipeline
* and the scanner should bind namespaces
*/
protected boolean fBindNamespaces;
/**
* If validating parser, make sure we report an error in the
* scanner if DTD grammar is missing.
*/
protected boolean fPerformValidation;
// private data
//
/** DTD validator */
private XMLDTDValidatorFilter fDTDValidator;
/**
* Saw spaces after element name or between attributes.
*
* This is reserved for the case where scanning of a start element spans
* several methods, as is the case when scanning the start of a root element
* where a DTD external subset may be read after scanning the element name.
*/
private boolean fSawSpace;
/**
* The scanner is responsible for removing DTD validator
* from the pipeline if it is not needed.
*
* @param validator the DTD validator from the pipeline
*/
public void setDTDValidator(XMLDTDValidatorFilter validator) {
fDTDValidator = validator;
}
/**
* Scans a start element. This method will handle the binding of
* namespace information and notifying the handler of the start
* of the element.
* <p>
* <pre>
* [44] EmptyElemTag ::= '&lt;' Name (S Attribute)* S? '/>'
* [40] STag ::= '&lt;' Name (S Attribute)* S? '>'
* </pre>
* <p>
* <strong>Note:</strong> This method assumes that the leading
* '&lt;' character has been consumed.
* <p>
* <strong>Note:</strong> This method uses the fElementQName and
* fAttributes variables. The contents of these variables will be
* destroyed. The caller should copy important information out of
* these variables before calling this method.
*
* @return True if element is empty. (i.e. It matches
* production [44].
*/
protected boolean scanStartElement() throws IOException, XNIException {
if (DEBUG_START_END_ELEMENT)
System.out.println(">>> scanStartElementNS()");
// Note: namespace processing is on by default
fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART);
// REVISIT - [Q] Why do we need this local variable? -- mrglavas
String rawname = fElementQName.rawname;
if (fBindNamespaces) {
fNamespaceContext.pushContext();
if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
if (fPerformValidation) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"MSG_GRAMMAR_NOT_FOUND",
new Object[] { rawname },
XMLErrorReporter.SEVERITY_ERROR);
if (fDoctypeName == null
|| !fDoctypeName.equals(rawname)) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"RootElementTypeMustMatchDoctypedecl",
new Object[] { fDoctypeName, rawname },
XMLErrorReporter.SEVERITY_ERROR);
}
}
}
}
// push element stack
fCurrentElement = fElementStack.pushElement(fElementQName);
// attributes
boolean empty = false;
fAttributes.removeAllAttributes();
do {
// spaces
boolean sawSpace = fEntityScanner.skipSpaces();
// end tag?
int c = fEntityScanner.peekChar();
if (c == '>') {
fEntityScanner.scanChar(null);
break;
} else if (c == '/') {
fEntityScanner.scanChar(null);
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError(
"ElementUnterminated",
new Object[] { rawname });
}
empty = true;
break;
} else if (!isValidNameStartChar(c) || !sawSpace) {
// Second chance. Check if this character is a high
// surrogate of a valid name start character.
if (!isValidNameStartHighSurrogate(c) || !sawSpace) {
reportFatalError(
"ElementUnterminated",
new Object[] { rawname });
}
}
// attributes
scanAttribute(fAttributes);
if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) &&
fAttributes.getLength() > fElementAttributeLimit){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ElementAttributeLimit",
new Object[]{rawname, new Integer(fElementAttributeLimit) },
XMLErrorReporter.SEVERITY_FATAL_ERROR );
}
} while (true);
if (fBindNamespaces) {
// REVISIT: is it required? forbit xmlns prefix for element
if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementXMLNSPrefix",
new Object[] { fElementQName.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind the element
String prefix =
fElementQName.prefix != null
? fElementQName.prefix
: XMLSymbols.EMPTY_STRING;
// assign uri to the element
fElementQName.uri = fNamespaceContext.getURI(prefix);
// make sure that object in the element stack is updated as well
fCurrentElement.uri = fElementQName.uri;
if (fElementQName.prefix == null && fElementQName.uri != null) {
fElementQName.prefix = XMLSymbols.EMPTY_STRING;
// making sure that the object in the element stack is updated too.
fCurrentElement.prefix = XMLSymbols.EMPTY_STRING;
}
if (fElementQName.prefix != null && fElementQName.uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementPrefixUnbound",
new Object[] {
fElementQName.prefix,
fElementQName.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind attributes (xmlns are already bound bellow)
int length = fAttributes.getLength();
for (int i = 0; i < length; i++) {
fAttributes.getName(i, fAttributeQName);
String aprefix =
fAttributeQName.prefix != null
? fAttributeQName.prefix
: XMLSymbols.EMPTY_STRING;
String uri = fNamespaceContext.getURI(aprefix);
// REVISIT: try removing the first "if" and see if it is faster.
//
if (fAttributeQName.uri != null
&& fAttributeQName.uri == uri) {
continue;
}
if (aprefix != XMLSymbols.EMPTY_STRING) {
fAttributeQName.uri = uri;
if (uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[] {
fElementQName.rawname,
fAttributeQName.rawname,
aprefix },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
fAttributes.setURI(i, uri);
}
}
if (length > 1) {
QName name = fAttributes.checkDuplicatesNS();
if (name != null) {
if (name.uri != null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[] {
fElementQName.rawname,
name.localpart,
name.uri },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
} else {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNotUnique",
new Object[] {
fElementQName.rawname,
name.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
}
// call handler
if (empty) {
//decrease the markup depth..
fMarkupDepth--;
// check that this element was opened in the same entity
if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
reportFatalError(
"ElementEntityMismatch",
new Object[] { fCurrentElement.rawname });
}
if (fDocumentHandler != null) {
fDocumentHandler.emptyElement(fElementQName, fAttributes, null);
}
/*if (fBindNamespaces) {
fNamespaceContext.popContext();
}*/
fScanEndElement = true;
//pop the element off the stack..
fElementStack.popElement();
} else {
if(dtdGrammarUtil != null) {
dtdGrammarUtil.startElement(fElementQName, fAttributes);
}
if (fDocumentHandler != null) {
fDocumentHandler.startElement(fElementQName, fAttributes, null);
}
}
if (DEBUG_START_END_ELEMENT)
System.out.println("<<< scanStartElement(): " + empty);
return empty;
} // scanStartElement():boolean
/**
* Scans the name of an element in a start or empty tag.
*
* @see #scanStartElement()
*/
protected void scanStartElementName ()
throws IOException, XNIException {
// Note: namespace processing is on by default
fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART);
// Must skip spaces here because the DTD scanner
// would consume them at the end of the external subset.
fSawSpace = fEntityScanner.skipSpaces();
} // scanStartElementName()
/**
* Scans the remainder of a start or empty tag after the element name.
*
* @see #scanStartElement
* @return True if element is empty.
*/
protected boolean scanStartElementAfterName()
throws IOException, XNIException {
// REVISIT - [Q] Why do we need this local variable? -- mrglavas
String rawname = fElementQName.rawname;
if (fBindNamespaces) {
fNamespaceContext.pushContext();
if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
if (fPerformValidation) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"MSG_GRAMMAR_NOT_FOUND",
new Object[] { rawname },
XMLErrorReporter.SEVERITY_ERROR);
if (fDoctypeName == null
|| !fDoctypeName.equals(rawname)) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"RootElementTypeMustMatchDoctypedecl",
new Object[] { fDoctypeName, rawname },
XMLErrorReporter.SEVERITY_ERROR);
}
}
}
}
// push element stack
fCurrentElement = fElementStack.pushElement(fElementQName);
// attributes
boolean empty = false;
fAttributes.removeAllAttributes();
do {
// end tag?
int c = fEntityScanner.peekChar();
if (c == '>') {
fEntityScanner.scanChar(null);
break;
} else if (c == '/') {
fEntityScanner.scanChar(null);
if (!fEntityScanner.skipChar('>', null)) {
reportFatalError(
"ElementUnterminated",
new Object[] { rawname });
}
empty = true;
break;
} else if (!isValidNameStartChar(c) || !fSawSpace) {
// Second chance. Check if this character is a high
// surrogate of a valid name start character.
if (!isValidNameStartHighSurrogate(c) || !fSawSpace) {
reportFatalError(
"ElementUnterminated",
new Object[] { rawname });
}
}
// attributes
scanAttribute(fAttributes);
// spaces
fSawSpace = fEntityScanner.skipSpaces();
} while (true);
if (fBindNamespaces) {
// REVISIT: is it required? forbit xmlns prefix for element
if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementXMLNSPrefix",
new Object[] { fElementQName.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind the element
String prefix =
fElementQName.prefix != null
? fElementQName.prefix
: XMLSymbols.EMPTY_STRING;
// assign uri to the element
fElementQName.uri = fNamespaceContext.getURI(prefix);
// make sure that object in the element stack is updated as well
fCurrentElement.uri = fElementQName.uri;
if (fElementQName.prefix == null && fElementQName.uri != null) {
fElementQName.prefix = XMLSymbols.EMPTY_STRING;
// making sure that the object in the element stack is updated too.
fCurrentElement.prefix = XMLSymbols.EMPTY_STRING;
}
if (fElementQName.prefix != null && fElementQName.uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementPrefixUnbound",
new Object[] {
fElementQName.prefix,
fElementQName.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind attributes (xmlns are already bound bellow)
int length = fAttributes.getLength();
for (int i = 0; i < length; i++) {
fAttributes.getName(i, fAttributeQName);
String aprefix =
fAttributeQName.prefix != null
? fAttributeQName.prefix
: XMLSymbols.EMPTY_STRING;
String uri = fNamespaceContext.getURI(aprefix);
// REVISIT: try removing the first "if" and see if it is faster.
//
if (fAttributeQName.uri != null
&& fAttributeQName.uri == uri) {
continue;
}
if (aprefix != XMLSymbols.EMPTY_STRING) {
fAttributeQName.uri = uri;
if (uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[] {
fElementQName.rawname,
fAttributeQName.rawname,
aprefix },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
fAttributes.setURI(i, uri);
}
}
if (length > 1) {
QName name = fAttributes.checkDuplicatesNS();
if (name != null) {
if (name.uri != null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[] {
fElementQName.rawname,
name.localpart,
name.uri },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
} else {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNotUnique",
new Object[] {
fElementQName.rawname,
name.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
}
// call handler
if (fDocumentHandler != null) {
if (empty) {
//decrease the markup depth..
fMarkupDepth--;
// check that this element was opened in the same entity
if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
reportFatalError(
"ElementEntityMismatch",
new Object[] { fCurrentElement.rawname });
}
fDocumentHandler.emptyElement(fElementQName, fAttributes, null);
if (fBindNamespaces) {
fNamespaceContext.popContext();
}
//pop the element off the stack..
fElementStack.popElement();
} else {
fDocumentHandler.startElement(fElementQName, fAttributes, null);
}
}
if (DEBUG_START_END_ELEMENT)
System.out.println("<<< scanStartElementAfterName(): " + empty);
return empty;
} // scanStartElementAfterName()
/**
* Scans an attribute.
* <p>
* <pre>
* [41] Attribute ::= Name Eq AttValue
* </pre>
* <p>
* <strong>Note:</strong> This method assumes that the next
* character on the stream is the first character of the attribute
* name.
* <p>
* <strong>Note:</strong> This method uses the fAttributeQName and
* fQName variables. The contents of these variables will be
* destroyed.
*
* @param attributes The attributes list for the scanned attribute.
*/
protected void scanAttribute(XMLAttributesImpl attributes)
throws IOException, XNIException {
if (DEBUG_START_END_ELEMENT)
System.out.println(">>> scanAttribute()");
// name
fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTENAME);
// equals
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) {
reportFatalError(
"EqRequiredInAttribute",
new Object[] {
fCurrentElement.rawname,
fAttributeQName.rawname });
}
fEntityScanner.skipSpaces();
// content
int attrIndex;
if (fBindNamespaces) {
attrIndex = attributes.getLength();
attributes.addAttributeNS(
fAttributeQName,
XMLSymbols.fCDATASymbol,
null);
} else {
int oldLen = attributes.getLength();
attrIndex =
attributes.addAttribute(
fAttributeQName,
XMLSymbols.fCDATASymbol,
null);
// WFC: Unique Att Spec
if (oldLen == attributes.getLength()) {
reportFatalError(
"AttributeNotUnique",
new Object[] {
fCurrentElement.rawname,
fAttributeQName.rawname });
}
}
//REVISIT: one more case needs to be included: external PE and standalone is no
boolean isVC = fHasExternalDTD && !fStandalone;
/**
* Determine whether this is a namespace declaration that will be subject
* to the name limit check in the scanAttributeValue operation.
* Namespace declaration format: xmlns="..." or xmlns:prefix="..."
* Note that prefix:xmlns="..." isn't a namespace.
*/
String localpart = fAttributeQName.localpart;
String prefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS);
scanAttributeValue(this.fTempString, fTempString2, fAttributeQName.rawname,
isVC, fCurrentElement.rawname, isNSDecl);
String value = fTempString.toString();
attributes.setValue(attrIndex, value);
attributes.setNonNormalizedValue(attrIndex, fTempString2.toString());
attributes.setSpecified(attrIndex, true);
// record namespace declarations if any.
if (fBindNamespaces) {
if (isNSDecl) {
if (value.length() > fXMLNameLimit) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MaxXMLNameLimit",
new Object[]{value, value.length(), fXMLNameLimit,
fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.MAX_NAME_LIMIT)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// get the internalized value of this attribute
String uri = fSymbolTable.addSymbol(value);
// 1. "xmlns" can't be bound to any namespace
if (prefix == XMLSymbols.PREFIX_XMLNS
&& localpart == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[] { fAttributeQName },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 2. the namespace for "xmlns" can't be bound to any prefix
if (uri == NamespaceContext.XMLNS_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[] { fAttributeQName },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 3. "xml" can't be bound to any other namespace than it's own
if (localpart == XMLSymbols.PREFIX_XML) {
if (uri != NamespaceContext.XML_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[] { fAttributeQName },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
// 4. the namespace for "xml" can't be bound to any other prefix
else {
if (uri == NamespaceContext.XML_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[] { fAttributeQName },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
prefix =
localpart != XMLSymbols.PREFIX_XMLNS
? localpart
: XMLSymbols.EMPTY_STRING;
// Declare prefix in context. Removing the association between a prefix and a
// namespace name is permitted in XML 1.1, so if the uri value is the empty string,
// the prefix is being unbound. -- mrglavas
fNamespaceContext.declarePrefix(
prefix,
uri.length() != 0 ? uri : null);
// bind namespace attribute to a namespace
attributes.setURI(
attrIndex,
fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS));
} else {
// attempt to bind attribute
if (fAttributeQName.prefix != null) {
attributes.setURI(
attrIndex,
fNamespaceContext.getURI(fAttributeQName.prefix));
}
}
}
if (DEBUG_START_END_ELEMENT)
System.out.println("<<< scanAttribute()");
} // scanAttribute(XMLAttributes)
/**
* Scans an end element.
* <p>
* <pre>
* [42] ETag ::= '&lt;/' Name S? '>'
* </pre>
* <p>
* <strong>Note:</strong> This method uses the fElementQName variable.
* The contents of this variable will be destroyed. The caller should
* copy the needed information out of this variable before calling
* this method.
*
* @return The element depth.
*/
protected int scanEndElement() throws IOException, XNIException {
if (DEBUG_START_END_ELEMENT)
System.out.println(">>> scanEndElement()");
// pop context
QName endElementName = fElementStack.popElement();
// Take advantage of the fact that next string _should_ be "fElementQName.rawName",
//In scanners most of the time is consumed on checks done for XML characters, we can
// optimize on it and avoid the checks done for endElement,
//we will also avoid symbol table lookup - neeraj.bajaj@sun.com
// this should work both for namespace processing true or false...
//REVISIT: if the string is not the same as expected.. we need to do better error handling..
//We can skip this for now... In any case if the string doesn't match -- document is not well formed.
if (!fEntityScanner.skipString(endElementName.rawname)) {
reportFatalError(
"ETagRequired",
new Object[] { endElementName.rawname });
}
// end
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('>', NameType.ELEMENTEND)) {
reportFatalError(
"ETagUnterminated",
new Object[] { endElementName.rawname });
}
fMarkupDepth--;
//we have increased the depth for two markup "<" characters
fMarkupDepth--;
// check that this element was opened in the same entity
if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
reportFatalError(
"ElementEntityMismatch",
new Object[] { endElementName.rawname });
}
// call handler
if (fDocumentHandler != null) {
fDocumentHandler.endElement(endElementName, null);
/*if (fBindNamespaces) {
fNamespaceContext.popContext();
}*/
}
if(dtdGrammarUtil != null)
dtdGrammarUtil.endElement(endElementName);
return fMarkupDepth;
} // scanEndElement():int
public void reset(XMLComponentManager componentManager)
throws XMLConfigurationException {
super.reset(componentManager);
fPerformValidation = false;
fBindNamespaces = false;
}
/** Creates a content Driver. */
protected Driver createContentDriver() {
return new NS11ContentDriver();
} // createContentDriver():Driver
/** return the next state on the input
*
* @return int
*/
public int next() throws IOException, XNIException {
//since namespace context should still be valid when the parser is at the end element state therefore
//we pop the context only when next() has been called after the end element state was encountered. - nb.
if((fScannerLastState == XMLEvent.END_ELEMENT) && fBindNamespaces){
fScannerLastState = -1;
fNamespaceContext.popContext();
}
return fScannerLastState = super.next();
}
/**
* Driver to handle content scanning.
*/
protected final class NS11ContentDriver extends ContentDriver {
/**
* Scan for root element hook. This method is a hook for
* subclasses to add code that handles scanning for the root
* element. This method will also attempt to remove DTD validator
* from the pipeline, if there is no DTD grammar. If DTD validator
* is no longer in the pipeline bind namespaces in the scanner.
*
*
* @return True if the caller should stop and return true which
* allows the scanner to switch to a new scanning
* Driver. A return value of false indicates that
* the content Driver should continue as normal.
*/
protected boolean scanRootElementHook()
throws IOException, XNIException {
if (fExternalSubsetResolver != null && !fSeenDoctypeDecl
&& !fDisallowDoctype && (fValidation || fLoadExternalDTD)) {
scanStartElementName();
resolveExternalSubsetAndRead();
reconfigurePipeline();
if (scanStartElementAfterName()) {
setScannerState(SCANNER_STATE_TRAILING_MISC);
setDriver(fTrailingMiscDriver);
return true;
}
}
else {
reconfigurePipeline();
if (scanStartElement()) {
setScannerState(SCANNER_STATE_TRAILING_MISC);
setDriver(fTrailingMiscDriver);
return true;
}
}
return false;
} // scanRootElementHook():boolean
/**
* Re-configures pipeline by removing the DTD validator
* if no DTD grammar exists. If no validator exists in the
* pipeline or there is no DTD grammar, namespace binding
* is performed by the scanner in the enclosing class.
*/
private void reconfigurePipeline() {
if (fDTDValidator == null) {
fBindNamespaces = true;
}
else if (!fDTDValidator.hasGrammar()) {
fBindNamespaces = true;
fPerformValidation = fDTDValidator.validate();
// re-configure pipeline
XMLDocumentSource source = fDTDValidator.getDocumentSource();
XMLDocumentHandler handler = fDTDValidator.getDocumentHandler();
source.setDocumentHandler(handler);
if (handler != null)
handler.setDocumentSource(source);
fDTDValidator.setDocumentSource(null);
fDTDValidator.setDocumentHandler(null);
}
} // reconfigurePipeline()
}
}

View File

@@ -0,0 +1,66 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
/**
* This class performs namespace binding on the startElement and endElement
* method calls in accordance with Namespaces in XML 1.1. It extends the standard,
* Namespace-1.0-compliant binder in order to do this.
*
* @xerces.internal
*
* @author Neil Graham, IBM
*
*/
public class XML11NamespaceBinder extends XMLNamespaceBinder {
//
// Constants
//
//
// Data
//
//
// Constructors
//
/** Default constructor. */
public XML11NamespaceBinder() {
} // <init>()
//
// Public methods
//
//
// Protected methods
//
// returns true iff the given prefix is bound to "" *and*
// this is disallowed by the version of XML namespaces in use.
protected boolean prefixBoundToNullURI(String uri, String localpart) {
return false;
} // prefixBoundToNullURI(String, String): boolean
} // class XML11NamespaceBinder

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
/**
* <p>This interface describes the properties of entities--their
* physical location and their name.</p>
*
* @xerces.internal
*
* @author Michael Glavassevich, IBM
*
*/
public interface XMLEntityDescription extends XMLResourceIdentifier {
/**
* Sets the name of the entity.
*
* @param name the name of the entity
*/
public void setEntityName(String name);
/**
* Returns the name of the entity.
*
* @return the name of the entity
*/
public String getEntityName();
} // XMLEntityDescription

View File

@@ -0,0 +1,79 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XNIException;
/**
* The entity handler interface defines methods to report information
* about the start and end of entities.
*
* @xerces.internal
*
* @see com.sun.org.apache.xerces.internal.impl.XMLEntityScanner
*
* @author Andy Clark, IBM
*
*/
public interface XMLEntityHandler {
//
// XMLEntityHandler methods
//
/**
* This method notifies of the start of an entity. The DTD has the
* pseudo-name of "[dtd]" parameter entity names start with '%'; and
* general entities are just specified by their name.
*
* @param name The name of the entity.
* @param identifier The resource identifier.
* @param encoding The auto-detected IANA encoding name of the entity
* stream. This value will be null in those situations
* where the entity encoding is not auto-detected (e.g.
* internal entities or a document entity that is
* parsed from a java.io.Reader).
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void startEntity(String name,
XMLResourceIdentifier identifier,
String encoding, Augmentations augs) throws XNIException;
/**
* This method notifies the end of an entity. The DTD has the pseudo-name
* of "[dtd]" parameter entity names start with '%'; and general entities
* are just specified by their name.
*
* @param name The name of the entity.
* @param augs Additional information that may include infoset augmentations
*
* @throws IOException This exception might be thrown when there is premature end of entity
* @throws XNIException Thrown by handler to signal an error.
*/
public void endEntity(String name, Augmentations augs) throws IOException, XNIException;
} // interface XMLEntityHandler

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,611 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
import com.sun.org.apache.xerces.internal.util.ErrorHandlerProxy;
import com.sun.org.apache.xerces.internal.util.MessageFormatter;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.xml.sax.ErrorHandler;
/**
* This class is a common element of all parser configurations and is
* used to report errors that occur. This component can be queried by
* parser components from the component manager using the following
* property ID:
* <pre>
* http://apache.org/xml/properties/internal/error-reporter
* </pre>
* <p>
* Errors are separated into domains that categorize a class of errors.
* In a parser configuration, the parser would register a
* <code>MessageFormatter</code> for each domain that is capable of
* localizing error messages and formatting them based on information
* about the error. Any parser component can invent new error domains
* and register additional message formatters to localize messages in
* those domains.
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://apache.org/xml/properties/internal/error-handler</li>
* </ul>
* <p>
* This component can use the following features and properties but they
* are not required:
* <ul>
* <li>http://apache.org/xml/features/continue-after-fatal-error</li>
* </ul>
*
* @xerces.internal
*
* @see MessageFormatter
*
* @author Eric Ye, IBM
* @author Andy Clark, IBM
*
*/
public class XMLErrorReporter
implements XMLComponent {
//
// Constants
//
// severity
/**
* Severity: warning. Warnings represent informational messages only
* that should not be considered serious enough to stop parsing or
* indicate an error in the document's validity.
*/
public static final short SEVERITY_WARNING = 0;
/**
* Severity: error. Common causes of errors are document structure and/or
* content that that does not conform to the grammar rules specified for
* the document. These are typically validation errors.
*/
public static final short SEVERITY_ERROR = 1;
/**
* Severity: fatal error. Fatal errors are errors in the syntax of the
* XML document or invalid byte sequences for a given encoding. The
* XML 1.0 Specification mandates that errors of this type are not
* recoverable.
* <p>
* <strong>Note:</strong> The parser does have a "continue after fatal
* error" feature but it should be used with extreme caution and care.
*/
public static final short SEVERITY_FATAL_ERROR = 2;
// feature identifiers
/** Feature identifier: continue after fatal error. */
protected static final String CONTINUE_AFTER_FATAL_ERROR =
Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
// property identifiers
/** Property identifier: error handler. */
protected static final String ERROR_HANDLER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
// recognized features and properties
/** Recognized features. */
private static final String[] RECOGNIZED_FEATURES = {
CONTINUE_AFTER_FATAL_ERROR,
};
/** Feature defaults. */
private static final Boolean[] FEATURE_DEFAULTS = {
null,
};
/** Recognized properties. */
private static final String[] RECOGNIZED_PROPERTIES = {
ERROR_HANDLER,
};
/** Property defaults. */
private static final Object[] PROPERTY_DEFAULTS = {
null,
};
//
// Data
//
/** The locale to be used to format error messages. */
protected Locale fLocale;
/** Mapping of Message formatters for domains. */
protected Map<String, MessageFormatter> fMessageFormatters;
/** Error handler. */
protected XMLErrorHandler fErrorHandler;
/** Document locator. */
protected XMLLocator fLocator;
/** Continue after fatal error feature. */
protected boolean fContinueAfterFatalError;
/**
* Default error handler. This error handler is only used in the
* absence of a registered error handler so that errors are not
* "swallowed" silently. This is one of the most common "problems"
* reported by users of the parser.
*/
protected XMLErrorHandler fDefaultErrorHandler;
/** A SAX proxy to the error handler contained in this error reporter. */
private ErrorHandler fSaxProxy = null;
//
// Constructors
//
/** Constructs an error reporter with a locator. */
public XMLErrorReporter() {
// REVISIT: [Q] Should the locator be passed to the reportError
// method? Otherwise, there is no way for a parser
// component to store information about where an
// error occurred so as to report it later.
//
// An example would be to record the location of
// IDREFs so that, at the end of the document, if
// there is no associated ID declared, the error
// could report the location information of the
// reference. -Ac
//
// NOTE: I added another reportError method that allows the
// caller to specify the location of the error being
// reported. -Ac
fMessageFormatters = new HashMap<>();
} // <init>()
//
// Methods
//
/**
* Sets the current locale.
*
* @param locale The new locale.
*/
public void setLocale(Locale locale) {
fLocale = locale;
} // setLocale(Locale)
/**
* Gets the current locale.
*
* @return the current Locale
*/
public Locale getLocale() {
return fLocale ;
} // getLocale(): Locale
/**
* Sets the document locator.
*
* @param locator The locator.
*/
public void setDocumentLocator(XMLLocator locator) {
fLocator = locator;
} // setDocumentLocator(XMLLocator)
/**
* Registers a message formatter for the specified domain.
* <p>
* <strong>Note:</strong> Registering a message formatter for a domain
* when there is already a formatter registered will cause the previous
* formatter to be lost. This method replaces any previously registered
* message formatter for the specified domain.
*
* @param domain
* @param messageFormatter
*/
public void putMessageFormatter(String domain,
MessageFormatter messageFormatter) {
fMessageFormatters.put(domain, messageFormatter);
} // putMessageFormatter(String,MessageFormatter)
/**
* Returns the message formatter associated with the specified domain,
* or null if no message formatter is registered for that domain.
*
* @param domain The domain of the message formatter.
*/
public MessageFormatter getMessageFormatter(String domain) {
return fMessageFormatters.get(domain);
} // getMessageFormatter(String):MessageFormatter
/**
* Removes the message formatter for the specified domain and
* returns the removed message formatter.
*
* @param domain The domain of the message formatter.
*/
public MessageFormatter removeMessageFormatter(String domain) {
return fMessageFormatters.remove(domain);
} // removeMessageFormatter(String):MessageFormatter
/**
* Reports an error. The error message passed to the error handler
* is formatted for the locale by the message formatter installed
* for the specified error domain.
*
* @param domain The error domain.
* @param key The key of the error message.
* @param arguments The replacement arguments for the error message,
* if needed.
* @param severity The severity of the error.
* @return The formatted error message.
*
* @see #SEVERITY_WARNING
* @see #SEVERITY_ERROR
* @see #SEVERITY_FATAL_ERROR
*/
public String reportError(String domain, String key, Object[] arguments,
short severity) throws XNIException {
return reportError(fLocator, domain, key, arguments, severity);
} // reportError(String,String,Object[],short):String
/**
* Reports an error. The error message passed to the error handler
* is formatted for the locale by the message formatter installed
* for the specified error domain.
*
* @param domain The error domain.
* @param key The key of the error message.
* @param arguments The replacement arguments for the error message,
* if needed.
* @param severity The severity of the error.
* @param exception The exception to wrap.
* @return The formatted error message.
*
* @see #SEVERITY_WARNING
* @see #SEVERITY_ERROR
* @see #SEVERITY_FATAL_ERROR
*/
public String reportError(String domain, String key, Object[] arguments,
short severity, Exception exception) throws XNIException {
return reportError(fLocator, domain, key, arguments, severity, exception);
} // reportError(String,String,Object[],short,Exception):String
/**
* Reports an error at a specific location.
*
* @param location The error location.
* @param domain The error domain.
* @param key The key of the error message.
* @param arguments The replacement arguments for the error message,
* if needed.
* @param severity The severity of the error.
* @return The formatted error message.
*
* @see #SEVERITY_WARNING
* @see #SEVERITY_ERROR
* @see #SEVERITY_FATAL_ERROR
*/
public String reportError(XMLLocator location,
String domain, String key, Object[] arguments,
short severity) throws XNIException {
return reportError(location, domain, key, arguments, severity, null);
} // reportError(XMLLocator,String,String,Object[],short):String
/**
* Reports an error at a specific location.
*
* @param location The error location.
* @param domain The error domain.
* @param key The key of the error message.
* @param arguments The replacement arguments for the error message,
* if needed.
* @param severity The severity of the error.
* @param exception The exception to wrap.
* @return The formatted error message.
*
* @see #SEVERITY_WARNING
* @see #SEVERITY_ERROR
* @see #SEVERITY_FATAL_ERROR
*/
public String reportError(XMLLocator location,
String domain, String key, Object[] arguments,
short severity, Exception exception) throws XNIException {
// REVISIT: [Q] Should we do anything about invalid severity
// parameter? -Ac
// format error message and create parse exception
MessageFormatter messageFormatter = getMessageFormatter(domain);
String message;
if (messageFormatter != null) {
message = messageFormatter.formatMessage(fLocale, key, arguments);
}
else {
StringBuffer str = new StringBuffer();
str.append(domain);
str.append('#');
str.append(key);
int argCount = arguments != null ? arguments.length : 0;
if (argCount > 0) {
str.append('?');
for (int i = 0; i < argCount; i++) {
str.append(arguments[i]);
if (i < argCount -1) {
str.append('&');
}
}
}
message = str.toString();
}
XMLParseException parseException = (exception != null) ?
new XMLParseException(location, message, exception) :
new XMLParseException(location, message);
// get error handler
XMLErrorHandler errorHandler = fErrorHandler;
if (errorHandler == null) {
if (fDefaultErrorHandler == null) {
fDefaultErrorHandler = new DefaultErrorHandler();
}
errorHandler = fDefaultErrorHandler;
}
// call error handler
switch (severity) {
case SEVERITY_WARNING: {
errorHandler.warning(domain, key, parseException);
break;
}
case SEVERITY_ERROR: {
errorHandler.error(domain, key, parseException);
break;
}
case SEVERITY_FATAL_ERROR: {
errorHandler.fatalError(domain, key, parseException);
if (!fContinueAfterFatalError) {
throw parseException;
}
break;
}
}
return message;
} // reportError(XMLLocator,String,String,Object[],short,Exception):String
//
// XMLComponent methods
//
/**
* Resets the component. The component can query the component manager
* about any features and properties that affect the operation of the
* component.
*
* @param componentManager The component manager.
*
* @throws SAXException Thrown by component on initialization error.
* For example, if a feature or property is
* required for the operation of the component, the
* component manager may throw a
* SAXNotRecognizedException or a
* SAXNotSupportedException.
*/
public void reset(XMLComponentManager componentManager)
throws XNIException {
// features
fContinueAfterFatalError = componentManager.getFeature(CONTINUE_AFTER_FATAL_ERROR, false);
// properties
fErrorHandler = (XMLErrorHandler)componentManager.getProperty(ERROR_HANDLER);
} // reset(XMLComponentManager)
/**
* Returns a list of feature identifiers that are recognized by
* this component. This method may return null if no features
* are recognized by this component.
*/
public String[] getRecognizedFeatures() {
return (String[])(RECOGNIZED_FEATURES.clone());
} // getRecognizedFeatures():String[]
/**
* Sets the state of a feature. This method is called by the component
* manager any time after reset when a feature changes state.
* <p>
* <strong>Note:</strong> Components should silently ignore features
* that do not affect the operation of the component.
*
* @param featureId The feature identifier.
* @param state The state of the feature.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
public void setFeature(String featureId, boolean state)
throws XMLConfigurationException {
//
// Xerces features
//
if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
//
// http://apache.org/xml/features/continue-after-fatal-error
// Allows the parser to continue after a fatal error.
// Normally, a fatal error would stop the parse.
//
if (suffixLength == Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE.length() &&
featureId.endsWith(Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE)) {
fContinueAfterFatalError = state;
}
}
} // setFeature(String,boolean)
// return state of given feature or false if unsupported.
public boolean getFeature(String featureId)
throws XMLConfigurationException {
//
// Xerces features
//
if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
//
// http://apache.org/xml/features/continue-after-fatal-error
// Allows the parser to continue after a fatal error.
// Normally, a fatal error would stop the parse.
//
if (suffixLength == Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE.length() &&
featureId.endsWith(Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE)) {
return fContinueAfterFatalError ;
}
}
return false;
} // setFeature(String,boolean)
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
* are recognized by this component.
*/
public String[] getRecognizedProperties() {
return (String[])(RECOGNIZED_PROPERTIES.clone());
} // getRecognizedProperties():String[]
/**
* Sets the value of a property. This method is called by the component
* manager any time after reset when a property changes value.
* <p>
* <strong>Note:</strong> Components should silently ignore properties
* that do not affect the operation of the component.
*
* @param propertyId The property identifier.
* @param value The value of the property.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
public void setProperty(String propertyId, Object value)
throws XMLConfigurationException {
//
// Xerces properties
//
if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
if (suffixLength == Constants.ERROR_HANDLER_PROPERTY.length() &&
propertyId.endsWith(Constants.ERROR_HANDLER_PROPERTY)) {
fErrorHandler = (XMLErrorHandler)value;
}
}
} // setProperty(String,Object)
/**
* Returns the default state for a feature, or null if this
* component does not want to report a default value for this
* feature.
*
* @param featureId The feature identifier.
*
* @since Xerces 2.2.0
*/
public Boolean getFeatureDefault(String featureId) {
for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
if (RECOGNIZED_FEATURES[i].equals(featureId)) {
return FEATURE_DEFAULTS[i];
}
}
return null;
} // getFeatureDefault(String):Boolean
/**
* Returns the default state for a property, or null if this
* component does not want to report a default value for this
* property.
*
* @param propertyId The property identifier.
*
* @since Xerces 2.2.0
*/
public Object getPropertyDefault(String propertyId) {
for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
return PROPERTY_DEFAULTS[i];
}
}
return null;
} // getPropertyDefault(String):Object
/**
* Get the internal XMLErrrorHandler.
*/
public XMLErrorHandler getErrorHandler() {
return fErrorHandler;
}
/**
* Gets the internal XMLErrorHandler
* as SAX ErrorHandler.
*/
public ErrorHandler getSAXErrorHandler() {
if (fSaxProxy == null) {
fSaxProxy = new ErrorHandlerProxy() {
protected XMLErrorHandler getErrorHandler() {
return fErrorHandler;
}
};
}
return fSaxProxy;
}
} // class XMLErrorReporter

View File

@@ -0,0 +1,648 @@
/*
* Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidatorFilter;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
import javax.xml.stream.events.XMLEvent;
/**
* This class adds the functionality of namespace processing.
*
* This class has been modified as per the new design which is more suited to
* efficiently build pull parser. Lot of improvements have been done and
* the code has been added to support stax functionality/features.
*
*
* This class scans an XML document, checks if document has a DTD, and if
* DTD is not found the scanner will remove the DTD Validator from the pipeline and perform
* namespace binding.
*
*
* @author Neeraj Bajaj, Sun Microsystems
* @author Venugopal Rao K, Sun Microsystems
* @author Elena Litani, IBM
*/
public class XMLNSDocumentScannerImpl
extends XMLDocumentScannerImpl {
/**
* If is true, the dtd validator is no longer in the pipeline
* and the scanner should bind namespaces
*/
protected boolean fBindNamespaces;
/** If validating parser, make sure we report an error in the
* scanner if DTD grammar is missing.*/
protected boolean fPerformValidation;
/** Default value of this feature is false, when in Stax mode this should be true */
protected boolean fNotAddNSDeclAsAttribute = false;
/** DTD validator */
private XMLDTDValidatorFilter fDTDValidator;
/** xmlns, default Namespace, declared */
private boolean fXmlnsDeclared = false;
/** Resets the fields of this scanner.
*/
public void reset(PropertyManager propertyManager) {
setPropertyManager(propertyManager);
super.reset(propertyManager);
fBindNamespaces = false;
fNotAddNSDeclAsAttribute = !((Boolean)propertyManager.getProperty(Constants.ADD_NAMESPACE_DECL_AS_ATTRIBUTE)).booleanValue();
}
public void reset(XMLComponentManager componentManager)
throws XMLConfigurationException {
super.reset(componentManager);
fNotAddNSDeclAsAttribute = false ;
fPerformValidation = false;
fBindNamespaces = false;
}
/** return the next state on the input
*
* @return int
*/
public int next() throws IOException, XNIException {
//since namespace context should still be valid when the parser is at the end element state therefore
//we pop the context only when next() has been called after the end element state was encountered. - nb.
if((fScannerLastState == XMLEvent.END_ELEMENT) && fBindNamespaces){
fScannerLastState = -1;
fNamespaceContext.popContext();
}
return fScannerLastState = super.next();
}
/**
* The scanner is responsible for removing DTD validator
* from the pipeline if it is not needed.
*
* @param previous The filter component before DTDValidator
* @param dtdValidator
* The DTDValidator
* @param next The documentHandler after the DTDValidator
*/
public void setDTDValidator(XMLDTDValidatorFilter dtd){
fDTDValidator = dtd;
}
/**
* Scans a start element. This method will handle the binding of
* namespace information and notifying the handler of the start
* of the element.
* <p>
* <pre>
* [44] EmptyElemTag ::= '&lt;' Name (S Attribute)* S? '/>'
* [40] STag ::= '&lt;' Name (S Attribute)* S? '>'
* </pre>
* <p>
* <strong>Note:</strong> This method assumes that the leading
* '&lt;' character has been consumed.
* <p>
* <strong>Note:</strong> This method uses the fElementQName and
* fAttributes variables. The contents of these variables will be
* destroyed. The caller should copy important information out of
* these variables before calling this method.
*
* @return True if element is empty. (i.e. It matches
* production [44].
*/
protected boolean scanStartElement()
throws IOException, XNIException {
if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +">>> scanStartElement()");
//when skipping is true and no more elements should be added
if(fSkip && !fAdd){
//get the stored element -- if everything goes right this should match the
//token in the buffer
QName name = fElementStack.getNext();
if(DEBUG_SKIP_ALGORITHM){
System.out.println("Trying to skip String = " + name.rawname);
}
//Be conservative -- if skipping fails -- stop.
fSkip = fEntityScanner.skipString(name.rawname); // skipQElement(name);
if(fSkip){
if(DEBUG_SKIP_ALGORITHM){
System.out.println("Element SUCESSFULLY skipped = " + name.rawname);
}
fElementStack.push();
fElementQName = name;
}else{
//if skipping fails reposition the stack or fallback to normal way of processing
fElementStack.reposition();
if(DEBUG_SKIP_ALGORITHM){
System.out.println("Element was NOT skipped, REPOSITIONING stack" );
}
}
}
//we are still at the stage of adding elements
//the elements were not matched or
//fSkip is not set to true
if(!fSkip || fAdd){
//get the next element from the stack
fElementQName = fElementStack.nextElement();
// There are two variables,fNamespaces and fBindNamespaces
//StAX uses XMLNSDocumentScannerImpl so this distinction needs to be maintained
if (fNamespaces) {
fEntityScanner.scanQName(fElementQName, NameType.ELEMENTSTART);
} else {
String name = fEntityScanner.scanName(NameType.ELEMENTSTART);
fElementQName.setValues(null, name, name, null);
}
if(DEBUG)System.out.println("Element scanned in start element is " + fElementQName.toString());
if(DEBUG_SKIP_ALGORITHM){
if(fAdd){
System.out.println("Elements are being ADDED -- elemet added is = " + fElementQName.rawname + " at count = " + fElementStack.fCount);
}
}
}
//when the elements are being added , we need to check if we are set for skipping the elements
if(fAdd){
//this sets the value of fAdd variable
fElementStack.matchElement(fElementQName);
}
//xxx: We dont need another pointer, fCurrentElement, we can use fElementQName
fCurrentElement = fElementQName;
String rawname = fElementQName.rawname;
checkDepth(rawname);
if (fBindNamespaces) {
fNamespaceContext.pushContext();
if (fScannerState == SCANNER_STATE_ROOT_ELEMENT) {
if (fPerformValidation) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MSG_GRAMMAR_NOT_FOUND",
new Object[]{ rawname},
XMLErrorReporter.SEVERITY_ERROR);
if (fDoctypeName == null || !fDoctypeName.equals(rawname)) {
fErrorReporter.reportError( XMLMessageFormatter.XML_DOMAIN,
"RootElementTypeMustMatchDoctypedecl",
new Object[]{fDoctypeName, rawname},
XMLErrorReporter.SEVERITY_ERROR);
}
}
}
}
fEmptyElement = false;
fAttributes.removeAllAttributes();
if(!seekCloseOfStartTag()){
fReadingAttributes = true;
fAttributeCacheUsedCount =0;
fStringBufferIndex =0;
fAddDefaultAttr = true;
fXmlnsDeclared = false;
do {
scanAttribute(fAttributes);
if (fSecurityManager != null && (!fSecurityManager.isNoLimit(fElementAttributeLimit)) &&
fAttributes.getLength() > fElementAttributeLimit){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"ElementAttributeLimit",
new Object[]{rawname, fElementAttributeLimit },
XMLErrorReporter.SEVERITY_FATAL_ERROR );
}
} while (!seekCloseOfStartTag());
fReadingAttributes=false;
}
if (fBindNamespaces) {
// REVISIT: is it required? forbit xmlns prefix for element
if (fElementQName.prefix == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"ElementXMLNSPrefix",
new Object[]{fElementQName.rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind the element
String prefix = fElementQName.prefix != null
? fElementQName.prefix : XMLSymbols.EMPTY_STRING;
// assign uri to the element
fElementQName.uri = fNamespaceContext.getURI(prefix);
// make sure that object in the element stack is updated as well
fCurrentElement.uri = fElementQName.uri;
if (fElementQName.prefix == null && fElementQName.uri != null) {
fElementQName.prefix = XMLSymbols.EMPTY_STRING;
}
if (fElementQName.prefix != null && fElementQName.uri == null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"ElementPrefixUnbound",
new Object[]{fElementQName.prefix, fElementQName.rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind attributes (xmlns are already bound bellow)
int length = fAttributes.getLength();
// fLength = 0; //initialize structure
for (int i = 0; i < length; i++) {
fAttributes.getName(i, fAttributeQName);
String aprefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
String uri = fNamespaceContext.getURI(aprefix);
// REVISIT: try removing the first "if" and see if it is faster.
//
if (fAttributeQName.uri != null && fAttributeQName.uri == uri) {
// checkDuplicates(fAttributeQName, fAttributes);
continue;
}
if (aprefix != XMLSymbols.EMPTY_STRING) {
fAttributeQName.uri = uri;
if (uri == null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[]{fElementQName.rawname,fAttributeQName.rawname,aprefix},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
fAttributes.setURI(i, uri);
// checkDuplicates(fAttributeQName, fAttributes);
}
}
if (length > 1) {
QName name = fAttributes.checkDuplicatesNS();
if (name != null) {
if (name.uri != null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[]{fElementQName.rawname, name.localpart, name.uri},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
} else {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNotUnique",
new Object[]{fElementQName.rawname, name.rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
}
if (fEmptyElement) {
//decrease the markup depth..
fMarkupDepth--;
// check that this element was opened in the same entity
if (fMarkupDepth < fEntityStack[fEntityDepth - 1]) {
reportFatalError("ElementEntityMismatch",
new Object[]{fCurrentElement.rawname});
}
// call handler
if (fDocumentHandler != null) {
if(DEBUG)
System.out.println("emptyElement = " + fElementQName);
fDocumentHandler.emptyElement(fElementQName, fAttributes, null);
}
//We should not be popping out the context here in endELement becaause the namespace context is still
//valid when parser is at the endElement state.
fScanEndElement = true;
//if (fBindNamespaces) {
// fNamespaceContext.popContext();
//}
//pop the element off the stack..
fElementStack.popElement();
} else {
if(dtdGrammarUtil != null)
dtdGrammarUtil.startElement(fElementQName,fAttributes);
if(fDocumentHandler != null){
//complete element and attributes are traversed in this function so we can send a callback
//here.
//<strong>we shouldn't be sending callback in scanDocument()</strong>
if(DEBUG)
System.out.println("startElement = " + fElementQName);
fDocumentHandler.startElement(fElementQName, fAttributes, null);
}
}
if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +"<<< scanStartElement(): "+fEmptyElement);
return fEmptyElement;
} // scanStartElement():boolean
/**
* Scans an attribute.
* <p>
* <pre>
* [41] Attribute ::= Name Eq AttValue
* </pre>
* <p>
* <strong>Note:</strong> This method assumes that the next
* character on the stream is the first character of the attribute
* name.
* <p>
* <strong>Note:</strong> This method uses the fAttributeQName and
* fQName variables. The contents of these variables will be
* destroyed.
*
* @param attributes The attributes list for the scanned attribute.
*/
protected void scanAttribute(XMLAttributesImpl attributes)
throws IOException, XNIException {
if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +">>> scanAttribute()");
// name
fEntityScanner.scanQName(fAttributeQName, NameType.ATTRIBUTENAME);
// equals
fEntityScanner.skipSpaces();
if (!fEntityScanner.skipChar('=', NameType.ATTRIBUTE)) {
reportFatalError("EqRequiredInAttribute",
new Object[]{fCurrentElement.rawname,fAttributeQName.rawname});
}
fEntityScanner.skipSpaces();
// content
int attrIndex = 0 ;
//REVISIT: one more case needs to be included: external PE and standalone is no
boolean isVC = fHasExternalDTD && !fStandalone;
// REVISIT: it seems that this function should not take attributes, and length
//fTempString would store attribute value
///fTempString2 would store attribute non-normalized value
//this function doesn't use 'attIndex'. We are adding the attribute later
//after we have figured out that current attribute is not namespace declaration
//since scanAttributeValue doesn't use attIndex parameter therefore we
//can safely add the attribute later..
XMLString tmpStr = getString();
/**
* Determine whether this is a namespace declaration that will be subject
* to the name limit check in the scanAttributeValue operation.
* Namespace declaration format: xmlns="..." or xmlns:prefix="..."
* Note that prefix:xmlns="..." isn't a namespace.
*/
String localpart = fAttributeQName.localpart;
String prefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
boolean isNSDecl = fBindNamespaces & (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS);
scanAttributeValue(tmpStr, fTempString2, fAttributeQName.rawname, attributes,
attrIndex, isVC, fCurrentElement.rawname, isNSDecl);
String value = null;
//fTempString.toString();
// record namespace declarations if any.
if (fBindNamespaces) {
if (isNSDecl) {
//check the length of URI
if (tmpStr.length > fXMLNameLimit) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MaxXMLNameLimit",
new Object[]{new String(tmpStr.ch,tmpStr.offset,tmpStr.length),
tmpStr.length, fXMLNameLimit,
fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.MAX_NAME_LIMIT)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// get the internalized value of this attribute
String uri = fSymbolTable.addSymbol(tmpStr.ch,tmpStr.offset,tmpStr.length);
value = uri;
// 1. "xmlns" can't be bound to any namespace
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 2. the namespace for "xmlns" can't be bound to any prefix
if (uri == NamespaceContext.XMLNS_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 3. "xml" can't be bound to any other namespace than it's own
if (localpart == XMLSymbols.PREFIX_XML) {
if (uri != NamespaceContext.XML_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
// 4. the namespace for "xml" can't be bound to any other prefix
else {
if (uri ==NamespaceContext.XML_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
//set it equal to XMLSymbols.PREFIX_XMLNS when namespace declaration
// is of type xmlns = "..", in this case prefix = "" and localname = XMLSymbols.PREFIX_XMLNS
//this special behavior is because of dependency on this behavior in DOM components
if(prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS){
fAttributeQName.prefix = XMLSymbols.PREFIX_XMLNS;
}
// http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix
// We should only report an error if there is a prefix,
// that is, the local part is not "xmlns". -SG
if (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"EmptyPrefixedAttName",
new Object[]{fAttributeQName},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// check for duplicate prefix bindings
if (((com.sun.org.apache.xerces.internal.util.NamespaceSupport) fNamespaceContext).containsPrefixInCurrentContext(prefix)) {
reportFatalError("AttributeNotUnique",
new Object[]{fCurrentElement.rawname,
fAttributeQName.rawname});
}
// declare prefix in context
boolean declared = fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
// check for duplicate xmlns declarations
if (!declared) { // by convention, prefix == "xmlns" | "xml"
// error if duplicate declaration
if (fXmlnsDeclared) {
reportFatalError("AttributeNotUnique",
new Object[]{fCurrentElement.rawname,
fAttributeQName.rawname});
}
// xmlns declared
fXmlnsDeclared = true;
}
//xerces internals (XSAttributeChecker) has dependency on namespace declaration returned
//as part of XMLAttributes.
//addition of namespace declaration to the attribute list is controlled by fNotAddNSDeclAsAttribute
//feature. This is required in Stax where namespace declarations are not considered as attribute
if(fNotAddNSDeclAsAttribute){
return ;
}
}
}
//add the attributes to the list of attributes
if (fBindNamespaces) {
attrIndex = attributes.getLength();
attributes.addAttributeNS(fAttributeQName, XMLSymbols.fCDATASymbol, null);
} else {
int oldLen = attributes.getLength();
attrIndex = attributes.addAttribute(fAttributeQName, XMLSymbols.fCDATASymbol, null);
// WFC: Unique Att Spec
if (oldLen == attributes.getLength()) {
reportFatalError("AttributeNotUnique",
new Object[]{fCurrentElement.rawname,
fAttributeQName.rawname});
}
}
attributes.setValue(attrIndex, value,tmpStr);
//attributes.setNonNormalizedValue(attrIndex, fTempString2.toString());
//removing as we are not using non-normalized values . -Venu
attributes.setSpecified(attrIndex, true);
// attempt to bind attribute
if (fAttributeQName.prefix != null) {
attributes.setURI(attrIndex, fNamespaceContext.getURI(fAttributeQName.prefix));
}
if (DEBUG_START_END_ELEMENT) System.out.println(this.getClass().toString() +"<<< scanAttribute()");
} // scanAttribute(XMLAttributes)
/** Creates a content driver. */
protected Driver createContentDriver() {
return new NSContentDriver();
} // createContentDriver():Driver
/**
* Driver to handle content scanning.
*/
protected final class NSContentDriver
extends ContentDriver {
/**
* Scan for root element hook. This method is a hook for
* subclasses to add code that handles scanning for the root
* element. This method will also attempt to remove DTD validator
* from the pipeline, if there is no DTD grammar. If DTD validator
* is no longer in the pipeline bind namespaces in the scanner.
*
*
* @return True if the caller should stop and return true which
* allows the scanner to switch to a new scanning
* driver. A return value of false indicates that
* the content driver should continue as normal.
*/
protected boolean scanRootElementHook()
throws IOException, XNIException {
reconfigurePipeline();
if (scanStartElement()) {
setScannerState(SCANNER_STATE_TRAILING_MISC);
setDriver(fTrailingMiscDriver);
return true;
}
return false;
} // scanRootElementHook():boolean
/**
* Re-configures pipeline by removing the DTD validator
* if no DTD grammar exists. If no validator exists in the
* pipeline or there is no DTD grammar, namespace binding
* is performed by the scanner in the enclosing class.
*/
private void reconfigurePipeline() {
//fDTDValidator will be null in Stax mode
if (fNamespaces && fDTDValidator == null) {
fBindNamespaces = true;
}
else if (fNamespaces && !fDTDValidator.hasGrammar() ) {
fBindNamespaces = true;
fPerformValidation = fDTDValidator.validate();
// re-configure pipeline by removing DTDValidator
XMLDocumentSource source = fDTDValidator.getDocumentSource();
XMLDocumentHandler handler = fDTDValidator.getDocumentHandler();
source.setDocumentHandler(handler);
if (handler != null)
handler.setDocumentSource(source);
fDTDValidator.setDocumentSource(null);
fDTDValidator.setDocumentHandler(null);
}
} // reconfigurePipeline()
}
} // class XMLNSDocumentScannerImpl

View File

@@ -0,0 +1,848 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
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;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
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.parser.XMLComponent;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
/**
* This class performs namespace binding on the startElement and endElement
* method calls and passes all other methods through to the registered
* document handler. This class can be configured to only pass the
* start and end prefix mappings (start/endPrefixMapping).
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/namespaces</li>
* <li>http://apache.org/xml/properties/internal/symbol-table</li>
* <li>http://apache.org/xml/properties/internal/error-reporter</li>
* </ul>
*
* @xerces.internal
*
* @author Andy Clark, IBM
*
*/
public class XMLNamespaceBinder
implements XMLComponent, XMLDocumentFilter {
//
// Constants
//
// feature identifiers
/** Feature identifier: namespaces. */
protected static final String NAMESPACES =
Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
// property identifiers
/** Property identifier: symbol table. */
protected static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
/** Property identifier: error reporter. */
protected static final String ERROR_REPORTER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
// recognized features and properties
/** Recognized features. */
private static final String[] RECOGNIZED_FEATURES = {
NAMESPACES,
};
/** Feature defaults. */
private static final Boolean[] FEATURE_DEFAULTS = {
null,
};
/** Recognized properties. */
private static final String[] RECOGNIZED_PROPERTIES = {
SYMBOL_TABLE,
ERROR_REPORTER,
};
/** Property defaults. */
private static final Object[] PROPERTY_DEFAULTS = {
null,
null,
};
//
// Data
//
// features
/** Namespaces. */
protected boolean fNamespaces;
// properties
/** Symbol table. */
protected SymbolTable fSymbolTable;
/** Error reporter. */
protected XMLErrorReporter fErrorReporter;
// handlers
/** Document handler. */
protected XMLDocumentHandler fDocumentHandler;
protected XMLDocumentSource fDocumentSource;
// settings
/** Only pass start and end prefix mapping events. */
protected boolean fOnlyPassPrefixMappingEvents;
// shared context
/** Namespace context. */
private NamespaceContext fNamespaceContext;
// temp vars
/** Attribute QName. */
private QName fAttributeQName = new QName();
//
// Constructors
//
/** Default constructor. */
public XMLNamespaceBinder() {
} // <init>()
//
// Public methods
//
// settings
/**
* Sets whether the namespace binder only passes the prefix mapping
* events to the registered document handler or passes all document
* events.
*
* @param onlyPassPrefixMappingEvents True to pass only the prefix
* mapping events; false to pass
* all events.
*/
public void setOnlyPassPrefixMappingEvents(boolean onlyPassPrefixMappingEvents) {
fOnlyPassPrefixMappingEvents = onlyPassPrefixMappingEvents;
} // setOnlyPassPrefixMappingEvents(boolean)
/**
* Returns true if the namespace binder only passes the prefix mapping
* events to the registered document handler; false if the namespace
* binder passes all document events.
*/
public boolean getOnlyPassPrefixMappingEvents() {
return fOnlyPassPrefixMappingEvents;
} // getOnlyPassPrefixMappingEvents():boolean
//
// XMLComponent methods
//
/**
* Resets the component. The component can query the component manager
* about any features and properties that affect the operation of the
* component.
*
* @param componentManager The component manager.
*
* @throws SAXException Thrown by component on initialization error.
* For example, if a feature or property is
* required for the operation of the component, the
* component manager may throw a
* SAXNotRecognizedException or a
* SAXNotSupportedException.
*/
public void reset(XMLComponentManager componentManager)
throws XNIException {
// features
fNamespaces = componentManager.getFeature(NAMESPACES, true);
// Xerces properties
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
} // reset(XMLComponentManager)
/**
* Returns a list of feature identifiers that are recognized by
* this component. This method may return null if no features
* are recognized by this component.
*/
public String[] getRecognizedFeatures() {
return (String[])(RECOGNIZED_FEATURES.clone());
} // getRecognizedFeatures():String[]
/**
* Sets the state of a feature. This method is called by the component
* manager any time after reset when a feature changes state.
* <p>
* <strong>Note:</strong> Components should silently ignore features
* that do not affect the operation of the component.
*
* @param featureId The feature identifier.
* @param state The state of the feature.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
public void setFeature(String featureId, boolean state)
throws XMLConfigurationException {
} // setFeature(String,boolean)
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
* are recognized by this component.
*/
public String[] getRecognizedProperties() {
return (String[])(RECOGNIZED_PROPERTIES.clone());
} // getRecognizedProperties():String[]
/**
* Sets the value of a property during parsing.
*
* @param propertyId
* @param value
*/
public void setProperty(String propertyId, Object value)
throws XMLConfigurationException {
// Xerces properties
if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
if (suffixLength == Constants.SYMBOL_TABLE_PROPERTY.length() &&
propertyId.endsWith(Constants.SYMBOL_TABLE_PROPERTY)) {
fSymbolTable = (SymbolTable)value;
}
else if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() &&
propertyId.endsWith(Constants.ERROR_REPORTER_PROPERTY)) {
fErrorReporter = (XMLErrorReporter)value;
}
return;
}
} // setProperty(String,Object)
/**
* Returns the default state for a feature, or null if this
* component does not want to report a default value for this
* feature.
*
* @param featureId The feature identifier.
*
* @since Xerces 2.2.0
*/
public Boolean getFeatureDefault(String featureId) {
for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
if (RECOGNIZED_FEATURES[i].equals(featureId)) {
return FEATURE_DEFAULTS[i];
}
}
return null;
} // getFeatureDefault(String):Boolean
/**
* Returns the default state for a property, or null if this
* component does not want to report a default value for this
* property.
*
* @param propertyId The property identifier.
*
* @since Xerces 2.2.0
*/
public Object getPropertyDefault(String propertyId) {
for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
return PROPERTY_DEFAULTS[i];
}
}
return null;
} // getPropertyDefault(String):Object
//
// XMLDocumentSource methods
//
/** Sets the document handler to receive information about the document. */
public void setDocumentHandler(XMLDocumentHandler documentHandler) {
fDocumentHandler = documentHandler;
} // setDocumentHandler(XMLDocumentHandler)
/** Returns the document handler */
public XMLDocumentHandler getDocumentHandler() {
return fDocumentHandler;
} // setDocumentHandler(XMLDocumentHandler)
//
// XMLDocumentHandler methods
//
/** Sets the document source */
public void setDocumentSource(XMLDocumentSource source){
fDocumentSource = source;
} // setDocumentSource
/** Returns the document source */
public XMLDocumentSource getDocumentSource (){
return fDocumentSource;
} // getDocumentSource
/**
* This method notifies the start of a general entity.
* <p>
* <strong>Note:</strong> This method is not called for entity references
* appearing as part of attribute values.
*
* @param name The name of the general entity.
* @param identifier The resource identifier.
* @param encoding The auto-detected IANA encoding name of the entity
* stream. This value will be null in those situations
* where the entity encoding is not auto-detected (e.g.
* internal entities or a document entity that is
* parsed from a java.io.Reader).
* @param augs Additional information that may include infoset augmentations
*
* @exception XNIException Thrown by handler to signal an error.
*/
public void startGeneralEntity(String name,
XMLResourceIdentifier identifier,
String encoding, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs);
}
} // startEntity(String,String,String,String,String)
/**
* Notifies of the presence of a TextDecl line in an entity. If present,
* this method will be called immediately following the startEntity call.
* <p>
* <strong>Note:</strong> This method will never be called for the
* document entity; it is only called for external general entities
* referenced in document content.
* <p>
* <strong>Note:</strong> This method is not called for entity references
* appearing as part of attribute values.
*
* @param version The XML version, or null if not specified.
* @param encoding The IANA encoding name of the entity.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void textDecl(String version, String encoding, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.textDecl(version, encoding, augs);
}
} // textDecl(String,String)
/**
* The start of the document.
*
* @param locator The system identifier of the entity if the entity
* is external, null otherwise.
* @param encoding The auto-detected IANA encoding name of the entity
* stream. This value will be null in those situations
* where the entity encoding is not auto-detected (e.g.
* internal entities or a document entity that is
* parsed from a java.io.Reader).
* @param namespaceContext
* The namespace context in effect at the
* start of this document.
* This object represents the current context.
* Implementors of this class are responsible
* for copying the namespace bindings from the
* the current context (and its parent contexts)
* if that information is important.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void startDocument(XMLLocator locator, String encoding,
NamespaceContext namespaceContext, Augmentations augs)
throws XNIException {
fNamespaceContext = namespaceContext;
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.startDocument(locator, encoding, namespaceContext, augs);
}
} // startDocument(XMLLocator,String)
/**
* Notifies of the presence of an XMLDecl line in the document. If
* present, this method will be called immediately following the
* startDocument call.
*
* @param version The XML version.
* @param encoding The IANA encoding name of the document, or null if
* not specified.
* @param standalone The standalone value, or null if not specified.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void xmlDecl(String version, String encoding, String standalone, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.xmlDecl(version, encoding, standalone, augs);
}
} // xmlDecl(String,String,String)
/**
* Notifies of the presence of the DOCTYPE line in the document.
*
* @param rootElement The name of the root element.
* @param publicId The public identifier if an external DTD or null
* if the external DTD is specified using SYSTEM.
* @param systemId The system identifier if an external DTD, null
* otherwise.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void doctypeDecl(String rootElement,
String publicId, String systemId, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs);
}
} // doctypeDecl(String,String,String)
/**
* A comment.
*
* @param text The text in the comment.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by application to signal an error.
*/
public void comment(XMLString text, Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.comment(text, augs);
}
} // comment(XMLString)
/**
* A processing instruction. Processing instructions consist of a
* target name and, optionally, text data. The data is only meaningful
* to the application.
* <p>
* Typically, a processing instruction's data will contain a series
* of pseudo-attributes. These pseudo-attributes follow the form of
* element attributes but are <strong>not</strong> parsed or presented
* to the application as anything other than text. The application is
* responsible for parsing the data.
*
* @param target The target.
* @param data The data or null if none specified.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void processingInstruction(String target, XMLString data, Augmentations augs)
throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.processingInstruction(target, data, augs);
}
} // processingInstruction(String,XMLString)
/**
* Binds the namespaces. This method will handle calling the
* document handler to start the prefix mappings.
* <p>
* <strong>Note:</strong> This method makes use of the
* fAttributeQName variable. Any contents of the variable will
* be destroyed. Caller should copy the values out of this
* temporary variable before calling this method.
*
* @param element The name of the element.
* @param attributes The element attributes.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
throws XNIException {
if (fNamespaces) {
handleStartElement(element, attributes, augs, false);
}
else if (fDocumentHandler != null) {
fDocumentHandler.startElement(element, attributes, augs);
}
} // startElement(QName,XMLAttributes)
/**
* An empty element.
*
* @param element The name of the element.
* @param attributes The element attributes.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs)
throws XNIException {
if (fNamespaces) {
handleStartElement(element, attributes, augs, true);
handleEndElement(element, augs, true);
}
else if (fDocumentHandler != null) {
fDocumentHandler.emptyElement(element, attributes, augs);
}
} // emptyElement(QName,XMLAttributes)
/**
* Character content.
*
* @param text The content.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void characters(XMLString text, Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.characters(text, augs);
}
} // characters(XMLString)
/**
* Ignorable whitespace. For this method to be called, the document
* source must have some way of determining that the text containing
* only whitespace characters should be considered ignorable. For
* example, the validator can determine if a length of whitespace
* characters in the document are ignorable based on the element
* content model.
*
* @param text The ignorable whitespace.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.ignorableWhitespace(text, augs);
}
} // ignorableWhitespace(XMLString)
/**
* The end of an element.
*
* @param element The name of the element.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void endElement(QName element, Augmentations augs) throws XNIException {
if (fNamespaces) {
handleEndElement(element, augs, false);
}
else if (fDocumentHandler != null) {
fDocumentHandler.endElement(element, augs);
}
} // endElement(QName)
/**
* The start of a CDATA section.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void startCDATA(Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.startCDATA(augs);
}
} // startCDATA()
/**
* The end of a CDATA section.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void endCDATA(Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.endCDATA(augs);
}
} // endCDATA()
/**
* The end of the document.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void endDocument(Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.endDocument(augs);
}
} // endDocument()
/**
* This method notifies the end of a general entity.
* <p>
* <strong>Note:</strong> This method is not called for entity references
* appearing as part of attribute values.
*
* @param name The name of the entity.
* @param augs Additional information that may include infoset augmentations
*
* @exception XNIException
* Thrown by handler to signal an error.
*/
public void endGeneralEntity(String name, Augmentations augs) throws XNIException {
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
fDocumentHandler.endGeneralEntity(name, augs);
}
} // endEntity(String)
//
// Protected methods
//
/** Handles start element. */
protected void handleStartElement(QName element, XMLAttributes attributes,
Augmentations augs,
boolean isEmpty) throws XNIException {
// add new namespace context
fNamespaceContext.pushContext();
if (element.prefix == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"ElementXMLNSPrefix",
new Object[]{element.rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// search for new namespace bindings
int length = attributes.getLength();
for (int i = 0; i < length; i++) {
String localpart = attributes.getLocalName(i);
String prefix = attributes.getPrefix(i);
// when it's of form xmlns="..." or xmlns:prefix="...",
// it's a namespace declaration. but prefix:xmlns="..." isn't.
if (prefix == XMLSymbols.PREFIX_XMLNS ||
prefix == XMLSymbols.EMPTY_STRING && localpart == XMLSymbols.PREFIX_XMLNS) {
// get the internalized value of this attribute
String uri = fSymbolTable.addSymbol(attributes.getValue(i));
// 1. "xmlns" can't be bound to any namespace
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[]{attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 2. the namespace for "xmlns" can't be bound to any prefix
if (uri == NamespaceContext.XMLNS_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[]{attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 3. "xml" can't be bound to any other namespace than it's own
if (localpart == XMLSymbols.PREFIX_XML) {
if (uri != NamespaceContext.XML_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[]{attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
// 4. the namespace for "xml" can't be bound to any other prefix
else {
if (uri ==NamespaceContext.XML_URI) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[]{attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
// http://www.w3.org/TR/1999/REC-xml-names-19990114/#dt-prefix
// We should only report an error if there is a prefix,
// that is, the local part is not "xmlns". -SG
// Since this is an error condition in XML 1.0,
// and should be relatively uncommon in XML 1.1,
// making this test into a method call to reuse code
// should be acceptable. - NG
if(prefixBoundToNullURI(uri, localpart)) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"EmptyPrefixedAttName",
new Object[]{attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
continue;
}
// declare prefix in context
fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
}
}
// bind the element
String prefix = element.prefix != null
? element.prefix : XMLSymbols.EMPTY_STRING;
element.uri = fNamespaceContext.getURI(prefix);
if (element.prefix == null && element.uri != null) {
element.prefix = XMLSymbols.EMPTY_STRING;
}
if (element.prefix != null && element.uri == null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"ElementPrefixUnbound",
new Object[]{element.prefix, element.rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind the attributes
for (int i = 0; i < length; i++) {
attributes.getName(i, fAttributeQName);
String aprefix = fAttributeQName.prefix != null
? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
String arawname = fAttributeQName.rawname;
if (arawname == XMLSymbols.PREFIX_XMLNS) {
fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS);
attributes.setName(i, fAttributeQName);
}
else if (aprefix != XMLSymbols.EMPTY_STRING) {
fAttributeQName.uri = fNamespaceContext.getURI(aprefix);
if (fAttributeQName.uri == null) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[]{element.rawname,arawname,aprefix},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
attributes.setName(i, fAttributeQName);
}
}
// verify that duplicate attributes don't exist
// Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
int attrCount = attributes.getLength();
for (int i = 0; i < attrCount - 1; i++) {
String auri = attributes.getURI(i);
if (auri == null || auri == NamespaceContext.XMLNS_URI) {
continue;
}
String alocalpart = attributes.getLocalName(i);
for (int j = i + 1; j < attrCount; j++) {
String blocalpart = attributes.getLocalName(j);
String buri = attributes.getURI(j);
if (alocalpart == blocalpart && auri == buri) {
fErrorReporter.reportError(XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[]{element.rawname,alocalpart, auri},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
// call handler
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
if (isEmpty) {
fDocumentHandler.emptyElement(element, attributes, augs);
}
else {
fDocumentHandler.startElement(element, attributes, augs);
}
}
} // handleStartElement(QName,XMLAttributes,boolean)
/** Handles end element. */
protected void handleEndElement(QName element, Augmentations augs, boolean isEmpty)
throws XNIException {
// bind element
String eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
element.uri = fNamespaceContext.getURI(eprefix);
if (element.uri != null) {
element.prefix = eprefix;
}
// call handlers
if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
if (!isEmpty) {
fDocumentHandler.endElement(element, augs);
}
}
// pop context
fNamespaceContext.popContext();
} // handleEndElement(QName,boolean)
// returns true iff the given prefix is bound to "" *and*
// this is disallowed by the version of XML namespaces in use.
protected boolean prefixBoundToNullURI(String uri, String localpart) {
return (uri == XMLSymbols.EMPTY_STRING && localpart != XMLSymbols.PREFIX_XMLNS);
} // prefixBoundToNullURI(String, String): boolean
} // class XMLNamespaceBinder

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,533 @@
/*
* Copyright (c) 2005, 2006, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.org.apache.xerces.internal.impl;
import javax.xml.XMLConstants;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.StreamFilter;
import javax.xml.stream.XMLStreamException;
import javax.xml.namespace.QName;
import javax.xml.stream.events.XMLEvent;
/**
*
* @author Joe Wang:
* This is a rewrite of the original class. The focus is on removing caching, and make the filtered
* stream reader more compatible with those in other implementations. Note however, that this version
* will not solve all the issues related to the undefined condition in the spec. The priority is
* to pass the TCK. Issues arising due to the requirement, that is, (1) should it initiate at BEGIN_DOCUMENT
* or an accepted event; (2) should hasNext() advance the underlining stream in order to find an acceptable
* event, would have to wait until 1.1 of StAX in which the filtered stream reader would be defined more clearly.
*/
public class XMLStreamFilterImpl implements javax.xml.stream.XMLStreamReader {
private StreamFilter fStreamFilter = null;
private XMLStreamReader fStreamReader = null;
private int fCurrentEvent;
private boolean fEventAccepted = false;
/**the very issue around a long discussion. but since we must pass the TCK, we have to allow
* hasNext() to advance the underlining stream in order to find the next acceptable event
*/
private boolean fStreamAdvancedByHasNext = false;
/** Creates a new instance of XMLStreamFilterImpl */
public XMLStreamFilterImpl(XMLStreamReader reader,StreamFilter filter){
fStreamReader = reader;
this.fStreamFilter = filter;
//this is debatable to initiate at an acceptable event,
//but it's neccessary in order to pass the TCK and yet avoid skipping element
try {
if (fStreamFilter.accept(fStreamReader)) {
fEventAccepted = true;
} else {
findNextEvent();
}
}catch(XMLStreamException xs){
System.err.println("Error while creating a stream Filter"+xs);
}
}
/**
*
* @param sf
*/
protected void setStreamFilter(StreamFilter sf){
this.fStreamFilter = sf;
}
/**
*
* @return
* @throws XMLStreamException
*/
public int next() throws XMLStreamException {
if (fStreamAdvancedByHasNext && fEventAccepted) {
fStreamAdvancedByHasNext = false;
return fCurrentEvent;
}
int event = findNextEvent();
if (event != -1) {
return event;
}
throw new IllegalStateException("The stream reader has reached the end of the document, or there are no more "+
" items to return");
}
/**
*
* @throws XMLStreamException
* @return
*/
public int nextTag() throws XMLStreamException {
if (fStreamAdvancedByHasNext && fEventAccepted &&
(fCurrentEvent == XMLEvent.START_ELEMENT || fCurrentEvent == XMLEvent.START_ELEMENT)) {
fStreamAdvancedByHasNext = false;
return fCurrentEvent;
}
int event = findNextTag();
if (event != -1) {
return event;
}
throw new IllegalStateException("The stream reader has reached the end of the document, or there are no more "+
" items to return");
}
/**
*
* @throws XMLStreamException
* @return
*/
public boolean hasNext() throws XMLStreamException {
if (fStreamReader.hasNext()) {
if (!fEventAccepted) {
if ((fCurrentEvent = findNextEvent()) == -1) {
return false;
} else {
fStreamAdvancedByHasNext = true;
}
}
return true;
}
return false;
}
private int findNextEvent() throws XMLStreamException {
fStreamAdvancedByHasNext = false;
while(fStreamReader.hasNext()){
fCurrentEvent = fStreamReader.next();
if(fStreamFilter.accept(fStreamReader)){
fEventAccepted = true;
return fCurrentEvent;
}
}
//although it seems that IllegalStateException should be thrown when next() is called
//on a stream that has no more items, we have to assume END_DOCUMENT is always accepted
//in order to pass the TCK
if (fCurrentEvent == XMLEvent.END_DOCUMENT)
return fCurrentEvent;
else
return -1;
}
private int findNextTag() throws XMLStreamException {
fStreamAdvancedByHasNext = false;
while(fStreamReader.hasNext()){
fCurrentEvent = fStreamReader.nextTag();
if(fStreamFilter.accept(fStreamReader)){
fEventAccepted = true;
return fCurrentEvent;
}
}
if (fCurrentEvent == XMLEvent.END_DOCUMENT)
return fCurrentEvent;
else
return -1;
}
/**
*
* @throws XMLStreamException
*/
public void close() throws XMLStreamException {
fStreamReader.close();
}
/**
*
* @return
*/
public int getAttributeCount() {
return fStreamReader.getAttributeCount();
}
/**
*
* @param index
* @return
*/
public QName getAttributeName(int index) {
return fStreamReader.getAttributeName(index);
}
/**
*
* @param index
* @return
*/
public String getAttributeNamespace(int index) {
return fStreamReader.getAttributeNamespace(index);
}
/**
*
* @param index
* @return
*/
public String getAttributePrefix(int index) {
return fStreamReader.getAttributePrefix(index);
}
/**
*
* @param index
* @return
*/
public String getAttributeType(int index) {
return fStreamReader.getAttributeType(index);
}
/**
*
* @param index
* @return
*/
public String getAttributeValue(int index) {
return fStreamReader.getAttributeValue(index);
}
/**
*
* @param namespaceURI
* @param localName
* @return
*/
public String getAttributeValue(String namespaceURI, String localName) {
return fStreamReader.getAttributeValue(namespaceURI,localName);
}
/**
*
* @return
*/
public String getCharacterEncodingScheme() {
return fStreamReader.getCharacterEncodingScheme();
}
/**
*
* @throws XMLStreamException
* @return
*/
public String getElementText() throws XMLStreamException {
return fStreamReader.getElementText();
}
/**
*
* @return
*/
public String getEncoding() {
return fStreamReader.getEncoding();
}
/**
*
* @return
*/
public int getEventType() {
return fStreamReader.getEventType();
}
/**
*
* @return
*/
public String getLocalName() {
return fStreamReader.getLocalName();
}
/**
*
* @return
*/
public javax.xml.stream.Location getLocation() {
return fStreamReader.getLocation();
}
/**
*
* @return
*/
public javax.xml.namespace.QName getName() {
return fStreamReader.getName();
}
/**
*
* @return
*/
public javax.xml.namespace.NamespaceContext getNamespaceContext() {
return fStreamReader.getNamespaceContext();
}
/**
*
* @return
*/
public int getNamespaceCount() {
return fStreamReader.getNamespaceCount();
}
/**
*
* @param index
* @return
*/
public String getNamespacePrefix(int index) {
return fStreamReader.getNamespacePrefix(index);
}
/**
*
* @return
*/
public String getNamespaceURI() {
return fStreamReader.getNamespaceURI();
}
/**
*
* @param index
* @return
*/
public String getNamespaceURI(int index) {
return fStreamReader.getNamespaceURI(index);
}
/**
*
* @param prefix
* @return
*/
public String getNamespaceURI(String prefix) {
return fStreamReader.getNamespaceURI(prefix);
}
/**
*
* @return
*/
public String getPIData() {
return fStreamReader.getPIData();
}
/**
*
* @return
*/
public String getPITarget() {
return fStreamReader.getPITarget();
}
/**
*
* @return
*/
public String getPrefix() {
return fStreamReader.getPrefix();
}
/**
*
* @param name
* @throws IllegalArgumentException
* @return
*/
public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
return fStreamReader.getProperty(name);
}
/**
*
* @return
*/
public String getText() {
return fStreamReader.getText();
}
/**
*
* @return
*/
public char[] getTextCharacters() {
return fStreamReader.getTextCharacters();
}
/**
*
* @param sourceStart
* @param target
* @param targetStart
* @param length
* @throws XMLStreamException
* @return
*/
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
return fStreamReader.getTextCharacters(sourceStart, target,targetStart,length);
}
/**
*
* @return
*/
public int getTextLength() {
return fStreamReader.getTextLength();
}
/**
*
* @return
*/
public int getTextStart() {
return fStreamReader.getTextStart();
}
/**
*
* @return
*/
public String getVersion() {
return fStreamReader.getVersion();
}
/**
*
* @return
*/
public boolean hasName() {
return fStreamReader.hasName();
}
/**
*
* @return
*/
public boolean hasText() {
return fStreamReader.hasText();
}
/**
*
* @return
* @param index
*/
public boolean isAttributeSpecified(int index) {
return fStreamReader.isAttributeSpecified(index);
}
/**
*
* @return
*/
public boolean isCharacters() {
return fStreamReader.isCharacters();
}
/**
*
* @return
*/
public boolean isEndElement() {
return fStreamReader.isEndElement();
}
/**
*
* @return
*/
public boolean isStandalone() {
return fStreamReader.isStandalone();
}
/**
*
* @return
*/
public boolean isStartElement() {
return fStreamReader.isStartElement();
}
/**
*
* @return
*/
public boolean isWhiteSpace() {
return fStreamReader.isWhiteSpace();
}
/**
*
* @param type
* @param namespaceURI
* @param localName
* @throws XMLStreamException
*/
public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
fStreamReader.require(type,namespaceURI,localName);
}
/**
*
* @return
*/
public boolean standaloneSet() {
return fStreamReader.standaloneSet();
}
/**
*
* @param index
* @return
*/
public String getAttributeLocalName(int index){
return fStreamReader.getAttributeLocalName(index);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl;
import java.io.EOFException;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.xml.internal.stream.Entity.ScannedEntity;
/**
* This class scans the version of the document to determine
* which scanner to use: XML 1.1 or XML 1.0.
* The version is scanned using XML 1.1. scanner.
*
* @xerces.internal
*
* @author Neil Graham, IBM
* @author Elena Litani, IBM
*/
public class XMLVersionDetector {
//
// Constants
//
private final static char[] XML11_VERSION = new char[]{'1', '.', '1'};
// property identifiers
/** Property identifier: symbol table. */
protected static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
/** Property identifier: error reporter. */
protected static final String ERROR_REPORTER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
/** Property identifier: entity manager. */
protected static final String ENTITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
//
// Data
//
/** Symbol: "version". */
protected final static String fVersionSymbol = "version".intern();
// symbol: [xml]:
protected static final String fXMLSymbol = "[xml]".intern();
/** Symbol table. */
protected SymbolTable fSymbolTable;
/** Error reporter. */
protected XMLErrorReporter fErrorReporter;
/** Entity manager. */
protected XMLEntityManager fEntityManager;
protected String fEncoding = null;
private XMLString fVersionNum = new XMLString();
private final char [] fExpectedVersionString = {'<', '?', 'x', 'm', 'l', ' ', 'v', 'e', 'r', 's',
'i', 'o', 'n', '=', ' ', ' ', ' ', ' ', ' '};
/**
*
*
* @param componentManager The component manager.
*
* @throws SAXException Throws exception if required features and
* properties cannot be found.
*/
public void reset(XMLComponentManager componentManager)
throws XMLConfigurationException {
// Xerces properties
fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE);
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
for(int i=14; i<fExpectedVersionString.length; i++ )
fExpectedVersionString[i] = ' ';
} // reset(XMLComponentManager)
/**
* Reset the reference to the appropriate scanner given the version of the
* document and start document scanning.
* @param scanner - the scanner to use
* @param version - the version of the document (XML 1.1 or XML 1.0).
*/
public void startDocumentParsing(XMLEntityHandler scanner, short version){
if (version == Constants.XML_VERSION_1_0){
fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
}
else {
fEntityManager.setScannerVersion(Constants.XML_VERSION_1_1);
}
// Make sure the locator used by the error reporter is the current entity scanner.
fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
// Note: above we reset fEntityScanner in the entity manager, thus in startEntity
// in each scanner fEntityScanner field must be reset to reflect the change.
//
fEntityManager.setEntityHandler(scanner);
scanner.startEntity(fXMLSymbol, fEntityManager.getCurrentResourceIdentifier(), fEncoding, null);
}
/**
* This methods scans the XML declaration to find out the version
* (and provisional encoding) of the document.
* The scanning is doing using XML 1.1 scanner.
* @param inputSource
* @return short - Constants.XML_VERSION_1_1 if document version 1.1,
* otherwise Constants.XML_VERSION_1_0
* @throws IOException
*/
public short determineDocVersion(XMLInputSource inputSource) throws IOException {
fEncoding = fEntityManager.setupCurrentEntity(false, fXMLSymbol, inputSource, false, true);
// Must use XML 1.0 scanner to handle whitespace correctly
// in the XML declaration.
fEntityManager.setScannerVersion(Constants.XML_VERSION_1_0);
XMLEntityScanner scanner = fEntityManager.getEntityScanner();
scanner.detectingVersion = true;
try {
if (!scanner.skipString("<?xml")) {
// definitely not a well-formed 1.1 doc!
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0;
}
if (!scanner.skipDeclSpaces()) {
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 5);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0;
}
if (!scanner.skipString("version")) {
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 6);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0;
}
scanner.skipDeclSpaces();
// Check if the next character is '='. If it is then consume it.
if (scanner.peekChar() != '=') {
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 13);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0;
}
scanner.scanChar(null);
scanner.skipDeclSpaces();
int quoteChar = scanner.scanChar(null);
fExpectedVersionString[14] = (char) quoteChar;
for (int versionPos = 0; versionPos < XML11_VERSION.length; versionPos++) {
fExpectedVersionString[15 + versionPos] = (char) scanner.scanChar(null);
}
// REVISIT: should we check whether this equals quoteChar?
fExpectedVersionString[18] = (char) scanner.scanChar(null);
fixupCurrentEntity(fEntityManager, fExpectedVersionString, 19);
int matched = 0;
for (; matched < XML11_VERSION.length; matched++) {
if (fExpectedVersionString[15 + matched] != XML11_VERSION[matched])
break;
}
scanner.detectingVersion = false;
if (matched == XML11_VERSION.length)
return Constants.XML_VERSION_1_1;
return Constants.XML_VERSION_1_0;
// premature end of file
}
catch (EOFException e) {
fErrorReporter.reportError(
XMLMessageFormatter.XML_DOMAIN,
"PrematureEOF",
null,
XMLErrorReporter.SEVERITY_FATAL_ERROR);
scanner.detectingVersion = false;
return Constants.XML_VERSION_1_0;
}
}
// This method prepends "length" chars from the char array,
// from offset 0, to the manager's fCurrentEntity.ch.
private void fixupCurrentEntity(XMLEntityManager manager,
char [] scannedChars, int length) {
ScannedEntity currentEntity = manager.getCurrentEntity();
if(currentEntity.count-currentEntity.position+length > currentEntity.ch.length) {
//resize array; this case is hard to imagine...
char[] tempCh = currentEntity.ch;
currentEntity.ch = new char[length+currentEntity.count-currentEntity.position+1];
System.arraycopy(tempCh, 0, currentEntity.ch, 0, tempCh.length);
}
if(currentEntity.position < length) {
// have to move sensitive stuff out of the way...
System.arraycopy(currentEntity.ch, currentEntity.position, currentEntity.ch, length, currentEntity.count-currentEntity.position);
currentEntity.count += length-currentEntity.position;
} else {
// have to reintroduce some whitespace so this parses:
for(int i=length; i<currentEntity.position; i++)
currentEntity.ch[i]=' ';
}
// prepend contents...
System.arraycopy(scannedChars, 0, currentEntity.ch, 0, length);
currentEntity.position = 0;
currentEntity.baseCharOffset = 0;
currentEntity.startPosition = 0;
currentEntity.columnNumber = currentEntity.lineNumber = 1;
}
} // class XMLVersionDetector

View File

@@ -0,0 +1,287 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XNIException;
/**
* <p>A DTD grammar that produces balanced syntax trees.</p>
*
* @xerces.internal
*
* @author Michael Glavassevich, IBM
*/
final class BalancedDTDGrammar extends DTDGrammar {
//
// Data
//
/** Mixed. */
private boolean fMixed;
/** Stack depth */
private int fDepth = 0;
/** Children content model operation stack. */
private short [] fOpStack = null;
/** Holder for choice/sequence/leaf groups at each depth. */
private int [][] fGroupIndexStack;
/** Sizes of the allocated portions of each int[] in fGroupIndexStack. */
private int [] fGroupIndexStackSizes;
//
// Constructors
//
/** Default constructor. */
public BalancedDTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) {
super(symbolTable, desc);
} // BalancedDTDGrammar(SymbolTable,XMLDTDDescription)
//
// Public methods
//
/**
* The start of a content model. Depending on the type of the content
* model, specific methods may be called between the call to the
* startContentModel method and the call to the endContentModel method.
*
* @param elementName The name of the element.
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*/
public final void startContentModel(String elementName, Augmentations augs)
throws XNIException {
fDepth = 0;
initializeContentModelStacks();
super.startContentModel(elementName, augs);
} // startContentModel(String)
/**
* A start of either a mixed or children content model. A mixed
* content model will immediately be followed by a call to the
* <code>pcdata()</code> method. A children content model will
* contain additional groups and/or elements.
*
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*
* @see #any
* @see #empty
*/
public final void startGroup(Augmentations augs) throws XNIException {
++fDepth;
initializeContentModelStacks();
fMixed = false;
} // startGroup()
/**
* The appearance of "#PCDATA" within a group signifying a
* mixed content model. This method will be the first called
* following the content model's <code>startGroup()</code>.
*
*@param augs Additional information that may include infoset
* augmentations.
*
* @throws XNIException Thrown by handler to signal an error.
*
* @see #startGroup
*/
public final void pcdata(Augmentations augs) throws XNIException {
fMixed = true;
} // pcdata()
/**
* A referenced element in a mixed or children content model.
*
* @param elementName The name of the referenced element.
* @param augs Additional information that may include infoset
* augmentations.
*
* @throws XNIException Thrown by handler to signal an error.
*/
public final void element(String elementName, Augmentations augs) throws XNIException {
addToCurrentGroup(addUniqueLeafNode(elementName));
} // element(String)
/**
* The separator between choices or sequences of a mixed or children
* content model.
*
* @param separator The type of children separator.
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE
*/
public final void separator(short separator, Augmentations augs) throws XNIException {
if (separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE) {
fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
}
else if (separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) {
fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
}
} // separator(short)
/**
* The occurrence count for a child in a children content model or
* for the mixed content model group.
*
* @param occurrence The occurrence count for the last element
* or group.
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE
* @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE
*/
public final void occurrence(short occurrence, Augmentations augs) throws XNIException {
if (!fMixed) {
int currentIndex = fGroupIndexStackSizes[fDepth] - 1;
if (occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE) {
fGroupIndexStack[fDepth][currentIndex] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fGroupIndexStack[fDepth][currentIndex], -1);
}
else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE) {
fGroupIndexStack[fDepth][currentIndex] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fGroupIndexStack[fDepth][currentIndex], -1);
}
else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) {
fGroupIndexStack[fDepth][currentIndex] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fGroupIndexStack[fDepth][currentIndex], -1);
}
}
} // occurrence(short)
/**
* The end of a group for mixed or children content models.
*
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*/
public final void endGroup(Augmentations augs) throws XNIException {
final int length = fGroupIndexStackSizes[fDepth];
final int group = length > 0 ? addContentSpecNodes(0, length - 1) : addUniqueLeafNode(null);
--fDepth;
addToCurrentGroup(group);
} // endGroup()
/**
* The end of the DTD.
*
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*/
public final void endDTD(Augmentations augs) throws XNIException {
super.endDTD(augs);
fOpStack = null;
fGroupIndexStack = null;
fGroupIndexStackSizes = null;
} // endDTD()
//
// Protected methods
//
/**
* Adds the content spec to the given element declaration.
*/
protected final void addContentSpecToElement(XMLElementDecl elementDecl) {
int contentSpec = fGroupIndexStackSizes[0] > 0 ? fGroupIndexStack[0][0] : -1;
setContentSpecIndex(fCurrentElementIndex, contentSpec);
}
//
// Private methods
//
/**
* Creates a subtree from the leaf nodes at the current depth.
*/
private int addContentSpecNodes(int begin, int end) {
if (begin == end) {
return fGroupIndexStack[fDepth][begin];
}
final int middle = (begin + end) >>> 1;
return addContentSpecNode(fOpStack[fDepth],
addContentSpecNodes(begin, middle),
addContentSpecNodes(middle + 1, end));
} // addContentSpecNodes(int,int)
/**
* Initialize the stacks which temporarily hold content models.
*/
private void initializeContentModelStacks() {
if (fOpStack == null) {
fOpStack = new short[8];
fGroupIndexStack = new int [8][];
fGroupIndexStackSizes = new int [8];
}
else if (fDepth == fOpStack.length) {
short [] newOpStack = new short[fDepth * 2];
System.arraycopy(fOpStack, 0, newOpStack, 0, fDepth);
fOpStack = newOpStack;
int [][] newGroupIndexStack = new int[fDepth * 2][];
System.arraycopy(fGroupIndexStack, 0, newGroupIndexStack, 0, fDepth);
fGroupIndexStack = newGroupIndexStack;
int [] newGroupIndexStackLengths = new int[fDepth * 2];
System.arraycopy(fGroupIndexStackSizes, 0, newGroupIndexStackLengths, 0, fDepth);
fGroupIndexStackSizes = newGroupIndexStackLengths;
}
fOpStack[fDepth] = -1;
fGroupIndexStackSizes[fDepth] = 0;
} // initializeContentModelStacks()
/**
* Add XMLContentSpec to the current group.
*
* @param contentSpec handle to the XMLContentSpec to add to the current group
*/
private void addToCurrentGroup(int contentSpec) {
int [] currentGroup = fGroupIndexStack[fDepth];
int length = fGroupIndexStackSizes[fDepth]++;
if (currentGroup == null) {
currentGroup = new int[8];
fGroupIndexStack[fDepth] = currentGroup;
}
else if (length == currentGroup.length) {
int [] newGroup = new int[currentGroup.length * 2];
System.arraycopy(currentGroup, 0, newGroup, 0, currentGroup.length);
currentGroup = newGroup;
fGroupIndexStack[fDepth] = currentGroup;
}
currentGroup[length] = contentSpec;
} // addToCurrentGroup(int)
} // class BalancedDTDGrammar

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
import java.util.HashMap;
import java.util.Map;
/**
* This very simple class is the skeleton of what the DTDValidator could use
* to store various grammars that it gets from the GrammarPool. As in the
* case of XSGrammarBucket, one thinks of this object as being closely
* associated with its validator; when fully mature, this class will be
* filled from the GrammarPool when the DTDValidator is invoked on a
* document, and, if a new DTD grammar is parsed, the new set will be
* offered back to the GrammarPool for possible inclusion.
*
* @xerces.internal
*
* @author Neil Graham, IBM
*
*/
public class DTDGrammarBucket {
// REVISIT: make this class smarter and *way* more complete!
//
// Data
//
/** Grammars associated with element root name. */
protected Map<XMLDTDDescription, DTDGrammar> fGrammars;
// the unique grammar from fGrammars (or that we're
// building) that is used in validation.
protected DTDGrammar fActiveGrammar;
// is the "active" grammar standalone?
protected boolean fIsStandalone;
//
// Constructors
//
/** Default constructor. */
public DTDGrammarBucket() {
fGrammars = new HashMap<>();
} // <init>()
//
// Public methods
//
/**
* Puts the specified grammar into the grammar pool and associate it to
* a root element name (this being internal, the lack of generality is irrelevant).
*
* @param grammar The grammar.
*/
public void putGrammar(DTDGrammar grammar) {
XMLDTDDescription desc = (XMLDTDDescription)grammar.getGrammarDescription();
fGrammars.put(desc, grammar);
} // putGrammar(DTDGrammar)
// retrieve a DTDGrammar given an XMLDTDDescription
public DTDGrammar getGrammar(XMLGrammarDescription desc) {
return fGrammars.get((XMLDTDDescription)desc);
} // putGrammar(DTDGrammar)
public void clear() {
fGrammars.clear();
fActiveGrammar = null;
fIsStandalone = false;
} // clear()
// is the active grammar standalone? This must live here because
// at the time the validator discovers this we don't yet know
// what the active grammar should be (no info about root)
void setStandalone(boolean standalone) {
fIsStandalone = standalone;
}
boolean getStandalone() {
return fIsStandalone;
}
// set the "active" grammar:
void setActiveGrammar (DTDGrammar grammar) {
fActiveGrammar = grammar;
}
DTDGrammar getActiveGrammar () {
return fActiveGrammar;
}
} // class DTDGrammarBucket

View File

@@ -0,0 +1,88 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl;
import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
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.xni.grammars.XMLGrammarPool;
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
/**
* This class extends XMLDTDProcessor by giving it
* the ability to parse XML 1.1 documents correctly. It can also be used
* as a DTD loader, so that XML 1.1 external subsets can
* be processed correctly (hence it's rather anomalous-appearing
* derivation from XMLDTDLoader).
*
* @xerces.internal
*
* @author Neil Graham, IBM
*
*/
public class XML11DTDProcessor extends XMLDTDLoader{
// constructors
public XML11DTDProcessor() {
super();
} // <init>()
public XML11DTDProcessor(SymbolTable symbolTable) {
super(symbolTable);
} // init(SymbolTable)
public XML11DTDProcessor(SymbolTable symbolTable,
XMLGrammarPool grammarPool) {
super(symbolTable, grammarPool);
} // init(SymbolTable, XMLGrammarPool)
XML11DTDProcessor(SymbolTable symbolTable,
XMLGrammarPool grammarPool, XMLErrorReporter errorReporter,
XMLEntityResolver entityResolver) {
super(symbolTable, grammarPool, errorReporter, entityResolver);
} // init(SymbolTable, XMLGrammarPool, XMLErrorReporter, XMLEntityResolver)
// overridden methods
protected boolean isValidNmtoken(String nmtoken) {
return XML11Char.isXML11ValidNmtoken(nmtoken);
} // isValidNmtoken(String): boolean
protected boolean isValidName(String name) {
return XML11Char.isXML11ValidName(name);
} // isValidNmtoken(String): boolean
protected XMLDTDScannerImpl createDTDScanner(SymbolTable symbolTable,
XMLErrorReporter errorReporter, XMLEntityManager entityManager) {
return new XML11DTDScannerImpl(symbolTable, errorReporter, entityManager);
} // createDTDScanner(SymbolTable, XMLErrorReporter, XMLEntityManager) : XMLDTDScannerImpl
protected short getScannerVersion() {
return Constants.XML_VERSION_1_1;
} // getScannerVersion() : short
} // class XML11DTDProcessor

View File

@@ -0,0 +1,86 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
/**
* This allows the validator to correctlyhandle XML 1.1
* documents.
*
* @xerces.internal
*
* @author Neil Graham
*/
public class XML11DTDValidator extends XMLDTDValidator {
//
// Constants
//
protected final static String DTD_VALIDATOR_PROPERTY =
Constants.XERCES_PROPERTY_PREFIX+Constants.DTD_VALIDATOR_PROPERTY;
//
// Constructors
//
/** Default constructor. */
public XML11DTDValidator() {
super();
} // <init>()
// overridden so that this class has access to the same
// grammarBucket as the corresponding DTDProcessor
// will try and use...
public void reset(XMLComponentManager manager) {
XMLDTDValidator curr = null;
if((curr = (XMLDTDValidator)manager.getProperty(DTD_VALIDATOR_PROPERTY)) != null &&
curr != this) {
fGrammarBucket = curr.getGrammarBucket();
}
super.reset(manager);
} //reset(XMLComponentManager)
protected void init() {
if(fValidation || fDynamicValidation) {
super.init();
// now overwrite some entries in parent:
try {
fValID = fDatatypeValidatorFactory.getBuiltInDV("XML11ID");
fValIDRef = fDatatypeValidatorFactory.getBuiltInDV("XML11IDREF");
fValIDRefs = fDatatypeValidatorFactory.getBuiltInDV("XML11IDREFS");
fValNMTOKEN = fDatatypeValidatorFactory.getBuiltInDV("XML11NMTOKEN");
fValNMTOKENS = fDatatypeValidatorFactory.getBuiltInDV("XML11NMTOKENS");
}
catch (Exception e) {
// should never happen
e.printStackTrace(System.err);
}
}
} // init()
} // class XML11DTDValidator

View File

@@ -0,0 +1,226 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
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;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XNIException;
/**
* The DTD validator. The validator implements a document
* filter: receiving document events from the scanner; validating
* the content and structure; augmenting the InfoSet, if applicable;
* and notifying the parser of the information resulting from the
* validation process.
* <p> Formerly, this component also handled DTD events and grammar construction.
* To facilitate the development of a meaningful DTD grammar caching/preparsing
* framework, this functionality has been moved into the XMLDTDLoader
* class. Therefore, this class no longer implements the DTDFilter
* or DTDContentModelFilter interfaces.
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/namespaces</li>
* <li>http://xml.org/sax/features/validation</li>
* <li>http://apache.org/xml/features/validation/dynamic</li>
* <li>http://apache.org/xml/properties/internal/symbol-table</li>
* <li>http://apache.org/xml/properties/internal/error-reporter</li>
* <li>http://apache.org/xml/properties/internal/grammar-pool</li>
* <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
* </ul>
*
* @xerces.internal
*
* @author Elena Litani, IBM
* @author Michael Glavassevich, IBM
*
*/
public class XML11NSDTDValidator extends XML11DTDValidator {
/** Attribute QName. */
private QName fAttributeQName = new QName();
/** Bind namespaces */
protected final void startNamespaceScope(QName element, XMLAttributes attributes, Augmentations augs)
throws XNIException {
// add new namespace context
fNamespaceContext.pushContext();
if (element.prefix == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementXMLNSPrefix",
new Object[] { element.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// search for new namespace bindings
int length = attributes.getLength();
for (int i = 0; i < length; i++) {
String localpart = attributes.getLocalName(i);
String prefix = attributes.getPrefix(i);
// when it's of form xmlns="..." or xmlns:prefix="...",
// it's a namespace declaration. but prefix:xmlns="..." isn't.
if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING
&& localpart == XMLSymbols.PREFIX_XMLNS) {
// get the internalized value of this attribute
String uri = fSymbolTable.addSymbol(attributes.getValue(i));
// 1. "xmlns" can't be bound to any namespace
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 2. the namespace for "xmlns" can't be bound to any prefix
if (uri == NamespaceContext.XMLNS_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 3. "xml" can't be bound to any other namespace than it's own
if (localpart == XMLSymbols.PREFIX_XML) {
if (uri != NamespaceContext.XML_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
// 4. the namespace for "xml" can't be bound to any other prefix
else {
if (uri == NamespaceContext.XML_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
// Declare prefix in context. Removing the association between a prefix and a
// namespace name is permitted in XML 1.1, so if the uri value is the empty string,
// the prefix is being unbound. -- mrglavas
fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
}
}
// bind the element
String prefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
element.uri = fNamespaceContext.getURI(prefix);
if (element.prefix == null && element.uri != null) {
element.prefix = XMLSymbols.EMPTY_STRING;
}
if (element.prefix != null && element.uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementPrefixUnbound",
new Object[] { element.prefix, element.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind the attributes
for (int i = 0; i < length; i++) {
attributes.getName(i, fAttributeQName);
String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
String arawname = fAttributeQName.rawname;
if (arawname == XMLSymbols.PREFIX_XMLNS) {
fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS);
attributes.setName(i, fAttributeQName);
} else if (aprefix != XMLSymbols.EMPTY_STRING) {
fAttributeQName.uri = fNamespaceContext.getURI(aprefix);
if (fAttributeQName.uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[] { element.rawname, arawname, aprefix },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
attributes.setName(i, fAttributeQName);
}
}
// verify that duplicate attributes don't exist
// Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
int attrCount = attributes.getLength();
for (int i = 0; i < attrCount - 1; i++) {
String auri = attributes.getURI(i);
if (auri == null || auri == NamespaceContext.XMLNS_URI) {
continue;
}
String alocalpart = attributes.getLocalName(i);
for (int j = i + 1; j < attrCount; j++) {
String blocalpart = attributes.getLocalName(j);
String buri = attributes.getURI(j);
if (alocalpart == blocalpart && auri == buri) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[] { element.rawname, alocalpart, auri },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
} // startNamespaceScope(QName,XMLAttributes)
/** Handles end element. */
protected void endNamespaceScope(QName element, Augmentations augs, boolean isEmpty)
throws XNIException {
// bind element
String eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
element.uri = fNamespaceContext.getURI(eprefix);
if (element.uri != null) {
element.prefix = eprefix;
}
// call handlers
if (fDocumentHandler != null) {
if (!isEmpty) {
fDocumentHandler.endElement(element, augs);
}
}
// pop context
fNamespaceContext.popContext();
} // endNamespaceScope(QName,boolean)
}

View File

@@ -0,0 +1,70 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import com.sun.org.apache.xerces.internal.xni.QName;
/**
*/
public class XMLAttributeDecl {
//
// Data
//
/** name */
public final QName name = new QName();
/** simpleType */
public final XMLSimpleType simpleType = new XMLSimpleType();
/** optional */
public boolean optional;
//
// Methods
//
/**
* setValues
*
* @param name
* @param simpleType
* @param optional
*/
public void setValues(QName name, XMLSimpleType simpleType, boolean optional) {
this.name.setValues(name);
this.simpleType.setValues(simpleType);
this.optional = optional;
} // setValues
/**
* clear
*/
public void clear() {
this.name.clear();
this.simpleType.clear();
this.optional = false;
} // clear
} // class XMLAttributeDecl

View File

@@ -0,0 +1,296 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
/**
* ContentSpec really exists to aid the parser classes in implementing
* access to the grammar.
* <p>
* This class is used by the DTD scanner and the validator classes,
* allowing them to be used separately or together. This "struct"
* class is used to build content models for validation, where it
* is more efficient to fetch all of the information for each of
* these content model "fragments" than to fetch each field one at
* a time. Since configurations are allowed to have validators
* without a DTD scanner (i.e. a schema validator) and a DTD scanner
* without a validator (non-validating processor), this class can be
* used by each without requiring the presence of the other.
* <p>
* When processing element declarations, the DTD scanner will build
* up a representation of the content model using the node types that
* are defined here. Since a non-validating processor only needs to
* remember the type of content model declared (i.e. ANY, EMPTY, MIXED,
* or CHILDREN), it is free to discard the specific details of the
* MIXED and CHILDREN content models described using this class.
* <p>
* In the typical case of a validating processor reading the grammar
* of the document from a DTD, the information about the content model
* declared will be preserved and later "compiled" into an efficient
* form for use during element validation. Each content spec node
* that is saved is assigned a unique index that is used as a handle
* for the "value" or "otherValue" fields of other content spec nodes.
* A leaf node has a "value" that is either an index in the string
* pool of the element type of that leaf, or a value of -1 to indicate
* the special "#PCDATA" leaf type used in a mixed content model.
* <p>
* For a mixed content model, the content spec will be made up of
* leaf and choice content spec nodes, with an optional "zero or more"
* node. For example, the mixed content declaration "(#PCDATA)" would
* contain a single leaf node with a node value of -1. A mixed content
* declaration of "(#PCDATA|foo)*" would have a content spec consisting
* of two leaf nodes, for the "#PCDATA" and "foo" choices, a choice node
* with the "value" set to the index of the "#PCDATA" leaf node and the
* "otherValue" set to the index of the "foo" leaf node, and a "zero or
* more" node with the "value" set to the index of the choice node. If
* the content model has more choices, for example "(#PCDATA|a|b)*", then
* there will be more corresponding choice and leaf nodes, the choice
* nodes will be chained together through the "value" field with each
* leaf node referenced by the "otherValue" field.
* <p>
* For element content models, there are sequence nodes and also "zero or
* one" and "one or more" nodes. The leaf nodes would always have a valid
* string pool index, as the "#PCDATA" leaf is not used in the declarations
* for element content models.
*
* @xerces.internal
*
*/
public class XMLContentSpec {
//
// Constants
//
/**
* Name or #PCDATA. Leaf nodes that represent parsed character
* data (#PCDATA) have values of -1.
*/
public static final short CONTENTSPECNODE_LEAF = 0;
/** Represents a zero or one occurence count, '?'. */
public static final short CONTENTSPECNODE_ZERO_OR_ONE = 1;
/** Represents a zero or more occurence count, '*'. */
public static final short CONTENTSPECNODE_ZERO_OR_MORE = 2;
/** Represents a one or more occurence count, '+'. */
public static final short CONTENTSPECNODE_ONE_OR_MORE = 3;
/** Represents choice, '|'. */
public static final short CONTENTSPECNODE_CHOICE = 4;
/** Represents sequence, ','. */
public static final short CONTENTSPECNODE_SEQ = 5;
/**
* Represents any namespace specified namespace. When the element
* found in the document must belong to a specific namespace,
* <code>otherValue</code> will contain the name of the namespace.
* If <code>otherValue</code> is <code>-1</code> then the element
* can be from any namespace.
* <p>
* Lists of valid namespaces are created from choice content spec
* nodes that have any content spec nodes as children.
*/
public static final short CONTENTSPECNODE_ANY = 6;
/**
* Represents any other namespace (XML Schema: ##other).
* <p>
* When the content spec node type is set to CONTENTSPECNODE_ANY_OTHER,
* <code>value</code> will contain the namespace that <em>cannot</em>
* occur.
*/
public static final short CONTENTSPECNODE_ANY_OTHER = 7;
/** Represents any local element (XML Schema: ##local). */
public static final short CONTENTSPECNODE_ANY_LOCAL = 8;
/** prcessContent is 'lax' **/
public static final short CONTENTSPECNODE_ANY_LAX = 22;
public static final short CONTENTSPECNODE_ANY_OTHER_LAX = 23;
public static final short CONTENTSPECNODE_ANY_LOCAL_LAX = 24;
/** processContent is 'skip' **/
public static final short CONTENTSPECNODE_ANY_SKIP = 38;
public static final short CONTENTSPECNODE_ANY_OTHER_SKIP = 39;
public static final short CONTENTSPECNODE_ANY_LOCAL_SKIP = 40;
//
// Data
//
/**
* The content spec node type.
*
* @see #CONTENTSPECNODE_LEAF
* @see #CONTENTSPECNODE_ZERO_OR_ONE
* @see #CONTENTSPECNODE_ZERO_OR_MORE
* @see #CONTENTSPECNODE_ONE_OR_MORE
* @see #CONTENTSPECNODE_CHOICE
* @see #CONTENTSPECNODE_SEQ
*/
public short type;
/**
* The "left hand" value object of the content spec node.
* leaf name.localpart, single child for unary ops, left child for binary ops.
*/
public Object value;
/**
* The "right hand" value of the content spec node.
* leaf name.uri, right child for binary ops
*/
public Object otherValue;
//
// Constructors
//
/** Default constructor. */
public XMLContentSpec() {
clear();
}
/** Constructs a content spec with the specified values. */
public XMLContentSpec(short type, Object value, Object otherValue) {
setValues(type, value, otherValue);
}
/**
* Constructs a content spec from the values in the specified content spec.
*/
public XMLContentSpec(XMLContentSpec contentSpec) {
setValues(contentSpec);
}
/**
* Constructs a content spec from the values specified by the given
* content spec provider and identifier.
*/
public XMLContentSpec(XMLContentSpec.Provider provider,
int contentSpecIndex) {
setValues(provider, contentSpecIndex);
}
//
// Public methods
//
/** Clears the values. */
public void clear() {
type = -1;
value = null;
otherValue = null;
}
/** Sets the values. */
public void setValues(short type, Object value, Object otherValue) {
this.type = type;
this.value = value;
this.otherValue = otherValue;
}
/** Sets the values of the specified content spec. */
public void setValues(XMLContentSpec contentSpec) {
type = contentSpec.type;
value = contentSpec.value;
otherValue = contentSpec.otherValue;
}
/**
* Sets the values from the values specified by the given content spec
* provider and identifier. If the specified content spec cannot be
* provided, the values of this content spec are cleared.
*/
public void setValues(XMLContentSpec.Provider provider,
int contentSpecIndex) {
if (!provider.getContentSpec(contentSpecIndex, this)) {
clear();
}
}
//
// Object methods
//
/** Returns a hash code for this node. */
public int hashCode() {
return type << 16 |
value.hashCode() << 8 |
otherValue.hashCode();
}
/** Returns true if the two objects are equal. */
public boolean equals(Object object) {
if (object != null && object instanceof XMLContentSpec) {
XMLContentSpec contentSpec = (XMLContentSpec)object;
return type == contentSpec.type &&
value == contentSpec.value &&
otherValue == contentSpec.otherValue;
}
return false;
}
//
// Interfaces
//
/**
* Provides a means for walking the structure built out of
* content spec "nodes". The user of this provider interface is
* responsible for knowing what the content spec node values
* "mean". If those values refer to content spec identifiers,
* then the user can call back into the provider to get the
* next content spec node in the structure.
*
* @xerces.internal
*/
public interface Provider {
//
// XMLContentSpec.Provider methods
//
/**
* Fills in the provided content spec structure with content spec
* information for a unique identifier.
*
* @param contentSpecIndex The content spec identifier. All content
* spec "nodes" have a unique identifier.
* @param contentSpec The content spec struct to fill in with
* the information.
*
* @return Returns true if the contentSpecIndex was found.
*/
public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec);
} // interface Provider
} // class XMLContentSpec

View File

@@ -0,0 +1,188 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import java.util.ArrayList;
import java.util.Vector;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
/**
* All information specific to DTD grammars.
*
* @xerces.internal
*
* @author Neil Graham, IBM
*/
public class XMLDTDDescription extends XMLResourceIdentifierImpl
implements com.sun.org.apache.xerces.internal.xni.grammars.XMLDTDDescription {
// Data
// pieces of information needed to make this usable as a Grammar key
// if we know the root of this grammar, here's its name:
protected String fRootName = null;
// if we don't know the root name, this stores all elements that
// could serve; fPossibleRoots and fRootName cannot both be non-null
protected ArrayList fPossibleRoots = null;
// Constructors:
public XMLDTDDescription(XMLResourceIdentifier id, String rootName) {
this.setValues(id.getPublicId(), id.getLiteralSystemId(),
id.getBaseSystemId(), id.getExpandedSystemId());
this.fRootName = rootName;
this.fPossibleRoots = null;
} // init(XMLResourceIdentifier, String)
public XMLDTDDescription(String publicId, String literalId,
String baseId, String expandedId, String rootName) {
this.setValues(publicId, literalId, baseId, expandedId);
this.fRootName = rootName;
this.fPossibleRoots = null;
} // init(String, String, String, String, String)
public XMLDTDDescription(XMLInputSource source) {
this.setValues(source.getPublicId(), null,
source.getBaseSystemId(), source.getSystemId());
this.fRootName = null;
this.fPossibleRoots = null;
} // init(XMLInputSource)
// XMLGrammarDescription methods
public String getGrammarType () {
return XMLGrammarDescription.XML_DTD;
} // getGrammarType(): String
/**
* @return the root name of this DTD or null if root name is unknown
*/
public String getRootName() {
return fRootName;
} // getRootName(): String
/** Set the root name **/
public void setRootName(String rootName) {
fRootName = rootName;
fPossibleRoots = null;
}
/** Set possible roots **/
public void setPossibleRoots(ArrayList possibleRoots) {
fPossibleRoots = possibleRoots;
}
/** Set possible roots **/
public void setPossibleRoots(Vector possibleRoots) {
fPossibleRoots = (possibleRoots != null) ? new ArrayList(possibleRoots) : null;
}
/**
* Compares this grammar with the given grammar. Currently, we compare
* as follows:
* - if grammar type not equal return false immediately
* - try and find a common root name:
* - if both have roots, use them
* - else if one has a root, examine other's possible root's for a match;
* - else try all combinations
* - test fExpandedSystemId and fPublicId as above
*
* @param desc The description of the grammar to be compared with
* @return True if they are equal, else false
*/
public boolean equals(Object desc) {
if (!(desc instanceof XMLGrammarDescription)) return false;
if (!getGrammarType().equals(((XMLGrammarDescription)desc).getGrammarType())) {
return false;
}
// assume it's a DTDDescription
XMLDTDDescription dtdDesc = (XMLDTDDescription)desc;
if (fRootName != null) {
if ((dtdDesc.fRootName) != null && !dtdDesc.fRootName.equals(fRootName)) {
return false;
}
else if (dtdDesc.fPossibleRoots != null && !dtdDesc.fPossibleRoots.contains(fRootName)) {
return false;
}
}
else if (fPossibleRoots != null) {
if (dtdDesc.fRootName != null) {
if (!fPossibleRoots.contains(dtdDesc.fRootName)) {
return false;
}
}
else if (dtdDesc.fPossibleRoots == null) {
return false;
}
else {
boolean found = false;
final int size = fPossibleRoots.size();
for (int i = 0; i < size; ++i) {
String root = (String) fPossibleRoots.get(i);
found = dtdDesc.fPossibleRoots.contains(root);
if (found) break;
}
if (!found) return false;
}
}
// if we got this far we've got a root match... try other two fields,
// since so many different DTD's have roots in common:
if (fExpandedSystemId != null) {
if (!fExpandedSystemId.equals(dtdDesc.fExpandedSystemId)) {
return false;
}
}
else if (dtdDesc.fExpandedSystemId != null) {
return false;
}
if (fPublicId != null) {
if (!fPublicId.equals(dtdDesc.fPublicId)) {
return false;
}
}
else if (dtdDesc.fPublicId != null) {
return false;
}
return true;
}
/**
* Returns the hash code of this grammar
* Because our .equals method is so complex, we just return a very
* simple hash that might avoid calls to the equals method a bit...
* @return The hash code
*/
public int hashCode() {
if (fExpandedSystemId != null) {
return fExpandedSystemId.hashCode();
}
if (fPublicId != null) {
return fPublicId.hashCode();
}
// give up; hope .equals can handle it:
return 0;
}
} // class XMLDTDDescription

View File

@@ -0,0 +1,518 @@
/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.dtd;
import java.io.EOFException;
import java.io.IOException;
import java.io.StringReader;
import java.util.Locale;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarLoader;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
/**
* The DTD loader. The loader knows how to build grammars from XMLInputSources.
* It extends the DTD processor in order to do this; it's
* a separate class because DTD processors don't need to know how
* to talk to the outside world in their role as instance-document
* helpers.
* <p>
* This component requires the following features and properties. It
* know ho to set them if no one else does:from the
* <ul>
* <li>http://xml.org/sax/features/namespaces</li>
* <li>http://apache.org/xml/properties/internal/symbol-table</li>
* <li>http://apache.org/xml/properties/internal/error-reporter</li>
* <li>http://apache.org/xml/properties/internal/grammar-pool</li>
* <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
* </ul>
*
* @xerces.internal
*
* @author Neil Graham, IBM
* @author Michael Glavassevich, IBM
*
*/
public class XMLDTDLoader
extends XMLDTDProcessor
implements XMLGrammarLoader {
//
// Constants
//
// feature identifiers
/** Feature identifier: standard uri conformant feature. */
protected static final String STANDARD_URI_CONFORMANT_FEATURE =
Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE;
/** Feature identifier: balance syntax trees. */
protected static final String BALANCE_SYNTAX_TREES =
Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES;
// recognized features:
private static final String[] LOADER_RECOGNIZED_FEATURES = {
VALIDATION,
WARN_ON_DUPLICATE_ATTDEF,
WARN_ON_UNDECLARED_ELEMDEF,
NOTIFY_CHAR_REFS,
STANDARD_URI_CONFORMANT_FEATURE,
BALANCE_SYNTAX_TREES
};
// property identifiers
/** Property identifier: error handler. */
protected static final String ERROR_HANDLER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
/** Property identifier: entity resolver. */
public static final String ENTITY_RESOLVER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
/** Property identifier: locale. */
public static final String LOCALE =
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
/** Recognized properties. */
private static final String[] LOADER_RECOGNIZED_PROPERTIES = {
SYMBOL_TABLE,
ERROR_REPORTER,
ERROR_HANDLER,
ENTITY_RESOLVER,
GRAMMAR_POOL,
DTD_VALIDATOR,
LOCALE
};
// enforcing strict uri?
private boolean fStrictURI = false;
/** Controls whether the DTD grammar produces balanced syntax trees. */
private boolean fBalanceSyntaxTrees = false;
/** Entity resolver . */
protected XMLEntityResolver fEntityResolver;
// the scanner we use to actually read the DTD
protected XMLDTDScannerImpl fDTDScanner;
// the entity manager the scanner needs.
protected XMLEntityManager fEntityManager;
// what's our Locale?
protected Locale fLocale;
//
// Constructors
//
/** Deny default construction; we need a SymtolTable! */
public XMLDTDLoader() {
this(new SymbolTable());
} // <init>()
public XMLDTDLoader(SymbolTable symbolTable) {
this(symbolTable, null);
} // init(SymbolTable)
public XMLDTDLoader(SymbolTable symbolTable,
XMLGrammarPool grammarPool) {
this(symbolTable, grammarPool, null, new XMLEntityManager());
} // init(SymbolTable, XMLGrammarPool)
XMLDTDLoader(SymbolTable symbolTable,
XMLGrammarPool grammarPool, XMLErrorReporter errorReporter,
XMLEntityResolver entityResolver) {
fSymbolTable = symbolTable;
fGrammarPool = grammarPool;
if(errorReporter == null) {
errorReporter = new XMLErrorReporter();
errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler());
}
fErrorReporter = errorReporter;
// Add XML message formatter if there isn't one.
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
XMLMessageFormatter xmft = new XMLMessageFormatter();
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
}
fEntityResolver = entityResolver;
if(fEntityResolver instanceof XMLEntityManager) {
fEntityManager = (XMLEntityManager)fEntityResolver;
} else {
fEntityManager = new XMLEntityManager();
}
fEntityManager.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY, errorReporter);
fDTDScanner = createDTDScanner(fSymbolTable, fErrorReporter, fEntityManager);
fDTDScanner.setDTDHandler(this);
fDTDScanner.setDTDContentModelHandler(this);
reset();
} // init(SymbolTable, XMLGrammarPool, XMLErrorReporter, XMLEntityResolver)
// XMLGrammarLoader methods
/**
* Returns a list of feature identifiers that are recognized by
* this component. This method may return null if no features
* are recognized by this component.
*/
public String[] getRecognizedFeatures() {
return (String[])(LOADER_RECOGNIZED_FEATURES.clone());
} // getRecognizedFeatures():String[]
/**
* Sets the state of a feature. This method is called by the component
* manager any time after reset when a feature changes state.
* <p>
* <strong>Note:</strong> Components should silently ignore features
* that do not affect the operation of the component.
*
* @param featureId The feature identifier.
* @param state The state of the feature.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
public void setFeature(String featureId, boolean state)
throws XMLConfigurationException {
if (featureId.equals(VALIDATION)) {
fValidation = state;
}
else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
fWarnDuplicateAttdef = state;
}
else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) {
fWarnOnUndeclaredElemdef = state;
}
else if (featureId.equals(NOTIFY_CHAR_REFS)) {
fDTDScanner.setFeature(featureId, state);
}
else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) {
fStrictURI = state;
}
else if (featureId.equals(BALANCE_SYNTAX_TREES)) {
fBalanceSyntaxTrees = state;
}
else {
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, featureId);
}
} // setFeature(String,boolean)
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
* are recognized by this component.
*/
public String[] getRecognizedProperties() {
return (String[])(LOADER_RECOGNIZED_PROPERTIES.clone());
} // getRecognizedProperties():String[]
/**
* Returns the state of a property.
*
* @param propertyId The property identifier.
*
* @throws XMLConfigurationException Thrown on configuration error.
*/
public Object getProperty(String propertyId)
throws XMLConfigurationException {
if (propertyId.equals(SYMBOL_TABLE)) {
return fSymbolTable;
}
else if (propertyId.equals(ERROR_REPORTER)) {
return fErrorReporter;
}
else if (propertyId.equals(ERROR_HANDLER)) {
return fErrorReporter.getErrorHandler();
}
else if (propertyId.equals(ENTITY_RESOLVER)) {
return fEntityResolver;
}
else if (propertyId.equals(LOCALE)) {
return getLocale();
}
else if (propertyId.equals(GRAMMAR_POOL)) {
return fGrammarPool;
}
else if (propertyId.equals(DTD_VALIDATOR)) {
return fValidator;
}
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, propertyId);
} // getProperty(String): Object
/**
* Sets the value of a property. This method is called by the component
* manager any time after reset when a property changes value.
* <p>
* <strong>Note:</strong> Components should silently ignore properties
* that do not affect the operation of the component.
*
* @param propertyId The property identifier.
* @param value The value of the property.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
public void setProperty(String propertyId, Object value)
throws XMLConfigurationException {
if (propertyId.equals(SYMBOL_TABLE)) {
fSymbolTable = (SymbolTable)value;
fDTDScanner.setProperty(propertyId, value);
fEntityManager.setProperty(propertyId, value);
}
else if(propertyId.equals(ERROR_REPORTER)) {
fErrorReporter = (XMLErrorReporter)value;
// Add XML message formatter if there isn't one.
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
XMLMessageFormatter xmft = new XMLMessageFormatter();
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
}
fDTDScanner.setProperty(propertyId, value);
fEntityManager.setProperty(propertyId, value);
}
else if (propertyId.equals(ERROR_HANDLER)) {
fErrorReporter.setProperty(propertyId, value);
}
else if (propertyId.equals(ENTITY_RESOLVER)) {
fEntityResolver = (XMLEntityResolver)value;
fEntityManager.setProperty(propertyId, value);
}
else if (propertyId.equals(LOCALE)) {
setLocale((Locale) value);
}
else if(propertyId.equals(GRAMMAR_POOL)) {
fGrammarPool = (XMLGrammarPool)value;
}
else {
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, propertyId);
}
} // setProperty(String,Object)
/**
* Returns the state of a feature.
*
* @param featureId The feature identifier.
*
* @throws XMLConfigurationException Thrown on configuration error.
*/
public boolean getFeature(String featureId)
throws XMLConfigurationException {
if (featureId.equals(VALIDATION)) {
return fValidation;
}
else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
return fWarnDuplicateAttdef;
}
else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) {
return fWarnOnUndeclaredElemdef;
}
else if (featureId.equals(NOTIFY_CHAR_REFS)) {
return fDTDScanner.getFeature(featureId);
}
else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) {
return fStrictURI;
}
else if (featureId.equals(BALANCE_SYNTAX_TREES)) {
return fBalanceSyntaxTrees;
}
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, featureId);
} //getFeature(String): boolean
/**
* Set the locale to use for messages.
*
* @param locale The locale object to use for localization of messages.
*
* @exception XNIException Thrown if the parser does not support the
* specified locale.
*/
public void setLocale(Locale locale) {
fLocale = locale;
fErrorReporter.setLocale(locale);
} // setLocale(Locale)
/** Return the Locale the XMLGrammarLoader is using. */
public Locale getLocale() {
return fLocale;
} // getLocale(): Locale
/**
* Sets the error handler.
*
* @param errorHandler The error handler.
*/
public void setErrorHandler(XMLErrorHandler errorHandler) {
fErrorReporter.setProperty(ERROR_HANDLER, errorHandler);
} // setErrorHandler(XMLErrorHandler)
/** Returns the registered error handler. */
public XMLErrorHandler getErrorHandler() {
return fErrorReporter.getErrorHandler();
} // getErrorHandler(): XMLErrorHandler
/**
* Sets the entity resolver.
*
* @param entityResolver The new entity resolver.
*/
public void setEntityResolver(XMLEntityResolver entityResolver) {
fEntityResolver = entityResolver;
fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver);
} // setEntityResolver(XMLEntityResolver)
/** Returns the registered entity resolver. */
public XMLEntityResolver getEntityResolver() {
return fEntityResolver;
} // getEntityResolver(): XMLEntityResolver
/**
* Returns a Grammar object by parsing the contents of the
* entity pointed to by source.
*
* @param source the location of the entity which forms
* the starting point of the grammar to be constructed.
* @throws IOException When a problem is encountered reading the entity
* XNIException When a condition arises (such as a FatalError) that requires parsing
* of the entity be terminated.
*/
public Grammar loadGrammar(XMLInputSource source)
throws IOException, XNIException {
reset();
// First chance checking strict URI
String eid = XMLEntityManager.expandSystemId(source.getSystemId(), source.getBaseSystemId(), fStrictURI);
XMLDTDDescription desc = new XMLDTDDescription(source.getPublicId(), source.getSystemId(), source.getBaseSystemId(), eid, null);
if (!fBalanceSyntaxTrees) {
fDTDGrammar = new DTDGrammar(fSymbolTable, desc);
}
else {
fDTDGrammar = new BalancedDTDGrammar(fSymbolTable, desc);
}
fGrammarBucket = new DTDGrammarBucket();
fGrammarBucket.setStandalone(false);
fGrammarBucket.setActiveGrammar(fDTDGrammar);
// no reason to use grammar bucket's "put" method--we
// know which grammar it is, and we don't know the root name anyway...
// actually start the parsing!
try {
fDTDScanner.setInputSource(source);
fDTDScanner.scanDTDExternalSubset(true);
} catch (EOFException e) {
// expected behaviour...
}
finally {
// Close all streams opened by the parser.
fEntityManager.closeReaders();
}
if(fDTDGrammar != null && fGrammarPool != null) {
fGrammarPool.cacheGrammars(XMLDTDDescription.XML_DTD, new Grammar[] {fDTDGrammar});
}
return fDTDGrammar;
} // loadGrammar(XMLInputSource): Grammar
/**
* Parse a DTD internal and/or external subset and insert the content
* into the existing DTD grammar owned by the given DTDValidator.
*/
public void loadGrammarWithContext(XMLDTDValidator validator, String rootName,
String publicId, String systemId, String baseSystemId, String internalSubset)
throws IOException, XNIException {
final DTDGrammarBucket grammarBucket = validator.getGrammarBucket();
final DTDGrammar activeGrammar = grammarBucket.getActiveGrammar();
if (activeGrammar != null && !activeGrammar.isImmutable()) {
fGrammarBucket = grammarBucket;
fEntityManager.setScannerVersion(getScannerVersion());
reset();
try {
// process internal subset
if (internalSubset != null) {
// To get the DTD scanner to end at the right place we have to fool
// it into thinking that it reached the end of the internal subset
// in a real document.
StringBuffer buffer = new StringBuffer(internalSubset.length() + 2);
buffer.append(internalSubset).append("]>");
XMLInputSource is = new XMLInputSource(null, baseSystemId,
null, new StringReader(buffer.toString()), null);
fEntityManager.startDocumentEntity(is);
fDTDScanner.scanDTDInternalSubset(true, false, systemId != null);
}
// process external subset
if (systemId != null) {
XMLDTDDescription desc = new XMLDTDDescription(publicId, systemId, baseSystemId, null, rootName);
XMLInputSource source = fEntityManager.resolveEntity(desc);
fDTDScanner.setInputSource(source);
fDTDScanner.scanDTDExternalSubset(true);
}
}
catch (EOFException e) {
// expected behaviour...
}
finally {
// Close all streams opened by the parser.
fEntityManager.closeReaders();
}
}
} // loadGrammarWithContext(XMLDTDValidator, String, String, String, String, String)
// reset all the components that we rely upon
protected void reset() {
super.reset();
fDTDScanner.reset();
fEntityManager.reset();
fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
}
protected XMLDTDScannerImpl createDTDScanner(SymbolTable symbolTable,
XMLErrorReporter errorReporter, XMLEntityManager entityManager) {
return new XMLDTDScannerImpl(symbolTable, errorReporter, entityManager);
} // createDTDScanner(SymbolTable, XMLErrorReporter, XMLEntityManager) : XMLDTDScannerImpl
protected short getScannerVersion() {
return Constants.XML_VERSION_1_0;
} // getScannerVersion() : short
} // class XMLDTDLoader

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More