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