Author: nbelaevski
Date: 2008-11-24 14:33:30 -0500 (Mon, 24 Nov 2008)
New Revision: 11335
Added:
trunk/framework/impl/src/main/java/org/ajax4jsf/component/QueueRegistry.java
Modified:
trunk/framework/impl/src/main/java/org/ajax4jsf/context/ViewResources.java
trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js
trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js
Log:
https://jira.jboss.org/jira/browse/RF-4957
https://jira.jboss.org/jira/browse/RF-5049
Copied: trunk/framework/impl/src/main/java/org/ajax4jsf/component/QueueRegistry.java (from
rev 11304, trunk/ui/core/src/main/java/org/ajax4jsf/renderkit/html/QueueRegistry.java)
===================================================================
--- trunk/framework/impl/src/main/java/org/ajax4jsf/component/QueueRegistry.java
(rev 0)
+++
trunk/framework/impl/src/main/java/org/ajax4jsf/component/QueueRegistry.java 2008-11-24
19:33:30 UTC (rev 11335)
@@ -0,0 +1,64 @@
+/**
+ * License Agreement.
+ *
+ * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ *
+ * Copyright (C) 2007 Exadel, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+package org.ajax4jsf.component;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Nick Belaevski
+ * @since 3.3.0
+ */
+public class QueueRegistry {
+
+ private static final String REGISTRY_ATTRIBUTE_NAME = QueueRegistry.class.getName();
+
+ public static void registerQueue(FacesContext context, String clientName, Object data)
{
+ ExternalContext externalContext = context.getExternalContext();
+ Map<String, Object> requestMap = externalContext.getRequestMap();
+
+ Map<String, Object> registryMap = (Map<String, Object>)
+ requestMap.get(REGISTRY_ATTRIBUTE_NAME);
+
+ if (registryMap == null) {
+ registryMap = new LinkedHashMap<String, Object>();
+ requestMap.put(REGISTRY_ATTRIBUTE_NAME, registryMap);
+ }
+
+ if (!registryMap.containsKey(clientName)) {
+ registryMap.put(clientName, data);
+ } else {
+ context.getExternalContext().log("Queue with name '" + clientName +
"' has already been registered");
+ }
+ }
+
+ public static Map<String, Object> getRegisteredQueues(FacesContext context) {
+ ExternalContext externalContext = context.getExternalContext();
+ Map<String, Object> requestMap = externalContext.getRequestMap();
+
+ return (Map<String, Object>) requestMap.get(REGISTRY_ATTRIBUTE_NAME);
+ }
+}
Property changes on:
trunk/framework/impl/src/main/java/org/ajax4jsf/component/QueueRegistry.java
___________________________________________________________________
Name: svn:mergeinfo
+
Modified: trunk/framework/impl/src/main/java/org/ajax4jsf/context/ViewResources.java
===================================================================
--- trunk/framework/impl/src/main/java/org/ajax4jsf/context/ViewResources.java 2008-11-24
19:14:35 UTC (rev 11334)
+++ trunk/framework/impl/src/main/java/org/ajax4jsf/context/ViewResources.java 2008-11-24
19:33:30 UTC (rev 11335)
@@ -25,7 +25,6 @@
import java.io.StringWriter;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -42,6 +41,8 @@
import javax.faces.render.RenderKitFactory;
import javax.faces.render.Renderer;
+import org.ajax4jsf.component.QueueRegistry;
+import org.ajax4jsf.component.UIQueue;
import org.ajax4jsf.io.SAXResponseWriter;
import org.ajax4jsf.renderkit.HeaderResourceProducer;
import org.ajax4jsf.renderkit.HeaderResourceProducer2;
@@ -171,6 +172,8 @@
public static final String SKINNING_STYLES_PATH =
"/org/richfaces/renderkit/html/css/";
+ public static final String QUEUE_SCRIPT_RESOURCE =
"org.ajax4jsf.renderkit.html.scripts.QueueScript";
+
private boolean extendedSkinningAllowed;
private boolean processScripts;
@@ -453,6 +456,18 @@
context.setResponseWriter(componentWriter);
+ Map<String, Object> queues = QueueRegistry.getRegisteredQueues(context);
+ if (Boolean.valueOf(getInitParameterValue(context,
"org.richfaces.queue.global.enabled"))) {
+ String encodedGlobalQueueName =
context.getExternalContext().encodeNamespace(UIQueue.GLOBAL_QUEUE_NAME);
+
+ if (queues == null || !queues.containsKey(encodedGlobalQueueName)) {
+ QueueRegistry.registerQueue(context, encodedGlobalQueueName, null);
+ }
+ }
+
+ InternetResource queueScriptResource =
resourceBuilder.getResource(QUEUE_SCRIPT_RESOURCE);
+ queueScriptResource.encode(context, null);
+
// Append Skin StyleSheet after a
if (null != skinStyleSheetUri) {
String resourceURL = context.getApplication()
Modified: trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js
===================================================================
--- trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js 2008-11-24 19:14:35 UTC
(rev 11334)
+++ trunk/framework/impl/src/main/javascript/ajaxjsf/JSFAJAX.js 2008-11-24 19:33:30 UTC
(rev 11335)
@@ -289,7 +289,30 @@
}
return data;
},
+
+ _evaluateScript: function(node) {
+ var includeComments = !A4J.AJAX.isXhtmlScriptMode();
+ var newscript = A4J.AJAX.getText(node, includeComments) ; // TODO - Mozilla disable
innerHTML in XML page ..."";
+
+ try {
+ LOG.debug("Evaluate script replaced area in document: ", newscript);
+ if (window.execScript) {
+ window.execScript( newscript );
+ } else {
+ window.eval(newscript);
+ }
+ } catch(e){
+ LOG.error("ERROR Evaluate script: Error name: " + e.name +
e.message?". Error message: "+e.message:"");
+ }
+ },
+ evaluateQueueScript: function() {
+ var queueScript = this.getElementById('org.ajax4jsf.queue_script');
+ if (queueScript) {
+ this._evaluateScript(queueScript);
+ }
+ },
+
evalScripts : function(node, isLast){
var newscripts = this.getElementsByTagName("script",node);
LOG.debug("Scripts in updated part count : " + newscripts.length);
@@ -297,19 +320,7 @@
var _this = this;
window.setTimeout(function() {
for (var i = 0; i < newscripts.length; i++){
- var includeComments = !A4J.AJAX.isXhtmlScriptMode();
- var newscript = A4J.AJAX.getText(newscripts[i], includeComments) ; // TODO -
Mozilla disable innerHTML in XML page ..."";
-
- try {
- LOG.debug("Evaluate script replaced area in document: ",
newscript);
- if (window.execScript) {
- window.execScript( newscript );
- } else {
- window.eval(newscript);
- }
- } catch(e){
- LOG.error("ERROR Evaluate script: Error name: " + e.name +
e.message?". Error message: "+e.message:"");
- }
+ _this._evaluateScript(newscripts[i]);
}
newscripts = null;
if (isLast)
@@ -838,6 +849,8 @@
A4J.AJAX.processResponseAfterUpdateHeadElements = function (req, ids)
{
+ req.evaluateQueueScript();
+
for ( var k =0; k < ids.length ; k++ ) {
var id = ids[k];
LOG.debug("Update page part from call parameter for ID " + id);
@@ -1087,6 +1100,7 @@
*/
A4J.AJAX.finishRequest = function(request){
var options = request.options;
+
// we can set listener for complete request - for example,
// it can shedule next request for update page.
var oncomp = request.getElementById('org.ajax4jsf.oncomplete');
Modified: trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js
===================================================================
--- trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js 2008-11-24 19:14:35 UTC (rev
11334)
+++ trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js 2008-11-24 19:33:30 UTC (rev
11335)
@@ -9,254 +9,260 @@
}
};
-var Pipeline = function(size, gate) {
- this.size = size || -1;
-
- this.gate = gate;
- this.items = new Array();
-};
+//queue constructor
+A4J.AJAX.EventQueue = function() {
+ var Pipeline = function(size, gate) {
+ this.size = size || -1;
+
+ this.gate = gate;
+ this.items = new Array();
+ };
-extend(Pipeline.prototype, function() {
-
- return {
- submit: function() {
- var data = this.items.shift();
- if (data) {
- this.createRequest(data);
- }
- },
+ extend(Pipeline.prototype, function() {
- createRequest: function(data) {
- this.request = data.submit();
- this.similarityGroupingId = data.getSimilarityGroupingId();
- this.request.shouldNotifyQueue = true;
- },
-
- clearRequest: function() {
- this.request = undefined;
- this.similarityGroupingId = undefined;
- },
-
- getSize: function() {
- var size = this.items.length;
+ return {
+ submit: function() {
+ var data = this.items.shift();
+ if (data) {
+ this.createRequest(data);
+ }
+ },
- if (this.request) {
- size++;
- }
+ createRequest: function(data) {
+ this.request = data.submit();
+ this.similarityGroupingId = data.getSimilarityGroupingId();
+ this.request.shouldNotifyQueue = true;
+ },
- return size;
- },
-
- dropFirst: function() {
- this.items.shift();
- },
-
- fireFirst: function() {
- var data = this.items.shift();
- if (data) {
- data.submit()
+ clearRequest: function() {
+ this.request = undefined;
+ this.similarityGroupingId = undefined;
+ },
+
+ getSize: function() {
+ var size = this.items.length;
+
+ if (this.request) {
+ size++;
+ }
+
+ return size;
+ },
+
+ dropFirst: function() {
+ this.items.shift();
+ },
+
+ fireFirst: function() {
+ var data = this.items.shift();
+ if (data) {
+ data.submit()
+ }
+ },
+
+ addEvent: function(data) {
+ if (!this.isFull()) {
+ this.items.push(data);
+ } else {
+ //log error
+ }
+ },
+
+ //TODO new good name!
+ submitEvent: function() {
+ if (!this.request && !this.isEmpty()) {
+ this.submit();
+ }
+ },
+
+ submitNext: function() {
+ this.clearRequest();
+
+ if (this.getSize() > 0) {
+ this.submit();
+ } else {
+ this.gate.transferIfReady();
+ }
+ },
+
+ isFull: function() {
+ return this.getSize() == this.size;
+ },
+
+ isEmpty: function() {
+ return this.getSize() == 0;
+ },
+
+ hasNext: function() {
+ return this.items.length != 0;
+ },
+
+ abortCurrentRequest: function() {
+ if (this.request) {
+ this.request.shouldNotifyQueue = false;
+ this.request.abort();
+ this.clearRequest();
+ }
+ },
+
+ abortDupResponses: function(data) {
+ if (!this.hasNext() && data.getSimilarityGroupingId() ==
this.similarityGroupingId) {
+ this.abortCurrentRequest();
+ }
}
- },
+ }
+ }());
- addEvent: function(data) {
- if (!this.isFull()) {
- this.items.push(data);
- } else {
- //log error
+ var Gate = function() {
+ this.eventsCounter = 0;
+ };
+
+ extend(Gate.prototype, {
+
+ stopRequestDelay: function () {
+ if (this.timer) {
+ clearTimeout(this.timer);
+ this.timer = undefined;
}
},
- //TODO new good name!
- submitEvent: function() {
- if (!this.request && !this.isEmpty()) {
- this.submit();
- }
+ resetRequestDelay: function() {
+ this.delayPassed = false;
+
+ this.stopRequestDelay();
+ this.startRequestDelay();
},
- submitNext: function() {
- this.clearRequest();
-
- if (this.getSize() > 0) {
- this.submit();
+ startRequestDelay: function() {
+ var delay = this.data.getRequestDelay();
+ if (delay) {
+ var _this = this;
+ this.timer = setTimeout(function() {
+ try {
+ _this.transferIfEmpty();
+ _this.timer = undefined;
+ } finally {
+ _this = undefined;
+ }
+ }, delay);
} else {
- this.gate.transferIfReady();
+ this.transferIfEmpty();
}
},
- isFull: function() {
- return this.getSize() == this.size;
+ transferIfEmpty: function() {
+ this.delayPassed = true;
+
+ if (this.pipeline.isEmpty()) {
+ this.pipeline.addEvent(this.pop());
+ this.pipeline.submitEvent();
+ }
},
- isEmpty: function() {
- return this.getSize() == 0;
+ transferIfReady: function() {
+ if (this.delayPassed) {
+ this.pipeline.addEvent(this.pop());
+ this.pipeline.submitEvent();
+ }
},
- hasNext: function() {
- return this.items.length != 0;
+ pop: function() {
+ var data = this.data;
+ this.data = undefined;
+
+ this.eventsCounter = 0;
+ this.similarityGroupingId = undefined;
+ this.delayPassed = false;
+
+ return data;
},
-
- abortCurrentRequest: function() {
- if (this.request) {
- this.request.shouldNotifyQueue = false;
- this.request.abort();
- this.clearRequest();
- }
- },
-
- abortDupResponses: function(data) {
- if (!this.hasNext() && data.getSimilarityGroupingId() ==
this.similarityGroupingId) {
- this.abortCurrentRequest();
- }
- }
- }
-}());
-var Gate = function() {
- this.eventsCounter = 0;
-};
+ push: function() {
+ var DROP_NEW = 'dropNew';
+ var DROP_NEXT = 'dropNext';
+ var FIRE_NEW = 'fireNew';
+ var FIRE_NEXT = 'fireNext';
-extend(Gate.prototype, {
-
- stopRequestDelay: function () {
- if (this.timer) {
- clearTimeout(this.timer);
- this.timer = undefined;
- }
- },
-
- resetRequestDelay: function() {
- this.delayPassed = false;
-
- this.stopRequestDelay();
- this.startRequestDelay();
- },
-
- startRequestDelay: function() {
- var delay = this.data.getRequestDelay();
- if (delay) {
- var _this = this;
- this.timer = setTimeout(function() {
- try {
- _this.transferIfEmpty();
- _this.timer = undefined;
- } finally {
- _this = undefined;
+ return function(data) {
+ if (data.isIgnoreDupResponses()) {
+ this.pipeline.abortDupResponses(data);
}
- }, delay);
- } else {
- this.transferIfEmpty();
- }
- },
-
- transferIfEmpty: function() {
- this.delayPassed = true;
+
+ var similarityGroupingId = data.getSimilarityGroupingId();
+
+ if (this.similarityGroupingId == similarityGroupingId) {
+ this.data = data;
+ data.setEventsCounter(++this.eventsCounter);
+
+ this.resetRequestDelay();
+ } else {
+ if (this.data) {
+ this.stopRequestDelay();
+ this.pipeline.addEvent(this.pop());
+ }
- if (this.pipeline.isEmpty()) {
- this.pipeline.addEvent(this.pop());
- this.pipeline.submitEvent();
- }
- },
-
- transferIfReady: function() {
- if (this.delayPassed) {
- this.pipeline.addEvent(this.pop());
- this.pipeline.submitEvent();
- }
- },
-
- pop: function() {
- var data = this.data;
- this.data = undefined;
-
- this.eventsCounter = 0;
- this.similarityGroupingId = undefined;
- this.delayPassed = false;
-
- return data;
- },
+ var newDataHandled = false;
+
+ if (this.pipeline.isFull()) {
+ var behavior = data.getSizeExceededBehavior();
+
+ var queue = data.queue;
+ var queueOptions = queue.queueOptions;
+
+ if (queueOptions.onsizeexceeded) {
+ var query = data.query;
+ var options = data.options;
+ var event = data.event;
- push: function() {
- var DROP_NEW = 'dropNew';
- var DROP_NEXT = 'dropNext';
- var FIRE_NEW = 'fireNew';
- var FIRE_NEXT = 'fireNext';
+ queueOptions.onsizeexceeded.call(data.queue, query, options, event);
+ }
+
+ if (behavior == DROP_NEW ||
+ (behavior == DROP_NEXT && !(this.pipeline.hasNext()))) {
+
+ newDataHandled = true;
+ } else if (behavior == FIRE_NEW ||
+ (behavior == FIRE_NEXT && !(this.pipeline.hasNext()))) {
- return function(data) {
- if (data.isIgnoreDupResponses()) {
- this.pipeline.abortDupResponses(data);
- }
-
- var similarityGroupingId = data.getSimilarityGroupingId();
-
- if (this.similarityGroupingId == similarityGroupingId) {
- this.data = data;
- data.setEventsCounter(++this.eventsCounter);
-
- this.resetRequestDelay();
- } else {
- if (this.data) {
- this.stopRequestDelay();
- this.pipeline.addEvent(this.pop());
- }
-
- var newDataHandled = false;
-
- if (this.pipeline.isFull()) {
- var behavior = data.getSizeExceededBehavior();
+ data.submit();
+ newDataHandled = true;
+ } else if (behavior == DROP_NEXT) {
+ this.pipeline.dropFirst();
+ } else if (behavior == FIRE_NEXT) {
+ this.pipeline.fireFirst();
+ }
- var queue = data.queue;
- var queueOptions = queue.queueOptions;
-
- if (queueOptions.onsizeexceeded) {
- var query = data.query;
- var options = data.options;
- var event = data.event;
-
- queueOptions.onsizeexceeded.call(data.queue, query, options, event);
}
- if (behavior == DROP_NEW ||
- (behavior == DROP_NEXT && !(this.pipeline.hasNext()))) {
-
- newDataHandled = true;
- } else if (behavior == FIRE_NEW ||
- (behavior == FIRE_NEXT && !(this.pipeline.hasNext()))) {
+ this.pipeline.submitEvent();
- data.submit();
- newDataHandled = true;
- } else if (behavior == DROP_NEXT) {
- this.pipeline.dropFirst();
- } else if (behavior == FIRE_NEXT) {
- this.pipeline.fireFirst();
+ if (!newDataHandled) {
+ this.data = data;
+ this.similarityGroupingId = similarityGroupingId;
+ this.startRequestDelay();
}
-
}
-
- this.pipeline.submitEvent();
-
- if (!newDataHandled) {
- this.data = data;
- this.similarityGroupingId = similarityGroupingId;
- this.startRequestDelay();
- }
}
- }
- }()
-});
+ }()
+ });
-//queue constructor
-A4J.AJAX.EventQueue = function(name, queueOptions, requestOptions) {
- this.name = name;
- this.queueOptions = queueOptions || {};
- this.requestOptions = requestOptions || {};
-
- this.gate = new Gate();
- this.pipeline = new Pipeline(this.queueOptions.size, this.gate);
- this.gate.pipeline = this.pipeline;
-};
+ return function(name, queueOptions, requestOptions) {
+ this.name = name;
+ this.queueOptions = queueOptions || {};
+ this.requestOptions = requestOptions || {};
+
+ this.gate = new Gate();
+ this.pipeline = new Pipeline(this.queueOptions.size, this.gate);
+ this.gate.pipeline = this.pipeline;
+ };
+}();
A4J.AJAX.EventQueue.DEFAULT_QUEUE_NAME = "org.richfaces.queue.global";
+A4J.AJAX.EventQueue.getQueue = function(name) {
+ return A4J.AJAX._eventQueues[name];
+};
+
A4J.AJAX.EventQueue.addQueue = function(queue) {
var name = queue.name;
@@ -435,16 +441,16 @@
extend(EventQueueData.prototype, {
submit: function() {
this.query.appendParameter("AJAX:EVENTS_COUNT", this.eventsCount);
- var request = A4J.AJAX.SubmitQuery(this.query, this.options)
+ this.request = A4J.AJAX.SubmitQuery(this.query, this.options)
+
var queue = this.queue;
+ this.request.queue = queue;
- request.queue = queue;
-
if (this.options.queueonsubmit) {
- this.options.queueonsubmit.call(queue, request);
+ this.options.queueonsubmit.call(queue, this.request);
}
- return request;
+ return this.request;
},
getSimilarityGroupingId: function() {
@@ -465,10 +471,6 @@
setEventsCounter: function(count) {
this.eventsCount = count;
- },
-
- setRequest: function() {
- //TODO nick
}
});