Author: nbelaevski
Date: 2010-10-11 12:06:07 -0400 (Mon, 11 Oct 2010)
New Revision: 19520
Added:
branches/RF-7817/push-redesign-app/
branches/RF-7817/push-redesign-app/pom.xml
branches/RF-7817/push-redesign-app/src/
branches/RF-7817/push-redesign-app/src/main/
branches/RF-7817/push-redesign-app/src/main/java/
branches/RF-7817/push-redesign-app/src/main/java/demo/
branches/RF-7817/push-redesign-app/src/main/java/demo/Bean.java
branches/RF-7817/push-redesign-app/src/main/resources/
branches/RF-7817/push-redesign-app/src/main/webapp/
branches/RF-7817/push-redesign-app/src/main/webapp/META-INF/
branches/RF-7817/push-redesign-app/src/main/webapp/META-INF/MANIFEST.MF
branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/
branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/faces-config.xml
branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/jboss-scanning.xml
branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/lib/
branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/web.xml
branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml
branches/RF-7817/push-redesign-app/src/main/webapp/resources/
branches/RF-7817/push-redesign/pom.xml
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/MessagesContextImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSession.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionTracker.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/Request.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestImpl.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestLifecycleListener.java
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/MessageListener.java
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/SubscriptionContext.java
Removed:
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueueSettings.java
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueuesContext.java
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/AtmospherePushHandler.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/DefaultMessageSerializer.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushServlet.java
branches/RF-7817/push-redesign/src/main/resources/META-INF/faces-config.xml
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/PublisherContext.java
Log:
https://jira.jboss.org/browse/RF-7817
Added: branches/RF-7817/push-redesign/pom.xml
===================================================================
--- branches/RF-7817/push-redesign/pom.xml (rev 0)
+++ branches/RF-7817/push-redesign/pom.xml 2010-10-11 16:06:07 UTC (rev 19520)
@@ -0,0 +1,58 @@
+<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>
+
+ <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>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>3.0-alpha-1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>2.0.2</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.ui.core</groupId>
+ <artifactId>richfaces-ui-core-api</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <version>0.6.2</version>
+ </dependency>
+ </dependencies>
+</project>
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/AtmospherePushHandler.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/AtmospherePushHandler.java 2010-10-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/AtmospherePushHandler.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -21,99 +21,97 @@
*/
package org.richfaces.application.impl;
-import static org.richfaces.application.PushPublisherContext.PUBLISHER_ATTRIBUTE_NAME;
-import static org.richfaces.component.PushSubscriberContext.SUBSCRIBER_ATTRIBUTE_NAME;
-
import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Map;
+import java.util.concurrent.Executors;
-import javax.servlet.ServletContext;
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.atmosphere.cpr.AtmosphereServlet.AtmosphereHandlerWrapper;
-import org.atmosphere.cpr.Broadcaster;
-import org.atmosphere.cpr.DefaultBroadcaster;
-import org.richfaces.SubscriberKey;
-import org.richfaces.TopicKey;
-import org.richfaces.application.MessagePublisher;
-import org.richfaces.application.PushPublisherContext;
-import org.richfaces.component.PushSubscriberContext;
-import org.richfaces.component.Subscription;
+import org.richfaces.application.push.TopicKey;
-import com.google.common.base.Function;
-import com.google.common.collect.MapMaker;
-
/**
* @author Nick Belaevski
*
*/
-public class AtmospherePushHandler implements AtmosphereHandler<HttpServletRequest,
HttpServletResponse>, MessagePublisher {
+public class AtmospherePushHandler implements AtmosphereHandler<HttpServletRequest,
HttpServletResponse> {
- private PushSubscriberContext subscriberContext;
+ private static final String PUSH_SESSION_ID_PARAM = "pushSessionId";
- private PushPublisherContext publisherContext;
+ 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 Map<TopicKey, Broadcaster> broadcasters = new
MapMaker().makeComputingMap(new Function<TopicKey, Broadcaster>() {
- public Broadcaster apply(TopicKey from) {
- return new DefaultBroadcaster(from.getTopicName());
- };
- });
+ private PushSessionTracker pushTracker;
- public AtmospherePushHandler(ServletContext servletContext) {
+ protected PushSessionTracker getPushTracker() {
+ return pushTracker;
+ }
+
+ public AtmospherePushHandler(MessagesContextImpl messagesContext) {
super();
- subscriberContext = new PushSubscriberContextImpl();
- publisherContext = new PushPublisherContextImpl(this);
-
- servletContext.setAttribute(SUBSCRIBER_ATTRIBUTE_NAME, subscriberContext);
- servletContext.setAttribute(PUBLISHER_ATTRIBUTE_NAME, publisherContext);
+ pushTracker = new PushSessionTracker(Executors.newFixedThreadPool(1),
messagesContext);
}
- protected SubscriberKey getSubscriberKey(AtmosphereResource<HttpServletRequest,
HttpServletResponse> resource) {
- return new SubscriberKey(resource.getRequest().getParameter("pid"));
- }
-
- public void publish(TopicKey topicKey, String message) {
- Broadcaster broadcaster = broadcasters.get(topicKey);
- broadcaster.broadcast(message);
- }
-
+ /* (non-Javadoc)
+ * @see
org.atmosphere.cpr.AtmosphereHandler#onRequest(org.atmosphere.cpr.AtmosphereResource)
+ */
public void onRequest(AtmosphereResource<HttpServletRequest,
HttpServletResponse> resource) throws IOException {
- SubscriberKey subscriberKey = getSubscriberKey(resource);
+ // TODO Auto-generated method stub
+
+ HttpServletRequest req = resource.getRequest();
+ HttpServletResponse resp = resource.getResponse();
- Subscription[] subscriptions =
subscriberContext.getSubscriptions(subscriberKey);
- if (subscriptions == null) {
- //TODO - handle
+ String pushSessionId = req.getParameter(PUSH_SESSION_ID_PARAM);
+
+ PushSessionImpl pushSession = null;
+
+ if (pushSessionId != null) {
+ pushSession = getPushTracker().getPushSession(pushSessionId);
}
- subscriberContext.onRequestStarted(subscriberKey);
+ if (pushSession == null) {
+ //TODO - debug log
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
- //TODO - ONLY FOR TESTING!!!
- Broadcaster broadcaster = broadcasters.get(subscriptions[0].getTopicKey());
- broadcaster.addAtmosphereResource(resource);
+ resp.setContentType("text/plain");
- //TODO - review
- resource.getAtmosphereConfig().mapBroadcasterToAtmosphereHandler(broadcaster, new
AtmosphereHandlerWrapper(this, broadcaster));
-
- resource.suspend();
+ req.setAttribute(PUSH_SESSION_ATTRIBUTE, pushSession);
+ pushSession.connect(new RequestImpl(resource));
+ pushSession.writeMessages();
}
public void onStateChange(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event)
throws IOException {
+ //do nothing
+ }
- if (event.isCancelled()) {
- SubscriberKey subscriberKey = getSubscriberKey(event.getResource());
- subscriberContext.onRequestFinished(subscriberKey);
- } else {
- PrintWriter responseWriter = event.getResource().getResponse().getWriter();
- responseWriter.write(event.getMessage().toString());
- responseWriter.flush();
+ public PushSessionImpl doConnect(String[] topicNames) {
+ PushSessionImpl pushSession = getPushTracker().createPushSession();
+
+ TopicKey[] topicKeys = new TopicKey[topicNames.length];
+ for (int i = 0; i < topicNames.length; i++) {
+ String topicName = topicNames[i];
+
+ topicKeys[i] = new TopicKey(topicName);
}
+
+ //TODO - check permissions for channels
+ pushSession.subscribe(topicKeys);
+ return pushSession;
}
-
}
Modified:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/DefaultMessageSerializer.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/DefaultMessageSerializer.java 2010-10-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/DefaultMessageSerializer.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -1,57 +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.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.
+// */
+//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);
+// }
+//
+//}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/MessagesContextImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/MessagesContextImpl.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/MessagesContextImpl.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,96 @@
+/*
+ * 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.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.servlet.ServletContext;
+
+import org.richfaces.application.push.Message;
+import org.richfaces.application.push.MessageListener;
+import org.richfaces.application.push.PublisherContext;
+import org.richfaces.application.push.SubscriptionContext;
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class MessagesContextImpl implements SubscriptionContext, PublisherContext {
+
+ private ConcurrentMap<TopicKey, List<MessageListener>> listenersMap = new
ConcurrentHashMap<TopicKey, List<MessageListener>>();
+
+ private MessagesContextImpl() {}
+
+ public void addMessageListener(TopicKey topicKey, MessageListener listener) {
+ List<MessageListener> listeners = listenersMap.get(topicKey);
+ if (listeners == null) {
+ List<MessageListener> newListenersList = new
CopyOnWriteArrayList<MessageListener>();
+
+ listeners = listenersMap.putIfAbsent(topicKey, newListenersList);
+ if (listeners == null) {
+ listeners = newListenersList;
+ }
+ }
+
+ listeners.add(listener);
+ }
+
+ public void removeMessageListener(TopicKey topicKey, MessageListener listener) {
+ List<MessageListener> listeners = listenersMap.get(topicKey);
+ if (listeners != null) {
+ listeners.remove(listener);
+ }
+ }
+
+ public void publish(TopicKey topicKey, Object data) {
+ Message message = new Message(topicKey);
+ message.setData(data);
+
+ publish(message);
+ }
+
+ public void publish(Message message) {
+ List<MessageListener> listeners = listenersMap.get(message.getTopicKey());
+ if (listeners != null) {
+ for (MessageListener listener : listeners) {
+ listener.onMessage(message);
+ }
+ }
+ }
+
+ public static MessagesContextImpl create(ServletContext servletContext) {
+ MessagesContextImpl result = new MessagesContextImpl();
+
+ servletContext.setAttribute(PublisherContext.ATTRIBUTE_NAME, result);
+
+ return result;
+ }
+
+ public static void destroy(ServletContext servletContext) {
+ servletContext.removeAttribute(PublisherContext.ATTRIBUTE_NAME);
+ }
+
+}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSession.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSession.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSession.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -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.impl;
+
+import java.io.IOException;
+
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface PushSession {
+
+ public void subscribe(TopicKey[] topics);
+
+ public void connect(Request request);
+
+ public void writeMessages() throws IOException;
+
+ public void disconnect();
+
+ public void destroy();
+
+}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionImpl.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionImpl.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,190 @@
+/*
+ * 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.io.IOException;
+import java.util.Queue;
+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;
+import org.richfaces.application.push.SubscriptionContext;
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushSessionImpl implements Delayed, PushSession {
+
+ private static final long EXPIRATION_DELAY = 30 * 1000;
+
+ private String id;
+
+ private AtomicReference<Request> requestRef =
+ new AtomicReference<Request>();
+
+ private PushSessionTracker pushTracker;
+
+ private volatile long expirationTime;
+
+ private 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(PushSessionTracker pushTracker) {
+ super();
+ this.pushTracker = pushTracker;
+ resetExpirationTime();
+ }
+
+ private void resetExpirationTime() {
+ expirationTime = System.currentTimeMillis() + EXPIRATION_DELAY;
+ }
+
+ public String getId() {
+ 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));
+ }
+
+ public long getDelay(TimeUnit unit) {
+ return unit.convert(expirationTime - System.currentTimeMillis(),
TimeUnit.MILLISECONDS);
+ }
+
+ public synchronized void subscribe(TopicKey[] topics) {
+ SubscriptionContext subscriptionContext = pushTracker.getSubscriptionContext();
+
+ if (this.topics != null) {
+ for (TopicKey topicKey : topics) {
+ subscriptionContext.removeMessageListener(topicKey,
queueMessageListener);
+ }
+ }
+
+ this.topics = topics;
+
+ for (TopicKey topicKey : topics) {
+ subscriptionContext.addMessageListener(topicKey, queueMessageListener);
+ }
+
+ }
+
+ public void connect(Request request) {
+ if (this.requestRef.getAndSet(request) != null) {
+ disconnect();
+ }
+
+ pushTracker.onRequestConnected(this);
+ request.addListener(requestLifecycleListener);
+ }
+
+ public synchronized void writeMessages() throws IOException {
+ Request request = requestRef.get();
+
+ if (request == null) {
+ return;
+ }
+
+ Message message = null;
+
+ while (true) {
+ message = messagesQueue.poll();
+
+ if (message == null) {
+ break;
+ }
+
+ request.write(message);
+ }
+
+ if (message == null) {
+ request.suspend();
+ } else {
+ request.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);
+ }
+ }
+}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionTracker.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionTracker.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/PushSessionTracker.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,102 @@
+/*
+ * 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.UUID;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.ExecutorService;
+
+import org.richfaces.application.push.SubscriptionContext;
+
+import com.google.common.collect.MapMaker;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushSessionTracker {
+
+ private final class SessionsExpirationRunnable implements Runnable {
+ public void run() {
+ while (true) {
+ try {
+ PushSessionImpl pushSession = expirationQueue.take();
+ pushSessionMap.remove(pushSession.getId());
+ pushSession.destroy();
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ }
+ }
+
+ private SubscriptionContext subscriptionContext;
+
+ private ConcurrentMap<String, PushSessionImpl> pushSessionMap = new
MapMaker().makeMap();
+
+ private DelayQueue<PushSessionImpl> expirationQueue = new
DelayQueue<PushSessionImpl>();
+
+ public PushSessionTracker(ExecutorService executorService, SubscriptionContext
subscriptionContext) {
+ executorService.submit(new SessionsExpirationRunnable());
+
+ this.subscriptionContext = subscriptionContext;
+ }
+
+ public PushSessionImpl createPushSession() {
+ PushSessionImpl pushSession = new PushSessionImpl(this);
+ while (true) {
+ String uuid = UUID.randomUUID().toString();
+ pushSession.setId(uuid);
+ if (pushSessionMap.putIfAbsent(uuid, pushSession) == null) {
+ expirationQueue.put(pushSession);
+
+ return pushSession;
+ }
+ }
+ }
+
+ public PushSessionImpl getPushSession(String id) {
+ return pushSessionMap.get(id);
+ }
+
+ public void removePushSession(String id) {
+ PushSessionImpl session = pushSessionMap.remove(id);
+ if (session != null) {
+ expirationQueue.remove(session);
+ }
+ }
+
+ void onRequestConnected(PushSessionImpl pushSession) {
+ expirationQueue.remove(pushSession);
+ }
+
+ void onRequestDisconnected(PushSessionImpl pushSession) {
+ expirationQueue.add(pushSession);
+ }
+
+ public SubscriptionContext getSubscriptionContext() {
+ return subscriptionContext;
+ }
+}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/Request.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/Request.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/Request.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -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.impl;
+
+import java.io.IOException;
+
+import org.richfaces.application.push.Message;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface Request {
+
+ public void write(Message message) throws IOException;
+
+ public void suspend() throws IOException;
+
+ public void resume() throws IOException;
+
+ public void addListener(RequestLifecycleListener listener);
+
+ public void removeListener(RequestLifecycleListener listener);
+
+ public boolean isSuspended();
+
+}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestImpl.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestImpl.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestImpl.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,171 @@
+/*
+ * 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.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+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;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class RequestImpl implements Request {
+
+ private static final String DATA_WRAPPER_START = "[";
+
+ private static final String DATA_WRAPPER_END = "]";
+
+ private static final String DATA_BLANK = "";
+
+ private AtmosphereResource<HttpServletRequest, HttpServletResponse>
atmosphereResource;
+
+ private List<RequestLifecycleListener> listeners = new
ArrayList<RequestLifecycleListener>(2);
+
+ private AtmosphereResourceEventListener atmosphereListener = new
AtmosphereResourceEventListener() {
+
+ public void onSuspend(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ for (RequestLifecycleListener listener : listeners) {
+ listener.onSuspend(RequestImpl.this);
+ }
+ }
+
+ public void onResume(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ for (RequestLifecycleListener listener : listeners) {
+ listener.onResume(RequestImpl.this);
+ }
+
+ try {
+ encodeRequestEndElement();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void onDisconnect(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ for (RequestLifecycleListener listener : listeners) {
+ listener.onDisconnect(RequestImpl.this);
+ }
+ }
+
+ public void onBroadcast(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ // TODO Auto-generated method stub
+
+ }
+ };
+
+ private boolean hasWrittenMessages = false;
+
+
+ public RequestImpl(AtmosphereResource<HttpServletRequest, HttpServletResponse>
resource) {
+ super();
+
+ this.atmosphereResource = resource;
+ ((AtmosphereEventLifecycle)
atmosphereResource).addEventListener(atmosphereListener);
+ }
+
+ public void addListener(RequestLifecycleListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(RequestLifecycleListener listener) {
+ listeners.remove(listener);
+ }
+
+ public void write(Message message) throws IOException {
+ HttpServletResponse response = atmosphereResource.getResponse();
+
+ PrintWriter writer = response.getWriter();
+
+ if (!hasWrittenMessages) {
+ encodeRequestStartElement();
+ }
+
+ Map<String,Object> map = new HashMap<String, Object>();
+
+ 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 {
+ if (!isSuspended()) {
+ //TODO - customize interval
+ atmosphereResource.suspend();
+ }
+ }
+
+ public void resume() throws IOException {
+ if (isSuspended()) {
+ atmosphereResource.resume();
+ }
+ }
+
+ public boolean isSuspended() {
+ return atmosphereResource.getAtmosphereResourceEvent().isSuspended();
+ }
+
+ public void encodeRequestStartElement() throws IOException {
+ write(DATA_WRAPPER_START);
+ }
+
+ public void encodeRequestEndElement() throws IOException {
+ if (hasWrittenMessages) {
+ write(DATA_WRAPPER_END);
+ } else {
+ write(DATA_BLANK);
+ }
+ }
+
+ private void write(String s) throws IOException {
+ HttpServletResponse response = atmosphereResource.getResponse();
+
+ PrintWriter writer = response.getWriter();
+ writer.write(s);
+ }
+}
Added:
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestLifecycleListener.java
===================================================================
---
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestLifecycleListener.java
(rev 0)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/impl/RequestLifecycleListener.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -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.impl;
+
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface RequestLifecycleListener {
+
+ public void onSuspend(Request request);
+
+ public void onDisconnect(Request request);
+
+ public void onResume(Request request);
+
+}
Modified:
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-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/html/PushRenderer.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -21,12 +21,10 @@
*/
package org.richfaces.renderkit.html;
-import static org.richfaces.component.PushSubscriberContext.SUBSCRIBER_ATTRIBUTE_NAME;
-
import java.io.IOException;
import java.text.MessageFormat;
+import java.util.HashMap;
import java.util.Map;
-import java.util.UUID;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
@@ -37,9 +35,6 @@
import javax.faces.render.Renderer;
import org.ajax4jsf.javascript.JSFunction;
-import org.richfaces.SubscriberKey;
-import org.richfaces.TopicKey;
-import org.richfaces.component.PushSubscriberContext;
import org.richfaces.component.UIPush;
import org.richfaces.renderkit.HtmlConstants;
@@ -54,32 +49,14 @@
})
public class PushRenderer extends Renderer {
- private static final String PUSH_PID_ATTRIBUTE = "org.richfaces.PushPID";
-
- private String getPushId(FacesContext context) {
- Map<String, Object> viewMap = context.getViewRoot().getViewMap();
- String pid = (String) viewMap.get(PUSH_PID_ATTRIBUTE);
- if (pid == null) {
- pid = UUID.randomUUID().toString();
- viewMap.put(PUSH_PID_ATTRIBUTE, pid);
- }
-
- return pid;
- }
-
- private String getPushUrl(FacesContext context, String pushId) {
+ private String getPushUrl(FacesContext context) {
ExternalContext ec = context.getExternalContext();
- return
MessageFormat.format("{0}://{1}:{2,number,#####}{3}/atmosphere/?pid={4}",
+ return MessageFormat.format("{0}://{1}:{2,number,#####}{3}/push",
ec.getRequestScheme(), ec.getRequestServerName(),
- ec.getRequestServerPort(), ec.getRequestContextPath(),
- pushId);
+ ec.getRequestServerPort(), ec.getRequestContextPath());
}
- private PushSubscriberContext getPushSubscriberContext(FacesContext context) {
- return (PushSubscriberContext)
context.getExternalContext().getApplicationMap().get(SUBSCRIBER_ATTRIBUTE_NAME);
- }
-
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException
{
super.encodeEnd(context, component);
@@ -91,18 +68,17 @@
writer.startElement(HtmlConstants.SPAN_ELEM, component);
writer.writeAttribute(HtmlConstants.ID_ATTRIBUTE, component.getClientId(context),
"id");
- String pushId = getPushId(context);
-
writer.startElement(HtmlConstants.SCRIPT_ELEM, component);
writer.writeAttribute(HtmlConstants.TYPE_ATTR,
HtmlConstants.TEXT_JAVASCRIPT_TYPE, null);
- writer.writeText(new JSFunction("Push.connect", getPushUrl(context,
pushId)).toScript(), 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);
-
- getPushSubscriberContext(context).subscribe(new SubscriberKey(pushId), new
TopicKey(push.getTopic()));
}
}
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-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushServlet.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -21,15 +21,19 @@
*/
package org.richfaces.webapp;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URLClassLoader;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import org.atmosphere.cpr.AtmosphereServlet;
-import org.atmosphere.cpr.DefaultBroadcaster;
import org.richfaces.application.impl.AtmospherePushHandler;
+import org.richfaces.application.impl.MessagesContextImpl;
+import org.richfaces.application.impl.PushSessionImpl;
/**
* @author Nick Belaevski
@@ -37,19 +41,62 @@
*/
public class PushServlet extends AtmosphereServlet {
+ /**
+ *
+ */
+ private static final String PUSH_HUB_MAPPING = "/push/hub/*";
+
private static final long serialVersionUID = 7616370505508715222L;
- public PushServlet() {
- super();
- }
+ private static final String PUSH_TOPIC_PARAM = "pushTopic[]";
+ private AtmospherePushHandler pushHandler;
+
+ private ServletContext servletContext;
+
@Override
- protected void autoDetectAtmosphereHandlers(ServletContext sc, URLClassLoader c)
throws MalformedURLException,
- URISyntaxException {
- super.autoDetectAtmosphereHandlers(sc, c);
+ public void init(ServletConfig config) throws ServletException {
+ super.init(config);
- addAtmosphereHandler("/atmosphere/*", new AtmospherePushHandler(sc),
new DefaultBroadcaster());
+ servletContext = config.getServletContext();
+ MessagesContextImpl messagesContext =
MessagesContextImpl.create(servletContext);
+
+ pushHandler = new AtmospherePushHandler(messagesContext);
+ addAtmosphereHandler(PUSH_HUB_MAPPING, pushHandler);
+
}
+ @Override
+ public void destroy() {
+ super.destroy();
+
+ MessagesContextImpl.destroy(servletContext);
+
+ pushHandler = null;
+ removeAtmosphereHandler(PUSH_HUB_MAPPING);
+ }
+ @Override
+ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
+ String[] topicNames = req.getParameterValues(PUSH_TOPIC_PARAM);
+ PushSessionImpl pushData = pushHandler.doConnect(topicNames);
+
+ resp.setStatus(HttpServletResponse.SC_OK);
+ resp.getWriter().write(pushData.getId());
+ }
+
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse res) throws
IOException, ServletException {
+ doCometSupport(req, res);
+ }
+
+ /* (non-Javadoc)
+ * @see
org.atmosphere.cpr.AtmosphereServlet#detectSupportedFramework(javax.servlet.ServletConfig)
+ */
+ @Override
+ protected boolean detectSupportedFramework(ServletConfig sc) throws
ClassNotFoundException, IllegalAccessException,
+ InstantiationException, NoSuchMethodException, InvocationTargetException {
+
+ return false;
+ }
}
Modified: 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-11
14:13:05 UTC (rev 19519)
+++ branches/RF-7817/push-redesign/src/main/resources/META-INF/faces-config.xml 2010-10-11
16:06:07 UTC (rev 19520)
@@ -3,12 +3,6 @@
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">
- <managed-bean eager="true">
- <managed-bean-name>__pushSubscriberContext</managed-bean-name>
-
<managed-bean-class>org.richfaces.application.impl.PushSubscriberContextImpl</managed-bean-class>
- <managed-bean-scope>application</managed-bean-scope>
- </managed-bean>
-
<component>
<component-type>org.richfaces.Push</component-type>
<component-class>org.richfaces.component.UIPush</component-class>
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-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-10-11
16:06:07 UTC (rev 19520)
@@ -1,22 +1,79 @@
Push = (function() {
+
+ var suspendMessageEndMarker = /(<!--[^>]+-->\s*)+/;
- var connected = false;
-
return {
__callback: function(response) {
- alert(response.responseBody);
- response.responseBody = "";
+ var dataString = response.responseBody.replace(suspendMessageEndMarker,
"");
+ if (dataString) {
+ var data = jQuery.parseJSON(dataString);
+ alert(data[0].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;
+ },
+
+ 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 (connected) {
- return ;
+ if (this.__connected) {
+ this.disconnect();
}
+
+ opts = opts || {};
- $.atmosphere.subscribe(url, this.__callback, opts);
+ this.setUrl(url);
- connected = true;
+ 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');
+
+ this.__connected = true;
+ },
+
+ disconnect: function() {
+ this.__connected = false;
+ this.__stopPoll();
+ this.setPushSessionId(null);
}
}
Added: branches/RF-7817/push-redesign-app/pom.xml
===================================================================
--- branches/RF-7817/push-redesign-app/pom.xml (rev 0)
+++ branches/RF-7817/push-redesign-app/pom.xml 2010-10-11 16:06:07 UTC (rev 19520)
@@ -0,0 +1,82 @@
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.richfaces.sandbox.ui</groupId>
+ <artifactId>push-redesign-app</artifactId>
+ <packaging>war</packaging>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>push-redesign-app Maven Webapp</name>
+ <url>http://maven.apache.org</url>
+
+ <repositories>
+ <repository>
+ <id>sonatype.snapshots</id>
+
<
url>http://oss.sonatype.org/content/repositories/snapshots/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.7</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ <version>3.0-alpha-1</version>
+ <scope>provided</scope>
+ </dependency>
+ <!-- dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-websocket</artifactId>
+ <version>8.0.0.M1</version>
+ </dependency -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <version>0.6.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-api</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.faces</groupId>
+ <artifactId>jsf-impl</artifactId>
+ <version>2.0.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.sandbox.ui</groupId>
+ <artifactId>push-redesign</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.richfaces.ui.core</groupId>
+ <artifactId>richfaces-ui-core-ui</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <finalName>push-redesign-app</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.6</source>
+ <target>1.6</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.mortbay.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ <version>8.0.0.M1</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Added: branches/RF-7817/push-redesign-app/src/main/java/demo/Bean.java
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/java/demo/Bean.java
(rev 0)
+++ branches/RF-7817/push-redesign-app/src/main/java/demo/Bean.java 2010-10-11 16:06:07
UTC (rev 19520)
@@ -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 demo;
+
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.ManagedProperty;
+import javax.faces.bean.RequestScoped;
+
+import org.richfaces.application.push.PublisherContext;
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+@ManagedBean
+@RequestScoped
+public class Bean {
+
+ private String message;
+
+ @ManagedProperty("#{" + PublisherContext.ATTRIBUTE_NAME + "}")
+ private PublisherContext publisherContext;
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public void say() {
+ publisherContext.publish(new TopicKey("chat"), message);
+ }
+
+ /**
+ * @param publisherContext the publisherContext to set
+ */
+ public void setPublisherContext(PublisherContext publisherContext) {
+ this.publisherContext = publisherContext;
+ }
+}
Added: branches/RF-7817/push-redesign-app/src/main/webapp/META-INF/MANIFEST.MF
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/webapp/META-INF/MANIFEST.MF
(rev 0)
+++ branches/RF-7817/push-redesign-app/src/main/webapp/META-INF/MANIFEST.MF 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+
Added: branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/faces-config.xml
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/faces-config.xml
(rev 0)
+++ branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/faces-config.xml 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,6 @@
+<?xml version='1.0' encoding='UTF-8'?>
+
+<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
+ version="2.0">
+
+</faces-config>
\ No newline at end of file
Added: branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/jboss-scanning.xml
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/jboss-scanning.xml
(rev 0)
+++
branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/jboss-scanning.xml 2010-10-11
16:06:07 UTC (rev 19520)
@@ -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: branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/web.xml
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/web.xml
(rev 0)
+++ branches/RF-7817/push-redesign-app/src/main/webapp/WEB-INF/web.xml 2010-10-11 16:06:07
UTC (rev 19520)
@@ -0,0 +1,32 @@
+<?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>
+
+ <servlet>
+ <servlet-name>push</servlet-name>
+ <servlet-class>org.richfaces.webapp.PushServlet</servlet-class>
+ <load-on-startup>1</load-on-startup>
+ <async-supported>true</async-supported>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>push</servlet-name>
+ <url-pattern>/push/*</url-pattern>
+ </servlet-mapping>
+
+ <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: branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml
===================================================================
--- branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml
(rev 0)
+++ branches/RF-7817/push-redesign-app/src/main/webapp/index.xhtml 2010-10-11 16:06:07 UTC
(rev 19520)
@@ -0,0 +1,26 @@
+<!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:p="http://richfaces.org/push">
+
+ <h:head>
+ </h:head>
+ <h:body>
+ <p:push topic="chat" />
+
+ <h:outputText id="text" />
+
+ <h:form>
+ <h:inputText value="#{bean.message}" />
+
+ <h:commandLink value="ajax" action="#{bean.say}">
+ <f:ajax render=":text" execute="@form" />
+ </h:commandLink>
+ </h:form>
+
+ </h:body>
+</html>
\ No newline at end of file
Added:
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/MessageListener.java
===================================================================
---
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/MessageListener.java
(rev 0)
+++
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/MessageListener.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -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 MessageListener {
+
+ public void onMessage(Message message);
+
+}
Modified:
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/PublisherContext.java
===================================================================
---
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/PublisherContext.java 2010-10-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/PublisherContext.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -29,6 +29,8 @@
*/
public interface PublisherContext {
+ public static final String ATTRIBUTE_NAME = "__publisherContxt";
+
//TODO - return Future?
//TODO - use topic key?
public void publish(TopicKey topic, Object data);
Added:
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/SubscriptionContext.java
===================================================================
---
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/SubscriptionContext.java
(rev 0)
+++
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/SubscriptionContext.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -0,0 +1,34 @@
+/*
+ * 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 SubscriptionContext {
+
+ public void addMessageListener(TopicKey topicKey, MessageListener listener);
+
+ public void removeMessageListener(TopicKey topicKey, MessageListener listener);
+
+}
Deleted:
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueueSettings.java
===================================================================
---
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueueSettings.java 2010-10-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueueSettings.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -1,61 +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.application.push;
-
-
-/**
- * @author Nick Belaevski
- *
- */
-public interface TopicQueueSettings {
-
- public void addMessageTransformer(MessageTransformer transformer);
-
- public void removeMessageTransformer(MessageTransformer transformer);
-
- public void setMessageSerializer(MessageSerializer serializer);
-
- public MessageSerializer getMessageSerializer();
-
- public void addMessageFilter(MessageFilter filter);
-
- public void removeMessageFilter(MessageFilter filter);
-
- public boolean isSessionAware();
-
- public void setSessionAware(boolean sessionAware);
-
- public boolean isFacesContextAware();
-
- public void setFacesContextAware(boolean facesContextAware);
-
- public TopicMode getDeliveryMode();
-
- public void setDeliveryMode(TopicMode mode);
-
- public int getCapacity();
-
- public void setCapacity(int capacity);
-
- //TODO - transport settings?
-
-}
Deleted:
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueuesContext.java
===================================================================
---
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueuesContext.java 2010-10-11
14:13:05 UTC (rev 19519)
+++
branches/RF-7817/ui/core/api/src/main/java/org/richfaces/application/push/TopicQueuesContext.java 2010-10-11
16:06:07 UTC (rev 19520)
@@ -1,35 +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.application.push;
-
-/**
- * @author Nick Belaevski
- *
- */
-public interface TopicQueuesContext {
-
- public TopicQueueSettings getTopicQueueSettings(TopicKey topicKey);
-
- public TopicQueueSettings getDefaultTopicQueueSettings();
-
-}
-