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