View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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  
19  package org.eclipse.jetty.server.handler;
20  
21  import java.io.IOException;
22  
23  import javax.servlet.ServletException;
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  
27  import org.eclipse.jetty.server.Request;
28  
29  
30  /* ------------------------------------------------------------ */
31  /** ScopedHandler.
32   *
33   * A ScopedHandler is a HandlerWrapper where the wrapped handlers
34   * each define a scope.   When {@link #handle(String, Request, HttpServletRequest, HttpServletResponse)}
35   * is called on the first ScopedHandler in a chain of HandlerWrappers,
36   * the {@link #doScope(String, Request, HttpServletRequest, HttpServletResponse)} method is
37   * called on all contained ScopedHandlers, before the
38   * {@link #doHandle(String, Request, HttpServletRequest, HttpServletResponse)} method
39   * is called on all contained handlers.
40   *
41   * <p>For example if Scoped handlers A, B & C were chained together, then
42   * the calling order would be:<pre>
43   * A.handle(...)
44   *   A.doScope(...)
45   *     B.doScope(...)
46   *       C.doScope(...)
47   *         A.doHandle(...)
48   *           B.doHandle(...)
49   *              C.doHandle(...)
50   * <pre>
51   *
52   * <p>If non scoped handler X was in the chained A, B, X & C, then
53   * the calling order would be:<pre>
54   * A.handle(...)
55   *   A.doScope(...)
56   *     B.doScope(...)
57   *       C.doScope(...)
58   *         A.doHandle(...)
59   *           B.doHandle(...)
60   *             X.handle(...)
61   *               C.handle(...)
62   *                 C.doHandle(...)
63   * <pre>
64   *
65   * <p>A typical usage pattern is:<pre>
66   *     private static class MyHandler extends ScopedHandler
67   *     {
68   *         public void doScope(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
69   *         {
70   *             try
71   *             {
72   *                 setUpMyScope();
73   *                 super.doScope(target,request,response);
74   *             }
75   *             finally
76   *             {
77   *                 tearDownMyScope();
78   *             }
79   *         }
80   *
81   *         public void doHandle(String target, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
82   *         {
83   *             try
84   *             {
85   *                 doMyHandling();
86   *                 super.doHandle(target,request,response);
87   *             }
88   *             finally
89   *             {
90   *                 cleanupMyHandling();
91   *             }
92   *         }
93   *     }
94   * </pre>
95   */
96  public abstract class ScopedHandler extends HandlerWrapper
97  {
98      private static final ThreadLocal<ScopedHandler> __outerScope= new ThreadLocal<ScopedHandler>();
99      protected ScopedHandler _outerScope;
100     protected ScopedHandler _nextScope;
101 
102     /* ------------------------------------------------------------ */
103     /**
104      * @see org.eclipse.jetty.server.handler.HandlerWrapper#doStart()
105      */
106     @Override
107     protected void doStart() throws Exception
108     {
109         try
110         {
111             _outerScope=__outerScope.get();
112             if (_outerScope==null)
113                 __outerScope.set(this);
114 
115             super.doStart();
116 
117             _nextScope= getChildHandlerByClass(ScopedHandler.class);
118 
119         }
120         finally
121         {
122             if (_outerScope==null)
123                 __outerScope.set(null);
124         }
125     }
126 
127     /* ------------------------------------------------------------ */
128     /*
129      */
130     @Override
131     public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
132     {
133         if (isStarted())
134         {
135             if (_outerScope==null)
136                 doScope(target,baseRequest,request, response);
137             else
138                 doHandle(target,baseRequest,request, response);
139         }
140     }
141 
142     /* ------------------------------------------------------------ */
143     /*
144      * Scope the handler
145      */
146     public abstract void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
147         throws IOException, ServletException;
148 
149     /* ------------------------------------------------------------ */
150     /*
151      * Scope the handler
152      */
153     public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
154         throws IOException, ServletException
155     {
156         // this method has been manually inlined in several locations, but
157         // is called protected by an if(never()), so your IDE can find those
158         // locations if this code is changed.
159         if (_nextScope!=null)
160             _nextScope.doScope(target,baseRequest,request, response);
161         else if (_outerScope!=null)
162             _outerScope.doHandle(target,baseRequest,request, response);
163         else
164             doHandle(target,baseRequest,request, response);
165     }
166 
167     /* ------------------------------------------------------------ */
168     /*
169      * Do the handler work within the scope.
170      */
171     public abstract void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
172         throws IOException, ServletException;
173 
174     /* ------------------------------------------------------------ */
175     /*
176      * Do the handler work within the scope.
177      */
178     public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
179     {
180         // this method has been manually inlined in several locations, but
181         // is called protected by an if(never()), so your IDE can find those
182         // locations if this code is changed.
183         if (_nextScope!=null && _nextScope==_handler)
184             _nextScope.doHandle(target,baseRequest,request, response);
185         else if (_handler!=null)
186             _handler.handle(target,baseRequest, request, response);
187     }
188 
189     /* ------------------------------------------------------------ */
190     protected boolean never()
191     {
192         return false;
193     }
194 
195 }