[ 
https://issues.apache.org/jira/browse/XERCESJ-1429?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13055093#comment-13055093
 ] 

Thiwanka Somasiri commented on XERCESJ-1429:
--------------------------------------------

Hi Michael and Devs,

     I have posted the AsynchronousParser's latest version here.

     I have few things to clarify:
     
     LoadEvent listeners should be triggered as the parser.parse() is executed 
and that can be done by extracting the listeners from the Hashtable by using 
the relevant type(LS_LOAD_EVENT). But progress event should be triggered in the 
middle of the parsing process. W3C specification has left it 
implementation-dependent. I want to know ideas of you regarding this scenario.


public class AsynchronousDOMParserImpl extends DOMParserImpl implements 
EventTarget{
    
    private Hashtable eventListeners;
    private DOMParserImpl parser;
    private volatile boolean fBusy = false;//TODO make this volatile to avoid 
other threads using the async parser when busy
    
    //Call the super class constructors - there are four constructors in the 
DOMParserImpl class
    
    public AsynchronousDOMParserImpl(String configuration, String schemaType){
        super(configuration, schemaType);
        parser = new DOMParserImpl(configuration, schemaType);
    }
    
    public AsynchronousDOMParserImpl(XMLParserConfiguration config){
        super(config);
        parser = new DOMParserImpl(config);
    }
    
    public AsynchronousDOMParserImpl(SymbolTable symbolTable){
        super(symbolTable);
        parser = new DOMParserImpl(symbolTable);
    }
    
    public AsynchronousDOMParserImpl(SymbolTable symbolTable, XMLGrammarPool 
grammarPool){
        super(symbolTable, grammarPool);
        parser = new DOMParserImpl(symbolTable, grammarPool);
    }
    
    public void addEventListener(String type, EventListener listener, boolean 
useCapture){
        
        if (type == null || type.length() == 0 || listener == null)
            return;
        
        //Remove the previous entry for the same EventListener
        removeEventListener(type, listener, useCapture);
        
        Vector listeners = getEventListeners(type);        
        if(listeners  == null) {
            listeners  = new Vector();
            setEventListeners(type, listeners);
        }
        
        listeners .addElement(new ListenerHolder(listener, useCapture));
        
        //TODO Initiate capture and bubbling stuff
        
    }
    
    private Vector getEventListeners(String type){
        if (eventListeners == null) {
            return null;
        }
        return (Vector) eventListeners.get(type);
    }
    
    private void setEventListeners(String type, Vector listeners){
        if (eventListeners == null) {
            eventListeners = new Hashtable();
        }             
        if(listeners == null){
            eventListeners.remove(type);
        }else{
            eventListeners.put(type, listeners);
        }                        
    }
    
    public void removeEventListener(String type, EventListener listener, 
boolean useCapture){
        if (type == null || type.length() == 0 || listener == null)
            return;
        
        //If the vector is null for a particular type it will return
        Vector listeners = getEventListeners(type);
        if (listeners == null)
            return;
        
        //If the vector is not null, compare the listener and useCapture and 
remove the listener
        for(int i = 0; i < listeners.size(); i++){
            ListenerHolder lh = (ListenerHolder) listeners.get(i);
            if(lh.useCapture == useCapture && lh.el == listener){
                listeners.removeElementAt(i);
                //TODO assign null value in to hashtable when the vector is 
empty
                if(listeners.size()==0){
                    setEventListeners(type, null);
                }
                
              //TODO Initiate capture and bubbling stuff
                
                break;
            }
        }                        
    }
    
    public boolean dispatchEvent(Event evt){
        return false;//TODO change the return value
    }
    
    public Document parse(LSInput is){        
        final LSInput ls = is;
        setBusyFlag();         
        
  /*      if(eventListeners != null){
            final Hashtable eventListenersClone = (Hashtable) 
eventListeners.clone();
        }                    
  */      
        
        Runnable target = new Runnable() {
            
            @Override
            public void run() {
                try{
                    Document documentParsed = parser.parse(ls);
                    //TODO Invoke the listeners who were waiting for the events 
                   
                    if(eventListeners != null){
                        Hashtable eventListenersClone = (Hashtable) 
eventListeners.clone();
                        //Extract the listeners who were waiting for the load 
event and call the handleEvent() - after parsing occurs
                        Vector loadEventListeners = 
(Vector)eventListenersClone.get("LS_LOAD_EVENT"); //Change the String 'type'    
                    
                        if(loadEventListeners != null){
                            Iterator iterator = loadEventListeners.iterator();
                            
                            while(iterator.hasNext()){                          
      
                                EventListener el = (EventListener) 
iterator.next();                               

                                //Just for testing
                                LoadEventImpl lei = new 
LoadEventImpl(documentParsed, ls);                                              
                 
                                
                                el.handleEvent(lei);
                            }
                        }
                    }                                        
                }finally{
                    resetBusyFlag();
                }                
            }
        };                      
        
        Thread t = new Thread(target);
        t.start();  
        
        return null;        
    }
    
    public void setBusyFlag(){        
        if(fBusy == false){
            fBusy = true;
        }else{
            //Check what is the domain for the first argument
            String msg = 
DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, 
"INVALID_STATE_ERR", null);
            throw new DOMException(DOMException.INVALID_STATE_ERR, msg); 
        }        
    }    
    
    public void resetBusyFlag () {
        fBusy = false;
    }
    
    public boolean getBusy () {
        return fBusy;
    }       
    
    /**
     *  return true always as it is asynchronous
     *  */    
    public boolean getAsync () {
        return true;
    }
        
    //This struct holds the EventListner associated with the string types
    class ListenerHolder{
                
        EventListener el;
        boolean useCapture;
        
        ListenerHolder(EventListener el, boolean useCapture) {
            this.el = el;
            this.useCapture = useCapture;            
        }
    }       
}

> [GSoC]: Asynchronous LSParser and parseWithContext
> --------------------------------------------------
>
>                 Key: XERCESJ-1429
>                 URL: https://issues.apache.org/jira/browse/XERCESJ-1429
>             Project: Xerces2-J
>          Issue Type: New Feature
>          Components: DOM (Level 3 Load & Save)
>    Affects Versions: 2.9.1
>            Reporter: Michael Glavassevich
>              Labels: gsoc2011
>
> The goal of this project is to complete the implementation of the DOM Level 3 
> LSParser. Though Xerces has a functional LSParser, there are a couple parts 
> of the spec which still need to be implemented. This includes an asynchronous 
> [1] version which returns from the parse method immediately and builds the 
> DOM tree on another thread as well as parseWithContext [2] which allows a 
> document fragment to be parsed and attached to an existing DOM.
> Possible Mentors: Michael Glavassevich
> [1] 
> http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSParser
> [2] 
> http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/load-save.html#LS-LSParser-parseWithContext

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to