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.JspPropertyGroupServlet;
45 import org.eclipse.jetty.servlet.ServletContextHandler;
46 import org.eclipse.jetty.servlet.ServletHandler;
47 import org.eclipse.jetty.servlet.ServletContextHandler.JspConfig;
48 import org.eclipse.jetty.servlet.ServletContextHandler.JspPropertyGroup;
49 import org.eclipse.jetty.servlet.ServletContextHandler.TagLib;
50 import org.eclipse.jetty.servlet.ServletHolder;
51 import org.eclipse.jetty.servlet.ServletMapping;
52 import org.eclipse.jetty.util.ArrayUtil;
53 import org.eclipse.jetty.util.Loader;
54 import org.eclipse.jetty.util.log.Log;
55 import org.eclipse.jetty.util.log.Logger;
56 import org.eclipse.jetty.util.security.Constraint;
57 import org.eclipse.jetty.xml.XmlParser;
58
59
60
61
62
63
64 public class StandardDescriptorProcessor extends IterativeDescriptorProcessor
65 {
66 private static final Logger LOG = Log.getLogger(StandardDescriptorProcessor.class);
67
68 public static final String STANDARD_PROCESSOR = "org.eclipse.jetty.standardDescriptorProcessor";
69
70
71
72 public StandardDescriptorProcessor ()
73 {
74
75 try
76 {
77 registerVisitor("context-param", this.getClass().getDeclaredMethod("visitContextParam", __signature));
78 registerVisitor("display-name", this.getClass().getDeclaredMethod("visitDisplayName", __signature));
79 registerVisitor("servlet", this.getClass().getDeclaredMethod("visitServlet", __signature));
80 registerVisitor("servlet-mapping", this.getClass().getDeclaredMethod("visitServletMapping", __signature));
81 registerVisitor("session-config", this.getClass().getDeclaredMethod("visitSessionConfig", __signature));
82 registerVisitor("mime-mapping", this.getClass().getDeclaredMethod("visitMimeMapping", __signature));
83 registerVisitor("welcome-file-list", this.getClass().getDeclaredMethod("visitWelcomeFileList", __signature));
84 registerVisitor("locale-encoding-mapping-list", this.getClass().getDeclaredMethod("visitLocaleEncodingList", __signature));
85 registerVisitor("error-page", this.getClass().getDeclaredMethod("visitErrorPage", __signature));
86 registerVisitor("taglib", this.getClass().getDeclaredMethod("visitTagLib", __signature));
87 registerVisitor("jsp-config", this.getClass().getDeclaredMethod("visitJspConfig", __signature));
88 registerVisitor("security-constraint", this.getClass().getDeclaredMethod("visitSecurityConstraint", __signature));
89 registerVisitor("login-config", this.getClass().getDeclaredMethod("visitLoginConfig", __signature));
90 registerVisitor("security-role", this.getClass().getDeclaredMethod("visitSecurityRole", __signature));
91 registerVisitor("filter", this.getClass().getDeclaredMethod("visitFilter", __signature));
92 registerVisitor("filter-mapping", this.getClass().getDeclaredMethod("visitFilterMapping", __signature));
93 registerVisitor("listener", this.getClass().getDeclaredMethod("visitListener", __signature));
94 registerVisitor("distributable", this.getClass().getDeclaredMethod("visitDistributable", __signature));
95 }
96 catch (Exception e)
97 {
98 throw new IllegalStateException(e);
99 }
100 }
101
102
103
104
105
106
107 public void start(WebAppContext context, Descriptor descriptor)
108 {
109 }
110
111
112
113
114
115
116 public void end(WebAppContext context, Descriptor descriptor)
117 {
118 }
119
120
121
122
123
124
125 public void visitContextParam (WebAppContext context, Descriptor descriptor, XmlParser.Node node)
126 {
127 String name = node.getString("param-name", false, true);
128 String value = node.getString("param-value", false, true);
129 Origin o = context.getMetaData().getOrigin("context-param."+name);
130 switch (o)
131 {
132 case NotSet:
133 {
134
135 context.getInitParams().put(name, value);
136 context.getMetaData().setOrigin("context-param."+name, descriptor);
137 break;
138 }
139 case WebXml:
140 case WebDefaults:
141 case WebOverride:
142 {
143
144 if (!(descriptor instanceof FragmentDescriptor))
145 {
146 context.getInitParams().put(name, value);
147 context.getMetaData().setOrigin("context-param."+name, descriptor);
148 }
149 break;
150 }
151 case WebFragment:
152 {
153
154 if (descriptor instanceof FragmentDescriptor)
155 {
156 if (!((String)context.getInitParams().get(name)).equals(value))
157 throw new IllegalStateException("Conflicting context-param "+name+"="+value+" in "+descriptor.getResource());
158 }
159 break;
160 }
161 }
162 if (LOG.isDebugEnabled())
163 LOG.debug("ContextParam: " + name + "=" + value);
164
165 }
166
167
168
169
170
171
172
173
174 protected void visitDisplayName(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
175 {
176
177 if (!(descriptor instanceof FragmentDescriptor))
178 {
179 context.setDisplayName(node.toString(false, true));
180 context.getMetaData().setOrigin("display-name", descriptor);
181 }
182 }
183
184
185
186
187
188
189
190 protected void visitServlet(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
191 {
192 String id = node.getAttribute("id");
193
194
195 String servlet_name = node.getString("servlet-name", false, true);
196 ServletHolder holder = context.getServletHandler().getServlet(servlet_name);
197
198
199
200
201 if (holder == null)
202 {
203 holder = context.getServletHandler().newServletHolder(Holder.Source.DESCRIPTOR);
204 holder.setName(servlet_name);
205 context.getServletHandler().addServlet(holder);
206 }
207
208
209 Iterator<?> iParamsIter = node.iterator("init-param");
210 while (iParamsIter.hasNext())
211 {
212 XmlParser.Node paramNode = (XmlParser.Node) iParamsIter.next();
213 String pname = paramNode.getString("param-name", false, true);
214 String pvalue = paramNode.getString("param-value", false, true);
215
216 Origin origin = context.getMetaData().getOrigin(servlet_name+".servlet.init-param."+pname);
217
218 switch (origin)
219 {
220 case NotSet:
221 {
222
223
224 holder.setInitParameter(pname, pvalue);
225 context.getMetaData().setOrigin(servlet_name+".servlet.init-param."+pname, descriptor);
226 break;
227 }
228 case WebXml:
229 case WebDefaults:
230 case WebOverride:
231 {
232
233
234 if (!(descriptor instanceof FragmentDescriptor))
235 {
236 holder.setInitParameter(pname, pvalue);
237 context.getMetaData().setOrigin(servlet_name+".servlet.init-param."+pname, descriptor);
238 }
239 break;
240 }
241 case WebFragment:
242 {
243
244 if (!holder.getInitParameter(pname).equals(pvalue))
245 throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
246 break;
247 }
248 }
249 }
250
251 String servlet_class = node.getString("servlet-class", false, true);
252
253
254 String jspServletClass=null;
255
256
257 if (id != null && id.equals("jsp"))
258 {
259 jspServletClass = servlet_class;
260 try
261 {
262 Loader.loadClass(this.getClass(), servlet_class);
263
264
265 if (holder.getInitParameter("scratchdir") == null)
266 {
267 File tmp = context.getTempDirectory();
268 File scratch = new File(tmp, "jsp");
269 if (!scratch.exists()) scratch.mkdir();
270 holder.setInitParameter("scratchdir", scratch.getAbsolutePath());
271 }
272 }
273 catch (ClassNotFoundException e)
274 {
275 LOG.info("NO JSP Support for {}, did not find {}", context.getContextPath(), servlet_class);
276 jspServletClass = servlet_class = "org.eclipse.jetty.servlet.NoJspServlet";
277 }
278 }
279
280
281
282 if (servlet_class != null)
283 {
284 ((WebDescriptor)descriptor).addClassName(servlet_class);
285
286 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.servlet-class");
287 switch (o)
288 {
289 case NotSet:
290 {
291
292 holder.setClassName(servlet_class);
293 context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor);
294 break;
295 }
296 case WebXml:
297 case WebDefaults:
298 case WebOverride:
299 {
300
301 if (!(descriptor instanceof FragmentDescriptor))
302 {
303 holder.setClassName(servlet_class);
304 context.getMetaData().setOrigin(servlet_name+".servlet.servlet-class", descriptor);
305 }
306 break;
307 }
308 case WebFragment:
309 {
310
311 if (!servlet_class.equals(holder.getClassName()))
312 throw new IllegalStateException("Conflicting servlet-class "+servlet_class+" in "+descriptor.getResource());
313 break;
314 }
315 }
316 }
317
318
319 String jsp_file = node.getString("jsp-file", false, true);
320 if (jsp_file != null)
321 {
322 holder.setForcedPath(jsp_file);
323 ServletHolder jsp=context.getServletHandler().getServlet("jsp");
324 if (jsp!=null)
325 holder.setClassName(jsp.getClassName());
326 }
327
328
329 XmlParser.Node startup = node.get("load-on-startup");
330 if (startup != null)
331 {
332 String s = startup.toString(false, true).toLowerCase(Locale.ENGLISH);
333 int order = 0;
334 if (s.startsWith("t"))
335 {
336 LOG.warn("Deprecated boolean load-on-startup. Please use integer");
337 order = 1;
338 }
339 else
340 {
341 try
342 {
343 if (s != null && s.trim().length() > 0) order = Integer.parseInt(s);
344 }
345 catch (Exception e)
346 {
347 LOG.warn("Cannot parse load-on-startup " + s + ". Please use integer");
348 LOG.ignore(e);
349 }
350 }
351
352 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.load-on-startup");
353 switch (o)
354 {
355 case NotSet:
356 {
357
358 holder.setInitOrder(order);
359 context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
360 break;
361 }
362 case WebXml:
363 case WebDefaults:
364 case WebOverride:
365 {
366
367 if (!(descriptor instanceof FragmentDescriptor))
368 {
369 holder.setInitOrder(order);
370 context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
371 }
372 break;
373 }
374 case WebFragment:
375 {
376
377 if (order != holder.getInitOrder())
378 throw new IllegalStateException("Conflicting load-on-startup value in "+descriptor.getResource());
379 break;
380 }
381 }
382 }
383
384 Iterator sRefsIter = node.iterator("security-role-ref");
385 while (sRefsIter.hasNext())
386 {
387 XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
388 String roleName = securityRef.getString("role-name", false, true);
389 String roleLink = securityRef.getString("role-link", false, true);
390 if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
391 {
392 if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this);
393 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.role-name."+roleName);
394 switch (o)
395 {
396 case NotSet:
397 {
398
399 holder.setUserRoleLink(roleName, roleLink);
400 context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
401 break;
402 }
403 case WebXml:
404 case WebDefaults:
405 case WebOverride:
406 {
407
408 if (!(descriptor instanceof FragmentDescriptor))
409 {
410 holder.setUserRoleLink(roleName, roleLink);
411 context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
412 }
413 break;
414 }
415 case WebFragment:
416 {
417 if (!holder.getUserRoleLink(roleName).equals(roleLink))
418 throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource());
419 break;
420 }
421 }
422 }
423 else
424 {
425 LOG.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + holder.getName() + ", " + securityRef);
426 }
427 }
428
429
430 XmlParser.Node run_as = node.get("run-as");
431 if (run_as != null)
432 {
433 String roleName = run_as.getString("role-name", false, true);
434
435 if (roleName != null)
436 {
437 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.run-as");
438 switch (o)
439 {
440 case NotSet:
441 {
442
443 holder.setRunAsRole(roleName);
444 context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor);
445 break;
446 }
447 case WebXml:
448 case WebDefaults:
449 case WebOverride:
450 {
451
452 if (!(descriptor instanceof FragmentDescriptor))
453 {
454 holder.setRunAsRole(roleName);
455 context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor);
456 }
457 break;
458 }
459 case WebFragment:
460 {
461
462 if (!holder.getRunAsRole().equals(roleName))
463 throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource());
464 break;
465 }
466 }
467 }
468 }
469
470 String async=node.getString("async-supported",false,true);
471 if (async!=null)
472 {
473 boolean val = async.length()==0||Boolean.valueOf(async);
474 Origin o =context.getMetaData().getOrigin(servlet_name+".servlet.async-supported");
475 switch (o)
476 {
477 case NotSet:
478 {
479
480 holder.setAsyncSupported(val);
481 context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor);
482 break;
483 }
484 case WebXml:
485 case WebDefaults:
486 case WebOverride:
487 {
488
489 if (!(descriptor instanceof FragmentDescriptor))
490 {
491 holder.setAsyncSupported(val);
492 context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor);
493 }
494 break;
495 }
496 case WebFragment:
497 {
498
499 if (holder.isAsyncSupported() != val)
500 throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+servlet_name+" in "+descriptor.getResource());
501 break;
502 }
503 }
504 }
505
506 String enabled = node.getString("enabled", false, true);
507 if (enabled!=null)
508 {
509 boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled);
510 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.enabled");
511 switch (o)
512 {
513 case NotSet:
514 {
515
516 holder.setEnabled(is_enabled);
517 context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor);
518 break;
519 }
520 case WebXml:
521 case WebDefaults:
522 case WebOverride:
523 {
524
525 if (!(descriptor instanceof FragmentDescriptor))
526 {
527 holder.setEnabled(is_enabled);
528 context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor);
529 }
530 break;
531 }
532 case WebFragment:
533 {
534
535 if (holder.isEnabled() != is_enabled)
536 throw new IllegalStateException("Conflicting value of servlet enabled for servlet "+servlet_name+" in "+descriptor.getResource());
537 break;
538 }
539 }
540 }
541
542
543
544
545
546
547 XmlParser.Node multipart = node.get("multipart-config");
548 if (multipart != null)
549 {
550 String location = multipart.getString("location", false, true);
551 String maxFile = multipart.getString("max-file-size", false, true);
552 String maxRequest = multipart.getString("max-request-size", false, true);
553 String threshold = multipart.getString("file-size-threshold",false,true);
554 MultipartConfigElement element = new MultipartConfigElement(location,
555 (maxFile==null||"".equals(maxFile)?-1L:Long.parseLong(maxFile)),
556 (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
557 (threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
558
559 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.multipart-config");
560 switch (o)
561 {
562 case NotSet:
563 {
564
565 holder.getRegistration().setMultipartConfig(element);
566 context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor);
567 break;
568 }
569 case WebXml:
570 case WebDefaults:
571 case WebOverride:
572 {
573
574 if (!(descriptor instanceof FragmentDescriptor))
575 {
576 holder.getRegistration().setMultipartConfig(element);
577 context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor);
578 }
579 break;
580 }
581 case WebFragment:
582 {
583
584 MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig();
585
586 if (cfg.getMaxFileSize() != element.getMaxFileSize())
587 throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+servlet_name+" in "+descriptor.getResource());
588 if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
589 throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+servlet_name+" in "+descriptor.getResource());
590 if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
591 throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+servlet_name+" in "+descriptor.getResource());
592 if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0))
593 || (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0)))
594 throw new IllegalStateException("Conflicting multipart-config location for servlet "+servlet_name+" in "+descriptor.getResource());
595 break;
596 }
597 }
598 }
599 }
600
601
602
603
604
605
606
607
608 protected void visitServletMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
609 {
610
611
612
613
614
615
616 String servlet_name = node.getString("servlet-name", false, true);
617 Origin origin = context.getMetaData().getOrigin(servlet_name+".servlet.mappings");
618
619 switch (origin)
620 {
621 case NotSet:
622 {
623
624 context.getMetaData().setOrigin(servlet_name+".servlet.mappings", descriptor);
625 ServletMapping mapping = addServletMapping(servlet_name, node, context, descriptor);
626 mapping.setDefault(context.getMetaData().getOrigin(servlet_name+".servlet.mappings") == Origin.WebDefaults);
627 break;
628 }
629 case WebXml:
630 case WebDefaults:
631 case WebOverride:
632 {
633
634
635 if (!(descriptor instanceof FragmentDescriptor))
636 {
637 addServletMapping(servlet_name, node, context, descriptor);
638 }
639 break;
640 }
641 case WebFragment:
642 {
643
644 addServletMapping(servlet_name, node, context, descriptor);
645 break;
646 }
647 }
648 }
649
650
651
652
653
654
655
656 protected void visitSessionConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
657 {
658 XmlParser.Node tNode = node.get("session-timeout");
659 if (tNode != null)
660 {
661 int timeout = Integer.parseInt(tNode.toString(false, true));
662 context.getSessionHandler().getSessionManager().setMaxInactiveInterval(timeout * 60);
663 }
664
665
666
667
668 Iterator iter = node.iterator("tracking-mode");
669 Set<SessionTrackingMode> modes = new HashSet<SessionTrackingMode>();
670 modes.addAll(context.getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes());
671 while (iter.hasNext())
672 {
673 XmlParser.Node mNode = (XmlParser.Node) iter.next();
674 String trackMode = mNode.toString(false, true);
675 modes.add(SessionTrackingMode.valueOf(trackMode));
676 }
677 context.getSessionHandler().getSessionManager().setSessionTrackingModes(modes);
678
679
680
681
682 XmlParser.Node cookieConfig = node.get("cookie-config");
683 if (cookieConfig != null)
684 {
685
686 String name = cookieConfig.getString("name", false, true);
687 if (name != null)
688 {
689 Origin o = context.getMetaData().getOrigin("cookie-config.name");
690 switch (o)
691 {
692 case NotSet:
693 {
694
695 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
696 context.getMetaData().setOrigin("cookie-config.name", descriptor);
697 break;
698 }
699 case WebXml:
700 case WebDefaults:
701 case WebOverride:
702 {
703
704 if (!(descriptor instanceof FragmentDescriptor))
705 {
706 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setName(name);
707 context.getMetaData().setOrigin("cookie-config.name", descriptor);
708 }
709 break;
710 }
711 case WebFragment:
712 {
713
714 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getName().equals(name))
715 throw new IllegalStateException("Conflicting cookie-config name "+name+" in "+descriptor.getResource());
716 break;
717 }
718 }
719 }
720
721
722 String domain = cookieConfig.getString("domain", false, true);
723 if (domain != null)
724 {
725 Origin o = context.getMetaData().getOrigin("cookie-config.domain");
726 switch (o)
727 {
728 case NotSet:
729 {
730
731 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
732 context.getMetaData().setOrigin("cookie-config.domain", descriptor);
733 break;
734 }
735 case WebXml:
736 case WebDefaults:
737 case WebOverride:
738 {
739
740 if (!(descriptor instanceof FragmentDescriptor))
741 {
742 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setDomain(domain);
743 context.getMetaData().setOrigin("cookie-config.domain", descriptor);
744 }
745 break;
746 }
747 case WebFragment:
748 {
749
750 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getDomain().equals(domain))
751 throw new IllegalStateException("Conflicting cookie-config domain "+domain+" in "+descriptor.getResource());
752 break;
753 }
754 }
755 }
756
757
758 String path = cookieConfig.getString("path", false, true);
759 if (path != null)
760 {
761 Origin o = context.getMetaData().getOrigin("cookie-config.path");
762 switch (o)
763 {
764 case NotSet:
765 {
766
767 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
768 context.getMetaData().setOrigin("cookie-config.path", descriptor);
769 break;
770 }
771 case WebXml:
772 case WebDefaults:
773 case WebOverride:
774 {
775
776 if (!(descriptor instanceof FragmentDescriptor))
777 {
778 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setPath(path);
779 context.getMetaData().setOrigin("cookie-config.path", descriptor);
780 }
781 break;
782 }
783 case WebFragment:
784 {
785
786 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getPath().equals(path))
787 throw new IllegalStateException("Conflicting cookie-config path "+path+" in "+descriptor.getResource());
788 break;
789 }
790 }
791 }
792
793
794 String comment = cookieConfig.getString("comment", false, true);
795 if (comment != null)
796 {
797 Origin o = context.getMetaData().getOrigin("cookie-config.comment");
798 switch (o)
799 {
800 case NotSet:
801 {
802
803 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
804 context.getMetaData().setOrigin("cookie-config.comment", descriptor);
805 break;
806 }
807 case WebXml:
808 case WebDefaults:
809 case WebOverride:
810 {
811
812 if (!(descriptor instanceof FragmentDescriptor))
813 {
814 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setComment(comment);
815 context.getMetaData().setOrigin("cookie-config.comment", descriptor);
816 }
817 break;
818 }
819 case WebFragment:
820 {
821
822 if (!context.getSessionHandler().getSessionManager().getSessionCookieConfig().getComment().equals(comment))
823 throw new IllegalStateException("Conflicting cookie-config comment "+comment+" in "+descriptor.getResource());
824 break;
825 }
826 }
827 }
828
829
830 tNode = cookieConfig.get("http-only");
831 if (tNode != null)
832 {
833 boolean httpOnly = Boolean.parseBoolean(tNode.toString(false,true));
834 Origin o = context.getMetaData().getOrigin("cookie-config.http-only");
835 switch (o)
836 {
837 case NotSet:
838 {
839
840 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
841 context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
842 break;
843 }
844 case WebXml:
845 case WebDefaults:
846 case WebOverride:
847 {
848
849 if (!(descriptor instanceof FragmentDescriptor))
850 {
851 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setHttpOnly(httpOnly);
852 context.getMetaData().setOrigin("cookie-config.http-only", descriptor);
853 }
854 break;
855 }
856 case WebFragment:
857 {
858
859 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isHttpOnly() != httpOnly)
860 throw new IllegalStateException("Conflicting cookie-config http-only "+httpOnly+" in "+descriptor.getResource());
861 break;
862 }
863 }
864 }
865
866
867 tNode = cookieConfig.get("secure");
868 if (tNode != null)
869 {
870 boolean secure = Boolean.parseBoolean(tNode.toString(false,true));
871 Origin o = context.getMetaData().getOrigin("cookie-config.secure");
872 switch (o)
873 {
874 case NotSet:
875 {
876
877 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
878 context.getMetaData().setOrigin("cookie-config.secure", descriptor);
879 break;
880 }
881 case WebXml:
882 case WebDefaults:
883 case WebOverride:
884 {
885
886 if (!(descriptor instanceof FragmentDescriptor))
887 {
888 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setSecure(secure);
889 context.getMetaData().setOrigin("cookie-config.secure", descriptor);
890 }
891 break;
892 }
893 case WebFragment:
894 {
895
896 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().isSecure() != secure)
897 throw new IllegalStateException("Conflicting cookie-config secure "+secure+" in "+descriptor.getResource());
898 break;
899 }
900 }
901 }
902
903
904 tNode = cookieConfig.get("max-age");
905 if (tNode != null)
906 {
907 int maxAge = Integer.parseInt(tNode.toString(false,true));
908 Origin o = context.getMetaData().getOrigin("cookie-config.max-age");
909 switch (o)
910 {
911 case NotSet:
912 {
913
914 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
915 context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
916 break;
917 }
918 case WebXml:
919 case WebDefaults:
920 case WebOverride:
921 {
922
923 if (!(descriptor instanceof FragmentDescriptor))
924 {
925 context.getSessionHandler().getSessionManager().getSessionCookieConfig().setMaxAge(maxAge);
926 context.getMetaData().setOrigin("cookie-config.max-age", descriptor);
927 }
928 break;
929 }
930 case WebFragment:
931 {
932
933 if (context.getSessionHandler().getSessionManager().getSessionCookieConfig().getMaxAge() != maxAge)
934 throw new IllegalStateException("Conflicting cookie-config max-age "+maxAge+" in "+descriptor.getResource());
935 break;
936 }
937 }
938 }
939 }
940 }
941
942
943
944
945
946
947
948
949 protected void visitMimeMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
950 {
951 String extension = node.getString("extension", false, true);
952 if (extension != null && extension.startsWith("."))
953 extension = extension.substring(1);
954 String mimeType = node.getString("mime-type", false, true);
955 if (extension != null)
956 {
957 Origin o = context.getMetaData().getOrigin("extension."+extension);
958 switch (o)
959 {
960 case NotSet:
961 {
962
963 context.getMimeTypes().addMimeMapping(extension, mimeType);
964 context.getMetaData().setOrigin("extension."+extension, descriptor);
965 break;
966 }
967 case WebXml:
968 case WebDefaults:
969 case WebOverride:
970 {
971
972 if (!(descriptor instanceof FragmentDescriptor))
973 {
974 context.getMimeTypes().addMimeMapping(extension, mimeType);
975 context.getMetaData().setOrigin("extension."+extension, descriptor);
976 }
977 break;
978 }
979 case WebFragment:
980 {
981
982 if (!context.getMimeTypes().getMimeByExtension("."+extension).equals(mimeType))
983 throw new IllegalStateException("Conflicting mime-type "+mimeType+" for extension "+extension+" in "+descriptor.getResource());
984 break;
985 }
986 }
987 }
988 }
989
990
991
992
993
994
995 protected void visitWelcomeFileList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
996 {
997 Origin o = context.getMetaData().getOrigin("welcome-file-list");
998 switch (o)
999 {
1000 case NotSet:
1001 {
1002 context.getMetaData().setOrigin("welcome-file-list", descriptor);
1003 addWelcomeFiles(context,node);
1004 break;
1005 }
1006 case WebXml:
1007 {
1008
1009 addWelcomeFiles(context,node);
1010 break;
1011 }
1012 case WebDefaults:
1013 {
1014
1015
1016 if (!(descriptor instanceof DefaultsDescriptor) && !(descriptor instanceof OverrideDescriptor) && !(descriptor instanceof FragmentDescriptor))
1017 {
1018 context.setWelcomeFiles(new String[0]);
1019 }
1020 addWelcomeFiles(context,node);
1021 break;
1022 }
1023 case WebOverride:
1024 {
1025
1026 addWelcomeFiles(context,node);
1027 break;
1028 }
1029 case WebFragment:
1030 {
1031
1032 addWelcomeFiles(context,node);
1033 break;
1034 }
1035 }
1036 }
1037
1038
1039
1040
1041
1042
1043 protected void visitLocaleEncodingList(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1044 {
1045 Iterator<XmlParser.Node> iter = node.iterator("locale-encoding-mapping");
1046 while (iter.hasNext())
1047 {
1048 XmlParser.Node mapping = iter.next();
1049 String locale = mapping.getString("locale", false, true);
1050 String encoding = mapping.getString("encoding", false, true);
1051
1052 if (encoding != null)
1053 {
1054 Origin o = context.getMetaData().getOrigin("locale-encoding."+locale);
1055 switch (o)
1056 {
1057 case NotSet:
1058 {
1059
1060 context.addLocaleEncoding(locale, encoding);
1061 context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
1062 break;
1063 }
1064 case WebXml:
1065 case WebDefaults:
1066 case WebOverride:
1067 {
1068
1069 if (!(descriptor instanceof FragmentDescriptor))
1070 {
1071 context.addLocaleEncoding(locale, encoding);
1072 context.getMetaData().setOrigin("locale-encoding."+locale, descriptor);
1073 }
1074 break;
1075 }
1076 case WebFragment:
1077 {
1078
1079 if (!encoding.equals(context.getLocaleEncoding(locale)))
1080 throw new IllegalStateException("Conflicting loacle-encoding mapping for locale "+locale+" in "+descriptor.getResource());
1081 break;
1082 }
1083 }
1084 }
1085 }
1086 }
1087
1088
1089
1090
1091
1092
1093 protected void visitErrorPage(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1094 {
1095 String error = node.getString("error-code", false, true);
1096 int code=0;
1097 if (error == null || error.length() == 0)
1098 {
1099 error = node.getString("exception-type", false, true);
1100 if (error == null || error.length() == 0)
1101 error = ErrorPageErrorHandler.GLOBAL_ERROR_PAGE;
1102 }
1103 else
1104 code=Integer.valueOf(error);
1105
1106 String location = node.getString("location", false, true);
1107 ErrorPageErrorHandler handler = (ErrorPageErrorHandler)context.getErrorHandler();
1108
1109
1110 Origin o = context.getMetaData().getOrigin("error."+error);
1111
1112 switch (o)
1113 {
1114 case NotSet:
1115 {
1116
1117 if (code>0)
1118 handler.addErrorPage(code,location);
1119 else
1120 handler.addErrorPage(error,location);
1121 context.getMetaData().setOrigin("error."+error, descriptor);
1122 break;
1123 }
1124 case WebXml:
1125 case WebDefaults:
1126 case WebOverride:
1127 {
1128
1129 if (!(descriptor instanceof FragmentDescriptor))
1130 {
1131 if (descriptor instanceof OverrideDescriptor || descriptor instanceof DefaultsDescriptor)
1132 {
1133 if (code>0)
1134 handler.addErrorPage(code,location);
1135 else
1136 handler.addErrorPage(error,location);
1137 context.getMetaData().setOrigin("error."+error, descriptor);
1138 }
1139 else
1140 throw new IllegalStateException("Duplicate global error-page "+location);
1141 }
1142 break;
1143 }
1144 case WebFragment:
1145 {
1146
1147 if (!handler.getErrorPages().get(error).equals(location))
1148 throw new IllegalStateException("Conflicting error-code or exception-type "+error+" in "+descriptor.getResource());
1149 break;
1150 }
1151 }
1152
1153 }
1154
1155
1156
1157
1158
1159 protected void addWelcomeFiles(WebAppContext context, XmlParser.Node node)
1160 {
1161 Iterator<XmlParser.Node> iter = node.iterator("welcome-file");
1162 while (iter.hasNext())
1163 {
1164 XmlParser.Node indexNode = (XmlParser.Node) iter.next();
1165 String welcome = indexNode.toString(false, true);
1166
1167
1168 context.setWelcomeFiles((String[])ArrayUtil.addToArray(context.getWelcomeFiles(),welcome,String.class));
1169 }
1170 }
1171
1172
1173
1174
1175
1176
1177
1178 protected ServletMapping addServletMapping (String servletName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
1179 {
1180 ServletMapping mapping = new ServletMapping();
1181 mapping.setServletName(servletName);
1182
1183 List<String> paths = new ArrayList<String>();
1184 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1185 while (iter.hasNext())
1186 {
1187 String p = iter.next().toString(false, true);
1188 p = normalizePattern(p);
1189 paths.add(p);
1190 context.getMetaData().setOrigin(servletName+".servlet.mapping."+p, descriptor);
1191 }
1192 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1193 context.getServletHandler().addServletMapping(mapping);
1194 return mapping;
1195 }
1196
1197
1198
1199
1200
1201
1202 protected void addFilterMapping (String filterName, XmlParser.Node node, WebAppContext context, Descriptor descriptor)
1203 {
1204 FilterMapping mapping = new FilterMapping();
1205 mapping.setFilterName(filterName);
1206
1207 List<String> paths = new ArrayList<String>();
1208 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1209 while (iter.hasNext())
1210 {
1211 String p = iter.next().toString(false, true);
1212 p = normalizePattern(p);
1213 paths.add(p);
1214 context.getMetaData().setOrigin(filterName+".filter.mapping."+p, descriptor);
1215 }
1216 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1217
1218 List<String> names = new ArrayList<String>();
1219 iter = node.iterator("servlet-name");
1220 while (iter.hasNext())
1221 {
1222 String n = ((XmlParser.Node) iter.next()).toString(false, true);
1223 names.add(n);
1224 }
1225 mapping.setServletNames((String[]) names.toArray(new String[names.size()]));
1226
1227
1228 List<DispatcherType> dispatches = new ArrayList<DispatcherType>();
1229 iter=node.iterator("dispatcher");
1230 while(iter.hasNext())
1231 {
1232 String d=((XmlParser.Node)iter.next()).toString(false,true);
1233 dispatches.add(FilterMapping.dispatch(d));
1234 }
1235
1236 if (dispatches.size()>0)
1237 mapping.setDispatcherTypes(EnumSet.copyOf(dispatches));
1238
1239 context.getServletHandler().addFilterMapping(mapping);
1240 }
1241
1242
1243
1244
1245
1246
1247
1248 protected void visitTagLib(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1249 {
1250
1251 String uri = node.getString("taglib-uri", false, true);
1252 String location = node.getString("taglib-location", false, true);
1253
1254 context.setResourceAlias(uri, location);
1255
1256 JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
1257 if (config == null)
1258 {
1259 config = new JspConfig();
1260 context.getServletContext().setJspConfigDescriptor(config);
1261 }
1262
1263 TagLib tl = new TagLib();
1264 tl.setTaglibLocation(location);
1265 tl.setTaglibURI(uri);
1266 config.addTaglibDescriptor(tl);
1267 }
1268
1269
1270
1271
1272
1273
1274 protected void visitJspConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1275 {
1276
1277 JspConfig config = (JspConfig)context.getServletContext().getJspConfigDescriptor();
1278 if (config == null)
1279 {
1280 config = new JspConfig();
1281 context.getServletContext().setJspConfigDescriptor(config);
1282 }
1283
1284
1285 for (int i = 0; i < node.size(); i++)
1286 {
1287 Object o = node.get(i);
1288 if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag()))
1289 visitTagLib(context,descriptor, (XmlParser.Node) o);
1290 }
1291
1292
1293
1294 Iterator<XmlParser.Node> iter = node.iterator("jsp-property-group");
1295 List<String> paths = new ArrayList<String>();
1296 while (iter.hasNext())
1297 {
1298 JspPropertyGroup jpg = new JspPropertyGroup();
1299 config.addJspPropertyGroup(jpg);
1300 XmlParser.Node group = iter.next();
1301
1302
1303 Iterator<XmlParser.Node> iter2 = group.iterator("url-pattern");
1304 while (iter2.hasNext())
1305 {
1306 String url = iter2.next().toString(false, true);
1307 url = normalizePattern(url);
1308 paths.add( url);
1309 jpg.addUrlPattern(url);
1310 }
1311
1312 jpg.setElIgnored(group.getString("el-ignored", false, true));
1313 jpg.setPageEncoding(group.getString("page-encoding", false, true));
1314 jpg.setScriptingInvalid(group.getString("scripting-invalid", false, true));
1315 jpg.setIsXml(group.getString("is-xml", false, true));
1316 jpg.setDeferredSyntaxAllowedAsLiteral(group.getString("deferred-syntax-allowed-as-literal", false, true));
1317 jpg.setTrimDirectiveWhitespaces(group.getString("trim-directive-whitespaces", false, true));
1318 jpg.setDefaultContentType(group.getString("default-content-type", false, true));
1319 jpg.setBuffer(group.getString("buffer", false, true));
1320 jpg.setErrorOnUndeclaredNamespace(group.getString("error-on-undeclared-namespace", false, true));
1321
1322
1323 Iterator<XmlParser.Node> preludes = group.iterator("include-prelude");
1324 while (preludes.hasNext())
1325 {
1326 String prelude = preludes.next().toString(false, true);
1327 jpg.addIncludePrelude(prelude);
1328 }
1329
1330 Iterator<XmlParser.Node> codas = group.iterator("include-coda");
1331 while (codas.hasNext())
1332 {
1333 String coda = codas.next().toString(false, true);
1334 jpg.addIncludeCoda(coda);
1335 }
1336
1337 if (LOG.isDebugEnabled()) LOG.debug(config.toString());
1338 }
1339
1340 if (paths.size() > 0)
1341 {
1342 ServletHandler handler = context.getServletHandler();
1343 ServletHolder jsp_pg_servlet = handler.getServlet(JspPropertyGroupServlet.NAME);
1344 if (jsp_pg_servlet==null)
1345 {
1346 jsp_pg_servlet=new ServletHolder(JspPropertyGroupServlet.NAME,new JspPropertyGroupServlet(context,handler));
1347 handler.addServlet(jsp_pg_servlet);
1348 }
1349
1350 ServletMapping mapping = new ServletMapping();
1351 mapping.setServletName(JspPropertyGroupServlet.NAME);
1352 mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
1353 context.getServletHandler().addServletMapping(mapping);
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 }