The following comment has been added to this issue:

     Author: Lucian Holland
    Created: Tue, 4 May 2004 9:17 AM
       Body:
I have experienced a very similar issue, and I believe that the proposed patch does 
not solve the whole problem. 

In the sample code attached to this bug, the useCapture feature is being used, and the 
listeners are being registered on ancestors of the Node being inserted. In the 
dispatchEventToSubtree on DocumentImpl, there is an attempted optimisation that checks 
for listeners on the node that is to be the parent of the inserted node, and if none 
are found, it doesn't bother dispatching the event. The proposed patch recognises that 
this ignores the fact that listeners may be registered with useCapture=true higher up 
the tree, and these would be "optimised out" by the existing code.

However, the other side of this problem is that the DOMNodeInsertedIntoDocument event 
should fire for every node in the whole subtree of the node actually inserted. So as 
well as the change proposed in the patch we would also need something that checked the 
node being inserted and its whole subtree for listeners. I imagine that this would not 
be much of an "optimisation" any more!

Short of radically altering the way that the eventListeners structure is maintained in 
DocumentImpl to include awareness of subtrees and ancestors, I suggest that for the 
time being this optimisation is simply removed altogether so that the method at least 
works correctly. There is already a comment pointing out that it needs to be revisited 
and optimised anyway.

I will attach a patch to this effect.
---------------------------------------------------------------------
View this comment:
  http://issues.apache.org/jira/browse/XERCESJ-941?page=comments#action_35391

---------------------------------------------------------------------
View the issue:
  http://issues.apache.org/jira/browse/XERCESJ-941

Here is an overview of the issue:
---------------------------------------------------------------------
        Key: XERCESJ-941
    Summary: DOM Events Module: event notification of "indirect" insertions
       Type: Bug

     Status: Open

    Project: Xerces2-J
 Components: 
             DOM
   Versions:
             2.6.2

   Assignee: Xerces-J Developers Mailing List
   Reporter: Martin Bernauer

    Created: Tue, 6 Apr 2004 7:59 AM
    Updated: Tue, 4 May 2004 9:17 AM
Environment: Operating System: Windows XP
Platform: PC

Description:
When inserting a subtree, e.g., <b><c>444</c></b> as child of document element
<a>, and registering an event listener for event type
DOMNodeInsertedIntoDocument, one would expect the DOM implementation to report
the insertions of element b, element c, and the text node containing 444.

In my above defined environment, this only happens if the event listener is
registered on the document element. When registered on the document itself, the
indirect insertions of element c and text node containing 444 are not reported.

I have enclosed a sample application and its ouput below.

Regards,
Martin

---------- sample application ----------


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.events.MutationEvent;

public class DOMEventTest 
        implements EventListener
{
        /**
         * 
         * @param args
         * @throws Exception
         */
        public static void main(String[] args)
                throws Exception
        {
                DOMEventTest test = new DOMEventTest();
        }
        
        /**
         * 
         * @throws Exception
         */
        public DOMEventTest()
                throws Exception
        {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = factory.newDocumentBuilder();
                
                // Initialize document
                Document doc = builder.newDocument();
                doc.appendChild(doc.createElement("a"));
                
                // Alternative 1: register event listener on the document itself
                ((EventTarget) doc).addEventListener("DOMCharacterDataModified", this, 
true);
                ((EventTarget) doc).addEventListener("DOMNodeInserted", this, true);
                ((EventTarget) doc).addEventListener("DOMNodeInsertedIntoDocument", 
this, true);
                
                // Manipulate document
                manipulateDocument(doc);
                
                System.out.println("\n----------\n");
                
                // Initialize document
                doc = builder.newDocument();
                doc.appendChild(doc.createElement("a"));
                
                // Alternative 2: register event listener on the document element
                Element elt = doc.getDocumentElement(); 
                ((EventTarget) elt).addEventListener("DOMCharacterDataModified", this, 
true);
                ((EventTarget) elt).addEventListener("DOMNodeInserted", this, true);
                ((EventTarget) elt).addEventListener("DOMNodeInsertedIntoDocument", 
this, true);
                
                // Manipulate document
                manipulateDocument(doc);
                
                System.out.println("\n----------\n");
                
                OutputFormat format = new OutputFormat(doc);
                XMLSerializer output = new XMLSerializer(System.out, format);
                output.serialize(doc);
        }

        void manipulateDocument(Document doc)
        {
                Element elt = doc.getDocumentElement();
                /*
                elt.appendChild(doc.createTextNode("111"));
                Text txt = (Text) elt.appendChild(doc.createTextNode("222"));
                txt.setData("333");
                */
                
                elt = doc.createElement("b");
                
elt.appendChild(doc.createElement("c")).appendChild(doc.createTextNode("444"));
                doc.getDocumentElement().appendChild(elt);
        }

        /**
         * 
         */
        public void handleEvent(org.w3c.dom.events.Event inEvt)
        {
                if (!(inEvt instanceof MutationEvent))
                        return;
                MutationEvent evt = (MutationEvent) inEvt;
                
                StringBuffer res = new StringBuffer();
                res.append("[" + evt.getType() + "]\n");

                res.append("  prevValue:" + evt.getPrevValue() + "\n");
                res.append("  newValue:" + evt.getNewValue() + "\n");
                Node targetNode = (Node) evt.getTarget();
                if (targetNode != null)
                {
                        res.append("  targetNodeType:");
                        switch (targetNode.getNodeType())
                        {
                                case Node.ELEMENT_NODE: res.append("ELEMENT_NODE"); 
break;
                                case Node.ATTRIBUTE_NODE: 
res.append("ATTRIBUTE_NODE"); break;
                                case Node.TEXT_NODE: res.append("TEXT_NODE"); break;
                                default: res.append("##OTHER");
                        }
                        res.append("\n");
                        res.append("  targetNodeName:" + targetNode.getNodeName() + 
"\n");
                }
                Node relatedNode = evt.getRelatedNode();
                if (relatedNode != null)
                        res.append("  relatedNodeName:" + relatedNode.getNodeName() + 
"\n");

                System.out.print(res.toString());       
        }
}

---------- Output ----------

[DOMNodeInserted]
  prevValue:null
  newValue:null
  targetNodeType:ELEMENT_NODE
  targetNodeName:b
  relatedNodeName:a

----------

[DOMNodeInserted]
  prevValue:null
  newValue:null
  targetNodeType:ELEMENT_NODE
  targetNodeName:b
  relatedNodeName:a
[DOMNodeInsertedIntoDocument]
  prevValue:null
  newValue:null
  targetNodeType:ELEMENT_NODE
  targetNodeName:b
[DOMNodeInsertedIntoDocument]
  prevValue:null
  newValue:null
  targetNodeType:ELEMENT_NODE
  targetNodeName:c
[DOMNodeInsertedIntoDocument]
  prevValue:null
  newValue:null
  targetNodeType:TEXT_NODE
  targetNodeName:#text

----------

<?xml version="1.0" encoding="UTF-8"?>
<a><b><c>444</c></b></a>


---------------------------------------------------------------------
JIRA INFORMATION:
This message is automatically generated by JIRA.

If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa

If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


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

Reply via email to