1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.jetty.servlet;
16
17
18 import java.io.IOException;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.servlet.Filter;
26 import javax.servlet.FilterChain;
27 import javax.servlet.RequestDispatcher;
28 import javax.servlet.Servlet;
29 import javax.servlet.ServletContext;
30 import javax.servlet.ServletException;
31 import javax.servlet.ServletRequest;
32 import javax.servlet.ServletRequestEvent;
33 import javax.servlet.ServletRequestListener;
34 import javax.servlet.ServletResponse;
35 import javax.servlet.UnavailableException;
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpServletResponse;
38
39 import org.mortbay.io.RuntimeIOException;
40 import org.mortbay.jetty.EofException;
41 import org.mortbay.jetty.HttpConnection;
42 import org.mortbay.jetty.HttpException;
43 import org.mortbay.jetty.Request;
44 import org.mortbay.jetty.RetryRequest;
45 import org.mortbay.jetty.Server;
46 import org.mortbay.jetty.handler.AbstractHandler;
47 import org.mortbay.jetty.handler.ContextHandler;
48 import org.mortbay.log.Log;
49 import org.mortbay.util.LazyList;
50 import org.mortbay.util.MultiException;
51 import org.mortbay.util.MultiMap;
52 import org.mortbay.util.URIUtil;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class ServletHandler extends AbstractHandler
71 {
72
73 public static final String __DEFAULT_SERVLET="default";
74 public static final String __J_S_CONTEXT_TEMPDIR="javax.servlet.context.tempdir";
75 public static final String __J_S_ERROR_EXCEPTION="javax.servlet.error.exception";
76 public static final String __J_S_ERROR_EXCEPTION_TYPE="javax.servlet.error.exception_type";
77 public static final String __J_S_ERROR_MESSAGE="javax.servlet.error.message";
78 public static final String __J_S_ERROR_REQUEST_URI="javax.servlet.error.request_uri";
79 public static final String __J_S_ERROR_SERVLET_NAME="javax.servlet.error.servlet_name";
80 public static final String __J_S_ERROR_STATUS_CODE="javax.servlet.error.status_code";
81
82
83 private ContextHandler _contextHandler;
84 private ContextHandler.SContext _servletContext;
85 private FilterHolder[] _filters;
86 private FilterMapping[] _filterMappings;
87 private boolean _filterChainsCached=true;
88 private int _maxFilterChainsCacheSize=1000;
89 private boolean _startWithUnavailable=true;
90
91 private ServletHolder[] _servlets;
92 private ServletMapping[] _servletMappings;
93
94 private transient Map _filterNameMap= new HashMap();
95 private transient List _filterPathMappings;
96 private transient MultiMap _filterNameMappings;
97
98 private transient Map _servletNameMap=new HashMap();
99 private transient PathMap _servletPathMap;
100
101 protected transient HashMap _chainCache[];
102
103
104
105
106
107 public ServletHandler()
108 {
109 }
110
111
112
113
114
115 public void setServer(Server server)
116 {
117 if (getServer()!=null && getServer()!=server)
118 {
119 getServer().getContainer().update(this, _filters, null, "filter",true);
120 getServer().getContainer().update(this, _filterMappings, null, "filterMapping",true);
121 getServer().getContainer().update(this, _servlets, null, "servlet",true);
122 getServer().getContainer().update(this, _servletMappings, null, "servletMapping",true);
123 }
124 if (server!=null && getServer()!=server)
125 {
126 server.getContainer().update(this, null, _filters, "filter",true);
127 server.getContainer().update(this, null, _filterMappings, "filterMapping",true);
128 server.getContainer().update(this, null, _servlets, "servlet",true);
129 server.getContainer().update(this, null, _servletMappings, "servletMapping",true);
130 }
131 super.setServer(server);
132
133 }
134
135
136 protected synchronized void doStart()
137 throws Exception
138 {
139 _servletContext=ContextHandler.getCurrentContext();
140 _contextHandler=_servletContext==null?null:_servletContext.getContextHandler();
141
142 updateNameMappings();
143 updateMappings();
144
145 if(_filterChainsCached)
146 _chainCache= new HashMap[]{null,new HashMap(),new HashMap(),null,new HashMap(),null,null,null,new HashMap()};
147
148 super.doStart();
149
150 if (_contextHandler==null || !(_contextHandler instanceof Context))
151 initialize();
152 }
153
154
155 protected synchronized void doStop()
156 throws Exception
157 {
158 super.doStop();
159
160
161 if (_filters!=null)
162 {
163 for (int i=_filters.length; i-->0;)
164 {
165 try { _filters[i].stop(); }catch(Exception e){Log.warn(Log.EXCEPTION,e);}
166 }
167 }
168
169
170 if (_servlets!=null)
171 {
172 for (int i=_servlets.length; i-->0;)
173 {
174 try { _servlets[i].stop(); }catch(Exception e){Log.warn(Log.EXCEPTION,e);}
175 }
176 }
177
178 _filterPathMappings=null;
179 _filterNameMappings=null;
180
181 _servletPathMap=null;
182 _chainCache=null;
183 }
184
185
186
187
188
189
190 public Object getContextLog()
191 {
192 return null;
193 }
194
195
196
197
198 public FilterMapping[] getFilterMappings()
199 {
200 return _filterMappings;
201 }
202
203
204
205
206
207 public FilterHolder[] getFilters()
208 {
209 return _filters;
210 }
211
212
213
214
215
216
217 public PathMap.Entry getHolderEntry(String pathInContext)
218 {
219 if (_servletPathMap==null)
220 return null;
221 return _servletPathMap.getMatch(pathInContext);
222 }
223
224
225
226
227
228
229 public boolean matchesPath(String pathInContext)
230 {
231 return _servletPathMap.containsMatch(pathInContext);
232 }
233
234
235
236
237
238 public RequestDispatcher getRequestDispatcher(String uriInContext)
239 {
240 if (uriInContext == null)
241 return null;
242
243 if (!uriInContext.startsWith("/"))
244 return null;
245
246 try
247 {
248 String query=null;
249 int q=0;
250 if ((q=uriInContext.indexOf('?'))>0)
251 {
252 query=uriInContext.substring(q+1);
253 uriInContext=uriInContext.substring(0,q);
254 }
255 if ((q=uriInContext.indexOf(';'))>0)
256 uriInContext=uriInContext.substring(0,q);
257
258 String pathInContext=URIUtil.canonicalPath(URIUtil.decodePath(uriInContext));
259 String uri=URIUtil.addPaths(_contextHandler.getContextPath(), uriInContext);
260 return new Dispatcher(_contextHandler, uri, pathInContext, query);
261 }
262 catch(Exception e)
263 {
264 Log.ignore(e);
265 }
266 return null;
267 }
268
269
270 public ServletContext getServletContext()
271 {
272 return _servletContext;
273 }
274
275
276
277
278 public ServletMapping[] getServletMappings()
279 {
280 return _servletMappings;
281 }
282
283
284
285
286
287 public ServletHolder[] getServlets()
288 {
289 return _servlets;
290 }
291
292
293 public ServletHolder getServlet(String name)
294 {
295 return (ServletHolder)_servletNameMap.get(name);
296 }
297
298
299
300
301
302 public void handle(String target, HttpServletRequest request,HttpServletResponse response, int type)
303 throws IOException, ServletException
304 {
305 if (!isStarted())
306 return;
307
308
309 final Request base_request=(request instanceof Request)?((Request)request):HttpConnection.getCurrentConnection().getRequest();
310 final String old_servlet_name=base_request.getServletName();
311 final String old_servlet_path=base_request.getServletPath();
312 final String old_path_info=base_request.getPathInfo();
313 final Map old_role_map=base_request.getRoleMap();
314 Object request_listeners=null;
315 ServletRequestEvent request_event=null;
316
317 try
318 {
319 ServletHolder servlet_holder=null;
320 FilterChain chain=null;
321
322
323 if (target.startsWith("/"))
324 {
325
326 PathMap.Entry entry=getHolderEntry(target);
327 if (entry!=null)
328 {
329 servlet_holder=(ServletHolder)entry.getValue();
330 base_request.setServletName(servlet_holder.getName());
331 base_request.setRoleMap(servlet_holder.getRoleMap());
332 if(Log.isDebugEnabled())Log.debug("servlet="+servlet_holder);
333
334 String servlet_path_spec=(String)entry.getKey();
335 String servlet_path=entry.getMapped()!=null?entry.getMapped():PathMap.pathMatch(servlet_path_spec,target);
336 String path_info=PathMap.pathInfo(servlet_path_spec,target);
337
338 if (type==INCLUDE)
339 {
340 base_request.setAttribute(Dispatcher.__INCLUDE_SERVLET_PATH,servlet_path);
341 base_request.setAttribute(Dispatcher.__INCLUDE_PATH_INFO, path_info);
342 }
343 else
344 {
345 base_request.setServletPath(servlet_path);
346 base_request.setPathInfo(path_info);
347 }
348
349 if (servlet_holder!=null && _filterMappings!=null && _filterMappings.length>0)
350 chain=getFilterChain(type, target, servlet_holder);
351 }
352 }
353 else
354 {
355
356 servlet_holder=(ServletHolder)_servletNameMap.get(target);
357 if (servlet_holder!=null && _filterMappings!=null && _filterMappings.length>0)
358 {
359 base_request.setServletName(servlet_holder.getName());
360 chain=getFilterChain(type, null,servlet_holder);
361 }
362 }
363
364 if (Log.isDebugEnabled())
365 {
366 Log.debug("chain="+chain);
367 Log.debug("servlet holder="+servlet_holder);
368 }
369
370
371 request_listeners = base_request.takeRequestListeners();
372 if (request_listeners!=null)
373 {
374 request_event = new ServletRequestEvent(getServletContext(),request);
375 final int s=LazyList.size(request_listeners);
376 for(int i=0;i<s;i++)
377 {
378 final ServletRequestListener listener = (ServletRequestListener)LazyList.get(request_listeners,i);
379 listener.requestInitialized(request_event);
380 }
381 }
382
383
384 if (servlet_holder!=null)
385 {
386 base_request.setHandled(true);
387 if (chain!=null)
388 chain.doFilter(request, response);
389 else
390 servlet_holder.handle(request,response);
391 }
392 else
393 notFound(request, response);
394 }
395 catch(RetryRequest e)
396 {
397 base_request.setHandled(false);
398 throw e;
399 }
400 catch(EofException e)
401 {
402 throw e;
403 }
404 catch(RuntimeIOException e)
405 {
406 throw e;
407 }
408 catch(Exception e)
409 {
410 if (type!=REQUEST)
411 {
412 if (e instanceof IOException)
413 throw (IOException)e;
414 if (e instanceof RuntimeException)
415 throw (RuntimeException)e;
416 if (e instanceof ServletException)
417 throw (ServletException)e;
418 }
419
420
421
422 Throwable th=e;
423 if (th instanceof UnavailableException)
424 {
425 Log.debug(th);
426 }
427 else if (th instanceof ServletException)
428 {
429 Log.debug(th);
430 Throwable cause=((ServletException)th).getRootCause();
431 if (cause!=th && cause!=null)
432 th=cause;
433 }
434
435
436 if (th instanceof RetryRequest)
437 {
438 base_request.setHandled(false);
439 throw (RetryRequest)th;
440 }
441 else if (th instanceof HttpException)
442 throw (HttpException)th;
443 else if (th instanceof RuntimeIOException)
444 throw (RuntimeIOException)th;
445 else if (th instanceof EofException)
446 throw (EofException)th;
447 else if (Log.isDebugEnabled())
448 {
449 Log.warn(request.getRequestURI(), th);
450 Log.debug(request.toString());
451 }
452 else if (th instanceof IOException || th instanceof UnavailableException)
453 {
454 Log.warn(request.getRequestURI()+": "+th);
455 }
456 else
457 {
458 Log.warn(request.getRequestURI(),th);
459 }
460
461
462 if (!response.isCommitted())
463 {
464 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,th.getClass());
465 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,th);
466 if (th instanceof UnavailableException)
467 {
468 UnavailableException ue = (UnavailableException)th;
469 if (ue.isPermanent())
470 response.sendError(HttpServletResponse.SC_NOT_FOUND,th.getMessage());
471 else
472 response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,th.getMessage());
473 }
474 else
475 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,th.getMessage());
476 }
477 else
478 if(Log.isDebugEnabled())Log.debug("Response already committed for handling "+th);
479 }
480 catch(Error e)
481 {
482 if (type!=REQUEST)
483 throw e;
484 Log.warn("Error for "+request.getRequestURI(),e);
485 if(Log.isDebugEnabled())Log.debug(request.toString());
486
487
488 if (!response.isCommitted())
489 {
490 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION_TYPE,e.getClass());
491 request.setAttribute(ServletHandler.__J_S_ERROR_EXCEPTION,e);
492 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
493 }
494 else
495 if(Log.isDebugEnabled())Log.debug("Response already committed for handling ",e);
496 }
497 finally
498 {
499 if (request_listeners!=null)
500 {
501 for(int i=LazyList.size(request_listeners);i-->0;)
502 {
503 final ServletRequestListener listener = (ServletRequestListener)LazyList.get(request_listeners,i);
504 listener.requestDestroyed(request_event);
505 }
506 }
507
508 base_request.setServletName(old_servlet_name);
509 base_request.setRoleMap(old_role_map);
510 if (type!=INCLUDE)
511 {
512 base_request.setServletPath(old_servlet_path);
513 base_request.setPathInfo(old_path_info);
514 }
515 }
516 return;
517 }
518
519
520 private FilterChain getFilterChain(int requestType, String pathInContext, ServletHolder servletHolder)
521 {
522 String key=pathInContext==null?servletHolder.getName():pathInContext;
523
524 if (_filterChainsCached && _chainCache!=null)
525 {
526 synchronized(this)
527 {
528 if(_chainCache[requestType].containsKey(key))
529 return (FilterChain)_chainCache[requestType].get(key);
530 }
531 }
532
533
534 Object filters= null;
535
536
537 if (pathInContext!=null && _filterPathMappings!=null)
538 {
539 for (int i= 0; i < _filterPathMappings.size(); i++)
540 {
541 FilterMapping mapping = (FilterMapping)_filterPathMappings.get(i);
542 if (mapping.appliesTo(pathInContext, requestType))
543 filters= LazyList.add(filters, mapping.getFilterHolder());
544 }
545 }
546
547
548 if (servletHolder != null && _filterNameMappings!=null && _filterNameMappings.size() > 0)
549 {
550
551 if (_filterNameMappings.size() > 0)
552 {
553 Object o= _filterNameMappings.get(servletHolder.getName());
554 for (int i=0; i<LazyList.size(o);i++)
555 {
556 FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
557 if (mapping.appliesTo(requestType))
558 filters=LazyList.add(filters,mapping.getFilterHolder());
559 }
560
561 o= _filterNameMappings.get("*");
562 for (int i=0; i<LazyList.size(o);i++)
563 {
564 FilterMapping mapping = (FilterMapping)LazyList.get(o,i);
565 if (mapping.appliesTo(requestType))
566 filters=LazyList.add(filters,mapping.getFilterHolder());
567 }
568 }
569 }
570
571 if (filters==null)
572 return null;
573
574 FilterChain chain = null;
575 if (_filterChainsCached)
576 {
577 if (LazyList.size(filters) > 0)
578 chain= new CachedChain(filters, servletHolder);
579 synchronized(this)
580 {
581 if (_maxFilterChainsCacheSize>0 && _chainCache[requestType].size()>_maxFilterChainsCacheSize)
582 _chainCache[requestType].clear();
583 _chainCache[requestType].put(key,chain);
584 }
585 }
586 else if (LazyList.size(filters) > 0)
587 chain = new Chain(filters, servletHolder);
588
589 return chain;
590 }
591
592
593
594
595
596
597 public boolean isInitializeAtStart()
598 {
599 return false;
600 }
601
602
603
604
605
606
607 public void setInitializeAtStart(boolean initializeAtStart)
608 {
609 }
610
611
612
613
614
615 public boolean isAvailable()
616 {
617 if (!isStarted())
618 return false;
619 ServletHolder[] holders = getServlets();
620 for (int i=0;i<holders.length;i++)
621 {
622 ServletHolder holder = holders[i];
623 if (holder!=null && !holder.isAvailable())
624 return false;
625 }
626 return true;
627 }
628
629
630
631
632
633 public void setStartWithUnavailable(boolean start)
634 {
635 _startWithUnavailable=start;
636 }
637
638
639
640
641
642 public boolean isStartWithUnavailable()
643 {
644 return _startWithUnavailable;
645 }
646
647
648
649
650
651
652
653 public void initialize()
654 throws Exception
655 {
656 MultiException mx = new MultiException();
657
658
659 if (_filters!=null)
660 {
661 for (int i=0;i<_filters.length; i++)
662 _filters[i].start();
663 }
664
665 if (_servlets!=null)
666 {
667
668 ServletHolder[] servlets = (ServletHolder[])_servlets.clone();
669 Arrays.sort(servlets);
670 for (int i=0; i<servlets.length; i++)
671 {
672 try
673 {
674 if (servlets[i].getClassName()==null && servlets[i].getForcedPath()!=null)
675 {
676 ServletHolder forced_holder = (ServletHolder)_servletPathMap.match(servlets[i].getForcedPath());
677 if (forced_holder==null || forced_holder.getClassName()==null)
678 {
679 mx.add(new IllegalStateException("No forced path servlet for "+servlets[i].getForcedPath()));
680 continue;
681 }
682 servlets[i].setClassName(forced_holder.getClassName());
683 }
684
685 servlets[i].start();
686 }
687 catch(Throwable e)
688 {
689 Log.debug(Log.EXCEPTION,e);
690 mx.add(e);
691 }
692 }
693 mx.ifExceptionThrow();
694 }
695 }
696
697
698
699
700
701 public boolean isFilterChainsCached()
702 {
703 return _filterChainsCached;
704 }
705
706
707
708
709
710 public ServletHolder newServletHolder()
711 {
712 return new ServletHolder();
713 }
714
715
716 public ServletHolder newServletHolder(Class servlet)
717 {
718 return new ServletHolder(servlet);
719 }
720
721
722
723
724
725 public ServletHolder addServletWithMapping (String className,String pathSpec)
726 {
727 ServletHolder holder = newServletHolder(null);
728 holder.setName(className+"-"+holder.hashCode());
729 holder.setClassName(className);
730
731 addServletWithMapping(holder,pathSpec);
732
733 return holder;
734 }
735
736
737
738
739
740 public ServletHolder addServletWithMapping (Class servlet,String pathSpec)
741 {
742 ServletHolder holder = newServletHolder(servlet);
743 setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
744
745 addServletWithMapping(holder,pathSpec);
746
747 return holder;
748 }
749
750
751
752
753
754
755
756
757 public void addServletWithMapping (ServletHolder servlet,String pathSpec)
758 {
759 ServletHolder[] holders=getServlets();
760 if (holders!=null)
761 holders = (ServletHolder[])holders.clone();
762
763 try
764 {
765 setServlets((ServletHolder[])LazyList.addToArray(holders, servlet, ServletHolder.class));
766
767 ServletMapping mapping = new ServletMapping();
768 mapping.setServletName(servlet.getName());
769 mapping.setPathSpec(pathSpec);
770 setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mapping, ServletMapping.class));
771 }
772 catch (Exception e)
773 {
774 setServlets(holders);
775 if (e instanceof RuntimeException)
776 throw (RuntimeException)e;
777 throw new RuntimeException(e);
778 }
779 }
780
781
782
783
784
785
786
787
788 public ServletHolder addServlet (String className, String pathSpec)
789 {
790 return addServletWithMapping (className, pathSpec);
791 }
792
793
794
795
796
797
798 public void addServlet(ServletHolder holder)
799 {
800 setServlets((ServletHolder[])LazyList.addToArray(getServlets(), holder, ServletHolder.class));
801 }
802
803
804
805
806
807 public void addServletMapping (ServletMapping mapping)
808 {
809 setServletMappings((ServletMapping[])LazyList.addToArray(getServletMappings(), mapping, ServletMapping.class));
810 }
811
812
813 public FilterHolder newFilterHolder(Class filter)
814 {
815 return new FilterHolder(filter);
816 }
817
818
819
820
821
822 public FilterHolder newFilterHolder()
823 {
824 return new FilterHolder();
825 }
826
827
828 public FilterHolder getFilter(String name)
829 {
830 return (FilterHolder)_filterNameMap.get(name);
831 }
832
833
834
835
836
837
838
839
840
841 public FilterHolder addFilterWithMapping (Class filter,String pathSpec,int dispatches)
842 {
843 FilterHolder holder = newFilterHolder(filter);
844 addFilterWithMapping(holder,pathSpec,dispatches);
845
846 return holder;
847 }
848
849
850
851
852
853
854
855
856
857 public FilterHolder addFilterWithMapping (String className,String pathSpec,int dispatches)
858 {
859 FilterHolder holder = newFilterHolder(null);
860 holder.setName(className+"-"+holder.hashCode());
861 holder.setClassName(className);
862
863 addFilterWithMapping(holder,pathSpec,dispatches);
864 return holder;
865 }
866
867
868
869
870
871
872
873
874
875 public void addFilterWithMapping (FilterHolder holder,String pathSpec,int dispatches)
876 {
877 FilterHolder[] holders = getFilters();
878 if (holders!=null)
879 holders = (FilterHolder[])holders.clone();
880
881 try
882 {
883 setFilters((FilterHolder[])LazyList.addToArray(holders, holder, FilterHolder.class));
884
885 FilterMapping mapping = new FilterMapping();
886 mapping.setFilterName(holder.getName());
887 mapping.setPathSpec(pathSpec);
888 mapping.setDispatches(dispatches);
889 setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
890 }
891 catch (RuntimeException e)
892 {
893 setFilters(holders);
894 throw e;
895 }
896 catch (Error e)
897 {
898 setFilters(holders);
899 throw e;
900 }
901
902 }
903
904
905
906
907
908
909
910
911
912 public FilterHolder addFilter (String className,String pathSpec,int dispatches)
913 {
914 return addFilterWithMapping(className, pathSpec, dispatches);
915 }
916
917
918
919
920
921
922
923 public void addFilter (FilterHolder filter, FilterMapping filterMapping)
924 {
925 if (filter != null)
926 setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filter, FilterHolder.class));
927 if (filterMapping != null)
928 setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), filterMapping, FilterMapping.class));
929 }
930
931
932
933
934
935 public void addFilter (FilterHolder filter)
936 {
937 if (filter != null)
938 setFilters((FilterHolder[])LazyList.addToArray(getFilters(), filter, FilterHolder.class));
939 }
940
941
942
943
944
945 public void addFilterMapping (FilterMapping mapping)
946 {
947 if (mapping != null)
948 setFilterMappings((FilterMapping[])LazyList.addToArray(getFilterMappings(), mapping, FilterMapping.class));
949 }
950
951
952 protected synchronized void updateNameMappings()
953 {
954
955 _filterNameMap.clear();
956 if (_filters!=null)
957 {
958 for (int i=0;i<_filters.length;i++)
959 {
960 _filterNameMap.put(_filters[i].getName(),_filters[i]);
961 _filters[i].setServletHandler(this);
962 }
963 }
964
965
966 _servletNameMap.clear();
967 if (_servlets!=null)
968 {
969
970 for (int i=0;i<_servlets.length;i++)
971 {
972 _servletNameMap.put(_servlets[i].getName(),_servlets[i]);
973 _servlets[i].setServletHandler(this);
974 }
975 }
976 }
977
978
979 protected synchronized void updateMappings()
980 {
981
982 if (_filterMappings==null)
983 {
984 _filterPathMappings=null;
985 _filterNameMappings=null;
986 }
987 else
988 {
989 _filterPathMappings=new ArrayList();
990 _filterNameMappings=new MultiMap();
991 for (int i=0;i<_filterMappings.length;i++)
992 {
993 FilterHolder filter_holder = (FilterHolder)_filterNameMap.get(_filterMappings[i].getFilterName());
994 if (filter_holder==null)
995 throw new IllegalStateException("No filter named "+_filterMappings[i].getFilterName());
996 _filterMappings[i].setFilterHolder(filter_holder);
997 if (_filterMappings[i].getPathSpecs()!=null)
998 _filterPathMappings.add(_filterMappings[i]);
999
1000 if (_filterMappings[i].getServletNames()!=null)
1001 {
1002 String[] names=_filterMappings[i].getServletNames();
1003 for (int j=0;j<names.length;j++)
1004 {
1005 if (names[j]!=null)
1006 _filterNameMappings.add(names[j], _filterMappings[i]);
1007 }
1008 }
1009 }
1010 }
1011
1012
1013 if (_servletMappings==null || _servletNameMap==null)
1014 {
1015 _servletPathMap=null;
1016 }
1017 else
1018 {
1019 PathMap pm = new PathMap();
1020
1021
1022 for (int i=0;i<_servletMappings.length;i++)
1023 {
1024 ServletHolder servlet_holder = (ServletHolder)_servletNameMap.get(_servletMappings[i].getServletName());
1025 if (servlet_holder==null)
1026 throw new IllegalStateException("No such servlet: "+_servletMappings[i].getServletName());
1027 else if (_servletMappings[i].getPathSpecs()!=null)
1028 {
1029 String[] pathSpecs = _servletMappings[i].getPathSpecs();
1030 for (int j=0;j<pathSpecs.length;j++)
1031 if (pathSpecs[j]!=null)
1032 pm.put(pathSpecs[j],servlet_holder);
1033 }
1034 }
1035
1036 _servletPathMap=pm;
1037 }
1038
1039
1040
1041 if (Log.isDebugEnabled())
1042 {
1043 Log.debug("filterNameMap="+_filterNameMap);
1044 Log.debug("pathFilters="+_filterPathMappings);
1045 Log.debug("servletFilterMap="+_filterNameMappings);
1046 Log.debug("servletPathMap="+_servletPathMap);
1047 Log.debug("servletNameMap="+_servletNameMap);
1048 }
1049
1050 try
1051 {
1052 if (isStarted())
1053 initialize();
1054 }
1055 catch (Exception e)
1056 {
1057 throw new RuntimeException(e);
1058 }
1059 }
1060
1061
1062
1063 protected void notFound(HttpServletRequest request,
1064 HttpServletResponse response)
1065 throws IOException
1066 {
1067 if(Log.isDebugEnabled())Log.debug("Not Found "+request.getRequestURI());
1068 response.sendError(HttpServletResponse.SC_NOT_FOUND);
1069 }
1070
1071
1072
1073
1074
1075 public void setFilterChainsCached(boolean filterChainsCached)
1076 {
1077 _filterChainsCached = filterChainsCached;
1078 }
1079
1080
1081
1082
1083
1084 public void setFilterMappings(FilterMapping[] filterMappings)
1085 {
1086 if (getServer()!=null)
1087 getServer().getContainer().update(this,_filterMappings,filterMappings,"filterMapping",true);
1088 _filterMappings = filterMappings;
1089 updateMappings();
1090 }
1091
1092
1093 public synchronized void setFilters(FilterHolder[] holders)
1094 {
1095 if (getServer()!=null)
1096 getServer().getContainer().update(this,_filters,holders,"filter",true);
1097 _filters=holders;
1098 updateNameMappings();
1099 }
1100
1101
1102
1103
1104
1105 public void setServletMappings(ServletMapping[] servletMappings)
1106 {
1107 if (getServer()!=null)
1108 getServer().getContainer().update(this,_servletMappings,servletMappings,"servletMapping",true);
1109 _servletMappings = servletMappings;
1110 updateMappings();
1111 }
1112
1113
1114
1115
1116
1117 public synchronized void setServlets(ServletHolder[] holders)
1118 {
1119 if (getServer()!=null)
1120 getServer().getContainer().update(this,_servlets,holders,"servlet",true);
1121 _servlets=holders;
1122 updateNameMappings();
1123 }
1124
1125
1126
1127
1128 private class CachedChain implements FilterChain
1129 {
1130 FilterHolder _filterHolder;
1131 CachedChain _next;
1132 ServletHolder _servletHolder;
1133
1134
1135 CachedChain(Object filters, ServletHolder servletHolder)
1136 {
1137 if (LazyList.size(filters)>0)
1138 {
1139 _filterHolder=(FilterHolder)LazyList.get(filters, 0);
1140 filters=LazyList.remove(filters,0);
1141 _next=new CachedChain(filters,servletHolder);
1142 }
1143 else
1144 _servletHolder=servletHolder;
1145 }
1146
1147
1148 public void doFilter(ServletRequest request, ServletResponse response)
1149 throws IOException, ServletException
1150 {
1151
1152 if (_filterHolder!=null)
1153 {
1154 if (Log.isDebugEnabled())
1155 Log.debug("call filter " + _filterHolder);
1156 Filter filter= _filterHolder.getFilter();
1157 filter.doFilter(request, response, _next);
1158 return;
1159 }
1160
1161
1162 if (_servletHolder != null)
1163 {
1164 if (Log.isDebugEnabled())
1165 Log.debug("call servlet " + _servletHolder);
1166 _servletHolder.handle(request, response);
1167 }
1168 else
1169 notFound((HttpServletRequest)request, (HttpServletResponse)response);
1170 }
1171
1172 public String toString()
1173 {
1174 if (_filterHolder!=null)
1175 return _filterHolder+"->"+_next.toString();
1176 if (_servletHolder!=null)
1177 return _servletHolder.toString();
1178 return "null";
1179 }
1180 }
1181
1182
1183
1184 private class Chain implements FilterChain
1185 {
1186 int _filter= 0;
1187 Object _chain;
1188 ServletHolder _servletHolder;
1189
1190
1191 Chain(Object filters, ServletHolder servletHolder)
1192 {
1193 _chain= filters;
1194 _servletHolder= servletHolder;
1195 }
1196
1197
1198 public void doFilter(ServletRequest request, ServletResponse response)
1199 throws IOException, ServletException
1200 {
1201 if (Log.isDebugEnabled()) Log.debug("doFilter " + _filter);
1202
1203
1204 if (_filter < LazyList.size(_chain))
1205 {
1206 FilterHolder holder= (FilterHolder)LazyList.get(_chain, _filter++);
1207 if (Log.isDebugEnabled()) Log.debug("call filter " + holder);
1208 Filter filter= holder.getFilter();
1209 filter.doFilter(request, response, this);
1210 return;
1211 }
1212
1213
1214 if (_servletHolder != null)
1215 {
1216 if (Log.isDebugEnabled()) Log.debug("call servlet " + _servletHolder);
1217 _servletHolder.handle(request, response);
1218 }
1219 else
1220 notFound((HttpServletRequest)request, (HttpServletResponse)response);
1221 }
1222
1223
1224 public String toString()
1225 {
1226 StringBuffer b = new StringBuffer();
1227 for (int i=0; i<LazyList.size(_chain);i++)
1228 {
1229 b.append(LazyList.get(_chain, i).toString());
1230 b.append("->");
1231 }
1232 b.append(_servletHolder);
1233 return b.toString();
1234 }
1235 }
1236
1237
1238
1239
1240
1241 public int getMaxFilterChainsCacheSize()
1242 {
1243 return _maxFilterChainsCacheSize;
1244 }
1245
1246
1247
1248
1249
1250
1251
1252
1253 public void setMaxFilterChainsCacheSize(int maxFilterChainsCacheSize)
1254 {
1255 _maxFilterChainsCacheSize = maxFilterChainsCacheSize;
1256 }
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 public Servlet customizeServlet (Servlet servlet)
1270 throws Exception
1271 {
1272 return servlet;
1273 }
1274
1275
1276 public Servlet customizeServletDestroy (Servlet servlet)
1277 throws Exception
1278 {
1279 return servlet;
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 public Filter customizeFilter (Filter filter)
1295 throws Exception
1296 {
1297 return filter;
1298 }
1299
1300
1301 public Filter customizeFilterDestroy (Filter filter)
1302 throws Exception
1303 {
1304 return filter;
1305 }
1306 }