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