/*
* reserved comment block
* DO NOT REMOVE OR ALTER!
*/
/*
* Copyright 1999-2002,2004,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
*
*
* 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.
*/
/**
* The Document interface represents the entire HTML or XML document.
* Conceptually, it is the root of the document tree, and provides the
* primary access to the document's data.
* <P>
* Since elements, text nodes, comments, processing instructions,
* etc. cannot exist outside the context of a Document, the Document
* interface also contains the factory methods needed to create these
* objects. The Node objects created have a ownerDocument attribute
* which associates them with the Document within whose context they
* were created.
*
* @xerces.internal
*
* @version $Id: DeferredDocumentImpl.java,v 1.11 2010-11-01 04:39:38 joehw Exp $
* @since PR-DOM-Level-1-19980818.
*/
public class DeferredDocumentImpl
extends DocumentImpl
implements DeferredNode {
//
// Constants
//
/** Serialization version. */
// debugging
/** To include code for printing the ref count tables. */
private static final boolean DEBUG_PRINT_REF_COUNTS = false;
/** To include code for printing the internal tables. */
private static final boolean DEBUG_PRINT_TABLES = false;
/** To debug identifiers set to true and recompile. */
private static final boolean DEBUG_IDS = false;
// protected
/** Chunk shift. */
/** Chunk size. */
/** Chunk mask. */
/** Initial chunk size. */
//
// Data
//
// lazy-eval information
// To maximize memory consumption the actual semantic of these fields vary
// depending on the node type.
/** Node count. */
/** Node types. */
protected transient int fNodeType[][];
/** Node names. */
/** Node values. */
/** Node parents. */
protected transient int fNodeParent[][];
/** Node first children. */
protected transient int fNodeLastChild[][];
/** Node prev siblings. */
protected transient int fNodePrevSib[][];
/** Node namespace URI. */
/** Extra data. */
protected transient int fNodeExtra[][];
/** Identifier count. */
protected transient int fIdCount;
/** Identifier name indexes. */
/** Identifier element indexes. */
protected transient int fIdElement[];
/** DOM2: For namespace support in the deferred case.
*/
// Implementation Note: The deferred element and attribute must know how to
// interpret the int representing the qname.
protected boolean fNamespacesEnabled = false;
//
// private data
//
//
// Constructors
//
/**
* NON-DOM: Actually creating a Document is outside the DOM's spec,
* since it has to operate in terms of a particular implementation.
*/
public DeferredDocumentImpl() {
this(false);
} // <init>()
/**
* NON-DOM: Actually creating a Document is outside the DOM's spec,
* since it has to operate in terms of a particular implementation.
*/
this(namespacesEnabled, false);
} // <init>(boolean)
/** Experimental constructor. */
super(grammarAccess);
needsSyncData(true);
needsSyncChildren(true);
} // <init>(boolean,boolean)
//
// Public methods
//
/**
* 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.
*/
// Currently implemented as a singleton, since it's hardcoded
// information anyway.
}
/** Returns the cached parser.getNamespaces() value.*/
boolean getNamespacesEnabled() {
return fNamespacesEnabled;
}
}
// internal factory methods
/** Creates a document node in the table. */
public int createDeferredDocument() {
return nodeIndex;
}
/** Creates a doctype. */
// create node
// save name, public id, system id
// return node index
return nodeIndex;
} // createDeferredDocumentType(String,String,String):int
// create extra data node to store internal subset
}
/** Creates a notation in the table. */
// create node
// create extra data node
// save name, public id, system id, and notation name
// in extra data node set baseURI value
// return node index
return nodeIndex;
} // createDeferredNotation(String,String,String):int
/** Creates an entity in the table. */
// create node
// create extra data node
// save name, public id, system id, and notation name
// set other values in the extra chunk
// notation
// version L3
// encoding L3
// baseURI
// return node index
return nodeIndex;
} // createDeferredEntity(String,String,String,String):int
if (entityIndex != -1) {
return getNodeName (extraDataIndex, false);
}
return null;
}
// DOM Level 3: setting encoding and version
if (eNodeIndex !=-1) {
}
}
// DOM Level 3: sets element TypeInfo
}
/**
* DOM Internal
*
* An attribute specifying the actual encoding of this document. This is
* <code>null</code> otherwise.
* <br> This attribute represents the property [character encoding scheme]
* defined in .
*/
// get first extra data chunk
// get second extra data chunk
}
/** Creates an entity reference node in the table. */
// create node
// return node index
return nodeIndex;
} // createDeferredEntityReference(String):int
/**
* Creates an element node with a URI in the table and type information.
* @deprecated
*/
// create node
// return node index
return elementNodeIndex;
} // createDeferredElement(String,String,Object):int
/**
* Creates an element node in the table.
* @deprecated
*/
}
/**
* Creates an element node with a URI in the table.
*/
// create node
// return node index
return elementNodeIndex;
} // createDeferredElement(String,String):int
/**
* This method is used by the DOMParser to create attributes.
* @param elementNodeIndex
* @param attrName
* @param attrURI
* @param attrValue
* @param specified
* @param id
* @param type
* @return int
*/
boolean specified,
boolean id,
// create attribute
// set attribute's parent to element
// get element's last attribute
if (lastAttrNodeIndex != 0) {
// add link from new attribute to last attribute
}
// add link from element to new last attribute
if (id) {
}
// store type information
}
// return node index
return attrNodeIndex;
}
/**
* Sets an attribute on an element node.
* @deprecated
*/
// create attribute
// set attribute's parent to element
// get element's last attribute
if (lastAttrNodeIndex != 0) {
// add link from new attribute to last attribute
}
// add link from element to new last attribute
// return node index
return attrNodeIndex;
} // setDeferredAttribute(int,String,String,String,boolean):int
/** Creates an attribute in the table. */
boolean specified) {
}
/** Creates an attribute with a URI in the table. */
// create node
// return node index
return nodeIndex;
} // createDeferredAttribute(String,String,String,boolean):int
/** Creates an element definition in the table.*/
// create node
// return node index
return nodeIndex;
} // createDeferredElementDefinition(String):int
/** Creates a text node in the table. */
boolean ignorableWhitespace) {
// create node
// use extra to store ignorableWhitespace info
// return node index
return nodeIndex;
} // createDeferredTextNode(String,boolean):int
/** Creates a CDATA section node in the table. */
// create node
// return node index
return nodeIndex;
} // createDeferredCDATASection(String):int
/** Creates a processing instruction node in the table. */
// create node
// return node index
return nodeIndex;
} // createDeferredProcessingInstruction(String,String):int
/** Creates a comment node in the table. */
// create node
// return node index
return nodeIndex;
} // createDeferredComment(String):int
/** Creates a clone of the specified node. */
// clone immediate node
if (extraIndex != -1) {
}
}
// clone and attach children
if (deep) {
int prevIndex = -1;
while (childIndex != -1) {
}
}
// return cloned node index
return cloneIndex;
} // cloneNode(int,boolean):int
/** Appends a child to the specified parent in the table. */
// append parent index
// set previous sibling of new child
// update parent's last child
} // appendChild(int,int)
/** Adds an attribute node to the specified element. */
// see if this attribute is already here
int nextIndex = -1;
int oachunk = -1;
int oaindex = -1;
while (oldAttrIndex != -1) {
break;
}
}
// remove old attribute
if (oldAttrIndex != -1) {
// patch links
if (nextIndex == -1) {
}
else {
}
// remove connections to siblings
int attrTextIndex =
}
// add new attribute
// return
return oldAttrIndex;
} // setAttributeNode(int,int):int
/** Adds an attribute node to the specified element. */
}
/** Sets type of attribute */
}
/** Inserts a child before the specified node in the table. */
if (refChildIndex == -1) {
return newChildIndex;
}
return newChildIndex;
} // insertBefore(int,int,int):int
/** Sets the last child of the parentIndex to childIndex. */
} // setAsLastChild(int,int)
/**
* Returns the parent node of the given node.
* <em>Calling this method does not free the parent index.</em>
*/
return getParentNode(nodeIndex, false);
}
/**
* Returns the parent node of the given node.
* @param free True to free parent node.
*/
if (nodeIndex == -1) {
return -1;
}
} // getParentNode(int):int
/** Returns the last child of the given node. */
return getLastChild(nodeIndex, true);
}
/**
* Returns the last child of the given node.
* @param free True to free child index.
*/
if (nodeIndex == -1) {
return -1;
}
} // getLastChild(int,boolean):int
/**
* Returns the prev sibling of the given node.
* This is post-normalization of Text Nodes.
*/
return getPrevSibling(nodeIndex, true);
}
/**
* Returns the prev sibling of the given node.
* @param free True to free sibling index.
*/
if (nodeIndex == -1) {
return -1;
}
do {
if (nodeIndex == -1) {
break;
}
}
else {
}
return nodeIndex;
} // getPrevSibling(int,boolean):int
/**
* Returns the <i>real</i> prev sibling of the given node,
* directly from the data structures. Used by TextImpl#getNodeValue()
* to normalize values.
*/
return getRealPrevSibling(nodeIndex, true);
}
/**
* Returns the <i>real</i> prev sibling of the given node.
* @param free True to free sibling index.
*/
if (nodeIndex == -1) {
return -1;
}
} // getReadPrevSibling(int,boolean):int
/**
* Returns the index of the element definition in the table
* with the specified name index, or -1 if no such definition
* exists.
*/
if (fNodeCount > 1) {
// find doctype
int docTypeIndex = -1;
int nchunk = 0;
int nindex = 0;
index != -1;
break;
}
}
// find element definition
if (docTypeIndex == -1) {
return -1;
}
index != -1;
return index;
}
}
}
return -1;
} // lookupElementDefinition(String):int
/** Instantiates the requested node object. */
// is there anything to do?
if (nodeIndex == -1) {
return null;
}
// get node type
}
// create new node
switch (type) {
//
// Standard DOM node types
//
case Node.ATTRIBUTE_NODE: {
if (fNamespacesEnabled) {
} else {
}
break;
}
case Node.CDATA_SECTION_NODE: {
break;
}
case Node.COMMENT_NODE: {
break;
}
// NOTE: Document fragments can never be "fast".
//
// The parser will never ask to create a document
// fragment during the parse. Document fragments
// are used by the application *after* the parse.
//
// case Node.DOCUMENT_FRAGMENT_NODE: { break; }
case Node.DOCUMENT_NODE: {
// this node is never "fast"
node = this;
break;
}
case Node.DOCUMENT_TYPE_NODE: {
// save the doctype node
break;
}
case Node.ELEMENT_NODE: {
if (DEBUG_IDS) {
}
// create node
if (fNamespacesEnabled) {
} else {
}
// check to see if this element needs to be
// registered for its ID attributes
if (fIdElement != null) {
while (idIndex != -1) {
if (DEBUG_IDS) {
}
// register ID
if (DEBUG_IDS) {
}
}
// continue if there are more IDs for
// this element
idIndex++;
}
else {
idIndex = -1;
}
}
}
break;
}
case Node.ENTITY_NODE: {
break;
}
case Node.ENTITY_REFERENCE_NODE: {
break;
}
case Node.NOTATION_NODE: {
break;
}
case Node.PROCESSING_INSTRUCTION_NODE: {
break;
}
break;
}
//
// non-standard DOM node types
//
case NodeImpl.ELEMENT_DEFINITION_NODE: {
break;
}
default: {
}
} // switch node type
// store and return
return node;
}
// error
throw new IllegalArgumentException();
} // createNodeObject(int):Node
/** Returns the name of the given node. */
return getNodeName(nodeIndex, true);
} // getNodeNameString(int):String
/**
* Returns the name of the given node.
* @param free True to free the string index.
*/
if (nodeIndex == -1) {
return null;
}
} // getNodeName(int,boolean):String
/** Returns the real value of the given node. */
return getNodeValueString(nodeIndex, true);
} // getNodeValueString(int):String
/**
* Returns the real value of the given node.
* @param free True to free the string index.
*/
if (nodeIndex == -1) {
return null;
}
return null;
}
if (prevSib != -1 &&
// append data that is stored in fNodeValue
// REVISIT: for text nodes it works differently than for CDATA
// nodes.
do {
// go in reverse order: find last child, then
// its previous sibling, etc
if (prevSib == -1) {
break;
}
// add to the buffer in the correct order.
}
fStrChunks.clear();
return value;
}
}
// find if any other data stored in children
if (child !=-1) {
// append data that is stored in fNodeValue
while (child !=-1) {
// go in reverse order: find last child, then
// its previous sibling, etc
}
// add to the buffer in the correct order.
}
fStrChunks.clear();
return value;
}
}
return value;
} // getNodeValueString(int,boolean):String
/**
* Returns the value of the given node.
*/
return getNodeValue(nodeIndex, true);
}
/**
* Clears the type info that is stored in the fNodeValue array
* @param nodeIndex
*/
if (nodeIndex == -1) {
return null;
}
c.fCount--;
if (c.fCount == 0) {
}
}
return value;
}
/**
* Returns the value of the given node.
* @param free True to free the value index.
*/
if (nodeIndex == -1) {
return null;
}
} // getNodeValue(int,boolean):String
/**
* Returns the extra info of the given node.
* Used by AttrImpl to store specified value (1 == true).
*/
return getNodeExtra(nodeIndex, true);
}
/**
* Returns the extra info of the given node.
* @param free True to free the value index.
*/
if (nodeIndex == -1) {
return -1;
}
} // getNodeExtra(int,boolean):int
/** Returns the type of the given node. */
return getNodeType(nodeIndex, true);
}
/**
* Returns the type of the given node.
* @param free True to free type index.
*/
if (nodeIndex == -1) {
return -1;
}
} // getNodeType(int):int
/** Returns the attribute value of the given name. */
return null;
}
while (attrIndex != -1) {
}
}
return null;
}
/** Returns the URI of the given node. */
return getNodeURI(nodeIndex, true);
}
/**
* Returns the URI of the given node.
* @param free True to free URI index.
*/
if (nodeIndex == -1) {
return null;
}
} // getNodeURI(int,int):String
// identifier maintenance
/** Registers an identifier name with a specified element node. */
if (DEBUG_IDS) {
}
// initialize arrays
fIdElement = new int[64];
}
// resize arrays
}
// store identifier
fIdCount++;
} // putIdentifier(String,int)
//
// DEBUG
//
/** Prints out the tables. */
public void print() {
if (DEBUG_PRINT_REF_COUNTS) {
// separator
// ref count
switch (fNodeType[i][CHUNK_SIZE]) {
}
}
}
}
if (DEBUG_PRINT_TABLES) {
// This assumes that the document is small
for (int i = 0; i < fNodeCount; i++) {
int chunk = i >> CHUNK_SHIFT;
int index = i & CHUNK_MASK;
if (i % 10 == 0) {
}
}
}
}
} // print()
//
// DeferredNode methods
//
/** Returns the node index. */
public int getNodeIndex() {
return 0;
}
//
// Protected methods
//
/** Synchronizes the node's data. */
protected void synchronizeData() {
// no need to sync in the future
needsSyncData(false);
// fluff up enough nodes to fill identifiers hash
if (fIdElement != null) {
// REVISIT: There has to be a more efficient way of
// doing this. But keep in mind that the
// tree can have been altered and re-ordered
// before all of the element nodes with ID
// attributes have been registered. For now
// this is reasonable and safe. -Ac
for (int i = 0; i < fIdCount; i++) {
// ignore if it's already been registered
int elementNodeIndex = fIdElement[i];
continue;
}
// find path from this element to the root
int index = elementNodeIndex;
do {
} while (index != -1);
// Traverse path (backwards), fluffing the elements
// along the way. When this loop finishes, "place"
// will contain the reference to the element node
// we're interested in. -Ac
if (child instanceof DeferredNode) {
int nodeIndex =
break;
}
}
}
}
// register the element
// see if there are more IDs on this element
while (i + 1 < fIdCount &&
continue;
}
}
}
} // if identifiers
} // 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() {
if (needsSyncData()) {
/*
* when we have elements with IDs this method is being recursively
* called from synchronizeData, in which case we've already gone
* through the following and we can now simply stop here.
*/
if (!needsSyncChildren()) {
return;
}
}
// we don't want to generate any event for this so turn them off
boolean orig = mutationEvents;
mutationEvents = false;
// no need to sync in the future
needsSyncChildren(false);
getNodeType(0);
// create children and link them as siblings
index != -1;
}
else {
}
// save doctype and document type
}
}
}
firstChild = first;
first.isFirstChild(true);
}
// set mutation events flag back to its original value
} // synchronizeChildren()
/**
* 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.
* This is not directly used in this class but this method is
* here so that it can be shared by all deferred subclasses of AttrImpl.
*/
// we don't want to generate any event for this so turn them off
boolean orig = getMutationEvents();
setMutationEvents(false);
// no need to sync in the future
a.needsSyncChildren(false);
// create children and link them as siblings or simply store the value
// as a String if all we have is one piece of text
if (prev == -1) {
a.hasStringValue(true);
}
else {
}
else {
}
}
firstNode.isFirstChild(true);
}
a.hasStringValue(false);
}
// set mutation events flag back to its original value
} // synchronizeChildren(AttrImpl,int):void
/**
* 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.
* This is not directly used in this class but this method is
* here so that it can be shared by all deferred subclasses of ParentNode.
*/
// we don't want to generate any event for this so turn them off
boolean orig = getMutationEvents();
setMutationEvents(false);
// no need to sync in the future
p.needsSyncChildren(false);
// create children and link them as siblings
index != -1;
}
else {
}
}
p.firstChild = firstNode;
firstNode.isFirstChild(true);
}
// set mutation events flag back to its original value
} // synchronizeChildren(ParentNode,int):void
// utility methods
/** Ensures that the internal tables are large enough. */
// create buffers
fNodeType = new int[INITIAL_CHUNK_COUNT][];
fNodeParent = new int[INITIAL_CHUNK_COUNT][];
fNodeLastChild = new int[INITIAL_CHUNK_COUNT][];
fNodePrevSib = new int[INITIAL_CHUNK_COUNT][];
fNodeExtra = new int[INITIAL_CHUNK_COUNT][];
}
// resize the tables
}
// Done - there's sufficient capacity
return;
}
// create new chunks
// Done
return;
} // ensureCapacity(int,int)
/** Creates a node of the specified type. */
// ensure tables are large enough
// initialize node
// return node index number
return fNodeCount++;
} // createNode(short):int
/**
* Performs a binary search for a target value in an array of
* values. The array of values must be in ascending sorted order
* before calling this method and all array values must be
* non-negative.
*
* @param values The array of values to search.
* @param start The starting offset of the search.
* @param end The ending offset of the search.
* @param target The target value.
*
* @return This function will return the <i>first</i> occurrence
* of the target value, or -1 if the target value cannot
* be found.
*/
if (DEBUG_IDS) {
}
// look for target value
// is this the one we're looking for?
if (DEBUG_IDS) {
}
middle--;
}
if (DEBUG_IDS) {
}
return middle;
}
// is this point higher or lower?
}
else {
}
} // while
// not found
if (DEBUG_IDS) {
}
return -1;
} // binarySearch(int[],int,int,int):int
//
// Private methods
//
static {
for (int i = 0; i < CHUNK_SIZE; i++) {
INIT_ARRAY[i] = -1;
}
}
/** Creates the specified chunk in the given array of chunks. */
}
static final class RefCount {
int fCount;
}
}
/**
* Sets the specified value in the given of data at the chunk and index.
*
* @return Returns the old value.
*/
if (value == -1) {
}
// Re-create chunk if it was deleted.
}
if (ovalue == -1) {
dataChunk[CHUNK_SIZE]++;
}
return ovalue;
}
}
// Re-create chunk if it was deleted.
}
c.fCount++;
}
return ovalue;
}
/**
* Returns the specified value in the given data at the chunk and index.
*/
}
}
return null;
}
}
else {
// type information
}
}
/**
* Clears the specified value in the given data at the chunk and index.
* Note that this method will clear the given chunk if the reference
* count becomes zero.
*
* @return Returns the old value.
*/
if (value != -1) {
}
}
return value;
}
c.fCount--;
if (c.fCount == 0) {
}
}
return value;
}
/**
* This version of putIdentifier is needed to avoid fluffing
* all of the paths to ID attributes when a node object is
* created that contains an ID attribute.
*/
if (DEBUG_IDS) {
idName+", "+
element+')');
}
// create hashtable
if (identifiers == null) {
}
// save ID and its associated element
} // putIdentifier0(String,Element)
/** Prints the ID array. */
if (DEBUG_IDS) {
if (middle == i) {
}
}
if (i < end - 1) {
}
}
}
} // print(int[],int,int,int,int)
//
// Classes
//
/**
* A simple integer vector.
*/
static final class IntVector {
//
// Data
//
/** Data. */
private int data[];
/** Size. */
private int size;
//
// Public methods
//
/** Returns the length of this vector. */
public int size() {
return size;
}
/** Returns the element at the specified index. */
}
/** Appends an element to the end of the vector. */
}
/** Clears the vector. */
public void removeAllElements() {
size = 0;
}
//
// Private methods
//
/** Makes sure that there is enough storage. */
}
}
} // ensureCapacity(int)
} // class IntVector
} // class DeferredDocumentImpl