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

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

Hi Michael,
     I have done some modifications to AsynchronousDOMParserImpl. Modifications 
were done mostly on progress events scenario. Can you give your feed back on 
the modifications?

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
    private XMLLocator locator;  
    private int nextCharOffset = 0;
    private Vector progressEventListeners;
    private LSInput input;
    private boolean callByParsingThread = false; 
    
    //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 void startDocument (XMLLocator locator, String 
encoding,NamespaceContext namespaceContext, Augmentations augs) throws 
XNIException {
        this.locator = locator;
        super.startDocument(locator, encoding, namespaceContext, augs);
    }
    
    public void startElement (QName element, XMLAttributes attributes, 
Augmentations augs) throws XNIException {
        if(locator.getCharacterOffset() == 0) {
            reportProgressEvents();
            nextCharOffset += 2048;            
        }else if(locator.getCharacterOffset() > nextCharOffset) {
            reportProgressEvents();
            nextCharOffset += 2048;            
        }
        
        //Call the AbstractDOMParser.startElement()
        super.startElement(element, attributes, augs);
    }
    
    public void reportProgressEvents(){
        //Invoke the progress event listeners
        if(eventListeners != null){
            Hashtable eventListenersClone = (Hashtable) eventListeners.clone();
            if(progressEventListeners == null){
                progressEventListeners = 
(Vector)eventListenersClone.get("progress");
            }else{
                Iterator iterator = progressEventListeners.iterator();
                while(iterator.hasNext()){                                
                    EventListener el = (EventListener) iterator.next();         
                      

                    ProgressEventImpl pei = new ProgressEventImpl(input, 
nextCharOffset, 0);                                                             
  
                    
                    el.handleEvent(pei);
                }
            }                           
        }        
    }
    
    /*private Document parseLSInput(LSInput is){
        return super.parse(is);
    }*/
    
    public Document parse(LSInput is){
        //final Object lock = new Object();
        if(!fBusy){
            setBusyFlag();
        }else if(callByParsingThread){
            super.parse(is);//What will happen if the user tries to call the 
parse() again?
        }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);
        }
        input = is;       
        final LSInput ls = is;
                           
        //Parsing thread
        Runnable parsingThread = new Runnable() {
            
            @Override
            public void run() {
                try{
                                       
                    //Document documentParsed = parser.parse(ls);
                    //Document documentParsed = asyncParser.parseLSInput(ls);
                    callByParsingThread = true;
                    Document documentParsed = parse(ls);
                    
                    //TODO Invoke the listeners who were waiting for the load 
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("load");                         
                        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 target = new Thread(parsingThread);                
        target.start();  
        
        return null;        
    }
    
    public void setBusyFlag(){        
        if(fBusy){
            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;            
        }
    }       
}

Thanks.

> [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
>            Assignee: Thiwanka Somasiri
>              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