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