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