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.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.EnumSet;
25 import java.util.EventListener;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.ListIterator;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Set;
34
35 import javax.servlet.DispatcherType;
36 import javax.servlet.MultipartConfigElement;
37 import javax.servlet.SessionTrackingMode;
38
39 import org.eclipse.jetty.security.ConstraintAware;
40 import org.eclipse.jetty.security.ConstraintMapping;
41 import org.eclipse.jetty.security.authentication.FormAuthenticator;
42 import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
43 import org.eclipse.jetty.servlet.FilterHolder;
44 import org.eclipse.jetty.servlet.FilterMapping;
45 import org.eclipse.jetty.servlet.BaseHolder.Source;
46 import org.eclipse.jetty.servlet.JspPropertyGroupServlet;
47 import org.eclipse.jetty.servlet.ListenerHolder;
48 import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
49 import org.eclipse.jetty.servlet.ServletContextHandler.JspPropertyGroup;
50 import org.eclipse.jetty.servlet.ServletContextHandler.TagLib;
51 import org.eclipse.jetty.servlet.ServletHandler;
52 import org.eclipse.jetty.servlet.ServletHolder;
53 import org.eclipse.jetty.servlet.ServletMapping;
54 import org.eclipse.jetty.util.ArrayUtil;
55 import org.eclipse.jetty.util.Loader;
56 import org.eclipse.jetty.util.log.Log;
57 import org.eclipse.jetty.util.log.Logger;
58 import org.eclipse.jetty.util.security.Constraint;
59 import org.eclipse.jetty.xml.XmlParser;
60 import org.eclipse.jetty.xml.XmlParser.Node;
61
62
63
64
65
66
67 public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
68 {
69 private static final Logger LOG = Log.getLogger(StandardDescriptorProcessor.class);
70
71 public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor";
72
73 final Map<String,FilterHolder> _filterHolderMap = new HashMap<>();
74 final List<FilterHolder> _filterHolders = new ArrayList<>();
75 final List<FilterMapping> _filterMappings = new ArrayList<>();
76 final Map<String,ServletHolder> _servletHolderMap = new HashMap<>();
77 final List<ServletHolder> _servletHolders = new ArrayList<>();
78 final List<ServletMapping> _servletMappings = new ArrayList<>();
79
80 public StandardDescriptorProcessor ()
81 {
82 try
83 {
84 registerVisitor("context-param", this.getClass().getMethod("visitContextParam", __signature));
85 registerVisitor("display-name", this.getClass().getMethod("visitDisplayName", __signature));
86 registerVisitor("servlet", this.getClass().getMethod("visitServlet", __signature));
87 registerVisitor("servlet-mapping", this.getClass().getMethod("visitServletMapping", __signature));
88 registerVisitor("session-config", this.getClass().getMethod("visitSessionConfig", __signature));
89 registerVisitor("mime-mapping", this.getClass().getMethod("visitMimeMapping", __signature));
90 registerVisitor("welcome-file-list", this.getClass().getMethod("visitWelcomeFileList", __signature));
91 registerVisitor("locale-encoding-mapping-list", this.getClass().getMethod("visitLocaleEncodingList", __signature));
92 registerVisitor("error-page", this.getClass().getMethod("visitErrorPage", __signature));
93 registerVisitor("taglib", this.getClass().getMethod("visitTagLib", __signature));
94 registerVisitor("jsp-config", this.getClass().getMethod("visitJspConfig", __signature));
95 registerVisitor("security-constraint", this.getClass().getMethod("visitSecurityConstraint", __signature));
96 registerVisitor("login-config", this.getClass().getMethod("visitLoginConfig", __signature));
97 registerVisitor("security-role", this.getClass().getMethod("visitSecurityRole", __signature));
98 registerVisitor("filter", this.getClass().getMethod("visitFilter", __signature));
99 registerVisitor("filter-mapping", this.getClass().getMethod("visitFilterMapping", __signature));
100 registerVisitor("listener", this.getClass().getMethod("visitListener", __signature));
101 registerVisitor("distributable", this.getClass().getMethod("visitDistributable", __signature));
102 registerVisitor("deny-uncovered-http-methods", this.getClass().getMethod("visitDenyUncoveredHttpMethods", __signature));
103 }
104 catch (Exception e)
105 {
106 throw new IllegalStateException(e);
107 }
108 }
109
110
111
112
113
114
115 public void start(WebAppContext context, Descriptor descriptor)
116 {
117 for (FilterHolder h : context.getServletHandler().getFilters())
118 {
119 _filterHolderMap.put(h.getName(),h);
120 _filterHolders.add(h);
121 }
122 if (context.getServletHandler().getFilterMappings()!=null)
123 _filterMappings.addAll(Arrays.asList(context.getServletHandler().getFilterMappings()));
124 for (ServletHolder h : context.getServletHandler().getServlets())
125 {
126 _servletHolderMap.put(h.getName(),h);
127 _servletHolders.add(h);
128 }
129 if (context.getServletHandler().getServletMappings()!=null)
130 _servletMappings.addAll(Arrays.asList(context.getServletHandler().getServletMappings()));
131 }
132
133
134
135
136
137 public void end(WebAppContext context, Descriptor descriptor)
138 {
139 context.getServletHandler().setFilters(_filterHolders.toArray(new FilterHolder[_filterHolderMap.size()]));
140 context.getServletHandler().setServlets(_servletHolders.toArray(new ServletHolder[_servletHolderMap.size()]));
141
142 context.getServletHandler().setFilterMappings(_filterMappings.toArray(new FilterMapping[_filterMappings.size()]));
143 context.getServletHandler().setServletMappings(_servletMappings.toArray(new ServletMapping[_servletMappings.size()]));
144
145 _filterHolderMap.clear();
146 _filterHolders.clear();
147 _filterMappings.clear();
148 _servletHolderMap.clear();
149 _servletHolders.clear();
150 _servletMappings.clear();
151 }
152
153
154
155
156
157
158 public void visitContextParam (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
159 {
160 String name = node.getString("param-name", false, true);
161 String value = node.getString("param-value", false, true);
162 switch (context.getMetaData().getOrigin("context-param."+name))
163 {
164 case NotSet:
165 {
166
167 context.getInitParams().put(name, value);
168 context.getMetaData().setOrigin("context-param."+name, descriptor);
169 break;
170 }
171 case WebXml:
172 case WebDefaults:
173 case WebOverride:
174 {
175
176 if (!(descriptor instanceof FragmentDescriptor))
177 {
178 context.getInitParams().put(name, value);
179 context.getMetaData().setOrigin("context-param."+name, descriptor);
180 }
181 break;
182 }
183 case WebFragment:
184 {
185
186 if (descriptor instanceof FragmentDescriptor)
187 {
188 if (!((String)context.getInitParams().get(name)).equals(value))
189 throw new IllegalStateException("Conflicting context-param "+name+"="+value+" in "+descriptor.getResource());
190 }
191 break;
192 }
193 default:
194 LOG.warn(new Throwable());
195 }
196 if (LOG.isDebugEnabled())
197 LOG.debug("ContextParam: " + name + "=" + value);
198
199 }
200
201
202
203
204
205
206
207
208 public void visitDisplayName(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
209 {
210
211 if (!(descriptor instanceof FragmentDescriptor))
212 {
213 context.setDisplayName(node.toString(false, true));
214 context.getMetaData().setOrigin("display-name", descriptor);
215 }
216 }
217
218
219
220
221
222
223
224 public void visitServlet(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
225 {
226 String id = node.getAttribute("id");
227
228
229 String name = node.getString("servlet-name", false, true);
230 ServletHolder holder = _servletHolderMap.get(name);
231
232
233 if (holder == null)
234 {
235 holder = context.getServletHandler().newServletHolder(Source.DESCRIPTOR);
236 holder.setName(name);
237 _servletHolderMap.put(name,holder);
238 _servletHolders.add(holder);
239 }
240
241
242 Iterator<?> iParamsIter = node.iterator("init-param");
243 while (iParamsIter.hasNext())
244 {
245 XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
246 String pname = paramNode.getString("param-name", false, true);
247 String pvalue = paramNode.getString("param-value", false, true);
248 String originName = name+".servlet.init-param."+pname;
249
250 Descriptor originDescriptor = context.getMetaData().getOriginDescriptor(originName);
251 switch (context.getMetaData().getOrigin(originName))
252 {
253 case NotSet:
254 {
255
256 holder.setInitParameter(pname, pvalue);
257 context.getMetaData().setOrigin(originName, descriptor);
258 break;
259 }
260 case WebXml:
261 case WebDefaults:
262 case WebOverride:
263 {
264
265
266
267 if (!(descriptor instanceof FragmentDescriptor) && (descriptor!=originDescriptor))
268 {
269 holder.setInitParameter(pname, pvalue);
270 context.getMetaData().setOrigin(originName, descriptor);
271 }
272 break;
273 }
274 case WebFragment:
275 {
276
277 if ((descriptor != originDescriptor) && !holder.getInitParameter(pname).equals(pvalue))
278 throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
279 break;
280 }
281 default:
282 LOG.warn(new Throwable());
283 }
284 }
285
286 String servlet_class = node.getString("servlet-class", false, true);
287 if ("".equals(servlet_class))
288 servlet_class = null;
289
290
291 if (id != null && id.equals("jsp") && servlet_class != null)
292 {
293 try
294 {
295 Loader.loadClass(this.getClass(), servlet_class);
296 }
297 catch (ClassNotFoundException e)
298 {
299 LOG.info("NO JSP Support for {}, did not find {}", context.getContextPath(), servlet_class);
300 servlet_class = "org.eclipse.jetty.servlet.NoJspServlet";
301 }
302 }
303
304
305
306 if (servlet_class != null)
307 {
308 ((WebDescriptor)descriptor).addClassName(servlet_class);
309 switch (context.getMetaData().getOrigin(name+".servlet.servlet-class"))
310 {
311 case NotSet:
312 {
313
314 holder.setClassName(servlet_class);
315 context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor);
316 break;
317 }
318 case WebXml:
319 case WebDefaults:
320 case WebOverride:
321 {
322
323 if (!(descriptor instanceof FragmentDescriptor))
324 {
325 holder.setClassName(servlet_class);
326 context.getMetaData().setOrigin(name+".servlet.servlet-class", descriptor);
327 }
328 break;
329 }
330 case WebFragment:
331 {
332
333 if (!servlet_class.equals(holder.getClassName()))
334 throw new IllegalStateException("Conflicting servlet-class "+servlet_class+" in "+descriptor.getResource());
335 break;
336 }
337 default:
338 LOG.warn(new Throwable());
339 }
340 }
341
342
343 String jsp_file = node.getString("jsp-file", false, true);
344 if (jsp_file != null)
345 holder.setForcedPath(jsp_file);
346
347
348 XmlParser.Node startup = node.get("load-on-startup");
349 if (startup != null)
350 {
351 String s = startup.toString(false, true).toLowerCase(Locale.ENGLISH);
352 int order = 0;
353 if (s.startsWith("t"))
354 {
355 LOG.warn("Deprecated boolean load-on-startup. Please use integer");
356 order = 1;
357 }
358 else
359 {
360 try
361 {
362 if (s != null && s.trim().length() > 0) order = Integer.parseInt(s);
363 }
364 catch (Exception e)
365 {
366 LOG.warn("Cannot parse load-on-startup " + s + ". Please use integer");
367 LOG.ignore(e);
368 }
369 }
370
371 switch (context.getMetaData().getOrigin(name+".servlet.load-on-startup"))
372 {
373 case NotSet:
374 {
375
376 holder.setInitOrder(order);
377 context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor);
378 break;
379 }
380 case WebXml:
381 case WebDefaults:
382 case WebOverride:
383 {
384
385 if (!(descriptor instanceof FragmentDescriptor))
386 {
387 holder.setInitOrder(order);
388 context.getMetaData().setOrigin(name+".servlet.load-on-startup", descriptor);
389 }
390 break;
391 }
392 case WebFragment:
393 {
394
395 if (order != holder.getInitOrder())
396 throw new IllegalStateException("Conflicting load-on-startup value in "+descriptor.getResource());
397 break;
398 }
399 default:
400 LOG.warn(new Throwable());
401 }
402 }
403
404 Iterator<Node> sRefsIter = node.iterator("security-role-ref");
405 while (sRefsIter.hasNext())
406 {
407 XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
408 String roleName = securityRef.getString("role-name", false, true);
409 String roleLink = securityRef.getString("role-link", false, true);
410 if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
411 {
412 if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this);
413 switch (context.getMetaData().getOrigin(name+".servlet.role-name."+roleName))
414 {
415 case NotSet:
416 {
417
418 holder.setUserRoleLink(roleName, roleLink);
419 context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor);
420 break;
421 }
422 case WebXml:
423 case WebDefaults:
424 case WebOverride:
425 {
426
427 if (!(descriptor instanceof FragmentDescriptor))
428 {
429 holder.setUserRoleLink(roleName, roleLink);
430 context.getMetaData().setOrigin(name+".servlet.role-name."+roleName, descriptor);
431 }
432 break;
433 }
434 case WebFragment:
435 {
436 if (!holder.getUserRoleLink(roleName).equals(roleLink))
437 throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+name+" in "+descriptor.getResource());
438 break;
439 }
440 default:
441 LOG.warn(new Throwable());
442 }
443 }
444 else
445 {
446 LOG.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + holder.getName() + ", " + securityRef);
447 }
448 }
449
450
451 XmlParser.Node run_as = node.get("run-as");
452 if (run_as != null)
453 {
454 String roleName = run_as.getString("role-name", false, true);
455
456 if (roleName != null)
457 {
458 switch (context.getMetaData().getOrigin(name+".servlet.run-as"))
459 {
460 case NotSet:
461 {
462
463 holder.setRunAsRole(roleName);
464 context.getMetaData().setOrigin(name+".servlet.run-as", descriptor);
465 break;
466 }
467 case WebXml:
468 case WebDefaults:
469 case WebOverride:
470 {
471
472 if (!(descriptor instanceof FragmentDescriptor))
473 {
474 holder.setRunAsRole(roleName);
475 context.getMetaData().setOrigin(name+".servlet.run-as", descriptor);
476 }
477 break;
478 }
479 case WebFragment:
480 {
481
482 if (!holder.getRunAsRole().equals(roleName))
483 throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+name+" in "+descriptor.getResource());
484 break;
485 }
486 default:
487 LOG.warn(new Throwable());
488 }
489 }
490 }
491
492 String async=node.getString("async-supported",false,true);
493 if (async!=null)
494 {
495 boolean val = async.length()==0||Boolean.valueOf(async);
496 switch (context.getMetaData().getOrigin(name+".servlet.async-supported"))
497 {
498 case NotSet:
499 {
500
501 holder.setAsyncSupported(val);
502 context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor);
503 break;
504 }
505 case WebXml:
506 case WebDefaults:
507 case WebOverride:
508 {
509
510 if (!(descriptor instanceof FragmentDescriptor))
511 {
512 holder.setAsyncSupported(val);
513 context.getMetaData().setOrigin(name+".servlet.async-supported", descriptor);
514 }
515 break;
516 }
517 case WebFragment:
518 {
519
520 if (holder.isAsyncSupported() != val)
521 throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+name+" in "+descriptor.getResource());
522 break;
523 }
524 default:
525 LOG.warn(new Throwable());
526 }
527 }
528
529 String enabled = node.getString("enabled", false, true);
530 if (enabled!=null)
531 {
532 boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled);
533 switch (context.getMetaData().getOrigin(name+".servlet.enabled"))
534 {
535 case NotSet:
536 {
537
538 holder.setEnabled(is_enabled);
539 context.getMetaData().setOrigin(name+".servlet.enabled", descriptor);
540 break;
541 }
542 case WebXml:
543 case WebDefaults:
544 case WebOverride:
545 {
546
547 if (!(descriptor instanceof FragmentDescriptor))
548 {
549 holder.setEnabled(is_enabled);
550 context.getMetaData().setOrigin(name+".servlet.enabled", descriptor);
551 }
552 break;
553 }
554 case WebFragment:
555 {
556
557 if (holder.isEnabled() != is_enabled)
558 throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+name+" in "+descriptor.getResource());
559 break;
560 }
561 default:
562 LOG.warn(new Throwable());
563 }
564 }
565
566
567
568
569
570
571 XmlParser.Node multipart = node.get("multipart-config");
572 if (multipart != null)
573 {
574 String location = multipart.getString("location", false, true);
575 String maxFile = multipart.getString("max-file-size", false, true);
576 String maxRequest = multipart.getString("max-request-size", false, true);
577 String threshold = multipart.getString("file-size-threshold",false,true);
578 MultipartConfigElement element = new MultipartConfigElement(location,
579 (maxFile==null||"".equals(maxFile)?-1L:Long.parseLong(maxFile)),
580 (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
581 (threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
582
583 switch (context.getMetaData().getOrigin(name+".servlet.multipart-config"))
584 {
585 case NotSet:
586 {
587
588 holder.getRegistration().setMultipartConfig(element);
589 context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor);
590 break;
591 }
592 case WebXml:
593 case WebDefaults:
594 case WebOverride:
595 {
596
597 if (!(descriptor instanceof FragmentDescriptor))
598 {
599 holder.getRegistration().setMultipartConfig(element);
600 context.getMetaData().setOrigin(name+".servlet.multipart-config", descriptor);
601 }
602 break;
603 }
604 case WebFragment:
605 {
606
607 MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig();
608
609 if (cfg.getMaxFileSize() != element.getMaxFileSize())
610 throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+name+" in "+descriptor.getResource());
611 if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
612 throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+name+" in "+descriptor.getResource());
613 if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
614 throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+name+" in "+descriptor.getResource());
615 if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0))
616 || (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0)))
617 throw new IllegalStateException("Conflicting multipart-config location for servlet "+name+" in "+descriptor.getResource());
618 break;
619 }
620 default:
621 LOG.warn(new Throwable());
622 }
623 }
624 }
625
626
627
628
629
630
631
632
633 public void visitServletMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
634 {
635
636
637
638
639
640
641 String servlet_name = node.getString("servlet-name", false, true);
642 switch (context.getMetaData().getOrigin(servlet_name+".servlet.mappings"))
643 {
644 case NotSet:
645 {
646
647 context.getMetaData().setOrigin(servlet_name+".servlet.mappings", descriptor);
648 addServletMapping(servlet_name, node, context, descriptor);
649 break;
650 }
651 case WebDefaults:
652 case WebXml:
653 case WebOverride:
654 {
655
656
657 if (!(descriptor instanceof FragmentDescriptor))
658 {
659 addServletMapping(servlet_name, node, context, descriptor);
660 }
661 break;
662 }
663 case WebFragment:
664 {
665
666 addServletMapping(servlet_name, node, context, descriptor);
667 break;
668 }
669 default:
670 LOG.warn(new Throwable());
671 }
672 }
673
674
675
676
677
678
679
680 public void visitSessionConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
681 {
682 XmlParser.Node tNode = node.get("session-timeout");
683 if (tNode != null)
684 {
685 int timeout = Integer.parseInt(tNode.toString(false, true));
686 context.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout * 60);
687 }
688
689
690
691
692 Iterator<Node> iter = node.iterator("tracking-mode");
693 if (iter.hasNext())
694 {
695 Set<SessionTrackingMode> modes = null;
696 Origin o = context.getMetaData().getOrigin("session.tracking-mode");
697 switch (o)
698 {
699 case NotSet:
700 case WebDefaults:
701 {
702
703 modes = new HashSet<SessionTrackingMode>();
704 context.getMetaData().setOrigin("session.tracking-mode", descriptor);
705 break;
706 }
707 case WebXml:
708 case WebFragment:
709 case WebOverride:
710 {
711
712 if (descriptor instanceof OverrideDescriptor)
713 modes = new HashSet<SessionTrackingMode>();
714 else
715 modes = new HashSet<SessionTrackingMode>(context.getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes());
716 context.getMetaData().setOrigin("session.tracking-mode", descriptor);
717 break;
718 }
719 default:
720 LOG.warn(new Throwable());
721 }
722
723 while (iter.hasNext())
724 {
725 XmlParser.Node mNode = (XmlParser.Node) iter.next();
726 String trackMode = mNode.toString(false, true);
727 modes.add(SessionTrackingMode.valueOf(trackMode));
728 }
729 context.getSessionHandler().getSessionManager().setSessionTrackingModes(modes);
730 }
731
732
733
734
735 XmlParser.Node cookieConfig = node.get("cookie-config");
736 if (cookieConfig != null)
737 {
738
739 String name = cookieConfig.getString("name", false, true);
740 if (name != null)
741 {
742 switch (context.getMetaData().getOrigin("cookie-config.name"))
743 {
744 case NotSet:
745 {
746
747 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
748 context.getMetaData().setOrigin("cookie-config.name", descriptor);
749 break;
750 }
751 case WebXml:
752 case WebDefaults:
753 case WebOverride:
754 {
755
756 if (!(descriptor instanceof FragmentDescriptor))
757 {
758 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
759 context.getMetaData().setOrigin("cookie-config.name", descriptor);
760 }
761 break;
762 }
763 case WebFragment:
764 {
765
766 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getName().equals(name))
767 throw new IllegalStateException("Conflicting cookie-config name "+name+" in "+descriptor.getResource());
768 break;
769 }
770 default:
771 LOG.warn(new Throwable());
772 }
773 }
774
775
776 String domain = cookieConfig.getString("domain", false, true);
777 if (domain != null)
778 {
779 switch (context.getMetaData().getOrigin("cookie-config.domain"))
780 {
781 case NotSet:
782 {
783
784 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
785 context.getMetaData().setOrigin("cookie-config.domain", descriptor);
786 break;
787 }
788 case WebXml:
789 case WebDefaults:
790 case WebOverride:
791 {
792
793 if (!(descriptor instanceof FragmentDescriptor))
794 {
795 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
796 context.getMetaData().setOrigin("cookie-config.domain", descriptor);
797 }
798 break;
799 }
800 case WebFragment:
801 {
802
803 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getDomain().equals(domain))
804 throw new IllegalStateException("Conflicting cookie-config domain "+domain+" in "+descriptor.getResource());
805 break;
806 }
807 default:
808 LOG.warn(new Throwable());
809 }
810 }
811
812
813 String path = cookieConfig.getString("path", false, true);
814 if (path != null)
815 {
816 switch (context.getMetaData().getOrigin("cookie-config.path"))
817 {
818 case NotSet:
819 {
820
821 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
822 context.getMetaData().setOrigin("cookie-config.path", descriptor);
823 break;
824 }
825 case WebXml:
826 case WebDefaults:
827 case WebOverride:
828 {
829
830 if (!(descriptor instanceof FragmentDescriptor))
831 {
832 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
833 context.getMetaData().setOrigin("cookie-config.path", descriptor);
834 }
835 break;
836 }
837 case WebFragment:
838 {
839
840 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getPath().equals(path))
841 throw new IllegalStateException("Conflicting cookie-config path "+path+" in "+descriptor.getResource());
842 break;
843 }
844 default:
845 LOG.warn(new Throwable());
846 }
847 }
848
849
850 String comment = cookieConfig.getString("comment", false, true);
851 if (comment != null)
852 {
853 switch (context.getMetaData().getOrigin("cookie-config.comment"))
854 {
855 case NotSet:
856 {
857
858 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
859 context.getMetaData().setOrigin("cookie-config.comment", descriptor);
860 break;
861 }
862 case WebXml:
863 case WebDefaults:
864 case WebOverride:
865 {
866
867 if (!(descriptor instanceof FragmentDescriptor))
868 {
869 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
870 context.getMetaData().setOrigin("cookie-config.comment", descriptor);
871 }
872 break;
873 }
874 case WebFragment:
875 {
876
877 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getComment().equals(comment))
878 throw new IllegalStateException("Conflicting cookie-config comment "+comment+" in "+descriptor.getResource());
879 break;
880 }
881 default:
882 LOG.warn(new Throwable());
883 }
884 }
885
886
887 tNode = cookieConfig.get("http-only");
888 if (tNode != null)
889 {
890 boolean httpOnly = Boolean.parseBoolean(tNode.toString(false,true));
891 switch (context.getMetaData().getOrigin("cookie-config.http-only"))
892 {
893 case NotSet:
894 {
895
896 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
897 context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
898 break;
899 }
900 case WebXml:
901 case WebDefaults:
902 case WebOverride:
903 {
904
905 if (!(descriptor instanceof FragmentDescriptor))
906 {
907 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
908 context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
909 }
910 break;
911 }
912 case WebFragment:
913 {
914
915 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isHttpOnly() != httpOnly)
916 throw new IllegalStateException("Conflicting cookie-config http-only "+httpOnly+" in "+descriptor.getResource());
917 break;
918 }
919 default:
920 LOG.warn(new Throwable());
921 }
922 }
923
924
925 tNode = cookieConfig.get("secure");
926 if (tNode != null)
927 {
928 boolean secure = Boolean.parseBoolean(tNode.toString(false,true));
929 switch (context.getMetaData().getOrigin("cookie-config.secure"))
930 {
931 case NotSet:
932 {
933
934 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
935 context.getMetaData().setOrigin("cookie-config.secure", descriptor);
936 break;
937 }
938 case WebXml:
939 case WebDefaults:
940 case WebOverride:
941 {
942
943 if (!(descriptor instanceof FragmentDescriptor))
944 {
945 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
946 context.getMetaData().setOrigin("cookie-config.secure", descriptor);
947 }
948 break;
949 }
950 case WebFragment:
951 {
952
953 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isSecure() != secure)
954 throw new IllegalStateException("Conflicting cookie-config secure "+secure+" in "+descriptor.getResource());
955 break;
956 }
957 default:
958 LOG.warn(new Throwable());
959 }
960 }
961
962
963 tNode = cookieConfig.get("max-age");
964 if (tNode != null)
965 {
966 int maxAge = Integer.parseInt(tNode.toString(false,true));
967 switch (context.getMetaData().getOrigin("cookie-config.max-age"))
968 {
969 case NotSet:
970 {
971
972 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
973 context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
974 break;
975 }
976 case WebXml:
977 case WebDefaults:
978 case WebOverride:
979 {
980
981 if (!(descriptor instanceof FragmentDescriptor))
982 {
983 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
984 context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
985 }
986 break;
987 }
988 case WebFragment:
989 {
990
991 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().getMaxAge() != maxAge)
992 throw new IllegalStateException("Conflicting cookie-config max-age "+maxAge+" in "+descriptor.getResource());
993 break;
994 }
995 default:
996 LOG.warn(new Throwable());
997 }
998 }
999 }
1000 }
1001
1002
1003
1004
1005
1006
1007
1008
1009 public void visitMimeMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1010 {
1011 String extension = node.getString("extension", false, true);
1012 if (extension != null && extension.startsWith("."))
1013 extension = extension.substring(1);
1014 String mimeType = node.getString("mime-type", false, true);
1015 if (extension != null)
1016 {
1017 switch (context.getMetaData().getOrigin("extension."+extension))
1018 {
1019 case NotSet:
1020 {
1021
1022 context.getMimeTypes().addMimeMapping(extension, mimeType);
1023 context.getMetaData().setOrigin("extension."+extension, descriptor);
1024 break;
1025 }
1026 case WebXml:
1027 case WebDefaults:
1028 case WebOverride:
1029 {
1030
1031 if (!(descriptor instanceof FragmentDescriptor))
1032 {
1033 context.getMimeTypes().addMimeMapping(extension, mimeType);
1034 context.getMetaData().setOrigin("extension."+extension, descriptor);
1035 }
1036 break;
1037 }
1038 case WebFragment:
1039 {
1040
1041 if (!context.getMimeTypes().getMimeByExtension("."+extension).equals(mimeType))
1042 throw new IllegalStateException("Conflicting mime-type "+mimeType+" for extension "+extension+" in "+descriptor.getResource());
1043 break;
1044 }
1045 default:
1046 LOG.warn(new Throwable());
1047 }
1048 }
1049 }
1050
1051
1052
1053
1054
1055
1056 public void visitWelcomeFileList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1057 {
1058 switch (context.getMetaData().getOrigin("welcome-file-list"))
1059 {
1060 case NotSet:
1061 {
1062 context.getMetaData().setOrigin("welcome-file-list", descriptor);
1063 addWelcomeFiles(context,node);
1064 break;
1065 }
1066 case WebXml:
1067 {
1068
1069 addWelcomeFiles(context,node);
1070 break;
1071 }
1072 case WebDefaults:
1073 {
1074
1075
1076 if (!(descriptor instanceof DefaultsDescriptor) && !(descriptor instanceof OverrideDescriptor) && !(descriptor instanceof FragmentDescriptor))
1077 {
1078 context.setWelcomeFiles(new String[0]);
1079 }
1080 addWelcomeFiles(context,node);
1081 break;
1082 }
1083 case WebOverride:
1084 {
1085
1086 addWelcomeFiles(context,node);
1087 break;
1088 }
1089 case WebFragment:
1090 {
1091
1092 addWelcomeFiles(context,node);
1093 break;
1094 }
1095 default:
1096 LOG.warn(new Throwable());
1097 }
1098 }
1099
1100
1101
1102
1103
1104
1105 public void visitLocaleEncodingList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1106 {
1107 Iterator<XmlParser.Node> iter = node.iterator("locale-encoding-mapping");
1108 while (iter.hasNext())
1109 {
1110 XmlParser.Node mapping = iter.next();
1111 String locale = mapping.getString("locale", false, true);
1112 String encoding = mapping.getString("encoding", false, true);
1113
1114 if (encoding != null)
1115 {
1116 switch (context.getMetaData().getOrigin("locale-encoding."+locale))
1117 {
1118 case NotSet:
1119 {
1120
1121 context.addLocaleEncoding(locale, encoding);
1122 context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
1123 break;
1124 }
1125 case WebXml:
1126 case WebDefaults:
1127 case WebOverride:
1128 {
1129
1130 if (!(descriptor instanceof FragmentDescriptor))
1131 {
1132 context.addLocaleEncoding(locale, encoding);
1133 context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
1134 }
1135 break;
1136 }
1137 case WebFragment:
1138 {
1139
1140 if (!encoding.equals(context.getLocaleEncoding(locale)))
1141 throw new IllegalStateException("Conflicting loacle-encoding mapping for locale "+locale+" in "+descriptor.getResource());
1142 break;
1143 }
1144 default:
1145 LOG.warn(new Throwable());
1146 }
1147 }
1148 }
1149 }
1150
1151
1152
1153
1154
1155
1156 public void visitErrorPage(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1157 {
1158 String error = node.getString("error-code", false, true);
1159 int code=0;
1160 if (error == null || error.length() == 0)
1161 {
1162 error = node.getString("exception-type", false, true);
1163 if (error == null || error.length() == 0)
1164 error = ErrorPageErrorHandler.GLOBAL_ERROR_PAGE;
1165 }
1166 else
1167 code=Integer.valueOf(error);
1168
1169 String location = node.getString("location", false, true);
1170 ErrorPageErrorHandler handler = (ErrorPageErrorHandler)context.getErrorHandler();
1171
1172 switch (context.getMetaData().getOrigin("error."+error))
1173 {
1174 case NotSet:
1175 {
1176
1177 if (code>0)
1178 handler.addErrorPage(code,location);
1179 else
1180 handler.addErrorPage(error,location);
1181 context.getMetaData().setOrigin("error."+error, descriptor);
1182 break;
1183 }
1184 case WebXml:
1185 case WebDefaults:
1186 case WebOverride:
1187 {
1188
1189 if (!(descriptor instanceof FragmentDescriptor))
1190 {
1191 if (descriptor instanceof OverrideDescriptor || descriptor instanceof DefaultsDescriptor)
1192 {
1193 if (code>0)
1194 handler.addErrorPage(code,location);
1195 else
1196 handler.addErrorPage(error,location);
1197 context.getMetaData().setOrigin("error."+error, descriptor);
1198 }
1199 else
1200 throw new IllegalStateException("Duplicate global error-page "+location);
1201 }
1202 break;
1203 }
1204 case WebFragment:
1205 {
1206
1207 if (!handler.getErrorPages().get(error).equals(location))
1208 throw new IllegalStateException("Conflicting error-code or exception-type "+error+" in "+descriptor.getResource());
1209 break;
1210 }
1211 default:
1212 LOG.warn(new Throwable());
1213 }
1214
1215 }
1216
1217
1218
1219
1220
1221 public void addWelcomeFiles(WebAppContext context, XmlParser.Node node)
1222 {
1223 Iterator<XmlParser.Node> iter = node.iterator("welcome-file");
1224 while (iter.hasNext())
1225 {
1226 XmlParser.Node indexNode = (XmlParser.Node) iter.next();
1227 String welcome = indexNode.toString(false, true);
1228
1229
1230 if (welcome != null && welcome.trim().length() > 0)
1231 context.setWelcomeFiles((String[])ArrayUtil.addToArray(context.getWelcomeFiles(),welcome,String.class));
1232 }
1233 }
1234
1235
1236
1237
1238
1239
1240
1241 public ServletMapping addServletMapping (String servletName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
1242 {
1243 ServletMapping mapping = new ServletMapping();
1244 mapping.setServletName(servletName);
1245 mapping.setDefault(descriptor instanceof DefaultsDescriptor);
1246
1247 List<String> paths = new ArrayList<String>();
1248 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1249 while (iter.hasNext())
1250 {
1251 String p = iter.next().toString(false, true);
1252 p = normalizePattern(p);
1253
1254
1255
1256 ListIterator<ServletMapping> listItor = _servletMappings.listIterator();
1257 boolean found = false;
1258 while (listItor.hasNext() && !found)
1259 {
1260 ServletMapping sm = listItor.next();
1261 if (sm.getPathSpecs() != null)
1262 {
1263 for (String ps:sm.getPathSpecs())
1264 {
1265 if (p.equals(ps) && sm.isDefault())
1266 {
1267 if (LOG.isDebugEnabled()) LOG.debug("{} in mapping {} from defaults descriptor is overridden by ",ps,sm,servletName);
1268
1269
1270 String[] updatedPaths = ArrayUtil.removeFromArray(sm.getPathSpecs(), ps);
1271 if (updatedPaths == null || updatedPaths.length == 0)
1272 {
1273 if (LOG.isDebugEnabled()) LOG.debug("Removed mapping {} from defaults descriptor",sm);
1274 listItor.remove();
1275 }
1276 else
1277 {
1278 sm.setPathSpecs(updatedPaths);
1279 if (LOG.isDebugEnabled()) LOG.debug("Removed path {} from mapping {} from defaults descriptor ", p,sm);
1280 }
1281 found = true;
1282 break;
1283 }
1284 }
1285 }
1286 }
1287
1288 paths.add(p);
1289 context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor);
1290 }
1291 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1292 if (LOG.isDebugEnabled()) LOG.debug("Added mapping {} ",mapping);
1293
1294
1295
1296 _servletMappings.add(mapping);
1297 return mapping;
1298 }
1299
1300
1301
1302
1303
1304
1305 public void addFilterMapping (String filterName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
1306 {
1307 FilterMapping mapping = new FilterMapping();
1308 mapping.setFilterName(filterName);
1309
1310 List<String> paths = new ArrayList<String>();
1311 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1312 while (iter.hasNext())
1313 {
1314 String p = iter.next().toString(false, true);
1315 p = normalizePattern(p);
1316 paths.add(p);
1317 context.getMetaData().setOrigin(filterName+".filter.mapping."+p, descriptor);
1318 }
1319 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1320
1321 List<String> names = new ArrayList<String>();
1322 iter = node.iterator("servlet-name");
1323 while (iter.hasNext())
1324 {
1325 String n = ((XmlParser.Node) iter.next()).toString(false, true);
1326 names.add(n);
1327 }
1328 mapping.setServletNames((String[]) names.toArray(new String[names.size()]));
1329
1330
1331 List<DispatcherType> dispatches = new ArrayList<DispatcherType>();
1332 iter=node.iterator("dispatcher");
1333 while(iter.hasNext())
1334 {
1335 String d=((XmlParser.Node)iter.next()).toString(false,true);
1336 dispatches.add(FilterMapping.dispatch(d));
1337 }
1338
1339 if (dispatches.size()>0)
1340 mapping.setDispatcherTypes(EnumSet.copyOf(dispatches));
1341
1342 _filterMappings.add(mapping);
1343 }
1344
1345
1346
1347
1348
1349
1350
1351 public void visitTagLib(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1352 {
1353
1354 String uri = node.getString("taglib-uri", false, true);
1355 String location = node.getString("taglib-location", false, true);
1356
1357 context.setResourceAlias(uri, location);
1358
1359 JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
1360 if (config == null)
1361 {
1362 config = new JspConfig();
1363 context.getServletContext().setJspConfigDescriptor(config);
1364 }
1365
1366 TagLib tl = new TagLib();
1367 tl.setTaglibLocation(location);
1368 tl.setTaglibURI(uri);
1369 config.addTaglibDescriptor(tl);
1370 }
1371
1372
1373
1374
1375
1376
1377 public void visitJspConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1378 {
1379
1380 JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
1381 if (config == null)
1382 {
1383 config = new JspConfig();
1384 context.getServletContext().setJspConfigDescriptor(config);
1385 }
1386
1387
1388 for (int i = 0; i < node.size(); i++)
1389 {
1390 Object o = node.get(i);
1391 if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag()))
1392 visitTagLib(context,descriptor, (XmlParser.Node) o);
1393 }
1394
1395
1396
1397 Iterator<XmlParser.Node> iter = node.iterator("jsp-property-group");
1398 List<String> paths = new ArrayList<String>();
1399 while (iter.hasNext())
1400 {
1401 JspPropertyGroup jpg = new JspPropertyGroup();
1402 config.addJspPropertyGroup(jpg);
1403 XmlParser.Node group = iter.next();
1404
1405
1406 Iterator<XmlParser.Node> iter2 = group.iterator("url-pattern");
1407 while (iter2.hasNext())
1408 {
1409 String url = iter2.next().toString(false, true);
1410 url = normalizePattern(url);
1411 paths.add( url);
1412 jpg.addUrlPattern(url);
1413 }
1414
1415 jpg.setElIgnored(group.getString("el-ignored", false, true));
1416 jpg.setPageEncoding(group.getString("page-encoding", false, true));
1417 jpg.setScriptingInvalid(group.getString("scripting-invalid", false, true));
1418 jpg.setIsXml(group.getString("is-xml", false, true));
1419 jpg.setDeferredSyntaxAllowedAsLiteral(group.getString("deferred-syntax-allowed-as-literal", false, true));
1420 jpg.setTrimDirectiveWhitespaces(group.getString("trim-directive-whitespaces", false, true));
1421 jpg.setDefaultContentType(group.getString("default-content-type", false, true));
1422 jpg.setBuffer(group.getString("buffer", false, true));
1423 jpg.setErrorOnUndeclaredNamespace(group.getString("error-on-undeclared-namespace", false, true));
1424
1425
1426 Iterator<XmlParser.Node> preludes = group.iterator("include-prelude");
1427 while (preludes.hasNext())
1428 {
1429 String prelude = preludes.next().toString(false, true);
1430 jpg.addIncludePrelude(prelude);
1431 }
1432
1433 Iterator<XmlParser.Node> codas = group.iterator("include-coda");
1434 while (codas.hasNext())
1435 {
1436 String coda = codas.next().toString(false, true);
1437 jpg.addIncludeCoda(coda);
1438 }
1439
1440 if (LOG.isDebugEnabled()) LOG.debug(config.toString());
1441 }
1442
1443 if (paths.size() > 0)
1444 {
1445 ServletHandler handler = context.getServletHandler();
1446 ServletHolder jsp_pg_servlet = _servletHolderMap.get(JspPropertyGroupServlet.NAME);
1447 if (jsp_pg_servlet==null)
1448 {
1449 jsp_pg_servlet=new ServletHolder(JspPropertyGroupServlet.NAME,new JspPropertyGroupServlet(context,handler));
1450 _servletHolderMap.put(JspPropertyGroupServlet.NAME,jsp_pg_servlet);
1451 _servletHolders.add(jsp_pg_servlet);
1452 }
1453
1454 ServletMapping mapping = new ServletMapping();
1455 mapping.setServletName(JspPropertyGroupServlet.NAME);
1456 mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
1457 _servletMappings.add(mapping);
1458 }
1459 }
1460
1461
1462
1463
1464
1465
1466 public void visitSecurityConstraint(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1467 {
1468 Constraint scBase = new Constraint();
1469
1470
1471
1472
1473
1474 try
1475 {
1476 XmlParser.Node auths = node.get("auth-constraint");
1477
1478 if (auths != null)
1479 {
1480 scBase.setAuthenticate(true);
1481
1482 Iterator<XmlParser.Node> iter = auths.iterator("role-name");
1483 List<String> roles = new ArrayList<String>();
1484 while (iter.hasNext())
1485 {
1486 String role = iter.next().toString(false, true);
1487 roles.add(role);
1488 }
1489 scBase.setRoles(roles.toArray(new String[roles.size()]));
1490 }
1491
1492 XmlParser.Node data = node.get("user-data-constraint");
1493 if (data != null)
1494 {
1495 data = data.get("transport-guarantee");
1496 String guarantee = data.toString(false, true).toUpperCase(Locale.ENGLISH);
1497 if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
1498 scBase.setDataConstraint(Constraint.DC_NONE);
1499 else if ("INTEGRAL".equals(guarantee))
1500 scBase.setDataConstraint(Constraint.DC_INTEGRAL);
1501 else if ("CONFIDENTIAL".equals(guarantee))
1502 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
1503 else
1504 {
1505 LOG.warn("Unknown user-data-constraint:" + guarantee);
1506 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
1507 }
1508 }
1509 Iterator<XmlParser.Node> iter = node.iterator("web-resource-collection");
1510 while (iter.hasNext())
1511 {
1512 XmlParser.Node collection = iter.next();
1513 String name = collection.getString("web-resource-name", false, true);
1514 Constraint sc = (Constraint) scBase.clone();
1515 sc.setName(name);
1516
1517 Iterator<XmlParser.Node> iter2 = collection.iterator("url-pattern");
1518 while (iter2.hasNext())
1519 {
1520 String url = iter2.next().toString(false, true);
1521 url = normalizePattern(url);
1522
1523 context.getMetaData().setOrigin("constraint.url."+url, descriptor);
1524
1525 Iterator<XmlParser.Node> methods = collection.iterator("http-method");
1526 Iterator<XmlParser.Node> ommissions = collection.iterator("http-method-omission");
1527
1528 if (methods.hasNext())
1529 {
1530 if (ommissions.hasNext())
1531 throw new IllegalStateException ("web-resource-collection cannot contain both http-method and http-method-omission");
1532
1533
1534 while (methods.hasNext())
1535 {
1536 String method = ((XmlParser.Node) methods.next()).toString(false, true);
1537 ConstraintMapping mapping = new ConstraintMapping();
1538 mapping.setMethod(method);
1539 mapping.setPathSpec(url);
1540 mapping.setConstraint(sc);
1541 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1542 }
1543 }
1544 else if (ommissions.hasNext())
1545 {
1546
1547
1548 while (ommissions.hasNext())
1549 {
1550 String method = ((XmlParser.Node)ommissions.next()).toString(false, true);
1551 ConstraintMapping mapping = new ConstraintMapping();
1552 mapping.setMethodOmissions(new String[]{method});
1553 mapping.setPathSpec(url);
1554 mapping.setConstraint(sc);
1555 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1556 }
1557 }
1558 else
1559 {
1560
1561 ConstraintMapping mapping = new ConstraintMapping();
1562 mapping.setPathSpec(url);
1563 mapping.setConstraint(sc);
1564 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1565 }
1566 }
1567 }
1568 }
1569 catch (CloneNotSupportedException e)
1570 {
1571 LOG.warn(e);
1572 }
1573 }
1574
1575
1576
1577
1578
1579
1580
1581 public void visitLoginConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception
1582 {
1583
1584
1585
1586 XmlParser.Node method = node.get("auth-method");
1587 if (method != null)
1588 {
1589
1590 switch (context.getMetaData().getOrigin("auth-method"))
1591 {
1592 case NotSet:
1593 {
1594
1595 context.getSecurityHandler().setAuthMethod(method.toString(false, true));
1596 context.getMetaData().setOrigin("auth-method", descriptor);
1597 break;
1598 }
1599 case WebXml:
1600 case WebDefaults:
1601 case WebOverride:
1602 {
1603
1604 if (!(descriptor instanceof FragmentDescriptor))
1605 {
1606 context.getSecurityHandler().setAuthMethod(method.toString(false, true));
1607 context.getMetaData().setOrigin("auth-method", descriptor);
1608 }
1609 break;
1610 }
1611 case WebFragment:
1612 {
1613
1614 if (!context.getSecurityHandler().getAuthMethod().equals(method.toString(false, true)))
1615 throw new IllegalStateException("Conflicting auth-method value in "+descriptor.getResource());
1616 break;
1617 }
1618 default:
1619 LOG.warn(new Throwable());
1620 }
1621
1622
1623 XmlParser.Node name = node.get("realm-name");
1624 String nameStr = (name == null ? "default" : name.toString(false, true));
1625 switch (context.getMetaData().getOrigin("realm-name"))
1626 {
1627 case NotSet:
1628 {
1629
1630 context.getSecurityHandler().setRealmName(nameStr);
1631 context.getMetaData().setOrigin("realm-name", descriptor);
1632 break;
1633 }
1634 case WebXml:
1635 case WebDefaults:
1636 case WebOverride:
1637 {
1638
1639 if (!(descriptor instanceof FragmentDescriptor))
1640 {
1641 context.getSecurityHandler().setRealmName(nameStr);
1642 context.getMetaData().setOrigin("realm-name", descriptor);
1643 }
1644 break;
1645 }
1646 case WebFragment:
1647 {
1648
1649 if (!context.getSecurityHandler().getRealmName().equals(nameStr))
1650 throw new IllegalStateException("Conflicting realm-name value in "+descriptor.getResource());
1651 break;
1652 }
1653 default:
1654 LOG.warn(new Throwable());
1655 }
1656
1657 if (Constraint.__FORM_AUTH.equalsIgnoreCase(context.getSecurityHandler().getAuthMethod()))
1658 {
1659 XmlParser.Node formConfig = node.get("form-login-config");
1660 if (formConfig != null)
1661 {
1662 String loginPageName = null;
1663 XmlParser.Node loginPage = formConfig.get("form-login-page");
1664 if (loginPage != null)
1665 loginPageName = loginPage.toString(false, true);
1666 String errorPageName = null;
1667 XmlParser.Node errorPage = formConfig.get("form-error-page");
1668 if (errorPage != null)
1669 errorPageName = errorPage.toString(false, true);
1670
1671
1672 switch (context.getMetaData().getOrigin("form-login-page"))
1673 {
1674 case NotSet:
1675 {
1676
1677 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
1678 context.getMetaData().setOrigin("form-login-page",descriptor);
1679 break;
1680 }
1681 case WebXml:
1682 case WebDefaults:
1683 case WebOverride:
1684 {
1685
1686 if (!(descriptor instanceof FragmentDescriptor))
1687 {
1688 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
1689 context.getMetaData().setOrigin("form-login-page",descriptor);
1690 }
1691 break;
1692 }
1693 case WebFragment:
1694 {
1695
1696 if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE).equals(loginPageName))
1697 throw new IllegalStateException("Conflicting form-login-page value in "+descriptor.getResource());
1698 break;
1699 }
1700 default:
1701 LOG.warn(new Throwable());
1702 }
1703
1704
1705 switch (context.getMetaData().getOrigin("form-error-page"))
1706 {
1707 case NotSet:
1708 {
1709
1710 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
1711 context.getMetaData().setOrigin("form-error-page",descriptor);
1712 break;
1713 }
1714 case WebXml:
1715 case WebDefaults:
1716 case WebOverride:
1717 {
1718
1719 if (!(descriptor instanceof FragmentDescriptor))
1720 {
1721 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
1722 context.getMetaData().setOrigin("form-error-page",descriptor);
1723 }
1724 break;
1725 }
1726 case WebFragment:
1727 {
1728
1729 if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE).equals(errorPageName))
1730 throw new IllegalStateException("Conflicting form-error-page value in "+descriptor.getResource());
1731 break;
1732 }
1733 default:
1734 LOG.warn(new Throwable());
1735 }
1736 }
1737 else
1738 {
1739 throw new IllegalStateException("!form-login-config");
1740 }
1741 }
1742 }
1743 }
1744
1745
1746
1747
1748
1749
1750 public void visitSecurityRole(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1751 {
1752
1753 XmlParser.Node roleNode = node.get("role-name");
1754 String role = roleNode.toString(false, true);
1755 ((ConstraintAware)context.getSecurityHandler()).addRole(role);
1756 }
1757
1758
1759
1760
1761
1762
1763
1764 public void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1765 {
1766 String name = node.getString("filter-name", false, true);
1767 FilterHolder holder = _filterHolderMap.get(name);
1768 if (holder == null)
1769 {
1770 holder = context.getServletHandler().newFilterHolder(Source.DESCRIPTOR);
1771 holder.setName(name);
1772 _filterHolderMap.put(name,holder);
1773 _filterHolders.add(holder);
1774 }
1775
1776 String filter_class = node.getString("filter-class", false, true);
1777 if (filter_class != null)
1778 {
1779 ((WebDescriptor)descriptor).addClassName(filter_class);
1780
1781 switch (context.getMetaData().getOrigin(name+".filter.filter-class"))
1782 {
1783 case NotSet:
1784 {
1785
1786 holder.setClassName(filter_class);
1787 context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
1788 break;
1789 }
1790 case WebXml:
1791 case WebDefaults:
1792 case WebOverride:
1793 {
1794
1795 if (!(descriptor instanceof FragmentDescriptor))
1796 {
1797 holder.setClassName(filter_class);
1798 context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
1799 }
1800 break;
1801 }
1802 case WebFragment:
1803 {
1804
1805 if (!holder.getClassName().equals(filter_class))
1806 throw new IllegalStateException("Conflicting filter-class for filter "+name+" in "+descriptor.getResource());
1807 break;
1808 }
1809 default:
1810 LOG.warn(new Throwable());
1811 }
1812 }
1813
1814 Iterator<XmlParser.Node> iter = node.iterator("init-param");
1815 while (iter.hasNext())
1816 {
1817 XmlParser.Node paramNode = iter.next();
1818 String pname = paramNode.getString("param-name", false, true);
1819 String pvalue = paramNode.getString("param-value", false, true);
1820
1821 switch (context.getMetaData().getOrigin(name+".filter.init-param."+pname))
1822 {
1823 case NotSet:
1824 {
1825
1826 holder.setInitParameter(pname, pvalue);
1827 context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
1828 break;
1829 }
1830 case WebXml:
1831 case WebDefaults:
1832 case WebOverride:
1833 {
1834
1835
1836 if (!(descriptor instanceof FragmentDescriptor))
1837 {
1838 holder.setInitParameter(pname, pvalue);
1839 context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
1840 }
1841 break;
1842 }
1843 case WebFragment:
1844 {
1845
1846 if (!holder.getInitParameter(pname).equals(pvalue))
1847 throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
1848 break;
1849 }
1850 default:
1851 LOG.warn(new Throwable());
1852 }
1853 }
1854
1855 String async=node.getString("async-supported",false,true);
1856 if (async!=null)
1857 holder.setAsyncSupported(async.length()==0||Boolean.valueOf(async));
1858 if (async!=null)
1859 {
1860 boolean val = async.length()==0||Boolean.valueOf(async);
1861 switch (context.getMetaData().getOrigin(name+".filter.async-supported"))
1862 {
1863 case NotSet:
1864 {
1865
1866 holder.setAsyncSupported(val);
1867 context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
1868 break;
1869 }
1870 case WebXml:
1871 case WebDefaults:
1872 case WebOverride:
1873 {
1874
1875 if (!(descriptor instanceof FragmentDescriptor))
1876 {
1877 holder.setAsyncSupported(val);
1878 context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
1879 }
1880 break;
1881 }
1882 case WebFragment:
1883 {
1884
1885 if (holder.isAsyncSupported() != val)
1886 throw new IllegalStateException("Conflicting async-supported="+async+" for filter "+name+" in "+descriptor.getResource());
1887 break;
1888 }
1889 default:
1890 LOG.warn(new Throwable());
1891 }
1892 }
1893 }
1894
1895
1896
1897
1898
1899
1900 public void visitFilterMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1901 {
1902
1903
1904
1905
1906 String filter_name = node.getString("filter-name", false, true);
1907 switch (context.getMetaData().getOrigin(filter_name+".filter.mappings"))
1908 {
1909 case NotSet:
1910 {
1911
1912 context.getMetaData().setOrigin(filter_name+".filter.mappings", descriptor);
1913 addFilterMapping(filter_name, node, context, descriptor);
1914 break;
1915 }
1916 case WebDefaults:
1917 case WebOverride:
1918 case WebXml:
1919 {
1920
1921 if (!(descriptor instanceof FragmentDescriptor))
1922 {
1923 addFilterMapping(filter_name, node, context, descriptor);
1924 }
1925 break;
1926 }
1927 case WebFragment:
1928 {
1929
1930 addFilterMapping(filter_name, node, context, descriptor);
1931 break;
1932 }
1933 default:
1934 LOG.warn(new Throwable());
1935 }
1936 }
1937
1938
1939
1940
1941
1942
1943
1944 public void visitListener(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1945 {
1946 String className = node.getString("listener-class", false, true);
1947 EventListener listener = null;
1948 try
1949 {
1950 if (className != null && className.length()> 0)
1951 {
1952
1953
1954 EventListener[] listeners=context.getEventListeners();
1955 if (listeners!=null)
1956 {
1957 for (EventListener l : listeners)
1958 {
1959 if (l.getClass().getName().equals(className))
1960 return;
1961 }
1962 }
1963
1964 ((WebDescriptor)descriptor).addClassName(className);
1965
1966 Class<? extends EventListener> listenerClass = (Class<? extends EventListener>)context.loadClass(className);
1967 listener = newListenerInstance(context,listenerClass);
1968 if (!(listener instanceof EventListener))
1969 {
1970 LOG.warn("Not an EventListener: " + listener);
1971 return;
1972 }
1973 context.addEventListener(listener);
1974 context.getMetaData().setOrigin(className+".listener", descriptor);
1975
1976 }
1977 }
1978 catch (Exception e)
1979 {
1980 LOG.warn("Could not instantiate listener " + className, e);
1981 return;
1982 }
1983 }
1984
1985
1986
1987
1988
1989
1990 public void visitDistributable(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1991 {
1992
1993
1994
1995 ((WebDescriptor)descriptor).setDistributable(true);
1996 }
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008 public void visitDenyUncoveredHttpMethods(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
2009 {
2010 ((ConstraintAware)context.getSecurityHandler()).setDenyUncoveredHttpMethods(true);
2011 }
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021 public EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws Exception
2022 {
2023 ListenerHolder h = context.getServletHandler().newListenerHolder(Source.DESCRIPTOR);
2024 EventListener l = context.getServletContext().createInstance(clazz);
2025 h.setListener(l);
2026 context.getServletHandler().addListener(h);
2027 return l;
2028
2029 }
2030
2031
2032
2033
2034
2035 public String normalizePattern(String p)
2036 {
2037 if (p != null && p.length() > 0 && !p.startsWith("/") && !p.startsWith("*")) return "/" + p;
2038 return p;
2039 }
2040
2041
2042 }