Author: nbelaevski
Date: 2010-11-01 19:43:58 -0400 (Mon, 01 Nov 2010)
New Revision: 19869
Added:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms/
branches/RF-7817/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java
Removed:
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DummyPushContextFactory.java
Modified:
branches/RF-7817/core/impl/
branches/RF-7817/core/impl/pom.xml
branches/RF-7817/core/impl/richfaces-suppressions.xml
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DefaultModule.java
Log:
https://jira.jboss.org/browse/RF-9158
Deleted:
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java
===================================================================
---
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java 2010-11-01
23:42:34 UTC (rev 19868)
+++
branches/RF-7817/core/api/src/main/java/org/ajax4jsf/event/PushEventListener.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -1,31 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-package org.ajax4jsf.event;
-
-import java.util.EventListener;
-import java.util.EventObject;
-
-public interface PushEventListener extends EventListener {
- public void onEvent(EventObject event);
-}
Property changes on: branches/RF-7817/core/impl
___________________________________________________________________
Name: svn:ignore
- target
.settings
.project
.classpath
.clover
.externalToolBuilders
+ target
.settings
.project
.classpath
.clover
.externalToolBuilders
bin
Modified: branches/RF-7817/core/impl/pom.xml
===================================================================
--- branches/RF-7817/core/impl/pom.xml 2010-11-01 23:42:34 UTC (rev 19868)
+++ branches/RF-7817/core/impl/pom.xml 2010-11-01 23:43:58 UTC (rev 19869)
@@ -87,6 +87,18 @@
<optional>true</optional>
</dependency>
+ <!-- Push dependencies -->
+ <dependency>
+ <groupId>org.atmosphere</groupId>
+ <artifactId>atmosphere-runtime</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>javax.jms</groupId>
+ <artifactId>jms</artifactId>
+ <optional>true</optional>
+ </dependency>
+
<!-- Test Dependencies -->
<dependency>
<groupId>org.jboss.test-jsf</groupId>
Modified: branches/RF-7817/core/impl/richfaces-suppressions.xml
===================================================================
--- branches/RF-7817/core/impl/richfaces-suppressions.xml 2010-11-01 23:42:34 UTC (rev
19868)
+++ branches/RF-7817/core/impl/richfaces-suppressions.xml 2010-11-01 23:43:58 UTC (rev
19869)
@@ -16,4 +16,5 @@
<suppress checks="IllegalCatch"
files="ResourceHandlerImpl.java" />
<suppress checks="IllegalThrows"
files="AbstractThreadedTest.java" />
<suppress checks="ModifiedControlVariable"
files="URLCodec.java" />
+ <suppress checks="IllegalCatch" files="AbstractRequest.java"
/>
</suppressions>
Deleted:
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java 2010-11-01
23:42:34 UTC (rev 19868)
+++
branches/RF-7817/core/impl/src/main/java/org/ajax4jsf/webapp/PushEventsCounter.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -1,53 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.ajax4jsf.webapp;
-
-import java.io.Serializable;
-import java.util.EventObject;
-
-import org.ajax4jsf.event.PushEventListener;
-
-public class PushEventsCounter implements PushEventListener, Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = 4060284352186710009L;
- private volatile boolean performed = false;
-
- public void onEvent(EventObject event) {
- performed = true;
- }
-
- /**
- * @return the performed
- */
- public boolean isPerformed() {
- return performed;
- }
-
- /**
- */
- public void processed() {
- this.performed = false;
- }
-}
Modified:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DefaultModule.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DefaultModule.java 2010-11-01
23:42:34 UTC (rev 19868)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DefaultModule.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -3,6 +3,7 @@
import org.richfaces.application.configuration.ConfigurationService;
import org.richfaces.application.configuration.ConfigurationServiceImpl;
import org.richfaces.application.push.PushContextFactory;
+import org.richfaces.application.push.impl.jms.PushContextFactoryImpl;
import org.richfaces.cache.Cache;
import org.richfaces.l10n.BundleLoader;
import org.richfaces.renderkit.AjaxDataSerializer;
@@ -28,7 +29,7 @@
factory.setInstance(ResourceLibraryFactory.class, new
ResourceLibraryFactoryImpl());
//TODO add default implementation class name
- factory.setInstance(PushContextFactory.class,
ServiceLoader.loadService(PushContextFactory.class, DummyPushContextFactory.class));
+ factory.setInstance(PushContextFactory.class,
ServiceLoader.loadService(PushContextFactory.class, PushContextFactoryImpl.class));
}
}
Deleted:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DummyPushContextFactory.java
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DummyPushContextFactory.java 2010-11-01
23:42:34 UTC (rev 19868)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/DummyPushContextFactory.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -1,38 +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;
-
-import org.richfaces.application.push.PushContext;
-import org.richfaces.application.push.PushContextFactory;
-
-/**
- * @author Nick Belaevski
- *
- */
-//TODO - remove after push-redesign project merge
-public class DummyPushContextFactory implements PushContextFactory {
-
- public PushContext getPushContext() {
- throw new UnsupportedOperationException();
- }
-
-}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractRequest.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,231 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.ajax4jsf.javascript.JSLiteral;
+import org.ajax4jsf.javascript.ScriptString;
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.atmosphere.cpr.AtmosphereEventLifecycle;
+import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.atmosphere.cpr.AtmosphereResourceEventListener;
+import org.atmosphere.websocket.WebSocketSupport;
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractRequest implements Request {
+
+ private static final String TOPIC_KEY = "topic";
+
+ private static final String DATA_KEY = "data";
+
+ private static final int SUSPEND_TIMEOUT = 30 * 1000;
+
+ private static final class Message implements ScriptString {
+
+ private TopicKey topicKey;
+
+ private String serializedData;
+
+ public Message(TopicKey topicKey, String serializedData) {
+ super();
+ this.topicKey = topicKey;
+ this.serializedData = serializedData;
+ }
+
+ public String toScript() {
+ Map<String,Object> map = new HashMap<String, Object>(2);
+
+ map.put(TOPIC_KEY, topicKey.getTopicAddress());
+ map.put(DATA_KEY, new JSLiteral(serializedData));
+
+ return ScriptUtils.toScript(map);
+ }
+
+ public void appendScript(StringBuffer functionString) {
+ functionString.append(toScript());
+ }
+ }
+
+ private static final class FlushMessagesTask implements Runnable {
+
+ private Request request;
+
+ public FlushMessagesTask(Request request) {
+ super();
+ this.request = request;
+ }
+
+ public void run() {
+ try {
+ request.flushMessages();
+ } catch (Throwable e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ private final AtmosphereResourceEventListener resourceEventListener = new
AtmosphereResourceEventListener() {
+
+ public void onSuspend(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ AbstractRequest.this.onSuspend();
+ }
+
+ public void onResume(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ AbstractRequest.this.onResume();
+ }
+
+ public void onDisconnect(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ AbstractRequest.this.onDisconnect();
+ }
+
+ public void onBroadcast(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event) {
+ AbstractRequest.this.onBroadcast();
+ }
+ };
+
+ private final AtmosphereResource<HttpServletRequest, HttpServletResponse>
atmosphereResource;
+
+ private final Session session;
+
+ private final ExecutorService executorService;
+
+ private final Queue<Message> messagesQueue = new
ConcurrentLinkedQueue<Message>();
+
+ private AtomicBoolean submitted = new AtomicBoolean(false);
+
+ public AbstractRequest(AtmosphereResource<HttpServletRequest,
HttpServletResponse> atmosphereResource, Session session,
+ ExecutorService executorService) {
+
+ super();
+
+ this.atmosphereResource = atmosphereResource;
+
+ ((AtmosphereEventLifecycle)
atmosphereResource).addEventListener(resourceEventListener);
+
+ this.session = session;
+ this.executorService = executorService;
+ }
+
+ private void submitToWorker() {
+ if (submitted.compareAndSet(false, true)) {
+ executorService.submit(new FlushMessagesTask(this));
+ }
+ }
+
+ private String serializeMessages() {
+ return ScriptUtils.toScript(new
ConsumingCollection<Message>(messagesQueue));
+ }
+
+ public void flushMessages() throws IOException {
+ String serializedMessages = serializeMessages();
+ PrintWriter writer = atmosphereResource.getResponse().getWriter();
+ writer.write(serializedMessages);
+ writer.flush();
+
+ submitted.compareAndSet(true, false);
+
+ if (isPolling()) {
+ atmosphereResource.resume();
+ } else if (!messagesQueue.isEmpty()) {
+ submitToWorker();
+ }
+ }
+
+ public void postMessage(TopicKey topicKey, String serializedMessage) {
+ messagesQueue.add(new Message(topicKey, serializedMessage));
+ submitToWorker();
+ }
+
+ public void suspend() throws IOException {
+ atmosphereResource.suspend(SUSPEND_TIMEOUT, isPolling());
+ }
+
+ public void resume() throws IOException {
+ atmosphereResource.resume();
+ }
+
+ public boolean isSuspended() {
+ return atmosphereResource.getAtmosphereResourceEvent().isSuspended();
+ }
+
+ public boolean isPolling() {
+ HttpServletRequest req = atmosphereResource.getRequest();
+ boolean isWebsocket = req.getAttribute(WebSocketSupport.WEBSOCKET_SUSPEND) !=
null ||
+ req.getAttribute(WebSocketSupport.WEBSOCKET_RESUME) != null;
+
+ //TODO how to detect non-polling transports?
+ return !isWebsocket;
+ }
+
+ public Session getSession() {
+ return session;
+ }
+
+ protected AtmosphereResource<HttpServletRequest, HttpServletResponse>
getResource() {
+ return atmosphereResource;
+ }
+
+ protected void onSuspend() {
+ }
+
+ protected void onResume() {
+ try {
+ session.disconnect();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected void onDisconnect() {
+ try {
+ session.disconnect();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ protected void onBroadcast() {
+ }
+
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AbstractSession.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractSession.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,115 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.io.IOException;
+
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionManager;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractSession implements Session {
+
+ private static final int MAX_INACTIVE_INTERVAL = 5 * 60 * 1000;
+
+ private final String id;
+
+ private final SessionManager sessionManager;
+
+ private volatile long lastAccessedTime;
+
+ private volatile Request request;
+
+ public AbstractSession(String id, SessionManager sessionManager) {
+ super();
+ this.id = id;
+ this.sessionManager = sessionManager;
+
+ resetLastAccessedTimeToCurrent();
+ }
+
+ private void resetLastAccessedTimeToCurrent() {
+ lastAccessedTime = System.currentTimeMillis();
+ }
+
+ private void requeue() {
+ resetLastAccessedTimeToCurrent();
+ sessionManager.requeue(this);
+ }
+
+ public void connect(Request request) throws Exception {
+ if (this.request != null) {
+ this.request.resume();
+ }
+
+ this.request = request;
+
+ requeue();
+
+ request.suspend();
+ }
+
+ public void disconnect() throws Exception {
+ this.request = null;
+ }
+
+ public long getLastAccessedTime() {
+ if (request != null) {
+ return System.currentTimeMillis();
+ }
+
+ return lastAccessedTime;
+ }
+
+ public int getMaxInactiveInterval() {
+ return MAX_INACTIVE_INTERVAL;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Request getRequest() {
+ return request;
+ }
+
+ public void destroy() {
+ if (request != null) {
+ try {
+ request.resume();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ request = null;
+ //TODO - clean up request
+ }
+
+ sessionManager.removePushSession(this);
+ // TODO Auto-generated method stub
+
+ }
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AbstractTopic.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.richfaces.application.push.EventAbortedException;
+import org.richfaces.application.push.MessageDataSerializer;
+import org.richfaces.application.push.MessageException;
+import org.richfaces.application.push.Topic;
+import org.richfaces.application.push.TopicEvent;
+import org.richfaces.application.push.TopicKey;
+import org.richfaces.application.push.TopicListener;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AbstractTopic implements Topic {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private TopicKey key;
+
+ private volatile MessageDataSerializer serializer;
+
+ private volatile boolean allowSubtopics;
+
+ private List<TopicListener> listeners = new
CopyOnWriteArrayList<TopicListener>();
+
+ public AbstractTopic(TopicKey key) {
+ super();
+ this.key = key;
+ }
+
+ public MessageDataSerializer getMessageDataSerializer() {
+ if (serializer == null) {
+ return DefaultMessageDataSerializer.instance();
+ }
+
+ return serializer;
+ }
+
+ public void setMessageDataSerializer(MessageDataSerializer serializer) {
+ this.serializer = serializer;
+ }
+
+ public boolean isAllowSubtopics() {
+ return allowSubtopics;
+ }
+
+ public void setAllowSubtopics(boolean allowSubtopics) {
+ this.allowSubtopics = allowSubtopics;
+ }
+
+ public TopicKey getKey() {
+ return key;
+ }
+
+ public void addTopicListener(TopicListener topicListener) {
+ listeners.add(topicListener);
+ }
+
+ public void removeTopicListener(TopicListener topicListener) {
+ listeners.remove(topicListener);
+ }
+
+ public void publishEvent(TopicEvent event) throws EventAbortedException {
+ for (TopicListener listener: listeners) {
+ if (event.isAppropriateListener(listener)) {
+ try {
+ event.invokeListener(listener);
+ } catch (EventAbortedException e) {
+ throw e;
+ } catch (Exception e) {
+ LOGGER.error(MessageFormat.format("Exception invoking listener:
{0}", e.getMessage()), e);
+ }
+ }
+ }
+ }
+
+ public abstract void publish(String subtopic, Object messageData) throws
MessageException;
+
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmosphereHandlerProvider.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereHandler;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public interface AtmosphereHandlerProvider {
+
+ public AtmosphereHandler<HttpServletRequest, HttpServletResponse>
getHandler();
+
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/AtmospherePushHandler.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereHandler;
+import org.atmosphere.cpr.AtmosphereResource;
+import org.atmosphere.cpr.AtmosphereResourceEvent;
+import org.richfaces.application.push.Request;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionManager;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public abstract class AtmospherePushHandler implements
AtmosphereHandler<HttpServletRequest, HttpServletResponse> {
+
+ private static final ThreadFactory DAEMON_THREADS_FACTORY = new ThreadFactory() {
+
+ private final AtomicInteger threadsCounter = new AtomicInteger();
+
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, "rf-push-worker-thread-" +
threadsCounter.getAndIncrement());
+ t.setDaemon(true);
+
+ return t;
+ }
+ };
+
+ private static final String PUSH_SESSION_ID_PARAM = "pushSessionId";
+
+ private SessionManager sessionManager;
+
+ private ExecutorService worker;
+
+ public AtmospherePushHandler() {
+ super();
+
+ sessionManager = new SessionManagerImpl(DAEMON_THREADS_FACTORY);
+ worker = Executors.newCachedThreadPool(DAEMON_THREADS_FACTORY);
+ }
+
+ public SessionManager getSessionManager() {
+ return sessionManager;
+ }
+
+ public void onRequest(AtmosphereResource<HttpServletRequest,
HttpServletResponse> resource) throws IOException {
+ // TODO Auto-generated method stub
+
+ HttpServletRequest req = resource.getRequest();
+ HttpServletResponse resp = resource.getResponse();
+
+ String pushSessionId = req.getParameter(PUSH_SESSION_ID_PARAM);
+
+ Session session = null;
+
+ if (pushSessionId != null) {
+ session = getSessionManager().getPushSession(pushSessionId);
+ }
+
+ if (session == null) {
+ //TODO - debug log
+ resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ resp.setContentType("text/plain");
+
+ try {
+ session.connect(createRequest(resource, session));
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+ public void onStateChange(AtmosphereResourceEvent<HttpServletRequest,
HttpServletResponse> event)
+ throws IOException {
+ //do nothing
+ }
+
+ protected abstract Request createRequest(AtmosphereResource<HttpServletRequest,
HttpServletResponse> resource, Session session);
+
+ protected ExecutorService getWorker() {
+ return worker;
+ }
+
+ public void init(ServletConfig servletConfig) throws Exception {
+ }
+
+ public void destroy() throws Exception {
+ sessionManager.destroy();
+ }
+
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/ConsumingCollection.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,64 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.util.AbstractCollection;
+import java.util.Iterator;
+import java.util.Queue;
+
+import com.google.common.collect.AbstractIterator;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class ConsumingCollection<T> extends AbstractCollection<T> {
+
+ private final class ConsumingIterator extends AbstractIterator<T> {
+ @Override
+ protected T computeNext() {
+ T next = queue.poll();
+ if (next == null) {
+ endOfData();
+ }
+ return next;
+ }
+ }
+
+ private Queue<T> queue;
+
+ public ConsumingCollection(Queue<T> queue) {
+ super();
+ this.queue = queue;
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return new ConsumingIterator();
+ }
+
+ @Override
+ public int size() {
+ return queue.size();
+ }
+
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/DefaultMessageDataSerializer.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,44 @@
+package org.richfaces.application.push.impl;
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.application.push.MessageDataSerializer;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public final class DefaultMessageDataSerializer implements MessageDataSerializer {
+
+ private static final MessageDataSerializer INSTANCE = new
DefaultMessageDataSerializer();
+
+ private DefaultMessageDataSerializer() {}
+
+ public static MessageDataSerializer instance() {
+ return INSTANCE;
+ }
+
+ public String serialize(Object data) {
+ return ScriptUtils.toScript(data);
+ }
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionManagerImpl.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ThreadFactory;
+
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.SessionManager;
+import org.richfaces.log.Logger;
+import org.richfaces.log.RichfacesLogger;
+
+import com.google.common.collect.MapMaker;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class SessionManagerImpl implements SessionManager {
+
+ private static final Logger LOGGER = RichfacesLogger.APPLICATION.getLogger();
+
+ private final class SessionsExpirationRunnable implements Runnable {
+ public void run() {
+ while (true) {
+ try {
+ Session session = sessionQueue.take();
+ sessionMap.remove(session.getId());
+ session.destroy();
+ } catch (InterruptedException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+ }
+
+ }
+ }
+
+ private ConcurrentMap<String, Session> sessionMap = new MapMaker().makeMap();
+
+ private SessionQueue sessionQueue = new SessionQueue();
+
+ public SessionManagerImpl(ThreadFactory threadFactory) {
+ threadFactory.newThread(new SessionsExpirationRunnable()).start();
+ }
+
+ public Session getPushSession(String id) {
+ return sessionMap.get(id);
+ }
+
+ public void removePushSession(Session session) {
+ sessionMap.remove(session.getId());
+ if (session != null) {
+ sessionQueue.remove(session);
+ }
+ }
+
+ public void destroy() {
+ //TODO notify all session
+ sessionQueue.clear();
+
+ while (!sessionMap.isEmpty()) {
+ for (Iterator<Session> sessionsItr = sessionMap.values().iterator();
sessionsItr.hasNext(); ) {
+ Session session = sessionsItr.next();
+ sessionsItr.remove();
+
+ session.destroy();
+ }
+ }
+
+ sessionMap.clear();
+ }
+
+ public void putPushSession(Session session) throws IllegalStateException {
+ Session existingSession = sessionMap.putIfAbsent(session.getId(), session);
+ if (existingSession != null) {
+ throw new IllegalStateException();
+ }
+
+ requeue(session);
+ }
+
+ public void requeue(Session session) {
+ sessionQueue.requeue(session);
+ }
+}
Copied:
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/SessionQueue.java)
===================================================================
---
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/SessionQueue.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.application.push.impl;
+
+import java.util.Comparator;
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.richfaces.application.push.Session;
+
+/**
+ * Based on DelayQueue by Doug Lea:
http://gee.cs.oswego.edu/
+ * @author Nick Belaevski
+ *
+ */
+//TODO - optimize algorithm
+final class SessionQueue {
+
+ private static final Comparator<? super Session> SESSIONS_COMPARATOR = new
Comparator<Session>() {
+
+ public int compare(Session o1, Session o2) {
+ Long delay1 = Long.valueOf(o1.getLastAccessedTime() +
o1.getMaxInactiveInterval());
+ Long delay2 = Long.valueOf(o2.getLastAccessedTime() +
o2.getMaxInactiveInterval());
+
+ return delay1.compareTo(delay2);
+ }
+
+ };
+
+ private final Queue<Session> queue = new PriorityQueue<Session>(1,
SESSIONS_COMPARATOR);
+
+ private final ReentrantLock lock = new ReentrantLock();
+
+ private final Condition available = lock.newCondition();
+
+ private long getDelay(Session session, TimeUnit unit) {
+ return unit.convert(session.getLastAccessedTime() +
session.getMaxInactiveInterval() - System.currentTimeMillis(),
+ TimeUnit.MILLISECONDS);
+ }
+
+ public Session take() throws InterruptedException {
+ final ReentrantLock lock = this.lock;
+ lock.lockInterruptibly();
+ try {
+ while (true) {
+ Session first = queue.peek();
+ if (first == null) {
+ available.await();
+ } else {
+ long delay = getDelay(first, TimeUnit.NANOSECONDS);
+ if (delay > 0) {
+ available.awaitNanos(delay);
+ } else {
+ Session x = queue.poll();
+ assert x != null;
+ if (queue.size() != 0) {
+ available.signalAll(); // wake up other takers
+ }
+ return x;
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ }
+
+ public void remove(Session session) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ queue.remove(session);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void requeue(Session session) {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ queue.remove(session);
+
+ Session first = queue.peek();
+ queue.offer(session);
+ if (first == null || SESSIONS_COMPARATOR.compare(session, first) < 0) {
+ available.signalAll();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void clear() {
+ final ReentrantLock lock = this.lock;
+ lock.lock();
+ try {
+ queue.clear();
+ } finally {
+ lock.unlock();
+ }
+ }
+}
Copied: branches/RF-7817/core/impl/src/main/java/org/richfaces/application/push/impl/jms
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/jms)
Copied: branches/RF-7817/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/webapp/PushFilter.java)
===================================================================
--- branches/RF-7817/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java
(rev 0)
+++
branches/RF-7817/core/impl/src/main/java/org/richfaces/webapp/PushFilter.java 2010-11-01
23:43:58 UTC (rev 19869)
@@ -0,0 +1,159 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.webapp;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.atmosphere.cpr.AtmosphereServlet;
+import org.richfaces.application.push.PushContext;
+import org.richfaces.application.push.impl.AtmosphereHandlerProvider;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Sets;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+//TODO override broadcaster
+public class PushFilter implements Filter {
+
+ private static final String PUSH_HUB_MAPPING = "/*";
+
+ private static final long serialVersionUID = 7616370505508715222L;
+
+ /**
+ * @author Nick Belaevski
+ *
+ */
+ private final class ServletConfigFacade implements ServletConfig {
+ /**
+ *
+ */
+ private final FilterConfig filterConfig;
+
+ /**
+ * @param filterConfig
+ */
+ private ServletConfigFacade(FilterConfig filterConfig) {
+ this.filterConfig = filterConfig;
+ }
+
+ public String getServletName() {
+ return filterConfig.getFilterName();
+ }
+
+ public ServletContext getServletContext() {
+ return filterConfig.getServletContext();
+ }
+
+ public String getInitParameter(String name) {
+ String result = filterConfig.getInitParameter(name);
+
+ if (result == null) {
+ result = filterConfig.getServletContext().getInitParameter(name);
+ }
+
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Enumeration<String> getInitParameterNames() {
+ Set<String> result = Sets.newLinkedHashSet();
+
+ result.addAll(Collections.list(filterConfig.getInitParameterNames()));
+
result.addAll(Collections.list(filterConfig.getServletContext().getInitParameterNames()));
+
+ return Iterators.asEnumeration(result.iterator());
+ }
+ }
+
+ private AtmosphereServlet atmosphereServlet;
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+ AtmosphereHandlerProvider handlerProvider = (AtmosphereHandlerProvider)
filterConfig.getServletContext().getAttribute(PushContext.INSTANCE_KEY_NAME);
+
+ if (handlerProvider == null) {
+ return;
+ }
+
+ atmosphereServlet = new AtmosphereServlet() {
+
+ private static final long serialVersionUID = -8719394110408476331L;
+
+ protected boolean detectSupportedFramework(ServletConfig sc) throws
ClassNotFoundException, IllegalAccessException, InstantiationException
,NoSuchMethodException ,java.lang.reflect.InvocationTargetException {
+ return false;
+ };
+ };
+ ServletConfigFacade servletConfig = new ServletConfigFacade(filterConfig);
+ atmosphereServlet.init(servletConfig);
+
+ atmosphereServlet.addAtmosphereHandler(PUSH_HUB_MAPPING,
handlerProvider.getHandler());
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain
chain) throws IOException,
+ ServletException {
+
+ if (atmosphereServlet != null && request instanceof HttpServletRequest
&& response instanceof HttpServletResponse) {
+ HttpServletRequest httpReq = (HttpServletRequest) request;
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+
+ if ("GET".equals(httpReq.getMethod()) &&
httpReq.getQueryString() != null &&
httpReq.getQueryString().contains("__richfacesPushAsync")) {
+ atmosphereServlet.doGet(httpReq, httpResp);
+ return;
+ }
+ }
+
+ // TODO Auto-generated method stub
+ chain.doFilter(request, response);
+ }
+
+ /* (non-Javadoc)
+ * @see javax.servlet.Filter#destroy()
+ */
+ public void destroy() {
+ if (atmosphereServlet != null) {
+ atmosphereServlet.removeAtmosphereHandler(PUSH_HUB_MAPPING);
+ atmosphereServlet.destroy();
+ atmosphereServlet = null;
+ }
+ // TODO Auto-generated method stub
+ }
+
+}