XML for Java 2.0.15

com.ibm.xml.dom
Class NamedNodeMapImpl

java.lang.Object
  |
  +--com.ibm.xml.dom.NamedNodeMapImpl

public class NamedNodeMapImpl
extends java.lang.Object
implements NamedNodeMap, java.io.Serializable

NamedNodeMaps represent collections of Nodes that can be accessed by name. They're currently used in two modes. Attributes are placed in a NamedNodeMap rather than being children of the node they describe. On the other hand Entity and Notation appear both in the NamedNodeMap _and_ as kids of the DocumentType, requiring some additional logic so these are maintained as "live views" of each other.

Only one Node may be stored per name; attempting to store another will replace the previous value.

NOTE: The storage key is taken from the NodeName attribute of the node. As a result, Node types that have fixed names can only have a single instance stored in the NamedNodeMap. This is a DOM restriction.

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.

As of REC-DOM-Level-1-19981001, Entities and Notations are no longer shadowed as children of DocumentType.

Looked at basing this on Hashtable. Doing so would save about 250 bytes of classfile, at the expense of wasting memory at runtime... and the performance gains for such short sets are questionable. For now I'm going to stick with sorted vectors and binary search.

Since:
PR-DOM-Level-1-19980818.
Version:
Revision: 65 1.8 src/com/ibm/xml/dom/NamedNodeMapImpl.java, parser, xml4j2, xml4j2_0_15
See Also:
Serialized Form

Field Summary
protected  int changes
          Changes.
protected  NamedNodeMapImpl defaults
          Default nodes.
protected  ElementImpl element
          Element.
protected  int lastDefaultsChanges
          Last defaults changes.
protected  java.util.Vector nodes
          Nodes.
protected  Document ownerDocument
          Owner document.
protected  boolean readOnly
          Read-only.
 
Constructor Summary
protected NamedNodeMapImpl(Document ownerDoc, NamedNodeMapImpl defaults)
          Constructs a named node map.
protected NamedNodeMapImpl(ElementImpl element, NamedNodeMapImpl defaults)
          Constructs a named node map.
 
Method Summary
 NamedNodeMapImpl cloneMap()
          Cloning a NamedNodeMap is a DEEP OPERATION; it always clones all the nodes contained in the map.
 int getLength()
          Report how many nodes are currently stored in this NamedNodeMap.
 Node getNamedItem(java.lang.String name)
          Retrieve a node by name.
 Node item(int index)
          Retrieve an item from the map by 0-based index.
protected  void reconcileDefaults()
          Subroutine: If this NamedNodeMap is backed by a "defaults" map (eg, if it's being used for Attributes of an XML file validated against a DTD), we need to deal with the risk that those defaults might have changed.
 Node removeNamedItem(java.lang.String name)
          Remove an entry from the NamedNodeMap.
 Node setNamedItem(Node arg)
          Internal routine: Only update this structure.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

nodes

protected java.util.Vector nodes
Nodes.

ownerDocument

protected Document ownerDocument
Owner document.

element

protected ElementImpl element
Element. Only named node maps holding attributes for elements have an element object. This value is here to support the Attr#getElement method (DOM Level 2, 19 June 1999).

defaults

protected NamedNodeMapImpl defaults
Default nodes.

changes

protected int changes
Changes.

lastDefaultsChanges

protected int lastDefaultsChanges
Last defaults changes.

readOnly

protected boolean readOnly
Read-only.
Constructor Detail

NamedNodeMapImpl

protected NamedNodeMapImpl(Document ownerDoc,
                           NamedNodeMapImpl defaults)
Constructs a named node map.

NamedNodeMapImpl

protected NamedNodeMapImpl(ElementImpl element,
                           NamedNodeMapImpl defaults)
Constructs a named node map.
Method Detail

getLength

public int getLength()
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).

COMPLICATION: In the case of attributes, the count has to include any defaults that may be inherited, yet not double-count when there is both a default and a specified value. Convolving the two lists is expensive, and for GC reasons we don't want to register with the DTD (it wouldn't know when to release us).

One solution is to go into the change-counter domain, as we did for DeepNodeList. Another is to accept the convolution, and count on the fact that our implementation is a sorted list to keep the cost managable... which works pretty well for getLength(), but makes item() expensive.

The ideal fix would be to rearchitect to eliminate integer indexing, but of course that wouldn't meet the spec!

Specified by:
getLength in interface NamedNodeMap

item

public Node item(int index)
Retrieve an item from the map by 0-based index.
Specified by:
item in interface NamedNodeMap
Parameters:
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.

getNamedItem

public Node getNamedItem(java.lang.String name)
Retrieve a node by name. If not explicitly defined, checks the defaults before giving up.
Specified by:
getNamedItem in interface NamedNodeMap
Parameters:
name - Name of a node to look up.

setNamedItem

public Node setNamedItem(Node arg)
                  throws DOMException
Internal routine: Only update this structure.
Specified by:
setNamedItem in interface NamedNodeMap
Parameters:
arg - org.w3c.dom.Node
Returns:
org.w3c.dom.Node
Throws:
DOMException - The exception description.
See Also:
setNamedItem

removeNamedItem

public Node removeNamedItem(java.lang.String name)
                     throws DOMException
Remove an entry from the NamedNodeMap. @see removeNamedItem.
Specified by:
removeNamedItem in interface NamedNodeMap
Parameters:
name - java.lang.String
Returns:
org.w3c.dom.Node
Throws:
DOMException - The exception description.

cloneMap

public NamedNodeMapImpl cloneMap()
Cloning a NamedNodeMap is a DEEP OPERATION; it always clones all the nodes contained in the map.

????? Currently, this does _not_ clone the docType reference. Should the new docType object (if any) be a parameter, rather than being set manually later on?

????? We _do_ clone the defaults reference, if any.


reconcileDefaults

protected void reconcileDefaults()
Subroutine: If this NamedNodeMap is backed by a "defaults" map (eg, if it's being used for Attributes of an XML file validated against a DTD), we need to deal with the risk that those defaults might have changed. Entries may have been added, changed, or removed, and if so we need to update our version of that information

Luckily, this currently applies _only_ to Attributes, which have a "specified" flag that allows us to distinguish which we set manually versus which were defaults... assuming that the defaults list is being maintained properly, of course.

Also luckily, I made the decision to maintain NamedNodeMaps as sorted lists. This should keep the cost of convolving the two lists managable... not wonderful, but at least more like 2N than N**2..

Finally, to avoid doing the convolution except when there are actually changes to be absorbed, I've made the Map aware of whether or not its defaults Map has changed. This is not 110% reliable, but it should work under normal circumstances, especially since the DTD is usually relatively static information.

Note: This is NON-DOM implementation, though used to support behavior that the DOM requires.


XML for Java 2.0.15