Author: nbelaevski
Date: 2010-11-01 19:47:24 -0400 (Mon, 01 Nov 2010)
New Revision: 19870
Added:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere/
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
Removed:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml
Log:
https://jira.jboss.org/browse/RF-9158
Deleted:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,123 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-package org.richfaces.component;
-
-import java.io.IOException;
-import java.util.EventListener;
-
-import javax.el.MethodExpression;
-import javax.faces.component.NamingContainer;
-import javax.faces.context.FacesContext;
-import javax.servlet.http.HttpSession;
-
-import org.richfaces.cdk.annotations.Attribute;
-import org.richfaces.cdk.annotations.EventName;
-import org.richfaces.cdk.annotations.JsfComponent;
-import org.richfaces.cdk.annotations.JsfRenderer;
-import org.richfaces.cdk.annotations.Signature;
-import org.richfaces.cdk.annotations.Tag;
-import org.richfaces.cdk.annotations.TagType;
-
-/**
- * Component for periodically call AJAX events on server ( poll actions )
- * @author shura
- *
- */
-@JsfComponent(
- tag = @Tag(generate = false, handler =
"org.richfaces.view.facelets.html.AjaxPushHandler", type = TagType.Facelets),
- renderer = @JsfRenderer(type = "org.richfaces.PushRenderer")
-)
-public abstract class AbstractPush extends AbstractActionComponent {
-
- public static final String COMPONENT_TYPE = "org.richfaces.Push";
-
- public static final String COMPONENT_FAMILY = "org.richfaces.Push";
-
- public static final String DATA_AVAILABLE = "dataAvailable";
-
- public static final String ON_DATA_AVAILABLE = "ondataavailable";
-
- @Override
- public void encodeBegin(FacesContext context) throws IOException {
- MethodExpression producer = getEventProducer();
-
- // Subscribe events producer to push status listener.
- if (null != producer) {
- producer.invoke(context.getELContext(), new Object[]
{getListener(context)});
- }
-
- super.encodeBegin(context);
- }
-
- private PushEventTracker getListener(FacesContext context) {
- PushListenersManager pushListenersManager =
PushListenersManager.getInstance(context);
-
- return pushListenersManager.getListener(getListenerId(context));
- }
-
- public String getListenerId(FacesContext context) {
- Object session = context.getExternalContext().getSession(false);
- StringBuffer id = new StringBuffer();
-
- if (null != session && session instanceof HttpSession) {
- HttpSession httpSession = (HttpSession) session;
-
- id.append(httpSession.getId());
- }
-
- id.append(context.getViewRoot().getViewId());
- id.append(NamingContainer.SEPARATOR_CHAR);
- id.append(getClientId(context));
-
- return id.toString();
- }
-
- // ---------------------------------------
- @Attribute(signature = @Signature(parameters = EventListener.class))
- public abstract MethodExpression getEventProducer();
-
- public abstract void setEventProducer(MethodExpression producer);
-
- /**
- * @return time in mc for polling interval.
- */
- @Attribute(defaultValue = "1000")
- public abstract int getInterval();
-
- @Attribute(defaultValue = "true")
- public abstract boolean isEnabled();
-
- // TODO what wrong with that name?
- @Attribute(events = @EventName(value = DATA_AVAILABLE, defaultEvent = true))
- public abstract String getOndataavailable();
-
- @Attribute(events = @EventName("begin"))
- public abstract String getOnbegin();
-
- @Attribute(events = @EventName("beforedomupdate"))
- public abstract String getOnbeforedomupdate();
-
- @Attribute(events = @EventName("complete"))
- public abstract String getOncomplete();
-}
Copied:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java (from
rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/component/AbstractPush.java)
===================================================================
--- branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java
(rev 0)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/AbstractPush.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.component;
+
+import javax.faces.component.UIComponentBase;
+
+import org.richfaces.cdk.annotations.Attribute;
+import org.richfaces.cdk.annotations.EventName;
+import org.richfaces.cdk.annotations.JsfComponent;
+import org.richfaces.cdk.annotations.JsfRenderer;
+import org.richfaces.cdk.annotations.Tag;
+import org.richfaces.cdk.annotations.TagType;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+@JsfComponent(type = AbstractPush.COMPONENT_TYPE, family = AbstractPush.COMPONENT_FAMILY,
tag = @Tag(name = "push", type = TagType.Facelets),
+ renderer = @JsfRenderer(type = "org.richfaces.PushRenderer"))
+public abstract class AbstractPush extends UIComponentBase {
+
+ public static final String COMPONENT_TYPE = "org.richfaces.Push";
+
+ public static final String COMPONENT_FAMILY = "org.richfaces.Push";
+
+ @Override
+ public String getFamily() {
+ return COMPONENT_FAMILY;
+ }
+
+ @Attribute(required = true)
+ public abstract String getAddress();
+
+ @Attribute(events = {@EventName("dataavailable")})
+ public abstract String getOndataavailable();
+
+ @Attribute(events = {@EventName("error")})
+ public abstract String getOnerror();
+}
Deleted:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushEventTracker.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,52 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-package org.richfaces.component;
-
-import java.io.Serializable;
-
-import java.util.EventObject;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.ajax4jsf.event.PushEventListener;
-
-/**
- * @author Nick Belaevski
- * @since 4.0
- */
-public class PushEventTracker implements PushEventListener, Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = -4362297582678089326L;
- private final AtomicBoolean eventPerformed = new AtomicBoolean(false);
-
- public void onEvent(EventObject event) {
- eventPerformed.set(true);
- }
-
- public boolean pollStatus() {
- return eventPerformed.compareAndSet(true, false);
- }
-}
Deleted:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/component/PushListenersManager.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,66 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-
-package org.richfaces.component;
-
-import java.util.Map;
-
-import javax.faces.context.FacesContext;
-
-import org.richfaces.util.LRUMap;
-
-/**
- * @author Nick Belaevski
- * @since 4.0
- */
-public class PushListenersManager {
-
- private static final String CONTEXT_ATTRIBUTE_NAME =
"richFacesPushListenersManager";
-
- private Map<String, PushEventTracker> listeners;
-
- public PushListenersManager() {
-
- // TODO configure map size
- this.listeners = new LRUMap<String, PushEventTracker>();
- }
-
- public static PushListenersManager getInstance(FacesContext context) {
- return (PushListenersManager)
context.getExternalContext().getApplicationMap().get(CONTEXT_ATTRIBUTE_NAME);
- }
-
- public PushEventTracker getListener(String name) {
- synchronized (listeners) {
-
- // LRUMap involves write for each operation, so RWLock is not acceptable
here
- PushEventTracker listener = listeners.get(name);
-
- if (listener == null) {
- listener = new PushEventTracker();
- listeners.put(name, listener);
- }
-
- return listener;
- }
- }
-}
Copied:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/renderkit/PushRendererBase.java)
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java
(rev 0)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/PushRendererBase.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.richfaces.renderkit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.application.Resource;
+import javax.faces.application.ResourceHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.component.AbstractPush;
+import org.richfaces.resource.PushResource;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+public class PushRendererBase extends Renderer {
+
+ private static final String PUSH_URL_ENCODED_ATTRIBUTE =
PushRendererBase.class.getName();
+
+ protected String getPushUrl(FacesContext context) {
+ ResourceHandler resourceHandler = context.getApplication().getResourceHandler();
+ Resource pushResource =
resourceHandler.createResource(PushResource.class.getName());
+
+ return pushResource.getRequestPath();
+ }
+
+ protected boolean shouldEncodePushUrl(FacesContext context) {
+ Map<Object, Object> attributes = context.getAttributes();
+
+ if (attributes.get(PUSH_URL_ENCODED_ATTRIBUTE) == null) {
+ attributes.put(PUSH_URL_ENCODED_ATTRIBUTE, Boolean.TRUE);
+ return true;
+ }
+
+ return false;
+ }
+
+ protected String getOptionsString(FacesContext context, UIComponent component) {
+ AbstractPush push = (AbstractPush) component;
+
+ Map<String, Object> options = new HashMap<String, Object>(2);
+
+ options.put("address", push.getAddress());
+ options.put("dataHandler", push.getOndataavailable());
+ options.put("errorHandler", push.getOnerror());
+
+ return ScriptUtils.toScript(options);
+ }
+}
Deleted:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/renderkit/html/AjaxPushRenderer.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,153 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.renderkit.html;
-
-import static org.richfaces.renderkit.RenderKitUtils.shouldRenderAttribute;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.faces.application.ResourceDependency;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-import javax.faces.context.ResponseWriter;
-import javax.faces.event.ActionEvent;
-
-import org.ajax4jsf.javascript.JSFunction;
-import org.ajax4jsf.javascript.JSFunctionDefinition;
-import org.ajax4jsf.javascript.JSReference;
-import org.richfaces.cdk.annotations.JsfRenderer;
-import org.richfaces.component.AbstractPush;
-import org.richfaces.renderkit.HtmlConstants;
-import org.richfaces.renderkit.RendererBase;
-import org.richfaces.renderkit.util.HandlersChain;
-import org.richfaces.resource.PushResource;
-
-/**
- * @author shura
- */
-@ResourceDependency(library = "org.richfaces", name = "ajax.reslib")
-@JsfRenderer
-public class AjaxPushRenderer extends RendererBase {
-
- public static final String COMPONENT_FAMILY = "org.richfaces.Push";
-
- public static final String RENDERER_TYPE = "org.richfaces.PushRenderer";
-
- public static final String PUSH_INTERVAL_PARAMETER =
"A4J.AJAX.Push.INTERVAL";
-
- public static final int DEFAULT_PUSH_INTERVAL = 1000;
-
- public static final int DEFAULT_PUSH_WAIT = Integer.MIN_VALUE;
-
- @Override
- protected void queueComponentEventForBehaviorEvent(FacesContext context, UIComponent
component, String eventName) {
- super.queueComponentEventForBehaviorEvent(context, component, eventName);
-
- if (AbstractPush.DATA_AVAILABLE.equals(eventName)) {
- new ActionEvent(component).queue();
- }
- }
-
- /* (non-Javadoc)
- * @see
org.ajax4jsf.renderkit.RendererBase#doEncodeEnd(javax.faces.context.ResponseWriter,
- * javax.faces.context.FacesContext, javax.faces.component.UIComponent)
- */
- protected void doEncodeEnd(ResponseWriter writer, FacesContext context, UIComponent
component) throws IOException {
- AbstractPush push = (AbstractPush) component;
- writer.startElement(HtmlConstants.SPAN_ELEM, component);
- writer.writeAttribute(HtmlConstants.STYLE_ATTRIBUTE, "display:none;",
null);
- getUtils().encodeId(context, component);
-
- //TODO - ?
- getUtils().encodeBeginFormIfNessesary(context, component);
- // pushing script.
- writer.startElement(HtmlConstants.SCRIPT_ELEM, component);
- writer.writeAttribute(HtmlConstants.TYPE_ATTR, "text/javascript",
null);
- StringBuffer script = new StringBuffer("\n");
- if (push.isEnabled()) {
- JSFunction function = new JSFunction("RichFaces.startPush");
- // Set dummy form id, if nessesary.
- Map<String, Object> options = new HashMap<String, Object>();
-
- int interval = push.getInterval();
- if (shouldRenderAttribute(interval)) {
- String intervalInitParameter =
context.getExternalContext().getInitParameter(PUSH_INTERVAL_PARAMETER);
- if (null != intervalInitParameter) {
- interval = Integer.parseInt(intervalInitParameter);
- } else {
- interval = DEFAULT_PUSH_INTERVAL;
- }
- }
-
- options.put("interval", interval);
- options.put("pushResourceUrl", new
PushResource().getRequestPath());
- options.put("pushId", push.getListenerId(context));
- options.put("clientId", component.getClientId(context));
-
- HandlersChain handlersChain = new HandlersChain(context, push);
- handlersChain.addInlineHandlerFromAttribute(AbstractPush.ON_DATA_AVAILABLE);
- handlersChain.addBehaviors(AbstractPush.DATA_AVAILABLE);
- handlersChain.addAjaxSubmitFunction();
-
- String handler = handlersChain.toScript();
-
- if (handler != null) {
- JSFunctionDefinition dataAvailableHandler = new
JSFunctionDefinition(JSReference.EVENT);
- dataAvailableHandler.addToBody(handler);
- options.put(AbstractPush.ON_DATA_AVAILABLE, dataAvailableHandler);
- }
- function.addParameter(options);
- script.append(function.toScript());
- } else {
-
script.append("RichFaces.stopPush('").append(push.getListenerId(context)).append("')");
- }
- script.append(";\n");
- writer.writeText(script.toString(), null);
- writer.endElement(HtmlConstants.SCRIPT_ELEM);
- getUtils().encodeEndFormIfNessesary(context, component);
- writer.endElement(HtmlConstants.SPAN_ELEM);
- }
-
- /* (non-Javadoc)
- * @see org.ajax4jsf.renderkit.RendererBase#getComponentClass()
- */
- protected Class<? extends UIComponent> getComponentClass() {
- // only push component is allowed.
- return AbstractPush.class;
- }
-
- @Override
- protected void doDecode(FacesContext context, UIComponent component) {
- super.doDecode(context, component);
-
- AbstractPush push = (AbstractPush) component;
- if (push.isEnabled()) {
- Map<String, String> requestParameterMap =
context.getExternalContext().getRequestParameterMap();
- if (requestParameterMap.get(push.getClientId(context)) != null) {
- new ActionEvent(push).queue();
- }
- }
- }
-
-}
Deleted:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,97 +0,0 @@
-/**
- * License Agreement.
- *
- * Rich Faces - Natural Ajax for Java Server Faces (JSF)
- *
- * Copyright (C) 2007 Exadel, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-package org.richfaces.resource;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.faces.application.Resource;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-
-import org.richfaces.application.ServiceTracker;
-import org.richfaces.component.PushEventTracker;
-import org.richfaces.component.PushListenersManager;
-
-/**
- * @author Nick Belaevski
- * @since 4.0
- */
-
-//TODO make this a singleton
-@DynamicResource
-public class PushResource extends Resource {
-
- public PushResource() {
- setResourceName(getClass().getName());
- }
-
- public InputStream getInputStream() throws IOException {
- return null;
- }
-
- public Map<String, String> getResponseHeaders() {
- Map<String, String> headers = new HashMap<String, String>();
- FacesContext facesContext = FacesContext.getCurrentInstance();
- ExternalContext externalContext = facesContext.getExternalContext();
- String pushId = externalContext.getRequestParameterMap().get("id");
-
- if (pushId != null && pushId.length() != 0) {
- PushListenersManager manager =
PushListenersManager.getInstance(facesContext);
- PushEventTracker eventTracker = manager.getListener(pushId);
-
- if (eventTracker != null) {
- if (eventTracker.pollStatus()) {
- headers.put("Ajax-Push-Status", "READY");
- }
- }
- }
-
- return headers;
- }
-
- public String getContentType() {
- return null;
- }
-
- @Override
- public String getRequestPath() {
- FacesContext facesContext = FacesContext.getCurrentInstance();
- ResourceCodec resourceCodec = ServiceTracker.getService(ResourceCodec.class);
-
- String requestPath = resourceCodec.encodeResourceRequestPath(facesContext, null,
getResourceName(), null, null);
- return resourceCodec.encodeJSFMapping(facesContext, requestPath);
- }
-
- @Override
- public URL getURL() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean userAgentNeedsUpdate(FacesContext context) {
- return true;
- }
-}
Copied: branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
(from rev 19862,
branches/RF-7817/push-redesign/src/main/java/org/richfaces/application/push/impl/PushResource.java)
===================================================================
--- branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java
(rev 0)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/resource/PushResource.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -0,0 +1,125 @@
+/*
+ * 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.resource;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+import org.ajax4jsf.javascript.ScriptUtils;
+import org.richfaces.application.ServiceTracker;
+import org.richfaces.application.push.PushContext;
+import org.richfaces.application.push.PushContextFactory;
+import org.richfaces.application.push.Session;
+import org.richfaces.application.push.TopicKey;
+
+/**
+ * @author Nick Belaevski
+ *
+ */
+@DynamicResource
+public class PushResource implements UserResource {
+
+ private static final String PUSH_TOPIC_PARAM = "pushTopic";
+
+ private static final String FORGET_PUSH_SESSION_ID_PARAM =
"forgetPushSessionId";
+
+ public Map<String, String> getResponseHeaders() {
+ return null;
+ }
+
+ public Date getLastModified() {
+ return null;
+ }
+
+ private InputStream mapToScript(Map<String, Object> map) {
+ try {
+ byte[] bs = ScriptUtils.toScript(map).getBytes("UTF-8");
+ return new ByteArrayInputStream(bs);
+ } catch (UnsupportedEncodingException e) {
+ throw new FacesException(e.getMessage(), e);
+ }
+ }
+
+ private Map<String, String> getFailuresMap(Map<TopicKey, String>
failedSubscriptions) {
+ Map<String,String> result = new HashMap<String, String>();
+
+ for (Entry<TopicKey, String> entry: failedSubscriptions.entrySet()) {
+ result.put(entry.getKey().getTopicAddress(), entry.getValue());
+ }
+
+ return result;
+ }
+
+ public InputStream getInputStream() throws IOException {
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ ExternalContext externalContext = facesContext.getExternalContext();
+
+ PushContextFactory pushContextFactory =
ServiceTracker.getService(PushContextFactory.class);
+ PushContext pushContext = pushContextFactory.getPushContext();
+
+ String forgetPushSessionId =
externalContext.getRequestParameterMap().get(FORGET_PUSH_SESSION_ID_PARAM);
+ if (forgetPushSessionId != null) {
+ Session oldSession =
pushContext.getSessionManager().getPushSession(forgetPushSessionId);
+ if (oldSession != null) {
+ oldSession.destroy();
+ }
+ }
+
+ Session session =
pushContext.getSessionFactory().createSession(UUID.randomUUID().toString());
+
+ String[] topicNames =
externalContext.getRequestParameterValuesMap().get(PUSH_TOPIC_PARAM);
+
+ if (topicNames == null) {
+ throw new IllegalArgumentException();
+ }
+
+ session.subscribe(topicNames);
+
+ Map<String, Object> subscriptionData = new HashMap<String,
Object>(4);
+ subscriptionData.put("sessionId", session.getId());
+
+ Map<TopicKey, String> failedSubscriptions =
session.getFailedSubscriptions();
+ subscriptionData.put("failures", getFailuresMap(failedSubscriptions));
+
+ return mapToScript(subscriptionData);
+ }
+
+ public String getContentType() {
+ return "application/javascript; charset=utf-8";
+ }
+
+ public int getContentLength() {
+ return -1;
+ }
+
+}
Deleted:
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/java/org/richfaces/view/facelets/html/AjaxPushHandler.java 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,83 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright , Red Hat, Inc. and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
- */
-package org.richfaces.view.facelets.html;
-
-import javax.faces.event.ActionEvent;
-import javax.faces.view.facelets.*;
-import org.richfaces.component.AbstractPush;
-import org.richfaces.view.facelets.MethodMetadata;
-
-import java.util.EventListener;
-
-public class AjaxPushHandler extends ComponentHandler {
-
- private static final AjaxPushHandlerMetaRule META_RULE = new
AjaxPushHandlerMetaRule();
-
-
- public AjaxPushHandler(ComponentConfig config) {
- super(config);
-
- }
-
- protected MetaRuleset createMetaRuleset(Class type) {
- MetaRuleset m = super.createMetaRuleset(type);
- m.addRule(META_RULE);
- return m;
- }
-
- static class AjaxPushHandlerMetaRule extends MetaRule{
-
- public Metadata applyRule(String name, TagAttribute attribute, MetadataTarget
meta) {
- if (meta.isTargetInstanceOf(AbstractPush.class)) {
- if ("action".equals(name)) {
- return new MethodMetadata(attribute) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush) instance).setAction(getMethodBinding(ctx));
- }
- };
- }
- if ("actionExpression".equals(name)) {
- return new MethodMetadata(attribute) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush)
instance).setActionExpression(getMethodExpression(ctx));
- }
- };
- }
- if ("actionListener".equals(name)) {
- return new MethodMetadata(attribute, ActionEvent.class) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush)
instance).setActionListener(getMethodBinding(ctx));
- }
- };
- }
- if ("eventProducer".equals(name)) {
- return new MethodMetadata(attribute, EventListener.class) {
- public void applyMetadata(FaceletContext ctx, Object instance) {
- ((AbstractPush)
instance).setEventProducer(getMethodExpression(ctx));
- }
- };
- }
- }
- return null;
- }
- }
-}
Deleted:
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml 2010-11-01
23:43:58 UTC (rev 19869)
+++
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/push-managed-beans.faces-config.xml 2010-11-01
23:47:24 UTC (rev 19870)
@@ -1,12 +0,0 @@
-<?xml version='1.0' encoding='UTF-8'?>
-
-<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
- version="2.0">
-
- <managed-bean eager="true">
- <managed-bean-name>richFacesPushListenersManager</managed-bean-name>
- <managed-bean-class>org.richfaces.component.PushListenersManager</managed-bean-class>
- <managed-bean-scope>application</managed-bean-scope>
- </managed-bean>
-
-</faces-config>
\ No newline at end of file
Copied:
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/net.java.dev.atmosphere
(from rev 19862,
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/net.java.dev.atmosphere)
Copied:
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
(from rev 19862,
branches/RF-7817/push-redesign/src/main/resources/META-INF/resources/org.richfaces/push.js)
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js
(rev 0)
+++
branches/RF-7817/ui/core/ui/src/main/resources/META-INF/resources/org.richfaces/push.js 2010-11-01
23:47:24 UTC (rev 19870)
@@ -0,0 +1,237 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright ${year}, Red Hat, Inc. and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+(function(jsf, richfaces, _$) {
+
+ var COMPONENT_NAME = "Push";
+
+ var RICH_NAMESPACE = richfaces.Event.RICH_NAMESPACE;
+
+ var EVENT_NAMESPACE_SEPARATOR = richfaces.Event.EVENT_NAMESPACE_SEPARATOR;
+
+ var DATA_EVENT_NAME = 'dataAvailable' + EVENT_NAMESPACE_SEPARATOR +
RICH_NAMESPACE + EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;
+
+ var ERROR_EVENT_NAME = 'error' + EVENT_NAMESPACE_SEPARATOR + RICH_NAMESPACE +
EVENT_NAMESPACE_SEPARATOR + COMPONENT_NAME;
+
+ var getDataEventNamespace = function(address) {
+ return DATA_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
+ };
+
+ var getErrorEventNamespace = function(address) {
+ return ERROR_EVENT_NAME + EVENT_NAMESPACE_SEPARATOR + address;
+ };
+
+ richfaces.Push = (function() {
+
+ var addedTopics = {};
+
+ var removedTopics = {};
+
+ var handlersCounter = {};
+
+ var pushUrl = null;
+
+ var pushSessionId = null;
+
+ var suspendMessageEndMarker = /(<!--[^>]+-->\s*)+/;
+
+ var messageCallback = function(response) {
+ var dataString = response.responseBody.replace(suspendMessageEndMarker,
"");
+ if (dataString) {
+ var messages = _$.parseJSON(dataString);
+ if (messages) {
+ for (var i = 0; i < messages.length; i++) {
+ var message = messages[i];
+
+ richfaces.Event.fire(document, getDataEventNamespace(message.topic),
message.data);
+ }
+ }
+ }
+ };
+
+ var connect = function() {
+ var pushSessionIdRequestHandler = function(data) {
+ var subscriptionData = _$.parseJSON(data);
+
+
+ for (var failedTopicKey in subscriptionData.failures) {
+ richfaces.Event.fire(
+ document,
+ getErrorEventNamespace(failedTopicKey),
+ subscriptionData.failures[failedTopicKey]
+ );
+ }
+
+ if (subscriptionData.sessionId) {
+ pushSessionId = subscriptionData.sessionId;
+
+ _$.atmosphere.subscribe(pushUrl +
"?__richfacesPushAsync=1&pushSessionId=" + pushSessionId, messageCallback,
{
+ /*transport: 'websocket'*/
+ });
+ }
+ };
+
+ var topics = new Array();
+ for (var topicName in handlersCounter) {
+ topics.push(topicName);
+ }
+
+ var data = {
+ "pushTopic": topics
+ };
+
+ if (pushSessionId) {
+ data['forgetPushSessionId'] = pushSessionId;
+ }
+
+ //TODO handle request errors
+ _$.ajax({
+ data: data,
+ dataType: 'text',
+ success: pushSessionIdRequestHandler,
+ traditional: true,
+ type: 'POST',
+ url: pushUrl
+ });
+ };
+
+ var disconnect = function() {
+ _$.atmosphere.closeSuspendedConnection();
+ };
+
+ return {
+ increaseSubscriptionCounters: function(address) {
+ if (isNaN(handlersCounter[address]++)) {
+ handlersCounter[address] = 1;
+ addedTopics[address] = true;
+ }
+ },
+
+ decreaseSubscriptionCounters: function(address) {
+ if (--handlersCounter[address] == 0) {
+ delete handlersCounter[address];
+ removedTopics[address] = true;
+ }
+ },
+
+ setPushUrl: function(argPushUrl) {
+ if (argPushUrl.charAt(0) == '/') {
+ pushUrl = location.protocol + '//' + location.host + argPushUrl;
+ } else {
+ pushUrl = argPushUrl;
+ }
+ },
+
+ updateConnection: function() {
+ if (_$.isEmptyObject(handlersCounter)) {
+ disconnect();
+ } else if (!_$.isEmptyObject(addedTopics) || !_$.isEmptyObject(removedTopics)) {
+ disconnect();
+ connect();
+ }
+
+ addedTopics = {};
+ removedTopics = {};
+ }
+ };
+
+ }());
+
+ _$(document).ready(richfaces.Push.updateConnection);
+
+ var ajaxEventHandler = function(event) {
+ if (event.type == 'event') {
+ if (event.status != 'success') {
+ return;
+ }
+ } else if (event.type != 'error') {
+ return;
+ }
+
+ richfaces.Push.updateConnection();
+ };
+
+ jsf.ajax.addOnEvent(ajaxEventHandler);
+ jsf.ajax.addOnError(ajaxEventHandler);
+
+ richfaces.ui = richfaces.ui || {};
+
+ richfaces.ui.Push = richfaces.BaseComponent.extendClass({
+
+ name: COMPONENT_NAME,
+
+ init: function (id, options) {
+ this.id = id;
+ this.attachToDom();
+
+ this.__address = options.address;
+ this.__handlers = {};
+
+ if (options.dataHandler) {
+ //TODO check compatibility with f:ajax
+ this.__bindDataHandler(options.dataHandler);
+ }
+
+ if (options.errorHandler) {
+ //TODO check compatibility with f:ajax
+ this.__bindErrorHandler(options.errorHandler);
+ }
+
+ richfaces.Push.increaseSubscriptionCounters(this.__address);
+ },
+
+ __bindDataHandler: function(handlerCode) {
+ var ns = getDataEventNamespace(this.__address)
+ this.__handlers.data = richfaces.Event.bind(document, ns, new
Function("event", handlerCode));
+ },
+
+ __unbindDataHandler: function() {
+ if (this.__handlers.data) {
+ var ns = getDataEventNamespace(this.__address);
+ richfaces.Event.unbind(document, ns, this.__handlers.data);
+
+ this.__handlers.data = null;
+ }
+ },
+
+ __bindErrorHandler: function(handlerCode) {
+ var ns = getErrorEventNamespace(this.__address);
+ this.__handlers.error = richfaces.Event.bind(document, ns, new
Function("event", handlerCode));
+ },
+
+ __unbindErrorHandler: function() {
+ if (this.__handlers.error) {
+ var ns = getErrorEventNamespace(this.__address);
+ richfaces.Event.unbind(document, ns, this.__handlers.error);
+
+ this.__handlers.error = null;
+ }
+ },
+
+ destroy: function() {
+ this.__unbindDataHandler();
+ this.__unbindErrorHandler();
+
+ richfaces.Push.decreaseSubscriptionCounters(this.__address);
+ }
+ });
+
+}(jsf, window.RichFaces, jQuery));
\ No newline at end of file
Copied:
branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
(from rev 19862, branches/RF-7817/push-redesign/src/main/templates/push.template.xml)
===================================================================
---
branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml
(rev 0)
+++
branches/RF-7817/ui/core/ui/src/main/templates/org/ajax4jsf/renderkit/html/push.template.xml 2010-11-01
23:47:24 UTC (rev 19870)
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<cdk:root
xmlns="http://jboss.org/schema/richfaces/cdk/xhtml-el"
xmlns:cdk="http://jboss.org/schema/richfaces/cdk/core"
+
xmlns:c="http://jboss.org/schema/richfaces/cdk/jstl/core"
xmlns:cc="http://jboss.org/schema/richfaces/cdk/jsf/composite"
+
xmlns:javaee="http://java.sun.com/xml/ns/javaee">
+
+ <cc:interface>
+ <cdk:class>org.richfaces.renderkit.html.PushRenderer</cdk:class>
+
<cdk:superclass>org.richfaces.renderkit.PushRendererBase</cdk:superclass>
+ <cdk:component-family>org.richfaces.Push</cdk:component-family>
+ <cdk:renderer-type>org.richfaces.PushRenderer</cdk:renderer-type>
+ <cdk:renders-children>true</cdk:renders-children>
+
+ <cdk:resource-dependency library="javax.faces"
name="jsf.js" />
+ <cdk:resource-dependency name="jquery.js" />
+ <cdk:resource-dependency name="richfaces.js" />
+ <cdk:resource-dependency name="richfaces-event.js" />
+ <cdk:resource-dependency name="richfaces-base-component.js" />
+ <cdk:resource-dependency library="net.java.dev.atmosphere"
name="jquery-atmosphere.js" />
+ <cdk:resource-dependency library="org.richfaces"
name="push.js" />
+ </cc:interface>
+
+ <cc:implementation>
+ <span id="#{clientId}">
+ <script type="text/javascript">
+ <c:if test="#{shouldEncodePushUrl(facesContext)}">
+ RichFaces.Push.setPushUrl("#{getPushUrl(facesContext)}");
+ </c:if>
+
+ new RichFaces.ui.Push("#{clientId}",
#{getOptionsString(facesContext, component)});
+ </script>
+ </span>
+ </cc:implementation>
+
+</cdk:root>