Author: nbelaevski
Date: 2010-10-11 20:08:27 -0400 (Mon, 11 Oct 2010)
New Revision: 19530
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionsWorker.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/AbstractPush.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/package-info.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/PushRendererBase.java
branches/RF-7817/push-redesign/src/main/templates/
branches/RF-7817/push-redesign/src/main/templates/push.template.xml
Removed:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/UIPush.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java
branches/RF-7817/push-redesign/src/main/resources/META-INF/faces-config.xml
branches/RF-7817/push-redesign/src/main/resources/META-INF/push.taglib.xml
Modified:
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Message.java
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/MessageSerializer.java
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSession.java
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSessionTracker.java
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Request.java
branches/RF-7817/push-redesign-app/pom.xml
branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml
branches/RF-7817/push-redesign/
branches/RF-7817/push-redesign/pom.xml
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/DefaultMessageSerializer.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/MessagesContextImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionTrackerImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/RequestImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushServlet.java
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js
Log:
https://jira.jboss.org/browse/RF-7817
Modified:
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Message.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Message.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Message.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -78,10 +78,6 @@
return null;
}
- public boolean hasAttributes() {
- return attributes != null && !attributes.isEmpty();
- }
-
public TopicKey getTopicKey() {
return topicKey;
}
Modified:
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/MessageSerializer.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/MessageSerializer.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/MessageSerializer.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -29,6 +29,8 @@
//TODO - byte message serializer?
public interface MessageSerializer {
+ public static final String MESSAGE_ATTRIBUTE_NAME =
MessageSerializer.class.getName();
+
public String serialize(Message message);
}
Modified:
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSession.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSession.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSession.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -34,12 +34,12 @@
public void subscribe(TopicKey[] topics);
- public void connect(Request request);
+ public void connect(Request request) throws IOException;
- public void writeMessages() throws IOException;
+ public void disconnect() throws IOException;
- public void disconnect();
-
public void destroy();
+
+ public void writeMessages() throws IOException;
}
Modified:
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSessionTracker.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSessionTracker.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/PushSessionTracker.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -34,6 +34,4 @@
public void removePushSession(String id);
- public SubscriptionContext getSubscriptionContext();
-
}
\ No newline at end of file
Modified:
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Request.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Request.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/core/api/src/main/java/org/richfaces/application/push/Request.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -30,6 +30,8 @@
*/
public interface Request {
+ //TODO expose request/session/application maps
+
public void write(Message message) throws IOException;
public void suspend() throws IOException;
Property changes on: branches/RF-7817/push-redesign
___________________________________________________________________
Name: svn:ignore
+ bin
Modified: branches/RF-7817/push-redesign/pom.xml
===================================================================
--- branches/RF-7817/push-redesign/pom.xml 2010-10-12 00:07:36 UTC (rev 19529)
+++ branches/RF-7817/push-redesign/pom.xml 2010-10-12 00:08:27 UTC (rev 19530)
@@ -1,14 +1,18 @@
<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">
+
+ <parent>
+ <groupId>org.richfaces.ui</groupId>
+ <artifactId>richfaces-ui-parent</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ </parent>
+
<modelVersion>4.0.0</modelVersion>
-
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>push-redesign</artifactId>
- <version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>push-redesign</name>
- <url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -23,6 +27,10 @@
<target>1.5</target>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.richfaces.cdk</groupId>
+ <artifactId>maven-cdk-plugin</artifactId>
+ </plugin>
</plugins>
</build>
<dependencies>
@@ -45,8 +53,14 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.richfaces.core</groupId>
- <artifactId>richfaces-core-api</artifactId>
+ <groupId>org.richfaces.cdk</groupId>
+ <artifactId>annotations</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.ui.common</groupId>
+ <artifactId>richfaces-ui-common-ui</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
<dependency>
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -22,7 +22,6 @@
package org.richfaces.application.push.impl;
import java.io.IOException;
-import java.util.concurrent.Executors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -32,6 +31,7 @@
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.richfaces.application.push.PushSession;
import org.richfaces.application.push.PushSessionTracker;
+import org.richfaces.application.push.SubscriptionContext;
import org.richfaces.application.push.TopicKey;
/**
@@ -42,31 +42,18 @@
private static final String PUSH_SESSION_ID_PARAM = "pushSessionId";
- private static final String PUSH_SESSION_ATTRIBUTE = "pushSession";
-
-// private PushSubscriberContext subscriberContext;
-//
-// private PushPublisherContext publisherContext;
-//
-// private Map<TopicKey, Broadcaster> broadcasters = new
MapMaker().makeComputingMap(new Function<TopicKey, Broadcaster>() {
-// public Broadcaster apply(TopicKey from) {
-// return new DefaultBroadcaster(from.getTopicName());
-// };
-// });
-//
-
private PushSessionTracker pushTracker;
- protected PushSessionTracker getPushTracker() {
- return pushTracker;
- }
-
- public AtmospherePushHandler(MessagesContextImpl messagesContext) {
+ public AtmospherePushHandler(SubscriptionContext subscriptionContext) {
super();
- pushTracker = new PushSessionTrackerImpl(Executors.newFixedThreadPool(1),
messagesContext);
+ pushTracker = new PushSessionTrackerImpl(subscriptionContext);
}
+ protected PushSessionTracker getPushTracker() {
+ return pushTracker;
+ }
+
/* (non-Javadoc)
* @see
org.atmosphere.cpr.AtmosphereHandler#onRequest(org.atmosphere.cpr.AtmosphereResource)
*/
@@ -92,9 +79,7 @@
resp.setContentType("text/plain");
- req.setAttribute(PUSH_SESSION_ATTRIBUTE, pushSession);
pushSession.connect(new RequestImpl(resource));
- pushSession.writeMessages();
}
public void onStateChange(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event)
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/DefaultMessageSerializer.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/DefaultMessageSerializer.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/DefaultMessageSerializer.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -1,58 +1,59 @@
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.
-// */
-//package org.richfaces.application.impl;
-//
-//import java.util.HashMap;
-//import java.util.Map;
-//
-//import org.ajax4jsf.javascript.ScriptUtils;
-//import org.richfaces.Message;
-//import org.richfaces.application.MessageSerializer;
-//
-///**
-// * @author Nick Belaevski
-// *
-// */
-//public class DefaultMessageSerializer implements MessageSerializer {
-//
-// public static final String TOPIC_ATTRIBUTE = "topic";
-//
-// public static final String ATTRIBUTES_ATTRIBUTE = "attributes";
-//
-// public static final String DATA_ATTRIBUTE = "data";
-//
-// public String serialize(Message message) {
-// Map<String,Object> dataMap = new HashMap<String, Object>();
-//
-// dataMap.put(TOPIC_ATTRIBUTE, message.getTopicKey().getTopicName());
-//
-// if (message.hasAttributes()) {
-// dataMap.put(ATTRIBUTES_ATTRIBUTE, message.getAttributes());
-// }
-//
-// dataMap.put(DATA_ATTRIBUTE, message.getData());
-//
-// return ScriptUtils.toScript(dataMap);
-// }
-//
-//}
+/*
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.application.push.Message;
+import org.richfaces.application.push.MessageSerializer;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public final class DefaultMessageSerializer implements MessageSerializer {
+
+ public static final String TOPIC_ATTRIBUTE = "topic";
+
+ public static final String ATTRIBUTES_ATTRIBUTE = "attributes";
+
+ public static final String DATA_ATTRIBUTE = "data";
+
+ private static final MessageSerializer INSTANCE = new DefaultMessageSerializer();
+
+ private DefaultMessageSerializer() {}
+
+ public String serialize(Message message) {
+ Map<String,Object> dataMap = new HashMap<String, Object>();
+
+ dataMap.put(TOPIC_ATTRIBUTE, message.getTopicKey().getTopicName());
+ dataMap.put(DATA_ATTRIBUTE, message.getData());
+
+ return ScriptUtils.toScript(dataMap);
+ }
+
+ public static MessageSerializer instance() {
+ return INSTANCE;
+ }
+}
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/MessagesContextImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/MessagesContextImpl.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/MessagesContextImpl.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -38,7 +38,7 @@
* @author Nick Belaevski
*
*/
-public class MessagesContextImpl implements SubscriptionContext, PublisherContext {
+public final class MessagesContextImpl implements SubscriptionContext, PublisherContext
{
private ConcurrentMap<TopicKey, List<MessageListener>> listenersMap = new
ConcurrentHashMap<TopicKey, List<MessageListener>>();
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionImpl.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionImpl.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -26,7 +26,6 @@
import java.util.concurrent.Delayed;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
import org.richfaces.application.push.Message;
import org.richfaces.application.push.MessageListener;
@@ -40,65 +39,26 @@
* @author Nick Belaevski
*
*/
-public class PushSessionImpl implements Delayed, PushSession {
+public class PushSessionImpl implements Delayed, PushSession, RequestLifecycleListener,
MessageListener {
- private static final long EXPIRATION_DELAY = 30 * 1000;
+ private static final long EXPIRATION_DELAY = 45 * 1000;
- private String id;
+ private final Queue<Message> messagesQueue = new
LinkedBlockingQueue<Message>();
+
+ private final PushSessionTrackerImpl pushTracker;
+
+ private final String id;
- private AtomicReference<Request> requestRef =
- new AtomicReference<Request>();
+ private volatile Request request = null;
- private PushSessionTrackerImpl pushTracker;
-
private volatile long expirationTime;
- private TopicKey[] topics;
+ private volatile TopicKey[] topics;
- private Queue<Message> messagesQueue = new
LinkedBlockingQueue<Message>();
-
- private MessageListener queueMessageListener = new MessageListener() {
-
- public void onMessage(Message message) {
- messagesQueue.add(message);
- Request request = requestRef.get();
-
- if (request != null && request.isSuspended()) {
- try {
- writeMessages();
- request.resume();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- };
-
- private RequestLifecycleListener requestLifecycleListener = new
RequestLifecycleListener() {
-
- public void onSuspend(Request request) {
- try {
- writeMessages();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- public void onResume(Request request) {
- // TODO Auto-generated method stub
- }
-
- public void onDisconnect(Request request) {
- // TODO Auto-generated method stub
- PushSessionImpl.this.disconnect();
- }
- };
-
- public PushSessionImpl(PushSessionTrackerImpl pushTracker) {
+ public PushSessionImpl(PushSessionTrackerImpl pushTracker, String id) {
super();
this.pushTracker = pushTracker;
+ this.id = id;
resetExpirationTime();
}
@@ -110,10 +70,6 @@
return id;
}
- public void setId(String id) {
- this.id = id;
- }
-
public int compareTo(Delayed o) {
return
Long.valueOf(getDelay(TimeUnit.MILLISECONDS)).compareTo(o.getDelay(TimeUnit.MILLISECONDS));
}
@@ -122,39 +78,105 @@
return unit.convert(expirationTime - System.currentTimeMillis(),
TimeUnit.MILLISECONDS);
}
+ // ***** RequestLifecycleListener methods
+
+ public void onSuspend(Request request) {
+ pushTracker.getPushSessionsWorker().submit(PushSessionImpl.this);
+ }
+
+ public void onResume(Request request) {
+ // TODO Auto-generated method stub
+ try {
+ disconnect();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void onDisconnect(Request request) {
+ // TODO Auto-generated method stub
+ try {
+ disconnect();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ // ***** RequestLifecycleListener methods end
+
+ // ***** MessageListener methods
+
+ public void onMessage(Message message) {
+ messagesQueue.add(message);
+
+ if (request != null) {
+ pushTracker.getPushSessionsWorker().submit(PushSessionImpl.this);
+ }
+ }
+
+ // ***** MessageListener methods end
+
public synchronized void subscribe(TopicKey[] topics) {
SubscriptionContext subscriptionContext = pushTracker.getSubscriptionContext();
if (this.topics != null) {
for (TopicKey topicKey : topics) {
- subscriptionContext.removeMessageListener(topicKey,
queueMessageListener);
+ subscriptionContext.removeMessageListener(topicKey, this);
}
}
this.topics = topics;
for (TopicKey topicKey : topics) {
- subscriptionContext.addMessageListener(topicKey, queueMessageListener);
+ subscriptionContext.addMessageListener(topicKey, this);
}
}
- public void connect(Request request) {
- if (this.requestRef.getAndSet(request) != null) {
- disconnect();
+ private void disconnect(Request request) throws IOException {
+ if (request != null) {
+ if (request.isSuspended()) {
+ request.resume();
+ }
+
+ request.removeListener(this);
+ resetExpirationTime();
+ pushTracker.onRequestDisconnected(this);
}
+ }
+
+ public synchronized void connect(Request argRequest) throws IOException {
+ disconnect(request);
+ request = argRequest;
+
pushTracker.onRequestConnected(this);
- request.addListener(requestLifecycleListener);
+ request.addListener(this);
+ request.suspend();
}
- public synchronized void writeMessages() throws IOException {
- Request request = requestRef.get();
+ public synchronized void disconnect() throws IOException {
+ disconnect(request);
+ request = null;
+ }
+
+ public synchronized void destroy() {
+ SubscriptionContext subscriptionContext = pushTracker.getSubscriptionContext();
+ for (TopicKey topicKey : topics) {
+ subscriptionContext.removeMessageListener(topicKey, this);
+ }
+ }
+
+ public void writeMessages() throws IOException {
+ Request requestVar = request;
- if (request == null) {
+ if (requestVar == null) {
return;
}
-
+
+ boolean shouldResume = false;
Message message = null;
while (true) {
@@ -164,30 +186,12 @@
break;
}
- request.write(message);
+ requestVar.write(message);
+ shouldResume = true;
}
- if (message == null) {
- request.suspend();
- } else {
- request.resume();
+ if (shouldResume) {
+ requestVar.resume();
}
}
-
- public void disconnect() {
- Request request = this.requestRef.getAndSet(null);
- if (request == null) {
- return;
- }
-
- request.removeListener(requestLifecycleListener);
- pushTracker.onRequestDisconnected(this);
- }
-
- public synchronized void destroy() {
- SubscriptionContext subscriptionContext = pushTracker.getSubscriptionContext();
- for (TopicKey topicKey : topics) {
- subscriptionContext.removeMessageListener(topicKey, queueMessageListener);
- }
- }
}
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionTrackerImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionTrackerImpl.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionTrackerImpl.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -24,7 +24,7 @@
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.DelayQueue;
-import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import org.richfaces.application.push.PushSessionTracker;
import org.richfaces.application.push.SubscriptionContext;
@@ -53,23 +53,26 @@
}
}
- private SubscriptionContext subscriptionContext;
-
private ConcurrentMap<String, PushSessionImpl> pushSessionMap = new
MapMaker().makeMap();
private DelayQueue<PushSessionImpl> expirationQueue = new
DelayQueue<PushSessionImpl>();
- public PushSessionTrackerImpl(ExecutorService executorService, SubscriptionContext
subscriptionContext) {
- executorService.submit(new SessionsExpirationRunnable());
+ private SubscriptionContext subscriptionContext;
+
+ private PushSessionsWorker pushSessionsWorker;
+
+ public PushSessionTrackerImpl(SubscriptionContext subscriptionContext) {
+ //TODO use configurable executor service
+ Executors.newFixedThreadPool(1).submit(new SessionsExpirationRunnable());
this.subscriptionContext = subscriptionContext;
+ this.pushSessionsWorker = new PushSessionsWorker(8);
}
public PushSessionImpl createPushSession() {
- PushSessionImpl pushSession = new PushSessionImpl(this);
while (true) {
String uuid = UUID.randomUUID().toString();
- pushSession.setId(uuid);
+ PushSessionImpl pushSession = new PushSessionImpl(this, uuid);
if (pushSessionMap.putIfAbsent(uuid, pushSession) == null) {
expirationQueue.put(pushSession);
@@ -97,7 +100,11 @@
expirationQueue.add(pushSession);
}
- public SubscriptionContext getSubscriptionContext() {
+ protected SubscriptionContext getSubscriptionContext() {
return subscriptionContext;
}
+
+ protected PushSessionsWorker getPushSessionsWorker() {
+ return pushSessionsWorker;
+ }
}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionsWorker.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionsWorker.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushSessionsWorker.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -0,0 +1,101 @@
+/*
+ * 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.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.richfaces.application.push.PushSession;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+final class PushSessionsWorker {
+
+ private static final class Pipeline implements Runnable {
+
+ private BlockingQueue<PushSession> sessionsQueue = new
LinkedBlockingQueue<PushSession>();
+
+ public void submit(PushSession session) {
+ sessionsQueue.add(session);
+ }
+
+ public void run() {
+ while (true) {
+ try {
+ PushSession session = sessionsQueue.take();
+ session.writeMessages();
+ //do something
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private final int numThreads;
+
+ private Pipeline[] pipelines;
+
+ public PushSessionsWorker(int numThreads) {
+ super();
+
+ //it's important for hash code algorithm that number of workers is a power of
two
+ this.numThreads = computeFloorPowerOfTwo(numThreads);
+
+ createPipelines();
+ }
+
+ private int computeFloorPowerOfTwo(int num) {
+ int result = 1;
+ while (result < num) {
+ result <<= 1;
+ }
+
+ return result;
+ }
+
+ private int hashIdx(Object o) {
+ int hash = o.hashCode();
+
+ return hash & (pipelines.length - 1);
+ }
+
+ private void createPipelines() {
+ pipelines = new Pipeline[numThreads];
+ for (int i = 0; i < pipelines.length; i++) {
+ pipelines[i] = new Pipeline();
+ new Thread(pipelines[i]).start();
+ }
+ }
+
+ public void submit(PushSession session) {
+ int pipelineIdx = hashIdx(session.getId());
+ pipelines[pipelineIdx].submit(session);
+ }
+}
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/RequestImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/RequestImpl.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/RequestImpl.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -23,20 +23,18 @@
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-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.richfaces.application.push.Message;
+import org.richfaces.application.push.MessageSerializer;
import org.richfaces.application.push.Request;
import org.richfaces.application.push.RequestLifecycleListener;
@@ -54,7 +52,8 @@
private AtmosphereResource<HttpServletRequest, HttpServletResponse>
atmosphereResource;
- private List<RequestLifecycleListener> listeners = new
ArrayList<RequestLifecycleListener>(2);
+ //TODO - performance?
+ private List<RequestLifecycleListener> listeners = new
CopyOnWriteArrayList<RequestLifecycleListener>();
private AtmosphereResourceEventListener atmosphereListener = new
AtmosphereResourceEventListener() {
@@ -116,23 +115,13 @@
encodeRequestStartElement();
}
- Map<String,Object> map = new HashMap<String, Object>();
+ writer.write(getMessageSerializer(message).serialize(message));
- map.put("topic", message.getTopicKey().getTopicName());
- map.put("data", message.getData());
- map.put("attributes", message.getAttributes());
-
- //TODO use message serializer
- writer.write(ScriptUtils.toScript(map));
-
if (hasWrittenMessages) {
writer.write(", ");
} else {
hasWrittenMessages = true;
}
-
- writer.flush();
-
}
public void suspend() throws IOException {
@@ -170,4 +159,14 @@
PrintWriter writer = response.getWriter();
writer.write(s);
}
+
+ private MessageSerializer getMessageSerializer(Message message) {
+ MessageSerializer serializer = (MessageSerializer)
message.getAttribute(MessageSerializer.MESSAGE_ATTRIBUTE_NAME);
+
+ if (serializer == null) {
+ serializer = DefaultMessageSerializer.instance();
+ }
+
+ return serializer;
+ }
}
Copied:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/AbstractPush.java
(from rev 19521,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/UIPush.java)
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/AbstractPush.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/AbstractPush.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -0,0 +1,55 @@
+/*
+ * 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.component;
+
+import javax.faces.component.UIComponentBase;
+
+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.Tag;
+import org.richfaces.cdk.annotations.TagType;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+@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";
+
+ @Override
+ public String getFamily() {
+ return COMPONENT_FAMILY;
+ }
+
+ @Attribute(required = true)
+ public abstract String getTopic();
+
+ @Attribute(events = {@EventName("dataavailable")})
+ public abstract String getOndataavailable();
+}
Deleted: branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/UIPush.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/UIPush.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/UIPush.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -1,56 +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.component;
-
-import javax.faces.component.UIComponentBase;
-
-/**
- * @author Nick Belaevski
- *
- */
-public class UIPush extends UIComponentBase {
-
- public static final String COMPONENT_TYPE = "org.richfaces.Push";
-
- public static final String COMPONENT_FAMILY = "org.richfaces.Push";
-
- private enum PropertyKeys {
- topic
- }
-
- public UIPush() {
- setRendererType("org.richfaces.Push");
- }
-
- @Override
- public String getFamily() {
- return COMPONENT_FAMILY;
- }
-
- public String getTopic() {
- return (String) getStateHelper().eval(PropertyKeys.topic);
- }
-
- public void setTopic(String topic) {
- getStateHelper().put(PropertyKeys.topic, topic);
- }
-}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/package-info.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/package-info.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/package-info.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+@org.richfaces.cdk.annotations.TagLibrary(uri="http://richfaces.org/push-redesign",
shortName="p")
+package org.richfaces.component;
Copied:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/PushRendererBase.java
(from rev 19521,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java)
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/PushRendererBase.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/PushRendererBase.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -0,0 +1,73 @@
+/*
+ * 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.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.component.AbstractPush;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushRendererBase extends Renderer {
+
+ private static final String PUSH_URL_ENCODED_ATTRIBUTE =
PushRendererBase.class.getName();
+
+ protected String getPushUrl(FacesContext context) {
+ ExternalContext ec = context.getExternalContext();
+
+ return MessageFormat.format("{0}://{1}:{2,number,#####}{3}/push",
+ ec.getRequestScheme(), ec.getRequestServerName(),
+ ec.getRequestServerPort(), ec.getRequestContextPath());
+ }
+
+ 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("t", push.getTopic());
+ options.put("h", push.getOndataavailable());
+
+ return ScriptUtils.toScript(options);
+ }
+}
Deleted:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -1,84 +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.renderkit.html;
-
-import java.io.IOException;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.faces.application.ResourceDependencies;
-import javax.faces.application.ResourceDependency;
-import javax.faces.component.UIComponent;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-import javax.faces.render.Renderer;
-
-import org.ajax4jsf.javascript.JSFunction;
-import org.richfaces.component.UIPush;
-import org.richfaces.renderkit.HtmlConstants;
-
-/**
- * @author Nick Belaevski
- *
- */
-@ResourceDependencies({
- @ResourceDependency(library = "org.jquery", name = "jquery.js"),
- @ResourceDependency(library = "net.java.dev.atmosphere", name =
"jquery-atmosphere.js"),
- @ResourceDependency(library = "org.richfaces", name = "push.js")
-})
-public class PushRenderer extends Renderer {
-
- private String getPushUrl(FacesContext context) {
- ExternalContext ec = context.getExternalContext();
-
- return MessageFormat.format("{0}://{1}:{2,number,#####}{3}/push",
- ec.getRequestScheme(), ec.getRequestServerName(),
- ec.getRequestServerPort(), ec.getRequestContextPath());
- }
-
- @Override
- public void encodeEnd(FacesContext context, UIComponent component) throws IOException
{
- super.encodeEnd(context, component);
-
- UIPush push = (UIPush) component;
-
- ResponseWriter writer = context.getResponseWriter();
-
- writer.startElement(HtmlConstants.SPAN_ELEM, component);
- writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, component.getClientId(context),
"id");
-
- writer.startElement(HtmlConstants.SCRIPT_ELEM, component);
- writer.writeAttribute(HtmlConstants.TYPE_ATTR,
HtmlConstants.TEXT_JAVASCRIPT_TYPE, null);
-
- Map<String,Object> options = new HashMap<String, Object>();
- options.put("topics", new String[] {push.getTopic(),
"meta"});
-
- writer.writeText(new JSFunction("Push.connect", getPushUrl(context),
options).toScript(), null);
-
- writer.endElement(HtmlConstants.SCRIPT_ELEM);
-
- writer.endElement(HtmlConstants.SPAN_ELEM);
- }
-
-}
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushServlet.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushServlet.java 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushServlet.java 2010-10-12
00:08:27 UTC (rev 19530)
@@ -39,6 +39,7 @@
* @author Nick Belaevski
*
*/
+//TODO override broadcaster
public class PushServlet extends AtmosphereServlet {
/**
Deleted: branches/RF-7817/push-redesign/src/main/resources/META-INF/faces-config.xml
===================================================================
--- branches/RF-7817/push-redesign/src/main/resources/META-INF/faces-config.xml 2010-10-12
00:07:36 UTC (rev 19529)
+++ branches/RF-7817/push-redesign/src/main/resources/META-INF/faces-config.xml 2010-10-12
00:08:27 UTC (rev 19530)
@@ -1,19 +0,0 @@
-<?xml version="1.0"?>
-<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">
-
- <component>
- <component-type>org.richfaces.Push</component-type>
- <component-class>org.richfaces.component.UIPush</component-class>
- </component>
-
- <render-kit>
- <renderer>
- <component-family>org.richfaces.Push</component-family>
- <renderer-type>org.richfaces.PushRenderer</renderer-type>
-
<renderer-class>org.richfaces.renderkit.html.PushRenderer</renderer-class>
- </renderer>
- </render-kit>
-
-</faces-config>
Deleted: branches/RF-7817/push-redesign/src/main/resources/META-INF/push.taglib.xml
===================================================================
--- branches/RF-7817/push-redesign/src/main/resources/META-INF/push.taglib.xml 2010-10-12
00:07:36 UTC (rev 19529)
+++ branches/RF-7817/push-redesign/src/main/resources/META-INF/push.taglib.xml 2010-10-12
00:08:27 UTC (rev 19530)
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
-
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-facelettaglibrary_2_0.xsd"
- version="2.0" id="a4j">
- <
namespace>http://richfaces.org/push</namespace>
-
- <tag>
- <tag-name>push</tag-name>
- <component>
- <component-type>org.richfaces.Push</component-type>
- <renderer-type>org.richfaces.PushRenderer</renderer-type>
- </component>
- </tag>
-</facelet-taglib>
Modified:
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js
===================================================================
---
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-10-12
00:07:36 UTC (rev 19529)
+++
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-10-12
00:08:27 UTC (rev 19530)
@@ -1,85 +1,156 @@
-Push = (function() {
+/*
+ * 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(richfaces, _$) {
- var suspendMessageEndMarker = /(<!--[^>]+-->\s*)+/;
-
- return {
+ richfaces.Push = (function() {
- __callback: function(response) {
+ var addedTopics = {};
+
+ var removedTopics = {};
+
+ var topicHandlers = {};
+
+ var pushUrl = null;
+
+ var pushSessionId = null;
+
+ var suspendMessageEndMarker = /(<!--[^>]+-->\s*)+/;
+
+ var messageCallback = function(response) {
var dataString = response.responseBody.replace(suspendMessageEndMarker,
"");
if (dataString) {
- var messages = jQuery.parseJSON(dataString);
+ var messages = _$.parseJSON(dataString);
if (messages) {
for (var i = 0; i < messages.length; i++) {
var message = messages[i];
- alert(message.data);
+
+ var handlers = topicHandlers[message.topic] || [];
+ for (var i = 0; i < handlers.length; i++) {
+ var handler = handlers[i];
+ handler(message.data);
+ }
}
}
}
- },
-
- __startPoll: function() {
- //TODO separate URLs
-
- var pushSessionId = this.getPushSessionId();
-
- jQuery.atmosphere.subscribe(this.getUrl() + "/hub?pushSessionId=" +
pushSessionId,
- jQuery.proxy(this.__callback, this));
- },
-
- __stopPoll: function() {
- //TODO implement
- },
+ };
- getUrl: function() {
- return this.__url;
- },
+ var connect = function() {
+ var pushSessionIdRequestHandler = function(data) {
+ pushSessionId = data;
+ _$.atmosphere.subscribe(pushUrl + "/hub?pushSessionId=" + pushSessionId,
messageCallback);
+ };
- setUrl: function(url) {
- this.__url = url;
- },
-
- getInterval: function() {
- return this.__interval;
- },
-
- setInterval: function(interval) {
- this.__interval = interval;
- },
-
- getPushSessionId: function(id) {
- return this.__pushSessionId;
- },
-
- setPushSessionId: function(id) {
- this.__pushSessionId = id;
- },
-
- connect: function(url, opts) {
- if (this.__connected) {
- this.disconnect();
- }
-
- opts = opts || {};
+ var topics = new Array();
+ for (var topicName in topicHandlers) {
+ topics.push(topicName);
+ }
- this.setUrl(url);
-
- var connectionResponseHandler = jQuery.proxy(function(data) {
- this.setPushSessionId(data);
- this.__startPoll();
- }, this);
-
//TODO handle request errors
//TODO separate URLs
- jQuery.post(url + "/connect", {"pushTopic": opts.topics},
connectionResponseHandler, 'text');
+ _$.post(pushUrl + "/connect", {"pushTopic": topics},
pushSessionIdRequestHandler, 'text');
+ };
+
+ var disconnect = function() {
- this.__connected = true;
- },
+ };
- disconnect: function() {
- this.__connected = false;
- this.__stopPoll();
- this.setPushSessionId(null);
- }
- }
+ return {
+ subscribe: function(topic, handler) {
+ var handlersArray = topicHandlers[topic];
+ if (!handlersArray) {
+ handlersArray = new Array();
+ topicHandlers[topic] = handlersArray;
+ addedTopics[topic] = true;
+
+ handlersArray.push(handler);
+ }
+ },
+
+ unsubscribe: function(topic, handler) {
+ var handlersArray = topicHandlers[topic];
+ if (!handlersArray) {
+ return;
+ }
+
+ var idx = _$.inArray(handler, handlersArray);
+ if (idx < 0) {
+ return;
+ }
+
+ handlersArray.splice(idx, 1);
+
+ if (handlersArray.length == 0) {
+ delete topicHandlers[topic];
+ removedTopics[topic] = true;
+ }
+ },
+
+ setPushUrl: function(argPushUrl) {
+ pushUrl = argPushUrl;
+ },
+
+ updateConnection: function() {
+ if (_$.isEmptyObject(topicHandlers)) {
+ disconnect();
+ } else if (!_$.isEmptyObject(addedTopics) || !_$.isEmptyObject(removedTopics)) {
+ connect();
+ }
+
+ addedTopics = {};
+ removedTopics = {};
+ }
+ };
+
+ }());
+
+ _$(document).ready(richfaces.Push.updateConnection);
-}());
\ No newline at end of file
+ richfaces.ui = richfaces.ui || {};
+
+ richfaces.ui.Push = richfaces.BaseComponent.extendClass({
+
+ name: "Push",
+
+ init: function (id, options) {
+ this.id = id;
+ this.__options = options;
+ this.attachToDom();
+
+ if (this.__options.h) {
+ //TODO check compatibility with f:ajax
+ this.__handlerFunction = new Function("data", this.__options.h);
+ richfaces.Push.subscribe(this.__options.t, this.__handlerFunction);
+ }
+ },
+
+ destroy: function() {
+ if (this.__handlerFunction) {
+ richfaces.Push.unsubscribe(this.__options.t, this.__handlerFunction);
+ this.__handlerFunction = null;
+ }
+
+ this.__options = null;
+ }
+
+ });
+
+}(window.RichFaces, jQuery));
\ No newline at end of file
Added: branches/RF-7817/push-redesign/src/main/templates/push.template.xml
===================================================================
--- branches/RF-7817/push-redesign/src/main/templates/push.template.xml
(rev 0)
+++ branches/RF-7817/push-redesign/src/main/templates/push.template.xml 2010-10-12
00:08:27 UTC (rev 19530)
@@ -0,0 +1,33 @@
+<?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="org.jquery"
name="jquery.js" />
+ <cdk:resource-dependency name="richfaces.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>
+
+ new RichFaces.ui.Push("#{clientId}",
#{getOptionsString(facesContext, component)});
+ </script>
+ </span>
+ </cc:implementation>
+
+</cdk:root>
Modified: branches/RF-7817/push-redesign-app/pom.xml
===================================================================
--- branches/RF-7817/push-redesign-app/pom.xml 2010-10-12 00:07:36 UTC (rev 19529)
+++ branches/RF-7817/push-redesign-app/pom.xml 2010-10-12 00:08:27 UTC (rev 19530)
@@ -54,13 +54,18 @@
<dependency>
<groupId>org.richfaces.sandbox.ui</groupId>
<artifactId>push-redesign</artifactId>
- <version>0.0.1-SNAPSHOT</version>
+ <version>4.0.0-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>org.richfaces.ui.core</groupId>
- <artifactId>richfaces-ui-core-ui</artifactId>
+ <groupId>org.richfaces.ui.common</groupId>
+ <artifactId>richfaces-ui-common-ui</artifactId>
<version>4.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.richfaces.core</groupId>
+ <artifactId>richfaces-core-impl</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
<finalName>push-redesign-app</finalName>
Modified: branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml 2010-10-12 00:07:36 UTC
(rev 19529)
+++ branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml 2010-10-12 00:08:27 UTC
(rev 19530)
@@ -5,22 +5,21 @@
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:p="http://richfaces.org/push">
+
xmlns:p="http://richfaces.org/push-redesign">
<h:head>
</h:head>
<h:body>
- <p:push topic="chat" />
+ <p:push topic="chat" ondataavailable="jQuery('<div
/>').appendTo(jQuery('#group')).text(data)" />
- <h:outputText id="text" />
-
<h:form>
<h:inputText value="#{bean.message}" />
<h:commandLink value="ajax" action="#{bean.say}">
- <f:ajax render=":text" execute="@form" />
+ <f:ajax execute="@form" />
</h:commandLink>
</h:form>
+ <h:panelGroup id="group"
layout="block"></h:panelGroup>
</h:body>
</html>
\ No newline at end of file