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