hillion     01/09/12 01:54:33

  Modified:    sources/org/apache/batik/dom AbstractDocument.java
                        AbstractElement.java AbstractParentNode.java
  Log:
  The NodeList objects returned by getElementsByTagName* are now live objects.
  
  Revision  Changes    Path
  1.9       +39 -30    xml-batik/sources/org/apache/batik/dom/AbstractDocument.java
  
  Index: AbstractDocument.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/dom/AbstractDocument.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AbstractDocument.java     2001/07/31 13:00:49     1.8
  +++ AbstractDocument.java     2001/09/12 08:54:33     1.9
  @@ -16,9 +16,11 @@
   
   import java.util.Locale;
   import java.util.MissingResourceException;
  +import java.util.WeakHashMap;
   
   import org.apache.batik.dom.events.DocumentEventSupport;
   import org.apache.batik.dom.traversal.TraversalSupport;
  +import org.apache.batik.dom.util.SoftDoublyIndexedTable;
   import org.apache.batik.i18n.Localizable;
   import org.apache.batik.i18n.LocalizableSupport;
   
  @@ -42,7 +44,7 @@
    * This class implements the {@link org.w3c.dom.Document} interface.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Stephane Hillion</a>
  - * @version $Id: AbstractDocument.java,v 1.8 2001/07/31 13:00:49 hillion Exp $
  + * @version $Id: AbstractDocument.java,v 1.9 2001/09/12 08:54:33 hillion Exp $
    */
   public abstract class AbstractDocument
       extends    AbstractParentNode
  @@ -84,6 +86,11 @@
       protected transient boolean eventsEnabled;
   
       /**
  +     * The ElementsByTagName lists.
  +     */
  +    protected transient WeakHashMap elementsByTagNames;
  +
  +    /**
        * Creates a new document.
        */
       protected AbstractDocument() {
  @@ -194,20 +201,6 @@
   
       /**
        * <b>DOM</b>: Implements {@link
  -     * org.w3c.dom.Document#getElementsByTagName(String)}.
  -     */
  -    public NodeList getElementsByTagName(String tagname) {
  -     Element e = getDocumentElement();
  -     if (e == null) {
  -         return EMPTY_NODE_LIST;
  -     }
  -     Nodes result = new Nodes();
  -     getElementsByTagName(e, tagname, result);
  -     return result;
  -    }
  -
  -    /**
  -     * <b>DOM</b>: Implements {@link
        * org.w3c.dom.Document#importNode(Node,boolean)}.
        */
       public Node importNode(Node importedNode, boolean deep)
  @@ -285,21 +278,6 @@
       }
   
       /**
  -     * <b>DOM</b>: Implements {@link
  -     * org.w3c.dom.Document#getElementsByTagNameNS(String,String)}.
  -     */
  -    public NodeList getElementsByTagNameNS(String namespaceURI,
  -                                           String localName) {
  -     Element e = getDocumentElement();
  -     if (e == null) {
  -         return EMPTY_NODE_LIST;
  -     }
  -     Nodes result = new Nodes();
  -     getElementsByTagNameNS(e, namespaceURI, localName, result);
  -     return result;
  -    }
  -
  -    /**
        * <b>DOM</b>: Implements {@link org.w3c.dom.Node#cloneNode(boolean)}.
        */
       public Node cloneNode(boolean deep) {
  @@ -313,6 +291,37 @@
               }
           }
           return n;
  +    }
  +
  +    /**
  +     * Returns an ElementsByTagName object from the cache, if any.
  +     */
  +    public ElementsByTagName getElementsByTagName(Node n, String ns, String ln) {
  +        if (elementsByTagNames == null) {
  +            return null;
  +        }
  +        SoftDoublyIndexedTable t;
  +        t = (SoftDoublyIndexedTable)elementsByTagNames.get(n);
  +        if (t == null) {
  +            return null;
  +        }
  +        return (ElementsByTagName)t.get(ns, ln);
  +    }
  +
  +    /**
  +     * Puts an ElementsByTagName object in the cache.
  +     */
  +    public void putElementsByTagName(Node n, String ns, String ln,
  +                                     ElementsByTagName l) {
  +        if (elementsByTagNames == null) {
  +            elementsByTagNames = new WeakHashMap(11);
  +        }
  +        SoftDoublyIndexedTable t;
  +        t = (SoftDoublyIndexedTable)elementsByTagNames.get(n);
  +        if (t == null) {
  +            elementsByTagNames.put(n, t = new SoftDoublyIndexedTable());
  +        }
  +        t.put(ns, ln, l);
       }
   
       // DocumentEvent /////////////////////////////////////////////////////////
  
  
  
  1.10      +44 -31    xml-batik/sources/org/apache/batik/dom/AbstractElement.java
  
  Index: AbstractElement.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/dom/AbstractElement.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- AbstractElement.java      2001/05/18 06:20:44     1.9
  +++ AbstractElement.java      2001/09/12 08:54:33     1.10
  @@ -29,7 +29,7 @@
    * This class implements the {@link org.w3c.dom.Element} interface.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Stephane Hillion</a>
  - * @version $Id: AbstractElement.java,v 1.9 2001/05/18 06:20:44 hillion Exp $
  + * @version $Id: AbstractElement.java,v 1.10 2001/09/12 08:54:33 hillion Exp $
    */
   public abstract class AbstractElement
       extends    AbstractParentChildNode
  @@ -180,23 +180,6 @@
       }
   
       /**
  -     * <b>DOM</b>: Implements {@link
  -     * org.w3c.dom.Element#getElementsByTagName(String)}.
  -     */
  -    public NodeList getElementsByTagName(String name) {
  -     Node n = getFirstChild();
  -     if (n == null || name == null) {
  -         return EMPTY_NODE_LIST;
  -     }
  -     Nodes result = new Nodes();
  -        while (n != null) {
  -            getElementsByTagName(n, name, result);
  -            n = n.getNextSibling();
  -        }
  -     return result;
  -    }
  -
  -    /**
        * <b>DOM</b>: Implements {@link org.w3c.dom.Node#normalize()}.
        */
       public void normalize() {
  @@ -287,21 +270,51 @@
       }
   
       /**
  -     * <b>DOM</b>: Implements {@link
  -     * org.w3c.dom.Element#getElementsByTagNameNS(String,String)}.
  +     * Called when a child node has been added.
  +     */
  +    protected void nodeAdded(Node node) {
  +        invalidateElementsByTagName(node);
  +    }
  +
  +    /**
  +     * Called when a child node is going to be removed.
  +     */
  +    protected void nodeToBeRemoved(Node node) {
  +        invalidateElementsByTagName(node);
  +    }
  +
  +    /**
  +     * Invalidates the ElementsByTagName objects of this node and its parents.
        */
  -    public NodeList getElementsByTagNameNS(String namespaceURI,
  -                                           String localName) {
  -     Node n = getFirstChild();
  -     if (n == null || localName == null) {
  -         return EMPTY_NODE_LIST;
  -     }
  -     Nodes result = new Nodes();
  -        while (n != null) {
  -            getElementsByTagNameNS(n, namespaceURI, localName, result);
  -            n = n.getNextSibling();
  +    private void invalidateElementsByTagName(Node node) {
  +        if (node.getNodeType() != ELEMENT_NODE) {
  +            return;
  +        }
  +        AbstractDocument ad = getCurrentDocument();
  +        String ns = node.getNamespaceURI();
  +        String ln = (ns == null) ? node.getNodeName() : node.getLocalName();
  +        for (Node n = this; n != null; n = n.getParentNode()) {
  +            switch (n.getNodeType()) {
  +            case ELEMENT_NODE:
  +            case DOCUMENT_NODE:
  +                ElementsByTagName l = ad.getElementsByTagName(n, ns, ln);
  +                if (l != null) {
  +                    l.invalidate();
  +                }
  +                l = ad.getElementsByTagName(n, "*", ln);
  +                if (l != null) {
  +                    l.invalidate();
  +                }
  +                l = ad.getElementsByTagName(n, ns, "*");
  +                if (l != null) {
  +                    l.invalidate();
  +                }
  +                l = ad.getElementsByTagName(n, "*", "*");
  +                if (l != null) {
  +                    l.invalidate();
  +                }
  +            }
           }
  -     return result;
       }
   
       /**
  
  
  
  1.10      +122 -52   xml-batik/sources/org/apache/batik/dom/AbstractParentNode.java
  
  Index: AbstractParentNode.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/dom/AbstractParentNode.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- AbstractParentNode.java   2001/08/03 04:27:23     1.9
  +++ AbstractParentNode.java   2001/09/12 08:54:33     1.10
  @@ -24,7 +24,7 @@
    * This class implements the Node interface with support for children.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Stephane Hillion</a>
  - * @version $Id: AbstractParentNode.java,v 1.9 2001/08/03 04:27:23 bella Exp $
  + * @version $Id: AbstractParentNode.java,v 1.10 2001/09/12 08:54:33 hillion Exp $
    */
   
   public abstract class AbstractParentNode extends AbstractNode {
  @@ -92,6 +92,8 @@
                                               (ExtendedNode)refChild);
            n.setParentNode(this);
   
  +            nodeAdded(n);
  +
            // Mutation event
            fireDOMNodeInsertedEvent(n);
            fireDOMSubtreeModifiedEvent();
  @@ -131,6 +133,7 @@
            fireDOMNodeRemovedEvent(oldChild);
   
               getCurrentDocument().nodeToBeRemoved(oldChild);
  +            nodeToBeRemoved(oldChild);
   
            // Node modification
            ExtendedNode n = (ExtendedNode)newChild;
  @@ -138,6 +141,8 @@
            n.setParentNode(this);
            o.setParentNode(null);
   
  +            nodeAdded(n);
  +
            // Mutation event
            fireDOMNodeInsertedEvent(n);
            fireDOMSubtreeModifiedEvent();
  @@ -167,6 +172,7 @@
        fireDOMNodeRemovedEvent(oldChild);
   
           getCurrentDocument().nodeToBeRemoved(oldChild);
  +        nodeToBeRemoved(oldChild);
   
        // Node modification
        ExtendedNode result = childNodes.remove((ExtendedNode)oldChild);
  @@ -199,6 +205,8 @@
            ExtendedNode n = childNodes.append((ExtendedNode)newChild);
            n.setParentNode(this);
   
  +            nodeAdded(n);
  +
            // Mutation event
            fireDOMNodeInsertedEvent(n);
            fireDOMSubtreeModifiedEvent();
  @@ -240,6 +248,42 @@
       }
   
       /**
  +     * <b>DOM</b>: Implements {@link
  +     * org.w3c.dom.Element#getElementsByTagName(String)}.
  +     */
  +    public NodeList getElementsByTagName(String name) {
  +     if (name == null) {
  +         return EMPTY_NODE_LIST;
  +     }
  +        AbstractDocument ad = getCurrentDocument();
  +        ElementsByTagName result = ad.getElementsByTagName(this, null, name);
  +        if (result == null) {
  +            result = new ElementsByTagName(null, name);
  +            ad.putElementsByTagName(this, null, name, result);
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * <b>DOM</b>: Implements {@link
  +     * org.w3c.dom.Element#getElementsByTagNameNS(String,String)}.
  +     */
  +    public NodeList getElementsByTagNameNS(String namespaceURI,
  +                                           String localName) {
  +     if (localName == null) {
  +         return EMPTY_NODE_LIST;
  +     }
  +        AbstractDocument ad = getCurrentDocument();
  +        ElementsByTagName result = ad.getElementsByTagName(this, namespaceURI,
  +                                                           localName);
  +        if (result == null) {
  +            result = new ElementsByTagName(namespaceURI, localName);
  +            ad.putElementsByTagName(this, namespaceURI, localName, result);
  +        }
  +        return result;
  +    }
  +
  +    /**
        * Recursively fires a DOMNodeInsertedIntoDocument event.
        */
       public void fireDOMNodeInsertedIntoDocumentEvent() {
  @@ -265,57 +309,16 @@
        }
       }
   
  -    /**
  -     * An auxiliary method of getElementsByTagName.
  -     */
  -    protected static void getElementsByTagName(Node node, String name,
  -                                               Nodes list) {
  -     if (node.getNodeType() == ELEMENT_NODE) {
  -         if (name.equals("*") || name.equals(node.getNodeName())) {
  -             list.append(node);
  -         }
  -     }
  -     for (Node n = node.getFirstChild();
  -             n != null;
  -             n = n.getNextSibling()) {
  -         getElementsByTagName(n, name, list);
  -     }
  -    }
  -
       /**
  -     * An auxiliary method for getElementsByTagNameNS.
  +     * Called when a child node has been added.
        */
  -    protected static void getElementsByTagNameNS(Node   node,
  -                                              String ns,
  -                                              String name,
  -                                              Nodes  list) {
  -     if (node.getNodeType() == ELEMENT_NODE) {
  -         if (stringMatches(ns, node.getNamespaceURI()) &&
  -             (name.equals("*") || name.equals(node.getLocalName()))) {
  -             list.append(node);
  -         }
  -     }
  -     for (Node n = node.getFirstChild();
  -             n != null;
  -             n = n.getNextSibling()) {
  -         getElementsByTagNameNS(n, ns, name, list);
  -     }
  +    protected void nodeAdded(Node n) {
       }
   
       /**
  -     * String matching for getElementsByTagNameNS function.
  +     * Called when a child node is going to be removed.
        */
  -    private static boolean stringMatches(String s1, String s2) {
  -     if (s1 == null && s2 == null) {
  -         return true;
  -     }
  -     if (s1 == null || s2 == null) {
  -         return false;
  -     }
  -     if (s1.equals("*")) {
  -         return true;
  -     }
  -     return s1.equals(s2);
  +    protected void nodeToBeRemoved(Node n) {
       }
   
       /**
  @@ -445,7 +448,8 @@
       /**
        * To manage a list of nodes.
        */
  -    protected static class Nodes implements NodeList {
  +    protected class ElementsByTagName implements NodeList {
  +
        /**
         * The table.
         */
  @@ -454,18 +458,33 @@
        /**
         * The number of nodes.
         */
  -     protected int size;
  +     protected int size = -1;
   
  +        /**
  +         * The namespace URI identifier.
  +         */
  +        protected String namespaceURI;
  +
  +        /**
  +         * The local name identifier.
  +         */
  +        protected String localName;
  +
        /**
         * Creates a new Nodes object.
         */
  -     public Nodes() {
  +     public ElementsByTagName(String ns, String ln) {
  +            namespaceURI = ns;
  +            localName = ln;
        }
   
        /**
  -      * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#item(int)}.
  +      * <b>DOM</b>: Implements {@link NodeList#item(int)}.
         */
        public Node item(int index) {
  +            if (size == -1) {
  +                initialize();
  +            }
            if (table == null || index < 0 || index > size) {
                return null;
            }
  @@ -473,17 +492,27 @@
        }
   
        /**
  -      * <b>DOM</b>: Implements {@link org.w3c.dom.NodeList#getLength()}.
  +      * <b>DOM</b>: Implements {@link NodeList#getLength()}.
         * @return {@link #size}.
         */
        public int getLength() {
  +            if (size == -1) {
  +                initialize();
  +            }
            return size;
        }
   
  +        /**
  +         * Invalidates the list.
  +         */
  +        public void invalidate() {
  +            size = -1;
  +        }
  +
        /**
         * Appends a node to the list.
         */
  -     public void append(Node n) {
  +     protected void append(Node n) {
            if (table == null) {
                table = new Node[11];
            } else if (size == table.length - 1) {
  @@ -495,6 +524,47 @@
            }
            table[size++] = n;
        }
  +
  +        /**
  +         * Initializes the list.
  +         */
  +        protected void initialize() {
  +            size = 0;
  +            for (Node n = AbstractParentNode.this.getFirstChild();
  +                 n != null;
  +                 n = n.getNextSibling()) {
  +                initialize(n);
  +            }
  +        }
  +
  +        private void initialize(Node node) {
  +            if (node.getNodeType() == ELEMENT_NODE) {
  +                String ns = node.getNamespaceURI();
  +                String nm = (ns == null) ? node.getNodeName() : node.getLocalName();
  +                if (nsMatch(namespaceURI, node.getNamespaceURI()) &&
  +                    (localName.equals("*") || localName.equals(nm))) {
  +                    append(node);
  +                }
  +            }
  +            for (Node n = node.getFirstChild();
  +                 n != null;
  +                 n = n.getNextSibling()) {
  +                initialize(n);
  +            }
  +        } 
  +
  +        private boolean nsMatch(String s1, String s2) {
  +            if (s1 == null && s2 == null) {
  +                return true;
  +            }
  +            if (s1 == null || s2 == null) {
  +                return false;
  +            }
  +            if (s1.equals("*")) {
  +                return true;
  +            }
  +            return s1.equals(s2);
  +        }
       }
   
       /**
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to