JBoss Rich Faces SVN: r19884 - in trunk/ui/validator/ui/src: test/java/org/richfaces/convert and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: pyaschenko
Date: 2010-11-02 05:53:35 -0400 (Tue, 02 Nov 2010)
New Revision: 19884
Removed:
trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js
trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js
Modified:
trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length-validator.js
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BooleanConverterTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ByteConverterTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/LengthValidatorTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ShortConverterTest.java
Log:
http://jira.jboss.com/jira/browse/RF-9329
http://jira.jboss.com/jira/browse/RF-9521
Modified: trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length-validator.js
===================================================================
--- trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length-validator.js 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length-validator.js 2010-11-02 09:53:35 UTC (rev 19884)
@@ -5,7 +5,7 @@
throw rf.csv.getMessage(params.customMessage, 'LENGTH_VALIDATOR_MAXIMUM', [params.maximum, componentId]);
}
if (params.minimum && value.length < params.minimum) {
- throw rf.csv.getMessage(params.customMessage, 'LENGTH_VALIDATOR_MINIMUM', [params.maximum, componentId]);
+ throw rf.csv.getMessage(params.customMessage, 'LENGTH_VALIDATOR_MINIMUM', [params.minimum, componentId]);
}
}
})(window.RichFaces || (window.RichFaces={}))
Deleted: trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js
===================================================================
--- trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/length.js 2010-11-02 09:53:35 UTC (rev 19884)
@@ -1,78 +0,0 @@
-(function($, rf) {
-
- rf.csv = rf.csv || {};
-
- var _messages = {};
- var _validators = {};
- var _converters = {};
-
- var RE_MESSAGE_PATTERN = /\{(\d+)\}/g;
-
- $.extend(rf.csv, {
- // Messages API
- addMessage: function (messagesObject) {
- $.extend(_messages, messagesObject);
- },
- getMessage: function(customMessages, id, values) {
- var message = (customMessages && customMessages[id]) || _messages[id] || "";
- if (message) {
- var msgObject = message.replace(RE_MESSAGE_PATTERN,"\n$1\n").split("\n");
- var value;
- for (var i=1; i<msgObject.length; i+=2) {
- value = values[msgObject[i]];
- msgObject[i] = typeof value == "undefined" ? "" : value;
- }
- message = msgObject.join('');
- }
- return message;
- },
- // Validators API
- addValidator: function (validatorFunctions) {
- $.extend(_validators, validatorFunctions);
- },
- validate: function (event, id, validatorList, messageComponentList, options) {
- var value;
- var element = rf.getDomElement(id);
- if (element.value) {
- value = element.value;
- } else {
- var component = rf.$(element);
- value = component && typeof component["getValue"] == "function" ? component.getValue() : "";
- }
- var result;
- var messageComponentsUpdated = false;
- var validatorFunction;
- for (var validator in validatorList) {
- validatorFunction = _validators[validator];
- if (validatorFunction) {
- result = validatorFunction(value, validatorList[validator]);
- }
- if (result && result.length>0) {
- messageComponentsUpdated = true;
- //updateMessageComponents(messageElementIds, result);
- alert(result);
- break;
- }
- }
- !messageComponentsUpdated && alert("no message from validators");//updateMessageComponents(messageElementIds, "");
- },
- addFormValidators: function (formId, callValidatorFunctions) {
-
- }
- });
-})(jQuery, window.RichFaces || (window.RichFaces={}));
-
-
-RichFaces.csv.addValidator({"length":
-(function(rf) {
- return function (value, params) {
- var result = "";
- if (value.length<params.min) {
- result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MINIMUM', [params.min,value]);
- } else if (value.length>params.max){
- result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MAXIMUM', [params.max,value]);
- }
- return result;
- }
-})(window.RichFaces || (window.RichFaces={}))
-});
\ No newline at end of file
Deleted: trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js
===================================================================
--- trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/main/resources/META-INF/resources/org.richfaces/validator-length.js 2010-11-02 09:53:35 UTC (rev 19884)
@@ -1,13 +0,0 @@
-RichFaces.csv.addValidator({"length":
-(function(rf) {
- return function (value, params) {
- var result = "";
- if (value.length<params.min) {
- result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MINIMUM', [params.min,value]);
- } else if (value.length>params.max){
- result = rf.csv.getMessage(params.customMessages, 'LengthValidator.MAXIMUM', [params.max,value]);
- }
- return result;
- }
-})(window.RichFaces || (window.RichFaces={}))
-});
\ No newline at end of file
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BooleanConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BooleanConverterTest.java 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BooleanConverterTest.java 2010-11-02 09:53:35 UTC (rev 19884)
@@ -39,9 +39,19 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "true"), @TestData(submittedValue = "True"),
- @TestData(submittedValue = "TRUE"), @TestData(submittedValue = "false"), @TestData(submittedValue = "0"),
- @TestData(submittedValue = "1"), @TestData(submittedValue = "") }, failures = {})
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "true"),
+ @TestData(submittedValue = "True"),
+ @TestData(submittedValue = "TRUE"),
+ @TestData(submittedValue = "false"),
+ @TestData(submittedValue = "0"),
+ @TestData(submittedValue = "1"),
+ @TestData(submittedValue = "")
+ },
+ failures = {}
+ )
+
public void testSuccess() throws Exception {
setClientFunction("RichFaces.csv.getConverter('boolean')");
setObjectId(BooleanConverter.CONVERTER_ID);
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ByteConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ByteConverterTest.java 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ByteConverterTest.java 2010-11-02 09:53:35 UTC (rev 19884)
@@ -39,10 +39,23 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "-128"), @TestData(submittedValue = "0"),
- @TestData(submittedValue = "127") }, failures = { @TestData(submittedValue = "-129"),
- @TestData(submittedValue = "128"), @TestData(submittedValue = "1.0"), @TestData(submittedValue = "1.2"),
- @TestData(submittedValue = "1a"), @TestData(submittedValue = "aaa"), @TestData(submittedValue = "- 127") })
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "-128"),
+ @TestData(submittedValue = "0"),
+ @TestData(submittedValue = "127")
+ },
+ failures = {
+ @TestData(submittedValue = "-129"),
+ @TestData(submittedValue = "128"),
+ @TestData(submittedValue = "1.0"),
+ @TestData(submittedValue = "1.2"),
+ @TestData(submittedValue = "1a"),
+ @TestData(submittedValue = "aaa"),
+ @TestData(submittedValue = "- 127")
+ }
+ )
+
public void testSuccess() throws Exception {
setClientFunction("RichFaces.csv.getConverter('byte')");
setObjectId(ByteConverter.CONVERTER_ID);
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java 2010-11-02 09:53:35 UTC (rev 19884)
@@ -38,11 +38,16 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "18-10-2010")
- // ,@TestData(submittedValue = "17-10-2010")
- }, failures = {
- // @TestData(submittedValue = "10/17/2010")
- })
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "18-10-2010")
+ // ,@TestData(submittedValue = "17-10-2010")
+ },
+ failures = {
+ // @TestData(submittedValue = "10/17/2010")
+ }
+ )
+
public void testPattern() throws Exception {
setClientFunction("org.rf.DateTimeConverter");
setObjectId(DateTimeConverter.CONVERTER_ID);
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/LengthValidatorTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/LengthValidatorTest.java 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/LengthValidatorTest.java 2010-11-02 09:53:35 UTC (rev 19884)
@@ -39,7 +39,15 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "dddd") }, failures = { @TestData(submittedValue = "1234567890A") })
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "1234")
+ },
+ failures = {
+ @TestData(submittedValue = "1234567890A")
+ }
+ )
+
public void testSuccess() throws Exception {
setClientFunction("RichFaces.csv.getValidator('length')");
setObjectId(LengthValidator.VALIDATOR_ID);
@@ -48,4 +56,44 @@
setAttribute("maximum", 10);
setAttribute("minimum", 0);
}
+
+ @Test
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "123"),
+ @TestData(submittedValue = "1234")
+ },
+ failures = {
+ @TestData(submittedValue = "12"),
+ @TestData(submittedValue = "")
+ }
+ )
+
+ public void minTestSuccess() throws Exception {
+ setClientFunction("RichFaces.csv.getValidator('length')");
+ setObjectId(LengthValidator.VALIDATOR_ID);
+ Enum<?>[] messages = { FacesMessages.LENGTH_VALIDATOR_MAXIMUM, FacesMessages.LENGTH_VALIDATOR_MINIMUM };
+ setErrorMessageEnums(messages);
+ setAttribute("minimum", 3);
+ }
+
+ @Test
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = ""),
+ @TestData(submittedValue = "12"),
+ @TestData(submittedValue = "123")
+ },
+ failures = {
+ @TestData(submittedValue = "1234")
+ }
+ )
+
+ public void maxTestSuccess() throws Exception {
+ setClientFunction("RichFaces.csv.getValidator('length')");
+ setObjectId(LengthValidator.VALIDATOR_ID);
+ Enum<?>[] messages = { FacesMessages.LENGTH_VALIDATOR_MAXIMUM, FacesMessages.LENGTH_VALIDATOR_MINIMUM };
+ setErrorMessageEnums(messages);
+ setAttribute("maximum", 3);
+ }
}
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/NumberConverterTest.java 2010-11-02 09:53:35 UTC (rev 19884)
@@ -39,7 +39,15 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "111") }, failures = { @TestData(submittedValue = "aaa") })
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "111")
+ },
+ failures = {
+ @TestData(submittedValue = "aaa")
+ }
+ )
+
public void testSuccess() throws Exception {
setClientFunction("RichFaces.csv.getConverter('number')");
setObjectId(NumberConverter.CONVERTER_ID);
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ShortConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ShortConverterTest.java 2010-11-02 06:22:38 UTC (rev 19883)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/ShortConverterTest.java 2010-11-02 09:53:35 UTC (rev 19884)
@@ -39,10 +39,23 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "-32768"), @TestData(submittedValue = "0"),
- @TestData(submittedValue = "32767") }, failures = { @TestData(submittedValue = "-32769"),
- @TestData(submittedValue = "32768"), @TestData(submittedValue = "1.0"), @TestData(submittedValue = "1.2"),
- @TestData(submittedValue = "1a"), @TestData(submittedValue = "aaa"), @TestData(submittedValue = "- 10") })
+ @TestDataHolder(
+ successes = {
+ @TestData(submittedValue = "-32768"),
+ @TestData(submittedValue = "0"),
+ @TestData(submittedValue = "32767")
+ },
+ failures = {
+ @TestData(submittedValue = "-32769"),
+ @TestData(submittedValue = "32768"),
+ @TestData(submittedValue = "1.0"),
+ @TestData(submittedValue = "1.2"),
+ @TestData(submittedValue = "1a"),
+ @TestData(submittedValue = "aaa"),
+ @TestData(submittedValue = "- 10")
+ }
+ )
+
public void testSuccess() throws Exception {
setClientFunction("RichFaces.csv.getConverter('short')");
setObjectId(ShortConverter.CONVERTER_ID);
14 years, 2 months
JBoss Rich Faces SVN: r19883 - trunk/ui/validator/api/src/main/java/org/richfaces/validator.
by richfaces-svn-commits@lists.jboss.org
Author: alexsmirnov
Date: 2010-11-02 02:22:38 -0400 (Tue, 02 Nov 2010)
New Revision: 19883
Modified:
trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScript.java
Log:
https://jira.jboss.org/browse/RF-9221
Modified: trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScript.java
===================================================================
--- trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScript.java 2010-11-02 06:11:17 UTC (rev 19882)
+++ trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScript.java 2010-11-02 06:22:38 UTC (rev 19883)
@@ -34,7 +34,5 @@
public interface LibraryScript {
LibraryResource getResource();
-
- String getName();
}
14 years, 2 months
JBoss Rich Faces SVN: r19882 - in trunk: ui/validator/api and 11 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: alexsmirnov
Date: 2010-11-02 02:11:17 -0400 (Tue, 02 Nov 2010)
New Revision: 19882
Added:
trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryFunction.java
trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScriptString.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/Bean.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/Script.java
Removed:
trunk/ui/validator/api/src/main/java/org/richfaces/validator/ClientScript.java
trunk/ui/validator/api/src/main/java/org/richfaces/validator/ObjectValidator.java
trunk/ui/validator/ui/src/main/java/org/richfaces/component/ClonedObjectResolver.java
trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScript.java
trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptString.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestBean.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestScript.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/behavior/ClientValidatorBehaviorTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTestRunner.java
Modified:
trunk/parent/pom.xml
trunk/ui/validator/api/pom.xml
trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryResource.java
trunk/ui/validator/impl/pom.xml
trunk/ui/validator/ui/pom.xml
trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientAndAjaxScript.java
trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientOnlyScript.java
trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptFunction.java
trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/NullConverterScript.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIValidatorScriptCollectionTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIViewResourceTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java
trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java
trunk/ui/validator/ui/src/test/resources/org/richfaces/component/WEB-INF/faces-config.xml
trunk/ui/validator/ui/src/test/resources/org/richfaces/component/faces-config.xml
Log:
https://jira.jboss.org/browse/RF-9221
Modified: trunk/parent/pom.xml
===================================================================
--- trunk/parent/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/parent/pom.xml 2010-11-02 06:11:17 UTC (rev 19882)
@@ -58,22 +58,22 @@
<dependency>
<groupId>org.jboss.test-jsf</groupId>
<artifactId>htmlunit-client</artifactId>
- <version>1.0.4</version>
+ <version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.jboss.test-jsf</groupId>
<artifactId>jsf-mock</artifactId>
- <version>1.0.4</version>
+ <version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.jboss.test-jsf</groupId>
<artifactId>jsf-test-stage</artifactId>
- <version>1.0.4</version>
+ <version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.jboss.test-jsf</groupId>
<artifactId>jsf-test-jetty</artifactId>
- <version>1.0.4</version>
+ <version>1.0.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Modified: trunk/ui/validator/api/pom.xml
===================================================================
--- trunk/ui/validator/api/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/api/pom.xml 2010-11-02 06:11:17 UTC (rev 19882)
@@ -58,18 +58,6 @@
<version>1.0.0.GA</version>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>org.jboss.test-jsf</groupId>
- <artifactId>jsf-mock</artifactId>
- <version>1.0.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.test-jsf</groupId>
- <artifactId>jsf-test-stage</artifactId>
- <version>1.0.5</version>
- <scope>test</scope>
- </dependency>
</dependencies>
<scm>
Deleted: trunk/ui/validator/api/src/main/java/org/richfaces/validator/ClientScript.java
===================================================================
--- trunk/ui/validator/api/src/main/java/org/richfaces/validator/ClientScript.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/api/src/main/java/org/richfaces/validator/ClientScript.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,39 +0,0 @@
-/*
- * $Id$
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.richfaces.validator;
-
-/**
- * <p class="changed_added_4_0">This class contains information about JavaScript associated with JSF object ( converter or validator )</p>
- * @author asmirnov(a)exadel.com
- *
- */
-public interface ClientScript {
-
- String getLibrary();
-
- String getResourceName();
-
- String getFunctionName();
-
-}
Copied: trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryFunction.java (from rev 19881, branches/RF-8742/ui/validator/api/src/main/java/org/richfaces/validator/LibraryFunction.java)
===================================================================
--- trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryFunction.java (rev 0)
+++ trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryFunction.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.richfaces.validator;
+
+/**
+ * <p class="changed_added_4_0">
+ * This class contains information about JavaScript function in external library ( resource )
+ * </p>
+ *
+ * @author asmirnov(a)exadel.com
+ *
+ */
+public interface LibraryFunction extends LibraryScript {
+
+
+ String getName();
+
+}
Modified: trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryResource.java
===================================================================
--- trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryResource.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryResource.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -2,7 +2,6 @@
import java.util.LinkedHashSet;
-import org.richfaces.renderkit.html.LibraryScriptString;
import com.google.common.collect.Sets;
Copied: trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScriptString.java (from rev 19881, branches/RF-8742/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScriptString.java)
===================================================================
--- trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScriptString.java (rev 0)
+++ trunk/ui/validator/api/src/main/java/org/richfaces/validator/LibraryScriptString.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -0,0 +1,13 @@
+package org.richfaces.validator;
+
+import org.ajax4jsf.javascript.ScriptString;
+
+/**
+ * This interface describes JavaScript object with possible dependent resource.
+ * @author asmirnov
+ *
+ */
+public interface LibraryScriptString extends LibraryScript, ScriptString {
+
+
+}
\ No newline at end of file
Deleted: trunk/ui/validator/api/src/main/java/org/richfaces/validator/ObjectValidator.java
===================================================================
--- trunk/ui/validator/api/src/main/java/org/richfaces/validator/ObjectValidator.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/api/src/main/java/org/richfaces/validator/ObjectValidator.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,443 +0,0 @@
-package org.richfaces.validator;
-
-import java.beans.FeatureDescriptor;
-import java.util.Collection;
-import java.util.EmptyStackException;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.ResourceBundle;
-import java.util.Set;
-import java.util.Stack;
-
-import javax.el.ELContext;
-import javax.el.ELException;
-import javax.el.ELResolver;
-import javax.el.ValueExpression;
-import javax.faces.FacesException;
-import javax.faces.application.Application;
-import javax.faces.context.FacesContext;
-
-import org.richfaces.application.ServiceTracker;
-import org.richfaces.component.ClonedObjectResolver;
-import org.richfaces.el.ELContextWrapper;
-
-public abstract class ObjectValidator {
-
- private static final String RESOURCE_BUNDLE_IS_NOT_REGISTERED_FOR_CURRENT_LOCALE = "Resource bundle is not registered for current locale";
-
- private static final String FACES_CONTEXT_IS_NULL = "Faces context is null";
- protected static final String INPUT_PARAMETERS_IS_NOT_CORRECT = "Input parameters is not correct.";
- private static final String LOCALE_IS_NOT_SET = "Locale is not set";
- private static final String VIEW_ROOT_IS_NOT_INITIALIZED = "ViewRoot is not initialized";
-
-
- protected final ObjectValidator parent;
-
-
- ObjectValidator() {
- this.parent = null;
- }
-
- ObjectValidator(ObjectValidator parent){
- this.parent = parent;
- }
- /**
- * Return BeanValidator object from a ServletContext attribute. Create new
- * instance if none is defined.
- *
- * @param context
- * @return
- */
- public static ObjectValidator getInstance(FacesContext context) {
- return ServiceTracker.getService(context, ObjectValidator.class);
- }
-
- public abstract Collection<String> validateGraph(FacesContext context, Object value,
- Set<String> profiles);
-
- /**
- * Perform Validation for a new value.
- *
- * @param context
- * current faces context.
- * @param target
- * {@link ValueExpression} for a value assignment.
- * @param value
- * new value for validation
- * @param profiles TODO
- * @return null if no validation errors. Array of the validation messages
- * otherwise.
- * @throws FacesException
- * if locale or context not properly initialized
- */
- public Collection<String> validate(FacesContext context, ValueExpression target,
- Object value, Set<String> profiles) {
- if (null == context) {
- throw new FacesException(INPUT_PARAMETERS_IS_NOT_CORRECT);
- }
- Collection<String> validationMessages = null;
- if (null != target) {
- ELContext elContext = context.getELContext();
- ValidationResolver validationResolver = createValidationResolver(
- context, elContext.getELResolver(),profiles);
- ELContextWrapper wrappedElContext = new ELContextWrapper(elContext,
- validationResolver);
- try {
- target.setValue(wrappedElContext, value);
- } catch (ELException e) {
- throw new FacesException(e);
- }
- if (!validationResolver.isValid()) {
- validationMessages = validationResolver.getValidationMessages();
- }
- if(null != parent){
- Collection<String> parentMessages = parent.validate(context, target, value, profiles);
- if (null != validationMessages) {
- if (null != parentMessages) {
- validationMessages.addAll(parentMessages);
- }
- } else {
- validationMessages = parentMessages;
- }
- }
-
- }
- return validationMessages;
- }
-
- /**
- * Validate bean property for a new value.
- * @param facesContext TODO
- * @param base
- * - bean
- * @param property
- * - bean property name.
- * @param value
- * new value.
- * @param profiles TODO
- *
- * @return null for a valid value, array of the validation messages
- * othervise.
- */
- protected abstract Collection<String> validate(FacesContext facesContext, Object base,
- String property, Object value, Set<String> profiles);
-
- static Locale calculateLocale(FacesContext context) {
- if (null == context.getViewRoot()) {
- throw new FacesException(VIEW_ROOT_IS_NOT_INITIALIZED);
- } else if (null == context.getViewRoot().getLocale()) {
- throw new FacesException(LOCALE_IS_NOT_SET);
- }
- Locale locale = context.getViewRoot().getLocale();
- return locale;
- }
-
- static ResourceBundle getResourceBundle(FacesContext facesContext, String name) {
- ResourceBundle bundle = null;
- if (null != facesContext) {
- Application application = facesContext.getApplication();
- try {
- bundle = application.getResourceBundle(facesContext,
- name);
-
- } catch (Exception e) {
- // Let one more attempt to load resource
- }
- }
- if (null == bundle) {
- ClassLoader classLoader = Thread.currentThread()
- .getContextClassLoader();
- if (null == classLoader) {
- classLoader = ObjectValidator.class.getClassLoader();
- }
- try {
- bundle = ResourceBundle.getBundle(name, calculateLocale(facesContext),
- classLoader);
-
- } catch (MissingResourceException e) {
- // Do nothing, use default bundle.
- }
- }
- return bundle;
- }
-
- protected ValidationResolver createValidationResolver(FacesContext context,
- ELResolver parent, Set<String> profiles) {
- return new ValidationResolver(parent, context, profiles);
- }
-
- /**
- * @author asmirnov
- *
- */
- protected static class BasePropertyPair {
- private final Object base;
- private final Object property;
-
- /**
- * @param base
- * @param property
- */
- public BasePropertyPair(Object base, Object property) {
- this.base = base;
- this.property = property;
- }
-
- /**
- * @return the base
- */
- public Object getBase() {
- return base;
- }
-
- /**
- * @return the property
- */
- public Object getProperty() {
- return property;
- }
-
- }
-
- /**
- * Class for identify validator instance by locale
- *
- * @author amarkhel
- *
- */
- protected static class ValidatorKey {
- private final Class<? extends Object> validatableClass;
- private final Locale locale;
-
- /**
- * Constructor for ValidatorKey object
- *
- * @param validatableClass
- * - class to validate
- * @param locale
- * - User locale to determine Resource bundle, used during
- * validation process
- */
- public ValidatorKey(Class<? extends Object> validatableClass,
- Locale locale) {
- this.validatableClass = validatableClass;
- this.locale = locale;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result
- + ((locale == null) ? 0 : locale.hashCode());
- result = prime
- * result
- + ((validatableClass == null) ? 0 : validatableClass
- .hashCode());
- return result;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (!(obj instanceof ValidatorKey))
- return false;
- ValidatorKey other = (ValidatorKey) obj;
- if (locale == null) {
- if (other.locale != null)
- return false;
- } else if (!locale.equals(other.locale))
- return false;
- if (validatableClass == null) {
- if (other.validatableClass != null)
- return false;
- } else if (!validatableClass.equals(other.validatableClass))
- return false;
- return true;
- }
-
- }
-
- /**
- * Wrapper class for a {@link ELResolver}. For a setValue method, perform
- * validation instead of real assignment.
- *
- * @author asmirnov
- *
- */
- final class ValidationResolver extends ELResolver {
-
- /**
- * Original resolver.
- */
- private final ELResolver parent;
-
- private boolean valid = true;
-
- private Collection<String> validationMessages = null;
-
- private Stack<BasePropertyPair> valuesStack;
-
- private Set<String> profiles;
-
- private FacesContext facesContext;
-
- private boolean clonedObject = false;
-
- /**
- * @param parent
- * @param context
- */
- public ValidationResolver(ELResolver parent, FacesContext context, Set<String> profiles) {
- this.parent = parent;
- this.valuesStack = new Stack<BasePropertyPair>();
- this.profiles = profiles;
- this.facesContext = context;
- }
-
- public boolean isValid() {
- return valid;
- }
-
- /**
- * @param context
- * @param base
- * @return
- * @see javax.el.ELResolver#getCommonPropertyType(javax.el.ELContext,
- * java.lang.Object)
- */
- public Class<?> getCommonPropertyType(ELContext context, Object base) {
- return parent.getCommonPropertyType(context, base);
- }
-
- /**
- * @param context
- * @param base
- * @return
- * @see javax.el.ELResolver#getFeatureDescriptors(javax.el.ELContext,
- * java.lang.Object)
- */
- public Iterator<FeatureDescriptor> getFeatureDescriptors(
- ELContext context, Object base) {
- return parent.getFeatureDescriptors(context, base);
- }
-
- /**
- * @param context
- * @param base
- * @param property
- * @return
- * @see javax.el.ELResolver#getType(javax.el.ELContext,
- * java.lang.Object, java.lang.Object)
- */
- public Class<?> getType(ELContext context, Object base, Object property) {
- return parent.getType(context, base, property);
- }
-
- /**
- * @param context
- * @param base
- * @param property
- * @return
- * @see javax.el.ELResolver#getValue(javax.el.ELContext,
- * java.lang.Object, java.lang.Object)
- */
- public Object getValue(ELContext context, Object base, Object property) {
- Object value = ClonedObjectResolver.resolveCloned(context, base, property);
- if(null != value){
- this.clonedObject =true;
- context.setPropertyResolved(true);
- } else {
- value = parent.getValue(context, base, property);
- }
- valuesStack.push(new BasePropertyPair(base, property));
- return value;
- }
-
- /**
- * @param context
- * @param base
- * @param property
- * @return
- * @see javax.el.ELResolver#isReadOnly(javax.el.ELContext,
- * java.lang.Object, java.lang.Object)
- */
- public boolean isReadOnly(ELContext context, Object base,
- Object property) {
- return parent.isReadOnly(context, base, property);
- }
-
- /**
- * @param context
- * @param base
- * @param property
- * @param value
- * @see javax.el.ELResolver#setValue(javax.el.ELContext,
- * java.lang.Object, java.lang.Object, java.lang.Object)
- */
- public void setValue(ELContext context, Object base, Object property,
- Object value) {
- if (null != base && null != property) {
- // TODO - detect value object from inderect references ( e.g. data table variables ).
- if(this.clonedObject){
- parent.setValue(context, base, property, value);
- }
- context.setPropertyResolved(true);
- // For Arrays, Collection or Map use parent base and property.
- BasePropertyPair basePropertyPair = lookupBeanProperty(new BasePropertyPair(
- base, property));
- base = basePropertyPair.getBase();
- property = basePropertyPair.getProperty();
- if (null != base && null != property) {
- // https://jira.jboss.org/jira/browse/RF-4034
- // apache el looses locale information during value
- // resolution,
- // so we use our own
- validationMessages = validate(facesContext, base,
- property.toString(), value, profiles);
- valid = null == validationMessages
- || 0 == validationMessages.size();
-
- }
- }
- }
-
- private BasePropertyPair lookupBeanProperty(BasePropertyPair pair) {
- Object base = pair.getBase();
- if (null != base
- && (base instanceof Collection || base instanceof Map || base
- .getClass().isArray())) {
- try {
- pair = lookupBeanProperty(valuesStack.pop());
- } catch (EmptyStackException e) {
- // Do nothing, this is a first item.
- }
- }
- return pair;
- }
-
- /**
- * @return the validationMessages
- */
- public Collection<String> getValidationMessages() {
- return validationMessages;
- }
-
- }
-
-}
\ No newline at end of file
Modified: trunk/ui/validator/impl/pom.xml
===================================================================
--- trunk/ui/validator/impl/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/impl/pom.xml 2010-11-02 06:11:17 UTC (rev 19882)
@@ -71,19 +71,18 @@
<version>4.0.0.GA</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.jboss.test-jsf</groupId>
- <artifactId>jsf-mock</artifactId>
- <version>1.0.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.test-jsf</groupId>
- <artifactId>jsf-test-stage</artifactId>
- <version>1.0.5</version>
- <scope>test</scope>
- </dependency>
-
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.5.11</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.5.11</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<scm>
Modified: trunk/ui/validator/ui/pom.xml
===================================================================
--- trunk/ui/validator/ui/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/pom.xml 2010-11-02 06:11:17 UTC (rev 19882)
@@ -100,19 +100,6 @@
<artifactId>jsf-test-jetty</artifactId>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.jboss.test-jsf</groupId>
- <artifactId>jsf-mock</artifactId>
- <version>1.0.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.jboss.test-jsf</groupId>
- <artifactId>jsf-test-stage</artifactId>
- <version>1.0.5</version>
- <scope>test</scope>
- </dependency>
-
</dependencies>
<scm>
Deleted: trunk/ui/validator/ui/src/main/java/org/richfaces/component/ClonedObjectResolver.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/component/ClonedObjectResolver.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/component/ClonedObjectResolver.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,103 +0,0 @@
-/**
- *
- */
-package org.richfaces.component;
-
-import java.beans.FeatureDescriptor;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Map.Entry;
-
-import javax.el.ELContext;
-import javax.el.ELResolver;
-import javax.faces.context.FacesContext;
-
-import org.richfaces.component.UIGraphValidator.GraphValidatorState;
-
-/**
- * @author asmirnov
- *
- */
-public class ClonedObjectResolver extends ELResolver {
-
- /* (non-Javadoc)
- * @see javax.el.ELResolver#getCommonPropertyType(javax.el.ELContext, java.lang.Object)
- */
- @Override
- public Class<?> getCommonPropertyType(ELContext context, Object base) {
- // Do nothing
- return null;
- }
-
- /* (non-Javadoc)
- * @see javax.el.ELResolver#getFeatureDescriptors(javax.el.ELContext, java.lang.Object)
- */
- @Override
- public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
- Object base) {
- // do nothing
- return null;
- }
-
- /* (non-Javadoc)
- * @see javax.el.ELResolver#getType(javax.el.ELContext, java.lang.Object, java.lang.Object)
- */
- @Override
- public Class<?> getType(ELContext context, Object base, Object property) {
- Object cloned = resolveCloned(context, base, property);
- if(null != cloned){
- context.setPropertyResolved(true);
- return cloned.getClass();
- }
- return null;
- }
-
- /* (non-Javadoc)
- * @see javax.el.ELResolver#getValue(javax.el.ELContext, java.lang.Object, java.lang.Object)
- */
- @Override
- public Object getValue(ELContext context, Object base, Object property) {
- Object cloned = resolveCloned(context, base, property);
- if(null != cloned){
- context.setPropertyResolved(true);
- }
- return cloned;
- }
-
-
- /* (non-Javadoc)
- * @see javax.el.ELResolver#isReadOnly(javax.el.ELContext, java.lang.Object, java.lang.Object)
- */
- @Override
- public boolean isReadOnly(ELContext context, Object base, Object property) {
- // TODO Auto-generated method stub
- return false;
- }
-
- /* (non-Javadoc)
- * @see javax.el.ELResolver#setValue(javax.el.ELContext, java.lang.Object, java.lang.Object, java.lang.Object)
- */
- @Override
- public void setValue(ELContext context, Object base, Object property,
- Object value) {
- // TODO Auto-generated method stub
-
- }
-
- public static Object resolveCloned(ELContext context, Object base, Object property){
- if(null != base || null != property){
- FacesContext facesContext = FacesContext.getCurrentInstance();
- Map<String, Object> requestMap = facesContext.getExternalContext().getRequestMap();
- for (String key : requestMap.keySet()) {
- if(null != key && key.startsWith(UIGraphValidator.STATE_ATTRIBUTE_PREFIX)){
- UIGraphValidator.GraphValidatorState state = (GraphValidatorState) requestMap.get(key);
- if(state.isSame(base, property)){
- return state.getCloned();
- }
- }
- }
- }
- return null;
- }
-}
Modified: trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientAndAjaxScript.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientAndAjaxScript.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientAndAjaxScript.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -2,7 +2,9 @@
import java.util.Collection;
+import org.richfaces.validator.LibraryScriptString;
+
public class ClientAndAjaxScript extends ClientOnlyScript{
Modified: trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientOnlyScript.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientOnlyScript.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/ClientOnlyScript.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -4,6 +4,7 @@
import java.util.LinkedHashSet;
import org.richfaces.validator.LibraryResource;
+import org.richfaces.validator.LibraryScriptString;
import com.google.common.collect.Sets;
@@ -15,7 +16,11 @@
public ClientOnlyScript(LibraryScriptString clientSideConverterScript,
Collection<? extends LibraryScriptString> validatorScripts) {
super();
- this.converter = null==clientSideConverterScript ? NULL_CONVERTER_SCRIPT:clientSideConverterScript;
+ if(null==clientSideConverterScript){
+ this.converter = NULL_CONVERTER_SCRIPT;
+ } else {
+ this.converter = clientSideConverterScript;
+ }
this.validators = validatorScripts;
}
Deleted: trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScript.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScript.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScript.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,13 +0,0 @@
-package org.richfaces.renderkit.html;
-
-import org.richfaces.validator.LibraryResource;
-
-public interface LibraryScript {
-
- /**
- * <p class="changed_added_4_0"></p>
- * @return the resourceName
- */
- LibraryResource getResource();
-
-}
\ No newline at end of file
Modified: trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptFunction.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptFunction.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptFunction.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -25,36 +25,44 @@
import org.ajax4jsf.javascript.JSFunction;
import org.richfaces.validator.LibraryResource;
-import org.richfaces.validator.LibraryScript;
+import org.richfaces.validator.LibraryFunction;
+import org.richfaces.validator.LibraryScriptString;
/**
- * <p class="changed_added_4_0">This class represents call to function in external library.</p>
+ * <p class="changed_added_4_0">
+ * This class represents call to function in external library.
+ * </p>
+ *
* @author asmirnov(a)exadel.com
- *
+ *
*/
-public class LibraryScriptFunction extends JSFunction implements LibraryScriptString {
+public class LibraryScriptFunction extends JSFunction implements LibraryScriptString {
private final LibraryResource resource;
private String name;
- public LibraryScriptFunction(LibraryScript libraryScript, Object... parameters) {
+ public LibraryScriptFunction(LibraryFunction libraryScript, Object... parameters) {
super(libraryScript.getName(), parameters);
this.resource = libraryScript.getResource();
name = libraryScript.getName();
}
-
+
public String getName() {
- return name;
- }
+ return name;
+ }
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.renderkit.html.LibraryScriptString#getResource()
*/
public LibraryResource getResource() {
return resource;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#hashCode()
*/
@Override
@@ -67,7 +75,9 @@
return result;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
@@ -95,16 +105,16 @@
}
} else if (!resource.equals(other.resource)) {
return false;
- } else if (!getParameters().equals(other.getParameters())){
+ } else if (!getParameters().equals(other.getParameters())) {
return false;
}
return true;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see java.lang.Object#hashCode()
*/
-
-
}
Deleted: trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptString.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptString.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/LibraryScriptString.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,13 +0,0 @@
-package org.richfaces.renderkit.html;
-
-import org.ajax4jsf.javascript.ScriptString;
-
-/**
- * This interface describes JavaScript object with possible dependent resource.
- * @author asmirnov
- *
- */
-public interface LibraryScriptString extends LibraryScript, ScriptString {
-
-
-}
\ No newline at end of file
Modified: trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/NullConverterScript.java
===================================================================
--- trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/NullConverterScript.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/main/java/org/richfaces/renderkit/html/NullConverterScript.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -5,25 +5,29 @@
import org.ajax4jsf.javascript.JSLiteral;
import org.richfaces.validator.LibraryResource;
+import org.richfaces.validator.LibraryScriptString;
/**
* This class represents "dummy" converter call ( just refference to "value" variable )
+ *
* @author asmirnov
- *
+ *
*/
public class NullConverterScript extends JSLiteral implements LibraryScriptString {
private String name;
-
+
public NullConverterScript() {
super(ClientValidatorRenderer.VALUE_VAR);
}
-
+
public String getName() {
- return name;
- }
-
- /* (non-Javadoc)
+ return name;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
* @see org.richfaces.renderkit.html.LibraryScriptString#getResource()
*/
public LibraryResource getResource() {
Copied: trunk/ui/validator/ui/src/test/java/org/richfaces/component/Bean.java (from rev 19881, trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestBean.java)
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/Bean.java (rev 0)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/Bean.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -0,0 +1,82 @@
+/**
+ *
+ */
+package org.richfaces.component;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+
+import org.richfaces.renderkit.html.ComponentValidatorScript;
+import org.richfaces.validator.LibraryResource;
+
+/**
+ * @author asmirnov
+ *
+ */
+public class Bean {
+
+ public static final String TEST_SCRIPT_NAME = "test_script";
+
+ public static final String FOO_BAR = "foo.bar";
+
+ public static final String FOO = "foo";
+
+ public static final String FOO_VALUE = "fooValue";
+
+ public static final String TEST_SCRIPT = "function " + FOO + "(id){alert(id);}";
+
+ private static final LibraryResource TEST_RESOURCE = new LibraryResource(FOO_BAR, TEST_SCRIPT_NAME + ".js");
+
+ private static final ComponentValidatorScript SCRIPT = new ComponentValidatorScript() {
+
+ public String toScript() {
+ return TEST_SCRIPT;
+ }
+
+ public void appendScript(StringBuffer functionString) {
+ functionString.append(TEST_SCRIPT);
+ }
+
+ public Collection<LibraryResource> getResources() {
+ return Collections.singleton(TEST_RESOURCE);
+ }
+
+ public String getName() {
+ return FOO;
+ }
+
+ public String createCallScript(String clientId,String sourceId) {
+ return FOO+"("+clientId+")";
+ }
+ };
+
+ private String value=FOO_VALUE;
+
+ /**
+ * @return the value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * @param value the value to set
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public String action() {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ UIViewRoot viewRoot = facesContext.getViewRoot();
+ UIValidatorScript resource = (UIValidatorScript) facesContext.getApplication().createComponent(UIValidatorScript.COMPONENT_TYPE);
+ resource.addOrFindScript(SCRIPT );
+ viewRoot.addComponentResource(facesContext, resource);
+ return null;
+ }
+
+
+}
Property changes on: trunk/ui/validator/ui/src/test/java/org/richfaces/component/Bean.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Copied: trunk/ui/validator/ui/src/test/java/org/richfaces/component/Script.java (from rev 19881, trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestScript.java)
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/Script.java (rev 0)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/Script.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -0,0 +1,65 @@
+package org.richfaces.component;
+
+import org.richfaces.validator.LibraryResource;
+import org.richfaces.validator.LibraryScriptString;
+
+final class Script implements LibraryScriptString {
+ private final String name;
+
+ Script(String name) {
+ this.name = name;
+ }
+
+ public String toScript() {
+ return name;
+ }
+
+ public void appendScript(StringBuffer functionString) {
+ functionString.append(name);
+
+ }
+
+ public LibraryResource getResource() {
+ return UIValidatorScriptCollectionTest.FOO_RESOURCE;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ Script other = (Script) obj;
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+ return true;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
\ No newline at end of file
Property changes on: trunk/ui/validator/ui/src/test/java/org/richfaces/component/Script.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Deleted: trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestBean.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestBean.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestBean.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,82 +0,0 @@
-/**
- *
- */
-package org.richfaces.component;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import javax.faces.component.UIViewRoot;
-import javax.faces.context.FacesContext;
-
-import org.richfaces.renderkit.html.ComponentValidatorScript;
-import org.richfaces.validator.LibraryResource;
-
-/**
- * @author asmirnov
- *
- */
-public class TestBean {
-
- public static final String TEST_SCRIPT_NAME = "test_script";
-
- public static final String FOO_BAR = "foo.bar";
-
- public static final String FOO = "foo";
-
- public static final String FOO_VALUE = "fooValue";
-
- public static final String TEST_SCRIPT = "function " + FOO + "(id){alert(id);}";
-
- private static final LibraryResource TEST_RESOURCE = new LibraryResource(FOO_BAR, TEST_SCRIPT_NAME + ".js");
-
- private static final ComponentValidatorScript SCRIPT = new ComponentValidatorScript() {
-
- public String toScript() {
- return TEST_SCRIPT;
- }
-
- public void appendScript(StringBuffer functionString) {
- functionString.append(TEST_SCRIPT);
- }
-
- public Collection<LibraryResource> getResources() {
- return Collections.singleton(TEST_RESOURCE);
- }
-
- public String getName() {
- return FOO;
- }
-
- public String createCallScript(String clientId,String sourceId) {
- return FOO+"("+clientId+")";
- }
- };
-
- private String value=FOO_VALUE;
-
- /**
- * @return the value
- */
- public String getValue() {
- return value;
- }
-
- /**
- * @param value the value to set
- */
- public void setValue(String value) {
- this.value = value;
- }
-
- public String action() {
- FacesContext facesContext = FacesContext.getCurrentInstance();
- UIViewRoot viewRoot = facesContext.getViewRoot();
- UIValidatorScript resource = (UIValidatorScript) facesContext.getApplication().createComponent(UIValidatorScript.COMPONENT_TYPE);
- resource.addOrFindScript(SCRIPT );
- viewRoot.addComponentResource(facesContext, resource);
- return null;
- }
-
-
-}
Deleted: trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestScript.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestScript.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/TestScript.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,61 +0,0 @@
-package org.richfaces.component;
-
-import org.richfaces.renderkit.html.LibraryScriptString;
-import org.richfaces.validator.LibraryResource;
-
-final class TestScript implements LibraryScriptString {
- private final String name;
-
- TestScript(String name) {
- this.name = name;
- }
-
- public String toScript() {
- return name;
- }
-
- public void appendScript(StringBuffer functionString) {
- functionString.append(name);
-
- }
-
- public LibraryResource getResource() {
- return UIValidatorScriptCollectionTest.FOO_RESOURCE;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((name == null) ? 0 : name.hashCode());
- return result;
- }
-
- /* (non-Javadoc)
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- TestScript other = (TestScript) obj;
- if (name == null) {
- if (other.name != null) {
- return false;
- }
- } else if (!name.equals(other.name)) {
- return false;
- }
- return true;
- }
-}
\ No newline at end of file
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIValidatorScriptCollectionTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIValidatorScriptCollectionTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIValidatorScriptCollectionTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -8,8 +8,8 @@
import org.junit.Test;
import org.richfaces.renderkit.html.ClientOnlyScript;
import org.richfaces.renderkit.html.ComponentValidatorScript;
-import org.richfaces.renderkit.html.LibraryScriptString;
import org.richfaces.validator.LibraryResource;
+import org.richfaces.validator.LibraryScriptString;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -59,7 +59,7 @@
}
private LibraryScriptString createLibraryScript(final String name) {
- return new TestScript(name);
+ return new Script(name);
}
private ComponentValidatorScript createValidatorScript(String converter, String ...validators){
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIViewResourceTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIViewResourceTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/UIViewResourceTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -49,20 +49,20 @@
FacesRequest request = environment.createFacesRequest("http://localhost/test.jsf?foo=bar");
assertNotNull(request.execute());
String contentAsString = request.getConnection().getContentAsString();
- assertFalse(contentAsString.contains(TestBean.TEST_SCRIPT));
+ assertFalse(contentAsString.contains(Bean.TEST_SCRIPT));
FacesRequest request2 = submit(request).submit();
request2.execute();
String content2 = request2.getConnection().getContentAsString();
- assertFalse(content2.contains(TestBean.TEST_SCRIPT));
+ assertFalse(content2.contains(Bean.TEST_SCRIPT));
}
private FacesRequest submit(FacesRequest request) throws MalformedURLException {
FacesRequest request2 = request.submit().withParameter("helloForm:input", "BAZ").withParameter("helloForm:command", "Ok");
request2.execute();
String content2 = request2.getConnection().getContentAsString();
- assertTrue(content2.contains(TestBean.TEST_SCRIPT));
- assertTrue(content2.contains(TestBean.TEST_SCRIPT_NAME));
- assertTrue(content2.contains(TestBean.FOO_BAR));
+ assertTrue(content2.contains(Bean.TEST_SCRIPT));
+ assertTrue(content2.contains(Bean.TEST_SCRIPT_NAME));
+ assertTrue(content2.contains(Bean.FOO_BAR));
return request2;
}
Deleted: trunk/ui/validator/ui/src/test/java/org/richfaces/component/behavior/ClientValidatorBehaviorTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/component/behavior/ClientValidatorBehaviorTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/component/behavior/ClientValidatorBehaviorTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,180 +0,0 @@
-package org.richfaces.component.behavior;
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.faces.FacesException;
-import javax.faces.component.UIComponent;
-import javax.faces.component.UIForm;
-import javax.faces.component.UIInput;
-import javax.faces.component.UIOutput;
-import javax.faces.component.UIViewRoot;
-import javax.faces.component.behavior.ClientBehaviorContext;
-import javax.faces.context.FacesContext;
-import javax.faces.convert.Converter;
-
-import org.jboss.test.faces.mock.Environment;
-import org.jboss.test.faces.mock.Mock;
-import org.jboss.test.faces.mock.MockController;
-import org.jboss.test.faces.mock.MockFacesEnvironment;
-import org.jboss.test.faces.mock.MockTestRunner;
-import org.jboss.test.faces.mock.Stub;
-import org.jboss.test.faces.mock.Environment.Feature;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.richfaces.component.behavior.ClientValidatorBehavior;
-import org.richfaces.component.mock.MockUIForm;
-import org.richfaces.component.mock.MockUIMessage;
-
-
-/**
- * <p class="changed_added_4_0">This class tests client validator behavior.
- * as it described at https://community.jboss.org/wiki/ClientSideValidation # Server-side rendering algorithm</p>
- * @author asmirnov(a)exadel.com
- *
- */
-(a)RunWith(MockTestRunner.class)
-public class ClientValidatorBehaviorTest {
-
- private static final String CLIENT_VALIDATION_FUNCTION = "rf.csv.v";
-
- private final class DummyConverter implements Converter {
- public String getAsString(FacesContext context, UIComponent component, Object value) {
- return value.toString();
- }
-
- public Object getAsObject(FacesContext context, UIComponent component, String value) {
- return value;
- }
- }
-
- private static final String FORM_ID = "formId";
-
- private static final String INPUT_ID = "inputId";
-
- private static final String MESSAGE_ID = "messageId";
-
- @Mock()
- @Environment({Feature.APPLICATION})
- protected MockFacesEnvironment environment;
-
- @Stub
- private UIOutput output;
-
- @Mock
- protected UIInput input;
-
- @Mock
- protected UIViewRoot root;
-
- @Mock
- protected MockUIForm form;
-
- @Mock
- protected MockUIMessage message;
-
- @Mock
- private ClientBehaviorContext behaviorContext;
-
- protected MockController controller;
-
- private ClientValidatorBehavior behavior;
-
- @Before
- public void setUp() {
- behavior = createBehavior();
- }
-
- /**
- * <p class="changed_added_4_0">Server-side rendering algorithm .1</p>
- */
- @Test(expected=FacesException.class)
- public void testGetScriptForIllegalComponent() {
- getScript(output);
- }
-
- /**
- * <p class="changed_added_4_0">Server-side rendering algorithm .2</p>
- * @throws Exception
- */
- @Test
- public void testGetScriptWithoutMessageComponent() throws Exception {
- buildForm(false);
- assertEquals(0, getScript(input).length());
- }
-
- /**
- * <p class="changed_added_4_0">Server-side rendering algorithm .3 - determine client-side converter</p>
- * @throws Exception
- */
- @Test
- public void testGetClientConverter() throws Exception {
-
- }
- /**
- * <p class="changed_added_4_0">Server-side rendering algorithm .3</p>
- * @throws Exception
- */
- @Test
- public void testGetScriptWithoutClientConverter() throws Exception {
- buildForm(true);
- expect(input.getConverter()).andStubReturn(new DummyConverter());
- String script = getScript(input);// ajax-only validator.
- assertFalse(script.contains(CLIENT_VALIDATION_FUNCTION));
- }
-
- /**
- * <p class="changed_added_4_0">Server-side rendering algorithm .3</p>
- * @throws Exception
- */
- @Test
- public void testGetScriptWithClientConverter() throws Exception {
-
- }
-
- private String getScript(UIComponent component) {
- ClientBehaviorContext clientBehaviorContext = setupBehaviorContext(component);
- controller.replay();
- String script = behavior.getScript(clientBehaviorContext);
- controller.verify();
- return script;
- }
-
- private ClientBehaviorContext setupBehaviorContext(UIComponent component) {
- expect(behaviorContext.getComponent()).andStubReturn(component);
- expect(behaviorContext.getFacesContext()).andStubReturn(environment.getFacesContext());
- return behaviorContext;
- }
-
- private void buildForm(boolean withMessage) {
- expect(environment.getFacesContext().getViewRoot()).andStubReturn(root);
- expect(form.getId()).andStubReturn(FORM_ID);
- List<UIComponent> formChildren = new ArrayList<UIComponent>();
- expect(form.getChildren()).andStubReturn(formChildren);
- expect(input.getId()).andStubReturn(INPUT_ID);
- expect(input.getParent()).andStubReturn(form);
- formChildren.add(input);
- expect(output.getParent()).andStubReturn(form);
- formChildren.add(output);
- if(withMessage){
- expect(message.getId()).andStubReturn(MESSAGE_ID);
- expect(message.getFor()).andStubReturn(INPUT_ID);
- expect(message.getParent()).andStubReturn(form);
- formChildren.add(message);
- }
-// root.getChildren().add(form);
- }
-
- private ClientValidatorBehavior createBehavior() {
- return new ClientValidatorBehavior();
- }
-
- @Test
- public void testDecode() {
- fail("Not yet implemented");
- }
-
-}
Deleted: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,334 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.richfaces.convert;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.text.MessageFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TimeZone;
-
-import javax.el.ExpressionFactory;
-import javax.el.ValueExpression;
-import javax.el.VariableMapper;
-import javax.faces.component.UIComponent;
-import javax.faces.component.html.HtmlInputText;
-import javax.faces.context.FacesContext;
-import javax.faces.convert.Converter;
-import javax.faces.convert.ConverterException;
-import javax.servlet.ServletRequestEvent;
-import javax.servlet.ServletRequestListener;
-
-import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
-
-import org.ajax4jsf.javascript.JSFunction;
-import org.ajax4jsf.javascript.ScriptUtils;
-import org.jboss.test.faces.htmlunit.HtmlUnitEnvironment;
-import org.jboss.test.faces.jetty.JettyServer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.runner.RunWith;
-import org.richfaces.application.MessageFactory;
-import org.richfaces.application.ServiceTracker;
-
-import com.gargoylesoftware.htmlunit.ScriptResult;
-import com.gargoylesoftware.htmlunit.html.HtmlPage;
-import com.google.common.base.Strings;
-
-/**
- * @author Nick Belaevski
- *
- */
-(a)RunWith(BaseConverterTestRunner.class)
-public abstract class BaseConverterTest {
-
- public static final String TEST_COMPONENT_LABEL = "input";
-
- public class TestBean {
-
- private static final String CONVERTER_VAR = "__converter";
-
- private String converterId;
-
- private String clientConverterClassName;
-
- private String convertedValueAsScript;
-
- private String conversionErrorMessage;
-
- private Enum<?> conversionErrorMessageEnum;
-
- private ConverterException converterException;
-
- private Map<String, Object> attributes = new HashMap<String, Object>();
-
- private String converterParametersString;
-
- public void setClientConverterClassName(String clientConverterClassName) {
- this.clientConverterClassName = clientConverterClassName;
- }
-
- public String getClientConverterClassName() {
- return clientConverterClassName;
- }
-
- public void setConverterId(String converterId) {
- this.converterId = converterId;
- }
-
- public String getSubmittedValue() {
- return submittedValue;
- }
-
- public String getSubmittedValueAsScript() {
- return ScriptUtils.toScript(submittedValue);
- }
-
- public String getConversionErrorMessage() {
- return conversionErrorMessage;
- }
-
- public void setConversionErrorMessage(String conversionErrorMessage) {
- this.conversionErrorMessage = conversionErrorMessage;
- }
-
- public void setAttribute(String name, Object value) {
- attributes.put(name, value);
- }
-
- public String getConverterParametersString() {
- return converterParametersString;
- }
-
- public ConverterException getConverterException() {
- return converterException;
- }
-
- public void setConversionErrorMessageEnum(
- Enum<?> conversionErrorMessageEnum) {
- this.conversionErrorMessageEnum = conversionErrorMessageEnum;
- }
-
- private void configure(FacesContext facesContext, Converter converter) {
- ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
-
- VariableMapper varMapper = facesContext.getELContext().getVariableMapper();
- ValueExpression originalExpr = varMapper.resolveVariable(CONVERTER_VAR);
- try {
- varMapper.setVariable(CONVERTER_VAR, expressionFactory.createValueExpression(converter, Converter.class));
-
- for (Entry<String, Object> mapEntry: attributes.entrySet()) {
-
- String exprString = MessageFormat.format("#'{'{0}.{1}'}'", CONVERTER_VAR, mapEntry.getKey());
- ValueExpression ve = expressionFactory.createValueExpression(facesContext.getELContext(), exprString, Object.class);
-
- ve.setValue(facesContext.getELContext(), mapEntry.getValue());
- }
- } finally {
- varMapper.setVariable(CONVERTER_VAR, originalExpr);
- }
- }
-
- private Converter createConverter(FacesContext facesContext) {
- Converter converter = facesContext.getApplication().createConverter(converterId);
- configure(facesContext, converter);
- return converter;
- }
-
- private UIComponent createTestComponent() {
- HtmlInputText testComponent = new HtmlInputText();
- testComponent.setLabel(TEST_COMPONENT_LABEL);
- return testComponent;
- }
-
- public String getConvertedValueAsScript() {
- return convertedValueAsScript != null ? convertedValueAsScript : "null";
- }
-
- public void init() {
- if (converterId == null || clientConverterClassName == null) {
- throw new NullPointerException();
- }
-
- FacesContext facesContext = FacesContext.getCurrentInstance();
- Converter converter = createConverter(facesContext);
- try {
- Object convertedObject = converter.getAsObject(facesContext, createTestComponent(), submittedValue);
- convertedValueAsScript = serializeObjectToScript(convertedObject);
- } catch (ConverterException e) {
- this.converterException = e;
- }
-
- if (Strings.isNullOrEmpty(conversionErrorMessage) && conversionErrorMessageEnum != null) {
- MessageFactory messageFactory = ServiceTracker.getService(MessageFactory.class);
- conversionErrorMessage = messageFactory.getMessageFormat(facesContext, conversionErrorMessageEnum);
- }
-
- Map<String,Object> map = new HashMap<String, Object>(attributes);
- map.put("componentId", TEST_COMPONENT_LABEL);
- map.put("customMessage", MessageFormat.format(conversionErrorMessage , "{0}"));
-
- converterParametersString = ScriptUtils.toScript(map);
- }
- }
-
- private TestBean testBean;
-
- private HtmlUnitEnvironment environment;
-
- private String converterScriptName;
-
- private String submittedValue;
-
- private String failureMessage;
-
- public BaseConverterTest(String converterScriptName) {
- this.converterScriptName = converterScriptName;
- }
-
- @Before
- public void setUp() throws Exception {
- testBean = new TestBean();
-
- environment = new HtmlUnitEnvironment(new JettyServer());
- environment.getServer().addResource("/test.xhtml", BaseConverterTest.class.getResource("test.xhtml"));
- environment.getServer().addResource("/resources/converter.js", converterScriptName);
- environment.getServer().addWebListener(new ServletRequestListener() {
-
- public void requestInitialized(ServletRequestEvent sre) {
- sre.getServletRequest().setAttribute("testBean", testBean);
- }
-
- public void requestDestroyed(ServletRequestEvent sre) {
- }
- });
-
- environment.start();
- }
-
- @After
- public void tearDown() throws Exception {
- submittedValue = null;
- failureMessage = null;
-
- testBean = null;
-
- environment.release();
- environment = null;
- }
-
- protected String serializeObjectToScript(Object object) {
- if (object instanceof Date) {
- Calendar calendar = Calendar.getInstance();
- calendar.setTime((Date) object);
- calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
-
- return new JSFunction("new Date", calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
- calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR), calendar.get(Calendar.MINUTE),
- calendar.get(Calendar.SECOND), calendar.get(Calendar.MILLISECOND)).toScript();
- }
-
- return ScriptUtils.toScript(object);
- }
-
- public void setConversionErrorMessage(String conversionErrorMessage) {
- testBean.setConversionErrorMessage(conversionErrorMessage);
- }
-
- public void setConverterId(String converterId) {
- testBean.setConverterId(converterId);
- }
-
- public void setClientConverterClassName(String clientConverterClassName) {
- testBean.setClientConverterClassName(clientConverterClassName);
- }
-
- public void setAttribute(String name, Object value) {
- testBean.setAttribute(name, value);
- }
-
- public void setSubmittedValue(String submittedValue) {
- this.submittedValue = submittedValue;
- }
-
- public void setFailureMessage(String failureMessage) {
- this.failureMessage = failureMessage;
- }
-
- public void setConversionErrorMessageEnum(
- Enum<?> conversionErrorMessageEnum) {
- testBean.setConversionErrorMessageEnum(conversionErrorMessageEnum);
- }
-
- public void assertConversionOk() throws Exception {
- HtmlPage page = environment.getPage("/test.jsf");
- System.out.println(page.asXml());
- assertTrue(page.getWebClient().isJavaScriptEnabled());
- ScriptResult conversionMessageResult = page.executeJavaScript("verifyConversion()");
- if (!ScriptResult.isUndefined(conversionMessageResult)) {
- fail(conversionMessageResult.getJavaScriptResult().toString());
- }
- }
-
- public void assertConversionFailure() throws Exception {
- HtmlPage page = environment.getPage("/test.jsf");
-
- assertNotNull(testBean.getConverterException());
-
- assertTrue(page.getWebClient().isJavaScriptEnabled());
- ScriptResult conversionErrorResult = page.executeJavaScript("window.conversionError");
-
- if (ScriptResult.isUndefined(conversionErrorResult)) {
- fail("converter has not thrown an error");
- return;
- }
-
- Object conversionErrorMessage;
-
- Object scriptResult = conversionErrorResult.getJavaScriptResult();
- if (scriptResult instanceof Scriptable) {
- Scriptable scriptable = (Scriptable) scriptResult;
- conversionErrorMessage = scriptable.get("message", scriptable);
- } else {
- conversionErrorMessage = scriptResult;
- }
-
- if (failureMessage != null) {
- assertEquals(failureMessage, conversionErrorMessage);
- } else {
- assertEquals(testBean.getConverterException().getMessage(), conversionErrorMessage);
- }
- }
-
- public void setup(TestData testData) {
- setSubmittedValue(testData.submittedValue());
- setFailureMessage(testData.failureMessage());
- }
-
-}
Deleted: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTestRunner.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTestRunner.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/BaseConverterTestRunner.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -1,198 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.richfaces.convert;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.junit.Test;
-import org.junit.internal.runners.model.ReflectiveCallable;
-import org.junit.runner.Runner;
-import org.junit.runner.notification.RunNotifier;
-import org.junit.runners.BlockJUnit4ClassRunner;
-import org.junit.runners.Suite;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.InitializationError;
-import org.junit.runners.model.Statement;
-import org.junit.runners.model.TestClass;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-
-/**
- * @author Nick Belaevski
- *
- */
-public class BaseConverterTestRunner extends Suite {
-
- private static final class ParameterizedFrameworkMethod extends FrameworkMethod {
-
- private TestData testData;
-
- private boolean failure;
-
- public ParameterizedFrameworkMethod(Method method, TestData testData, boolean failure) {
- super(method);
- this.testData = testData;
- this.failure = failure;
- }
-
- public String getFormattedParameters() {
- if (testData == null) {
- return "no test data";
- }
-
- StringBuilder sb = new StringBuilder();
-
- if (failure) {
- sb.append("<failure>");
- } else {
- sb.append("<success>");
- }
-
- sb.append(" @TestData {");
-
- sb.append("submittedValue=" + testData.submittedValue());
-
- if (!Strings.isNullOrEmpty(testData.failureMessage())) {
- sb.append(", failureMessage=" + testData.failureMessage());
- }
-
- sb.append("}");
-
- return sb.toString();
- }
-
- @Override
- public Object invokeExplosively(final Object target, final Object... params) throws Throwable {
- return new ReflectiveCallable() {
- @Override
- protected Object runReflectiveCall() throws Throwable {
- BaseConverterTest baseConverterTest = (BaseConverterTest) target;
-
- baseConverterTest.setSubmittedValue(testData.submittedValue());
-
- if (!Strings.isNullOrEmpty(testData.failureMessage())) {
- baseConverterTest.setFailureMessage(testData.failureMessage());
- }
-
- Object returnValue = getMethod().invoke(target, params);
-
- if (failure) {
- baseConverterTest.assertConversionFailure();
- } else {
- baseConverterTest.assertConversionOk();
- }
-
- return returnValue;
- }
- }.run();
- }
- }
-
- private class ParameterizedTestRunner extends BlockJUnit4ClassRunner {
-
- private String testMethodName;
-
- private List<FrameworkMethod> children = Lists.newArrayList();
-
- public ParameterizedTestRunner(Class<?> klass, FrameworkMethod testMethod)
- throws InitializationError {
-
- super(klass);
-
- this.testMethodName = testMethod.getName();
-
- TestDataHolder testDataHolder = testMethod.getAnnotation(TestDataHolder.class);
- if (testDataHolder != null) {
- for (TestData testData : testDataHolder.successes()) {
- children.add(new ParameterizedFrameworkMethod(testMethod.getMethod(), testData, false));
- }
-
- for (TestData testData : testDataHolder.failures()) {
- children.add(new ParameterizedFrameworkMethod(testMethod.getMethod(), testData, true));
- }
- } else {
- children.add(testMethod);
- }
- }
-
- @Override
- public Object createTest() throws Exception {
- return getTestClass().getOnlyConstructor().newInstance();
- }
-
- @Override
- protected String getName() {
- return testMethodName;
- }
-
- @Override
- protected String testName(final FrameworkMethod method) {
- if (method instanceof ParameterizedFrameworkMethod) {
- String formattedParamsString = ((ParameterizedFrameworkMethod) method).getFormattedParameters();
-
- return String.format("%s %s", testMethodName, formattedParamsString);
- }
-
- return testMethodName;
- }
-
- @Override
- protected void validateConstructor(List<Throwable> errors) {
- validateOnlyOneConstructor(errors);
- }
-
- @Override
- protected Statement classBlock(RunNotifier notifier) {
- return childrenInvoker(notifier);
- }
-
- @Override
- protected List<FrameworkMethod> getChildren() {
- return children;
- }
-
- }
-
- private final ArrayList<Runner> runners = new ArrayList<Runner>();
-
- /**
- * Only called reflectively. Do not use programmatically.
- */
- public BaseConverterTestRunner(Class<?> klass) throws Throwable {
- super(klass, Collections.<Runner>emptyList());
-
- TestClass testClass = getTestClass();
- List<FrameworkMethod> testMethods = testClass.getAnnotatedMethods(Test.class);
- for (FrameworkMethod testMethod: testMethods) {
- runners.add(new ParameterizedTestRunner(klass, testMethod));
- }
- }
-
- @Override
- protected List<Runner> getChildren() {
- return runners;
- }
-}
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/convert/DateTimeConverterTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -38,8 +38,8 @@
}
@Test
- @TestDataHolder(successes = { @TestData(submittedValue = "18-10-2010"),
- // @TestData(submittedValue = "17-10-2010")
+ @TestDataHolder(successes = { @TestData(submittedValue = "18-10-2010")
+ // ,@TestData(submittedValue = "17-10-2010")
}, failures = {
// @TestData(submittedValue = "10/17/2010")
})
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetClientSideScriptTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -20,7 +20,8 @@
import org.richfaces.application.ServiceTracker;
import org.richfaces.validator.ClientScriptService;
import org.richfaces.validator.ConverterDescriptor;
-import org.richfaces.validator.LibraryScript;
+import org.richfaces.validator.LibraryFunction;
+import org.richfaces.validator.LibraryScriptString;
import org.richfaces.validator.ScriptNotFoundException;
import org.richfaces.validator.ValidatorDescriptor;
@@ -40,7 +41,7 @@
private ClientScriptService scriptService;
@Mock
- private LibraryScript script;
+ private LibraryFunction script;
private Collection<ValidatorDescriptor> descriptors;
Modified: trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java
===================================================================
--- trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/java/org/richfaces/renderkit/html/RendererGetComponentScriptTest.java 2010-11-02 06:11:17 UTC (rev 19882)
@@ -40,7 +40,7 @@
@RunWith(MockTestRunner.class)
public class RendererGetComponentScriptTest extends RendererTestBase {
- private static final String JSF_AJAX_REQUEST = "jsf.ajax.request(this,event)";
+ private static final String JSF_AJAX_REQUEST = "jsf.ajax.request(element,event)";
private static final String NUMBER_CONVERTER = "numConverter";
@@ -87,6 +87,7 @@
private void exceptGetAjaxScript() {
expect(mockBehavior.getAjaxScript(behaviorContext)).andReturn(JSF_AJAX_REQUEST);
+ expect(behaviorContext.getSourceId()).andStubReturn("clientValidator");
}
/**
Modified: trunk/ui/validator/ui/src/test/resources/org/richfaces/component/WEB-INF/faces-config.xml
===================================================================
--- trunk/ui/validator/ui/src/test/resources/org/richfaces/component/WEB-INF/faces-config.xml 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/resources/org/richfaces/component/WEB-INF/faces-config.xml 2010-11-02 06:11:17 UTC (rev 19882)
@@ -2,7 +2,7 @@
<faces-config version="2.0" metadata-complete="false" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:cdk="http://jboss.org/schema/richfaces/cdk/extensions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<managed-bean>
<managed-bean-name>test</managed-bean-name>
- <managed-bean-class>org.richfaces.component.TestBean</managed-bean-class>
+ <managed-bean-class>org.richfaces.component.Bean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
\ No newline at end of file
Modified: trunk/ui/validator/ui/src/test/resources/org/richfaces/component/faces-config.xml
===================================================================
--- trunk/ui/validator/ui/src/test/resources/org/richfaces/component/faces-config.xml 2010-11-02 02:44:05 UTC (rev 19881)
+++ trunk/ui/validator/ui/src/test/resources/org/richfaces/component/faces-config.xml 2010-11-02 06:11:17 UTC (rev 19882)
@@ -2,7 +2,7 @@
<faces-config version="2.0" metadata-complete="false" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:cdk="http://jboss.org/schema/richfaces/cdk/extensions" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<managed-bean>
<managed-bean-name>test</managed-bean-name>
- <managed-bean-class>org.richfaces.component.TestBean</managed-bean-class>
+ <managed-bean-class>org.richfaces.component.Bean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
</faces-config>
\ No newline at end of file
14 years, 2 months
JBoss Rich Faces SVN: r19881 - in trunk: core/api/src/main/java/org/ajax4jsf/event and 30 other directories.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 22:44:05 -0400 (Mon, 01 Nov 2010)
New Revision: 19881
Added:
trunk/core/api/src/main/java/org/richfaces/application/push/
trunk/core/api/src/main/java/org/richfaces/application/push/EventAbortedException.java
trunk/core/api/src/main/java/org/richfaces/application/push/MessageDataSerializer.java
trunk/core/api/src/main/java/org/richfaces/application/push/MessageException.java
trunk/core/api/src/main/java/org/richfaces/application/push/PushContext.java
trunk/core/api/src/main/java/org/richfaces/application/push/PushContextFactory.java
trunk/core/api/src/main/java/org/richfaces/application/push/Request.java
trunk/core/api/src/main/java/org/richfaces/application/push/Session.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionFactory.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionManager.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionPreSubscriptionEvent.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionSubscriptionEvent.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicEvent.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicListener.java
trunk/core/api/src/main/java/org/richfaces/application/push/SessionUnsubscriptionEvent.java
trunk/core/api/src/main/java/org/richfaces/application/push/SubscriptionFailureException.java
trunk/core/api/src/main/java/org/richfaces/application/push/Topic.java
trunk/core/api/src/main/java/org/richfaces/application/push/TopicEvent.java
trunk/core/api/src/main/java/org/richfaces/application/push/TopicKey.java
trunk/core/api/src/main/java/org/richfaces/application/push/TopicListener.java
trunk/core/api/src/main/java/org/richfaces/application/push/TopicMode.java
trunk/core/api/src/main/java/org/richfaces/application/push/TopicsContext.java
trunk/core/impl/src/main/java/org/richfaces/application/push/
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextFactoryImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushHandlerImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/RequestImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/SessionImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicImpl.java
trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicsContextImpl.java
trunk/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java
trunk/examples/push-demo/
trunk/examples/push-demo/pom.xml
trunk/examples/push-demo/src/
trunk/examples/push-demo/src/main/
trunk/examples/push-demo/src/main/java/
trunk/examples/push-demo/src/main/java/demo/
trunk/examples/push-demo/src/main/java/demo/Channel.java
trunk/examples/push-demo/src/main/java/demo/ChannelsBean.java
trunk/examples/push-demo/src/main/java/demo/ChatBean.java
trunk/examples/push-demo/src/main/java/demo/HornetQInitializer.java
trunk/examples/push-demo/src/main/java/demo/TopicsInitializer.java
trunk/examples/push-demo/src/main/resources/
trunk/examples/push-demo/src/main/webapp/
trunk/examples/push-demo/src/main/webapp/META-INF/
trunk/examples/push-demo/src/main/webapp/META-INF/MANIFEST.MF
trunk/examples/push-demo/src/main/webapp/WEB-INF/
trunk/examples/push-demo/src/main/webapp/WEB-INF/faces-config.xml
trunk/examples/push-demo/src/main/webapp/WEB-INF/jboss-scanning.xml
trunk/examples/push-demo/src/main/webapp/WEB-INF/lib/
trunk/examples/push-demo/src/main/webapp/WEB-INF/web.xml
trunk/examples/push-demo/src/main/webapp/chat.xhtml
trunk/examples/push-demo/src/main/webapp/index.jsp
trunk/examples/push-demo/src/main/webapp/index.xhtml
trunk/examples/push-demo/src/main/webapp/resources/
trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java
trunk/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere/
trunk/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere/jquery-atmosphere.js
trunk/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
trunk/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
Removed:
trunk/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java
trunk/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java
trunk/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java
trunk/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java
trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java
trunk/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java
trunk/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml
Modified:
trunk/bom/pom.xml
trunk/core/impl/pom.xml
trunk/core/impl/richfaces-suppressions.xml
trunk/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java
trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java
trunk/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js
trunk/core/impl/src/main/resources/META-INF/resources/richfaces-event.js
trunk/core/impl/src/main/resources/META-INF/resources/richfaces.js
trunk/examples/pom.xml
trunk/ui/common/ui/checkstyle-suppressions.xml
trunk/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java
trunk/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
Log:
https://jira.jboss.org/browse/RF-9158
Modified: trunk/bom/pom.xml
===================================================================
--- trunk/bom/pom.xml 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/bom/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -206,6 +206,18 @@
<artifactId>ehcache</artifactId>
<version>1.6.0</version>
</dependency>
+
+ <!-- Push dependencies -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <version>0.6.3</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.1</version>
+ </dependency>
</dependencies>
</dependencyManagement>
Deleted: trunk/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java
===================================================================
--- trunk/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,31 +0,0 @@
-/**
- * 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.event;
-
-import java.util.EventListener;
-import java.util.EventObject;
-
-public interface PushEventListener extends EventListener {
- public void onEvent(EventObject event);
-}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/EventAbortedException.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/EventAbortedException.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/EventAbortedException.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class EventAbortedException extends Exception {
+
+ private static final long serialVersionUID = -1546282468438542993L;
+
+ public EventAbortedException() {
+ super();
+ }
+
+ public EventAbortedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public EventAbortedException(String message) {
+ super(message);
+ }
+
+ public EventAbortedException(Throwable cause) {
+ super(cause);
+ }
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/MessageDataSerializer.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/MessageDataSerializer.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/MessageDataSerializer.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+//TODO - byte message serializer?
+public interface MessageDataSerializer {
+
+ public static final String MESSAGE_ATTRIBUTE_NAME = MessageDataSerializer.class.getName();
+
+ public String serialize(Object data);
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/MessageException.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/MessageException.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/MessageException.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class MessageException extends Exception {
+
+ private static final long serialVersionUID = -8684363449647232385L;
+
+ public MessageException() {
+ super();
+ }
+
+ public MessageException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public MessageException(String message) {
+ super(message);
+ }
+
+ public MessageException(Throwable cause) {
+ super(cause);
+ }
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/PushContext.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/PushContext.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/PushContext.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface PushContext {
+
+ public static final String INSTANCE_KEY_NAME = PushContext.class.getName();
+
+ public TopicsContext getTopicsContext();
+
+ public SessionFactory getSessionFactory();
+
+ public SessionManager getSessionManager();
+
+ public void init(FacesContext facesContext);
+
+ public void destroy();
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/PushContextFactory.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/PushContextFactory.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/PushContextFactory.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface PushContextFactory {
+
+ public PushContext getPushContext();
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/Request.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/Request.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/Request.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import java.io.IOException;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface Request {
+
+ //TODO expose request/session/application maps
+
+ public void flushMessages() throws IOException;
+
+ //TODO suspend with timeout?
+ public void suspend() throws IOException;
+
+ public void resume() throws IOException;
+
+ public Session getSession();
+
+ public boolean isSuspended();
+
+ public boolean isPolling();
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/Session.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/Session.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/Session.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import java.util.Map;
+
+import com.google.common.collect.Multimap;
+
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface Session {
+
+ public int getMaxInactiveInterval();
+
+ public long getLastAccessedTime();
+
+ public String getId();
+
+ public Multimap<TopicKey, TopicKey> getSuccessfulSubscriptions();
+
+ public Map<TopicKey, String> getFailedSubscriptions();
+
+ public void subscribe(String[] topics);
+
+ public void connect(Request request) throws Exception;
+
+ public void disconnect() throws Exception;
+
+ public void onRequestSuspended();
+
+ public void onRequestDisconnected();
+
+ public void onRequestResumed();
+
+ public void destroy();
+
+ public Request getRequest();
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionFactory.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionFactory.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionFactory.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface SessionFactory {
+
+ public Session createSession(String pushSessionId);
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionManager.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionManager.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionManager.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface SessionManager {
+
+ public void putPushSession(Session pushSession) throws IllegalStateException;
+
+ public Session getPushSession(String id);
+
+ public void removePushSession(Session session);
+
+ public void requeue(Session session);
+
+ public void destroy();
+
+}
\ No newline at end of file
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionPreSubscriptionEvent.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionPreSubscriptionEvent.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionPreSubscriptionEvent.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SessionPreSubscriptionEvent extends SessionTopicEvent {
+
+ private static final long serialVersionUID = 2741390800212036457L;
+
+ public SessionPreSubscriptionEvent(Topic topic, TopicKey topicKey, Session session) {
+ super(topic, topicKey, session);
+ }
+
+ @Override
+ public void invokeListener(TopicListener listener) throws EventAbortedException {
+ ((SessionTopicListener) listener).processPreSubscriptionEvent(this);
+ }
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionSubscriptionEvent.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionSubscriptionEvent.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionSubscriptionEvent.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SessionSubscriptionEvent extends SessionTopicEvent {
+
+ private static final long serialVersionUID = -463481692840464586L;
+
+ public SessionSubscriptionEvent(Topic topic, TopicKey topicKey, Session session) {
+ super(topic, topicKey, session);
+ }
+
+ @Override
+ public void invokeListener(TopicListener listener) throws EventAbortedException {
+ ((SessionTopicListener) listener).processSubscriptionEvent(this);
+ }
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicEvent.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicEvent.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicEvent.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class SessionTopicEvent extends TopicEvent {
+
+ private static final long serialVersionUID = 6339351737472180503L;
+
+ private Session session;
+
+ private TopicKey topicKey;
+
+ public SessionTopicEvent(Topic topic, TopicKey topicKey, Session session) {
+ super(topic);
+ this.topicKey = topicKey;
+ this.session = session;
+ }
+
+ public Session getSession() {
+ return session;
+ }
+
+ public TopicKey getTopicKey() {
+ return topicKey;
+ }
+
+ @Override
+ public boolean isAppropriateListener(TopicListener listener) {
+ return (listener instanceof SessionTopicListener);
+ }
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicListener.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicListener.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionTopicListener.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface SessionTopicListener extends TopicListener {
+
+ public void processPreSubscriptionEvent(SessionPreSubscriptionEvent event) throws EventAbortedException;
+
+ public void processSubscriptionEvent(SessionSubscriptionEvent event) throws EventAbortedException;
+
+ public void processUnsubscriptionEvent(SessionUnsubscriptionEvent event) throws EventAbortedException;
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SessionUnsubscriptionEvent.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SessionUnsubscriptionEvent.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SessionUnsubscriptionEvent.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,41 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SessionUnsubscriptionEvent extends SessionTopicEvent {
+
+ private static final long serialVersionUID = -2286664647234464678L;
+
+ public SessionUnsubscriptionEvent(Topic topic, TopicKey topicKey, Session session) {
+ super(topic, topicKey, session);
+ }
+
+ @Override
+ public void invokeListener(TopicListener listener) throws EventAbortedException {
+ ((SessionTopicListener) listener).processUnsubscriptionEvent(this);
+ }
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/SubscriptionFailureException.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/SubscriptionFailureException.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/SubscriptionFailureException.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,40 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SubscriptionFailureException extends Exception {
+
+ private static final long serialVersionUID = -2070837902276133333L;
+
+ public SubscriptionFailureException() {
+ super();
+ }
+
+ public SubscriptionFailureException(String message) {
+ super(message);
+ }
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/Topic.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/Topic.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/Topic.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,46 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface Topic {
+
+ public TopicKey getKey();
+
+ public MessageDataSerializer getMessageDataSerializer();
+
+ public void setMessageDataSerializer(MessageDataSerializer serializer);
+
+ public void addTopicListener(TopicListener topicListener);
+
+ public void removeTopicListener(TopicListener topicListener);
+
+ public void publishEvent(TopicEvent event) throws EventAbortedException;
+
+ public void publish(String subtopic, Object messageData) throws MessageException;
+
+}
\ No newline at end of file
Added: trunk/core/api/src/main/java/org/richfaces/application/push/TopicEvent.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/TopicEvent.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/TopicEvent.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import java.util.EventObject;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TopicEvent extends EventObject {
+
+ private static final long serialVersionUID = 1986841627148973279L;
+
+ public TopicEvent(Topic topic) {
+ super(topic);
+ }
+
+ public Topic getTopic() {
+ return (Topic) source;
+ }
+
+ public boolean isAppropriateListener(TopicListener listener) {
+ return false;
+ }
+
+ public void invokeListener(TopicListener listener) throws EventAbortedException {
+ throw new IllegalArgumentException(listener.getClass().getName());
+ }
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/TopicKey.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/TopicKey.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/TopicKey.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,169 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import java.io.Serializable;
+import java.util.regex.Pattern;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TopicKey implements Serializable {
+
+ public static final char SUBCHANNEL_SEPARATOR = '@';
+
+ private static final Function<String, TopicKey> FACTORY = new Function<String, TopicKey>() {
+ public TopicKey apply(String from) {
+ return new TopicKey(from);
+ };
+ };
+
+ private static final Function<TopicKey, String> TO_ADDRESS = new Function<TopicKey, String>() {
+ public String apply(TopicKey from) {
+ return from.getTopicAddress();
+ };
+ };
+
+ private static final long serialVersionUID = -6967010810728932698L;
+
+ private static final Pattern NAME_PATTERN = Pattern.compile("[a-zA-Z0-9_]+");
+
+ private static final Joiner AT_JOINER = Joiner.on(SUBCHANNEL_SEPARATOR).skipNulls();
+
+ private final String topicName;
+
+ private final String subtopicName;
+
+ public TopicKey(String topicAddress) {
+ this(getTopicName(topicAddress), getSubtopicName(topicAddress));
+ }
+
+ public TopicKey(String topicName, String subtopicName) {
+ super();
+
+ if (topicName == null) {
+ throw new NullPointerException();
+ }
+
+ this.topicName = topicName;
+ this.subtopicName = subtopicName;
+
+ if (!NAME_PATTERN.matcher(topicName).matches()) {
+ throw new IllegalArgumentException(topicName);
+ }
+
+ if (subtopicName != null && !NAME_PATTERN.matcher(subtopicName).matches()) {
+ throw new IllegalArgumentException(subtopicName);
+ }
+ }
+
+ public static Function<String, TopicKey> factory() {
+ return FACTORY;
+ }
+
+ public static Function<TopicKey, String> toAddress() {
+ return TO_ADDRESS;
+ }
+
+ private static String getTopicName(String topicAddress) {
+ int idx = topicAddress.indexOf(SUBCHANNEL_SEPARATOR);
+
+ if (idx < 0) {
+ return topicAddress;
+ }
+
+ return topicAddress.substring(idx + 1);
+ }
+
+ private static String getSubtopicName(String topicAddress) {
+ int idx = topicAddress.indexOf(SUBCHANNEL_SEPARATOR);
+
+ if (idx < 0) {
+ return null;
+ }
+
+ return topicAddress.substring(0, idx);
+ }
+
+ public String getTopicName() {
+ return topicName;
+ }
+
+ public String getSubtopicName() {
+ return subtopicName;
+ }
+
+ public String getTopicAddress() {
+ return AT_JOINER.join(subtopicName, topicName);
+ }
+
+ public TopicKey getRootTopicKey() {
+ if (getSubtopicName() == null) {
+ return this;
+ } else {
+ return new TopicKey(getTopicName(), null);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((subtopicName == null) ? 0 : subtopicName.hashCode());
+ result = prime * result + ((topicName == null) ? 0 : topicName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ TopicKey other = (TopicKey) obj;
+ if (subtopicName == null) {
+ if (other.subtopicName != null) {
+ return false;
+ }
+ } else if (!subtopicName.equals(other.subtopicName)) {
+ return false;
+ }
+ if (topicName == null) {
+ if (other.topicName != null) {
+ return false;
+ }
+ } else if (!topicName.equals(other.topicName)) {
+ return false;
+ }
+ return true;
+ }
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/TopicListener.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/TopicListener.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/TopicListener.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import java.util.EventListener;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface TopicListener extends EventListener {
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/TopicMode.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/TopicMode.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/TopicMode.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public enum TopicMode {
+
+ flash, persistent, persistentLast
+
+}
Added: trunk/core/api/src/main/java/org/richfaces/application/push/TopicsContext.java
===================================================================
--- trunk/core/api/src/main/java/org/richfaces/application/push/TopicsContext.java (rev 0)
+++ trunk/core/api/src/main/java/org/richfaces/application/push/TopicsContext.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push;
+
+import java.text.MessageFormat;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.richfaces.application.ServiceTracker;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+//TODO annotations for declarative topics registration
+public abstract class TopicsContext {
+
+ private ConcurrentMap<String, Topic> topics = new ConcurrentHashMap<String, Topic>();
+
+ protected abstract Topic createTopic(TopicKey key);
+
+ public Topic getOrCreateTopic(TopicKey key) {
+ Topic result = topics.get(key.getTopicName());
+
+ if (result == null) {
+ Topic newTopic = createTopic(key);
+ result = topics.putIfAbsent(key.getTopicName(), newTopic);
+ if (result == null) {
+ result = newTopic;
+ }
+ }
+
+ return result;
+ }
+
+ public Topic getTopic(TopicKey key) {
+ Topic topic = topics.get(key.getTopicName());
+
+ if (topic == null) {
+ //TODO
+ }
+
+ return topic;
+ }
+
+ public void removeTopic(TopicKey key) {
+ topics.remove(key.getTopicName());
+ }
+
+ public void publish(TopicKey key, Object data) throws MessageException {
+ Topic topic = getTopic(key);
+
+ if (topic == null) {
+ throw new MessageException(MessageFormat.format("Topic {0} not found", key.getTopicAddress()));
+ }
+
+ topic.publish(key.getSubtopicName(), data);
+ }
+
+ public static TopicsContext lookup() {
+ return ServiceTracker.getService(PushContextFactory.class).getPushContext().getTopicsContext();
+ }
+
+}
Modified: trunk/core/impl/pom.xml
===================================================================
--- trunk/core/impl/pom.xml 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -87,6 +87,18 @@
<optional>true</optional>
</dependency>
+ <!-- Push dependencies -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <optional>true</optional>
+ </dependency>
+
<!-- Test Dependencies -->
<dependency>
<groupId>org.jboss.test-jsf</groupId>
Modified: trunk/core/impl/richfaces-suppressions.xml
===================================================================
--- trunk/core/impl/richfaces-suppressions.xml 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/richfaces-suppressions.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -16,4 +16,5 @@
<suppress checks="IllegalCatch" files="ResourceHandlerImpl.java" />
<suppress checks="IllegalThrows" files="AbstractThreadedTest.java" />
<suppress checks="ModifiedControlVariable" files="URLCodec.java" />
+ <suppress checks="IllegalCatch" files="AbstractRequest.java" />
</suppressions>
Deleted: trunk/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java
===================================================================
--- trunk/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,53 +0,0 @@
-/**
- * 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.webapp;
-
-import java.io.Serializable;
-import java.util.EventObject;
-
-import org.ajax4jsf.event.PushEventListener;
-
-public class PushEventsCounter implements PushEventListener, Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = 4060284352186710009L;
- private volatile boolean performed = false;
-
- public void onEvent(EventObject event) {
- performed = true;
- }
-
- /**
- * @return the performed
- */
- public boolean isPerformed() {
- return performed;
- }
-
- /**
- */
- public void processed() {
- this.performed = false;
- }
-}
Modified: trunk/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -70,6 +70,18 @@
staticResourceLocation,
@ConfigurationItem(defaultValue = "true", names = "org.richfaces.executeAWTInitializer", literal = true)
- executeAWTInitializer
+ executeAWTInitializer,
+
+ @ConfigurationItem(defaultValue = "/ConnectionFactory", names = "org.richfaces.push.jms.connectionFactory")
+ pushJMSConnectionFactory,
+
+ @ConfigurationItem(defaultValue = "/topic", names = "org.richfaces.push.jms.topicsNamespace")
+ pushJMSTopicsNamespace,
+
+ @ConfigurationItem(defaultValue = "", names = "org.richfaces.push.jms.connectionUsername")
+ pushJMSConnectionUsername,
+
+ @ConfigurationItem(defaultValue = "", names = "org.richfaces.push.jms.connectionPassword")
+ pushJMSConnectionPassword
}
}
Modified: trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/src/main/java/org/richfaces/application/DefaultModule.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -2,6 +2,8 @@
import org.richfaces.application.configuration.ConfigurationService;
import org.richfaces.application.configuration.ConfigurationServiceImpl;
+import org.richfaces.application.push.PushContextFactory;
+import org.richfaces.application.push.impl.jms.PushContextFactoryImpl;
import org.richfaces.cache.Cache;
import org.richfaces.l10n.BundleLoader;
import org.richfaces.renderkit.AjaxDataSerializer;
@@ -25,6 +27,7 @@
factory.setInstance(DependencyInjector.class, new DependencyInjectionServiceImpl());
factory.setInstance(MessageFactory.class, new MessageFactoryImpl(new BundleLoader()));
factory.setInstance(ResourceLibraryFactory.class, new ResourceLibraryFactoryImpl());
+ factory.setInstance(PushContextFactory.class, ServiceLoader.loadService(PushContextFactory.class, PushContextFactoryImpl.class));
}
}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,231 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ajax4jsf.javascript.JSLiteral;
+import org.ajax4jsf.javascript.ScriptString;
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.atmosphere.cpr.AtmosphereEventLifecycle;
+import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.atmosphere.cpr.AtmosphereResourceEventListener;
+import org.atmosphere.websocket.WebSocketSupport;
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractRequest implements Request {
+
+ private static final String TOPIC_KEY = "topic";
+
+ private static final String DATA_KEY = "data";
+
+ private static final int SUSPEND_TIMEOUT = 30 * 1000;
+
+ private static final class Message implements ScriptString {
+
+ private TopicKey topicKey;
+
+ private String serializedData;
+
+ public Message(TopicKey topicKey, String serializedData) {
+ super();
+ this.topicKey = topicKey;
+ this.serializedData = serializedData;
+ }
+
+ public String toScript() {
+ Map<String,Object> map = new HashMap<String, Object>(2);
+
+ map.put(TOPIC_KEY, topicKey.getTopicAddress());
+ map.put(DATA_KEY, new JSLiteral(serializedData));
+
+ return ScriptUtils.toScript(map);
+ }
+
+ public void appendScript(StringBuffer functionString) {
+ functionString.append(toScript());
+ }
+ }
+
+ private static final class FlushMessagesTask implements Runnable {
+
+ private Request request;
+
+ public FlushMessagesTask(Request request) {
+ super();
+ this.request = request;
+ }
+
+ public void run() {
+ try {
+ request.flushMessages();
+ } catch (Throwable e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ private final AtmosphereResourceEventListener resourceEventListener = new AtmosphereResourceEventListener() {
+
+ public void onSuspend(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event) {
+ AbstractRequest.this.onSuspend();
+ }
+
+ public void onResume(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event) {
+ AbstractRequest.this.onResume();
+ }
+
+ public void onDisconnect(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event) {
+ AbstractRequest.this.onDisconnect();
+ }
+
+ public void onBroadcast(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event) {
+ AbstractRequest.this.onBroadcast();
+ }
+ };
+
+ private final AtmosphereResource<HttpServletRequest, HttpServletResponse> atmosphereResource;
+
+ private final Session session;
+
+ private final ExecutorService executorService;
+
+ private final Queue<Message> messagesQueue = new ConcurrentLinkedQueue<Message>();
+
+ private AtomicBoolean submitted = new AtomicBoolean(false);
+
+ public AbstractRequest(AtmosphereResource<HttpServletRequest, HttpServletResponse> atmosphereResource, Session session,
+ ExecutorService executorService) {
+
+ super();
+
+ this.atmosphereResource = atmosphereResource;
+
+ ((AtmosphereEventLifecycle) atmosphereResource).addEventListener(resourceEventListener);
+
+ this.session = session;
+ this.executorService = executorService;
+ }
+
+ private void submitToWorker() {
+ if (submitted.compareAndSet(false, true)) {
+ executorService.submit(new FlushMessagesTask(this));
+ }
+ }
+
+ private String serializeMessages() {
+ return ScriptUtils.toScript(new ConsumingCollection<Message>(messagesQueue));
+ }
+
+ public void flushMessages() throws IOException {
+ String serializedMessages = serializeMessages();
+ PrintWriter writer = atmosphereResource.getResponse().getWriter();
+ writer.write(serializedMessages);
+ writer.flush();
+
+ submitted.compareAndSet(true, false);
+
+ if (isPolling()) {
+ atmosphereResource.resume();
+ } else if (!messagesQueue.isEmpty()) {
+ submitToWorker();
+ }
+ }
+
+ public void postMessage(TopicKey topicKey, String serializedMessage) {
+ messagesQueue.add(new Message(topicKey, serializedMessage));
+ submitToWorker();
+ }
+
+ public void suspend() throws IOException {
+ atmosphereResource.suspend(SUSPEND_TIMEOUT, isPolling());
+ }
+
+ public void resume() throws IOException {
+ atmosphereResource.resume();
+ }
+
+ public boolean isSuspended() {
+ return atmosphereResource.getAtmosphereResourceEvent().isSuspended();
+ }
+
+ public boolean isPolling() {
+ HttpServletRequest req = atmosphereResource.getRequest();
+ boolean isWebsocket = req.getAttribute(WebSocketSupport.WEBSOCKET_SUSPEND) != null ||
+ req.getAttribute(WebSocketSupport.WEBSOCKET_RESUME) != null;
+
+ //TODO how to detect non-polling transports?
+ return !isWebsocket;
+ }
+
+ public Session getSession() {
+ return session;
+ }
+
+ protected AtmosphereResource<HttpServletRequest, HttpServletResponse> getResource() {
+ return atmosphereResource;
+ }
+
+ protected void onSuspend() {
+ }
+
+ protected void onResume() {
+ try {
+ session.disconnect();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected void onDisconnect() {
+ try {
+ session.disconnect();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected void onBroadcast() {
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.io.IOException;
+
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionManager;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractSession implements Session {
+
+ private static final int MAX_INACTIVE_INTERVAL = 5 * 60 * 1000;
+
+ private final String id;
+
+ private final SessionManager sessionManager;
+
+ private volatile long lastAccessedTime;
+
+ private volatile Request request;
+
+ public AbstractSession(String id, SessionManager sessionManager) {
+ super();
+ this.id = id;
+ this.sessionManager = sessionManager;
+
+ resetLastAccessedTimeToCurrent();
+ }
+
+ private void resetLastAccessedTimeToCurrent() {
+ lastAccessedTime = System.currentTimeMillis();
+ }
+
+ private void requeue() {
+ resetLastAccessedTimeToCurrent();
+ sessionManager.requeue(this);
+ }
+
+ public void connect(Request request) throws Exception {
+ if (this.request != null) {
+ this.request.resume();
+ }
+
+ this.request = request;
+
+ requeue();
+
+ request.suspend();
+ }
+
+ public void disconnect() throws Exception {
+ this.request = null;
+ }
+
+ public long getLastAccessedTime() {
+ if (request != null) {
+ return System.currentTimeMillis();
+ }
+
+ return lastAccessedTime;
+ }
+
+ public int getMaxInactiveInterval() {
+ return MAX_INACTIVE_INTERVAL;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Request getRequest() {
+ return request;
+ }
+
+ public void destroy() {
+ if (request != null) {
+ try {
+ request.resume();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ request = null;
+ //TODO - clean up request
+ }
+
+ sessionManager.removePushSession(this);
+ // TODO Auto-generated method stub
+
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.richfaces.application.push.EventAbortedException;
+import org.richfaces.application.push.MessageDataSerializer;
+import org.richfaces.application.push.MessageException;
+import org.richfaces.application.push.Topic;
+import org.richfaces.application.push.TopicEvent;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicListener;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractTopic implements Topic {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private TopicKey key;
+
+ private volatile MessageDataSerializer serializer;
+
+ private volatile boolean allowSubtopics;
+
+ private List<TopicListener> listeners = new CopyOnWriteArrayList<TopicListener>();
+
+ public AbstractTopic(TopicKey key) {
+ super();
+ this.key = key;
+ }
+
+ public MessageDataSerializer getMessageDataSerializer() {
+ if (serializer == null) {
+ return DefaultMessageDataSerializer.instance();
+ }
+
+ return serializer;
+ }
+
+ public void setMessageDataSerializer(MessageDataSerializer serializer) {
+ this.serializer = serializer;
+ }
+
+ public boolean isAllowSubtopics() {
+ return allowSubtopics;
+ }
+
+ public void setAllowSubtopics(boolean allowSubtopics) {
+ this.allowSubtopics = allowSubtopics;
+ }
+
+ public TopicKey getKey() {
+ return key;
+ }
+
+ public void addTopicListener(TopicListener topicListener) {
+ listeners.add(topicListener);
+ }
+
+ public void removeTopicListener(TopicListener topicListener) {
+ listeners.remove(topicListener);
+ }
+
+ public void publishEvent(TopicEvent event) throws EventAbortedException {
+ for (TopicListener listener: listeners) {
+ if (event.isAppropriateListener(listener)) {
+ try {
+ event.invokeListener(listener);
+ } catch (EventAbortedException e) {
+ throw e;
+ } catch (Exception e) {
+ LOGGER.error(MessageFormat.format("Exception invoking listener: {0}", e.getMessage()), e);
+ }
+ }
+ }
+ }
+
+ public abstract void publish(String subtopic, Object messageData) throws MessageException;
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereHandler;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface AtmosphereHandlerProvider {
+
+ public AtmosphereHandler<HttpServletRequest, HttpServletResponse> getHandler();
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereHandler;
+import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionManager;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AtmospherePushHandler implements AtmosphereHandler<HttpServletRequest, HttpServletResponse> {
+
+ private static final ThreadFactory DAEMON_THREADS_FACTORY = new ThreadFactory() {
+
+ private final AtomicInteger threadsCounter = new AtomicInteger();
+
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, "rf-push-worker-thread-" + threadsCounter.getAndIncrement());
+ t.setDaemon(true);
+
+ return t;
+ }
+ };
+
+ private static final String PUSH_SESSION_ID_PARAM = "pushSessionId";
+
+ private SessionManager sessionManager;
+
+ private ExecutorService worker;
+
+ public AtmospherePushHandler() {
+ super();
+
+ sessionManager = new SessionManagerImpl(DAEMON_THREADS_FACTORY);
+ worker = Executors.newCachedThreadPool(DAEMON_THREADS_FACTORY);
+ }
+
+ public SessionManager getSessionManager() {
+ return sessionManager;
+ }
+
+ public void onRequest(AtmosphereResource<HttpServletRequest, HttpServletResponse> resource) throws IOException {
+ // TODO Auto-generated method stub
+
+ HttpServletRequest req = resource.getRequest();
+ HttpServletResponse resp = resource.getResponse();
+
+ String pushSessionId = req.getParameter(PUSH_SESSION_ID_PARAM);
+
+ Session session = null;
+
+ if (pushSessionId != null) {
+ session = getSessionManager().getPushSession(pushSessionId);
+ }
+
+ if (session == null) {
+ //TODO - debug log
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ resp.setContentType("text/plain");
+
+ try {
+ session.connect(createRequest(resource, session));
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void onStateChange(AtmosphereResourceEvent<HttpServletRequest, HttpServletResponse> event)
+ throws IOException {
+ //do nothing
+ }
+
+ protected abstract Request createRequest(AtmosphereResource<HttpServletRequest, HttpServletResponse> resource, Session session);
+
+ protected ExecutorService getWorker() {
+ return worker;
+ }
+
+ public void init(ServletConfig servletConfig) throws Exception {
+ }
+
+ public void destroy() throws Exception {
+ sessionManager.destroy();
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.util.AbstractCollection;
+import java.util.Iterator;
+import java.util.Queue;
+
+import com.google.common.collect.AbstractIterator;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class ConsumingCollection<T> extends AbstractCollection<T> {
+
+ private final class ConsumingIterator extends AbstractIterator<T> {
+ @Override
+ protected T computeNext() {
+ T next = queue.poll();
+ if (next == null) {
+ endOfData();
+ }
+ return next;
+ }
+ }
+
+ private Queue<T> queue;
+
+ public ConsumingCollection(Queue<T> queue) {
+ super();
+ this.queue = queue;
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return new ConsumingIterator();
+ }
+
+ @Override
+ public int size() {
+ return queue.size();
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,44 @@
+package org.richfaces.application.push.impl;
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.application.push.MessageDataSerializer;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public final class DefaultMessageDataSerializer implements MessageDataSerializer {
+
+ private static final MessageDataSerializer INSTANCE = new DefaultMessageDataSerializer();
+
+ private DefaultMessageDataSerializer() {}
+
+ public static MessageDataSerializer instance() {
+ return INSTANCE;
+ }
+
+ public String serialize(Object data) {
+ return ScriptUtils.toScript(data);
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ThreadFactory;
+
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionManager;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+import com.google.common.collect.MapMaker;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SessionManagerImpl implements SessionManager {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private final class SessionsExpirationRunnable implements Runnable {
+ public void run() {
+ while (true) {
+ try {
+ Session session = sessionQueue.take();
+ sessionMap.remove(session.getId());
+ session.destroy();
+ } catch (InterruptedException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ }
+ }
+
+ private ConcurrentMap<String, Session> sessionMap = new MapMaker().makeMap();
+
+ private SessionQueue sessionQueue = new SessionQueue();
+
+ public SessionManagerImpl(ThreadFactory threadFactory) {
+ threadFactory.newThread(new SessionsExpirationRunnable()).start();
+ }
+
+ public Session getPushSession(String id) {
+ return sessionMap.get(id);
+ }
+
+ public void removePushSession(Session session) {
+ sessionMap.remove(session.getId());
+ if (session != null) {
+ sessionQueue.remove(session);
+ }
+ }
+
+ public void destroy() {
+ //TODO notify all session
+ sessionQueue.clear();
+
+ while (!sessionMap.isEmpty()) {
+ for (Iterator<Session> sessionsItr = sessionMap.values().iterator(); sessionsItr.hasNext(); ) {
+ Session session = sessionsItr.next();
+ sessionsItr.remove();
+
+ session.destroy();
+ }
+ }
+
+ sessionMap.clear();
+ }
+
+ public void putPushSession(Session session) throws IllegalStateException {
+ Session existingSession = sessionMap.putIfAbsent(session.getId(), session);
+ if (existingSession != null) {
+ throw new IllegalStateException();
+ }
+
+ requeue(session);
+ }
+
+ public void requeue(Session session) {
+ sessionQueue.requeue(session);
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.util.Comparator;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.richfaces.application.push.Session;
+
+/**
+ * Based on DelayQueue by Doug Lea: http://gee.cs.oswego.edu/
+ * @author Nick Belaevski
+ *
+ */
+//TODO - optimize algorithm
+final class SessionQueue {
+
+ private static final Comparator<? super Session> SESSIONS_COMPARATOR = new Comparator<Session>() {
+
+ public int compare(Session o1, Session o2) {
+ Long delay1 = Long.valueOf(o1.getLastAccessedTime() + o1.getMaxInactiveInterval());
+ Long delay2 = Long.valueOf(o2.getLastAccessedTime() + o2.getMaxInactiveInterval());
+
+ return delay1.compareTo(delay2);
+ }
+
+ };
+
+ private final Queue<Session> queue = new PriorityQueue<Session>(1, SESSIONS_COMPARATOR);
+
+ private final ReentrantLock lock = new ReentrantLock();
+
+ private final Condition available = lock.newCondition();
+
+ private long getDelay(Session session, TimeUnit unit) {
+ return unit.convert(session.getLastAccessedTime() + session.getMaxInactiveInterval() - System.currentTimeMillis(),
+ TimeUnit.MILLISECONDS);
+ }
+
+ public Session take() throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ while (true) {
+ Session first = queue.peek();
+ if (first == null) {
+ available.await();
+ } else {
+ long delay = getDelay(first, TimeUnit.NANOSECONDS);
+ if (delay > 0) {
+ available.awaitNanos(delay);
+ } else {
+ Session x = queue.poll();
+ assert x != null;
+ if (queue.size() != 0) {
+ available.signalAll(); // wake up other takers
+ }
+ return x;
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ }
+
+ public void remove(Session session) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ queue.remove(session);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void requeue(Session session) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ queue.remove(session);
+
+ Session first = queue.peek();
+ queue.offer(session);
+ if (first == null || SESSIONS_COMPARATOR.compare(session, first) < 0) {
+ available.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void clear() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ queue.clear();
+ } finally {
+ lock.unlock();
+ }
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,172 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import javax.faces.context.FacesContext;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.Topic;
+import javax.jms.TopicSubscriber;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.servlet.ServletContext;
+
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.TopicKey;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class MessagingContext {
+
+ static final String SUBTOPIC_ATTRIBUTE_NAME = "rf_push_subtopic";
+
+ private static final Joiner OR_JOINER = Joiner.on(" OR ").skipNulls();
+
+ private static final Function<TopicKey, String> TOPIC_KEY_TO_MESSAGE_SELECTOR = new Function<TopicKey, String>() {
+ public String apply(TopicKey from) {
+ if (Strings.isNullOrEmpty(from.getSubtopicName())) {
+ return null;
+ }
+
+ return SUBTOPIC_ATTRIBUTE_NAME + " = '" + from.getSubtopicName() + "'";
+ }
+ };
+
+ private static final String SHARED_INSTANCE_KEY = MessagingContext.class.getName();
+
+ private final InitialContext initialContext;
+
+ private final Name connectionFactoryName;
+
+ private final Name topicsNamespace;
+
+ private final String applicationName;
+
+ private final String username;
+
+ private final String password;
+
+ private Connection connection;
+
+ public MessagingContext(InitialContext initialContext, Name connectionFactoryName, Name topicsNamespace,
+ String applicationName, String username, String password) {
+
+ super();
+ this.initialContext = initialContext;
+ this.connectionFactoryName = connectionFactoryName;
+ this.topicsNamespace = topicsNamespace;
+ this.applicationName = applicationName;
+ this.username = username;
+ this.password = password;
+ }
+
+ private Name appendToName(Name name, String comp) throws NamingException {
+ Name clonedName = (Name) name.clone();
+ return clonedName.add(comp);
+ }
+
+ public void start() throws Exception {
+ ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup(connectionFactoryName);
+
+ connection = connectionFactory.createConnection(username, password);
+
+ //TODO - review
+ try {
+ //durable subscription requires ClientID to be set
+ connection.setClientID(UUID.randomUUID().toString());
+ } catch (IllegalStateException e) {
+ //ignore - clientId has already been set
+ }
+
+ connection.start();
+ }
+
+ public void stop() throws Exception {
+ connection.stop();
+ connection = null;
+ }
+
+ public Connection getConnection() {
+ if (connection == null) {
+ throw new IllegalStateException("connection is absent");
+ }
+
+ return connection;
+ }
+
+ public Topic lookup(TopicKey topicKey) throws NamingException {
+ Name topicName = appendToName(topicsNamespace, topicKey.getTopicName());
+
+ return (Topic) initialContext.lookup(topicName);
+ }
+
+ public javax.jms.Session createSession() throws JMSException {
+ return connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
+ }
+
+ public String getSubscriptionClientId(Session session, TopicKey topicKey) {
+ //here TopicKey#topicName should be used, not TopicKey#topicAddress
+ return "rf-push:" + applicationName + ":" + topicKey.getTopicName() + ":" + session.getId();
+ }
+
+ public void shareInstance(FacesContext facesContext) {
+ Map<String, Object> applicationMap = facesContext.getExternalContext().getApplicationMap();
+ applicationMap.put(SHARED_INSTANCE_KEY, this);
+ }
+
+ public static MessagingContext getSharedInstance(ServletContext servletContext) {
+ return (MessagingContext) servletContext.getAttribute(SHARED_INSTANCE_KEY);
+ }
+
+ private String createMessageSelector(Iterable<TopicKey> topicKeys) {
+ Iterable<String> sqlStrings = Iterables.transform(topicKeys, TOPIC_KEY_TO_MESSAGE_SELECTOR);
+ return OR_JOINER.join(sqlStrings) + " OR false" /* workaround for HornetQ */;
+ }
+
+ public TopicSubscriber createTopicSubscriber(Session pushSession, javax.jms.Session jmsSession,
+ Entry<TopicKey, Collection<TopicKey>> entry)
+ throws JMSException, NamingException {
+
+ TopicKey rootTopicKey = entry.getKey();
+
+ String subscriptionClientId = getSubscriptionClientId(pushSession, rootTopicKey);
+
+ javax.jms.Topic jmsTopic = lookup(rootTopicKey);
+
+ return jmsSession.createDurableSubscriber(jmsTopic, subscriptionClientId, createMessageSelector(entry.getValue()), true);
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextFactoryImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextFactoryImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextFactoryImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import javax.faces.context.FacesContext;
+
+import org.richfaces.application.push.PushContext;
+import org.richfaces.application.push.PushContextFactory;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushContextFactoryImpl implements PushContextFactory {
+
+ private static final class PushContextHolder {
+
+ static final PushContext INSTANCE = createInstance();
+
+ private PushContextHolder() {
+ }
+
+ }
+
+ private static PushContext createInstance() {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+
+ PushContextImpl pushContext = new PushContextImpl();
+ pushContext.init(facesContext);
+
+ return pushContext;
+ }
+
+ public PushContext getPushContext() {
+ return PushContextHolder.INSTANCE;
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,145 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSConnectionFactory;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSConnectionPassword;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSConnectionUsername;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSTopicsNamespace;
+
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.PreDestroyApplicationEvent;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+import javax.naming.CompositeName;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereHandler;
+import org.richfaces.application.ServiceTracker;
+import org.richfaces.application.configuration.ConfigurationService;
+import org.richfaces.application.push.PushContext;
+import org.richfaces.application.push.SessionFactory;
+import org.richfaces.application.push.SessionManager;
+import org.richfaces.application.push.TopicsContext;
+import org.richfaces.application.push.impl.AtmosphereHandlerProvider;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushContextImpl implements PushContext, SystemEventListener, AtmosphereHandlerProvider {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private MessagingContext messagingContext;
+
+ private TopicsContext topicsContext;
+
+ private PushHandlerImpl pushHandlerImpl;
+
+ public TopicsContext getTopicsContext() {
+ return topicsContext;
+ }
+
+ private String getApplicationName(FacesContext facesContext) {
+ ServletContext servletContext = (ServletContext) facesContext.getExternalContext().getContext();
+ return servletContext.getContextPath();
+ }
+
+ public void init(FacesContext facesContext) {
+ try {
+ facesContext.getApplication().subscribeToEvent(PreDestroyApplicationEvent.class, this);
+ facesContext.getExternalContext().getApplicationMap().put(PushContext.INSTANCE_KEY_NAME, this);
+
+ ConfigurationService configurationService = ServiceTracker.getService(ConfigurationService.class);
+
+ InitialContext initialContext = new InitialContext();
+ Name cnfName = new CompositeName(configurationService.getStringValue(facesContext, pushJMSConnectionFactory));
+ Name topicsNamespace = new CompositeName(configurationService.getStringValue(facesContext, pushJMSTopicsNamespace));
+
+ messagingContext = new MessagingContext(initialContext, cnfName, topicsNamespace,
+ getApplicationName(facesContext),
+ configurationService.getStringValue(facesContext, pushJMSConnectionUsername),
+ configurationService.getStringValue(facesContext, pushJMSConnectionPassword));
+
+ messagingContext.shareInstance(facesContext);
+
+ messagingContext.start();
+
+ topicsContext = new TopicsContextImpl(messagingContext);
+
+ pushHandlerImpl = new PushHandlerImpl(messagingContext, topicsContext);
+ } catch (Exception e) {
+ throw new FacesException(e.getMessage(), e);
+ }
+ }
+
+ public void destroy() {
+ if (messagingContext != null) {
+ try {
+ messagingContext.stop();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ if (pushHandlerImpl != null) {
+ try {
+ pushHandlerImpl.destroy();
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ public void processEvent(SystemEvent event) throws AbortProcessingException {
+ if (event instanceof PreDestroyApplicationEvent) {
+ destroy();
+ } else {
+ throw new IllegalArgumentException(event.getClass().getName());
+ }
+ }
+
+ public boolean isListenerForSource(Object source) {
+ return true;
+ }
+
+ public SessionFactory getSessionFactory() {
+ return pushHandlerImpl;
+ }
+
+ public AtmosphereHandler<HttpServletRequest, HttpServletResponse> getHandler() {
+ return pushHandlerImpl;
+ }
+
+ public SessionManager getSessionManager() {
+ return pushHandlerImpl.getSessionManager();
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushHandlerImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushHandlerImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushHandlerImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereResource;
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionFactory;
+import org.richfaces.application.push.SessionManager;
+import org.richfaces.application.push.TopicsContext;
+import org.richfaces.application.push.impl.AtmospherePushHandler;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushHandlerImpl extends AtmospherePushHandler implements SessionFactory {
+
+ private MessagingContext messagingContext;
+
+ private TopicsContext topicsContext;
+
+ public PushHandlerImpl(MessagingContext messagingContext, TopicsContext topicsContext) {
+ super();
+ this.messagingContext = messagingContext;
+ this.topicsContext = topicsContext;
+ }
+
+ public Session createSession(String key) {
+ SessionManager sessionManager = getSessionManager();
+ Session session = new SessionImpl(key, sessionManager, messagingContext, topicsContext);
+ sessionManager.putPushSession(session);
+
+ return session;
+ }
+
+ @Override
+ protected Request createRequest(AtmosphereResource<HttpServletRequest, HttpServletResponse> resource,
+ Session session) {
+ return new RequestImpl(resource, session, getWorker(), messagingContext, topicsContext);
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/RequestImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/RequestImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/RequestImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,186 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutorService;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.ObjectMessage;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereResource;
+import org.richfaces.application.push.MessageDataSerializer;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicsContext;
+import org.richfaces.application.push.impl.AbstractRequest;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class RequestImpl extends AbstractRequest implements MessageListener {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private javax.jms.Session jmsSession;
+
+ private MessagingContext messagingContext;
+
+ private TopicsContext topicsContext;
+
+ public RequestImpl(AtmosphereResource<HttpServletRequest, HttpServletResponse> atmosphereResource, Session session,
+ ExecutorService executorService, MessagingContext messagingContext, TopicsContext topicsContext) {
+
+ super(atmosphereResource, session, executorService);
+
+ this.messagingContext = messagingContext;
+ this.topicsContext = topicsContext;
+ }
+
+ private void closeSession() {
+ if (jmsSession != null) {
+ try {
+ jmsSession.close();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ jmsSession = null;
+ }
+ }
+
+ @Override
+ public void onSuspend() {
+ super.onSuspend();
+
+ try {
+ jmsSession = messagingContext.createSession();
+
+ //TODO - remove this case
+ SessionImpl sessionImpl = (SessionImpl) getSession();
+
+ for (Entry<TopicKey, Collection<TopicKey>> entry: sessionImpl.getSuccessfulSubscriptions().asMap().entrySet()) {
+ messagingContext.createTopicSubscriber(sessionImpl, jmsSession, entry).setMessageListener(this);
+ }
+
+ } catch (Exception e) {
+ // TODO: handle exception
+ e.printStackTrace();
+ }
+
+ }
+
+ @Override
+ public void flushMessages() throws IOException {
+ if (isPolling()) {
+ closeSession();
+ }
+
+ super.flushMessages();
+ }
+
+ @Override
+ public void onDisconnect() {
+ closeSession();
+ super.onDisconnect();
+ }
+
+ @Override
+ public void onResume() {
+ closeSession();
+ super.onResume();
+ }
+
+ private String serializeMessage(org.richfaces.application.push.Topic topic, Message message) {
+ String serializedMessageData = null;
+ Object messageData = null;
+
+ try {
+ if (message instanceof ObjectMessage) {
+ messageData = ((ObjectMessage) message).getObject();
+ } else if (message instanceof TextMessage) {
+ TextMessage textMessage = (TextMessage) message;
+
+ if (message.getBooleanProperty(TopicImpl.SERIALIZED_DATA_INDICATOR)) {
+ serializedMessageData = textMessage.getText();
+ } else {
+ messageData = textMessage.getText();
+ }
+ }
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ if (serializedMessageData != null) {
+ return serializedMessageData;
+ }
+
+ if (messageData != null) {
+ MessageDataSerializer messageDataSerializer = topic.getMessageDataSerializer();
+ try {
+ return messageDataSerializer.serialize(messageData);
+ } catch (Exception e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see javax.jms.MessageListener#onMessage(javax.jms.Message)
+ */
+ public void onMessage(Message message) {
+ try {
+ String topicName = ((Topic) message.getJMSDestination()).getTopicName();
+
+ org.richfaces.application.push.Topic topic = topicsContext.getTopic(new TopicKey(topicName));
+ if (topic == null) {
+ //TODO log
+ return;
+ }
+
+ String serializedMessageData = serializeMessage(topic, message);
+ if (serializedMessageData == null) {
+ //TODO log
+ return;
+ }
+
+ postMessage(new TopicKey(topicName, message.getStringProperty(MessagingContext.SUBTOPIC_ATTRIBUTE_NAME)), serializedMessageData);
+
+ message.acknowledge();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/SessionImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/SessionImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/SessionImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,166 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.jms.JMSException;
+import javax.naming.NamingException;
+
+import org.richfaces.application.push.EventAbortedException;
+import org.richfaces.application.push.SessionManager;
+import org.richfaces.application.push.SessionPreSubscriptionEvent;
+import org.richfaces.application.push.Topic;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicsContext;
+import org.richfaces.application.push.impl.AbstractSession;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SessionImpl extends AbstractSession {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private final MessagingContext messagingContext;
+
+ private final TopicsContext topicsContext;
+
+ private final Multimap<TopicKey, TopicKey> successfulSubscriptions = ArrayListMultimap.<TopicKey, TopicKey>create();
+
+ private final Map<TopicKey, String> failedSubscriptions = Maps.newHashMap();
+
+ public SessionImpl(String id, SessionManager sessionManager, MessagingContext messagingContext, TopicsContext topicsContext) {
+ super(id, sessionManager);
+
+ this.messagingContext = messagingContext;
+ this.topicsContext = topicsContext;
+ }
+
+ public void onRequestSuspended() {
+ // TODO Auto-generated method stub
+ }
+
+ public void onRequestDisconnected() {
+ // TODO Auto-generated method stub
+ // TODO Auto-generated method stub
+ try {
+ disconnect();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void onRequestResumed() {
+ // TODO Auto-generated method stub
+ try {
+ disconnect();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public Map<TopicKey, String> getFailedSubscriptions() {
+ return failedSubscriptions;
+ }
+
+ public Multimap<TopicKey, TopicKey> getSuccessfulSubscriptions() {
+ return successfulSubscriptions;
+ }
+
+ private void createSubscriptions(Iterable<TopicKey> topicKeys) {
+ javax.jms.Session jmsSession = null;
+ try {
+ Multimap<TopicKey, TopicKey> rootTopicsMap = createRootTopicsKeysMap(topicKeys);
+
+ jmsSession = messagingContext.createSession();
+
+ for (Entry<TopicKey, Collection<TopicKey>> entry: rootTopicsMap.asMap().entrySet()) {
+ messagingContext.createTopicSubscriber(this, jmsSession, entry);
+
+ successfulSubscriptions.putAll(entry.getKey(), entry.getValue());
+ }
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ } catch (NamingException e) {
+ LOGGER.error(e.getMessage(), e);
+ } finally {
+ if (jmsSession != null) {
+ try {
+ jmsSession.close();
+ } catch (JMSException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+ private Multimap<TopicKey, TopicKey> createRootTopicsKeysMap(Iterable<TopicKey> topicKeys) {
+ Multimap<TopicKey, TopicKey> rootTopicKeys = ArrayListMultimap.<TopicKey, TopicKey>create();
+
+ for (TopicKey topicKey : topicKeys) {
+ rootTopicKeys.put(topicKey.getRootTopicKey(), topicKey);
+ }
+
+ return rootTopicKeys;
+ }
+
+ private void processFailedSubscriptions(Iterable<TopicKey> topicKeys) {
+ for (Iterator<TopicKey> itr = topicKeys.iterator(); itr.hasNext(); ) {
+ TopicKey topicKey = itr.next();
+
+ TopicKey rootTopicKey = topicKey.getRootTopicKey();
+ Topic pushTopic = topicsContext.getTopic(rootTopicKey);
+
+ try {
+ //TODO - publish another events
+ pushTopic.publishEvent(new SessionPreSubscriptionEvent(pushTopic, topicKey, this));
+ } catch (EventAbortedException e) {
+ itr.remove();
+ failedSubscriptions.put(topicKey, e.getMessage());
+ }
+ }
+ }
+
+ public void subscribe(String[] topics) {
+ Iterable<TopicKey> topicKeys = Iterables.transform(Lists.newLinkedList(Arrays.asList(topics)), TopicKey.factory());
+
+ processFailedSubscriptions(topicKeys);
+ createSubscriptions(topicKeys);
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,89 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import javax.jms.JMSException;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.NamingException;
+
+import org.richfaces.application.push.MessageException;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.impl.AbstractTopic;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+import com.google.common.base.Strings;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TopicImpl extends AbstractTopic {
+
+ static final String SERIALIZED_DATA_INDICATOR = "org_richfaces_push_SerializedData";
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private MessagingContext messagingContext;
+
+ public TopicImpl(TopicKey key, MessagingContext messagingContext) {
+ super(key);
+
+ this.messagingContext = messagingContext;
+ }
+
+ @Override
+ public void publish(String subtopic, Object messageData) throws MessageException {
+ String serializedData = getMessageDataSerializer().serialize(messageData);
+
+ Session session = null;
+ try {
+ session = messagingContext.createSession();
+ MessageProducer producer = session.createProducer(messagingContext.lookup(getKey()));
+
+ TextMessage textMessage = session.createTextMessage();
+ textMessage.setText(serializedData);
+ textMessage.setBooleanProperty(SERIALIZED_DATA_INDICATOR, true);
+
+ if (!Strings.isNullOrEmpty(subtopic)) {
+ textMessage.setStringProperty(MessagingContext.SUBTOPIC_ATTRIBUTE_NAME, subtopic);
+ }
+
+ producer.send(textMessage);
+ } catch (JMSException e) {
+ throw new MessageException(e.getMessage(), e);
+ } catch (NamingException e) {
+ throw new MessageException(e.getMessage(), e);
+ } finally {
+ if (session != null) {
+ try {
+ session.close();
+ } catch (JMSException e) {
+ LOGGER.debug(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicsContextImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicsContextImpl.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/application/push/impl/jms/TopicsContextImpl.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl.jms;
+
+import org.richfaces.application.push.Topic;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicsContext;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TopicsContextImpl extends TopicsContext {
+
+ private MessagingContext messagingContext;
+
+ public TopicsContextImpl(MessagingContext messagingContext) {
+ super();
+ this.messagingContext = messagingContext;
+ }
+
+ protected Topic createTopic(TopicKey key) {
+ return new TopicImpl(key, messagingContext);
+ }
+
+}
Added: trunk/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java (rev 0)
+++ trunk/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,159 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.webapp;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereServlet;
+import org.richfaces.application.push.PushContext;
+import org.richfaces.application.push.impl.AtmosphereHandlerProvider;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Sets;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+//TODO override broadcaster
+public class PushFilter implements Filter {
+
+ private static final String PUSH_HUB_MAPPING = "/*";
+
+ private static final long serialVersionUID = 7616370505508715222L;
+
+ /**
+ * @author Nick Belaevski
+ *
+ */
+ private final class ServletConfigFacade implements ServletConfig {
+ /**
+ *
+ */
+ private final FilterConfig filterConfig;
+
+ /**
+ * @param filterConfig
+ */
+ private ServletConfigFacade(FilterConfig filterConfig) {
+ this.filterConfig = filterConfig;
+ }
+
+ public String getServletName() {
+ return filterConfig.getFilterName();
+ }
+
+ public ServletContext getServletContext() {
+ return filterConfig.getServletContext();
+ }
+
+ public String getInitParameter(String name) {
+ String result = filterConfig.getInitParameter(name);
+
+ if (result == null) {
+ result = filterConfig.getServletContext().getInitParameter(name);
+ }
+
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Enumeration<String> getInitParameterNames() {
+ Set<String> result = Sets.newLinkedHashSet();
+
+ result.addAll(Collections.list(filterConfig.getInitParameterNames()));
+ result.addAll(Collections.list(filterConfig.getServletContext().getInitParameterNames()));
+
+ return Iterators.asEnumeration(result.iterator());
+ }
+ }
+
+ private AtmosphereServlet atmosphereServlet;
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+ AtmosphereHandlerProvider handlerProvider = (AtmosphereHandlerProvider) filterConfig.getServletContext().getAttribute(PushContext.INSTANCE_KEY_NAME);
+
+ if (handlerProvider == null) {
+ return;
+ }
+
+ atmosphereServlet = new AtmosphereServlet() {
+
+ private static final long serialVersionUID = -8719394110408476331L;
+
+ protected boolean detectSupportedFramework(ServletConfig sc) throws ClassNotFoundException, IllegalAccessException, InstantiationException ,NoSuchMethodException ,java.lang.reflect.InvocationTargetException {
+ return false;
+ };
+ };
+ ServletConfigFacade servletConfig = new ServletConfigFacade(filterConfig);
+ atmosphereServlet.init(servletConfig);
+
+ atmosphereServlet.addAtmosphereHandler(PUSH_HUB_MAPPING, handlerProvider.getHandler());
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
+ ServletException {
+
+ if (atmosphereServlet != null && request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
+ HttpServletRequest httpReq = (HttpServletRequest) request;
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+
+ if ("GET".equals(httpReq.getMethod()) && httpReq.getQueryString() != null && httpReq.getQueryString().contains("__richfacesPushAsync")) {
+ atmosphereServlet.doGet(httpReq, httpResp);
+ return;
+ }
+ }
+
+ // TODO Auto-generated method stub
+ chain.doFilter(request, response);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.Filter#destroy()
+ */
+ public void destroy() {
+ if (atmosphereServlet != null) {
+ atmosphereServlet.removeAtmosphereHandler(PUSH_HUB_MAPPING);
+ atmosphereServlet.destroy();
+ atmosphereServlet = null;
+ }
+ // TODO Auto-generated method stub
+ }
+
+}
Modified: trunk/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js
===================================================================
--- trunk/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/src/main/resources/META-INF/resources/richfaces-base-component.js 2010-11-02 02:44:05 UTC (rev 19881)
@@ -228,8 +228,11 @@
source = source || this.id;
var element = richfaces.getDomElement(source);
if (element) {
- element[richfaces.RICH_CONTAINER] = element[richfaces.RICH_CONTAINER] || {};
- element.richfaces.component = this;
+ element[richfaces.RICH_CONTAINER] = $.extend(element[richfaces.RICH_CONTAINER] || {},
+ {
+ component:this
+ }
+ );
}
return element;
},
Modified: trunk/core/impl/src/main/resources/META-INF/resources/richfaces-event.js
===================================================================
--- trunk/core/impl/src/main/resources/META-INF/resources/richfaces-event.js 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/src/main/resources/META-INF/resources/richfaces-event.js 2010-11-02 02:44:05 UTC (rev 19881)
@@ -32,6 +32,9 @@
var getHandlerWrapper = function (component, fn) {
return function (e,d){
+ if (!e[richfaces.RICH_CONTAINER]) {
+ e[richfaces.RICH_CONTAINER] = {data: d};
+ }
return fn.call(component||this, e, this, d);
};
}
@@ -52,6 +55,13 @@
* */
RICH_NAMESPACE : "RICH",
+ /**
+ * @constant
+ * @name RichFaces.Event.EVENT_NAMESPACE_SEPARATOR
+ * @type string
+ * */
+ EVENT_NAMESPACE_SEPARATOR : ".",
+
/**
* Attach an event handler to execute when the DOM is fully loaded.
*
@@ -215,7 +225,7 @@
* */
fire : function(selector, eventType, data) {
var event = $.Event(eventType);
- getEventElement(selector).trigger(eventType, data);
+ getEventElement(selector).trigger(event, data);
return !event.isDefaultPrevented();
},
@@ -287,7 +297,7 @@
if (id) {
a.push(id);
}
- return a.join('.');
+ return a.join(richfaces.Event.EVENT_NAMESPACE_SEPARATOR);
}
});
Modified: trunk/core/impl/src/main/resources/META-INF/resources/richfaces.js
===================================================================
--- trunk/core/impl/src/main/resources/META-INF/resources/richfaces.js 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/core/impl/src/main/resources/META-INF/resources/richfaces.js 2010-11-02 02:44:05 UTC (rev 19881)
@@ -13,7 +13,7 @@
(function(jQuery, richfaces) {
- richfaces.RICH_CONTAINER = "richfaces";
+ richfaces.RICH_CONTAINER = "rf";
// get DOM element by id or DOM element or jQuery object
richfaces.getDomElement = function (source) {
Modified: trunk/examples/pom.xml
===================================================================
--- trunk/examples/pom.xml 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/examples/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,4 +1,3 @@
-<<<<<<< .working
<?xml version="1.0" encoding="UTF-8"?>
<!--
JBoss, Home of Professional Open Source Copyright 2010, Red Hat,
@@ -47,8 +46,9 @@
<module>input-demo</module>
<module>repeater-demo</module>
<module>iteration-demo</module>
+ <module>push-demo</module>
<module>richfaces-showcase</module>
- <!--<module>dist</module>-->
+ <module>validator-demo</module>
</modules>
<scm>
@@ -57,66 +57,4 @@
<url>http://fisheye.jboss.org/browse/richfaces/trunk/examples</url>
</scm>
-</project>
-=======
-<?xml version="1.0" encoding="UTF-8"?>
- <!--
- JBoss, Home of Professional Open Source Copyright 2010, Red Hat,
- Inc. and individual contributors by the @authors tag. See the
- copyright.txt in the distribution for a full listing of
- individual contributors. This is free software; you can
- redistribute it and/or modify it under the terms of the GNU
- Lesser General Public License as published by the Free Software
- Foundation; either version 2.1 of the License, or (at your
- option) any later version. This software 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 software; if not,
- write to the Free Software Foundation, Inc., 51 Franklin St,
- Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site:
- http://www.fsf.org.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <!--
- This aggregator pom, is not released, and is only used to make
- it easy to build all of the examples at once from trunk.
- -->
-
- <parent>
- <groupId>org.richfaces</groupId>
- <artifactId>richfaces-parent</artifactId>
- <version>10</version>
- <relativePath>../build/parent/pom.xml</relativePath>
- </parent>
-
- <groupId>org.richfaces.examples</groupId>
- <artifactId>examples-aggregator</artifactId>
- <version>4.0.0-SNAPSHOT</version>
- <packaging>pom</packaging>
- <name>RichFaces Examples: Aggregator</name>
-
- <modules>
- <module>parent</module>
- <module>template</module>
- <module>core-demo</module>
- <module>misc-demo</module>
- <module>output-demo</module>
- <module>input-demo</module>
- <module>repeater-demo</module>
- <module>iteration-demo</module>
- <module>richfaces-showcase</module>
- <module>validator-demo</module>
- </modules>
-
- <scm>
- <connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/trunk/examples</connection>
- <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/trunk/examples</developerConnection>
- <url>http://fisheye.jboss.org/browse/richfaces/trunk/examples</url>
- </scm>
-
-</project>
->>>>>>> .merge-right.r19180
+</project>
\ No newline at end of file
Added: trunk/examples/push-demo/pom.xml
===================================================================
--- trunk/examples/push-demo/pom.xml (rev 0)
+++ trunk/examples/push-demo/pom.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ JBoss, Home of Professional Open Source Copyright 2010, Red Hat,
+ Inc. and individual contributors by the @authors tag. See the
+ copyright.txt in the distribution for a full listing of
+ individual contributors. This is free software; you can
+ redistribute it and/or modify it under the terms of the GNU
+ Lesser General Public License as published by the Free Software
+ Foundation; either version 2.1 of the License, or (at your
+ option) any later version. This software 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 software; if not,
+ write to the Free Software Foundation, Inc., 51 Franklin St,
+ Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site:
+ http://www.fsf.org.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.richfaces.examples</groupId>
+ <artifactId>richfaces-example-parent</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.richfaces.examples</groupId>
+ <artifactId>push-demo</artifactId>
+ <packaging>war</packaging>
+ <version>4.0.0-SNAPSHOT</version>
+ <name>RichFaces Examples: Push</name>
+
+ <properties>
+ <hornetq.version>2.1.2.Final</hornetq.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.hornetq</groupId>
+ <artifactId>hornetq-core</artifactId>
+ <version>${hornetq.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hornetq</groupId>
+ <artifactId>hornetq-jms</artifactId>
+ <version>${hornetq.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.hornetq</groupId>
+ <artifactId>hornetq-logging</artifactId>
+ <version>${hornetq.version}</version>
+ </dependency>
+ <!-- dependency>
+ <groupId>org.hornetq</groupId>
+ <artifactId>hornetq-transports</artifactId>
+ <version>2.1.0.r9031</version>
+ </dependency -->
+ <dependency>
+ <groupId>org.jboss.netty</groupId>
+ <artifactId>netty</artifactId>
+ <version>3.2.2.Final</version>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <version>1.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.core</groupId>
+ <artifactId>richfaces-core-impl</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet.jsp</groupId>
+ <artifactId>jsp-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.el</groupId>
+ <artifactId>el-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>jstl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.ui.core</groupId>
+ <artifactId>richfaces-ui-core-ui</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>jee6</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-war-plugin</artifactId>
+ <configuration>
+ <webappDirectory>${project.build.directory}/${project.build.finalName}-jee6</webappDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <!-- TODO these should be switchable in example specific parent -->
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.transaction</groupId>
+ <artifactId>jta</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ </profile>
+ <profile>
+ <id>jetty</id>
+ <dependencies>
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-websocket</artifactId>
+ <version>8.0.0.M1</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ <version>8.0.0.M1</version>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <scm>
+ <connection>scm:svn:http://anonsvn.jboss.org/repos/richfaces/trunk/examples/push-demo</connection>
+ <developerConnection>scm:svn:https://svn.jboss.org/repos/richfaces/trunk/examples/push-demo</developerConnection>
+ <url>http://fisheye.jboss.org/browse/richfaces</url>
+ </scm>
+</project>
Added: trunk/examples/push-demo/src/main/java/demo/Channel.java
===================================================================
--- trunk/examples/push-demo/src/main/java/demo/Channel.java (rev 0)
+++ trunk/examples/push-demo/src/main/java/demo/Channel.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package demo;
+
+import java.io.Serializable;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.ValueChangeEvent;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class Channel implements Serializable {
+
+ private static final long serialVersionUID = 6798558262812940593L;
+
+ private String name;
+
+ private boolean rendered = true;
+
+ public Channel(String name) {
+ super();
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public boolean isRendered() {
+ return rendered;
+ }
+
+ public void setRendered(boolean rendered) {
+ this.rendered = rendered;
+ }
+
+ public void processChannelStateChange(ValueChangeEvent event) {
+ setRendered(Boolean.TRUE.equals(event.getNewValue()));
+
+ ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+ ChatBean chatBean = (ChatBean) externalContext.getSessionMap().get("chatBean");
+
+ chatBean.handleStateChange(this);
+ }
+}
Added: trunk/examples/push-demo/src/main/java/demo/ChannelsBean.java
===================================================================
--- trunk/examples/push-demo/src/main/java/demo/ChannelsBean.java (rev 0)
+++ trunk/examples/push-demo/src/main/java/demo/ChannelsBean.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,53 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package demo;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+@SessionScoped
+@ManagedBean
+public class ChannelsBean implements Serializable {
+
+ private static final long serialVersionUID = 2916670958555985564L;
+
+ private List<Channel> channels = new ArrayList<Channel>();
+
+ public ChannelsBean() {
+ channels.add(new Channel("upgrade"));
+ channels.add(new Channel("programming"));
+ channels.add(new Channel("hardware"));
+ channels.add(new Channel("os"));
+ }
+
+ public List<Channel> getChannels() {
+ return channels;
+ }
+}
Added: trunk/examples/push-demo/src/main/java/demo/ChatBean.java
===================================================================
--- trunk/examples/push-demo/src/main/java/demo/ChatBean.java (rev 0)
+++ trunk/examples/push-demo/src/main/java/demo/ChatBean.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,153 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package demo;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.Date;
+
+import javax.annotation.PostConstruct;
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.ManagedProperty;
+import javax.faces.bean.SessionScoped;
+
+import org.richfaces.application.push.MessageException;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicsContext;
+import org.richfaces.log.LogFactory;
+import org.richfaces.log.Logger;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+@ManagedBean
+@SessionScoped
+public class ChatBean implements Serializable {
+
+ private static final long serialVersionUID = -6377543444437645751L;
+
+ private static final Logger LOGGER = LogFactory.getLogger(ChatBean.class);
+
+ private String userName;
+
+ private String message;
+
+ private boolean chatJoined;
+
+ private transient TopicsContext topicsContext;
+
+ private String subchannel;
+
+ @ManagedProperty("#{channelsBean}")
+ private ChannelsBean channelsBean;
+
+ @PostConstruct
+ public void init() {
+ topicsContext = TopicsContext.lookup();
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ private void publishStateChangeMessage(String name, String action) {
+ try {
+ topicsContext.publish(new TopicKey("chat", name), MessageFormat.format("*** {0} {1} chat in {2,time,medium}",
+ userName, action, new Date()));
+ } catch (MessageException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ public void joinChat() {
+ if (!chatJoined) {
+ if (userName == null) {
+ throw new NullPointerException("username");
+ }
+
+ chatJoined = true;
+
+ for (Channel subchannel : channelsBean.getChannels()) {
+ publishStateChangeMessage(subchannel.getName(), "joined");
+ }
+ }
+ }
+
+ public void handleStateChange(Channel channel) {
+ String action;
+ if (channel.isRendered()) {
+ action = "joined";
+ } else {
+ action = "left";
+ }
+
+ publishStateChangeMessage(channel.getName(), action);
+ }
+
+ public void say() {
+ try {
+ topicsContext.publish(new TopicKey("chat", subchannel), MessageFormat.format("{0,time,medium} {1}: {2}", new Date(),
+ userName, message));
+ } catch (MessageException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ public void setTopicsContext(TopicsContext topicsContext) {
+ this.topicsContext = topicsContext;
+ }
+
+ /**
+ * @return the subchannel
+ */
+ public String getSubchannel() {
+ return subchannel;
+ }
+
+ /**
+ * @param subchannel the subchannel to set
+ */
+ public void setSubchannel(String subchannel) {
+ this.subchannel = subchannel;
+ }
+
+ /**
+ * @param channelsBean the channelsBean to set
+ */
+ public void setChannelsBean(ChannelsBean channelsBean) {
+ this.channelsBean = channelsBean;
+ }
+
+}
Added: trunk/examples/push-demo/src/main/java/demo/HornetQInitializer.java
===================================================================
--- trunk/examples/push-demo/src/main/java/demo/HornetQInitializer.java (rev 0)
+++ trunk/examples/push-demo/src/main/java/demo/HornetQInitializer.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,118 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package demo;
+
+import java.util.HashSet;
+
+import javax.faces.application.Application;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.PostConstructApplicationEvent;
+import javax.faces.event.PreDestroyApplicationEvent;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+import javax.naming.InitialContext;
+
+import org.hornetq.api.core.TransportConfiguration;
+import org.hornetq.core.config.Configuration;
+import org.hornetq.core.config.impl.ConfigurationImpl;
+import org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory;
+import org.hornetq.core.remoting.impl.netty.NettyConnectorFactory;
+import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.server.HornetQServers;
+import org.hornetq.jms.server.JMSServerManager;
+import org.hornetq.jms.server.impl.JMSServerManagerImpl;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class HornetQInitializer implements SystemEventListener {
+
+ private JMSServerManager serverManager;
+
+ public void processEvent(SystemEvent event) throws AbortProcessingException {
+ if (event instanceof PostConstructApplicationEvent) {
+ try {
+ startHornetQ();
+ } catch (Exception e) {
+ throw new AbortProcessingException(e);
+ }
+
+ Application application = FacesContext.getCurrentInstance().getApplication();
+ application.subscribeToEvent(PreDestroyApplicationEvent.class, this);
+ } else {
+ try {
+ stopHornetQ();
+ } catch (Exception e) {
+ throw new AbortProcessingException(e);
+ }
+ }
+ }
+
+ /**
+ * @throws Exception
+ *
+ */
+ private void stopHornetQ() throws Exception {
+ serverManager.stop();
+ serverManager = null;
+ }
+
+ /**
+ * @throws Exception
+ *
+ */
+ private void startHornetQ() throws Exception {
+ // Step 2. Create the Configuration, and set the properties accordingly
+ Configuration configuration = new ConfigurationImpl();
+ configuration.setPersistenceEnabled(false);
+ configuration.setSecurityEnabled(false);
+
+ TransportConfiguration transpConf = new TransportConfiguration(NettyAcceptorFactory.class.getName());
+
+ HashSet<TransportConfiguration> setTransp = new HashSet<TransportConfiguration>();
+ setTransp.add(transpConf);
+
+ configuration.setAcceptorConfigurations(setTransp);
+
+ // Step 3. Create and start the server
+ HornetQServer server = HornetQServers.newHornetQServer(configuration);
+
+ serverManager = new JMSServerManagerImpl(server);
+
+ //if you want to use JNDI, simple inject a context here or don't call this method and make sure the JNDI parameters are set.
+ serverManager.setContext(new InitialContext());
+ serverManager.start();
+
+ serverManager.createConnectionFactory("ConnectionFactory", new TransportConfiguration(NettyConnectorFactory.class.getName()),
+ "ConnectionFactory");
+
+ serverManager.createTopic(false, "chat", "/topic/chat");
+ serverManager.createTopic(false, "info", "/topic/info");
+ }
+
+ public boolean isListenerForSource(Object source) {
+ return true;
+ }
+
+}
Added: trunk/examples/push-demo/src/main/java/demo/TopicsInitializer.java
===================================================================
--- trunk/examples/push-demo/src/main/java/demo/TopicsInitializer.java (rev 0)
+++ trunk/examples/push-demo/src/main/java/demo/TopicsInitializer.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package demo;
+
+import java.text.MessageFormat;
+
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.event.AbortProcessingException;
+import javax.faces.event.SystemEvent;
+import javax.faces.event.SystemEventListener;
+import javax.servlet.http.HttpServletRequest;
+
+import org.richfaces.application.push.EventAbortedException;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionPreSubscriptionEvent;
+import org.richfaces.application.push.SessionSubscriptionEvent;
+import org.richfaces.application.push.SessionTopicListener;
+import org.richfaces.application.push.SessionUnsubscriptionEvent;
+import org.richfaces.application.push.Topic;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicsContext;
+import org.richfaces.application.push.impl.DefaultMessageDataSerializer;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class TopicsInitializer implements SystemEventListener {
+
+ public void processEvent(SystemEvent event) throws AbortProcessingException {
+ TopicsContext topicsContext = TopicsContext.lookup();
+
+ Topic topic = topicsContext.getOrCreateTopic(new TopicKey("chat"));
+
+ topic.setMessageDataSerializer(DefaultMessageDataSerializer.instance());
+
+ topic.addTopicListener(new SessionTopicListener() {
+
+ public void processUnsubscriptionEvent(SessionUnsubscriptionEvent event) throws EventAbortedException {
+ TopicKey topicKey = event.getTopicKey();
+ Session session = event.getSession();
+ System.out.println(MessageFormat.format("Session {0} disconnected from {1}", session.getId(), topicKey.getTopicAddress()));
+ }
+
+ public void processSubscriptionEvent(SessionSubscriptionEvent event) throws EventAbortedException {
+ TopicKey topicKey = event.getTopicKey();
+ Session session = event.getSession();
+
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ HttpServletRequest hsr = (HttpServletRequest) facesContext.getExternalContext().getRequest();
+
+ System.out.println(MessageFormat.format("Session {0} connected to {1} from {2}", session.getId(),
+ topicKey.getTopicAddress(), hsr.getRemoteAddr()));
+ }
+
+ public void processPreSubscriptionEvent(SessionPreSubscriptionEvent event) throws EventAbortedException {
+ ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+ ChatBean chatBean = (ChatBean) externalContext.getSessionMap().get("chatBean");
+ if (chatBean == null || "badname".equals(chatBean.getUserName())) {
+ throw new EventAbortedException("User name has not passed validation");
+ }
+ }
+ });
+ }
+
+ public boolean isListenerForSource(Object source) {
+ return true;
+ }
+
+}
Added: trunk/examples/push-demo/src/main/webapp/META-INF/MANIFEST.MF
===================================================================
--- trunk/examples/push-demo/src/main/webapp/META-INF/MANIFEST.MF (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/META-INF/MANIFEST.MF 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
Added: trunk/examples/push-demo/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
--- trunk/examples/push-demo/src/main/webapp/WEB-INF/faces-config.xml (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/WEB-INF/faces-config.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
+
+ <application>
+ <system-event-listener>
+ <system-event-listener-class>demo.HornetQInitializer</system-event-listener-class>
+ <system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
+ </system-event-listener>
+ <system-event-listener>
+ <system-event-listener-class>demo.TopicsInitializer</system-event-listener-class>
+ <system-event-class>javax.faces.event.PostConstructApplicationEvent</system-event-class>
+ </system-event-listener>
+ </application>
+
+ <navigation-rule>
+ <from-view-id>*</from-view-id>
+ <navigation-case>
+ <from-outcome>chat</from-outcome>
+ <to-view-id>/chat.xhtml</to-view-id>
+ <redirect>
+ <view-param>
+ <name>username</name>
+ <value>#{username}</value>
+ </view-param>
+ </redirect>
+ </navigation-case>
+ </navigation-rule>
+
+</faces-config>
\ No newline at end of file
Added: trunk/examples/push-demo/src/main/webapp/WEB-INF/jboss-scanning.xml
===================================================================
--- trunk/examples/push-demo/src/main/webapp/WEB-INF/jboss-scanning.xml (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/WEB-INF/jboss-scanning.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,11 @@
+<scanning xmlns="urn:jboss:scanning:1.0">
+<!--
+ For JBoss AS 6 integration there is a conflict with guava, and
+ google-collections. JBAS-8361
+-->
+ <path name="WEB-INF/classes"></path>
+
+ <path name="WEB-INF/lib/guava-r05.jar">
+ <exclude name="com.google.common.collect" />
+ </path>
+</scanning>
\ No newline at end of file
Added: trunk/examples/push-demo/src/main/webapp/WEB-INF/web.xml
===================================================================
--- trunk/examples/push-demo/src/main/webapp/WEB-INF/web.xml (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/WEB-INF/web.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ id="WebApp_ID" version="3.0">
+
+ <context-param>
+ <param-name>javax.faces.PROJECT_STAGE</param-name>
+ <param-value>Development</param-value>
+ </context-param>
+
+ <listener>
+ <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
+ </listener>
+
+ <filter-mapping>
+ <filter-name>PushFilter</filter-name>
+ <url-pattern>/faces/*</url-pattern>
+ </filter-mapping>
+
+ <filter>
+ <filter-name>PushFilter</filter-name>
+ <filter-class>org.richfaces.webapp.PushFilter</filter-class>
+ <async-supported>true</async-supported>
+ </filter>
+
+ <!-- context-param>
+ <param-name>org.atmosphere.useWebSocket</param-name>
+ <param-value>true</param-value>
+ </context-param-->
+
+ <servlet>
+ <servlet-name>Faces Servlet</servlet-name>
+ <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>Faces Servlet</servlet-name>
+ <url-pattern>/faces/*</url-pattern>
+ </servlet-mapping>
+</web-app>
\ No newline at end of file
Added: trunk/examples/push-demo/src/main/webapp/chat.xhtml
===================================================================
--- trunk/examples/push-demo/src/main/webapp/chat.xhtml (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/chat.xhtml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,72 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:c="http://java.sun.com/jsp/jstl/core"
+ xmlns:a4j="http://richfaces.org/a4j">
+
+ <f:view>
+ <f:metadata>
+ <f:viewParam name="username" value="#{chatBean.userName}" />
+ <f:event type="preRenderView" listener="#{chatBean.joinChat}"/>
+ </f:metadata>
+ <h:head>
+ <h:outputStylesheet>
+ .pushBlock {
+ width: 300px;
+ float: left;
+ border: 2px dotted navy;
+ margin: 10px;
+ }
+
+ .chatOutput {
+ width: 280px;
+ height: 200px;
+ overflow: auto;
+ }
+ </h:outputStylesheet>
+ </h:head>
+ <h:body>
+ <h:form id="form">
+ You are: #{chatBean.userName} <br />
+
+ <script type="text/javascript">
+ function clearInput(event) {
+ if (event.status == 'success') {
+ jQuery('.messageInput').val('');
+ }
+ }
+ </script>
+
+ <c:forEach var="channel" items="#{channelsBean.channels}">
+ <c:set var="channelName" value="#{channel.name}" />
+
+ <h:panelGroup styleClass="pushBlock" layout="block" id="pushBlock_#{channelName}">
+
+ Subchannel: #{channelName}
+
+ <h:selectBooleanCheckbox value="true" valueChangeListener="#{channel.processChannelStateChange}">
+ <f:ajax event="click" render="pushBlock_#{channelName}" />
+ </h:selectBooleanCheckbox>
+
+ <h:panelGroup layout="block" rendered="#{channel.rendered}">
+ <a4j:push address="#{channelName}@chat" onerror="alert(event.rf.data)" ondataavailable="jQuery('<div />').prependTo('.#{channelName}Output').text(event.rf.data)" />
+
+ <h:inputText styleClass="messageInput" value="#{chatBean.message}" size="40" />
+
+ <h:commandLink value="ajax" action="#{chatBean.say}">
+ <f:setPropertyActionListener value="#{channelName}" target="#{chatBean.subchannel}" />
+ <f:ajax execute="pushBlock_#{channelName}" onevent="clearInput" />
+ </h:commandLink>
+
+ <h:panelGroup styleClass="#{channelName}Output chatOutput" layout="block" />
+ </h:panelGroup>
+ </h:panelGroup>
+ </c:forEach>
+ </h:form>
+ </h:body>
+ </f:view>
+</html>
\ No newline at end of file
Added: trunk/examples/push-demo/src/main/webapp/index.jsp
===================================================================
--- trunk/examples/push-demo/src/main/webapp/index.jsp (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/index.jsp 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,6 @@
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+ pageEncoding="ISO-8859-1"%>
+
+<%
+ response.sendRedirect(request.getContextPath() + "/faces/index.xhtml");
+%>
\ No newline at end of file
Added: trunk/examples/push-demo/src/main/webapp/index.xhtml
===================================================================
--- trunk/examples/push-demo/src/main/webapp/index.xhtml (rev 0)
+++ trunk/examples/push-demo/src/main/webapp/index.xhtml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,22 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core">
+
+ <f:view>
+ <h:head>
+ </h:head>
+ <h:body>
+ <h:form id="form">
+ Enter username: <h:inputText value="#{username}" required="true" />
+ <h:commandLink action="chat" value="Enter chat" />
+ </h:form>
+ <h:link value="Test with bad user name" outcome="chat">
+ <f:param name="username" value="badname" />
+ </h:link>
+ </h:body>
+ </f:view>
+</html>
\ No newline at end of file
Modified: trunk/ui/common/ui/checkstyle-suppressions.xml
===================================================================
--- trunk/ui/common/ui/checkstyle-suppressions.xml 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/common/ui/checkstyle-suppressions.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -33,4 +33,8 @@
<!-- TODO it is hot fix for building process, this files belong to the ui/output/trunk/panela/ui module,
and must be removed from here -->
<suppress checks="IllegalCatch" files="AbstractTogglePanel.java" />
-</suppressions>
+
+ <!-- TODO it is hot fix for building process, this files belong to the push-redesign module,
+ and must be removed from here -->
+ <suppress checks="IllegalCatch" files="AbstractRequest.java" />
+</suppressions>
\ No newline at end of file
Modified: trunk/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,123 +1,58 @@
-/**
- * License Agreement.
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
*
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * 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,
+ * This software 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
+ * 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
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-
-
-
package org.richfaces.component;
-import java.io.IOException;
-import java.util.EventListener;
+import javax.faces.component.UIComponentBase;
-import javax.el.MethodExpression;
-import javax.faces.component.NamingContainer;
-import javax.faces.context.FacesContext;
-import javax.servlet.http.HttpSession;
-
import org.richfaces.cdk.annotations.Attribute;
import org.richfaces.cdk.annotations.EventName;
import org.richfaces.cdk.annotations.JsfComponent;
import org.richfaces.cdk.annotations.JsfRenderer;
-import org.richfaces.cdk.annotations.Signature;
import org.richfaces.cdk.annotations.Tag;
import org.richfaces.cdk.annotations.TagType;
/**
- * Component for periodically call AJAX events on server ( poll actions )
- * @author shura
- *
+ * @author Nick Belaevski
+ *
*/
-@JsfComponent(
- tag = @Tag(generate = false, handler = "org.richfaces.view.facelets.html.AjaxPushHandler", type = TagType.Facelets),
- renderer = @JsfRenderer(type = "org.richfaces.PushRenderer")
-)
-public abstract class AbstractPush extends AbstractActionComponent {
+@JsfComponent(type = AbstractPush.COMPONENT_TYPE, family = AbstractPush.COMPONENT_FAMILY, tag = @Tag(name = "push", type = TagType.Facelets),
+ renderer = @JsfRenderer(type = "org.richfaces.PushRenderer"))
+public abstract class AbstractPush extends UIComponentBase {
public static final String COMPONENT_TYPE = "org.richfaces.Push";
-
- public static final String COMPONENT_FAMILY = "org.richfaces.Push";
- public static final String DATA_AVAILABLE = "dataAvailable";
-
- public static final String ON_DATA_AVAILABLE = "ondataavailable";
-
+ public static final String COMPONENT_FAMILY = "org.richfaces.Push";
+
@Override
- public void encodeBegin(FacesContext context) throws IOException {
- MethodExpression producer = getEventProducer();
-
- // Subscribe events producer to push status listener.
- if (null != producer) {
- producer.invoke(context.getELContext(), new Object[] {getListener(context)});
- }
-
- super.encodeBegin(context);
+ public String getFamily() {
+ return COMPONENT_FAMILY;
}
- private PushEventTracker getListener(FacesContext context) {
- PushListenersManager pushListenersManager = PushListenersManager.getInstance(context);
+ @Attribute(required = true)
+ public abstract String getAddress();
- return pushListenersManager.getListener(getListenerId(context));
- }
-
- public String getListenerId(FacesContext context) {
- Object session = context.getExternalContext().getSession(false);
- StringBuffer id = new StringBuffer();
-
- if (null != session && session instanceof HttpSession) {
- HttpSession httpSession = (HttpSession) session;
-
- id.append(httpSession.getId());
- }
-
- id.append(context.getViewRoot().getViewId());
- id.append(NamingContainer.SEPARATOR_CHAR);
- id.append(getClientId(context));
-
- return id.toString();
- }
-
- // ---------------------------------------
- @Attribute(signature = @Signature(parameters = EventListener.class))
- public abstract MethodExpression getEventProducer();
-
- public abstract void setEventProducer(MethodExpression producer);
-
- /**
- * @return time in mc for polling interval.
- */
- @Attribute(defaultValue = "1000")
- public abstract int getInterval();
-
- @Attribute(defaultValue = "true")
- public abstract boolean isEnabled();
-
- // TODO what wrong with that name?
- @Attribute(events = @EventName(value = DATA_AVAILABLE, defaultEvent = true))
+ @Attribute(events = {@EventName("dataavailable")})
public abstract String getOndataavailable();
- @Attribute(events = @EventName("begin"))
- public abstract String getOnbegin();
-
- @Attribute(events = @EventName("beforedomupdate"))
- public abstract String getOnbeforedomupdate();
-
- @Attribute(events = @EventName("complete"))
- public abstract String getOncomplete();
+ @Attribute(events = {@EventName("error")})
+ public abstract String getOnerror();
}
Deleted: trunk/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,52 +0,0 @@
-/**
- * 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.richfaces.component;
-
-import java.io.Serializable;
-
-import java.util.EventObject;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.ajax4jsf.event.PushEventListener;
-
-/**
- * @author Nick Belaevski
- * @since 4.0
- */
-public class PushEventTracker implements PushEventListener, Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = -4362297582678089326L;
- private final AtomicBoolean eventPerformed = new AtomicBoolean(false);
-
- public void onEvent(EventObject event) {
- eventPerformed.set(true);
- }
-
- public boolean pollStatus() {
- return eventPerformed.compareAndSet(true, false);
- }
-}
Deleted: trunk/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,66 +0,0 @@
-/**
- * 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.richfaces.component;
-
-import java.util.Map;
-
-import javax.faces.context.FacesContext;
-
-import org.richfaces.util.LRUMap;
-
-/**
- * @author Nick Belaevski
- * @since 4.0
- */
-public class PushListenersManager {
-
- private static final String CONTEXT_ATTRIBUTE_NAME = "richFacesPushListenersManager";
-
- private Map<String, PushEventTracker> listeners;
-
- public PushListenersManager() {
-
- // TODO configure map size
- this.listeners = new LRUMap<String, PushEventTracker>();
- }
-
- public static PushListenersManager getInstance(FacesContext context) {
- return (PushListenersManager) context.getExternalContext().getApplicationMap().get(CONTEXT_ATTRIBUTE_NAME);
- }
-
- public PushEventTracker getListener(String name) {
- synchronized (listeners) {
-
- // LRUMap involves write for each operation, so RWLock is not acceptable here
- PushEventTracker listener = listeners.get(name);
-
- if (listener == null) {
- listener = new PushEventTracker();
- listeners.put(name, listener);
- }
-
- return listener;
- }
- }
-}
Added: trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java (rev 0)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.richfaces.renderkit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.component.AbstractPush;
+import org.richfaces.resource.PushResource;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushRendererBase extends Renderer {
+
+ private static final String PUSH_URL_ENCODED_ATTRIBUTE = PushRendererBase.class.getName();
+
+ protected String getPushUrl(FacesContext context) {
+ ResourceHandler resourceHandler = context.getApplication().getResourceHandler();
+ Resource pushResource = resourceHandler.createResource(PushResource.class.getName());
+
+ return pushResource.getRequestPath();
+ }
+
+ protected boolean shouldEncodePushUrl(FacesContext context) {
+ Map<Object, Object> attributes = context.getAttributes();
+
+ if (attributes.get(PUSH_URL_ENCODED_ATTRIBUTE) == null) {
+ attributes.put(PUSH_URL_ENCODED_ATTRIBUTE, Boolean.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+
+ protected String getOptionsString(FacesContext context, UIComponent component) {
+ AbstractPush push = (AbstractPush) component;
+
+ Map<String, Object> options = new HashMap<String, Object>(2);
+
+ options.put("address", push.getAddress());
+ options.put("dataHandler", push.getOndataavailable());
+ options.put("errorHandler", push.getOnerror());
+
+ return ScriptUtils.toScript(options);
+ }
+}
Deleted: trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,153 +0,0 @@
-/**
- * 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.richfaces.renderkit.html;
-
-import static org.richfaces.renderkit.RenderKitUtils.shouldRenderAttribute;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.faces.application.ResourceDependency;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-import javax.faces.event.ActionEvent;
-
-import org.ajax4jsf.javascript.JSFunction;
-import org.ajax4jsf.javascript.JSFunctionDefinition;
-import org.ajax4jsf.javascript.JSReference;
-import org.richfaces.cdk.annotations.JsfRenderer;
-import org.richfaces.component.AbstractPush;
-import org.richfaces.renderkit.HtmlConstants;
-import org.richfaces.renderkit.RendererBase;
-import org.richfaces.renderkit.util.HandlersChain;
-import org.richfaces.resource.PushResource;
-
-/**
- * @author shura
- */
-@ResourceDependency(library = "org.richfaces", name = "ajax.reslib")
-@JsfRenderer
-public class AjaxPushRenderer extends RendererBase {
-
- public static final String COMPONENT_FAMILY = "org.richfaces.Push";
-
- public static final String RENDERER_TYPE = "org.richfaces.PushRenderer";
-
- public static final String PUSH_INTERVAL_PARAMETER = "A4J.AJAX.Push.INTERVAL";
-
- public static final int DEFAULT_PUSH_INTERVAL = 1000;
-
- public static final int DEFAULT_PUSH_WAIT = Integer.MIN_VALUE;
-
- @Override
- protected void queueComponentEventForBehaviorEvent(FacesContext context, UIComponent component, String eventName) {
- super.queueComponentEventForBehaviorEvent(context, component, eventName);
-
- if (AbstractPush.DATA_AVAILABLE.equals(eventName)) {
- new ActionEvent(component).queue();
- }
- }
-
- /* (non-Javadoc)
- * @see org.ajax4jsf.renderkit.RendererBase#doEncodeEnd(javax.faces.context.ResponseWriter,
- * javax.faces.context.FacesContext, javax.faces.component.UIComponent)
- */
- protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent component) throws IOException {
- AbstractPush push = (AbstractPush) component;
- writer.startElement(HtmlConstants.SPAN_ELEM, component);
- writer.writeAttribute(HtmlConstants.STYLE_ATTRIBUTE, "display:none;", null);
- getUtils().encodeId(context, component);
-
- //TODO - ?
- getUtils().encodeBeginFormIfNessesary(context, component);
- // pushing script.
- writer.startElement(HtmlConstants.SCRIPT_ELEM, component);
- writer.writeAttribute(HtmlConstants.TYPE_ATTR, "text/javascript", null);
- StringBuffer script = new StringBuffer("\n");
- if (push.isEnabled()) {
- JSFunction function = new JSFunction("RichFaces.startPush");
- // Set dummy form id, if nessesary.
- Map<String, Object> options = new HashMap<String, Object>();
-
- int interval = push.getInterval();
- if (shouldRenderAttribute(interval)) {
- String intervalInitParameter = context.getExternalContext().getInitParameter(PUSH_INTERVAL_PARAMETER);
- if (null != intervalInitParameter) {
- interval = Integer.parseInt(intervalInitParameter);
- } else {
- interval = DEFAULT_PUSH_INTERVAL;
- }
- }
-
- options.put("interval", interval);
- options.put("pushResourceUrl", new PushResource().getRequestPath());
- options.put("pushId", push.getListenerId(context));
- options.put("clientId", component.getClientId(context));
-
- HandlersChain handlersChain = new HandlersChain(context, push);
- handlersChain.addInlineHandlerFromAttribute(AbstractPush.ON_DATA_AVAILABLE);
- handlersChain.addBehaviors(AbstractPush.DATA_AVAILABLE);
- handlersChain.addAjaxSubmitFunction();
-
- String handler = handlersChain.toScript();
-
- if (handler != null) {
- JSFunctionDefinition dataAvailableHandler = new JSFunctionDefinition(JSReference.EVENT);
- dataAvailableHandler.addToBody(handler);
- options.put(AbstractPush.ON_DATA_AVAILABLE, dataAvailableHandler);
- }
- function.addParameter(options);
- script.append(function.toScript());
- } else {
- script.append("RichFaces.stopPush('").append(push.getListenerId(context)).append("')");
- }
- script.append(";\n");
- writer.writeText(script.toString(), null);
- writer.endElement(HtmlConstants.SCRIPT_ELEM);
- getUtils().encodeEndFormIfNessesary(context, component);
- writer.endElement(HtmlConstants.SPAN_ELEM);
- }
-
- /* (non-Javadoc)
- * @see org.ajax4jsf.renderkit.RendererBase#getComponentClass()
- */
- protected Class<? extends UIComponent> getComponentClass() {
- // only push component is allowed.
- return AbstractPush.class;
- }
-
- @Override
- protected void doDecode(FacesContext context, UIComponent component) {
- super.doDecode(context, component);
-
- AbstractPush push = (AbstractPush) component;
- if (push.isEnabled()) {
- Map<String, String> requestParameterMap = context.getExternalContext().getRequestParameterMap();
- if (requestParameterMap.get(push.getClientId(context)) != null) {
- new ActionEvent(push).queue();
- }
- }
- }
-
-}
Modified: trunk/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,97 +1,125 @@
-/**
- * License Agreement.
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
*
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * 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,
+ * This software 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
+ * 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
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
-
package org.richfaces.resource;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.net.URL;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
-import javax.faces.application.Resource;
+import javax.faces.FacesException;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
+import org.ajax4jsf.javascript.ScriptUtils;
import org.richfaces.application.ServiceTracker;
-import org.richfaces.component.PushEventTracker;
-import org.richfaces.component.PushListenersManager;
+import org.richfaces.application.push.PushContext;
+import org.richfaces.application.push.PushContextFactory;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.TopicKey;
/**
* @author Nick Belaevski
- * @since 4.0
+ *
*/
-
-//TODO make this a singleton
@DynamicResource
-public class PushResource extends Resource {
+public class PushResource implements UserResource {
- public PushResource() {
- setResourceName(getClass().getName());
+ private static final String PUSH_TOPIC_PARAM = "pushTopic";
+
+ private static final String FORGET_PUSH_SESSION_ID_PARAM = "forgetPushSessionId";
+
+ public Map<String, String> getResponseHeaders() {
+ return null;
}
-
- public InputStream getInputStream() throws IOException {
+
+ public Date getLastModified() {
return null;
}
- public Map<String, String> getResponseHeaders() {
- Map<String, String> headers = new HashMap<String, String>();
+ private InputStream mapToScript(Map<String, Object> map) {
+ try {
+ byte[] bs = ScriptUtils.toScript(map).getBytes("UTF-8");
+ return new ByteArrayInputStream(bs);
+ } catch (UnsupportedEncodingException e) {
+ throw new FacesException(e.getMessage(), e);
+ }
+ }
+
+ private Map<String, String> getFailuresMap(Map<TopicKey, String> failedSubscriptions) {
+ Map<String,String> result = new HashMap<String, String>();
+
+ for (Entry<TopicKey, String> entry: failedSubscriptions.entrySet()) {
+ result.put(entry.getKey().getTopicAddress(), entry.getValue());
+ }
+
+ return result;
+ }
+
+ public InputStream getInputStream() throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
- String pushId = externalContext.getRequestParameterMap().get("id");
- if (pushId != null && pushId.length() != 0) {
- PushListenersManager manager = PushListenersManager.getInstance(facesContext);
- PushEventTracker eventTracker = manager.getListener(pushId);
-
- if (eventTracker != null) {
- if (eventTracker.pollStatus()) {
- headers.put("Ajax-Push-Status", "READY");
- }
+ PushContextFactory pushContextFactory = ServiceTracker.getService(PushContextFactory.class);
+ PushContext pushContext = pushContextFactory.getPushContext();
+
+ String forgetPushSessionId = externalContext.getRequestParameterMap().get(FORGET_PUSH_SESSION_ID_PARAM);
+ if (forgetPushSessionId != null) {
+ Session oldSession = pushContext.getSessionManager().getPushSession(forgetPushSessionId);
+ if (oldSession != null) {
+ oldSession.destroy();
}
}
+
+ Session session = pushContext.getSessionFactory().createSession(UUID.randomUUID().toString());
+
+ String[] topicNames = externalContext.getRequestParameterValuesMap().get(PUSH_TOPIC_PARAM);
+
+ if (topicNames == null) {
+ throw new IllegalArgumentException();
+ }
+
+ session.subscribe(topicNames);
+
+ Map<String, Object> subscriptionData = new HashMap<String, Object>(4);
+ subscriptionData.put("sessionId", session.getId());
- return headers;
+ Map<TopicKey, String> failedSubscriptions = session.getFailedSubscriptions();
+ subscriptionData.put("failures", getFailuresMap(failedSubscriptions));
+
+ return mapToScript(subscriptionData);
}
public String getContentType() {
- return null;
+ return "application/javascript; charset=utf-8";
}
- @Override
- public String getRequestPath() {
- FacesContext facesContext = FacesContext.getCurrentInstance();
- ResourceCodec resourceCodec = ServiceTracker.getService(ResourceCodec.class);
-
- String requestPath = resourceCodec.encodeResourceRequestPath(facesContext, null, getResourceName(), null, null);
- return resourceCodec.encodeJSFMapping(facesContext, requestPath);
+ public int getContentLength() {
+ return -1;
}
- @Override
- public URL getURL() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean userAgentNeedsUpdate(FacesContext context) {
- return true;
- }
}
Deleted: trunk/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java
===================================================================
--- trunk/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,83 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright , Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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 software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.richfaces.view.facelets.html;
-
-import javax.faces.event.ActionEvent;
-import javax.faces.view.facelets.*;
-import org.richfaces.component.AbstractPush;
-import org.richfaces.view.facelets.MethodMetadata;
-
-import java.util.EventListener;
-
-public class AjaxPushHandler extends ComponentHandler {
-
- private static final AjaxPushHandlerMetaRule META_RULE = new AjaxPushHandlerMetaRule();
-
-
- public AjaxPushHandler(ComponentConfig config) {
- super(config);
-
- }
-
- protected MetaRuleset createMetaRuleset(Class type) {
- MetaRuleset m = super.createMetaRuleset(type);
- m.addRule(META_RULE);
- return m;
- }
-
- static class AjaxPushHandlerMetaRule extends MetaRule{
-
- public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget meta) {
- if (meta.isTargetInstanceOf(AbstractPush.class)) {
- if ("action".equals(name)) {
- return new MethodMetadata(attribute) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush) instance).setAction(getMethodBinding(ctx));
- }
- };
- }
- if ("actionExpression".equals(name)) {
- return new MethodMetadata(attribute) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush) instance).setActionExpression(getMethodExpression(ctx));
- }
- };
- }
- if ("actionListener".equals(name)) {
- return new MethodMetadata(attribute, ActionEvent.class) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush) instance).setActionListener(getMethodBinding(ctx));
- }
- };
- }
- if ("eventProducer".equals(name)) {
- return new MethodMetadata(attribute, EventListener.class) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush) instance).setEventProducer(getMethodExpression(ctx));
- }
- };
- }
- }
- return null;
- }
- }
-}
Deleted: trunk/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml
===================================================================
--- trunk/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml 2010-11-02 01:14:12 UTC (rev 19880)
+++ trunk/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -1,12 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-
-<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
- version="2.0">
-
- <managed-bean eager="true">
- <managed-bean-name>richFacesPushListenersManager</managed-bean-name>
- <managed-bean-class>org.richfaces.component.PushListenersManager</managed-bean-class>
- <managed-bean-scope>application</managed-bean-scope>
- </managed-bean>
-
-</faces-config>
\ No newline at end of file
Added: trunk/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere/jquery-atmosphere.js
===================================================================
--- trunk/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere/jquery-atmosphere.js (rev 0)
+++ trunk/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere/jquery-atmosphere.js 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,508 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+jQuery.atmosphere = function() {
+ var activeRequest;
+ $(window).unload(function() {
+ if (activeRequest)
+ activeRequest.abort();
+ });
+
+ return {
+ version : 0.7,
+ response : {
+ status : 200,
+ responseBody : '',
+ headers : [],
+ state : "messageReceived",
+ transport : "polling",
+ push : [],
+ error : null,
+ id : 0
+ },
+
+ request : {},
+ logLevel : 'info',
+ callbacks : [],
+ activeTransport : null,
+ websocket : null,
+ killHiddenIFrame : null,
+
+ subscribe : function(url, callback, request) {
+ jQuery.atmosphere.request = jQuery.extend({
+ timeout : 300000,
+ method : 'GET',
+ headers : {},
+ contentType : "text/html;charset=ISO-8859-1",
+ cache : true,
+ async : true,
+ ifModified : false,
+ callback : null,
+ dataType : '',
+ url : url,
+ data : '',
+ suspend : true,
+ maxRequest : 60,
+ lastIndex : 0,
+ logLevel : 'info',
+ requestCount : 0,
+ fallbackTransport : 'streaming',
+ transport : 'long-polling'
+
+ }, request);
+
+ logLevel = jQuery.atmosphere.request.logLevel || 'info';
+ if (callback != null) {
+ jQuery.atmosphere.addCallback(callback);
+ jQuery.atmosphere.request.callback = callback;
+ }
+
+ if (jQuery.atmosphere.request.transport != jQuery.atmosphere.activeTransport) {
+ jQuery.atmosphere.closeSuspendedConnection();
+ }
+ jQuery.atmosphere.activeTransport = jQuery.atmosphere.request.transport;
+
+ if (jQuery.atmosphere.request.transport != 'websocket') {
+ jQuery.atmosphere.executeRequest();
+ } else if (jQuery.atmosphere.request.transport == 'websocket') {
+ if (!window.WebSocket) {
+ jQuery.atmosphere
+ .log(
+ logLevel,
+ [ "Websocket is not supported, using request.fallbackTransport" ]);
+ jQuery.atmosphere.request.transport = jQuery.atmosphere.request.fallbackTransport;
+ jQuery.atmosphere.executeRequest();
+ } else {
+ jQuery.atmosphere.executeWebSocket();
+ }
+ }
+ },
+
+ /**
+ * Always make sure one transport is used, not two at the same time except for Websocket.
+ */
+ closeSuspendedConnection : function() {
+ if (activeRequest != null) {
+ activeRequest.abort();
+ }
+
+ if (jQuery.atmosphere.websocket != null) {
+ jQuery.atmosphere.websocket.close();
+ jQuery.atmosphere.websocket = null;
+ }
+ },
+
+ executeRequest : function() {
+
+ if (jQuery.atmosphere.request.transport == 'streaming') {
+ if ($.browser.msie) {
+ jQuery.atmosphere.ieStreaming();
+ return;
+ } else if ((typeof window.addEventStream) == 'function') {
+ jQuery.atmosphere.operaStreaming();
+ return;
+ }
+ }
+
+ if (jQuery.atmosphere.request.requestCount++ < jQuery.atmosphere.request.maxRequest) {
+ jQuery.atmosphere.response.push = function(url) {
+ jQuery.atmosphere.request.callback = null;
+ jQuery.atmosphere.publish(url, null,
+ jQuery.atmosphere.request);
+ };
+
+ var request = jQuery.atmosphere.request;
+ var response = jQuery.atmosphere.response;
+ if (request.transport != 'polling') {
+ response.transport = request.transport;
+ }
+
+ var ajaxRequest;
+ var error = false;
+ if ($.browser.msie) {
+ var activexmodes = [ "Msxml2.XMLHTTP", "Microsoft.XMLHTTP" ]
+ for ( var i = 0; i < activexmodes.length; i++) {
+ try {
+ ajaxRequest = new ActiveXObject(activexmodes[i])
+ } catch (e) {
+ }
+ }
+ } else if (window.XMLHttpRequest) {
+ ajaxRequest = new XMLHttpRequest();
+ }
+
+ if (request.suspend) {
+ activeRequest = ajaxRequest;
+ }
+
+ ajaxRequest.open(request.method, request.url, true);
+ ajaxRequest.setRequestHeader("X-Atmosphere-Framework",
+ jQuery.atmosphere.version);
+ ajaxRequest.setRequestHeader("X-Atmosphere-Transport",
+ request.transport);
+ ajaxRequest.setRequestHeader("X-Cache-Date", new Date());
+
+ if (!$.browser.msie) {
+ ajaxRequest.onerror = function() {
+ error = true;
+ try {
+ response.status = XMLHttpRequest.status;
+ } catch (e) {
+ response.status = 404;
+ }
+
+ response.state = "error";
+ jQuery.atmosphere.invokeCallback(response);
+ ajaxRequest.abort();
+ activeRequest = null;
+ }
+ }
+
+ ajaxRequest.onreadystatechange = function() {
+ var junkForWebkit = false;
+ var update = false;
+ if (ajaxRequest.readyState == 4) {
+ jQuery.atmosphere.request = request;
+ if (request.suspend && ajaxRequest.status == 200) {
+ jQuery.atmosphere.executeRequest();
+ }
+
+ if ($.browser.msie) {
+ update = true;
+ }
+ } else if (!$.browser.msie && ajaxRequest.readyState == 3
+ && ajaxRequest.status == 200) {
+ update = true;
+ } else {
+ clearTimeout(request.id);
+ }
+
+ if (update) {
+ if (request.transport == 'streaming') {
+ response.responseBody = ajaxRequest.responseText
+ .substring(request.lastIndex,
+ ajaxRequest.responseText.length);
+ request.lastIndex = ajaxRequest.responseText.length;
+
+ if (response.responseBody.indexOf("<!--") != -1) {
+ junkForWebkit = true;
+ }
+
+ } else {
+ response.responseBody = ajaxRequest.responseText;
+ }
+
+ if (response.responseBody.indexOf("parent.callback") != -1) {
+ var start = response.responseBody.indexOf("('") + 2;
+ var end = response.responseBody.indexOf("')");
+ response.responseBody = response.responseBody
+ .substring(start, end);
+ }
+
+ if (junkForWebkit)
+ return;
+
+ try {
+ response.status = ajaxRequest.status;
+ response.headers = ajaxRequest
+ .getAllResponseHeaders();
+ } catch (e) {
+ response.status = 404;
+ }
+
+ if (request.suspend) {
+ response.state = "messageReceived";
+ } else {
+ response.state = "messagePublished";
+ }
+ jQuery.atmosphere.invokeCallback(response);
+ }
+ }
+ ajaxRequest.send(request.data);
+
+ if (request.suspend) {
+ request.id = setTimeout(
+ function() {
+ ajaxRequest.abort();
+ jQuery.atmosphere.subscribe(request.url, null,
+ request);
+
+ }, request.timeout);
+ }
+ } else {
+ jQuery.atmosphere.log(logLevel,
+ [ "Max re-connection reached." ]);
+ }
+ },
+
+ operaStreaming : function() {
+
+ var url = jQuery.atmosphere.request.url;
+ var es = document.createElement('event-source');
+ var response = jQuery.atmosphere.response;
+
+ jQuery.atmosphere.response.push = function(url) {
+ jQuery.atmosphere.request.transport = 'polling';
+ jQuery.atmosphere.request.callback = null;
+ jQuery.atmosphere.publish(url, null, jQuery.atmosphere.request);
+ };
+
+ es.setAttribute('src', url);
+ // without this check opera 9.5 would make two connections.
+ if (opera.version() < 9.5) {
+ document.body.appendChild(es);
+ }
+
+ var operaCallback = function(event) {
+ if (event.data) {
+ var junkForWebkit = false;
+
+ response.responseBody = event.data;
+ if (event.data.indexOf("<!--") != -1) {
+ junkForWebkit = true;
+ }
+
+ if (response.responseBody.indexOf("parent.callback") != -1) {
+ var start = response.responseBody.indexOf("('") + 2;
+ var end = response.responseBody.indexOf("')");
+ response.responseBody = response.responseBody
+ .substring(start, end);
+ }
+
+ if (junkForWebkit)
+ return;
+
+ response.state = "messageReceived";
+ jQuery.atmosphere.invokeCallback(response);
+ }
+ };
+
+ es.addEventListener('payload', operaCallback, false);
+
+ },
+
+ ieStreaming : function() {
+ var url = jQuery.atmosphere.request.url;
+ jQuery.atmosphere.response.push = function(url) {
+ jQuery.atmosphere.request.transport = 'polling';
+ jQuery.atmosphere.request.callback = null;
+ jQuery.atmosphere.publish(url, null, jQuery.atmosphere.request);
+ };
+
+ transferDoc = new ActiveXObject("htmlfile");
+ transferDoc.open();
+ transferDoc.close();
+ var ifrDiv = transferDoc.createElement("div");
+ transferDoc.body.appendChild(ifrDiv);
+ ifrDiv.innerHTML = "<iframe src='" + url + "'></iframe>";
+ transferDoc.parentWindow.callback = jQuery.atmosphere.streamingCallback;
+ },
+
+ streamingCallback : function(args) {
+ var response = jQuery.atmosphere.response;
+ response.transport = "streaming";
+ response.status = 200;
+ response.responseBody = args;
+ response.state = "messageReceived";
+
+ jQuery.atmosphere.invokeCallback(response);
+ },
+
+ executeWebSocket : function() {
+ var request = jQuery.atmosphere.request;
+ jQuery.atmosphere.log(logLevel, [ "Invoking executeWebSocket" ]);
+ jQuery.atmosphere.response.transport = "websocket";
+ var url = jQuery.atmosphere.request.url;
+ var callback = jQuery.atmosphere.request.callback;
+ var location = url.replace('http:', 'ws:')
+ .replace('https:', 'wss:');
+
+ var websocket = new WebSocket(location);
+ jQuery.atmosphere.websocket = websocket;
+
+ jQuery.atmosphere.response.push = function(url) {
+ var data;
+ var ws = jQuery.atmosphere.websocket;
+ try {
+ data = jQuery.atmosphere.request.data;
+ ws.send(jQuery.atmosphere.request.data);
+ } catch (e) {
+ jQuery.atmosphere
+ .log(
+ logLevel,
+ [ "Websocket failed. Downgrading to Comet and resending "
+ + data ]);
+ // Websocket is not supported, reconnect using the fallback transport.
+ request.transport = request.fallbackTransport;
+ jQuery.atmosphere.request = request;
+ jQuery.atmosphere.executeRequest();
+
+ // Repost the data.
+ jQuery.atmosphere.request.suspend = false;
+ jQuery.atmosphere.request.method = 'POST';
+ jQuery.atmosphere.request.data = data;
+ jQuery.atmosphere.response.state = 'messageReceived';
+ jQuery.atmosphere.response.transport = request.fallbackTransport;
+ jQuery.atmosphere.publish(url, null,
+ jQuery.atmosphere.request);
+
+ ws.onclose = function(message) {
+ }
+ ws.close();
+ }
+ };
+
+ websocket.onopen = function(message) {
+ jQuery.atmosphere.response.state = 'openning';
+ jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
+ };
+
+ websocket.onmessage = function(message) {
+ var data = message.data;
+ if (data.indexOf("parent.callback") != -1) {
+ var start = data.indexOf("('") + 2;
+ var end = data.indexOf("')");
+ jQuery.atmosphere.response.responseBody = data.substring(
+ start, end);
+ } else {
+ jQuery.atmosphere.response.responseBody = data;
+ }
+ jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
+ };
+
+ websocket.onerror = function(message) {
+ jQuery.atmosphere.response.state = 'error';
+ jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
+ };
+
+ websocket.onclose = function(message) {
+ jQuery.atmosphere.response.state = 'closed';
+ jQuery.atmosphere.invokeCallback(jQuery.atmosphere.response);
+ };
+ },
+
+ addCallback : function(func) {
+ if (jQuery.inArray(func, jQuery.atmosphere.callbacks) == -1) {
+ jQuery.atmosphere.callbacks.push(func);
+ }
+ },
+
+ removeCallback : function(func) {
+ if (jQuery.inArray(func, jQuery.atmosphere.callbacks) != -1) {
+ jQuery.atmosphere.callbacks.splice(index);
+ }
+ },
+
+ invokeCallback : function(response) {
+ var call = function(index, func) {
+ func(response);
+ };
+
+ jQuery.atmosphere.log(logLevel, [ "Invoking "
+ + jQuery.atmosphere.callbacks.length + " callbacks" ]);
+ if (jQuery.atmosphere.callbacks.length > 0) {
+ jQuery.each(jQuery.atmosphere.callbacks, call);
+ }
+ },
+
+ publish : function(url, callback, request) {
+ jQuery.atmosphere.request = jQuery.extend({
+ connected : false,
+ timeout : 60000,
+ method : 'POST',
+ headers : {},
+ cache : true,
+ async : true,
+ ifModified : false,
+ callback : null,
+ dataType : '',
+ url : url,
+ data : '',
+ suspend : false,
+ maxRequest : 60,
+ logLevel : 'info',
+ requestCount : 0,
+ transport : 'polling'
+ }, request);
+
+ if (callback != null) {
+ jQuery.atmosphere.addCallback(callback);
+ }
+ jQuery.atmosphere.request.transport = 'polling';
+ if (jQuery.atmosphere.request.transport != 'websocket') {
+ jQuery.atmosphere.executeRequest();
+ } else if (jQuery.atmosphere.request.transport == 'websocket') {
+ if (!window.WebSocket) {
+ alert("WebSocket not supported by this browser");
+ } else {
+ jQuery.atmosphere.executeWebSocket();
+ }
+ }
+ },
+
+ unload : function(arg) {
+ if (window.addEventListener) {
+ document.addEventListener('unload', arg, false);
+ window.addEventListener('unload', arg, false);
+ } else { // IE
+ document.attachEvent('onunload', arg);
+ window.attachEvent('onunload', arg);
+ }
+ },
+
+ kill_load_bar : function() {
+ if (jQuery.atmosphere.killHiddenIFrame == null) {
+ jQuery.atmosphere.killHiddenIFrame = document
+ .createElement('iframe');
+ var ifr = jQuery.atmosphere.killHiddenIFrame;
+ ifr.style.display = 'block';
+ ifr.style.width = '0';
+ ifr.style.height = '0';
+ ifr.style.border = '0';
+ ifr.style.margin = '0';
+ ifr.style.padding = '0';
+ ifr.style.overflow = 'hidden';
+ ifr.style.visibility = 'hidden';
+ }
+ document.body.appendChild(ifr);
+ ifr.src = 'about:blank';
+ document.body.removeChild(ifr);
+ },
+
+ log : function(level, args) {
+ if (window.console) {
+ var logger = window.console[level];
+ if (typeof logger == 'function') {
+ logger.apply(window.console, args);
+ }
+ }
+ },
+
+ warn : function() {
+ log('warn', arguments);
+ },
+
+ info : function() {
+ if (logLevel != 'warn') {
+ log('info', arguments);
+ }
+ },
+
+ debug : function() {
+ if (logLevel == 'debug') {
+ log('debug', arguments);
+ }
+ }
+ }
+
+}();
Added: trunk/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
===================================================================
--- trunk/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js (rev 0)
+++ trunk/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,237 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+(function(jsf, richfaces, _$) {
+
+ var COMPONENT_NAME = "Push";
+
+ var RICH_NAMESPACE = richfaces.Event.RICH_NAMESPACE;
+
+ var EVENT_NAMESPACE_SEPARATOR = richfaces.Event.EVENT_NAMESPACE_SEPARATOR;
+
+ var DATA_EVENT_NAME = 'dataAvailable' + EVENT_NAMESPACE_SEPARATOR + RICH_NAMESPACE + EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;
+
+ var ERROR_EVENT_NAME = 'error' + EVENT_NAMESPACE_SEPARATOR + RICH_NAMESPACE + EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;
+
+ var getDataEventNamespace = function(address) {
+ return DATA_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
+ };
+
+ var getErrorEventNamespace = function(address) {
+ return ERROR_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
+ };
+
+ richfaces.Push = (function() {
+
+ var addedTopics = {};
+
+ var removedTopics = {};
+
+ var handlersCounter = {};
+
+ var pushUrl = null;
+
+ var pushSessionId = null;
+
+ var suspendMessageEndMarker = /(<!--[^>]+-->\s*)+/;
+
+ var messageCallback = function(response) {
+ var dataString = response.responseBody.replace(suspendMessageEndMarker, "");
+ if (dataString) {
+ var messages = _$.parseJSON(dataString);
+ if (messages) {
+ for (var i = 0; i < messages.length; i++) {
+ var message = messages[i];
+
+ richfaces.Event.fire(document, getDataEventNamespace(message.topic), message.data);
+ }
+ }
+ }
+ };
+
+ var connect = function() {
+ var pushSessionIdRequestHandler = function(data) {
+ var subscriptionData = _$.parseJSON(data);
+
+
+ for (var failedTopicKey in subscriptionData.failures) {
+ richfaces.Event.fire(
+ document,
+ getErrorEventNamespace(failedTopicKey),
+ subscriptionData.failures[failedTopicKey]
+ );
+ }
+
+ if (subscriptionData.sessionId) {
+ pushSessionId = subscriptionData.sessionId;
+
+ _$.atmosphere.subscribe(pushUrl + "?__richfacesPushAsync=1&pushSessionId=" + pushSessionId, messageCallback, {
+ /*transport: 'websocket'*/
+ });
+ }
+ };
+
+ var topics = new Array();
+ for (var topicName in handlersCounter) {
+ topics.push(topicName);
+ }
+
+ var data = {
+ "pushTopic": topics
+ };
+
+ if (pushSessionId) {
+ data['forgetPushSessionId'] = pushSessionId;
+ }
+
+ //TODO handle request errors
+ _$.ajax({
+ data: data,
+ dataType: 'text',
+ success: pushSessionIdRequestHandler,
+ traditional: true,
+ type: 'POST',
+ url: pushUrl
+ });
+ };
+
+ var disconnect = function() {
+ _$.atmosphere.closeSuspendedConnection();
+ };
+
+ return {
+ increaseSubscriptionCounters: function(address) {
+ if (isNaN(handlersCounter[address]++)) {
+ handlersCounter[address] = 1;
+ addedTopics[address] = true;
+ }
+ },
+
+ decreaseSubscriptionCounters: function(address) {
+ if (--handlersCounter[address] == 0) {
+ delete handlersCounter[address];
+ removedTopics[address] = true;
+ }
+ },
+
+ setPushUrl: function(argPushUrl) {
+ if (argPushUrl.charAt(0) == '/') {
+ pushUrl = location.protocol + '//' + location.host + argPushUrl;
+ } else {
+ pushUrl = argPushUrl;
+ }
+ },
+
+ updateConnection: function() {
+ if (_$.isEmptyObject(handlersCounter)) {
+ disconnect();
+ } else if (!_$.isEmptyObject(addedTopics) || !_$.isEmptyObject(removedTopics)) {
+ disconnect();
+ connect();
+ }
+
+ addedTopics = {};
+ removedTopics = {};
+ }
+ };
+
+ }());
+
+ _$(document).ready(richfaces.Push.updateConnection);
+
+ var ajaxEventHandler = function(event) {
+ if (event.type == 'event') {
+ if (event.status != 'success') {
+ return;
+ }
+ } else if (event.type != 'error') {
+ return;
+ }
+
+ richfaces.Push.updateConnection();
+ };
+
+ jsf.ajax.addOnEvent(ajaxEventHandler);
+ jsf.ajax.addOnError(ajaxEventHandler);
+
+ richfaces.ui = richfaces.ui || {};
+
+ richfaces.ui.Push = richfaces.BaseComponent.extendClass({
+
+ name: COMPONENT_NAME,
+
+ init: function (id, options) {
+ this.id = id;
+ this.attachToDom();
+
+ this.__address = options.address;
+ this.__handlers = {};
+
+ if (options.ondataavailable) {
+ //TODO check compatibility with f:ajax
+ this.__bindDataHandler(options.ondataavailable);
+ }
+
+ if (options.onerror) {
+ //TODO check compatibility with f:ajax
+ this.__bindErrorHandler(options.onerror);
+ }
+
+ richfaces.Push.increaseSubscriptionCounters(this.__address);
+ },
+
+ __bindDataHandler: function(handlerCode) {
+ var ns = getDataEventNamespace(this.__address)
+ this.__handlers.data = richfaces.Event.bind(document, ns, new Function("event", handlerCode));
+ },
+
+ __unbindDataHandler: function() {
+ if (this.__handlers.data) {
+ var ns = getDataEventNamespace(this.__address);
+ richfaces.Event.unbind(document, ns, this.__handlers.data);
+
+ this.__handlers.data = null;
+ }
+ },
+
+ __bindErrorHandler: function(handlerCode) {
+ var ns = getErrorEventNamespace(this.__address);
+ this.__handlers.error = richfaces.Event.bind(document, ns, new Function("event", handlerCode));
+ },
+
+ __unbindErrorHandler: function() {
+ if (this.__handlers.error) {
+ var ns = getErrorEventNamespace(this.__address);
+ richfaces.Event.unbind(document, ns, this.__handlers.error);
+
+ this.__handlers.error = null;
+ }
+ },
+
+ destroy: function() {
+ this.__unbindDataHandler();
+ this.__unbindErrorHandler();
+
+ richfaces.Push.decreaseSubscriptionCounters(this.__address);
+ }
+ });
+
+}(jsf, window.RichFaces, jQuery));
\ No newline at end of file
Added: trunk/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
===================================================================
--- trunk/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml (rev 0)
+++ trunk/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml 2010-11-02 02:44:05 UTC (rev 19881)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<cdk:root xmlns="http://jboss.org/schema/richfaces/cdk/xhtml-el" xmlns:cdk="http://jboss.org/schema/richfaces/cdk/core"
+ xmlns:c="http://jboss.org/schema/richfaces/cdk/jstl/core" xmlns:cc="http://jboss.org/schema/richfaces/cdk/jsf/composite"
+ xmlns:javaee="http://java.sun.com/xml/ns/javaee">
+
+ <cc:interface>
+ <cdk:class>org.richfaces.renderkit.html.PushRenderer</cdk:class>
+ <cdk:superclass>org.richfaces.renderkit.PushRendererBase</cdk:superclass>
+ <cdk:component-family>org.richfaces.Push</cdk:component-family>
+ <cdk:renderer-type>org.richfaces.PushRenderer</cdk:renderer-type>
+ <cdk:renders-children>true</cdk:renders-children>
+
+ <cdk:resource-dependency library="javax.faces" name="jsf.js" />
+ <cdk:resource-dependency name="jquery.js" />
+ <cdk:resource-dependency name="richfaces.js" />
+ <cdk:resource-dependency name="richfaces-event.js" />
+ <cdk:resource-dependency name="richfaces-base-component.js" />
+ <cdk:resource-dependency library="net.java.dev.atmosphere" name="jquery-atmosphere.js" />
+ <cdk:resource-dependency library="org.richfaces" name="push.js" />
+ </cc:interface>
+
+ <cc:implementation>
+ <span id="#{clientId}">
+ <script type="text/javascript">
+ <c:if test="#{shouldEncodePushUrl(facesContext)}">
+ RichFaces.Push.setPushUrl("#{getPushUrl(facesContext)}");
+ </c:if>
+
+ <cdk:scriptObject name="options">
+ <cdk:scriptOption attributes="address ondataavailable onerror" />
+ </cdk:scriptObject>
+
+ new RichFaces.ui.Push(#{toScriptArgs(clientId, options)});
+ </script>
+ </span>
+ </cc:implementation>
+
+</cdk:root>
14 years, 2 months
JBoss Rich Faces SVN: r19880 - in branches/RF-7817: core/impl/src/main/java/org/richfaces/application and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 21:14:12 -0400 (Mon, 01 Nov 2010)
New Revision: 19880
Modified:
branches/RF-7817/
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java
Log:
Merged revisions 19878 via svnmerge from
https://svn.jboss.org/repos/richfaces/trunk
Property changes on: branches/RF-7817
___________________________________________________________________
Name: svnmerge-integrated
- /trunk:1-19876
+ /trunk:1-19879
Modified: branches/RF-7817/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java
===================================================================
--- branches/RF-7817/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java 2010-11-02 01:08:32 UTC (rev 19879)
+++ branches/RF-7817/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java 2010-11-02 01:14:12 UTC (rev 19880)
@@ -91,10 +91,9 @@
private static final Factory<String> FORMAT_FACTORY = new Factory<String>() {
- public String create(ResourceBundle bundle, Enum<?> messageKey, Object... args)
- throws MissingResourceException {
+ public String create(ResourceBundle bundle, Enum<?> messageKey, Object... args) throws MissingResourceException {
String format = bundle.getString(messageKey.toString());
- return format;
+ return format;
}
};
@@ -152,7 +151,7 @@
public String getMessageFormat(FacesContext facesContext, Enum<?> messageKey) {
String text = detectLocalesAndCreate(facesContext, FORMAT_FACTORY, messageKey);
if (Strings.isNullOrEmpty(text)) {
- throw new IllegalStateException("Format not found");
+ throw new IllegalStateException("Format not found");
}
return text;
14 years, 2 months
JBoss Rich Faces SVN: r19878 - trunk/core/impl/src/main/java/org/richfaces/application.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 20:51:39 -0400 (Mon, 01 Nov 2010)
New Revision: 19878
Modified:
trunk/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java
Log:
Fixed checkstyle problem
Modified: trunk/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java
===================================================================
--- trunk/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java 2010-11-02 00:45:49 UTC (rev 19877)
+++ trunk/core/impl/src/main/java/org/richfaces/application/MessageFactoryImpl.java 2010-11-02 00:51:39 UTC (rev 19878)
@@ -91,10 +91,9 @@
private static final Factory<String> FORMAT_FACTORY = new Factory<String>() {
- public String create(ResourceBundle bundle, Enum<?> messageKey, Object... args)
- throws MissingResourceException {
+ public String create(ResourceBundle bundle, Enum<?> messageKey, Object... args) throws MissingResourceException {
String format = bundle.getString(messageKey.toString());
- return format;
+ return format;
}
};
@@ -152,7 +151,7 @@
public String getMessageFormat(FacesContext facesContext, Enum<?> messageKey) {
String text = detectLocalesAndCreate(facesContext, FORMAT_FACTORY, messageKey);
if (Strings.isNullOrEmpty(text)) {
- throw new IllegalStateException("Format not found");
+ throw new IllegalStateException("Format not found");
}
return text;
14 years, 2 months
JBoss Rich Faces SVN: r19877 - branches/RF-7817.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 20:45:49 -0400 (Mon, 01 Nov 2010)
New Revision: 19877
Modified:
branches/RF-7817/pom.xml
Log:
https://jira.jboss.org/browse/RF-9158
Modified: branches/RF-7817/pom.xml
===================================================================
--- branches/RF-7817/pom.xml 2010-11-02 00:20:17 UTC (rev 19876)
+++ branches/RF-7817/pom.xml 2010-11-02 00:45:49 UTC (rev 19877)
@@ -29,8 +29,6 @@
<module>archetypes</module>
<module>examples</module>
<!--<module>docs</module>-->
- <module>push-redesign</module>
- <module>push-redesign-app</module>
</modules>
<build>
14 years, 2 months
JBoss Rich Faces SVN: r19876 - in branches/RF-7817/core/impl/src/main/java/org/richfaces/application: push/impl/jms and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 20:20:17 -0400 (Mon, 01 Nov 2010)
New Revision: 19876
Modified:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java
Log:
https://jira.jboss.org/browse/RF-9610
Modified: branches/RF-7817/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java
===================================================================
--- branches/RF-7817/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java 2010-11-02 00:02:04 UTC (rev 19875)
+++ branches/RF-7817/core/impl/src/main/java/org/richfaces/application/CoreConfiguration.java 2010-11-02 00:20:17 UTC (rev 19876)
@@ -70,6 +70,18 @@
staticResourceLocation,
@ConfigurationItem(defaultValue = "true", names = "org.richfaces.executeAWTInitializer", literal = true)
- executeAWTInitializer
+ executeAWTInitializer,
+
+ @ConfigurationItem(defaultValue = "/ConnectionFactory", names = "org.richfaces.push.jms.connectionFactory")
+ pushJMSConnectionFactory,
+
+ @ConfigurationItem(defaultValue = "/topic", names = "org.richfaces.push.jms.topicsNamespace")
+ pushJMSTopicsNamespace,
+
+ @ConfigurationItem(defaultValue = "", names = "org.richfaces.push.jms.connectionUsername")
+ pushJMSConnectionUsername,
+
+ @ConfigurationItem(defaultValue = "", names = "org.richfaces.push.jms.connectionPassword")
+ pushJMSConnectionPassword
}
}
Modified: branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java
===================================================================
--- branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java 2010-11-02 00:02:04 UTC (rev 19875)
+++ branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/MessagingContext.java 2010-11-02 00:20:17 UTC (rev 19876)
@@ -71,7 +71,7 @@
private final Name connectionFactoryName;
- private final Name topicsRootName;
+ private final Name topicsNamespace;
private final String applicationName;
@@ -81,19 +81,13 @@
private Connection connection;
- public MessagingContext(InitialContext initialContext, Name connectionFactoryName, Name topicsRootName,
- String applicationName) {
-
- this(initialContext, connectionFactoryName, topicsRootName, applicationName, null, null);
- }
-
- public MessagingContext(InitialContext initialContext, Name connectionFactoryName, Name topicsRootName,
+ public MessagingContext(InitialContext initialContext, Name connectionFactoryName, Name topicsNamespace,
String applicationName, String username, String password) {
super();
this.initialContext = initialContext;
this.connectionFactoryName = connectionFactoryName;
- this.topicsRootName = topicsRootName;
+ this.topicsNamespace = topicsNamespace;
this.applicationName = applicationName;
this.username = username;
this.password = password;
@@ -134,7 +128,7 @@
}
public Topic lookup(TopicKey topicKey) throws NamingException {
- Name topicName = appendToName(topicsRootName, topicKey.getTopicName());
+ Name topicName = appendToName(topicsNamespace, topicKey.getTopicName());
return (Topic) initialContext.lookup(topicName);
}
Modified: branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java
===================================================================
--- branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java 2010-11-02 00:02:04 UTC (rev 19875)
+++ branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/PushContextImpl.java 2010-11-02 00:20:17 UTC (rev 19876)
@@ -21,6 +21,11 @@
*/
package org.richfaces.application.push.impl.jms;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSConnectionFactory;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSConnectionPassword;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSConnectionUsername;
+import static org.richfaces.application.CoreConfiguration.Items.pushJMSTopicsNamespace;
+
import javax.faces.FacesException;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
@@ -35,6 +40,8 @@
import javax.servlet.http.HttpServletResponse;
import org.atmosphere.cpr.AtmosphereHandler;
+import org.richfaces.application.ServiceTracker;
+import org.richfaces.application.configuration.ConfigurationService;
import org.richfaces.application.push.PushContext;
import org.richfaces.application.push.SessionFactory;
import org.richfaces.application.push.SessionManager;
@@ -71,12 +78,16 @@
facesContext.getApplication().subscribeToEvent(PreDestroyApplicationEvent.class, this);
facesContext.getExternalContext().getApplicationMap().put(PushContext.INSTANCE_KEY_NAME, this);
+ ConfigurationService configurationService = ServiceTracker.getService(ConfigurationService.class);
+
InitialContext initialContext = new InitialContext();
- Name cnfName = new CompositeName("/ConnectionFactory");
- Name topicsRootName = new CompositeName("/topic");
+ Name cnfName = new CompositeName(configurationService.getStringValue(facesContext, pushJMSConnectionFactory));
+ Name topicsNamespace = new CompositeName(configurationService.getStringValue(facesContext, pushJMSTopicsNamespace));
- messagingContext = new MessagingContext(initialContext, cnfName, topicsRootName,
- getApplicationName(facesContext));
+ messagingContext = new MessagingContext(initialContext, cnfName, topicsNamespace,
+ getApplicationName(facesContext),
+ configurationService.getStringValue(facesContext, pushJMSConnectionUsername),
+ configurationService.getStringValue(facesContext, pushJMSConnectionPassword));
messagingContext.shareInstance(facesContext);
14 years, 2 months
JBoss Rich Faces SVN: r19875 - branches/RF-7817/examples/push-demo/src/main/java/demo.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 20:02:04 -0400 (Mon, 01 Nov 2010)
New Revision: 19875
Modified:
branches/RF-7817/examples/push-demo/src/main/java/demo/HornetQInitializer.java
branches/RF-7817/examples/push-demo/src/main/java/demo/TopicsInitializer.java
Log:
https://jira.jboss.org/browse/RF-9610
Modified: branches/RF-7817/examples/push-demo/src/main/java/demo/HornetQInitializer.java
===================================================================
--- branches/RF-7817/examples/push-demo/src/main/java/demo/HornetQInitializer.java 2010-11-02 00:00:02 UTC (rev 19874)
+++ branches/RF-7817/examples/push-demo/src/main/java/demo/HornetQInitializer.java 2010-11-02 00:02:04 UTC (rev 19875)
@@ -50,7 +50,6 @@
private JMSServerManager serverManager;
- @Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
if (event instanceof PostConstructApplicationEvent) {
try {
@@ -112,7 +111,6 @@
serverManager.createTopic(false, "info", "/topic/info");
}
- @Override
public boolean isListenerForSource(Object source) {
return true;
}
Modified: branches/RF-7817/examples/push-demo/src/main/java/demo/TopicsInitializer.java
===================================================================
--- branches/RF-7817/examples/push-demo/src/main/java/demo/TopicsInitializer.java 2010-11-02 00:00:02 UTC (rev 19874)
+++ branches/RF-7817/examples/push-demo/src/main/java/demo/TopicsInitializer.java 2010-11-02 00:02:04 UTC (rev 19875)
@@ -47,7 +47,6 @@
*/
public class TopicsInitializer implements SystemEventListener {
- @Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
TopicsContext topicsContext = TopicsContext.lookup();
@@ -57,14 +56,12 @@
topic.addTopicListener(new SessionTopicListener() {
- @Override
public void processUnsubscriptionEvent(SessionUnsubscriptionEvent event) throws EventAbortedException {
TopicKey topicKey = event.getTopicKey();
Session session = event.getSession();
System.out.println(MessageFormat.format("Session {0} disconnected from {1}", session.getId(), topicKey.getTopicAddress()));
}
- @Override
public void processSubscriptionEvent(SessionSubscriptionEvent event) throws EventAbortedException {
TopicKey topicKey = event.getTopicKey();
Session session = event.getSession();
@@ -76,7 +73,6 @@
topicKey.getTopicAddress(), hsr.getRemoteAddr()));
}
- @Override
public void processPreSubscriptionEvent(SessionPreSubscriptionEvent event) throws EventAbortedException {
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
ChatBean chatBean = (ChatBean) externalContext.getSessionMap().get("chatBean");
@@ -87,7 +83,6 @@
});
}
- @Override
public boolean isListenerForSource(Object source) {
return true;
}
14 years, 2 months
JBoss Rich Faces SVN: r19873 - in branches/RF-7817/ui/core/ui/src/main: templates/org/ajax4jsf/renderkit/html and 1 other directory.
by richfaces-svn-commits@lists.jboss.org
Author: nbelaevski
Date: 2010-11-01 19:59:45 -0400 (Mon, 01 Nov 2010)
New Revision: 19873
Modified:
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
Log:
https://jira.jboss.org/browse/RF-9158
Modified: branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
===================================================================
--- branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-11-01 23:50:08 UTC (rev 19872)
+++ branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-11-01 23:59:45 UTC (rev 19873)
@@ -185,14 +185,14 @@
this.__address = options.address;
this.__handlers = {};
- if (options.dataHandler) {
+ if (options.ondataavailable) {
//TODO check compatibility with f:ajax
- this.__bindDataHandler(options.dataHandler);
+ this.__bindDataHandler(options.ondataavailable);
}
- if (options.errorHandler) {
+ if (options.onerror) {
//TODO check compatibility with f:ajax
- this.__bindErrorHandler(options.errorHandler);
+ this.__bindErrorHandler(options.onerror);
}
richfaces.Push.increaseSubscriptionCounters(this.__address);
Modified: branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
===================================================================
--- branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml 2010-11-01 23:50:08 UTC (rev 19872)
+++ branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml 2010-11-01 23:59:45 UTC (rev 19873)
@@ -27,7 +27,11 @@
RichFaces.Push.setPushUrl("#{getPushUrl(facesContext)}");
</c:if>
- new RichFaces.ui.Push("#{clientId}", #{getOptionsString(facesContext, component)});
+ <cdk:scriptObject name="options">
+ <cdk:scriptOption attributes="address ondataavailable onerror" />
+ </cdk:scriptObject>
+
+ new RichFaces.ui.Push(#{toScriptArgs(clientId, options)});
</script>
</span>
</cc:implementation>
14 years, 2 months