1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.webapp;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.net.MalformedURLException;
24 import java.net.URL;
25 import java.security.PermissionCollection;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.EventListener;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36
37 import javax.servlet.ServletContext;
38 import javax.servlet.ServletRegistration.Dynamic;
39 import javax.servlet.ServletSecurityElement;
40 import javax.servlet.http.HttpSessionActivationListener;
41 import javax.servlet.http.HttpSessionAttributeListener;
42 import javax.servlet.http.HttpSessionBindingListener;
43 import javax.servlet.http.HttpSessionIdListener;
44 import javax.servlet.http.HttpSessionListener;
45
46 import org.eclipse.jetty.security.ConstraintAware;
47 import org.eclipse.jetty.security.ConstraintMapping;
48 import org.eclipse.jetty.security.ConstraintSecurityHandler;
49 import org.eclipse.jetty.security.SecurityHandler;
50 import org.eclipse.jetty.server.Connector;
51 import org.eclipse.jetty.server.HandlerContainer;
52 import org.eclipse.jetty.server.Server;
53 import org.eclipse.jetty.server.handler.ContextHandler;
54 import org.eclipse.jetty.server.handler.ErrorHandler;
55 import org.eclipse.jetty.server.session.SessionHandler;
56 import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
57 import org.eclipse.jetty.servlet.ServletContextHandler;
58 import org.eclipse.jetty.servlet.ServletHandler;
59 import org.eclipse.jetty.util.Loader;
60 import org.eclipse.jetty.util.MultiException;
61 import org.eclipse.jetty.util.URIUtil;
62 import org.eclipse.jetty.util.annotation.ManagedAttribute;
63 import org.eclipse.jetty.util.annotation.ManagedObject;
64 import org.eclipse.jetty.util.log.Log;
65 import org.eclipse.jetty.util.log.Logger;
66 import org.eclipse.jetty.util.resource.Resource;
67 import org.eclipse.jetty.util.resource.ResourceCollection;
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 @ManagedObject("Web Application ContextHandler")
83 public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
84 {
85 private static final Logger LOG = Log.getLogger(WebAppContext.class);
86
87 public static final String TEMPDIR = "javax.servlet.context.tempdir";
88 public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
89 public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml";
90 public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
91 public final static String SERVER_SYS_CLASSES = "org.eclipse.jetty.webapp.systemClasses";
92 public final static String SERVER_SRV_CLASSES = "org.eclipse.jetty.webapp.serverClasses";
93
94 private String[] __dftProtectedTargets = {"/web-inf", "/meta-inf"};
95
96 public static final String[] DEFAULT_CONFIGURATION_CLASSES =
97 {
98 "org.eclipse.jetty.webapp.WebInfConfiguration",
99 "org.eclipse.jetty.webapp.WebXmlConfiguration",
100 "org.eclipse.jetty.webapp.MetaInfConfiguration",
101 "org.eclipse.jetty.webapp.FragmentConfiguration",
102 "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"
103 } ;
104
105
106
107
108 public final static String[] __dftSystemClasses =
109 {
110 "java.",
111 "javax.",
112 "org.xml.",
113 "org.w3c.",
114 "org.eclipse.jetty.continuation.",
115 "org.eclipse.jetty.jndi.",
116 "org.eclipse.jetty.jaas.",
117 "org.eclipse.jetty.websocket.",
118 "org.eclipse.jetty.util.log.",
119 "org.eclipse.jetty.servlet.ServletContextHandler.Decorator",
120 "org.eclipse.jetty.servlet.DefaultServlet",
121 "org.eclipse.jetty.servlets.AsyncGzipFilter"
122 } ;
123
124
125
126
127
128 public final static String[] __dftServerClasses =
129 {
130 "-org.eclipse.jetty.continuation.",
131 "-org.eclipse.jetty.jndi.",
132 "-org.eclipse.jetty.jaas.",
133 "-org.eclipse.jetty.servlets.",
134 "-org.eclipse.jetty.servlet.DefaultServlet",
135 "-org.eclipse.jetty.servlet.listener.",
136 "-org.eclipse.jetty.websocket.",
137 "-org.eclipse.jetty.apache.",
138 "-org.eclipse.jetty.util.log.",
139 "-org.eclipse.jetty.servlet.ServletContextHandler.Decorator",
140 "org.objectweb.asm.",
141 "org.eclipse.jdt.",
142 "org.eclipse.jetty."
143 } ;
144
145 private final List<String> _configurationClasses = new ArrayList<>();
146 private ClasspathPattern _systemClasses = null;
147 private ClasspathPattern _serverClasses = null;
148
149 private final List<Configuration> _configurations = new ArrayList<>();
150 private String _defaultsDescriptor=WEB_DEFAULTS_XML;
151 private String _descriptor=null;
152 private final List<String> _overrideDescriptors = new ArrayList<>();
153 private boolean _distributable=false;
154 private boolean _extractWAR=true;
155 private boolean _copyDir=false;
156 private boolean _copyWebInf=false;
157 private boolean _logUrlOnStart =false;
158 private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
159 private PermissionCollection _permissions;
160
161 private String[] _contextWhiteList = null;
162
163 private File _tmpDir;
164 private boolean _persistTmpDir = false;
165
166 private String _war;
167 private String _extraClasspath;
168 private Throwable _unavailableException;
169
170 private Map<String, String> _resourceAliases;
171 private boolean _ownClassLoader=false;
172 private boolean _configurationDiscovered=true;
173 private boolean _allowDuplicateFragmentNames = false;
174 private boolean _throwUnavailableOnStartupException = false;
175
176
177
178 private MetaData _metadata=new MetaData();
179
180 public static WebAppContext getCurrentWebAppContext()
181 {
182 ContextHandler.Context context=ContextHandler.getCurrentContext();
183 if (context!=null)
184 {
185 ContextHandler handler = context.getContextHandler();
186 if (handler instanceof WebAppContext)
187 return (WebAppContext)handler;
188 }
189 return null;
190 }
191
192
193 public WebAppContext()
194 {
195 this(null,null,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
196 }
197
198
199
200
201
202
203 public WebAppContext(String webApp,String contextPath)
204 {
205 this(null,contextPath,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
206 setWar(webApp);
207 }
208
209
210
211
212
213
214
215 public WebAppContext(HandlerContainer parent, String webApp, String contextPath)
216 {
217 this(parent,contextPath,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
218 setWar(webApp);
219 }
220
221
222
223
224
225
226
227
228
229
230
231 public WebAppContext(SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
232 {
233 this(null, null, sessionHandler, securityHandler, servletHandler, errorHandler,0);
234 }
235
236
237
238
239
240
241
242
243
244
245 public WebAppContext(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler,int options)
246 {
247 super(parent, contextPath,sessionHandler, securityHandler, servletHandler, errorHandler,options);
248 _scontext = new Context();
249 setErrorHandler(errorHandler != null ? errorHandler : new ErrorPageErrorHandler());
250 setProtectedTargets(__dftProtectedTargets);
251 }
252
253
254
255
256
257 @Override
258 public void setDisplayName(String servletContextName)
259 {
260 super.setDisplayName(servletContextName);
261 ClassLoader cl = getClassLoader();
262 if (cl!=null && cl instanceof WebAppClassLoader && servletContextName!=null)
263 ((WebAppClassLoader)cl).setName(servletContextName);
264 }
265
266
267
268
269
270 public Throwable getUnavailableException()
271 {
272 return _unavailableException;
273 }
274
275
276
277
278
279
280
281
282
283
284 public void setResourceAlias(String alias, String uri)
285 {
286 if (_resourceAliases == null)
287 _resourceAliases= new HashMap<String, String>(5);
288 _resourceAliases.put(alias, uri);
289 }
290
291
292 public Map<String, String> getResourceAliases()
293 {
294 if (_resourceAliases == null)
295 return null;
296 return _resourceAliases;
297 }
298
299
300 public void setResourceAliases(Map<String, String> map)
301 {
302 _resourceAliases = map;
303 }
304
305
306 public String getResourceAlias(String path)
307 {
308 if (_resourceAliases == null)
309 return null;
310 String alias = _resourceAliases.get(path);
311
312 int slash=path.length();
313 while (alias==null)
314 {
315 slash=path.lastIndexOf("/",slash-1);
316 if (slash<0)
317 break;
318 String match=_resourceAliases.get(path.substring(0,slash+1));
319 if (match!=null)
320 alias=match+path.substring(slash+1);
321 }
322 return alias;
323 }
324
325
326 public String removeResourceAlias(String alias)
327 {
328 if (_resourceAliases == null)
329 return null;
330 return _resourceAliases.remove(alias);
331 }
332
333
334
335
336
337 @Override
338 public void setClassLoader(ClassLoader classLoader)
339 {
340 super.setClassLoader(classLoader);
341
342
343
344
345
346
347 if (classLoader!=null && classLoader instanceof WebAppClassLoader && getDisplayName()!=null)
348 ((WebAppClassLoader)classLoader).setName(getDisplayName());
349 }
350
351
352 @Override
353 public Resource getResource(String uriInContext) throws MalformedURLException
354 {
355 if (uriInContext==null || !uriInContext.startsWith(URIUtil.SLASH))
356 throw new MalformedURLException(uriInContext);
357
358 IOException ioe= null;
359 Resource resource= null;
360 int loop=0;
361 while (uriInContext!=null && loop++<100)
362 {
363 try
364 {
365 resource= super.getResource(uriInContext);
366 if (resource != null && resource.exists())
367 return resource;
368
369 uriInContext = getResourceAlias(uriInContext);
370 }
371 catch (IOException e)
372 {
373 LOG.ignore(e);
374 if (ioe==null)
375 ioe= e;
376 }
377 }
378
379 if (ioe != null && ioe instanceof MalformedURLException)
380 throw (MalformedURLException)ioe;
381
382 return resource;
383 }
384
385
386
387
388
389
390
391 public boolean isConfigurationDiscovered()
392 {
393 return _configurationDiscovered;
394 }
395
396
397
398
399
400
401
402
403
404
405
406 public void setConfigurationDiscovered(boolean discovered)
407 {
408 _configurationDiscovered = discovered;
409 }
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 public void preConfigure() throws Exception
427 {
428
429 loadConfigurations();
430
431
432 loadSystemClasses();
433
434
435 loadServerClasses();
436
437
438 _ownClassLoader=false;
439 if (getClassLoader()==null)
440 {
441 WebAppClassLoader classLoader = new WebAppClassLoader(this);
442 setClassLoader(classLoader);
443 _ownClassLoader=true;
444 }
445
446 if (LOG.isDebugEnabled())
447 {
448 ClassLoader loader = getClassLoader();
449 LOG.debug("Thread Context classloader {}",loader);
450 loader=loader.getParent();
451 while(loader!=null)
452 {
453 LOG.debug("Parent class loader: {} ",loader);
454 loader=loader.getParent();
455 }
456 }
457
458
459 for (Configuration configuration : _configurations)
460 {
461 LOG.debug("preConfigure {} with {}",this,configuration);
462 configuration.preConfigure(this);
463 }
464 }
465
466
467 public void configure() throws Exception
468 {
469
470 for (Configuration configuration : _configurations)
471 {
472 LOG.debug("configure {} with {}",this,configuration);
473 configuration.configure(this);
474 }
475 }
476
477
478 public void postConfigure() throws Exception
479 {
480
481 for (Configuration configuration : _configurations)
482 {
483 LOG.debug("postConfigure {} with {}",this,configuration);
484 configuration.postConfigure(this);
485 }
486 }
487
488
489
490
491
492 @Override
493 protected void doStart() throws Exception
494 {
495 try
496 {
497 _metadata.setAllowDuplicateFragmentNames(isAllowDuplicateFragmentNames());
498 preConfigure();
499 super.doStart();
500 postConfigure();
501
502 if (isLogUrlOnStart())
503 dumpUrl();
504 }
505 catch (Exception e)
506 {
507
508 LOG.warn("Failed startup of context "+this, e);
509 _unavailableException=e;
510 setAvailable(false);
511 if (isThrowUnavailableOnStartupException())
512 throw e;
513 }
514 }
515
516
517
518
519
520 @Override
521 protected void doStop() throws Exception
522 {
523 super.doStop();
524
525 try
526 {
527 for (int i=_configurations.size();i-->0;)
528 _configurations.get(i).deconfigure(this);
529
530 if (_metadata != null)
531 _metadata.clear();
532 _metadata=new MetaData();
533
534 }
535 finally
536 {
537 if (_ownClassLoader)
538 setClassLoader(null);
539
540 setAvailable(true);
541 _unavailableException=null;
542 }
543 }
544
545
546 @Override
547 public void destroy()
548 {
549
550 MultiException mx=new MultiException();
551 if (_configurations!=null)
552 {
553 for (int i=_configurations.size();i-->0;)
554 {
555 try
556 {
557 _configurations.get(i).destroy(this);
558 }
559 catch(Exception e)
560 {
561 mx.add(e);
562 }
563 }
564 }
565 _configurations.clear();
566 super.destroy();
567 mx.ifExceptionThrowRuntime();
568 }
569
570
571
572
573
574
575 private void dumpUrl()
576 {
577 Connector[] connectors = getServer().getConnectors();
578 for (int i=0;i<connectors.length;i++)
579 {
580 String displayName = getDisplayName();
581 if (displayName == null)
582 displayName = "WebApp@"+connectors.hashCode();
583
584 LOG.info(displayName + " at http://" + connectors[i].toString() + getContextPath());
585 }
586 }
587
588
589
590
591
592 @ManagedAttribute(value="configuration classes used to configure webapp", readonly=true)
593 public String[] getConfigurationClasses()
594 {
595 return _configurationClasses.toArray(new String[_configurationClasses.size()]);
596 }
597
598
599
600
601
602 public Configuration[] getConfigurations()
603 {
604 return _configurations.toArray(new Configuration[_configurations.size()]);
605 }
606
607
608
609
610
611
612 @ManagedAttribute(value="default web.xml deascriptor applied before standard web.xml", readonly=true)
613 public String getDefaultsDescriptor()
614 {
615 return _defaultsDescriptor;
616 }
617
618
619
620
621
622
623 public String getOverrideDescriptor()
624 {
625 if (_overrideDescriptors.size()!=1)
626 return null;
627 return _overrideDescriptors.get(0);
628 }
629
630
631
632
633
634
635 @ManagedAttribute(value="web.xml deascriptors applied after standard web.xml", readonly=true)
636 public List<String> getOverrideDescriptors()
637 {
638 return Collections.unmodifiableList(_overrideDescriptors);
639 }
640
641
642
643
644
645 @Override
646 public PermissionCollection getPermissions()
647 {
648 return _permissions;
649 }
650
651
652
653
654
655
656 @ManagedAttribute(value="classes and packages hidden by the context classloader", readonly=true)
657 public String[] getServerClasses()
658 {
659 if (_serverClasses == null)
660 loadServerClasses();
661
662 return _serverClasses.getPatterns();
663 }
664
665
666
667
668
669
670
671
672
673
674
675 public void addServerClass(String classOrPackage)
676 {
677 if (_serverClasses == null)
678 loadServerClasses();
679
680 _serverClasses.addPattern(classOrPackage);
681 }
682
683
684
685
686
687
688
689
690
691
692
693 public void prependServerClass(String classOrPackage)
694 {
695 if (_serverClasses == null)
696 loadServerClasses();
697
698 _serverClasses.prependPattern(classOrPackage);
699 }
700
701
702
703
704
705
706 @ManagedAttribute(value="classes and packages given priority by context classloader", readonly=true)
707 public String[] getSystemClasses()
708 {
709 if (_systemClasses == null)
710 loadSystemClasses();
711
712 return _systemClasses.getPatterns();
713 }
714
715
716
717
718
719
720
721
722
723
724
725 public void addSystemClass(String classOrPackage)
726 {
727 if (_systemClasses == null)
728 loadSystemClasses();
729
730 _systemClasses.addPattern(classOrPackage);
731 }
732
733
734
735
736
737
738
739
740
741
742
743
744 public void prependSystemClass(String classOrPackage)
745 {
746 if (_systemClasses == null)
747 loadSystemClasses();
748
749 _systemClasses.prependPattern(classOrPackage);
750 }
751
752
753 @Override
754 public boolean isServerClass(String name)
755 {
756 if (_serverClasses == null)
757 loadServerClasses();
758
759 return _serverClasses.match(name);
760 }
761
762
763 @Override
764 public boolean isSystemClass(String name)
765 {
766 if (_systemClasses == null)
767 loadSystemClasses();
768
769 return _systemClasses.match(name);
770 }
771
772
773 protected void loadSystemClasses()
774 {
775 if (_systemClasses != null)
776 return;
777
778
779
780 Server server = getServer();
781 if (server != null)
782 {
783 Object systemClasses = server.getAttribute(SERVER_SYS_CLASSES);
784 if (systemClasses != null && systemClasses instanceof String[])
785 _systemClasses = new ClasspathPattern((String[])systemClasses);
786 }
787
788 if (_systemClasses == null)
789 _systemClasses = new ClasspathPattern(__dftSystemClasses);
790 }
791
792
793 private void loadServerClasses()
794 {
795 if (_serverClasses != null)
796 {
797 return;
798 }
799
800
801
802 Server server = getServer();
803 if (server != null)
804 {
805 Object serverClasses = server.getAttribute(SERVER_SRV_CLASSES);
806 if (serverClasses != null && serverClasses instanceof String[])
807 {
808 _serverClasses = new ClasspathPattern((String[])serverClasses);
809 }
810 }
811
812 if (_serverClasses == null)
813 {
814 _serverClasses = new ClasspathPattern(__dftServerClasses);
815 }
816 }
817
818
819
820
821
822 @ManagedAttribute(value="war file location", readonly=true)
823 public String getWar()
824 {
825 if (_war==null)
826 _war=getResourceBase();
827 return _war;
828 }
829
830
831 public Resource getWebInf() throws IOException
832 {
833 if (super.getBaseResource() == null)
834 return null;
835
836
837 Resource web_inf= super.getBaseResource().addPath("WEB-INF/");
838 if (!web_inf.exists() || !web_inf.isDirectory())
839 return null;
840
841 return web_inf;
842 }
843
844
845
846
847
848 @ManagedAttribute("web application distributable")
849 public boolean isDistributable()
850 {
851 return _distributable;
852 }
853
854
855
856
857
858 @ManagedAttribute(value="extract war", readonly=true)
859 public boolean isExtractWAR()
860 {
861 return _extractWAR;
862 }
863
864
865
866
867
868 @ManagedAttribute(value="webdir copied on deploy (allows hot replacement on windows)", readonly=true)
869 public boolean isCopyWebDir()
870 {
871 return _copyDir;
872 }
873
874
875
876
877
878 public boolean isCopyWebInf()
879 {
880 return _copyWebInf;
881 }
882
883
884
885
886
887
888
889
890
891 @Override
892 @ManagedAttribute(value="parent classloader given priority", readonly=true)
893 public boolean isParentLoaderPriority()
894 {
895 return _parentLoaderPriority;
896 }
897
898
899
900 public static String[] getDefaultConfigurationClasses ()
901 {
902 return DEFAULT_CONFIGURATION_CLASSES;
903 }
904
905
906 public String[] getDefaultServerClasses ()
907 {
908 return __dftServerClasses;
909 }
910
911
912 public String[] getDefaultSystemClasses ()
913 {
914 return __dftSystemClasses;
915 }
916
917
918 protected void loadConfigurations()
919 throws Exception
920 {
921
922 if (_configurations.size()>0)
923 return;
924
925 if (_configurationClasses.size()==0)
926 _configurationClasses.addAll(Configuration.ClassList.serverDefault(getServer()));
927 for (String configClass : _configurationClasses)
928 _configurations.add((Configuration)Loader.loadClass(this.getClass(), configClass).newInstance());
929 }
930
931
932 @Override
933 public String toString()
934 {
935 if (_war!=null)
936 {
937 String war=_war;
938 if (war.indexOf("/webapps/")>=0)
939 war=war.substring(war.indexOf("/webapps/")+8);
940 return super.toString()+"{"+war+"}";
941 }
942 return super.toString();
943 }
944
945
946
947
948
949
950 public void setConfigurationClasses(String[] configurations)
951 {
952 if (isStarted())
953 throw new IllegalStateException();
954 _configurationClasses.clear();
955 if (configurations!=null)
956 _configurationClasses.addAll(Arrays.asList(configurations));
957 _configurations.clear();
958 }
959
960 public void setConfigurationClasses(List<String> configurations)
961 {
962 setConfigurationClasses(configurations.toArray(new String[configurations.size()]));
963 }
964
965
966
967
968
969 public void setConfigurations(Configuration[] configurations)
970 {
971 if (isStarted())
972 throw new IllegalStateException();
973 _configurations.clear();
974 if (configurations!=null)
975 _configurations.addAll(Arrays.asList(configurations));
976 }
977
978
979
980
981
982
983 public void setDefaultsDescriptor(String defaultsDescriptor)
984 {
985 _defaultsDescriptor = defaultsDescriptor;
986 }
987
988
989
990
991
992
993 public void setOverrideDescriptor(String overrideDescriptor)
994 {
995 _overrideDescriptors.clear();
996 _overrideDescriptors.add(overrideDescriptor);
997 }
998
999
1000
1001
1002
1003
1004 public void setOverrideDescriptors(List<String> overrideDescriptors)
1005 {
1006 _overrideDescriptors.clear();
1007 _overrideDescriptors.addAll(overrideDescriptors);
1008 }
1009
1010
1011
1012
1013
1014
1015 public void addOverrideDescriptor(String overrideDescriptor)
1016 {
1017 _overrideDescriptors.add(overrideDescriptor);
1018 }
1019
1020
1021
1022
1023
1024 @ManagedAttribute(value="standard web.xml descriptor", readonly=true)
1025 public String getDescriptor()
1026 {
1027 return _descriptor;
1028 }
1029
1030
1031
1032
1033
1034 public void setDescriptor(String descriptor)
1035 {
1036 _descriptor=descriptor;
1037 }
1038
1039
1040
1041
1042
1043 public void setDistributable(boolean distributable)
1044 {
1045 this._distributable = distributable;
1046 }
1047
1048
1049 @Override
1050 public void setEventListeners(EventListener[] eventListeners)
1051 {
1052 if (_sessionHandler!=null)
1053 _sessionHandler.clearEventListeners();
1054
1055 super.setEventListeners(eventListeners);
1056 }
1057
1058
1059
1060
1061
1062
1063 @Override
1064 public void addEventListener(EventListener listener)
1065 {
1066 super.addEventListener(listener);
1067 if ((listener instanceof HttpSessionActivationListener)
1068 || (listener instanceof HttpSessionAttributeListener)
1069 || (listener instanceof HttpSessionBindingListener)
1070 || (listener instanceof HttpSessionListener)
1071 || (listener instanceof HttpSessionIdListener))
1072 {
1073 if (_sessionHandler!=null)
1074 _sessionHandler.addEventListener(listener);
1075 }
1076 }
1077
1078 @Override
1079 public void removeEventListener(EventListener listener)
1080 {
1081 super.removeEventListener(listener);
1082 if ((listener instanceof HttpSessionActivationListener)
1083 || (listener instanceof HttpSessionAttributeListener)
1084 || (listener instanceof HttpSessionBindingListener)
1085 || (listener instanceof HttpSessionListener)
1086 || (listener instanceof HttpSessionIdListener))
1087 {
1088 if (_sessionHandler!=null)
1089 _sessionHandler.removeEventListener(listener);
1090 }
1091
1092 }
1093
1094
1095
1096
1097
1098
1099 public void setExtractWAR(boolean extractWAR)
1100 {
1101 _extractWAR = extractWAR;
1102 }
1103
1104
1105
1106
1107
1108 public void setCopyWebDir(boolean copy)
1109 {
1110 _copyDir = copy;
1111 }
1112
1113
1114
1115
1116
1117 public void setCopyWebInf(boolean copyWebInf)
1118 {
1119 _copyWebInf = copyWebInf;
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 public void setParentLoaderPriority(boolean java2compliant)
1131 {
1132 _parentLoaderPriority = java2compliant;
1133 }
1134
1135
1136
1137
1138
1139 public void setPermissions(PermissionCollection permissions)
1140 {
1141 _permissions = permissions;
1142 }
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153 public void setContextWhiteList(String[] contextWhiteList)
1154 {
1155 _contextWhiteList = contextWhiteList;
1156 }
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 public void setServerClasses(String[] serverClasses)
1174 {
1175 _serverClasses = new ClasspathPattern(serverClasses);
1176 }
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193 public void setSystemClasses(String[] systemClasses)
1194 {
1195 _systemClasses = new ClasspathPattern(systemClasses);
1196 }
1197
1198
1199
1200
1201
1202
1203
1204 public void setTempDirectory(File dir)
1205 {
1206 if (isStarted())
1207 throw new IllegalStateException("Started");
1208
1209 if (dir!=null)
1210 {
1211 try{dir=new File(dir.getCanonicalPath());}
1212 catch (IOException e){LOG.warn(Log.EXCEPTION,e);}
1213 }
1214
1215 _tmpDir=dir;
1216 setAttribute(TEMPDIR,_tmpDir);
1217 }
1218
1219
1220 @ManagedAttribute(value="temporary directory location", readonly=true)
1221 public File getTempDirectory ()
1222 {
1223 return _tmpDir;
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233 public void setPersistTempDirectory(boolean persist)
1234 {
1235 _persistTmpDir = persist;
1236 }
1237
1238
1239
1240
1241 public boolean isPersistTempDirectory()
1242 {
1243 return _persistTmpDir;
1244 }
1245
1246
1247
1248
1249
1250
1251 public void setWar(String war)
1252 {
1253 _war = war;
1254 }
1255
1256
1257
1258
1259
1260
1261
1262 @Override
1263 @ManagedAttribute(value="extra classpath for context classloader", readonly=true)
1264 public String getExtraClasspath()
1265 {
1266 return _extraClasspath;
1267 }
1268
1269
1270
1271
1272
1273
1274
1275 public void setExtraClasspath(String extraClasspath)
1276 {
1277 _extraClasspath=extraClasspath;
1278 }
1279
1280
1281 public boolean isLogUrlOnStart()
1282 {
1283 return _logUrlOnStart;
1284 }
1285
1286
1287
1288
1289
1290
1291
1292 public void setLogUrlOnStart(boolean logOnStart)
1293 {
1294 this._logUrlOnStart = logOnStart;
1295 }
1296
1297
1298 @Override
1299 public void setServer(Server server)
1300 {
1301 super.setServer(server);
1302 }
1303
1304
1305 public boolean isAllowDuplicateFragmentNames()
1306 {
1307 return _allowDuplicateFragmentNames;
1308 }
1309
1310
1311 public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames)
1312 {
1313 _allowDuplicateFragmentNames = allowDuplicateFragmentNames;
1314 }
1315
1316
1317 public void setThrowUnavailableOnStartupException (boolean throwIfStartupException) {
1318 _throwUnavailableOnStartupException = throwIfStartupException;
1319 }
1320
1321
1322 public boolean isThrowUnavailableOnStartupException () {
1323 return _throwUnavailableOnStartupException;
1324 }
1325
1326
1327 @Override
1328 protected void startContext()
1329 throws Exception
1330 {
1331 configure();
1332
1333
1334 _metadata.resolve(this);
1335
1336 startWebapp();
1337 }
1338
1339
1340 protected void startWebapp()
1341 throws Exception
1342 {
1343 super.startContext();
1344 }
1345
1346
1347 @Override
1348 public Set<String> setServletSecurity(Dynamic registration, ServletSecurityElement servletSecurityElement)
1349 {
1350 Set<String> unchangedURLMappings = new HashSet<String>();
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367 Collection<String> pathMappings = registration.getMappings();
1368 if (pathMappings != null)
1369 {
1370 ConstraintSecurityHandler.createConstraint(registration.getName(), servletSecurityElement);
1371
1372 for (String pathSpec:pathMappings)
1373 {
1374 Origin origin = getMetaData().getOrigin("constraint.url."+pathSpec);
1375
1376 switch (origin)
1377 {
1378 case NotSet:
1379 {
1380
1381 List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
1382 for (ConstraintMapping m:mappings)
1383 ((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
1384 ((ConstraintAware)getSecurityHandler()).checkPathsWithUncoveredHttpMethods();
1385 getMetaData().setOriginAPI("constraint.url."+pathSpec);
1386 break;
1387 }
1388 case WebXml:
1389 case WebDefaults:
1390 case WebOverride:
1391 case WebFragment:
1392 {
1393
1394 unchangedURLMappings.add(pathSpec);
1395 break;
1396 }
1397 case Annotation:
1398 case API:
1399 {
1400
1401
1402 List<ConstraintMapping> constraintMappings = ConstraintSecurityHandler.removeConstraintMappingsForPath(pathSpec, ((ConstraintAware)getSecurityHandler()).getConstraintMappings());
1403
1404 List<ConstraintMapping> freshMappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
1405 constraintMappings.addAll(freshMappings);
1406
1407 ((ConstraintSecurityHandler)getSecurityHandler()).setConstraintMappings(constraintMappings);
1408 ((ConstraintAware)getSecurityHandler()).checkPathsWithUncoveredHttpMethods();
1409 break;
1410 }
1411 }
1412 }
1413 }
1414
1415 return unchangedURLMappings;
1416 }
1417
1418
1419
1420
1421 public class Context extends ServletContextHandler.Context
1422 {
1423
1424
1425 @Override
1426 public void checkListener(Class<? extends EventListener> listener) throws IllegalStateException
1427 {
1428 try
1429 {
1430 super.checkListener(listener);
1431 }
1432 catch (IllegalArgumentException e)
1433 {
1434
1435 boolean ok = false;
1436 for (Class l:SessionHandler.SESSION_LISTENER_TYPES)
1437 {
1438 if (l.isAssignableFrom(listener))
1439 {
1440 ok = true;
1441 break;
1442 }
1443 }
1444 if (!ok)
1445 throw new IllegalArgumentException("Inappropriate listener type "+listener.getName());
1446 }
1447 }
1448
1449
1450 @Override
1451 public URL getResource(String path) throws MalformedURLException
1452 {
1453 Resource resource=WebAppContext.this.getResource(path);
1454 if (resource==null || !resource.exists())
1455 return null;
1456
1457
1458 if (resource.isDirectory() && resource instanceof ResourceCollection && !WebAppContext.this.isExtractWAR())
1459 {
1460 Resource[] resources = ((ResourceCollection)resource).getResources();
1461 for (int i=resources.length;i-->0;)
1462 {
1463 if (resources[i].getName().startsWith("jar:file"))
1464 return resources[i].getURL();
1465 }
1466 }
1467
1468 return resource.getURL();
1469 }
1470
1471
1472 @Override
1473 public ServletContext getContext(String uripath)
1474 {
1475 ServletContext servletContext = super.getContext(uripath);
1476
1477 if ( servletContext != null && _contextWhiteList != null )
1478 {
1479 for ( String context : _contextWhiteList )
1480 {
1481 if ( context.equals(uripath) )
1482 {
1483 return servletContext;
1484 }
1485 }
1486
1487 return null;
1488 }
1489 else
1490 {
1491 return servletContext;
1492 }
1493 }
1494
1495 }
1496
1497
1498 public MetaData getMetaData()
1499 {
1500 return _metadata;
1501 }
1502 }