1//
2//  ========================================================================
3//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4//  ------------------------------------------------------------------------
5//  All rights reserved. This program and the accompanying materials
6//  are made available under the terms of the Eclipse Public License v1.0
7//  and Apache License v2.0 which accompanies this distribution.
8//
9//      The Eclipse Public License is available at
10//      http://www.eclipse.org/legal/epl-v10.html
11//
12//      The Apache License v2.0 is available at
13//      http://www.opensource.org/licenses/apache2.0.php
14//
15//  You may elect to redistribute this code under either of these licenses.
16//  ========================================================================
17//
18
19package org.eclipse.jetty.continuation;
20
21import java.lang.reflect.Constructor;
22import javax.servlet.ServletRequest;
23import javax.servlet.ServletRequestWrapper;
24import javax.servlet.ServletResponse;
25
26/* ------------------------------------------------------------ */
27/** ContinuationSupport.
28 *
29 * Factory class for accessing Continuation instances, which with either be
30 * native to the container (jetty >= 6), a servlet 3.0 or a faux continuation.
31 *
32 */
33public class ContinuationSupport
34{
35    static final boolean __jetty6;
36    static final boolean __servlet3;
37    static final Class<?> __waitingContinuation;
38    static final Constructor<? extends Continuation> __newServlet3Continuation;
39    static final Constructor<? extends Continuation> __newJetty6Continuation;
40    static
41    {
42        boolean servlet3Support=false;
43        Constructor<? extends Continuation>s3cc=null;
44        try
45        {
46            boolean servlet3=ServletRequest.class.getMethod("startAsync")!=null;
47            if (servlet3)
48            {
49                Class<? extends Continuation> s3c = ContinuationSupport.class.getClassLoader().loadClass("org.eclipse.jetty.continuation.Servlet3Continuation").asSubclass(Continuation.class);
50                s3cc=s3c.getConstructor(ServletRequest.class);
51                servlet3Support=true;
52            }
53        }
54        catch (Exception e)
55        {}
56        finally
57        {
58            __servlet3=servlet3Support;
59            __newServlet3Continuation=s3cc;
60        }
61
62        boolean jetty6Support=false;
63        Constructor<? extends Continuation>j6cc=null;
64        try
65        {
66            Class<?> jetty6ContinuationClass = ContinuationSupport.class.getClassLoader().loadClass("org.mortbay.util.ajax.Continuation");
67            boolean jetty6=jetty6ContinuationClass!=null;
68            if (jetty6)
69            {
70                Class<? extends Continuation> j6c = ContinuationSupport.class.getClassLoader().loadClass("org.eclipse.jetty.continuation.Jetty6Continuation").asSubclass(Continuation.class);
71                j6cc=j6c.getConstructor(ServletRequest.class, jetty6ContinuationClass);
72                jetty6Support=true;
73            }
74        }
75        catch (Exception e)
76        {}
77        finally
78        {
79            __jetty6=jetty6Support;
80            __newJetty6Continuation=j6cc;
81        }
82
83        Class<?> waiting=null;
84        try
85        {
86            waiting=ContinuationSupport.class.getClassLoader().loadClass("org.mortbay.util.ajax.WaitingContinuation");
87        }
88        catch (Exception e)
89        {
90        }
91        finally
92        {
93            __waitingContinuation=waiting;
94        }
95    }
96
97    /* ------------------------------------------------------------ */
98    /**
99     * Get a Continuation.  The type of the Continuation returned may
100     * vary depending on the container in which the application is
101     * deployed. It may be an implementation native to the container (eg
102     * org.eclipse.jetty.server.AsyncContinuation) or one of the utility
103     * implementations provided such as an internal <code>FauxContinuation</code>
104     * or a real implementation like {@link org.eclipse.jetty.continuation.Servlet3Continuation}.
105     * @param request The request
106     * @return a Continuation instance
107     */
108    public static Continuation getContinuation(ServletRequest request)
109    {
110        Continuation continuation = (Continuation) request.getAttribute(Continuation.ATTRIBUTE);
111        if (continuation!=null)
112            return continuation;
113
114        while (request instanceof ServletRequestWrapper)
115            request=((ServletRequestWrapper)request).getRequest();
116
117        if (__servlet3 )
118        {
119            try
120            {
121                continuation=__newServlet3Continuation.newInstance(request);
122                request.setAttribute(Continuation.ATTRIBUTE,continuation);
123                return continuation;
124            }
125            catch(Exception e)
126            {
127                throw new RuntimeException(e);
128            }
129        }
130
131        if (__jetty6)
132        {
133            Object c=request.getAttribute("org.mortbay.jetty.ajax.Continuation");
134            try
135            {
136                if (c==null || __waitingContinuation==null || __waitingContinuation.isInstance(c))
137                    continuation=new FauxContinuation(request);
138                else
139                    continuation= __newJetty6Continuation.newInstance(request,c);
140                request.setAttribute(Continuation.ATTRIBUTE,continuation);
141                return continuation;
142            }
143            catch(Exception e)
144            {
145                throw new RuntimeException(e);
146            }
147        }
148
149        throw new IllegalStateException("!(Jetty || Servlet 3.0 || ContinuationFilter)");
150    }
151
152    /* ------------------------------------------------------------ */
153    /**
154     * @param request the servlet request
155     * @param response the servlet response
156     * @deprecated use {@link #getContinuation(ServletRequest)}
157     * @return the continuation
158     */
159    @Deprecated
160    public static Continuation getContinuation(final ServletRequest request, final ServletResponse response)
161    {
162        return getContinuation(request);
163    }
164}
165