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 _handlers = handlers;
79
80 Server server = getServer();
81 MultiException mex = new MultiException();
82 for (int i=0;handlers!=null && i<handlers.length;i++)
83 {
84 if (handlers[i].getServer()!=server)
85 handlers[i].setServer(server);
86 }
87
88 if (getServer()!=null)
89 getServer().getContainer().update(this, old_handlers, handlers, "handler");
90
91
92 for (int i=0;old_handlers!=null && i<old_handlers.length;i++)
93 {
94 if (old_handlers[i]!=null)
95 {
96 try
97 {
98 if (old_handlers[i].isStarted())
99 old_handlers[i].stop();
100 }
101 catch (Throwable e)
102 {
103 mex.add(e);
104 }
105 }
106 }
107
108 mex.ifExceptionThrowRuntime();
109 }
110
111
112
113
114
115
116
117 public boolean isParallelStart()
118 {
119 return _parallelStart;
120 }
121
122
123
124
125
126
127
128 public void setParallelStart(boolean parallelStart)
129 {
130 this._parallelStart = parallelStart;
131 }
132
133
134
135
136
137
138 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
139 throws IOException, ServletException
140 {
141 if (_handlers!=null && isStarted())
142 {
143 MultiException mex=null;
144
145 for (int i=0;i<_handlers.length;i++)
146 {
147 try
148 {
149 _handlers[i].handle(target,baseRequest, request, response);
150 }
151 catch(IOException e)
152 {
153 throw e;
154 }
155 catch(RuntimeException e)
156 {
157 throw e;
158 }
159 catch(Exception e)
160 {
161 if (mex==null)
162 mex=new MultiException();
163 mex.add(e);
164 }
165 }
166 if (mex!=null)
167 {
168 if (mex.size()==1)
169 throw new ServletException(mex.getThrowable(0));
170 else
171 throw new ServletException(mex);
172 }
173
174 }
175 }
176
177
178
179
180
181 @Override
182 protected void doStart() throws Exception
183 {
184 final MultiException mex=new MultiException();
185 if (_handlers!=null)
186 {
187 if (_parallelStart)
188 {
189 final CountDownLatch latch = new CountDownLatch(_handlers.length);
190 final ClassLoader loader = Thread.currentThread().getContextClassLoader();
191 for (int i=0;i<_handlers.length;i++)
192 {
193 final int h=i;
194 getServer().getThreadPool().dispatch(
195 new Runnable()
196 {
197 public void run()
198 {
199 ClassLoader orig = Thread.currentThread().getContextClassLoader();
200 try
201 {
202 Thread.currentThread().setContextClassLoader(loader);
203 _handlers[h].start();
204 }
205 catch(Throwable e)
206 {
207 mex.add(e);
208 }
209 finally
210 {
211 Thread.currentThread().setContextClassLoader(orig);
212 latch.countDown();
213 }
214 }
215 }
216 );
217 }
218 latch.await();
219 }
220 else
221 {
222 for (int i=0;i<_handlers.length;i++)
223 {
224 try{_handlers[i].start();}
225 catch(Throwable e){mex.add(e);}
226 }
227 }
228 }
229 super.doStart();
230 mex.ifExceptionThrow();
231 }
232
233
234
235
236
237 @Override
238 protected void doStop() throws Exception
239 {
240 MultiException mex=new MultiException();
241 try { super.doStop(); } catch(Throwable e){mex.add(e);}
242 if (_handlers!=null)
243 {
244 for (int i=_handlers.length;i-->0;)
245 try{_handlers[i].stop();}catch(Throwable e){mex.add(e);}
246 }
247 mex.ifExceptionThrow();
248 }
249
250
251 @Override
252 public void setServer(Server server)
253 {
254 if (isStarted())
255 throw new IllegalStateException(STARTED);
256
257 Server old_server=getServer();
258
259 super.setServer(server);
260
261 Handler[] h=getHandlers();
262 for (int i=0;h!=null && i<h.length;i++)
263 h[i].setServer(server);
264
265 if (server!=null && server!=old_server)
266 server.getContainer().update(this, null,_handlers, "handler");
267
268 }
269
270
271
272
273
274
275 public void addHandler(Handler handler)
276 {
277 setHandlers((Handler[])LazyList.addToArray(getHandlers(), handler, Handler.class));
278 }
279
280
281 public void removeHandler(Handler handler)
282 {
283 Handler[] handlers = getHandlers();
284
285 if (handlers!=null && handlers.length>0 )
286 setHandlers((Handler[])LazyList.removeFromArray(handlers, handler));
287 }
288
289
290 @Override
291 protected Object expandChildren(Object list, Class byClass)
292 {
293 Handler[] handlers = getHandlers();
294 for (int i=0;handlers!=null && i<handlers.length;i++)
295 list=expandHandler(handlers[i], list, byClass);
296 return list;
297 }
298
299
300 @Override
301 public void destroy()
302 {
303 if (!isStopped())
304 throw new IllegalStateException("!STOPPED");
305 Handler[] children=getChildHandlers();
306 setHandlers(null);
307 for (Handler child: children)
308 child.destroy();
309 super.destroy();
310 }
311 }