blob: 0acfff22c2fa9d3f84b0612821e4e1147decb3f1 [file] [log] [blame]
Jake Slack03928ae2014-05-13 18:41:56 -07001//
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.server.handler;
20
21import java.io.IOException;
22
23import javax.servlet.ServletException;
24import javax.servlet.http.HttpServletRequest;
25import javax.servlet.http.HttpServletResponse;
26
27import 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 */
96public 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}