1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.server.handler;
15
16 import java.io.IOException;
17 import java.util.concurrent.CountDownLatch;
18
19 import javax.servlet.ServletException;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import org.eclipse.jetty.server.Handler;
24 import org.eclipse.jetty.server.Request;
25 import org.eclipse.jetty.server.Server;
26 import org.eclipse.jetty.util.LazyList;
27 import org.eclipse.jetty.util.MultiException;
28
29
30
31
32
33
34
35
36
37
38
39
40 public class HandlerCollection extends AbstractHandlerContainer
41 {
42 private final boolean _mutableWhenRunning;
43 private volatile Handler[] _handlers;
44 private boolean _parallelStart=false;
45
46
47 public HandlerCollection()
48 {
49 _mutableWhenRunning=false;
50 }
51
52
53 public HandlerCollection(boolean mutableWhenRunning)
54 {
55 _mutableWhenRunning=mutableWhenRunning;
56 }
57
58
59
60
61
62 public Handler[] getHandlers()
63 {
64 return _handlers;
65 }
66
67
68
69
70
71
72 public void setHandlers(Handler[] handlers)
73 {
74 if (!_mutableWhenRunning && isStarted())
75 throw new IllegalStateException(STARTED);
76
77 Handler [] old_handlers = _handlers==null?null:_handlers.clone();
78
79 if (getServer()!=null)
80 getServer().getContainer().update(this, old_handlers, handlers, "handler");
81
82 Server server = getServer();
83 MultiException mex = new MultiException();
84 for (int i=0;handlers!=null && i<handlers.length;i++)
85 {
86 if (handlers[i].getServer()!=server)
87 handlers[i].setServer(server);
88 }
89
90
91 _handlers = handlers;
92
93
94 for (int i=0;old_handlers!=null && i<old_handlers.length;i++)
95 {
96 if (old_handlers[i]!=null)
97 {
98 try
99 {
100 if (old_handlers[i].isStarted())
101 old_handlers[i].stop();
102 }
103 catch (Throwable e)
104 {
105 mex.add(e);
106 }
107 }
108 }
109
110 mex.ifExceptionThrowRuntime();
111 }
112
113
114
115
116
117
118
119 public boolean isParallelStart()
120 {
121 return _parallelStart;
122 }
123
124
125
126
127
128
129
130 public void setParallelStart(boolean parallelStart)
131 {
132 this._parallelStart = parallelStart;
133 }
134
135
136
137
138
139
140 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
141 throws IOException, ServletException
142 {
143 if (_handlers!=null && isStarted())
144 {
145 MultiException mex=null;
146
147 for (int i=0;i<_handlers.length;i++)
148 {
149 try
150 {
151 _handlers[i].handle(target,baseRequest, request, response);
152 }
153 catch(IOException e)
154 {
155 throw e;
156 }
157 catch(RuntimeException e)
158 {
159 throw e;
160 }
161 catch(Exception e)
162 {
163 if (mex==null)
164 mex=new MultiException();
165 mex.add(e);
166 }
167 }
168 if (mex!=null)
169 {
170 if (mex.size()==1)
171 throw new ServletException(mex.getThrowable(0));
172 else
173 throw new ServletException(mex);
174 }
175
176 }
177 }
178
179
180
181
182
183 @Override
184 protected void doStart() throws Exception
185 {
186 final MultiException mex=new MultiException();
187 if (_handlers!=null)
188 {
189 if (_parallelStart)
190 {
191 final CountDownLatch latch = new CountDownLatch(_handlers.length);
192 final ClassLoader loader = Thread.currentThread().getContextClassLoader();
193 for (int i=0;i<_handlers.length;i++)
194 {
195 final int h=i;
196 getServer().getThreadPool().dispatch(
197 new Runnable()
198 {
199 public void run()
200 {
201 ClassLoader orig = Thread.currentThread().getContextClassLoader();
202 try
203 {
204 Thread.currentThread().setContextClassLoader(loader);
205 _handlers[h].start();
206 }
207 catch(Throwable e)
208 {
209 mex.add(e);
210 }
211 finally
212 {
213 Thread.currentThread().setContextClassLoader(orig);
214 latch.countDown();
215 }
216 }
217 }
218 );
219 }
220 latch.await();
221 }
222 else
223 {
224 for (int i=0;i<_handlers.length;i++)
225 {
226 try{_handlers[i].start();}
227 catch(Throwable e){mex.add(e);}
228 }
229 }
230 }
231 super.doStart();
232 mex.ifExceptionThrow();
233 }
234
235
236
237
238
239 @Override
240 protected void doStop() throws Exception
241 {
242 MultiException mex=new MultiException();
243 try { super.doStop(); } catch(Throwable e){mex.add(e);}
244 if (_handlers!=null)
245 {
246 for (int i=_handlers.length;i-->0;)
247 try{_handlers[i].stop();}catch(Throwable e){mex.add(e);}
248 }
249 mex.ifExceptionThrow();
250 }
251
252
253 @Override
254 public void setServer(Server server)
255 {
256 if (isStarted())
257 throw new IllegalStateException(STARTED);
258
259 Server old_server=getServer();
260
261 super.setServer(server);
262
263 Handler[] h=getHandlers();
264 for (int i=0;h!=null && i<h.length;i++)
265 h[i].setServer(server);
266
267 if (server!=null && server!=old_server)
268 server.getContainer().update(this, null,_handlers, "handler");
269
270 }
271
272
273
274
275
276
277 public void addHandler(Handler handler)
278 {
279 setHandlers((Handler[])LazyList.addToArray(getHandlers(), handler, Handler.class));
280 }
281
282
283 public void removeHandler(Handler handler)
284 {
285 Handler[] handlers = getHandlers();
286
287 if (handlers!=null && handlers.length>0 )
288 setHandlers((Handler[])LazyList.removeFromArray(handlers, handler));
289 }
290
291
292 @Override
293 protected Object expandChildren(Object list, Class byClass)
294 {
295 Handler[] handlers = getHandlers();
296 for (int i=0;handlers!=null && i<handlers.length;i++)
297 list=expandHandler(handlers[i], list, byClass);
298 return list;
299 }
300
301
302 @Override
303 public void destroy()
304 {
305 if (!isStopped())
306 throw new IllegalStateException("!STOPPED");
307 Handler[] children=getChildHandlers();
308 setHandlers(null);
309 for (Handler child: children)
310 child.destroy();
311 super.destroy();
312 }
313 }