You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by le...@locus.apache.org on 2000/05/25 03:58:36 UTC
cvs commit: xml-xerces/java/src/org/apache/xerces/dom AttributeMap.java DeferredDocumentTypeImpl.java DeferredElementDefinitionImpl.java DocumentTypeImpl.java ElementDefinitionImpl.java ElementImpl.java Makefile NamedNodeMapImpl.java NodeImpl.java
lehors 00/05/24 18:58:36
Modified: java/src/org/apache/xerces/dom DeferredDocumentTypeImpl.java
DeferredElementDefinitionImpl.java
DocumentTypeImpl.java ElementDefinitionImpl.java
ElementImpl.java Makefile NamedNodeMapImpl.java
NodeImpl.java
Added: java/src/org/apache/xerces/dom AttributeMap.java
Log:
changed NamedNodeMapImpl to a vanilla implementation moving
specific code related to handling attributes into a new subclass AttributeMap.
got rid of the direct reference to the default attributes map so that to save
a pointer, instead we now have a flag that says whether there are any, and
if there are any we do a little more work to find the default attributes map
back. But this only happens on attribute removal so it's a good trade-off.
This version no longer supports dynamic editing of the default attributes
but we do not really support this operation anyway, and if we did that's not
the way we'd want to do it. Instead of doing it in a lazy way, which has
an overhead on every operation related to attributes we'd better do it on
user's demand.
Revision Changes Path
1.6 +3 -3 xml-xerces/java/src/org/apache/xerces/dom/DeferredDocumentTypeImpl.java
Index: DeferredDocumentTypeImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/DeferredDocumentTypeImpl.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- DeferredDocumentTypeImpl.java 2000/04/13 00:34:40 1.5
+++ DeferredDocumentTypeImpl.java 2000/05/25 01:58:30 1.6
@@ -159,9 +159,9 @@
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
- entities = new NamedNodeMapImpl(this, null);
- notations = new NamedNodeMapImpl(this, null);
- elements = new NamedNodeMapImpl(this, null);
+ entities = new NamedNodeMapImpl(this);
+ notations = new NamedNodeMapImpl(this);
+ elements = new NamedNodeMapImpl(this);
// fill node maps
DeferredNode last = null;
1.4 +1 -1 xml-xerces/java/src/org/apache/xerces/dom/DeferredElementDefinitionImpl.java
Index: DeferredElementDefinitionImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/DeferredElementDefinitionImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DeferredElementDefinitionImpl.java 2000/04/13 00:34:40 1.3
+++ DeferredElementDefinitionImpl.java 2000/05/25 01:58:30 1.4
@@ -138,7 +138,7 @@
// create attributes node map
DeferredDocumentImpl ownerDocument =
(DeferredDocumentImpl)this.ownerDocument;
- attributes = new NamedNodeMapImpl(ownerDocument, null);
+ attributes = new NamedNodeMapImpl(ownerDocument);
// Default attributes dangle as children of the element
// definition "node" in the internal fast table.
1.13 +3 -3 xml-xerces/java/src/org/apache/xerces/dom/DocumentTypeImpl.java
Index: DocumentTypeImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/DocumentTypeImpl.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- DocumentTypeImpl.java 2000/04/28 22:46:45 1.12
+++ DocumentTypeImpl.java 2000/05/25 01:58:30 1.13
@@ -127,11 +127,11 @@
this.name = name;
// DOM
- entities = new NamedNodeMapImpl(this, null);
- notations = new NamedNodeMapImpl(this, null);
+ entities = new NamedNodeMapImpl(this);
+ notations = new NamedNodeMapImpl(this);
// NON-DOM
- elements = new NamedNodeMapImpl(this,null);
+ elements = new NamedNodeMapImpl(this);
} // <init>(DocumentImpl,String)
1.7 +1 -1 xml-xerces/java/src/org/apache/xerces/dom/ElementDefinitionImpl.java
Index: ElementDefinitionImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/ElementDefinitionImpl.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- ElementDefinitionImpl.java 2000/04/10 22:08:11 1.6
+++ ElementDefinitionImpl.java 2000/05/25 01:58:31 1.7
@@ -96,7 +96,7 @@
public ElementDefinitionImpl(DocumentImpl ownerDocument, String name) {
super(ownerDocument);
this.name = name;
- attributes = new NamedNodeMapImpl(ownerDocument, null);
+ attributes = new NamedNodeMapImpl(ownerDocument);
}
//
1.22 +46 -71 xml-xerces/java/src/org/apache/xerces/dom/ElementImpl.java
Index: ElementImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/ElementImpl.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- ElementImpl.java 2000/05/24 18:10:26 1.21
+++ ElementImpl.java 2000/05/25 01:58:31 1.22
@@ -101,7 +101,7 @@
protected String name;
/** Attributes. */
- protected NamedNodeMapImpl attributes;
+ protected AttributeMap attributes;
//
// Constructors
@@ -152,7 +152,7 @@
synchronizeData();
}
if (attributes == null) {
- attributes = new NamedNodeMapImpl(this, null);
+ attributes = new AttributeMap(this, null);
}
return attributes;
@@ -174,7 +174,7 @@
ElementImpl newnode = (ElementImpl) super.cloneNode(deep);
// Replicate NamedNodeMap rather than sharing it.
if (attributes != null) {
- newnode.attributes = attributes.cloneMap(newnode);
+ newnode.attributes = (AttributeMap) attributes.cloneMap(newnode);
}
return newnode;
@@ -340,14 +340,12 @@
if (syncData()) {
synchronizeData();
}
+
if (attributes == null) {
return;
}
- AttrImpl att = (AttrImpl) attributes.getNamedItem(name);
- // Remove it (and let the NamedNodeMap recreate the default, if any)
- if (att != null) {
- attributes.removeNamedItem(name);
- }
+
+ attributes.safeRemoveNamedItem(name);
} // removeAttribute(String)
@@ -386,19 +384,8 @@
throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
"DOM008 Not found");
}
- AttrImpl found = (AttrImpl) attributes.getNamedItem(oldAttr.getName());
-
- // If it is in fact the right object, remove it (and let the
- // NamedNodeMap recreate the default, if any)
-
- if (found == oldAttr) {
- attributes.removeNamedItem(oldAttr.getName());
- return found;
- }
+ return (Attr) attributes.removeNamedItem(oldAttr.getName());
- throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
- "DOM008 Not found");
-
} // removeAttributeNode(Attr):Attr
@@ -433,12 +420,12 @@
synchronizeData();
}
- AttrImpl newAttr = (AttrImpl) getAttributeNode(name);
+ Attr newAttr = getAttributeNode(name);
if (newAttr == null) {
- newAttr = (AttrImpl) getOwnerDocument().createAttribute(name);
+ newAttr = getOwnerDocument().createAttribute(name);
if (attributes == null) {
- attributes = new NamedNodeMapImpl(this, null);
+ attributes = new AttributeMap(this, null);
}
attributes.setNamedItem(newAttr);
}
@@ -473,23 +460,17 @@
synchronizeData();
}
- if (ownerDocument.errorChecking && !(newAttr instanceof AttrImpl)) {
+ if (ownerDocument.errorChecking
+ && newAttr.getOwnerDocument() != ownerDocument) {
throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
"DOM005 Wrong document");
}
- AttrImpl na = (AttrImpl) newAttr;
- AttrImpl oldAttr;
if (attributes == null) {
- attributes = new NamedNodeMapImpl(this, null);
- oldAttr = null;
- } else {
- oldAttr = (AttrImpl) attributes.getNamedItem(newAttr.getName());
+ attributes = new AttributeMap(this, null);
}
// This will throw INUSE if necessary
- attributes.setNamedItem(na);
-
- return oldAttr;
+ return (Attr) attributes.setNamedItem(newAttr);
} // setAttributeNode(Attr):Attr
@@ -516,9 +497,11 @@
if (syncData()) {
synchronizeData();
}
+
if (attributes == null) {
return "";
}
+
Attr attr = (Attr)(attributes.getNamedItemNS(namespaceURI, localName));
return (attr == null) ? null : attr.getValue();
@@ -575,14 +558,14 @@
if (syncData()) {
synchronizeData();
}
- AttrImpl newAttr = (AttrImpl)
- getAttributeNodeNS(namespaceURI, localName);
+
+ Attr newAttr = getAttributeNodeNS(namespaceURI, localName);
if (newAttr == null) {
- newAttr = (AttrImpl)
+ newAttr =
getOwnerDocument().createAttributeNS(namespaceURI, localName);
if (attributes == null) {
- attributes = new NamedNodeMapImpl(this, null);
+ attributes = new AttributeMap(this, null);
}
attributes.setNamedItemNS(newAttr);
}
@@ -616,15 +599,12 @@
if (syncData()) {
synchronizeData();
}
+
if (attributes == null) {
return;
}
- AttrImpl att =
- (AttrImpl) attributes.getNamedItemNS(namespaceURI, localName);
- // Remove it (and let the NamedNodeMap recreate the default, if any)
- if (att != null) {
- attributes.removeNamedItemNS(namespaceURI, localName);
- }
+
+ attributes.safeRemoveNamedItemNS(namespaceURI, localName);
} // removeAttributeNS(String,String)
@@ -647,7 +627,7 @@
if (attributes == null) {
return null;
}
- return (Attr)attributes.getNamedItemNS( namespaceURI, localName);
+ return (Attr)attributes.getNamedItemNS(namespaceURI, localName);
} // getAttributeNodeNS(String,String):Attr
@@ -691,26 +671,18 @@
synchronizeData();
}
- if (ownerDocument.errorChecking && !(newAttr instanceof AttrImpl)) {
+ if (ownerDocument.errorChecking
+ && newAttr.getOwnerDocument() != ownerDocument) {
throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
"DOM005 Wrong document");
}
- AttrImpl na = (AttrImpl) newAttr;
- AttrImpl oldAttr;
if (attributes == null) {
- attributes = new NamedNodeMapImpl(this, null);
- oldAttr = null;
- } else {
- oldAttr =
- (AttrImpl) attributes.getNamedItemNS(na.getNamespaceURI(),
- na.getLocalName());
+ attributes = new AttributeMap(this, null);
}
// This will throw INUSE if necessary
- attributes.setNamedItem(na);
+ return (Attr) attributes.setNamedItemNS(newAttr);
- return oldAttr;
-
} // setAttributeNodeNS(Attr):Attr
/**
@@ -780,24 +752,27 @@
/** Setup the default attributes. */
protected void setupDefaultAttributes() {
-
- // If there is an ElementDefintion, set its Attributes up as
- // shadows behind our own.
- NamedNodeMapImpl defaultAttrs = null;
- DocumentTypeImpl doctype = (DocumentTypeImpl)ownerDocument.getDoctype();
- if (doctype != null) {
- ElementDefinitionImpl eldef =
- (ElementDefinitionImpl)doctype.getElements()
- .getNamedItem(getNodeName());
- if (eldef != null) {
- defaultAttrs = (NamedNodeMapImpl)eldef.getAttributes();
- }
+ NamedNodeMapImpl defaults = getDefaultAttributes();
+ if (defaults != null) {
+ attributes = new AttributeMap(this, defaults);
}
+ }
+
+ /** Get the default attributes. */
+ protected NamedNodeMapImpl getDefaultAttributes() {
- // create attributes
- if (defaultAttrs != null) {
- attributes = new NamedNodeMapImpl(this, defaultAttrs);
+ DocumentTypeImpl doctype =
+ (DocumentTypeImpl) ownerDocument.getDoctype();
+ if (doctype == null) {
+ return null;
+ }
+ ElementDefinitionImpl eldef =
+ (ElementDefinitionImpl)doctype.getElements()
+ .getNamedItem(getNodeName());
+ if (eldef == null) {
+ return null;
}
+ return (NamedNodeMapImpl) eldef.getAttributes();
} // setupAttributes(DocumentImpl)
1.10 +1 -0 xml-xerces/java/src/org/apache/xerces/dom/Makefile
Index: Makefile
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/Makefile,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Makefile 2000/04/10 22:08:11 1.9
+++ Makefile 2000/05/25 01:58:31 1.10
@@ -2,6 +2,7 @@
TARGETS=\
AttrImpl.class\
+ AttributeMap.class\
AttrNSImpl.class\
CDATASectionImpl.class\
CharacterDataImpl.class\
1.15 +38 -330 xml-xerces/java/src/org/apache/xerces/dom/NamedNodeMapImpl.java
Index: NamedNodeMapImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/NamedNodeMapImpl.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- NamedNodeMapImpl.java 2000/05/04 20:21:55 1.14
+++ NamedNodeMapImpl.java 2000/05/25 01:58:31 1.15
@@ -63,41 +63,27 @@
import org.w3c.dom.*;
-//import org.apache.xerces.domx.events.*;
-import org.apache.xerces.dom.events.MutationEventImpl;
-import org.w3c.dom.events.*;
-
/**
* 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.
+ * 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 "nodes" Vector is kept sorted by this key to speed lookup,
- * ad make it easier to reconcile with the defaults. 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.
+ * 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>
- * As of REC-DOM-Level-1-19981001, Entities and Notations are no longer
- * shadowed as children of DocumentType.
- * <P>
- * This implementation includes support for DOM Level 2 Mutation Events.
- * If the static boolean NodeImpl.MUTATIONEVENTS is not set true, that support
- * is disabled and can be optimized out to reduce code size.
- * <P>
*
* @version
* @since PR-DOM-Level-1-19980818.
@@ -111,7 +97,6 @@
/** Serialization version. */
static final long serialVersionUID = -7039242451046758020L;
- static final boolean DEBUG = false;
//
// Data
@@ -121,24 +106,20 @@
protected final static short READONLY = 0x1<<0;
protected final static short CHANGED = 0x1<<1;
+ protected final static short HASDEFAULTS = 0x1<<2;
/** Nodes. */
protected Vector nodes;
protected NodeImpl ownerNode; // the node this map belongs to
- /** Default nodes. */
- protected NamedNodeMapImpl defaults;
-
//
// Constructors
//
/** Constructs a named node map. */
- protected NamedNodeMapImpl(NodeImpl ownerNode, NamedNodeMapImpl defaults) {
+ protected NamedNodeMapImpl(NodeImpl ownerNode) {
this.ownerNode = ownerNode;
- this.defaults = defaults;
- changed(true); // to get reconcileDefaults called
}
//
@@ -150,25 +131,8 @@
* Caveat: This is a count rather than an index, so the
* highest-numbered node at any time can be accessed via
* item(getLength()-1).
- * <P>
- * 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).
- * <P>
- * 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.
- * <P>
- * The ideal fix would be to rearchitect to eliminate integer indexing,
- * but of course that wouldn't meet the spec!
*/
public int getLength() {
- reconcileDefaults();
return (nodes != null) ? nodes.size() : 0;
}
@@ -187,14 +151,12 @@
* if index is greater than or equal to getLength().
*/
public Node item(int index) {
- reconcileDefaults();
return (nodes != null && index < nodes.size()) ?
(Node)(nodes.elementAt(index)) : null;
}
/**
- * Retrieve a node by name. If not explicitly defined, checks the
- * defaults before giving up.
+ * Retrieve a node by name.
*
* @param name Name of a node to look up.
* @returns the Node (of unspecified sub-class) stored with that name,
@@ -249,26 +211,16 @@
throw new DOMExceptionImpl(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"DOM001 Modification not allowed");
}
- if(arg.getOwnerDocument() != ownerNode.ownerDocument()) {
+ if (arg.getOwnerDocument() != ownerNode.ownerDocument()) {
throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
"DOM005 Wrong document");
}
- NodeImpl argn = (NodeImpl)arg;
-
- if (argn.owned()) {
- throw new DOMExceptionImpl(DOMException.INUSE_ATTRIBUTE_ERR,
- "DOM009 Attribute already in use");
- }
- argn.ownerNode = ownerNode;
- argn.owned(true);
int i = findNamePoint(arg.getNodeName(),0);
NodeImpl previous = null;
if (i >= 0) {
previous = (NodeImpl) nodes.elementAt(i);
nodes.setElementAt(arg,i);
- previous.ownerNode = ownerNode.ownerDocument();
- previous.owned(false);
} else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
@@ -276,19 +228,6 @@
}
nodes.insertElementAt(arg, i);
}
- changed(true);
-
- // Only NamedNodeMaps containing attributes (those which are
- // bound to an element) need report MutationEvents
- if (NodeImpl.MUTATIONEVENTS &&
- ownerNode != null && ownerNode instanceof ElementImpl)
- {
- // MUTATION POST-EVENTS:
- ownerNode.dispatchAggregateEvents(
- (AttrImpl)arg,
- previous==null ? null : previous.getNodeValue()
- );
- }
return previous;
} // setNamedItem(Node):Node
@@ -317,23 +256,15 @@
"DOM005 Wrong document");
}
- NodeImpl argn = (NodeImpl)arg;
- if (argn.owned()) {
- throw new DOMExceptionImpl(DOMException.INUSE_ATTRIBUTE_ERR,
- "DOM009 Attribute already in use");
- }
-
- int i = findNamePoint(argn.getNamespaceURI(), argn.getLocalName());
+ int i = findNamePoint(arg.getNamespaceURI(), arg.getLocalName());
NodeImpl previous = null;
if (i >= 0) {
previous = (NodeImpl) nodes.elementAt(i);
nodes.setElementAt(arg,i);
- previous.ownerNode = ownerNode.ownerDocument();
- previous.owned(false);
} 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);
+ i = findNamePoint(arg.getNodeName(),0);
if (i >=0) {
previous = (NodeImpl) nodes.elementAt(i);
nodes.insertElementAt(arg,i);
@@ -345,33 +276,13 @@
nodes.insertElementAt(arg, i);
}
}
- changed(true);
-
- // Only NamedNodeMaps containing attributes (those which are
- // bound to an element) need report MutationEvents
- if (NodeImpl.MUTATIONEVENTS &&
- ownerNode != null && ownerNode instanceof ElementImpl)
- {
- // MUTATION POST-EVENTS:
- ownerNode.dispatchAggregateEvents(
- (AttrImpl)arg,
- previous==null ? null : previous.getNodeValue()
- );
- }
return previous;
} // setNamedItem(Node):Node
/**
* Removes a node specified by name.
- * @param name
- * The name of a node to remove. When this NamedNodeMap
- * contains the attributes attached to an element, as returned
- * by the attributes attribute of the Node interface, 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.
+ * @param name The name of a node to remove.
* @return The node removed from the map if a node with such a name exists.
*/
/***/
@@ -390,24 +301,8 @@
}
NodeImpl n = (NodeImpl)nodes.elementAt(i);
- // If there's a default, add it instead
- Node d;
- if (defaults != null && (d = defaults.getNamedItem(name)) != null
- && findNamePoint(name, i+1) < 0) {
-
- NodeImpl clone = (NodeImpl)d.cloneNode(true);
- clone.ownerNode = ownerNode;
- clone.owned(true);
- nodes.setElementAt(clone, i);
- }
- else {
- nodes.removeElementAt(i);
- }
-
- changed(true);
- // remove owning element
- n.ownerNode = ownerNode.ownerDocument();
- n.owned(false);
+ nodes.removeElementAt(i);
+
return n;
} // removeNamedItem(String):Node
@@ -419,15 +314,9 @@
* 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. When
- * this NamedNodeMap contains the attributes
- * attached to an element, as returned by the
- * attributes attribute of the Node interface, 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.
+ * @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.
@@ -446,72 +335,9 @@
"DOM008 Not found");
}
- LCount lc=null;
- String oldvalue="";
- AttrImpl enclosingAttribute=null;
- if (NodeImpl.MUTATIONEVENTS &&
- ownerNode != null && ownerNode instanceof ElementImpl)
- {
- // MUTATION PREPROCESSING AND PRE-EVENTS:
- lc=LCount.lookup(MutationEventImpl.DOM_ATTR_MODIFIED);
- if(lc.captures+lc.bubbles+lc.defaults>0)
- {
- enclosingAttribute=(AttrImpl)(nodes.elementAt(i));
- oldvalue=enclosingAttribute.getNodeValue();
- }
- } // End mutation preprocessing
-
NodeImpl n = (NodeImpl)nodes.elementAt(i);
- // If there's a default, add it instead
- Node d;
- String nodeName = n.getNodeName();
- 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;
- clone.owned(true);
- nodes.setElementAt(clone, i);
- } else {
- nodes.removeElementAt(i);
- }
- }
- else {
- nodes.removeElementAt(i);
- }
-
- changed(true);
-
- // Need to remove references to an Attr's owner before the
- // MutationEvents fire.
- n.ownerNode = ownerNode.ownerDocument();
- n.owned(false);
-
- // We can't use the standard dispatchAggregate, since it assumes
- // that the Attr is still attached to an owner. This code is
- // similar but dispatches to the previous owner, "element".
- if(NodeImpl.MUTATIONEVENTS &&
- ownerNode != null && ownerNode instanceof ElementImpl)
- {
- // If we have to send DOMAttrModified (determined earlier),
- // do so.
- if(lc.captures+lc.bubbles+lc.defaults>0)
- {
- MutationEvent me= new MutationEventImpl();
- //?????ownerDocument.createEvent("MutationEvents");
- me.initMutationEvent(MutationEventImpl.DOM_ATTR_MODIFIED,
- true, false,
- null, n.getNodeValue(),
- ((ElementImpl)ownerNode).getAttribute(name),name);
- ownerNode.dispatchEvent(me);
- }
+ nodes.removeElementAt(i);
- // We can hand off to process DOMSubtreeModified, though.
- // Note that only the Element needs to be informed; the
- // Attr's subtree has not been changed by this operation.
- ownerNode.dispatchAggregateEvents(null,null);
- }
return n;
} // removeNamedItem(String):Node
@@ -525,23 +351,20 @@
* all the nodes contained in the map.
*/
- // REVIST: 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.
public NamedNodeMapImpl cloneMap(NodeImpl ownerNode) {
- NamedNodeMapImpl newmap = new NamedNodeMapImpl(ownerNode, defaults);
+ NamedNodeMapImpl newmap = new NamedNodeMapImpl(ownerNode);
+ cloneContent(newmap);
+ return newmap;
+ }
+
+ protected void cloneContent(NamedNodeMapImpl newmap) {
if (nodes != null) {
newmap.nodes = new Vector(nodes.size());
for (int i = 0; i < nodes.size(); ++i) {
- NodeImpl clone = (NodeImpl)((Node)nodes.elementAt(i)).cloneNode(true);
+ Node clone = ((Node)nodes.elementAt(i)).cloneNode(true);
newmap.setNamedItem(clone);
}
}
- newmap.defaults = defaults;
- newmap.changed(changed());
- return newmap;
-
} // cloneMap():NamedNodeMapImpl
//
@@ -585,124 +408,6 @@
//
/**
- * 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
- * <P>
- * 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.
- * <P>
- * Also luckily, The NameNodeMaps are maintained 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..
- * <P>
- * 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.
- * <P>
- * Note: This is NON-DOM implementation, though used to support behavior
- * that the DOM requires.
- */
- protected void reconcileDefaults() {
-
- if (DEBUG) System.out.println("reconcileDefaults:");
- if (defaults != null && changed()) {
-
- int n = 0;
- int d = 0;
- int nsize = (nodes != null) ? nodes.size() : 0;
- int dsize = defaults.nodes.size();
-
- AttrImpl nnode = (nsize == 0) ? null : (AttrImpl) nodes.elementAt(0);
- AttrImpl dnode = (dsize == 0) ? null : (AttrImpl) defaults.nodes.elementAt(0);
-
- while (n < nsize && d < dsize) {
- nnode = (AttrImpl) nodes.elementAt(n);
- dnode = (AttrImpl) defaults.nodes.elementAt(d);
- if (DEBUG) {
- System.out.println("\n\nnnode="+nnode.getNodeName());
- System.out.println("dnode="+dnode.getNodeName());
- }
-
-
- int test = nnode.getNodeName().compareTo(dnode.getNodeName());
-
- //REVIST: EACH CONDITION - HOW IT RESPONDS TO DUPLICATE KEYS!
- // Same name and a default -- make sure same value
- if (test == 0) {
- if (!nnode.getSpecified()) {
- if (DEBUG) System.out.println("reconcile (test==0, specified = false): clone default");
- NodeImpl clone = (NodeImpl)dnode.cloneNode(true);
- clone.ownerNode = ownerNode;
- clone.owned(true);
- nodes.setElementAt(clone, n);
- // Advance over both, since names in sync
- ++n;
- ++d;
- }
- else { //REVIST: if same name, but specified, simply increment over it.
- if (DEBUG)
- System.out.println("reconcile (test==0, specified=true): just increment");
- ++n;
- ++d;
- }
- }
-
- // Different name, new default in table; add it
- else if (test > 0) {
- if (DEBUG) System.out.println("reconcile (test>0): insert new default");
- NodeImpl clone = (NodeImpl)dnode.cloneNode(true);
- clone.ownerNode = ownerNode;
- clone.owned(true);
- nodes.insertElementAt(clone, n);
- // Now in sync, so advance over both
- ++n;
- ++d;
- }
-
- // Different name, old default here; remove it.
- else if (!nnode.getSpecified()) {
- if (DEBUG) System.out.println("reconcile(!specified): remove old default:"
- +nnode.getNodeName());
- // NOTE: We don't need to null out the parent
- // because this is a node that we're
- // throwing away (not returning). -Ac
- // REVISIT: [Q] Should we null it out anyway? -Ac
- nodes.removeElementAt(n);
- // n didn't advance but represents a different element
- }
-
- // Different name, specified; accept it
- else {
- if (DEBUG) System.out.println("reconcile: Different name else accept it.");
- ++n;
- }
- }
-
- // If we ran out of local before default, pick up defaults
- if (d < dsize) {
- if (nodes == null) nodes = new Vector();
- while (d < dsize) {
- dnode = (AttrImpl)defaults.nodes.elementAt(d++);
- NodeImpl clone = (NodeImpl)dnode.cloneNode(true);
- clone.ownerNode = ownerNode;
- clone.owned(true);
- if (DEBUG) System.out.println("reconcile: adding"+clone);
- nodes.addElement(clone);
- }
- }
- changed(false);
- }
- } // reconcileDefaults()
-
-
- /**
* NON-DOM
* set the ownerDocument of this node, and the attributes it contains
*/
@@ -730,6 +435,14 @@
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
//
@@ -738,8 +451,6 @@
* Subroutine: Locate the named item, or the point at which said item
* should be added.
*
- * SIDE EFFECT: Resynchronizes w/ Defaults.
- *
* @param name Name of a node to look up.
*
* @return If positive or zero, the index of the found item.
@@ -748,9 +459,7 @@
* 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.)
*/
- private int findNamePoint(String name, int start) {
-
- reconcileDefaults();
+ protected int findNamePoint(String name, int start) {
// Binary search
int i = 0;
@@ -784,9 +493,8 @@
/** This findNamePoint is for DOM Level 2 Namespaces.
*/
- private int findNamePoint(String namespaceURI, String name) {
+ protected int findNamePoint(String namespaceURI, String name) {
- reconcileDefaults();
if (nodes == null) return -1;
if (namespaceURI == null) return -1;
if (name == null) return -1;
1.23 +0 -9 xml-xerces/java/src/org/apache/xerces/dom/NodeImpl.java
Index: NodeImpl.java
===================================================================
RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/dom/NodeImpl.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- NodeImpl.java 2000/05/24 20:28:24 1.22
+++ NodeImpl.java 2000/05/25 01:58:32 1.23
@@ -140,7 +140,6 @@
protected final static short SPECIFIED = 0x1<<5;
protected final static short IGNORABLEWS = 0x1<<6;
protected final static short SETVALUE = 0x1<<7;
- protected final static short HASDEFAULT = 0x1<<8;
//
// Constructors
@@ -1334,14 +1333,6 @@
final void setValue(boolean value) {
flags = (short) (value ? flags | SETVALUE : flags & ~SETVALUE);
- }
-
- final boolean hasDefault() {
- return (flags & HASDEFAULT) != 0;
- }
-
- final void hasDefault(boolean value) {
- flags = (short) (value ? flags | HASDEFAULT : flags & ~HASDEFAULT);
}
//
1.1 xml-xerces/java/src/org/apache/xerces/dom/AttributeMap.java
Index: AttributeMap.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 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 org.apache.xerces.dom;
import java.io.*;
import java.util.Vector;
import java.util.Enumeration;
import org.w3c.dom.*;
import org.apache.xerces.dom.events.MutationEventImpl;
import org.w3c.dom.events.*;
/**
* 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>
*
*/
public class AttributeMap extends NamedNodeMapImpl {
//
// Constructors
//
/** Constructs a named node map. */
protected AttributeMap(ElementImpl ownerNode, NamedNodeMapImpl defaults) {
super(ownerNode);
if (defaults != null) {
hasDefaults(true);
// initialize map with the defaults
if (defaults.nodes != null) {
nodes = new Vector(defaults.nodes.size());
for (int i = 0; i < nodes.size(); ++i) {
NodeImpl node = (NodeImpl) defaults.nodes.elementAt(i);
NodeImpl clone = (NodeImpl) node.cloneNode(true);
clone.specified(false); // mark it as a default attr
setNamedItem(clone);
}
}
}
}
/**
* 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 {
if (readOnly()) {
throw
new DOMExceptionImpl(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"DOM001 Modification not allowed");
}
if(arg.getOwnerDocument() != ownerNode.ownerDocument()) {
throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
"DOM005 Wrong document");
}
NodeImpl argn = (NodeImpl)arg;
if (argn.owned()) {
throw new DOMExceptionImpl(DOMException.INUSE_ATTRIBUTE_ERR,
"DOM009 Attribute already in use");
}
// set owner
argn.ownerNode = ownerNode;
argn.owned(true);
int i = findNamePoint(arg.getNodeName(),0);
NodeImpl previous = null;
if (i >= 0) {
previous = (NodeImpl) nodes.elementAt(i);
nodes.setElementAt(arg,i);
previous.ownerNode = ownerNode.ownerDocument();
previous.owned(false);
// make sure it won't be mistaken with defaults in case it's reused
previous.specified(true);
} else {
i = -1 - i; // Insert point (may be end of list)
if (null == nodes) {
nodes = new Vector(5, 10);
}
nodes.insertElementAt(arg, i);
}
if (NodeImpl.MUTATIONEVENTS) {
// MUTATION POST-EVENTS:
ownerNode.dispatchAggregateEvents(
(AttrImpl)arg,
previous==null ? null : previous.getNodeValue()
);
}
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 {
if (readOnly()) {
throw
new DOMExceptionImpl(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"DOM001 Modification not allowed");
}
if(arg.getOwnerDocument() != ownerNode.ownerDocument()) {
throw new DOMExceptionImpl(DOMException.WRONG_DOCUMENT_ERR,
"DOM005 Wrong document");
}
NodeImpl argn = (NodeImpl)arg;
if (argn.owned()) {
throw new DOMExceptionImpl(DOMException.INUSE_ATTRIBUTE_ERR,
"DOM009 Attribute already in use");
}
int i = findNamePoint(argn.getNamespaceURI(), argn.getLocalName());
NodeImpl previous = null;
if (i >= 0) {
previous = (NodeImpl) nodes.elementAt(i);
nodes.setElementAt(arg,i);
previous.ownerNode = ownerNode.ownerDocument();
previous.owned(false);
// make sure it won't be mistaken with defaults in case it's reused
previous.specified(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 = (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);
}
}
// changed(true);
// Only NamedNodeMaps containing attributes (those which are
// bound to an element) need report MutationEvents
if (NodeImpl.MUTATIONEVENTS)
{
// MUTATION POST-EVENTS:
ownerNode.dispatchAggregateEvents(
(AttrImpl)arg,
previous==null ? null : previous.getNodeValue()
);
}
return previous;
} // setNamedItem(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);
}
/**
* 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 (readOnly()) {
throw
new DOMExceptionImpl(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"DOM001 Modification not allowed");
}
int i = findNamePoint(name,0);
if (i < 0) {
if (raiseEx) {
throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
"DOM008 Not found");
} else {
return null;
}
}
NodeImpl n = (NodeImpl)nodes.elementAt(i);
// If there's a default, add it instead
if (hasDefaults()) {
NamedNodeMapImpl defaults =
((ElementImpl) ownerNode).getDefaultAttributes();
Node d;
if (defaults != null && (d = defaults.getNamedItem(name)) != null
&& findNamePoint(name, i+1) < 0) {
NodeImpl clone = (NodeImpl)d.cloneNode(true);
clone.ownerNode = ownerNode;
clone.owned(true);
clone.specified(false);
nodes.setElementAt(clone, i);
} else {
nodes.removeElementAt(i);
}
} else {
nodes.removeElementAt(i);
}
// changed(true);
// remove owning element
n.ownerNode = ownerNode.ownerDocument();
n.owned(false);
// make sure it won't be mistaken with defaults in case it's reused
n.specified(true);
return n;
} // removeNamedItem(String):Node
/**
* 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 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) {
if (readOnly()) {
throw
new DOMExceptionImpl(DOMException.NO_MODIFICATION_ALLOWED_ERR,
"DOM001 Modification not allowed");
}
int i = findNamePoint(namespaceURI, name);
if (i < 0) {
if (raiseEx) {
throw new DOMExceptionImpl(DOMException.NOT_FOUND_ERR,
"DOM008 Not found");
} else {
return null;
}
}
LCount lc=null;
String oldvalue="";
AttrImpl enclosingAttribute=null;
if (NodeImpl.MUTATIONEVENTS)
{
// MUTATION PREPROCESSING AND PRE-EVENTS:
lc=LCount.lookup(MutationEventImpl.DOM_ATTR_MODIFIED);
if(lc.captures+lc.bubbles+lc.defaults>0)
{
enclosingAttribute=(AttrImpl)(nodes.elementAt(i));
oldvalue=enclosingAttribute.getNodeValue();
}
} // End mutation preprocessing
NodeImpl n = (NodeImpl)nodes.elementAt(i);
// 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;
clone.owned(true);
clone.specified(false);
nodes.setElementAt(clone, i);
} else {
nodes.removeElementAt(i);
}
} else {
nodes.removeElementAt(i);
}
} else {
nodes.removeElementAt(i);
}
// changed(true);
// Need to remove references to an Attr's owner before the
// MutationEvents fire.
n.ownerNode = ownerNode.ownerDocument();
n.owned(false);
// make sure it won't be mistaken with defaults in case it's reused
n.specified(true);
// We can't use the standard dispatchAggregate, since it assumes
// that the Attr is still attached to an owner. This code is
// similar but dispatches to the previous owner, "element".
if(NodeImpl.MUTATIONEVENTS)
{
// If we have to send DOMAttrModified (determined earlier),
// do so.
if(lc.captures+lc.bubbles+lc.defaults>0) {
MutationEvent me= new MutationEventImpl();
//?????ownerDocument.createEvent("MutationEvents");
me.initMutationEvent(MutationEventImpl.DOM_ATTR_MODIFIED,
true, false,
null, n.getNodeValue(),
((ElementImpl)ownerNode).getAttribute(name),name);
ownerNode.dispatchEvent(me);
}
// We can hand off to process DOMSubtreeModified, though.
// Note that only the Element needs to be informed; the
// Attr's subtree has not been changed by this operation.
ownerNode.dispatchAggregateEvents(null,null);
}
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) {
AttributeMap newmap =
new AttributeMap((ElementImpl) ownerNode, null);
newmap.hasDefaults(hasDefaults());
cloneContent(newmap);
return newmap;
} // cloneMap():AttributeMap
//
// Protected methods
//
/**
* 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
* <P>
* 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.
* <P>
* Also luckily, The NameNodeMaps are maintained 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..
* <P>
* 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.
* <P>
* Note: This is NON-DOM implementation, though used to support behavior
* that the DOM requires.
*/
/** COMMENTED OUT!!!!!!! ********
Doing this dynamically is a killer, since editing the DTD isn't even
supported this is commented out at least for now. In the long run it seems
better to update the document on user's demand after the DTD has been
changed rather than doing this anyway.
protected void reconcileDefaults() {
if (DEBUG) System.out.println("reconcileDefaults:");
if (defaults != null && changed()) {
int n = 0;
int d = 0;
int nsize = (nodes != null) ? nodes.size() : 0;
int dsize = defaults.nodes.size();
AttrImpl nnode = (nsize == 0) ? null : (AttrImpl) nodes.elementAt(0);
AttrImpl dnode = (dsize == 0) ? null : (AttrImpl) defaults.nodes.elementAt(0);
while (n < nsize && d < dsize) {
nnode = (AttrImpl) nodes.elementAt(n);
dnode = (AttrImpl) defaults.nodes.elementAt(d);
if (DEBUG) {
System.out.println("\n\nnnode="+nnode.getNodeName());
System.out.println("dnode="+dnode.getNodeName());
}
int test = nnode.getNodeName().compareTo(dnode.getNodeName());
//REVIST: EACH CONDITION - HOW IT RESPONDS TO DUPLICATE KEYS!
// Same name and a default -- make sure same value
if (test == 0) {
if (!nnode.getSpecified()) {
if (DEBUG) System.out.println("reconcile (test==0, specified = false): clone default");
NodeImpl clone = (NodeImpl)dnode.cloneNode(true);
clone.ownerNode = ownerNode;
clone.owned(true);
nodes.setElementAt(clone, n);
// Advance over both, since names in sync
++n;
++d;
}
else { //REVIST: if same name, but specified, simply increment over it.
if (DEBUG)
System.out.println("reconcile (test==0, specified=true): just increment");
++n;
++d;
}
}
// Different name, new default in table; add it
else if (test > 0) {
if (DEBUG) System.out.println("reconcile (test>0): insert new default");
NodeImpl clone = (NodeImpl)dnode.cloneNode(true);
clone.ownerNode = ownerNode;
clone.owned(true);
nodes.insertElementAt(clone, n);
// Now in sync, so advance over both
++n;
++d;
}
// Different name, old default here; remove it.
else if (!nnode.getSpecified()) {
if (DEBUG) System.out.println("reconcile(!specified): remove old default:"
+nnode.getNodeName());
// NOTE: We don't need to null out the parent
// because this is a node that we're
// throwing away (not returning). -Ac
// REVISIT: [Q] Should we null it out anyway? -Ac
nodes.removeElementAt(n);
// n didn't advance but represents a different element
}
// Different name, specified; accept it
else {
if (DEBUG) System.out.println("reconcile: Different name else accept it.");
++n;
}
}
// If we ran out of local before default, pick up defaults
if (d < dsize) {
if (nodes == null) nodes = new Vector();
while (d < dsize) {
dnode = (AttrImpl)defaults.nodes.elementAt(d++);
NodeImpl clone = (NodeImpl)dnode.cloneNode(true);
clone.ownerNode = ownerNode;
clone.owned(true);
if (DEBUG) System.out.println("reconcile: adding"+clone);
nodes.addElement(clone);
}
}
changed(false);
}
} // reconcileDefaults()
**/
} // class AttributeMap