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