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= (ScopedHandler)getChildHandlerByClass(ScopedHandler.class);
118             
119         }
120         finally
121         {
122             if (_outerScope==null)
123                 __outerScope.set(null);
124         }
125     }
126 
127 
128     /* ------------------------------------------------------------ */
129     /* 
130      */
131     @Override
132     public final void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
133     {
134         if (_outerScope==null)  
135             doScope(target,baseRequest,request, response);
136         else 
137             doHandle(target,baseRequest,request, response);
138     }
139     
140     /* ------------------------------------------------------------ */
141     /* 
142      * Scope the handler
143      */
144     public abstract void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
145         throws IOException, ServletException;
146     
147     /* ------------------------------------------------------------ */
148     /* 
149      * Scope the handler
150      */
151     public final void nextScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
152         throws IOException, ServletException
153     {
154         // this method has been manually inlined in several locations, but
155         // is called protected by an if(never()), so your IDE can find those
156         // locations if this code is changed.
157         if (_nextScope!=null)
158             _nextScope.doScope(target,baseRequest,request, response);
159         else if (_outerScope!=null)
160             _outerScope.doHandle(target,baseRequest,request, response);
161         else 
162             doHandle(target,baseRequest,request, response);
163     }
164 
165     /* ------------------------------------------------------------ */
166     /* 
167      * Do the handler work within the scope.
168      */
169     public abstract void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 
170         throws IOException, ServletException;
171     
172     /* ------------------------------------------------------------ */
173     /* 
174      * Do the handler work within the scope.
175      */
176     public final void nextHandle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
177     {
178         // this method has been manually inlined in several locations, but
179         // is called protected by an if(never()), so your IDE can find those
180         // locations if this code is changed.
181         if (_nextScope!=null && _nextScope==_handler)
182             _nextScope.doHandle(target,baseRequest,request, response);
183         else if (_handler!=null)
184             _handler.handle(target,baseRequest, request, response);
185     }
186     
187     /* ------------------------------------------------------------ */
188     protected boolean never()
189     {
190         return false;
191     }
192     
193 }