FileDocCategorySizeDatePackage
NamedNodeMapImpl.javaAPI DocJava SE 5 API22083Fri Aug 26 14:55:44 BST 2005com.sun.org.apache.xerces.internal.dom

NamedNodeMapImpl

public class NamedNodeMapImpl extends Object implements Serializable, NamedNodeMap
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.

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

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.

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.

version
$Id: NamedNodeMapImpl.java,v 1.35 2003/01/23 23:23:25 lmartin Exp $
since
PR-DOM-Level-1-19980818.

Fields Summary
static final long
serialVersionUID
Serialization version.
protected short
flags
protected static final short
READONLY
protected static final short
CHANGED
protected static final short
HASDEFAULTS
protected Vector
nodes
Nodes.
protected NodeImpl
ownerNode
Constructors Summary
protected NamedNodeMapImpl(NodeImpl ownerNode)
Constructs a named node map.

 // the node this map belongs to

    //
    // Constructors
    //

          
       
        this.ownerNode = ownerNode;
    
Methods Summary
protected intaddItem(org.w3c.dom.Node arg)

    	int i = findNamePoint(arg.getNamespaceURI(), arg.getLocalName());
    	NodeImpl previous = null;
    	if (i >= 0) {
            previous = (NodeImpl) nodes.elementAt(i);
            nodes.setElementAt(arg,i);
    	} 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.elementAt(i);
                nodes.insertElementAt(arg,i);
            } else {
                i = -1 - i; // Insert point (may be end of list)
                if (null == nodes) {
                    nodes = new Vector(5, 10);
                }
                nodes.insertElementAt(arg, i);
            }
        }
        return i;        
    
final booleanchanged()

        return (flags & CHANGED) != 0;
    
final voidchanged(boolean value)

        flags = (short) (value ? flags | CHANGED : flags & ~CHANGED);
    
protected voidcloneContent(com.sun.org.apache.xerces.internal.dom.NamedNodeMapImpl srcmap)

        Vector srcnodes = srcmap.nodes;
        if (srcnodes != null) {
            int size = srcnodes.size();
            if (size != 0) {
                if (nodes == null) {
                    nodes = new Vector(size);
                }
                nodes.setSize(size);
                for (int i = 0; i < size; ++i) {
                    NodeImpl n = (NodeImpl) srcmap.nodes.elementAt(i);
                    NodeImpl clone = (NodeImpl) n.cloneNode(true);
                    clone.isSpecified(n.isSpecified());
                    nodes.setElementAt(clone, i);
                }
            }
        }
    
protected java.util.VectorcloneMap(java.util.Vector list)
NON-DOM: copy content of this map into the specified vector

param
list Vector to copy information into.
return
A copy of this node named map

        if (list == null) {
            list = new Vector(5, 10);
        }
        list.setSize(0);
        if (nodes != null) {
            for (int i=0; i<nodes.size(); i++) {
                list.insertElementAt(nodes.elementAt(i), i);
            }
        }
        
        return list;
    
public com.sun.org.apache.xerces.internal.dom.NamedNodeMapImplcloneMap(com.sun.org.apache.xerces.internal.dom.NodeImpl ownerNode)
Cloning a NamedNodeMap is a DEEP OPERATION; it always clones all the nodes contained in the map.

    	NamedNodeMapImpl newmap = new NamedNodeMapImpl(ownerNode);
        newmap.cloneContent(this);
    	return newmap;
    
protected intfindNamePoint(java.lang.String name, int start)
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.)


    	// 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.elementAt(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.

    
protected intfindNamePoint(java.lang.String namespaceURI, java.lang.String name)
This findNamePoint is for DOM Level 2 Namespaces.

        
        if (nodes == null) return -1;
        if (name == null) return -1;
        
        // This is a linear search through the same nodes Vector.
        // The Vector 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 seconday key.
        for (int i = 0; i < nodes.size(); i++) {
            NodeImpl a = (NodeImpl)nodes.elementAt(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;
    
protected java.lang.ObjectgetItem(int index)

        if (nodes !=null) {
            return nodes.elementAt(index);
        }
        return null;
    
public intgetLength()
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).

    	return (nodes != null) ? nodes.size() : 0;
    
public org.w3c.dom.NodegetNamedItem(java.lang.String name)
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.


    	int i = findNamePoint(name,0);
        return (i < 0) ? null : (Node)(nodes.elementAt(i));

    
protected intgetNamedItemIndex(java.lang.String namespaceURI, java.lang.String localName)

        return findNamePoint(namespaceURI, localName);
     
public org.w3c.dom.NodegetNamedItemNS(java.lang.String namespaceURI, java.lang.String localName)
Introduced in DOM Level 2.

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.


    	int i = findNamePoint(namespaceURI, localName);
        return (i < 0) ? null : (Node)(nodes.elementAt(i));

    
booleangetReadOnly()
Internal subroutine returns this NodeNameMap's (shallow) readOnly value.

    	return isReadOnly();
    
final booleanhasDefaults()

        return (flags & HASDEFAULTS) != 0;
    
final voidhasDefaults(boolean value)

        flags = (short) (value ? flags | HASDEFAULTS : flags & ~HASDEFAULTS);
    
final booleanisReadOnly()

        return (flags & READONLY) != 0;
    
final voidisReadOnly(boolean value)

        flags = (short) (value ? flags | READONLY : flags & ~READONLY);
    
public org.w3c.dom.Nodeitem(int index)
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().

    	return (nodes != null && index < nodes.size()) ?
                    (Node)(nodes.elementAt(index)) : null;
    
protected booleanprecedes(org.w3c.dom.Node a, org.w3c.dom.Node b)


       if (nodes != null) {
          for (int i = 0; i < nodes.size(); i++) {
              Node n = (Node)nodes.elementAt(i);
              if (n==a) return true;
              if (n==b) return false;
          }
       }

       return false;
    
public voidremoveAll()
NON-DOM remove all elements from this map

        if (nodes != null) {
            nodes.removeAllElements();
        }
    
protected voidremoveItem(int index)
NON-DOM: Remove attribute at specified index

       if (nodes != null && index < nodes.size()){
           nodes.removeElementAt(index);
       }
    
public org.w3c.dom.NoderemoveNamedItemNS(java.lang.String namespaceURI, java.lang.String name)
/ 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.elementAt(i); nodes.removeElementAt(i); return n; } // removeNamedItem(String):Node /** Introduced in DOM Level 2.

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
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.


    	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.elementAt(i);
        nodes.removeElementAt(i);

        return n;

    
public org.w3c.dom.NodesetNamedItem(org.w3c.dom.Node arg)
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.


    	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);
        }

   	int i = findNamePoint(arg.getNodeName(),0);
    	NodeImpl previous = null;
    	if (i >= 0) {
            previous = (NodeImpl) nodes.elementAt(i);
            nodes.setElementAt(arg,i);
    	} else {
            i = -1 - i; // Insert point (may be end of list)
            if (null == nodes) {
                nodes = new Vector(5, 10);
            }
            nodes.insertElementAt(arg, i);
        }
    	return previous;

    
public org.w3c.dom.NodesetNamedItemNS(org.w3c.dom.Node arg)
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.


    	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);
        }

    	int i = findNamePoint(arg.getNamespaceURI(), arg.getLocalName());
    	NodeImpl previous = null;
    	if (i >= 0) {
            previous = (NodeImpl) nodes.elementAt(i);
            nodes.setElementAt(arg,i);
    	} 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.elementAt(i);
                nodes.insertElementAt(arg,i);
            } else {
                i = -1 - i; // Insert point (may be end of list)
                if (null == nodes) {
                    nodes = new Vector(5, 10);
                }
                nodes.insertElementAt(arg, i);
            }
        }
    	return previous;

    
voidsetOwnerDocument(com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl doc)
NON-DOM set the ownerDocument of this node, and the attributes it contains

        if (nodes != null) {
            for (int i = 0; i < nodes.size(); i++) {
                ((NodeImpl)item(i)).setOwnerDocument(doc);
            }
        }
    
voidsetReadOnly(boolean readOnly, boolean deep)
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.

        isReadOnly(readOnly);
    	if (deep && nodes != null) {
            for (int i = nodes.size() - 1; i >= 0; i--) {
                ((NodeImpl) nodes.elementAt(i)).setReadOnly(readOnly,deep);
            }
    	}