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.Servlet;
39 import javax.servlet.ServletContext;
40 import javax.servlet.ServletRegistration.Dynamic;
41 import javax.servlet.ServletSecurityElement;
42 import javax.servlet.http.HttpSessionActivationListener;
43 import javax.servlet.http.HttpSessionAttributeListener;
44 import javax.servlet.http.HttpSessionBindingListener;
45 import javax.servlet.http.HttpSessionIdListener;
46 import javax.servlet.http.HttpSessionListener;
47
48 import org.eclipse.jetty.security.ConstraintAware;
49 import org.eclipse.jetty.security.ConstraintMapping;
50 import org.eclipse.jetty.security.ConstraintSecurityHandler;
51 import org.eclipse.jetty.security.SecurityHandler;
52 import org.eclipse.jetty.server.ClassLoaderDump;
53 import org.eclipse.jetty.server.Connector;
54 import org.eclipse.jetty.server.HandlerContainer;
55 import org.eclipse.jetty.server.Server;
56 import org.eclipse.jetty.server.handler.ContextHandler;
57 import org.eclipse.jetty.server.handler.ErrorHandler;
58 import org.eclipse.jetty.server.session.SessionHandler;
59 import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
60 import org.eclipse.jetty.servlet.ServletContextHandler;
61 import org.eclipse.jetty.servlet.ServletHandler;
62 import org.eclipse.jetty.util.AttributesMap;
63 import org.eclipse.jetty.util.IO;
64 import org.eclipse.jetty.util.Loader;
65 import org.eclipse.jetty.util.MultiException;
66 import org.eclipse.jetty.util.URIUtil;
67 import org.eclipse.jetty.util.annotation.ManagedAttribute;
68 import org.eclipse.jetty.util.annotation.ManagedObject;
69 import org.eclipse.jetty.util.component.DumpableCollection;
70 import org.eclipse.jetty.util.log.Log;
71 import org.eclipse.jetty.util.log.Logger;
72 import org.eclipse.jetty.util.resource.Resource;
73 import org.eclipse.jetty.util.resource.ResourceCollection;
74
75
76
77
78
79
80
81
82
83
84
85
86
87 @ManagedObject("Web Application ContextHandler")
88 public class WebAppContext extends ServletContextHandler implements WebAppClassLoader.Context
89 {
90 private static final Logger LOG = Log.getLogger(WebAppContext.class);
91
92 public static final String TEMPDIR = "javax.servlet.context.tempdir";
93 public static final String BASETEMPDIR = "org.eclipse.jetty.webapp.basetempdir";
94 public final static String WEB_DEFAULTS_XML="org/eclipse/jetty/webapp/webdefault.xml";
95 public final static String ERROR_PAGE="org.eclipse.jetty.server.error_page";
96 public final static String SERVER_SYS_CLASSES = "org.eclipse.jetty.webapp.systemClasses";
97 public final static String SERVER_SRV_CLASSES = "org.eclipse.jetty.webapp.serverClasses";
98
99 private String[] __dftProtectedTargets = {"/web-inf", "/meta-inf"};
100
101 public static final String[] DEFAULT_CONFIGURATION_CLASSES =
102 {
103 "org.eclipse.jetty.webapp.WebInfConfiguration",
104 "org.eclipse.jetty.webapp.WebXmlConfiguration",
105 "org.eclipse.jetty.webapp.MetaInfConfiguration",
106 "org.eclipse.jetty.webapp.FragmentConfiguration",
107 "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"
108 } ;
109
110
111
112
113
114
115 public final static String[] __dftSystemClasses =
116 {
117 "java.",
118 "javax.",
119 "org.xml.",
120 "org.w3c.",
121 "org.eclipse.jetty.jmx.",
122 "org.eclipse.jetty.util.annotation.",
123 "org.eclipse.jetty.continuation.",
124 "org.eclipse.jetty.jndi.",
125 "org.eclipse.jetty.jaas.",
126 "org.eclipse.jetty.websocket.",
127 "org.eclipse.jetty.util.log.",
128 "org.eclipse.jetty.servlet.DefaultServlet",
129 "org.eclipse.jetty.jsp.JettyJspServlet",
130 "org.eclipse.jetty.servlets.PushCacheFilter"
131 } ;
132
133
134
135
136
137
138
139 public final static String[] __dftServerClasses =
140 {
141 "-org.eclipse.jetty.jmx.",
142 "-org.eclipse.jetty.util.annotation.",
143 "-org.eclipse.jetty.continuation.",
144 "-org.eclipse.jetty.jndi.",
145 "-org.eclipse.jetty.jaas.",
146 "-org.eclipse.jetty.servlets.",
147 "-org.eclipse.jetty.servlet.DefaultServlet",
148 "-org.eclipse.jetty.jsp.",
149 "-org.eclipse.jetty.servlet.listener.",
150 "-org.eclipse.jetty.websocket.",
151 "-org.eclipse.jetty.apache.",
152 "-org.eclipse.jetty.util.log.",
153 "-org.eclipse.jetty.alpn.",
154 "org.objectweb.asm.",
155 "org.eclipse.jdt.",
156 "org.eclipse.jetty."
157 } ;
158
159 private final List<String> _configurationClasses = new ArrayList<>();
160 private ClasspathPattern _systemClasses = null;
161 private ClasspathPattern _serverClasses = null;
162
163 private final List<Configuration> _configurations = new ArrayList<>();
164 private String _defaultsDescriptor=WEB_DEFAULTS_XML;
165 private String _descriptor=null;
166 private final List<String> _overrideDescriptors = new ArrayList<>();
167 private boolean _distributable=false;
168 private boolean _extractWAR=true;
169 private boolean _copyDir=false;
170 private boolean _copyWebInf=false;
171 private boolean _logUrlOnStart =false;
172 private boolean _parentLoaderPriority= Boolean.getBoolean("org.eclipse.jetty.server.webapp.parentLoaderPriority");
173 private PermissionCollection _permissions;
174
175 private String[] _contextWhiteList = null;
176
177 private File _tmpDir;
178 private boolean _persistTmpDir = false;
179
180 private String _war;
181 private String _extraClasspath;
182 private Throwable _unavailableException;
183
184 private Map<String, String> _resourceAliases;
185 private boolean _ownClassLoader=false;
186 private boolean _configurationDiscovered=true;
187 private boolean _allowDuplicateFragmentNames = false;
188 private boolean _throwUnavailableOnStartupException = false;
189
190
191
192 private MetaData _metadata=new MetaData();
193
194 public static WebAppContext getCurrentWebAppContext()
195 {
196 ContextHandler.Context context=ContextHandler.getCurrentContext();
197 if (context!=null)
198 {
199 ContextHandler handler = context.getContextHandler();
200 if (handler instanceof WebAppContext)
201 return (WebAppContext)handler;
202 }
203 return null;
204 }
205
206
207 public WebAppContext()
208 {
209 this(null,null,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
210 }
211
212
213
214
215
216
217 public WebAppContext(String webApp,String contextPath)
218 {
219 this(null,contextPath,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
220 setWar(webApp);
221 }
222
223
224
225
226
227
228
229 public WebAppContext(HandlerContainer parent, String webApp, String contextPath)
230 {
231 this(parent,contextPath,null,null,null,new ErrorPageErrorHandler(),SESSIONS|SECURITY);
232 setWar(webApp);
233 }
234
235
236
237
238
239
240
241
242
243
244
245 public WebAppContext(SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
246 {
247 this(null, null, sessionHandler, securityHandler, servletHandler, errorHandler,0);
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262 public WebAppContext(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler,int options)
263 {
264 super(parent, contextPath,sessionHandler, securityHandler, servletHandler, errorHandler,options);
265 _scontext = new Context();
266 setErrorHandler(errorHandler != null ? errorHandler : new ErrorPageErrorHandler());
267 setProtectedTargets(__dftProtectedTargets);
268 }
269
270
271
272
273
274 @Override
275 public void setDisplayName(String servletContextName)
276 {
277 super.setDisplayName(servletContextName);
278 ClassLoader cl = getClassLoader();
279 if (cl!=null && cl instanceof WebAppClassLoader && servletContextName!=null)
280 ((WebAppClassLoader)cl).setName(servletContextName);
281 }
282
283
284
285
286
287 public Throwable getUnavailableException()
288 {
289 return _unavailableException;
290 }
291
292
293
294
295
296
297
298
299
300
301
302 public void setResourceAlias(String alias, String uri)
303 {
304 if (_resourceAliases == null)
305 _resourceAliases= new HashMap<String, String>(5);
306 _resourceAliases.put(alias, uri);
307 }
308
309
310 public Map<String, String> getResourceAliases()
311 {
312 if (_resourceAliases == null)
313 return null;
314 return _resourceAliases;
315 }
316
317
318 public void setResourceAliases(Map<String, String> map)
319 {
320 _resourceAliases = map;
321 }
322
323
324 public String getResourceAlias(String path)
325 {
326 if (_resourceAliases == null)
327 return null;
328 String alias = _resourceAliases.get(path);
329
330 int slash=path.length();
331 while (alias==null)
332 {
333 slash=path.lastIndexOf("/",slash-1);
334 if (slash<0)
335 break;
336 String match=_resourceAliases.get(path.substring(0,slash+1));
337 if (match!=null)
338 alias=match+path.substring(slash+1);
339 }
340 return alias;
341 }
342
343
344 public String removeResourceAlias(String alias)
345 {
346 if (_resourceAliases == null)
347 return null;
348 return _resourceAliases.remove(alias);
349 }
350
351
352
353
354
355 @Override
356 public void setClassLoader(ClassLoader classLoader)
357 {
358 super.setClassLoader(classLoader);
359
360 String name = getDisplayName();
361 if (name==null)
362 name=getContextPath();
363
364 if (classLoader!=null && classLoader instanceof WebAppClassLoader && getDisplayName()!=null)
365 ((WebAppClassLoader)classLoader).setName(name);
366 }
367
368
369 @Override
370 public Resource getResource(String uriInContext) throws MalformedURLException
371 {
372 if (uriInContext==null || !uriInContext.startsWith(URIUtil.SLASH))
373 throw new MalformedURLException(uriInContext);
374
375 IOException ioe= null;
376 Resource resource= null;
377 int loop=0;
378 while (uriInContext!=null && loop++<100)
379 {
380 try
381 {
382 resource= super.getResource(uriInContext);
383 if (resource != null && resource.exists())
384 return resource;
385
386 uriInContext = getResourceAlias(uriInContext);
387 }
388 catch (IOException e)
389 {
390 LOG.ignore(e);
391 if (ioe==null)
392 ioe= e;
393 }
394 }
395
396 if (ioe != null && ioe instanceof MalformedURLException)
397 throw (MalformedURLException)ioe;
398
399 return resource;
400 }
401
402
403
404
405
406
407
408 public boolean isConfigurationDiscovered()
409 {
410 return _configurationDiscovered;
411 }
412
413
414
415
416
417
418
419
420
421
422
423 public void setConfigurationDiscovered(boolean discovered)
424 {
425 _configurationDiscovered = discovered;
426 }
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 public void preConfigure() throws Exception
446 {
447
448 loadConfigurations();
449
450
451 loadSystemClasses();
452
453
454 loadServerClasses();
455
456
457 _ownClassLoader=false;
458 if (getClassLoader()==null)
459 {
460 WebAppClassLoader classLoader = new WebAppClassLoader(this);
461 setClassLoader(classLoader);
462 _ownClassLoader=true;
463 }
464
465 if (LOG.isDebugEnabled())
466 {
467 ClassLoader loader = getClassLoader();
468 LOG.debug("Thread Context classloader {}",loader);
469 loader=loader.getParent();
470 while(loader!=null)
471 {
472 LOG.debug("Parent class loader: {} ",loader);
473 loader=loader.getParent();
474 }
475 }
476
477
478 for (Configuration configuration : _configurations)
479 {
480 LOG.debug("preConfigure {} with {}",this,configuration);
481 configuration.preConfigure(this);
482 }
483 }
484
485
486 public void configure() throws Exception
487 {
488
489 for (Configuration configuration : _configurations)
490 {
491 LOG.debug("configure {} with {}",this,configuration);
492 configuration.configure(this);
493 }
494 }
495
496
497 public void postConfigure() throws Exception
498 {
499
500 for (Configuration configuration : _configurations)
501 {
502 LOG.debug("postConfigure {} with {}",this,configuration);
503 configuration.postConfigure(this);
504 }
505 }
506
507
508
509
510
511 @Override
512 protected void doStart() throws Exception
513 {
514 try
515 {
516 _metadata.setAllowDuplicateFragmentNames(isAllowDuplicateFragmentNames());
517 preConfigure();
518 super.doStart();
519 postConfigure();
520
521 if (isLogUrlOnStart())
522 dumpUrl();
523 }
524 catch (Exception e)
525 {
526
527 LOG.warn("Failed startup of context "+this, e);
528 _unavailableException=e;
529 setAvailable(false);
530 if (isThrowUnavailableOnStartupException())
531 throw e;
532 }
533 }
534
535
536
537
538
539 @Override
540 protected void doStop() throws Exception
541 {
542 super.doStop();
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.add(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.add(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 @Override
947 public void dump(Appendable out, String indent) throws IOException
948 {
949 dumpBeans(out,indent,
950 Collections.singletonList(new ClassLoaderDump(getClassLoader())),
951 Collections.singletonList(new DumpableCollection("Systemclasses "+this,_systemClasses)),
952 Collections.singletonList(new DumpableCollection("Serverclasses "+this,_serverClasses)),
953 Collections.singletonList(new DumpableCollection("Configurations "+this,_configurations)),
954 Collections.singletonList(new DumpableCollection("Handler attributes "+this,((AttributesMap)getAttributes()).getAttributeEntrySet())),
955 Collections.singletonList(new DumpableCollection("Context attributes "+this,((Context)getServletContext()).getAttributeEntrySet())),
956 Collections.singletonList(new DumpableCollection("Initparams "+this,getInitParams().entrySet()))
957 );
958 }
959
960
961
962
963
964
965 public void setConfigurationClasses(String[] configurations)
966 {
967 if (isStarted())
968 throw new IllegalStateException();
969 _configurationClasses.clear();
970 if (configurations!=null)
971 _configurationClasses.addAll(Arrays.asList(configurations));
972 _configurations.clear();
973 }
974
975 public void setConfigurationClasses(List<String> configurations)
976 {
977 setConfigurationClasses(configurations.toArray(new String[configurations.size()]));
978 }
979
980
981
982
983
984 public void setConfigurations(Configuration[] configurations)
985 {
986 if (isStarted())
987 throw new IllegalStateException();
988 _configurations.clear();
989 if (configurations!=null)
990 _configurations.addAll(Arrays.asList(configurations));
991 }
992
993
994
995
996
997
998 public void setDefaultsDescriptor(String defaultsDescriptor)
999 {
1000 _defaultsDescriptor = defaultsDescriptor;
1001 }
1002
1003
1004
1005
1006
1007
1008 public void setOverrideDescriptor(String overrideDescriptor)
1009 {
1010 _overrideDescriptors.clear();
1011 _overrideDescriptors.add(overrideDescriptor);
1012 }
1013
1014
1015
1016
1017
1018
1019 public void setOverrideDescriptors(List<String> overrideDescriptors)
1020 {
1021 _overrideDescriptors.clear();
1022 _overrideDescriptors.addAll(overrideDescriptors);
1023 }
1024
1025
1026
1027
1028
1029
1030 public void addOverrideDescriptor(String overrideDescriptor)
1031 {
1032 _overrideDescriptors.add(overrideDescriptor);
1033 }
1034
1035
1036
1037
1038
1039 @ManagedAttribute(value="standard web.xml descriptor", readonly=true)
1040 public String getDescriptor()
1041 {
1042 return _descriptor;
1043 }
1044
1045
1046
1047
1048
1049 public void setDescriptor(String descriptor)
1050 {
1051 _descriptor=descriptor;
1052 }
1053
1054
1055
1056
1057
1058 public void setDistributable(boolean distributable)
1059 {
1060 this._distributable = distributable;
1061 }
1062
1063
1064 @Override
1065 public void setEventListeners(EventListener[] eventListeners)
1066 {
1067 if (_sessionHandler!=null)
1068 _sessionHandler.clearEventListeners();
1069
1070 super.setEventListeners(eventListeners);
1071 }
1072
1073
1074
1075
1076
1077
1078 @Override
1079 public void addEventListener(EventListener listener)
1080 {
1081 super.addEventListener(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.addEventListener(listener);
1090 }
1091 }
1092
1093 @Override
1094 public void removeEventListener(EventListener listener)
1095 {
1096 super.removeEventListener(listener);
1097 if ((listener instanceof HttpSessionActivationListener)
1098 || (listener instanceof HttpSessionAttributeListener)
1099 || (listener instanceof HttpSessionBindingListener)
1100 || (listener instanceof HttpSessionListener)
1101 || (listener instanceof HttpSessionIdListener))
1102 {
1103 if (_sessionHandler!=null)
1104 _sessionHandler.removeEventListener(listener);
1105 }
1106
1107 }
1108
1109
1110
1111
1112
1113
1114 public void setExtractWAR(boolean extractWAR)
1115 {
1116 _extractWAR = extractWAR;
1117 }
1118
1119
1120
1121
1122
1123 public void setCopyWebDir(boolean copy)
1124 {
1125 _copyDir = copy;
1126 }
1127
1128
1129
1130
1131
1132 public void setCopyWebInf(boolean copyWebInf)
1133 {
1134 _copyWebInf = copyWebInf;
1135 }
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 public void setParentLoaderPriority(boolean java2compliant)
1146 {
1147 _parentLoaderPriority = java2compliant;
1148 }
1149
1150
1151
1152
1153
1154 public void setPermissions(PermissionCollection permissions)
1155 {
1156 _permissions = permissions;
1157 }
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169 public void setContextWhiteList(String[] contextWhiteList)
1170 {
1171 _contextWhiteList = contextWhiteList;
1172 }
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184 public void setServerClasses(String[] serverClasses)
1185 {
1186 _serverClasses = new ClasspathPattern(serverClasses);
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199 public void setSystemClasses(String[] systemClasses)
1200 {
1201 _systemClasses = new ClasspathPattern(systemClasses);
1202 }
1203
1204
1205
1206
1207
1208
1209
1210 public void setTempDirectory(File dir)
1211 {
1212 if (isStarted())
1213 throw new IllegalStateException("Started");
1214
1215 if (dir!=null)
1216 {
1217 try{dir=new File(dir.getCanonicalPath());}
1218 catch (IOException e){LOG.warn(Log.EXCEPTION,e);}
1219 }
1220
1221 _tmpDir=dir;
1222 setAttribute(TEMPDIR,_tmpDir);
1223 }
1224
1225
1226 @ManagedAttribute(value="temporary directory location", readonly=true)
1227 public File getTempDirectory ()
1228 {
1229 return _tmpDir;
1230 }
1231
1232
1233
1234
1235
1236
1237
1238
1239 public void setPersistTempDirectory(boolean persist)
1240 {
1241 _persistTmpDir = persist;
1242 }
1243
1244
1245
1246
1247 public boolean isPersistTempDirectory()
1248 {
1249 return _persistTmpDir;
1250 }
1251
1252
1253
1254
1255
1256
1257 public void setWar(String war)
1258 {
1259 _war = war;
1260 }
1261
1262
1263
1264
1265
1266
1267
1268 @Override
1269 @ManagedAttribute(value="extra classpath for context classloader", readonly=true)
1270 public String getExtraClasspath()
1271 {
1272 return _extraClasspath;
1273 }
1274
1275
1276
1277
1278
1279
1280
1281 public void setExtraClasspath(String extraClasspath)
1282 {
1283 _extraClasspath=extraClasspath;
1284 }
1285
1286
1287 public boolean isLogUrlOnStart()
1288 {
1289 return _logUrlOnStart;
1290 }
1291
1292
1293
1294
1295
1296
1297
1298 public void setLogUrlOnStart(boolean logOnStart)
1299 {
1300 this._logUrlOnStart = logOnStart;
1301 }
1302
1303
1304 @Override
1305 public void setServer(Server server)
1306 {
1307 super.setServer(server);
1308 }
1309
1310
1311 public boolean isAllowDuplicateFragmentNames()
1312 {
1313 return _allowDuplicateFragmentNames;
1314 }
1315
1316
1317 public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames)
1318 {
1319 _allowDuplicateFragmentNames = allowDuplicateFragmentNames;
1320 }
1321
1322
1323 public void setThrowUnavailableOnStartupException (boolean throwIfStartupException) {
1324 _throwUnavailableOnStartupException = throwIfStartupException;
1325 }
1326
1327
1328 public boolean isThrowUnavailableOnStartupException () {
1329 return _throwUnavailableOnStartupException;
1330 }
1331
1332
1333 @Override
1334 protected void startContext()
1335 throws Exception
1336 {
1337 configure();
1338
1339
1340 _metadata.resolve(this);
1341
1342 startWebapp();
1343 }
1344
1345
1346
1347 @Override
1348 protected void stopContext() throws Exception
1349 {
1350 stopWebapp();
1351 try
1352 {
1353 for (int i=_configurations.size();i-->0;)
1354 _configurations.get(i).deconfigure(this);
1355
1356 if (_metadata != null)
1357 _metadata.clear();
1358 _metadata=new MetaData();
1359
1360 }
1361 finally
1362 {
1363 if (_ownClassLoader)
1364 {
1365 ClassLoader loader = getClassLoader();
1366 if (loader != null && loader instanceof URLClassLoader)
1367 ((URLClassLoader)loader).close();
1368 setClassLoader(null);
1369 }
1370
1371 setAvailable(true);
1372 _unavailableException=null;
1373 }
1374 }
1375
1376
1377 protected void startWebapp()
1378 throws Exception
1379 {
1380 super.startContext();
1381 }
1382
1383
1384 protected void stopWebapp() throws Exception
1385 {
1386 super.stopContext();
1387 }
1388
1389 @Override
1390 public Set<String> setServletSecurity(Dynamic registration, ServletSecurityElement servletSecurityElement)
1391 {
1392 Set<String> unchangedURLMappings = new HashSet<String>();
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409 Collection<String> pathMappings = registration.getMappings();
1410 if (pathMappings != null)
1411 {
1412 ConstraintSecurityHandler.createConstraint(registration.getName(), servletSecurityElement);
1413
1414 for (String pathSpec:pathMappings)
1415 {
1416 Origin origin = getMetaData().getOrigin("constraint.url."+pathSpec);
1417
1418 switch (origin)
1419 {
1420 case NotSet:
1421 {
1422
1423 List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
1424 for (ConstraintMapping m:mappings)
1425 ((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
1426 ((ConstraintAware)getSecurityHandler()).checkPathsWithUncoveredHttpMethods();
1427 getMetaData().setOriginAPI("constraint.url."+pathSpec);
1428 break;
1429 }
1430 case WebXml:
1431 case WebDefaults:
1432 case WebOverride:
1433 case WebFragment:
1434 {
1435
1436 unchangedURLMappings.add(pathSpec);
1437 break;
1438 }
1439 case Annotation:
1440 case API:
1441 {
1442
1443
1444 List<ConstraintMapping> constraintMappings = ConstraintSecurityHandler.removeConstraintMappingsForPath(pathSpec, ((ConstraintAware)getSecurityHandler()).getConstraintMappings());
1445
1446 List<ConstraintMapping> freshMappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
1447 constraintMappings.addAll(freshMappings);
1448
1449 ((ConstraintSecurityHandler)getSecurityHandler()).setConstraintMappings(constraintMappings);
1450 ((ConstraintAware)getSecurityHandler()).checkPathsWithUncoveredHttpMethods();
1451 break;
1452 }
1453 }
1454 }
1455 }
1456
1457 return unchangedURLMappings;
1458 }
1459
1460
1461
1462
1463 public class Context extends ServletContextHandler.Context
1464 {
1465
1466
1467 @Override
1468 public void checkListener(Class<? extends EventListener> listener) throws IllegalStateException
1469 {
1470 try
1471 {
1472 super.checkListener(listener);
1473 }
1474 catch (IllegalArgumentException e)
1475 {
1476
1477 boolean ok = false;
1478 for (Class l:SessionHandler.SESSION_LISTENER_TYPES)
1479 {
1480 if (l.isAssignableFrom(listener))
1481 {
1482 ok = true;
1483 break;
1484 }
1485 }
1486 if (!ok)
1487 throw new IllegalArgumentException("Inappropriate listener type "+listener.getName());
1488 }
1489 }
1490
1491
1492 @Override
1493 public URL getResource(String path) throws MalformedURLException
1494 {
1495 Resource resource=WebAppContext.this.getResource(path);
1496 if (resource==null || !resource.exists())
1497 return null;
1498
1499
1500 if (resource.isDirectory() && resource instanceof ResourceCollection && !WebAppContext.this.isExtractWAR())
1501 {
1502 Resource[] resources = ((ResourceCollection)resource).getResources();
1503 for (int i=resources.length;i-->0;)
1504 {
1505 if (resources[i].getName().startsWith("jar:file"))
1506 return resources[i].getURL();
1507 }
1508 }
1509
1510 return resource.getURL();
1511 }
1512
1513
1514 @Override
1515 public ServletContext getContext(String uripath)
1516 {
1517 ServletContext servletContext = super.getContext(uripath);
1518
1519 if ( servletContext != null && _contextWhiteList != null )
1520 {
1521 for ( String context : _contextWhiteList )
1522 {
1523 if ( context.equals(uripath) )
1524 {
1525 return servletContext;
1526 }
1527 }
1528
1529 return null;
1530 }
1531 else
1532 {
1533 return servletContext;
1534 }
1535 }
1536
1537 }
1538
1539
1540 public MetaData getMetaData()
1541 {
1542 return _metadata;
1543 }
1544 }