1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.servlet;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.lang.reflect.Method;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.Stack;
34
35 import javax.servlet.MultipartConfigElement;
36 import javax.servlet.RequestDispatcher;
37 import javax.servlet.Servlet;
38 import javax.servlet.ServletConfig;
39 import javax.servlet.ServletContext;
40 import javax.servlet.ServletException;
41 import javax.servlet.ServletRegistration;
42 import javax.servlet.ServletRequest;
43 import javax.servlet.ServletResponse;
44 import javax.servlet.ServletSecurityElement;
45 import javax.servlet.SingleThreadModel;
46 import javax.servlet.UnavailableException;
47
48 import org.eclipse.jetty.security.IdentityService;
49 import org.eclipse.jetty.security.RunAsToken;
50 import org.eclipse.jetty.server.MultiPartCleanerListener;
51 import org.eclipse.jetty.server.Request;
52 import org.eclipse.jetty.server.UserIdentity;
53 import org.eclipse.jetty.server.handler.ContextHandler;
54 import org.eclipse.jetty.util.Loader;
55 import org.eclipse.jetty.util.annotation.ManagedAttribute;
56 import org.eclipse.jetty.util.annotation.ManagedObject;
57 import org.eclipse.jetty.util.log.Log;
58 import org.eclipse.jetty.util.log.Logger;
59
60
61
62
63
64
65
66
67
68 @ManagedObject("Servlet Holder")
69 public class ServletHolder extends Holder<Servlet> implements UserIdentity.Scope, Comparable<ServletHolder>
70 {
71
72
73 private static final Logger LOG = Log.getLogger(ServletHolder.class);
74 private int _initOrder = -1;
75 private boolean _initOnStartup=false;
76 private boolean _initialized = false;
77 private Map<String, String> _roleMap;
78 private String _forcedPath;
79 private String _runAsRole;
80 private RunAsToken _runAsToken;
81 private IdentityService _identityService;
82 private ServletRegistration.Dynamic _registration;
83 private JspContainer _jspContainer;
84
85 private transient Servlet _servlet;
86 private transient Config _config;
87 private transient long _unavailable;
88 private transient boolean _enabled = true;
89 private transient UnavailableException _unavailableEx;
90
91
92 public static final String APACHE_SENTINEL_CLASS = "org.apache.tomcat.InstanceManager";
93 public static final String JSP_GENERATED_PACKAGE_NAME = "org.eclipse.jetty.servlet.jspPackagePrefix";
94 public static final Map<String,String> NO_MAPPED_ROLES = Collections.emptyMap();
95 public static enum JspContainer {APACHE, OTHER};
96
97
98
99
100 public ServletHolder()
101 {
102 this(Source.EMBEDDED);
103 }
104
105
106
107
108
109 public ServletHolder(Holder.Source creator)
110 {
111 super(creator);
112 }
113
114
115
116
117
118 public ServletHolder(Servlet servlet)
119 {
120 this(Source.EMBEDDED);
121 setServlet(servlet);
122 }
123
124
125
126
127
128
129 public ServletHolder(String name, Class<? extends Servlet> servlet)
130 {
131 this(Source.EMBEDDED);
132 setName(name);
133 setHeldClass(servlet);
134 }
135
136
137
138
139
140
141 public ServletHolder(String name, Servlet servlet)
142 {
143 this(Source.EMBEDDED);
144 setName(name);
145 setServlet(servlet);
146 }
147
148
149
150
151
152 public ServletHolder(Class<? extends Servlet> servlet)
153 {
154 this(Source.EMBEDDED);
155 setHeldClass(servlet);
156 }
157
158
159
160
161
162 public UnavailableException getUnavailableException()
163 {
164 return _unavailableEx;
165 }
166
167
168 public synchronized void setServlet(Servlet servlet)
169 {
170 if (servlet==null || servlet instanceof SingleThreadModel)
171 throw new IllegalArgumentException();
172
173 _extInstance=true;
174 _servlet=servlet;
175 setHeldClass(servlet.getClass());
176 if (getName()==null)
177 setName(servlet.getClass().getName()+"-"+super.hashCode());
178 }
179
180
181 @ManagedAttribute(value="initialization order", readonly=true)
182 public int getInitOrder()
183 {
184 return _initOrder;
185 }
186
187
188
189
190
191
192
193
194
195
196 public void setInitOrder(int order)
197 {
198 _initOnStartup=order>=0;
199 _initOrder = order;
200 }
201
202
203
204
205
206 @Override
207 public int compareTo(ServletHolder sh)
208 {
209 if (sh==this)
210 return 0;
211
212 if (sh._initOrder<_initOrder)
213 return 1;
214
215 if (sh._initOrder>_initOrder)
216 return -1;
217
218
219 int c;
220 if (_className==null && sh._className==null)
221 c=0;
222 else if (_className==null)
223 c=-1;
224 else if (sh._className==null)
225 c=1;
226 else
227 c=_className.compareTo(sh._className);
228
229
230 if (c==0)
231 c=_name.compareTo(sh._name);
232
233 return c;
234 }
235
236
237 public boolean equals(Object o)
238 {
239 return o instanceof ServletHolder && compareTo((ServletHolder)o)==0;
240 }
241
242
243 public int hashCode()
244 {
245 return _name==null?System.identityHashCode(this):_name.hashCode();
246 }
247
248
249
250
251
252
253
254
255 public synchronized void setUserRoleLink(String name,String link)
256 {
257 if (_roleMap==null)
258 _roleMap=new HashMap<String, String>();
259 _roleMap.put(name,link);
260 }
261
262
263
264
265
266
267
268 public String getUserRoleLink(String name)
269 {
270 if (_roleMap==null)
271 return name;
272 String link= _roleMap.get(name);
273 return (link==null)?name:link;
274 }
275
276
277
278
279
280 @ManagedAttribute(value="forced servlet path", readonly=true)
281 public String getForcedPath()
282 {
283 return _forcedPath;
284 }
285
286
287
288
289
290 public void setForcedPath(String forcedPath)
291 {
292 _forcedPath = forcedPath;
293 }
294
295 public boolean isEnabled()
296 {
297 return _enabled;
298 }
299
300
301 public void setEnabled(boolean enabled)
302 {
303 _enabled = enabled;
304 }
305
306
307
308 public void doStart()
309 throws Exception
310 {
311 _unavailable=0;
312 if (!_enabled)
313 return;
314
315
316 if (_forcedPath != null)
317 {
318
319 String precompiled=getClassNameForJsp(_forcedPath);
320 if (LOG.isDebugEnabled())
321 LOG.debug("Checking for precompiled servlet {} for jsp {}", precompiled, _forcedPath);
322 ServletHolder jsp=getServletHandler().getServlet(precompiled);
323 if (jsp!=null && jsp.getClassName() != null)
324 {
325 if (LOG.isDebugEnabled())
326 LOG.debug("JSP file {} for {} mapped to Servlet {}",_forcedPath, getName(),jsp.getClassName());
327
328 setClassName(jsp.getClassName());
329 }
330 else
331 {
332 if (getClassName() == null)
333 {
334
335 jsp=getServletHandler().getServlet("jsp");
336 if (jsp!=null)
337 {
338 if (LOG.isDebugEnabled())
339 LOG.debug("JSP file {} for {} mapped to Servlet class {}",_forcedPath, getName(),jsp.getClassName());
340 setClassName(jsp.getClassName());
341
342 for (Map.Entry<String, String> entry:jsp.getInitParameters().entrySet())
343 {
344 if (!_initParams.containsKey(entry.getKey()))
345 setInitParameter(entry.getKey(), entry.getValue());
346 }
347
348
349
350
351 setInitParameter("jspFile", _forcedPath);
352 }
353 }
354 }
355 }
356
357
358
359 try
360 {
361 super.doStart();
362 }
363 catch (UnavailableException ue)
364 {
365 makeUnavailable(ue);
366 if (_servletHandler.isStartWithUnavailable())
367 {
368 LOG.ignore(ue);
369 return;
370 }
371 else
372 throw ue;
373 }
374
375
376
377 try
378 {
379 checkServletType();
380 }
381 catch (UnavailableException ue)
382 {
383 makeUnavailable(ue);
384 if (_servletHandler.isStartWithUnavailable())
385 {
386 LOG.ignore(ue);
387 return;
388 }
389 else
390 throw ue;
391 }
392
393
394 checkInitOnStartup();
395
396 _identityService = _servletHandler.getIdentityService();
397 if (_identityService!=null && _runAsRole!=null)
398 _runAsToken=_identityService.newRunAsToken(_runAsRole);
399
400 _config=new Config();
401
402 if (_class!=null && javax.servlet.SingleThreadModel.class.isAssignableFrom(_class))
403 _servlet = new SingleThreadedWrapper();
404
405 }
406
407
408
409 @Override
410 public void initialize ()
411 throws Exception
412 {
413 if(!_initialized){
414 super.initialize();
415 if (_extInstance || _initOnStartup)
416 {
417 try
418 {
419 initServlet();
420 }
421 catch(Exception e)
422 {
423 if (_servletHandler.isStartWithUnavailable())
424 LOG.ignore(e);
425 else
426 throw e;
427 }
428 }
429 }
430 _initialized = true;
431 }
432
433
434
435 public void doStop()
436 throws Exception
437 {
438 Object old_run_as = null;
439 if (_servlet!=null)
440 {
441 try
442 {
443 if (_identityService!=null)
444 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
445
446 destroyInstance(_servlet);
447 }
448 catch (Exception e)
449 {
450 LOG.warn(e);
451 }
452 finally
453 {
454 if (_identityService!=null)
455 _identityService.unsetRunAs(old_run_as);
456 }
457 }
458
459 if (!_extInstance)
460 _servlet=null;
461
462 _config=null;
463 _initialized = false;
464 }
465
466
467 @Override
468 public void destroyInstance (Object o)
469 throws Exception
470 {
471 if (o==null)
472 return;
473 Servlet servlet = ((Servlet)o);
474 getServletHandler().destroyServlet(servlet);
475 servlet.destroy();
476 }
477
478
479
480
481
482
483 public synchronized Servlet getServlet()
484 throws ServletException
485 {
486
487 if (_unavailable!=0)
488 {
489 if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
490 throw _unavailableEx;
491 _unavailable=0;
492 _unavailableEx=null;
493 }
494
495 if (_servlet==null)
496 initServlet();
497 return _servlet;
498 }
499
500
501
502
503
504 public Servlet getServletInstance()
505 {
506 return _servlet;
507 }
508
509
510
511
512
513
514 public void checkServletType ()
515 throws UnavailableException
516 {
517 if (_class==null || !javax.servlet.Servlet.class.isAssignableFrom(_class))
518 {
519 throw new UnavailableException("Servlet "+_class+" is not a javax.servlet.Servlet");
520 }
521 }
522
523
524
525
526
527 public boolean isAvailable()
528 {
529 if (isStarted()&& _unavailable==0)
530 return true;
531 try
532 {
533 getServlet();
534 }
535 catch(Exception e)
536 {
537 LOG.ignore(e);
538 }
539
540 return isStarted()&& _unavailable==0;
541 }
542
543
544
545
546
547
548
549
550
551 private void checkInitOnStartup()
552 {
553 if (_class==null)
554 return;
555
556 if ((_class.getAnnotation(javax.servlet.annotation.ServletSecurity.class) != null) && !_initOnStartup)
557 setInitOrder(Integer.MAX_VALUE);
558 }
559
560
561 private void makeUnavailable(UnavailableException e)
562 {
563 if (_unavailableEx==e && _unavailable!=0)
564 return;
565
566 _servletHandler.getServletContext().log("unavailable",e);
567
568 _unavailableEx=e;
569 _unavailable=-1;
570 if (e.isPermanent())
571 _unavailable=-1;
572 else
573 {
574 if (_unavailableEx.getUnavailableSeconds()>0)
575 _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
576 else
577 _unavailable=System.currentTimeMillis()+5000;
578 }
579 }
580
581
582
583 private void makeUnavailable(final Throwable e)
584 {
585 if (e instanceof UnavailableException)
586 makeUnavailable((UnavailableException)e);
587 else
588 {
589 ServletContext ctx = _servletHandler.getServletContext();
590 if (ctx==null)
591 LOG.info("unavailable",e);
592 else
593 ctx.log("unavailable",e);
594 _unavailableEx=new UnavailableException(String.valueOf(e),-1)
595 {
596 {
597 initCause(e);
598 }
599 };
600 _unavailable=-1;
601 }
602 }
603
604
605 private void initServlet()
606 throws ServletException
607 {
608 Object old_run_as = null;
609 try
610 {
611 if (_servlet==null)
612 _servlet=newInstance();
613 if (_config==null)
614 _config=new Config();
615
616
617
618
619 if (_identityService!=null)
620 {
621 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
622 }
623
624
625 if (isJspServlet())
626 {
627 initJspServlet();
628 detectJspContainer();
629 }
630
631 initMultiPart();
632
633 if (_forcedPath != null && _jspContainer == null)
634 {
635 detectJspContainer();
636 }
637
638 if (LOG.isDebugEnabled())
639 LOG.debug("Servlet.init {} for {}",_servlet,getName());
640 _servlet.init(_config);
641 }
642 catch (UnavailableException e)
643 {
644 makeUnavailable(e);
645 _servlet=null;
646 _config=null;
647 throw e;
648 }
649 catch (ServletException e)
650 {
651 makeUnavailable(e.getCause()==null?e:e.getCause());
652 _servlet=null;
653 _config=null;
654 throw e;
655 }
656 catch (Exception e)
657 {
658 makeUnavailable(e);
659 _servlet=null;
660 _config=null;
661 throw new ServletException(this.toString(),e);
662 }
663 finally
664 {
665
666 if (_identityService!=null)
667 _identityService.unsetRunAs(old_run_as);
668 }
669 }
670
671
672
673
674
675
676 protected void initJspServlet () throws Exception
677 {
678 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
679
680
681 ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
682
683
684 if ("?".equals(getInitParameter("classpath")))
685 {
686 String classpath = ch.getClassPath();
687 if (LOG.isDebugEnabled())
688 LOG.debug("classpath=" + classpath);
689 if (classpath != null)
690 setInitParameter("classpath", classpath);
691 }
692
693
694 File scratch = null;
695 if (getInitParameter("scratchdir") == null)
696 {
697 File tmp = (File)getServletHandler().getServletContext().getAttribute(ServletContext.TEMPDIR);
698 scratch = new File(tmp, "jsp");
699 setInitParameter("scratchdir", scratch.getAbsolutePath());
700 }
701
702 scratch = new File (getInitParameter("scratchdir"));
703 if (!scratch.exists()) scratch.mkdir();
704 }
705
706
707
708
709
710
711
712
713 protected void initMultiPart () throws Exception
714 {
715
716
717 if (((Registration)getRegistration()).getMultipartConfig() != null)
718 {
719
720
721
722 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
723 ch.addEventListener(MultiPartCleanerListener.INSTANCE);
724 }
725 }
726
727
728
729
730
731 @Override
732 public String getContextPath()
733 {
734 return _config.getServletContext().getContextPath();
735 }
736
737
738
739
740
741 @Override
742 public Map<String, String> getRoleRefMap()
743 {
744 return _roleMap;
745 }
746
747
748 @ManagedAttribute(value="role to run servlet as", readonly=true)
749 public String getRunAsRole()
750 {
751 return _runAsRole;
752 }
753
754
755 public void setRunAsRole(String role)
756 {
757 _runAsRole = role;
758 }
759
760
761
762
763
764
765
766
767
768
769
770 protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
771 throws ServletException, UnavailableException
772 {
773 ensureInstance();
774 MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
775 if (mpce != null)
776 baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
777 }
778
779 public synchronized Servlet ensureInstance()
780 throws ServletException, UnavailableException
781 {
782 if (_class==null)
783 throw new UnavailableException("Servlet Not Initialized");
784 Servlet servlet=_servlet;
785 if (!isStarted())
786 throw new UnavailableException("Servlet not initialized", -1);
787 if (_unavailable!=0 || (!_initOnStartup && servlet==null))
788 servlet=getServlet();
789 if (servlet==null)
790 throw new UnavailableException("Could not instantiate "+_class);
791
792 return servlet;
793 }
794
795
796
797
798
799
800
801
802
803
804
805
806 public void handle(Request baseRequest,
807 ServletRequest request,
808 ServletResponse response)
809 throws ServletException,
810 UnavailableException,
811 IOException
812 {
813 if (_class==null)
814 throw new UnavailableException("Servlet Not Initialized");
815
816 Servlet servlet = ensureInstance();
817
818
819 boolean servlet_error=true;
820 Object old_run_as = null;
821 boolean suspendable = baseRequest.isAsyncSupported();
822 try
823 {
824
825 if (_forcedPath!=null)
826 adaptForcedPathToJspContainer(request);
827
828
829 if (_identityService!=null)
830 old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken);
831
832 if (!isAsyncSupported())
833 baseRequest.setAsyncSupported(false);
834
835 servlet.service(request,response);
836 servlet_error=false;
837 }
838 catch(UnavailableException e)
839 {
840 makeUnavailable(e);
841 throw _unavailableEx;
842 }
843 finally
844 {
845 baseRequest.setAsyncSupported(suspendable);
846
847
848 if (_identityService!=null)
849 _identityService.unsetRunAs(old_run_as);
850
851
852 if (servlet_error)
853 request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME,getName());
854 }
855 }
856
857
858
859 private boolean isJspServlet ()
860 {
861 if (_servlet == null)
862 return false;
863
864 Class<?> c = _servlet.getClass();
865
866 boolean result = false;
867 while (c != null && !result)
868 {
869 result = isJspServlet(c.getName());
870 c = c.getSuperclass();
871 }
872
873 return result;
874 }
875
876
877
878 private boolean isJspServlet (String classname)
879 {
880 if (classname == null)
881 return false;
882 return ("org.apache.jasper.servlet.JspServlet".equals(classname));
883 }
884
885
886 private void adaptForcedPathToJspContainer (ServletRequest request)
887 {
888
889 }
890
891
892 private void detectJspContainer ()
893 {
894 if (_jspContainer == null)
895 {
896 try
897 {
898
899 Loader.loadClass(Holder.class, APACHE_SENTINEL_CLASS);
900 if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected");
901 _jspContainer = JspContainer.APACHE;
902 }
903 catch (ClassNotFoundException x)
904 {
905 if (LOG.isDebugEnabled())LOG.debug("Other jasper detected");
906 _jspContainer = JspContainer.OTHER;
907 }
908 }
909 }
910
911
912 private String getNameOfJspClass (String jsp)
913 {
914 if (jsp == null)
915 return "";
916
917 int i = jsp.lastIndexOf('/') + 1;
918 jsp = jsp.substring(i);
919 try
920 {
921 Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
922 Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class);
923 return (String)makeJavaIdentifier.invoke(null, jsp);
924 }
925 catch (Exception e)
926 {
927 String tmp = jsp.replace('.','_');
928 LOG.warn("Unable to make identifier for jsp "+jsp +" trying "+tmp+" instead");
929 if (LOG.isDebugEnabled())
930 LOG.warn(e);
931 return tmp;
932 }
933 }
934
935
936
937 private String getPackageOfJspClass (String jsp)
938 {
939 if (jsp == null)
940 return "";
941
942 int i = jsp.lastIndexOf('/');
943 if (i <= 0)
944 return "";
945 try
946 {
947 Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
948 Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class);
949 return (String)makeJavaPackage.invoke(null, jsp.substring(0,i));
950 }
951 catch (Exception e)
952 {
953 String tmp = jsp.substring(1).replace('/','.');
954 LOG.warn("Unable to make package for jsp "+jsp +" trying "+tmp+" instead");
955 if (LOG.isDebugEnabled())
956 LOG.warn(e);
957 return tmp;
958 }
959 }
960
961
962
963 private String getJspPackagePrefix ()
964 {
965 String jspPackageName = (String)getServletHandler().getServletContext().getInitParameter(JSP_GENERATED_PACKAGE_NAME );
966 if (jspPackageName == null)
967 jspPackageName = "org.apache.jsp";
968
969 return jspPackageName;
970 }
971
972
973
974 private String getClassNameForJsp (String jsp)
975 {
976 if (jsp == null)
977 return null;
978
979 return getJspPackagePrefix() + "." +getPackageOfJspClass(jsp) + "." + getNameOfJspClass(jsp);
980 }
981
982
983
984
985
986 protected class Config extends HolderConfig implements ServletConfig
987 {
988
989 @Override
990 public String getServletName()
991 {
992 return getName();
993 }
994
995 }
996
997
998
999
1000 public class Registration extends HolderRegistration implements ServletRegistration.Dynamic
1001 {
1002 protected MultipartConfigElement _multipartConfig;
1003
1004 @Override
1005 public Set<String> addMapping(String... urlPatterns)
1006 {
1007 illegalStateIfContextStarted();
1008 Set<String> clash=null;
1009 for (String pattern : urlPatterns)
1010 {
1011 ServletMapping mapping = _servletHandler.getServletMapping(pattern);
1012 if (mapping!=null)
1013 {
1014
1015 if (!mapping.isDefault())
1016 {
1017 if (clash==null)
1018 clash=new HashSet<String>();
1019 clash.add(pattern);
1020 }
1021 }
1022 }
1023
1024
1025 if (clash!=null)
1026 return clash;
1027
1028
1029 ServletMapping mapping = new ServletMapping();
1030 mapping.setServletName(ServletHolder.this.getName());
1031 mapping.setPathSpecs(urlPatterns);
1032 _servletHandler.addServletMapping(mapping);
1033
1034 return Collections.emptySet();
1035 }
1036
1037 @Override
1038 public Collection<String> getMappings()
1039 {
1040 ServletMapping[] mappings =_servletHandler.getServletMappings();
1041 List<String> patterns=new ArrayList<String>();
1042 if (mappings!=null)
1043 {
1044 for (ServletMapping mapping : mappings)
1045 {
1046 if (!mapping.getServletName().equals(getName()))
1047 continue;
1048 String[] specs=mapping.getPathSpecs();
1049 if (specs!=null && specs.length>0)
1050 patterns.addAll(Arrays.asList(specs));
1051 }
1052 }
1053 return patterns;
1054 }
1055
1056 @Override
1057 public String getRunAsRole()
1058 {
1059 return _runAsRole;
1060 }
1061
1062 @Override
1063 public void setLoadOnStartup(int loadOnStartup)
1064 {
1065 illegalStateIfContextStarted();
1066 ServletHolder.this.setInitOrder(loadOnStartup);
1067 }
1068
1069 public int getInitOrder()
1070 {
1071 return ServletHolder.this.getInitOrder();
1072 }
1073
1074 @Override
1075 public void setMultipartConfig(MultipartConfigElement element)
1076 {
1077 _multipartConfig = element;
1078 }
1079
1080 public MultipartConfigElement getMultipartConfig()
1081 {
1082 return _multipartConfig;
1083 }
1084
1085 @Override
1086 public void setRunAsRole(String role)
1087 {
1088 _runAsRole = role;
1089 }
1090
1091 @Override
1092 public Set<String> setServletSecurity(ServletSecurityElement securityElement)
1093 {
1094 return _servletHandler.setServletSecurity(this, securityElement);
1095 }
1096 }
1097
1098 public ServletRegistration.Dynamic getRegistration()
1099 {
1100 if (_registration == null)
1101 _registration = new Registration();
1102 return _registration;
1103 }
1104
1105
1106
1107
1108 private class SingleThreadedWrapper implements Servlet
1109 {
1110 Stack<Servlet> _stack=new Stack<Servlet>();
1111
1112 @Override
1113 public void destroy()
1114 {
1115 synchronized(this)
1116 {
1117 while(_stack.size()>0)
1118 try { (_stack.pop()).destroy(); } catch (Exception e) { LOG.warn(e); }
1119 }
1120 }
1121
1122 @Override
1123 public ServletConfig getServletConfig()
1124 {
1125 return _config;
1126 }
1127
1128 @Override
1129 public String getServletInfo()
1130 {
1131 return null;
1132 }
1133
1134 @Override
1135 public void init(ServletConfig config) throws ServletException
1136 {
1137 synchronized(this)
1138 {
1139 if(_stack.size()==0)
1140 {
1141 try
1142 {
1143 Servlet s = newInstance();
1144 s.init(config);
1145 _stack.push(s);
1146 }
1147 catch (ServletException e)
1148 {
1149 throw e;
1150 }
1151 catch (Exception e)
1152 {
1153 throw new ServletException(e);
1154 }
1155 }
1156 }
1157 }
1158
1159 @Override
1160 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
1161 {
1162 Servlet s;
1163 synchronized(this)
1164 {
1165 if(_stack.size()>0)
1166 s=(Servlet)_stack.pop();
1167 else
1168 {
1169 try
1170 {
1171 s = newInstance();
1172 s.init(_config);
1173 }
1174 catch (ServletException e)
1175 {
1176 throw e;
1177 }
1178 catch (Exception e)
1179 {
1180 throw new ServletException(e);
1181 }
1182 }
1183 }
1184
1185 try
1186 {
1187 s.service(req,res);
1188 }
1189 finally
1190 {
1191 synchronized(this)
1192 {
1193 _stack.push(s);
1194 }
1195 }
1196 }
1197 }
1198
1199
1200
1201
1202
1203
1204
1205
1206 protected Servlet newInstance() throws ServletException, IllegalAccessException, InstantiationException
1207 {
1208 try
1209 {
1210 ServletContext ctx = getServletHandler().getServletContext();
1211 if (ctx instanceof ServletContextHandler.Context)
1212 return ((ServletContextHandler.Context)ctx).createServlet(getHeldClass());
1213 return getHeldClass().newInstance();
1214 }
1215 catch (ServletException se)
1216 {
1217 Throwable cause = se.getRootCause();
1218 if (cause instanceof InstantiationException)
1219 throw (InstantiationException)cause;
1220 if (cause instanceof IllegalAccessException)
1221 throw (IllegalAccessException)cause;
1222 throw se;
1223 }
1224 }
1225
1226
1227
1228 @Override
1229 public String toString()
1230 {
1231 return String.format("%s@%x==%s,%d,%b",_name,hashCode(),_className,_initOrder,_servlet!=null);
1232 }
1233 }