Author: nbelaevski
Date: 2008-11-07 18:44:42 -0500 (Fri, 07 Nov 2008)
New Revision: 11059
Modified:
trunk/framework/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js
trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js
Log:
Queue: discovery services & renderer implemented in draft
Modified:
trunk/framework/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java
===================================================================
---
trunk/framework/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2008-11-07
17:06:13 UTC (rev 11058)
+++
trunk/framework/impl/src/main/java/org/ajax4jsf/renderkit/AjaxRendererUtils.java 2008-11-07
23:44:42 UTC (rev 11059)
@@ -239,7 +239,7 @@
parameters.put(controlName, controlValue);
AjaxContext ajaxContext = AjaxContext.getCurrentInstance(facesContext);
// Setup action URL. For portlet environment, it will be different from
- // page.
+ // page.
options.put("actionUrl", ajaxContext.getAjaxActionURL(facesContext));
// Add application-wide Ajax parameters
parameters.putAll(ajaxContext.getCommonAjaxParameters());
@@ -321,21 +321,29 @@
.get(AJAX_DELAY_ATTR);
if (null != requestDelay && requestDelay.intValue() > 0) {
options.put(AJAX_DELAY_ATTR, requestDelay);
- if (null == queue) {
- queue = clientId;
- }
+// if (null == queue) {
+// queue = clientId;
+// }
}
Boolean ignoreDupResponses = (Boolean) componentAttributes
.get(AJAX_ABORT_ATTR);
if (null != ignoreDupResponses && ignoreDupResponses.booleanValue()) {
options.put(AJAX_ABORT_ATTR, JSReference.TRUE);
- if (null == queue) {
- queue = clientId;
- }
+// if (null == queue) {
+// queue = clientId;
+// }
}
if (null != queue) {
options.put(AJAX_QUEUE_ATTR, queue);
}
+
+ String namespace = facesContext.getExternalContext().encodeNamespace("");
+ if (namespace != null && namespace.length() != 0) {
+ options.put("namespace", namespace);
+ }
+
+ options.put("requestId", clientId);
+
// request timeout.
Integer timeout = (Integer) componentAttributes.get("timeout");
if (null != timeout && timeout.intValue() > 0) {
Modified: trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js
===================================================================
--- trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js 2008-11-07 17:06:13 UTC
(rev 11058)
+++ trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js 2008-11-07 23:44:42 UTC
(rev 11059)
@@ -15,6 +15,7 @@
*/
A4J.AJAX.XMLHttpRequest = function(query){
this._query = query;
+
// Store document element, to check page replacement.
this._documentElement = window.document.documentElement;
};
@@ -602,7 +603,7 @@
// Onsubmit disable current poll, start next interval.
A4J.AJAX.Poll(containerId,form,options);
} else {
- A4J.AJAX.SubmitRequest(containerId,form,null,options);
+ A4J.AJAX.Submit(containerId,form,null,options);
}
},options.pollinterval);
};
@@ -631,7 +632,7 @@
try {
if(request.status == 200){
if(request.getResponseHeader("Ajax-Push-Status")=="READY"){
- A4J.AJAX.SubmitRequest(containerId,form||options.dummyForm,null,options);
+ A4J.AJAX.Submit(containerId,form||options.dummyForm,null,options);
}
}
} catch(e){
@@ -691,9 +692,14 @@
A4J.AJAX.Submit(containerId,form,null,opt);
}
-// Submit or put in queue request. It not full queues - framework perform waiting only
one request to same queue, new events simple replace last.
-// If request for same queue already performed, replace with current parameters.
-A4J.AJAX.Submit = function( containerId, form, evt , options ) {
+/**
+ * This method should be deprecated and maybe even removed?
+ */
+A4J.AJAX.SubmiteventsQueue = function( eventsQueue ) {
+ eventsQueue.submit();
+};
+
+A4J.AJAX.PrepareQuery = function(containerId, formId, evt, options) {
var domEvt;
evt = evt || window.event || null;
if(evt){
@@ -705,30 +711,7 @@
}
LOG.debug("Have Event "+domEvt+" with properties: target:
"+domEvt.target+", srcElement: "+domEvt.srcElement+", type:
"+domEvt.type);
}
-
- var queue = A4J.AJAX.EventQueue.getOrCreateQueue(options.eventsQueue);
- if (queue) {
- queue.push(containerId, form, domEvt, options);
- } else {
- A4J.AJAX.SubmitRequest(containerId, form, domEvt, options);
- }
-};
-/**
- * This method should be deprecated and maybe even removed?
- */
-A4J.AJAX.SubmiteventsQueue = function( eventsQueue ) {
- eventsQueue.immediateSubmit();
-};
- // Main request submitting functions.
- // parameters :
- // form - HtmlForm object for submit.
- // control - form element, called request, or, clientID for JSF view.
- // affected - Array of ID's for DOM Objects, updated after request. Override
- // list of updated areas in response.
- // statusID - DOM id request status tags.
- // oncomplete - function for call after complete request.
-A4J.AJAX.SubmitRequest = function( containerId, formId ,domEvt , options ) {
// Process listeners.
for(var li = 0; li < A4J.AJAX._listeners.length; li++){
var listener = A4J.AJAX._listeners[li];
@@ -737,7 +720,7 @@
}
}
// First - run onsubmit event for client-side validation.
- LOG.debug("NEW AJAX REQUEST !!! with form :"+formId );
+ LOG.debug("Query preparation for form '" + formId + "'
requested");
// var form = A4J.AJAX.locateForm(event);
var form = window.document.getElementById(formId);
if( (!form || form.nodeName.toUpperCase() != "FORM") && domEvt ) {
@@ -753,7 +736,7 @@
return false;
};
};
- var tosend = new A4J.Query(containerId, form);
+ var tosend = new A4J.Query(containerId, form, domEvt);
tosend.appendFormControls(options.single, options.control);
//appending options.control moved to appendFormControls
//if(options.control){
@@ -762,19 +745,26 @@
if(options.parameters){
tosend.appendParameters(options.parameters);
};
- if(options.eventsCount){
- tosend.appendParameter("AJAX:EVENTS_COUNT",options.eventsCount);
- };
if(options.actionUrl){
tosend.setActionUrl(options.actionUrl);
};
- // build xxxHttpRequest. by Sarissa / JSHttpRequest class always defined.
- var req = new A4J.AJAX.XMLHttpRequest(tosend);
+
+ return tosend;
+};
+
+A4J.AJAX.SubmitQuery = function (query, options) {
+ // build xxxHttpRequest. by Sarissa / JSHttpRequest class always defined.
+ var req = new A4J.AJAX.XMLHttpRequest(query);
+ var form = query._form;
+ var containerId = query._containerId;
+ var domEvt = query._event;
+
req.options = options;
req.containerId = containerId;
req.domEvt = domEvt;
req.form = form;
+
if(options.timeout){
req.setRequestTimeout(options.timeout);
};
@@ -789,17 +779,49 @@
}
req.onfinish = A4J.AJAX.finishRequest;
- A4J.AJAX.status(containerId,options.status,true);
+ LOG.debug("NEW AJAX REQUEST !!! with form: " + (form.id || form.name ||
form));
+
+ A4J.AJAX.status(containerId,options.status,true);
req.send();
- var queue = A4J.AJAX.EventQueue.getQueue(options.eventsQueue);
- if (queue) {
- queue.request = req;
- }
-
+ return req;
+};
+
+//Submit or put in queue request. It not full queues - framework perform waiting only one
request to same queue, new events simple replace last.
+//If request for same queue already performed, replace with current parameters.
+A4J.AJAX.Submit = function( containerId, formId, event , options ) {
+ var query = A4J.AJAX.PrepareQuery(containerId, formId, event, options);
+ if (query) {
+ var queue = A4J.AJAX.EventQueue.getOrCreateQueue(options.eventsQueue,
options.requestId, options.namespace, formId);
+
+ if (queue) {
+ queue.push(query, options);
+ } else {
+ A4J.AJAX.SubmitQuery(query, options);
+ }
+ }
+
return false;
- };
+};
+
+ // Main request submitting functions.
+ // parameters :
+ // form - HtmlForm object for submit.
+ // control - form element, called request, or, clientID for JSF view.
+ // affected - Array of ID's for DOM Objects, updated after request. Override
+ // list of updated areas in response.
+ // statusID - DOM id request status tags.
+ // oncomplete - function for call after complete request.
+A4J.AJAX.SubmitRequest = function( containerId, formId, event, options ) {
+ var query = A4J.AJAX.PrepareQuery(containerId, formId, event, options);
+ if (query) {
+ A4J.AJAX.SubmitQuery(query, options);
+ }
+
+ return false;
+};
+
A4J.AJAX.processResponseAfterUpdateHeadElements = function (req, ids)
{
for ( var k =0; k < ids.length ; k++ ) {
@@ -1076,9 +1098,8 @@
A4J.AJAX.status(request.containerId,options.status,false);
}
- var queue = A4J.AJAX.EventQueue.getQueue(options.eventsQueue);
- if (queue) {
- queue.pop();
+ if (request.queue) {
+ request.queue.pop();
}
};
@@ -1160,11 +1181,13 @@
// Class for build query string.
-A4J.Query = function(containerId,form){
+A4J.Query = function(containerId, form, event){
// For detect AJAX Request.
this._query = {AJAXREQUEST : containerId};
this._oldSubmit = null ;
- this._form = form ;
+ this._form = form;
+ this._containerId = containerId;
+ this._event = event;
this._actionUrl = ( this._form.action)?this._form.action:this._form;
};
Modified: trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js
===================================================================
--- trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js 2008-11-07 17:06:13 UTC (rev
11058)
+++ trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js 2008-11-07 23:44:42 UTC (rev
11059)
@@ -1,12 +1,13 @@
+//TODO observe unload
+//unload
+
A4J.AJAX._eventQueues = {};
//queue constructor
-A4J.AJAX.EventQueue = function(name, size) {
- LOG.debug("Creating new queue " + name + " with settings: [size= " +
size + "]");
-
- this.eventCounter = 0;
+A4J.AJAX.EventQueue = function(name, options) {
this.name = name;
- this.size = size || 1;
+ this.options = options;
+
this.queue = new Array();
};
@@ -18,159 +19,188 @@
if (A4J.AJAX._eventQueues[name]) {
throw "Queue already registered";
} else {
+ LOG.debug("Adding queue '" + name + "' to queues
registry");
A4J.AJAX._eventQueues[name] = queue;
}
};
-A4J.AJAX.EventQueue.getQueue = function(name) {
- //uncomment to switch on global queue
- //name = name || A4J.AJAX.EventQueue.DEFAULT_QUEUE_NAME;
-
- return A4J.AJAX._eventQueues[name];
+A4J.AJAX.EventQueue.removeQueue = function(name) {
+ delete A4J.AJAX._eventQueues[name];
};
-A4J.AJAX.EventQueue.getOrCreateQueue = function(name) {
+//TODO A4J.AJAX.EventQueue.getQueue ?
+
+A4J.AJAX.EventQueue.getOrCreateQueue = function(queueName, requestId, namespace, formId)
{
//uncomment to switch on global queue
- //name = name || A4J.AJAX.EventQueue.DEFAULT_QUEUE_NAME;
+ var name = queueName || A4J.AJAX.EventQueue.DEFAULT_QUEUE_NAME;
- if (name) {
- var queue = A4J.AJAX._eventQueues[name];
- if (!queue) {
- LOG.debug("Creating new queue " + name + " with default
settings");
- queue = new A4J.AJAX.EventQueue(name);
- A4J.AJAX.EventQueue.addQueue(queue);
- }
+ var queue;
+ if (formId) {
+ queue = A4J.AJAX._eventQueues[formId + ":" + name];
+ }
+
+ if (!queue) {
+ queue = A4J.AJAX._eventQueues[namespace ? (namespace + ":" + name) : name];
+ }
+
+ if (!queue) {
+ name = queueName || requestId;
- return queue;
- }
+ LOG.debug("Creating new transient queue '" + name + "' with
default settings");
+ queue = new A4J.AJAX.EventQueue(name);
+ queue._transient = true;
+
+ A4J.AJAX.EventQueue.addQueue(queue);
+ }
+
+ return queue;
};
A4J.AJAX.EventQueue.prototype = function() {
- var replaceForDupResponse = function(event) {
- this.queue = new Array();
- this.queue.push(event);
+ var EventQueueData = function(queue) {
+ this.queue = queue;
+ this.eventsCount = 0;
};
+
+ EventQueueData.prototype.setEventData = function(query, options) {
+ this.query = query;
+ this.options = options;
+
+ this.eventsCount++;
+ };
+
+ EventQueueData.prototype.executeDelay = function(delay) {
+ LOG.debug("Queue will wait " + (delay || 0) + "ms before submit");
- var replaceForOversize = function(event) {
- this.queue.shift();
- this.queue.push(event);
+ if (delay) {
+ var _this = this;
+
+ this.timerId = setTimeout(function() {
+ try {
+ _this.delayPassed = true;
+ _this.queue.submit();
+ } finally {
+ _this = undefined;
+ }
+ }, delay);
+ } else {
+ this.delayPassed = true;
+ this.queue.submit();
+ }
};
+
+ EventQueueData.prototype.abortDelay = function() {
+ if (this.timerId) {
+ clearTimeout(this.timerId);
+ this.timerId = undefined;
+ }
+
+ this.delayPassed = false;
+ };
+
+ EventQueueData.prototype.submit = function() {
+ this.query.appendParameter("AJAX:EVENTS_COUNT", this.eventsCount);
+
+ return A4J.AJAX.SubmitQuery(this.query, this.options)
+ };
+
+ var extendOptions = function(options) {
+ var opts = {};
+
+ for (var name in options) {
+ opts[name] = options[name];
+ }
+
+ for (var name in this.options) {
+ if (!opts[name]) {
+ opts[name] = this.options[name];
+ }
+ }
+
+ return opts;
+ };
+
return {
//TODO separate service functions
- replace: function(event, policy) {
- if (this.request) {
- LOG.debug("Abort uncompleted request in queue " + this.name);
-
- this.request.abort();
- this.request = undefined;
+ submit: function() {
+ if (this.inactive) {
+ throw "Queue inactive";
+ }
- policy.call(this, event);
-
- if (this.queue.length == 1) {
- this.delayedSubmit();
+ if (!this.request) {
+ var queueData = this.queue.shift();
+ if (queueData) {
+ LOG.debug("Queue '" + this.name + "' will submit request
NOW");
+
+ if (this.queue.length == 0) {
+ LOG.debug("The last queue request is being submitted, resetting
requestId");
+ this._requestId = undefined;
+ }
+
+ this.request = queueData.submit();
+ this.request.queue = this;
} else {
- this.immediateSubmit();
+ LOG.debug("Queue '" + this.name + "' is empty, nothing to
submit");
}
} else {
- //there should be waiting request, let's wait for it
- policy.call(this, event);
+ LOG.debug("Request in queue '" + this.name + "' is active now,
wait until its completion");
}
- },
+ },
- push: function(containerId, form, evt, options) {
- var eventInfo = {containerId: containerId, form: form, domEvt: evt, options:
options};
+ push: function(query, opts) {
+ if (this.inactive) {
+ throw "Queue inactive";
+ }
+
+ var options = extendOptions.call(this, opts);
- this.eventCounter++;
+ //TODO add processing for ignoreDupResponse
+
+ var queueData;
+
+ var requestId = options.requestId;
+ var delay = options.requestDelay;
- if (this.queue.length == 0) {
- LOG.debug("New event added to empty queue " + this.name);
+ if (!this._requestId || requestId != this._requestId) {
+ queueData = new EventQueueData(this);
+
+ this.queue.push(queueData);
+ this._requestId = requestId;
- this.queue.push(eventInfo);
- this.delayedSubmit();
+ LOG.debug("New event added to queue '" + this.name + "'. Queue
requestId changed to " + requestId);
} else {
- if (options.ignoreDupResponses) {
- LOG.debug("Doing replace due to ignoreDupResponses event in queue " +
this.name);
+ queueData = this.queue[this.queue.length - 1];
+ queueData.abortDelay();
- this.replace(eventInfo, replaceForDupResponse);
- } else {
- //size != 0
- if (this.size == this.queue.length) {
- LOG.debug("Doing replace due to queue's " + this.name + "
oversize");
-
- this.replace(eventInfo, replaceForOversize);
- } else {
- LOG.debug("New event added to queue " + this.name);
-
- //there should be waiting request, let's wait for it
- this.queue.push(eventInfo);
- }
- }
+ LOG.debug("Similar request already in queue '" + this.name +
"'");
}
+
+ queueData.setEventData(query, options);
+ queueData.executeDelay(delay);
},
-
- immediateSubmit: function() {
- var packet = this.queue[0];
- if (packet) {
- if (!this.request) {
- //TODO externalize this?
- packet.options.eventsCount = this.eventCounter;
- A4J.AJAX.SubmitRequest(packet.containerId, packet.form, packet.domEvt,
packet.options);
-
- if (!this.request) {
- //ajax submission stopped by onsubmit form handler
- this.pop();
- }
- } else {
- LOG.debug("Submit method called for queue " + this.name +
- " processing another request right now. Method call has been ignored");
- }
- } else {
- LOG.debug("Submit method called for empty queue " + this.name);
- }
- },
-
- delayedSubmit: function() {
- var packet = this.queue[0];
- if (packet) {
- var options = packet.options;
- if (options.requestDelay) {
- var _this = this;
-
- window.setTimeout(function() {
- try {
- LOG.debug("End delay waiting, make request in queue " + _this.name);
- _this.immediateSubmit();
- } finally {
- _this = undefined;
- }
- }, options.requestDelay);
-
- LOG.debug("Create new waiting for request in queue " + this.name);
- } else {
- LOG.debug("No request delay, submit " + this.name + " queue's
request just now");
-
- this.immediateSubmit();
- }
- }
- },
-
+
pop: function() {
this.request = undefined;
- this.queue.shift();
+
if (this.queue.length == 0) {
- LOG.debug("Queue " + this.name + " is empty now");
+ LOG.debug("After request: queue '" + this.name + "' is empty
now");
- this.eventCounter = 0;
+ if (this._transient) {
+ this.inactive = true;
+
+ LOG.debug("Deleting transient queue '" + this.name + "' from
queues registry");
+ A4J.AJAX.EventQueue.removeQueue(this.name);
+ }
} else {
- LOG.debug("Queue not empty, execute next request in queue " + this.name);
-
- this.eventCounter--;
- //TODO - check that counter is still greater than zero
- this.immediateSubmit();
+ LOG.debug("After request: queue not empty, processing next event in queue
'" + this.name + "'");
+ var queueData = this.queue[0];
+ if (queueData.delayPassed) {
+ this.submit();
+ }
}
}
}