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