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