All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.atmosphere.cpr.AtmosphereServlet Maven / Gradle / Ivy

/*
 * 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 2007-2008 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 *
 */

package org.atmosphere.cpr;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;
import org.atmosphere.container.BlockingIOCometSupport;
import org.atmosphere.container.GoogleAppEngineCometSupport;
import org.atmosphere.container.JBossWebCometSupport;
import org.atmosphere.container.TomcatCometSupport;
import org.atmosphere.container.WebLogicCometSupport;
import org.atmosphere.handler.ReflectorServletProcessor;
import org.atmosphere.util.AtmosphereConfigReader;
import org.atmosphere.util.AtmosphereConfigReader.Property;
import org.atmosphere.util.BroadcasterLookup;
import org.atmosphere.util.IntrospectionUtils;
import org.atmosphere.util.LoggerUtils;
import org.atmosphere.util.Version;
import org.jboss.servlet.http.HttpEvent;
import org.jboss.servlet.http.HttpEventServlet;
import weblogic.servlet.http.AbstractAsyncServlet;
import weblogic.servlet.http.RequestResponseKey;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
 * The {@link AtmosphereServlet} acts as a dispatcher for {@link AtmosphereHandler}
 * defined in META-INF/atmosphere.xml, or if atmosphere.xml is missing, all classes
 * that implements {@link AtmosphereHandler} will be discovered and mapped using
 * the class's name. This {@link Servlet} can be defined inside an application's
 * web.xml using the following:
 * 


    <servlet>
        <description>AtmosphereServlet</description>
        <servlet-name>AtmosphereServlet</servlet-name>
        <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class>
        <load-on-startup>0 </load-on-startup>
    </servlet>
    <servlet-mapping>
         <servlet-name>AtmosphereServlet</servlet-name>
         <url-pattern>/Atmosphere </url-pattern>
    </servlet-mapping>
 * 

* * You can force this Servlet to use native API of the Web Server instead of * the Servlet 3.0 Async API you are deploying on by adding *


    <init-param>
         <param-name>org.atmosphere.useNative</param-name>
         <param-value>true</param-value>
    </init-param>
 * 

* * You can force this Servlet to use one Thread per connection instead of * native API of the Web Server you are deploying on by adding *


    <init-param>
         <param-name>org.atmosphere.useBlocking</param-name>
         <param-value>true</param-value>
    </init-param>
 * 

* * The Atmosphere Framework can also be used as a Servlet Filter ({@link AtmosphereFilter}). * * If you are planning to use JSP, Servlet or JSF, you can instead use the * {@link MeteorServlet}, which allow the use of {@link Meteor} inside those * components. * * @author Jeanfrancois Arcand */ public class AtmosphereServlet extends AbstractAsyncServlet implements CometProcessor, HttpEventServlet{ // If we detect Servlet 3.0, should we still use the default // native Comet API. protected boolean useNativeImplementation = false; protected boolean useBlockingImplementation = false; protected boolean useStreamForFlushingComments = false; public final static String JERSEY_BROADCASTER = "org.atmosphere.jersey.JerseyBroadcaster"; public final static String JERSEY_CONTAINER = "com.sun.jersey.spi.container.servlet.ServletContainer"; public final static String GAE_BROADCASTER = org.atmosphere.util.gae.GAEDefaultBroadcaster.class.getName(); public final static String PROPERTY_SERVLET_MAPPING = "org.atmosphere.jersey.servlet-mapping"; public final static String PROPERTY_BLOCKING_COMETSUPPORT = "org.atmosphere.useBlocking"; public final static String PROPERTY_NATIVE_COMETSUPPORT = "org.atmosphere.useNative"; public final static String PROPERTY_USE_STREAM = "org.atmosphere.useStream"; public final static String BROADCASTER_CLASS = "org.atmosphere.cpr.broadcasterClass"; public final static String PROPERTY_COMET_SUPPORT = "org.atmosphere.cpr.cometSupport"; public final static String PRIMEFACES_SERVLET="org.primefaces.comet.PrimeFacesCometServlet"; public final static String DISABLE_ONSTATE_EVENT = "org.atmosphere.disableOnStateEvent"; public final static String WEB_INF = "/WEB-INF/classes/"; public final static Logger logger = LoggerUtils.getLogger(); protected final ArrayList possibleAtmosphereHandlersCandidate = new ArrayList(); protected final HashMap initParams = new HashMap(); /** * The list of {@link AtmosphereHandler} and their associated mapping. */ protected final Map atmosphereHandlers = new HashMap(); // The WebServer we are running on. protected CometSupport cometSupport; protected AtmosphereConfig config; protected boolean isFilter = false; protected String broadcasterClassName = DefaultBroadcaster.class.getName(); protected final AtomicBoolean isCometSupportConfigured = new AtomicBoolean(false); protected boolean isCometSupportSpecified = false; protected boolean isBroadcasterSpecified = false; public final static class AtmosphereHandlerWrapper{ public final AtmosphereHandler atmosphereHandler; public Broadcaster broadcaster; public AtmosphereHandlerWrapper(AtmosphereHandler g){ this.atmosphereHandler = g; } public AtmosphereHandlerWrapper(AtmosphereHandler g, Broadcaster b){ this.atmosphereHandler = g; this.broadcaster = b; } } /** * Return a configured instance of {@link AtmosphereConfig} * @param supportSession true if session is supported. * * @return a configured instance of {@link AtmosphereConfig} */ public AtmosphereConfig newAtmosphereConfig(boolean supportSession){ AtmosphereConfig c = new AtmosphereConfig(); c.supportSession = supportSession; return c; } public class AtmosphereConfig{ protected boolean supportSession = true; protected AtmosphereHandler ah; private BroadcasterLookup bl = new BroadcasterLookup(); protected Map handlers(){ return AtmosphereServlet.this.atmosphereHandlers; } public ServletContext getServletContext(){ return AtmosphereServlet.this.getServletContext(); } public String getInitParameter(String name){ // First looks locally String s = initParams.get(name); if (s != null){ return s; } return AtmosphereServlet.this.getInitParameter(name); } public Enumeration getInitParameterNames(){ return AtmosphereServlet.this.getInitParameterNames(); } public ServletConfig getServletConfig(){ return AtmosphereServlet.this.getServletConfig(); } public String getWebServerName(){ return AtmosphereServlet.this.cometSupport.getContainerName(); } /** * Return the {@link AtmosphereHandler} associated with this config. * @return the {@link AtmosphereHandler} associated with this config. */ public AtmosphereHandler getAtmosphereHandler(){ return ah; } /** * Return an instance of a {@link BroadcasterLookup} * @return an instance of a {@link BroadcasterLookup} */ public BroadcasterLookup getBroadcasterLookup(){ return bl; } } /** * Simple class/struck that hold the current state. */ public static class Action{ public enum TYPE {SUSPEND, RESUME, NONE, CANCEL} public long timeout = -1L; public TYPE type; public Action(){ type = TYPE.NONE; } public Action(TYPE type){ this.type = type; } public Action(TYPE type,long timeout){ this.timeout = timeout; this.type = type; } } /** * Create an Atmosphere Servlet. */ public AtmosphereServlet(){ if (System.getProperty(PROPERTY_NATIVE_COMETSUPPORT) != null){ useNativeImplementation = Boolean .parseBoolean(System.getProperty(PROPERTY_NATIVE_COMETSUPPORT)); isCometSupportSpecified = true; } if (System.getProperty(PROPERTY_BLOCKING_COMETSUPPORT) != null){ useBlockingImplementation = Boolean .parseBoolean(System.getProperty(PROPERTY_BLOCKING_COMETSUPPORT)); isCometSupportSpecified = true; } if (System.getProperty(DISABLE_ONSTATE_EVENT) != null){ initParams.put(DISABLE_ONSTATE_EVENT,System.getProperty(DISABLE_ONSTATE_EVENT)); } } /** * Create an Atmosphere Servlet. */ public AtmosphereServlet(boolean isFilter){ this(); this.isFilter = isFilter; } /** * Add an {@link AtmosphereHandler} serviced by the {@link Servlet} * This API is exposed to allow embedding an Atmosphere application. * @param mapping The servlet mapping (servlet path) * @param h implementation of an {@link AtmosphereHandler} */ public void addAtmosphereHandler(String mapping, AtmosphereHandler h) { if (!mapping.startsWith("/")){ mapping = "/" + mapping; } AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(h); atmosphereHandlers.put(mapping,w); try{ w.broadcaster = (Broadcaster)this.getClass().getClassLoader() .loadClass(broadcasterClassName).newInstance(); } catch (Throwable t) { logger.log(Level.WARNING, "Unable to load Broadcaster class: " + broadcasterClassName, t); } finally { if (w.broadcaster == null){ w.broadcaster = new DefaultBroadcaster(); } } } /** * Add init-param like if they were defined in web.xml * @param name The name * @param value The value */ public void addInitParameter(String name, String value){ initParams.put(name,value); } /** * Load the {@link AtmosphereHandler} associated with this AtmosphereServlet. * @param sc the {@link ServletContext} */ @Override public void init(ServletConfig sc) throws ServletException{ try{ super.init(sc); config = new AtmosphereConfig(); doInitParams(sc); detectGoogleAppEngine(sc); loadConfiguration(sc); autoDetectContainer(); cometSupport.init(sc); initAtmosphereServletProcessor(sc); logger.log(Level.INFO,"Atmosphere Framework " + Version.getRawVersion() + " started."); } catch (Throwable t){ logger.log(Level.SEVERE,"",t); if (t instanceof ServletException) throw (ServletException)t; throw new ServletException(t.getCause()); } } /** * Read init param from web.xml and apply them. * @param sc */ protected void doInitParams(ServletConfig sc){ initParams.put(DISABLE_ONSTATE_EVENT,"false"); String s = sc.getInitParameter(PROPERTY_NATIVE_COMETSUPPORT); if (s != null){ useNativeImplementation = Boolean.parseBoolean(s); if (useNativeImplementation) isCometSupportSpecified = true; } s = sc.getInitParameter(PROPERTY_BLOCKING_COMETSUPPORT); if (s != null){ useBlockingImplementation = Boolean.parseBoolean(s); if (useBlockingImplementation) isCometSupportSpecified = true; } s = sc.getInitParameter(PROPERTY_USE_STREAM); if (s != null){ useStreamForFlushingComments = Boolean.parseBoolean(s); } s = sc.getInitParameter(PROPERTY_COMET_SUPPORT); if (s != null){ cometSupport = new DefaultCometSupportResolver(config).newCometSupport(s); isCometSupportSpecified = true; } s = sc.getInitParameter(BROADCASTER_CLASS); if (s != null){ broadcasterClassName = s; isBroadcasterSpecified = true; } } protected void loadConfiguration(ServletConfig sc)throws ServletException{ try{ //TODO -> Add support for WEB-INF/lib/*.jar URL url = sc.getServletContext().getResource("/WEB-INF/classes/"); URLClassLoader urlC = new URLClassLoader(new URL[] {url}, Thread.currentThread().getContextClassLoader()); loadAtmosphereDotXml(sc.getServletContext(). getResourceAsStream("/META-INF/atmosphere.xml"), urlC); if (atmosphereHandlers.size() == 0){ logger.warning("Missing META-INF/atmosphere.xml." + " Will try to autodetect AtmosphereHandler"); autoDetectAtmosphereHandlers(sc.getServletContext(), urlC); // If we still haven found anything. if (atmosphereHandlers.size() == 0) { detectJerseyRuntime(sc); } } } catch (Throwable t){ throw new ServletException(t); } } /** * Auto-detect Jersey when no atmosphere.xml file are specified. * * @param sc {@link ServletConfig} * @return true if Jersey classes are detected */ protected boolean detectJerseyRuntime(ServletConfig sc){ // If Primefaces is detected, never starts Jersey. try{ Class.forName(PRIMEFACES_SERVLET); return false; } catch (Throwable t){ } try{ Class.forName(JERSEY_CONTAINER); useStreamForFlushingComments = true; } catch (Throwable t){ return false; } logger.warning("Missing META-INF/atmosphere.xml but found the Jersey runtime. " + "Starting Jersey"); ReflectorServletProcessor rsp = new ReflectorServletProcessor(); if (!isBroadcasterSpecified) broadcasterClassName = JERSEY_BROADCASTER; rsp.setServletClassName(JERSEY_CONTAINER); config.supportSession = false; initParams.put(DISABLE_ONSTATE_EVENT,"true"); String mapping = sc.getInitParameter(PROPERTY_SERVLET_MAPPING); if (mapping == null){ mapping = "/*"; } addAtmosphereHandler(mapping,rsp); return true; } /** * Auto-Detect Google App Engine. */ boolean detectGoogleAppEngine(ServletConfig sc){ if (sc.getServletContext().getServerInfo().startsWith("Google")){ broadcasterClassName = GAE_BROADCASTER; cometSupport = new GoogleAppEngineCometSupport(config); return true; } else { return false; } } /** * Initialize {@link AtmosphereServletProcessor} * @param sc the {@link ServletConfig} * @throws javax.servlet.ServletException */ void initAtmosphereServletProcessor(ServletConfig sc) throws ServletException{ AtmosphereHandler a; for (Entry h: atmosphereHandlers.entrySet()){ a = h.getValue().atmosphereHandler; if (a instanceof AtmosphereServletProcessor){ ((AtmosphereServletProcessor)a).init(sc); } } } @Override public void destroy(){ if (cometSupport instanceof AsynchronousProcessor){ ((AsynchronousProcessor)cometSupport).shutdown(); } AtmosphereHandler a; for (Entry h: atmosphereHandlers.entrySet()){ a = h.getValue().atmosphereHandler; if (a instanceof AtmosphereServletProcessor){ ((AtmosphereServletProcessor)a).destroy(); } } BroadcasterLookup.destroy(); } /** * Load AtmosphereHandler defined under META-INF/atmosphere.xml */ protected void loadAtmosphereDotXml(InputStream stream, URLClassLoader c) throws IOException, ServletException{ if (stream == null){ return; } AtmosphereConfigReader reader = new AtmosphereConfigReader(stream); Map atmosphereHandlerNames = reader.getAtmosphereHandlers(); Set> entries = atmosphereHandlerNames.entrySet(); for (Entry entry: entries){ AtmosphereHandler g; try { if (!entry.getValue().equals(ReflectorServletProcessor.class.getName())){ g = (AtmosphereHandler) c.loadClass(entry.getValue()).newInstance(); } else { g = new ReflectorServletProcessor(); } logger.info("Sucessfully loaded " + g + " mapped to context-path " + entry.getKey()); AtmosphereHandlerWrapper wrapper = new AtmosphereHandlerWrapper(g); atmosphereHandlers.put(entry.getKey(), wrapper); boolean isJersey = false; for (Property p: reader.getProperty(entry.getKey())){ if (p.value != null && p.value.indexOf("jersey") != -1){ isJersey = true; initParams.put(DISABLE_ONSTATE_EVENT,"true"); useStreamForFlushingComments = true; } IntrospectionUtils.setProperty(g,p.name,p.value); } config.supportSession = !isJersey; if (!reader.supportSession().equals("")){ config.supportSession = Boolean.valueOf(reader.supportSession()); } for (Property p: reader.getProperty(entry.getKey())){ IntrospectionUtils.addProperty(g,p.name,p.value); } String broadcasterClass = reader.getBroadcasterClass(entry.getKey()); if (broadcasterClass != null){ wrapper.broadcaster = (Broadcaster) c.loadClass(broadcasterClass).newInstance(); broadcasterClassName = broadcasterClass; } if (!isJersey && wrapper.broadcaster == null){ wrapper.broadcaster = (Broadcaster) c.loadClass(broadcasterClassName).newInstance(); } else if (broadcasterClass == null){ broadcasterClassName = JERSEY_BROADCASTER; wrapper.broadcaster = (Broadcaster) c.loadClass(JERSEY_BROADCASTER).newInstance(); } if (reader.getCometSupportClass() != null){ cometSupport = (CometSupport) c.loadClass(reader.getCometSupportClass()).newInstance(); } logger.info("Using " + wrapper.broadcaster.getClass().getName() + " with a Thread Pool size of : " + BroadcasterConfig.numOfProcessor); } catch (Throwable t) { logger.log(Level.WARNING, "Unable to load AtmosphereHandler class: " + entry.getValue(), t); throw new ServletException(t); } } } /** * Set the {@link CometSupport} implementation. Make sure you don't set * an implementation that only works on some Container. See {@link BlockingIOCometSupport} * for an example. * * @param cometSupport */ public void setCometSupport(CometSupport cometSupport){ this.cometSupport = cometSupport; } /** * Return the current {@link CometSupport} * @return */ public CometSupport getCometSupport(){ return cometSupport; } /** * Returns an instance of CometSupportResolver {@link CometSupportResolver} * @return CometSupportResolver */ protected CometSupportResolver createCometSupportResolver(){ return new DefaultCometSupportResolver(config); } /** * Auto detect the underlying Servlet Container we are running on. */ protected void autoDetectContainer(){ // Was defined in atmosphere.xml if (getCometSupport() == null){ setCometSupport(createCometSupportResolver().resolve(useNativeImplementation,useBlockingImplementation)); } logger.info("Atmosphere is using for CometSupport: " + getCometSupport().getClass().getName()+ " running under container " + cometSupport.getContainerName()); } /** * Auto detect instance of {@link AtmosphereHandler} in case META-INF/atmosphere.xml * is missing. * @param sc {@link ServletContext} * @param c {@link URLClassLoader} to load the class. */ protected void autoDetectAtmosphereHandlers(ServletContext sc, URLClassLoader c) throws MalformedURLException, URISyntaxException{ String s = sc.getRealPath(WEB_INF); // Weblogic bug if (s == null){ URL u = sc.getResource(WEB_INF); if (u == null) return; s = u.getPath(); } File f = new File(s); if (f.isDirectory()){ getFiles(f); for (String className: possibleAtmosphereHandlersCandidate){ try { className = className.replace('\\','/'); className = className.substring(className.indexOf(WEB_INF) + WEB_INF.length(), className.lastIndexOf(".")).replace('/','.'); AtmosphereHandler g = (AtmosphereHandler) c.loadClass(className).newInstance(); logger.info("Sucessfully loaded " + g + " mapped to context-path " + g.getClass().getSimpleName()); atmosphereHandlers.put("/" + g.getClass().getSimpleName(), new AtmosphereHandlerWrapper(g, (Broadcaster)c.loadClass(broadcasterClassName).newInstance())); } catch (Throwable t) { logger.finest(className + " is not a AtmosphereHandler"); } } } logger.info("Atmosphere using Broadcaster " + broadcasterClassName); } /** * Get the list of possible candidate to load as {@link AtmosphereHandler} * @param f the real path {@link File} */ protected void getFiles(File f){ File[] files = f.listFiles(); for (File test: files){ if (test.isDirectory()){ getFiles(test); } else { String clazz = test.getAbsolutePath(); if (clazz.endsWith(".class")){ possibleAtmosphereHandlersCandidate.add(clazz); } } } } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doHead(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doOptions(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doTrace(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doDelete(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doPut(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doPost(req, res); } /** * Delegate the request processing to an instance of {@link CometSupport} * @param req the {@link HttpServletRequest} * @param res the {@link HttpServletResponse} * @throws java.io.IOException * @throws javax.servlet.ServletException */ @Override public void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { doCometSupport(req,res); } /** * Invoke the proprietary {@link CometSupport} * * @param req * @param res * @return * @throws IOException * @throws ServletException */ protected Action doCometSupport(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { req.setAttribute(BROADCASTER_CLASS, broadcasterClassName); req.setAttribute(PROPERTY_USE_STREAM, useStreamForFlushingComments); try{ return cometSupport.service(req, res); } catch (IllegalStateException ex){ if (ex.getMessage() != null && ex.getMessage().startsWith("Tomcat failed")){ if (!isFilter){ logger.warning(ex.getMessage()); logger.warning("Using the BlockingIOCometSupport."); } cometSupport = new BlockingIOCometSupport(config); service(req,res); } else { logger.log(Level.SEVERE,"AtmosphereServlet exception", ex); throw ex; } } return null; } /** * Hack to support Tomcat AIO like other WebServer. This method is invoked * by Tomcat when it detect a {@link Servlet} implements the interface * {@link CometProcessor} without invoking {@link Servlet#service} * * @param cometEvent the {@link CometEvent} * @throws java.io.IOException * @throws javax.servlet.ServletException */ public void event(CometEvent cometEvent) throws IOException, ServletException { HttpServletRequest req = cometEvent.getHttpServletRequest(); HttpServletResponse res = cometEvent.getHttpServletResponse(); req.setAttribute(TomcatCometSupport.COMET_EVENT, cometEvent); if (!isCometSupportSpecified && !isCometSupportConfigured.getAndSet(true)){ synchronized(cometSupport){ if (!cometSupport.getClass().equals(TomcatCometSupport.class)){ logger.warning("TomcatCometSupport is enabled, switching to it"); cometSupport = new TomcatCometSupport(config); } } } doCometSupport(req, res); } /** * Hack to support JBossWeb AIO like other WebServer. This method is invoked * by Tomcat when it detect a {@link Servlet} implements the interface * {@link HttpEventServlet} without invoking {@link Servlet#service} * * @param httpEvent the {@link CometEvent} * @throws java.io.IOException * @throws javax.servlet.ServletException */ public void event(HttpEvent httpEvent) throws IOException, ServletException { HttpServletRequest req = httpEvent.getHttpServletRequest(); HttpServletResponse res = httpEvent.getHttpServletResponse(); req.setAttribute(JBossWebCometSupport.HTTP_EVENT, httpEvent); if (!isCometSupportSpecified && !isCometSupportConfigured.getAndSet(true)){ synchronized(cometSupport){ if (!cometSupport.getClass().equals(JBossWebCometSupport.class)){ logger.warning("JBossWebCometSupport is enabled, switching to it"); cometSupport = new JBossWebCometSupport(config); } } } doCometSupport(req, res); } /** * Weblogic specific comet based implementation. * * @param rrk * @return * @throws java.io.IOException * @throws javax.servlet.ServletException */ protected boolean doRequest(RequestResponseKey rrk) throws IOException, ServletException { try{ rrk.getRequest().getSession().setAttribute(WebLogicCometSupport.RRK,rrk); Action action = doCometSupport(rrk.getRequest(), rrk.getResponse()); if (action.type == Action.TYPE.SUSPEND){ if (action.timeout == -1){ rrk.setTimeout(Integer.MAX_VALUE); } else { rrk.setTimeout((int)action.timeout); } } return action.type == Action.TYPE.SUSPEND; } catch (IllegalStateException ex){ logger.log(Level.SEVERE,"AtmosphereServlet.doRequest exception", ex); throw ex; } } /** * Weblogic specific comet based implementation. * * @param rrk * @return * @throws java.io.IOException * @throws javax.servlet.ServletException */ protected void doResponse(RequestResponseKey rrk, Object context) throws IOException, ServletException { rrk.getResponse().flushBuffer(); } /** * Weblogic specific comet based implementation. * * @param rrk * @return * @throws java.io.IOException * @throws javax.servlet.ServletException */ protected void doTimeout(RequestResponseKey rrk) throws IOException, ServletException { ((AsynchronousProcessor)cometSupport).timedout(rrk.getRequest(), rrk.getResponse()); } /** * Return the default {@link Broadcaster} class name. * @return the broadcasterClassName */ public String getDefaultBroadcasterClassName() { return broadcasterClassName; } /** * Set the default {@link Broadcaster} class name * @param broadcasterClassName the broadcasterClassName to set */ public void setDefaultBroadcasterClassName(String broadcasterClassName) { this.broadcasterClassName = broadcasterClassName; } /** * true if Atmosphere uses {@link HttpServletResponse#getOutputStream()} * by default for write operation. * * @return the useStreamForFlushingComments */ public boolean isUseStreamForFlushingComments() { return useStreamForFlushingComments; } /** * Set to true so Atmosphere uses {@link HttpServletResponse#getOutputStream()} * by default for write operation. Default is false. * * @param useStreamForFlushingComments the useStreamForFlushingComments to set */ public void setUseStreamForFlushingComments(boolean useStreamForFlushingComments) { this.useStreamForFlushingComments = useStreamForFlushingComments; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy