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