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