FileDocCategorySizeDatePackage
AttributeMap.javaAPI DocApache Xerces 3.0.123279Fri Sep 14 20:33:54 BST 2007org.apache.xerces.dom

AttributeMap

public class AttributeMap extends NamedNodeMapImpl
AttributeMap inherits from NamedNodeMapImpl and extends it to deal with the specifics of storing attributes. These are:
  • managing ownership of attribute nodes
  • managing default attributes
  • firing mutation events

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
version
$Id: AttributeMap.java 449328 2006-09-23 22:58:23Z mrglavas $

Fields Summary
static final long
serialVersionUID
Serialization version.
Constructors Summary
protected AttributeMap(ElementImpl ownerNode, NamedNodeMapImpl defaults)
Constructs a named node map.


    //
    // Constructors
    //

          
         
        super(ownerNode);
        if (defaults != null) {
            // initialize map with the defaults
            cloneContent(defaults);
            if (nodes != null) {
                hasDefaults(true);
            }
        }
    
Methods Summary
protected final intaddItem(org.w3c.dom.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.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(argn.getNodeName(),0);
            if (i >= 0) {
                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);
            }
        }
        
        // notify document
        ownerNode.ownerDocument().setAttrNode(argn, null);
        return i;        
    
protected voidcloneContent(NamedNodeMapImpl srcmap)
Override parent's method to set the ownerNode correctly

        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) srcnodes.elementAt(i);
                    NodeImpl clone = (NodeImpl) n.cloneNode(true);
                    clone.isSpecified(n.isSpecified());
                    nodes.setElementAt(clone, i);
                    clone.ownerNode = ownerNode;
                    clone.isOwned(true);
                }
            }
        }
    
public NamedNodeMapImplcloneMap(NodeImpl ownerNode)
Cloning a NamedNodeMap is a DEEP OPERATION; it always clones all the nodes contained in the map.

        AttributeMap newmap =
            new AttributeMap((ElementImpl) ownerNode, null);
        newmap.hasDefaults(hasDefaults());
        newmap.cloneContent(this);
        return newmap;
    
protected final org.w3c.dom.NodeinternalRemoveNamedItem(java.lang.String name, boolean raiseEx)
Internal removeNamedItem method allowing to specify whether an exception must be thrown if the specified name is not found.

        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.elementAt(i), i, true);

    
protected final org.w3c.dom.NodeinternalRemoveNamedItemNS(java.lang.String namespaceURI, java.lang.String name, boolean raiseEx)
Internal removeNamedItemNS method allowing to specify whether an exception must be thrown if the specified local name and namespace URI is not found.

        
        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.elementAt(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.setElementAt(clone, i);
                    if (clone.isIdAttribute()) {
                        ownerDocument.putIdentifier(clone.getNodeValue(), 
                                (ElementImpl)ownerNode);
                    }
                } else {
                    nodes.removeElementAt(i);
                }
            } else {
                nodes.removeElementAt(i);
            }
        } else {
            nodes.removeElementAt(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;
        
    
voidmoveSpecifiedAttributes(org.apache.xerces.dom.AttributeMap srcmap)
Move specified attributes from the given map to this one

        int nsize = (srcmap.nodes != null) ? srcmap.nodes.size() : 0;
        for (int i = nsize - 1; i >= 0; i--) {
            AttrImpl attr = (AttrImpl) srcmap.nodes.elementAt(i);
            if (attr.isSpecified()) {
                srcmap.remove(attr, i, false);
                if (attr.getLocalName() != null) {
                    setNamedItem(attr);
                }
                else {
                    setNamedItemNS(attr);
                }
            }
        }
    
protected voidreconcileDefaults(NamedNodeMapImpl defaults)
Get this AttributeMap in sync with the given "defaults" map.

param
defaults The default attributes map to sync with.


        // remove any existing default
        int nsize = (nodes != null) ? nodes.size() : 0;
        for (int i = nsize - 1; i >= 0; i--) {
            AttrImpl attr = (AttrImpl) nodes.elementAt(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.elementAt(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.insertElementAt(clone, i);
                }
            }
        }

    
private final org.w3c.dom.Noderemove(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.setElementAt(clone, index);
                    if (attr.isIdAttribute()) {
                        ownerDocument.putIdentifier(clone.getNodeValue(),
                                                (ElementImpl)ownerNode);
                    }
            } else {
                nodes.removeElementAt(index);
            }
        } else {
            nodes.removeElementAt(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;
    
protected org.w3c.dom.NoderemoveItem(org.w3c.dom.Node item, boolean addDefault)
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


        int index = -1;
        if (nodes != null) {
            for (int i = 0; i < nodes.size(); i++) {
                if (nodes.elementAt(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);
    
public org.w3c.dom.NoderemoveNamedItemNS(java.lang.String namespaceURI, java.lang.String name)
Introduced in DOM Level 2.

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.

        return internalRemoveNamedItemNS(namespaceURI, name, true);
    
org.w3c.dom.NodesafeRemoveNamedItem(java.lang.String name)
/ 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.

        return internalRemoveNamedItem(name, false);
    
org.w3c.dom.NodesafeRemoveNamedItemNS(java.lang.String namespaceURI, java.lang.String name)
Same as removeNamedItem except that it simply returns null if the specified local name and namespace URI is not found.

        return internalRemoveNamedItemNS(namespaceURI, name, false);
    
public org.w3c.dom.NodesetNamedItem(org.w3c.dom.Node arg)
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.

        
        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.elementAt(i);
            nodes.setElementAt(arg,i);
            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 Vector(5, 10);
            }
            nodes.insertElementAt(arg, i);
        }
        
        // 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;
        
    
public org.w3c.dom.NodesetNamedItemNS(org.w3c.dom.Node arg)
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.

        
        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.elementAt(i);
            nodes.setElementAt(arg,i);
            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.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);
            }
        }
        //    	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;