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