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
74
75 private static final Logger LOG = Log.getLogger(ServletHolder.class);
76 private int _initOrder = -1;
77 private boolean _initOnStartup=false;
78 private boolean _initialized = false;
79 private Map<String, String> _roleMap;
80 private String _forcedPath;
81 private String _runAsRole;
82 private RunAsToken _runAsToken;
83 private IdentityService _identityService;
84 private ServletRegistration.Dynamic _registration;
85 private JspContainer _jspContainer;
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 && jsp.getClassName() != 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 if(!_initialized){
391 super.initialize();
392 if (_extInstance || _initOnStartup)
393 {
394 try
395 {
396 initServlet();
397 }
398 catch(Exception e)
399 {
400 if (_servletHandler.isStartWithUnavailable())
401 LOG.ignore(e);
402 else
403 throw e;
404 }
405 }
406 }
407 _initialized = true;
408 }
409
410
411
412 public void doStop()
413 throws Exception
414 {
415 Object old_run_as = null;
416 if (_servlet!=null)
417 {
418 try
419 {
420 if (_identityService!=null)
421 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
422
423 destroyInstance(_servlet);
424 }
425 catch (Exception e)
426 {
427 LOG.warn(e);
428 }
429 finally
430 {
431 if (_identityService!=null)
432 _identityService.unsetRunAs(old_run_as);
433 }
434 }
435
436 if (!_extInstance)
437 _servlet=null;
438
439 _config=null;
440 _initialized = false;
441 }
442
443
444 @Override
445 public void destroyInstance (Object o)
446 throws Exception
447 {
448 if (o==null)
449 return;
450 Servlet servlet = ((Servlet)o);
451 getServletHandler().destroyServlet(servlet);
452 servlet.destroy();
453 }
454
455
456
457
458
459 public synchronized Servlet getServlet()
460 throws ServletException
461 {
462
463 if (_unavailable!=0)
464 {
465 if (_unavailable<0 || _unavailable>0 && System.currentTimeMillis()<_unavailable)
466 throw _unavailableEx;
467 _unavailable=0;
468 _unavailableEx=null;
469 }
470
471 if (_servlet==null)
472 initServlet();
473 return _servlet;
474 }
475
476
477
478
479
480 public Servlet getServletInstance()
481 {
482 return _servlet;
483 }
484
485
486
487
488
489
490 public void checkServletType ()
491 throws UnavailableException
492 {
493 if (_class==null || !javax.servlet.Servlet.class.isAssignableFrom(_class))
494 {
495 throw new UnavailableException("Servlet "+_class+" is not a javax.servlet.Servlet");
496 }
497 }
498
499
500
501
502
503 public boolean isAvailable()
504 {
505 if (isStarted()&& _unavailable==0)
506 return true;
507 try
508 {
509 getServlet();
510 }
511 catch(Exception e)
512 {
513 LOG.ignore(e);
514 }
515
516 return isStarted()&& _unavailable==0;
517 }
518
519
520
521
522
523
524
525
526
527 private void checkInitOnStartup()
528 {
529 if (_class==null)
530 return;
531
532 if ((_class.getAnnotation(javax.servlet.annotation.ServletSecurity.class) != null) && !_initOnStartup)
533 setInitOrder(Integer.MAX_VALUE);
534 }
535
536
537 private void makeUnavailable(UnavailableException e)
538 {
539 if (_unavailableEx==e && _unavailable!=0)
540 return;
541
542 _servletHandler.getServletContext().log("unavailable",e);
543
544 _unavailableEx=e;
545 _unavailable=-1;
546 if (e.isPermanent())
547 _unavailable=-1;
548 else
549 {
550 if (_unavailableEx.getUnavailableSeconds()>0)
551 _unavailable=System.currentTimeMillis()+1000*_unavailableEx.getUnavailableSeconds();
552 else
553 _unavailable=System.currentTimeMillis()+5000;
554 }
555 }
556
557
558
559 private void makeUnavailable(final Throwable e)
560 {
561 if (e instanceof UnavailableException)
562 makeUnavailable((UnavailableException)e);
563 else
564 {
565 ServletContext ctx = _servletHandler.getServletContext();
566 if (ctx==null)
567 LOG.info("unavailable",e);
568 else
569 ctx.log("unavailable",e);
570 _unavailableEx=new UnavailableException(String.valueOf(e),-1)
571 {
572 {
573 initCause(e);
574 }
575 };
576 _unavailable=-1;
577 }
578 }
579
580
581 private void initServlet()
582 throws ServletException
583 {
584 Object old_run_as = null;
585 try
586 {
587 if (_servlet==null)
588 _servlet=newInstance();
589 if (_config==null)
590 _config=new Config();
591
592
593
594
595 if (_identityService!=null)
596 {
597 old_run_as=_identityService.setRunAs(_identityService.getSystemUserIdentity(),_runAsToken);
598 }
599
600
601 if (isJspServlet())
602 {
603 initJspServlet();
604 detectJspContainer();
605 }
606
607 initMultiPart();
608
609 if (_forcedPath != null && _jspContainer == null)
610 {
611 detectJspContainer();
612 }
613
614 if (LOG.isDebugEnabled())
615 LOG.debug("Servlet.init {} for {}",_servlet,getName());
616 _servlet.init(_config);
617 }
618 catch (UnavailableException e)
619 {
620 makeUnavailable(e);
621 _servlet=null;
622 _config=null;
623 throw e;
624 }
625 catch (ServletException e)
626 {
627 makeUnavailable(e.getCause()==null?e:e.getCause());
628 _servlet=null;
629 _config=null;
630 throw e;
631 }
632 catch (Exception e)
633 {
634 makeUnavailable(e);
635 _servlet=null;
636 _config=null;
637 throw new ServletException(this.toString(),e);
638 }
639 finally
640 {
641
642 if (_identityService!=null)
643 _identityService.unsetRunAs(old_run_as);
644 }
645 }
646
647
648
649
650
651
652 protected void initJspServlet () throws Exception
653 {
654 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
655
656
657 ch.setAttribute("org.apache.catalina.jsp_classpath", ch.getClassPath());
658
659
660 setInitParameter("com.sun.appserv.jsp.classpath", Loader.getClassPath(ch.getClassLoader().getParent()));
661
662
663 if ("?".equals(getInitParameter("classpath")))
664 {
665 String classpath = ch.getClassPath();
666 if (LOG.isDebugEnabled())
667 LOG.debug("classpath=" + classpath);
668 if (classpath != null)
669 setInitParameter("classpath", classpath);
670 }
671
672
673 File scratch = null;
674 if (getInitParameter("scratchdir") == null)
675 {
676 File tmp = (File)getServletHandler().getServletContext().getAttribute(ServletContext.TEMPDIR);
677 scratch = new File(tmp, "jsp");
678 setInitParameter("scratchdir", scratch.getAbsolutePath());
679 }
680
681 scratch = new File (getInitParameter("scratchdir"));
682 if (!scratch.exists()) scratch.mkdir();
683 }
684
685
686
687
688
689
690
691
692 protected void initMultiPart () throws Exception
693 {
694
695
696 if (((Registration)getRegistration()).getMultipartConfig() != null)
697 {
698
699
700
701 ContextHandler ch = ContextHandler.getContextHandler(getServletHandler().getServletContext());
702 ch.addEventListener(new Request.MultiPartCleanerListener());
703 }
704 }
705
706
707
708
709
710 @Override
711 public String getContextPath()
712 {
713 return _config.getServletContext().getContextPath();
714 }
715
716
717
718
719
720 @Override
721 public Map<String, String> getRoleRefMap()
722 {
723 return _roleMap;
724 }
725
726
727 @ManagedAttribute(value="role to run servlet as", readonly=true)
728 public String getRunAsRole()
729 {
730 return _runAsRole;
731 }
732
733
734 public void setRunAsRole(String role)
735 {
736 _runAsRole = role;
737 }
738
739
740
741
742
743
744
745
746
747
748
749 protected void prepare (Request baseRequest, ServletRequest request, ServletResponse response)
750 throws ServletException, UnavailableException
751 {
752 ensureInstance();
753 MultipartConfigElement mpce = ((Registration)getRegistration()).getMultipartConfig();
754 if (mpce != null)
755 baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, mpce);
756 }
757
758 public synchronized Servlet ensureInstance()
759 throws ServletException, UnavailableException
760 {
761 if (_class==null)
762 throw new UnavailableException("Servlet Not Initialized");
763 Servlet servlet=_servlet;
764 if (!isStarted())
765 throw new UnavailableException("Servlet not initialized", -1);
766 if (_unavailable!=0 || (!_initOnStartup && servlet==null))
767 servlet=getServlet();
768 if (servlet==null)
769 throw new UnavailableException("Could not instantiate "+_class);
770
771 return servlet;
772 }
773
774
775
776
777
778
779
780
781
782
783 public void handle(Request baseRequest,
784 ServletRequest request,
785 ServletResponse response)
786 throws ServletException,
787 UnavailableException,
788 IOException
789 {
790 if (_class==null)
791 throw new UnavailableException("Servlet Not Initialized");
792
793 Servlet servlet = ensureInstance();
794
795
796 boolean servlet_error=true;
797 Object old_run_as = null;
798 boolean suspendable = baseRequest.isAsyncSupported();
799 try
800 {
801
802 if (_forcedPath!=null)
803 adaptForcedPathToJspContainer(request);
804
805
806 if (_identityService!=null)
807 old_run_as=_identityService.setRunAs(baseRequest.getResolvedUserIdentity(),_runAsToken);
808
809 if (!isAsyncSupported())
810 baseRequest.setAsyncSupported(false);
811
812 servlet.service(request,response);
813 servlet_error=false;
814 }
815 catch(UnavailableException e)
816 {
817 makeUnavailable(e);
818 throw _unavailableEx;
819 }
820 finally
821 {
822 baseRequest.setAsyncSupported(suspendable);
823
824
825 if (_identityService!=null)
826 _identityService.unsetRunAs(old_run_as);
827
828
829 if (servlet_error)
830 request.setAttribute("javax.servlet.error.servlet_name",getName());
831 }
832 }
833
834
835
836 private boolean isJspServlet ()
837 {
838 if (_servlet == null)
839 return false;
840
841 Class<?> c = _servlet.getClass();
842
843 boolean result = false;
844 while (c != null && !result)
845 {
846 result = isJspServlet(c.getName());
847 c = c.getSuperclass();
848 }
849
850 return result;
851 }
852
853
854
855 private boolean isJspServlet (String classname)
856 {
857 if (classname == null)
858 return false;
859 return ("org.apache.jasper.servlet.JspServlet".equals(classname));
860 }
861
862
863 private void adaptForcedPathToJspContainer (ServletRequest request)
864 {
865 if (_forcedPath != null && _jspContainer != null && JspContainer.GLASSFISH.equals(_jspContainer))
866 {
867
868
869
870 request.setAttribute("org.apache.catalina.jsp_file",_forcedPath);
871 }
872 }
873
874
875 private void detectJspContainer ()
876 {
877 if (_jspContainer == null)
878 {
879
880 try
881 {
882
883
884 Loader.loadClass(Holder.class, GLASSFISH_SENTINEL_CLASS);
885 if (LOG.isDebugEnabled())LOG.debug("Glassfish jasper detected");
886 _jspContainer = JspContainer.GLASSFISH;
887 }
888 catch (ClassNotFoundException e)
889 {
890 try
891 {
892
893 Loader.loadClass(Holder.class, APACHE_SENTINEL_CLASS);
894 if (LOG.isDebugEnabled())LOG.debug("Apache jasper detected");
895 _jspContainer = JspContainer.APACHE;
896 }
897 catch (ClassNotFoundException x)
898 {
899 if (LOG.isDebugEnabled())LOG.debug("Other jasper detected");
900 _jspContainer = JspContainer.OTHER;
901 }
902 }
903 }
904 }
905
906
907 private String getNameOfJspClass (String jsp)
908 {
909 if (jsp == null)
910 return "";
911
912 int i = jsp.lastIndexOf('/') + 1;
913 jsp = jsp.substring(i);
914 try
915 {
916 Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
917 Method makeJavaIdentifier = jspUtil.getMethod("makeJavaIdentifier", String.class);
918 return (String)makeJavaIdentifier.invoke(null, jsp);
919 }
920 catch (Exception e)
921 {
922 String tmp = jsp.replace('.','_');
923 LOG.warn("Unable to make identifier for jsp "+jsp +" trying "+tmp+" instead");
924 if (LOG.isDebugEnabled())
925 LOG.warn(e);
926 return tmp;
927 }
928 }
929
930
931
932 private String getPackageOfJspClass (String jsp)
933 {
934 if (jsp == null)
935 return "";
936
937 int i = jsp.lastIndexOf('/');
938 if (i <= 0)
939 return "";
940 try
941 {
942 Class<?> jspUtil = Loader.loadClass(Holder.class, "org.apache.jasper.compiler.JspUtil");
943 Method makeJavaPackage = jspUtil.getMethod("makeJavaPackage", String.class);
944 return (String)makeJavaPackage.invoke(null, jsp.substring(0,i));
945 }
946 catch (Exception e)
947 {
948 String tmp = jsp.substring(1).replace('/','.');
949 LOG.warn("Unable to make package for jsp "+jsp +" trying "+tmp+" instead");
950 if (LOG.isDebugEnabled())
951 LOG.warn(e);
952 return tmp;
953 }
954 }
955
956
957
958 private String getJspPackagePrefix ()
959 {
960 String jspPackageName = (String)getServletHandler().getServletContext().getInitParameter(JSP_GENERATED_PACKAGE_NAME );
961 if (jspPackageName == null)
962 jspPackageName = "org.apache.jsp";
963
964 return jspPackageName;
965 }
966
967
968
969 private String getClassNameForJsp (String jsp)
970 {
971 if (jsp == null)
972 return null;
973
974 return getJspPackagePrefix() + "." +getPackageOfJspClass(jsp) + "." + getNameOfJspClass(jsp);
975 }
976
977
978
979
980
981 protected class Config extends HolderConfig implements ServletConfig
982 {
983
984 @Override
985 public String getServletName()
986 {
987 return getName();
988 }
989
990 }
991
992
993
994
995 public class Registration extends HolderRegistration implements ServletRegistration.Dynamic
996 {
997 protected MultipartConfigElement _multipartConfig;
998
999 @Override
1000 public Set<String> addMapping(String... urlPatterns)
1001 {
1002 illegalStateIfContextStarted();
1003 Set<String> clash=null;
1004 for (String pattern : urlPatterns)
1005 {
1006 ServletMapping mapping = _servletHandler.getServletMapping(pattern);
1007 if (mapping!=null)
1008 {
1009
1010 if (!mapping.isDefault())
1011 {
1012 if (clash==null)
1013 clash=new HashSet<String>();
1014 clash.add(pattern);
1015 }
1016 }
1017 }
1018
1019
1020 if (clash!=null)
1021 return clash;
1022
1023
1024 ServletMapping mapping = new ServletMapping();
1025 mapping.setServletName(ServletHolder.this.getName());
1026 mapping.setPathSpecs(urlPatterns);
1027 _servletHandler.addServletMapping(mapping);
1028
1029 return Collections.emptySet();
1030 }
1031
1032 @Override
1033 public Collection<String> getMappings()
1034 {
1035 ServletMapping[] mappings =_servletHandler.getServletMappings();
1036 List<String> patterns=new ArrayList<String>();
1037 if (mappings!=null)
1038 {
1039 for (ServletMapping mapping : mappings)
1040 {
1041 if (!mapping.getServletName().equals(getName()))
1042 continue;
1043 String[] specs=mapping.getPathSpecs();
1044 if (specs!=null && specs.length>0)
1045 patterns.addAll(Arrays.asList(specs));
1046 }
1047 }
1048 return patterns;
1049 }
1050
1051 @Override
1052 public String getRunAsRole()
1053 {
1054 return _runAsRole;
1055 }
1056
1057 @Override
1058 public void setLoadOnStartup(int loadOnStartup)
1059 {
1060 illegalStateIfContextStarted();
1061 ServletHolder.this.setInitOrder(loadOnStartup);
1062 }
1063
1064 public int getInitOrder()
1065 {
1066 return ServletHolder.this.getInitOrder();
1067 }
1068
1069 @Override
1070 public void setMultipartConfig(MultipartConfigElement element)
1071 {
1072 _multipartConfig = element;
1073 }
1074
1075 public MultipartConfigElement getMultipartConfig()
1076 {
1077 return _multipartConfig;
1078 }
1079
1080 @Override
1081 public void setRunAsRole(String role)
1082 {
1083 _runAsRole = role;
1084 }
1085
1086 @Override
1087 public Set<String> setServletSecurity(ServletSecurityElement securityElement)
1088 {
1089 return _servletHandler.setServletSecurity(this, securityElement);
1090 }
1091 }
1092
1093 public ServletRegistration.Dynamic getRegistration()
1094 {
1095 if (_registration == null)
1096 _registration = new Registration();
1097 return _registration;
1098 }
1099
1100
1101
1102
1103 private class SingleThreadedWrapper implements Servlet
1104 {
1105 Stack<Servlet> _stack=new Stack<Servlet>();
1106
1107 @Override
1108 public void destroy()
1109 {
1110 synchronized(this)
1111 {
1112 while(_stack.size()>0)
1113 try { (_stack.pop()).destroy(); } catch (Exception e) { LOG.warn(e); }
1114 }
1115 }
1116
1117 @Override
1118 public ServletConfig getServletConfig()
1119 {
1120 return _config;
1121 }
1122
1123 @Override
1124 public String getServletInfo()
1125 {
1126 return null;
1127 }
1128
1129 @Override
1130 public void init(ServletConfig config) throws ServletException
1131 {
1132 synchronized(this)
1133 {
1134 if(_stack.size()==0)
1135 {
1136 try
1137 {
1138 Servlet s = newInstance();
1139 s.init(config);
1140 _stack.push(s);
1141 }
1142 catch (ServletException e)
1143 {
1144 throw e;
1145 }
1146 catch (Exception e)
1147 {
1148 throw new ServletException(e);
1149 }
1150 }
1151 }
1152 }
1153
1154 @Override
1155 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
1156 {
1157 Servlet s;
1158 synchronized(this)
1159 {
1160 if(_stack.size()>0)
1161 s=(Servlet)_stack.pop();
1162 else
1163 {
1164 try
1165 {
1166 s = newInstance();
1167 s.init(_config);
1168 }
1169 catch (ServletException e)
1170 {
1171 throw e;
1172 }
1173 catch (Exception e)
1174 {
1175 throw new ServletException(e);
1176 }
1177 }
1178 }
1179
1180 try
1181 {
1182 s.service(req,res);
1183 }
1184 finally
1185 {
1186 synchronized(this)
1187 {
1188 _stack.push(s);
1189 }
1190 }
1191 }
1192 }
1193
1194
1195
1196
1197
1198
1199
1200
1201 protected Servlet newInstance() throws ServletException, IllegalAccessException, InstantiationException
1202 {
1203 try
1204 {
1205 ServletContext ctx = getServletHandler().getServletContext();
1206 if (ctx instanceof ServletContextHandler.Context)
1207 return ((ServletContextHandler.Context)ctx).createServlet(getHeldClass());
1208 return getHeldClass().newInstance();
1209 }
1210 catch (ServletException se)
1211 {
1212 Throwable cause = se.getRootCause();
1213 if (cause instanceof InstantiationException)
1214 throw (InstantiationException)cause;
1215 if (cause instanceof IllegalAccessException)
1216 throw (IllegalAccessException)cause;
1217 throw se;
1218 }
1219 }
1220
1221
1222
1223 @Override
1224 public String toString()
1225 {
1226 return String.format("%s@%x==%s,%d,%b",_name,hashCode(),_className,_initOrder,_servlet!=null);
1227 }
1228 }