[
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]