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