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