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 context.setAttribute("org.apache.catalina.jsp_classpath", context.getClassPath());
282
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 holder.setInitParameter("com.sun.appserv.jsp.classpath", getSystemClassPath(context));
332 }
333
334
335 XmlParser.Node startup = node.get("load-on-startup");
336 if (startup != null)
337 {
338 String s = startup.toString(false, true).toLowerCase();
339 int order = 0;
340 if (s.startsWith("t"))
341 {
342 LOG.warn("Deprecated boolean load-on-startup. Please use integer");
343 order = 1;
344 }
345 else
346 {
347 try
348 {
349 if (s != null && s.trim().length() > 0) order = Integer.parseInt(s);
350 }
351 catch (Exception e)
352 {
353 LOG.warn("Cannot parse load-on-startup " + s + ". Please use integer");
354 LOG.ignore(e);
355 }
356 }
357
358 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.load-on-startup");
359 switch (o)
360 {
361 case NotSet:
362 {
363
364 holder.setInitOrder(order);
365 context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
366 break;
367 }
368 case WebXml:
369 case WebDefaults:
370 case WebOverride:
371 {
372
373 if (!(descriptor instanceof FragmentDescriptor))
374 {
375 holder.setInitOrder(order);
376 context.getMetaData().setOrigin(servlet_name+".servlet.load-on-startup", descriptor);
377 }
378 break;
379 }
380 case WebFragment:
381 {
382
383 if (order != holder.getInitOrder())
384 throw new IllegalStateException("Conflicting load-on-startup value in "+descriptor.getResource());
385 break;
386 }
387 }
388 }
389
390 Iterator sRefsIter = node.iterator("security-role-ref");
391 while (sRefsIter.hasNext())
392 {
393 XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
394 String roleName = securityRef.getString("role-name", false, true);
395 String roleLink = securityRef.getString("role-link", false, true);
396 if (roleName != null && roleName.length() > 0 && roleLink != null && roleLink.length() > 0)
397 {
398 if (LOG.isDebugEnabled()) LOG.debug("link role " + roleName + " to " + roleLink + " for " + this);
399 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.role-name."+roleName);
400 switch (o)
401 {
402 case NotSet:
403 {
404
405 holder.setUserRoleLink(roleName, roleLink);
406 context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
407 break;
408 }
409 case WebXml:
410 case WebDefaults:
411 case WebOverride:
412 {
413
414 if (!(descriptor instanceof FragmentDescriptor))
415 {
416 holder.setUserRoleLink(roleName, roleLink);
417 context.getMetaData().setOrigin(servlet_name+".servlet.role-name."+roleName, descriptor);
418 }
419 break;
420 }
421 case WebFragment:
422 {
423 if (!holder.getUserRoleLink(roleName).equals(roleLink))
424 throw new IllegalStateException("Conflicting role-link for role-name "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource());
425 break;
426 }
427 }
428 }
429 else
430 {
431 LOG.warn("Ignored invalid security-role-ref element: " + "servlet-name=" + holder.getName() + ", " + securityRef);
432 }
433 }
434
435
436 XmlParser.Node run_as = node.get("run-as");
437 if (run_as != null)
438 {
439 String roleName = run_as.getString("role-name", false, true);
440
441 if (roleName != null)
442 {
443 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.run-as");
444 switch (o)
445 {
446 case NotSet:
447 {
448
449 holder.setRunAsRole(roleName);
450 context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor);
451 break;
452 }
453 case WebXml:
454 case WebDefaults:
455 case WebOverride:
456 {
457
458 if (!(descriptor instanceof FragmentDescriptor))
459 {
460 holder.setRunAsRole(roleName);
461 context.getMetaData().setOrigin(servlet_name+".servlet.run-as", descriptor);
462 }
463 break;
464 }
465 case WebFragment:
466 {
467
468 if (!holder.getRunAsRole().equals(roleName))
469 throw new IllegalStateException("Conflicting run-as role "+roleName+" for servlet "+servlet_name+" in "+descriptor.getResource());
470 break;
471 }
472 }
473 }
474 }
475
476 String async=node.getString("async-supported",false,true);
477 if (async!=null)
478 {
479 boolean val = async.length()==0||Boolean.valueOf(async);
480 Origin o =context.getMetaData().getOrigin(servlet_name+".servlet.async-supported");
481 switch (o)
482 {
483 case NotSet:
484 {
485
486 holder.setAsyncSupported(val);
487 context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor);
488 break;
489 }
490 case WebXml:
491 case WebDefaults:
492 case WebOverride:
493 {
494
495 if (!(descriptor instanceof FragmentDescriptor))
496 {
497 holder.setAsyncSupported(val);
498 context.getMetaData().setOrigin(servlet_name+".servlet.async-supported", descriptor);
499 }
500 break;
501 }
502 case WebFragment:
503 {
504
505 if (holder.isAsyncSupported() != val)
506 throw new IllegalStateException("Conflicting async-supported="+async+" for servlet "+servlet_name+" in "+descriptor.getResource());
507 break;
508 }
509 }
510 }
511
512 String enabled = node.getString("enabled", false, true);
513 if (enabled!=null)
514 {
515 boolean is_enabled = enabled.length()==0||Boolean.valueOf(enabled);
516
517 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.enabled");
518 switch (o)
519 {
520 case NotSet:
521 {
522
523
524 context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor);
525 break;
526 }
527 case WebXml:
528 case WebDefaults:
529 case WebOverride:
530 {
531
532 if (!(descriptor instanceof FragmentDescriptor))
533 {
534
535 context.getMetaData().setOrigin(servlet_name+".servlet.enabled", descriptor);
536 }
537 break;
538 }
539 case WebFragment:
540 {
541
542
543 break;
544 }
545 }
546 }
547
548
549
550
551
552
553 XmlParser.Node multipart = node.get("multipart-config");
554 if (multipart != null)
555 {
556 String location = node.getString("location", false, true);
557 String maxFile = node.getString("max-file-size", false, true);
558 String maxRequest = node.getString("max-request-size", false, true);
559 String threshold = node.getString("file-size-threshold",false,true);
560 MultipartConfigElement element = new MultipartConfigElement(location,
561 (maxFile==null||"".equals(maxFile)?-1L:Long.parseLong(maxFile)),
562 (maxRequest==null||"".equals(maxRequest)?-1L:Long.parseLong(maxRequest)),
563 (threshold==null||"".equals(threshold)?0:Integer.parseInt(threshold)));
564
565 Origin o = context.getMetaData().getOrigin(servlet_name+".servlet.multipart-config");
566 switch (o)
567 {
568 case NotSet:
569 {
570
571 holder.getRegistration().setMultipartConfig(element);
572 context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor);
573 break;
574 }
575 case WebXml:
576 case WebDefaults:
577 case WebOverride:
578 {
579
580 if (!(descriptor instanceof FragmentDescriptor))
581 {
582 holder.getRegistration().setMultipartConfig(element);
583 context.getMetaData().setOrigin(servlet_name+".servlet.multipart-config", descriptor);
584 }
585 break;
586 }
587 case WebFragment:
588 {
589
590 MultipartConfigElement cfg = ((ServletHolder.Registration)holder.getRegistration()).getMultipartConfig();
591
592 if (cfg.getMaxFileSize() != element.getMaxFileSize())
593 throw new IllegalStateException("Conflicting multipart-config max-file-size for servlet "+servlet_name+" in "+descriptor.getResource());
594 if (cfg.getMaxRequestSize() != element.getMaxRequestSize())
595 throw new IllegalStateException("Conflicting multipart-config max-request-size for servlet "+servlet_name+" in "+descriptor.getResource());
596 if (cfg.getFileSizeThreshold() != element.getFileSizeThreshold())
597 throw new IllegalStateException("Conflicting multipart-config file-size-threshold for servlet "+servlet_name+" in "+descriptor.getResource());
598 if ((cfg.getLocation() != null && (element.getLocation() == null || element.getLocation().length()==0))
599 || (cfg.getLocation() == null && (element.getLocation()!=null || element.getLocation().length() > 0)))
600 throw new IllegalStateException("Conflicting multipart-config location for servlet "+servlet_name+" in "+descriptor.getResource());
601 break;
602 }
603 }
604 }
605 }
606
607
608
609
610
611
612
613
614 protected void visitServletMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
615 {
616
617
618
619
620
621
622 String servlet_name = node.getString("servlet-name", false, true);
623 Origin origin = context.getMetaData().getOrigin(servlet_name+".servlet.mappings");
624
625 switch (origin)
626 {
627 case NotSet:
628 {
629
630 context.getMetaData().setOrigin(servlet_name+".servlet.mappings", descriptor);
631 addServletMapping(servlet_name, node, context);
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);
643 }
644 break;
645 }
646 case WebFragment:
647 {
648
649 addServletMapping(servlet_name, node, context);
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 error = node.getString("exception-type", false, true);
1104 else
1105 code=Integer.valueOf(error);
1106 String location = node.getString("location", false, true);
1107
1108
1109 ErrorPageErrorHandler handler = (ErrorPageErrorHandler)context.getErrorHandler();
1110
1111
1112 Origin o = context.getMetaData().getOrigin("error."+error);
1113 switch (o)
1114 {
1115 case NotSet:
1116 {
1117
1118 if (code>0)
1119 handler.addErrorPage(code,location);
1120 else
1121 handler.addErrorPage(error,location);
1122 context.getMetaData().setOrigin("error."+error, descriptor);
1123 break;
1124 }
1125 case WebXml:
1126 case WebDefaults:
1127 case WebOverride:
1128 {
1129
1130 if (!(descriptor instanceof FragmentDescriptor))
1131 {
1132 if (code>0)
1133 handler.addErrorPage(code,location);
1134 else
1135 handler.addErrorPage(error,location);
1136 context.getMetaData().setOrigin("error."+error, descriptor);
1137 }
1138 break;
1139 }
1140 case WebFragment:
1141 {
1142
1143 if (!handler.getErrorPages().get(error).equals(location))
1144 throw new IllegalStateException("Conflicting error-code or exception-type "+error+" in "+descriptor.getResource());
1145 break;
1146 }
1147 }
1148
1149 }
1150
1151
1152
1153
1154
1155 protected void addWelcomeFiles(WebAppContext context, XmlParser.Node node)
1156 {
1157 Iterator<XmlParser.Node> iter = node.iterator("welcome-file");
1158 while (iter.hasNext())
1159 {
1160 XmlParser.Node indexNode = (XmlParser.Node) iter.next();
1161 String welcome = indexNode.toString(false, true);
1162
1163
1164 context.setWelcomeFiles((String[])LazyList.addToArray(context.getWelcomeFiles(),welcome,String.class));
1165 }
1166 }
1167
1168
1169
1170
1171
1172
1173
1174 protected void addServletMapping (String servletName, XmlParser.Node node, WebAppContext context)
1175 {
1176 ServletMapping mapping = new ServletMapping();
1177 mapping.setServletName(servletName);
1178
1179 List<String> paths = new ArrayList<String>();
1180 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1181 while (iter.hasNext())
1182 {
1183 String p = iter.next().toString(false, true);
1184 p = normalizePattern(p);
1185 paths.add(p);
1186 }
1187 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1188 context.getServletHandler().addServletMapping(mapping);
1189 }
1190
1191
1192
1193
1194
1195
1196 protected void addFilterMapping (String filterName, XmlParser.Node node, WebAppContext context)
1197 {
1198 FilterMapping mapping = new FilterMapping();
1199 mapping.setFilterName(filterName);
1200
1201 List<String> paths = new ArrayList<String>();
1202 Iterator<XmlParser.Node> iter = node.iterator("url-pattern");
1203 while (iter.hasNext())
1204 {
1205 String p = iter.next().toString(false, true);
1206 p = normalizePattern(p);
1207 paths.add(p);
1208 }
1209 mapping.setPathSpecs((String[]) paths.toArray(new String[paths.size()]));
1210
1211 List<String> names = new ArrayList<String>();
1212 iter = node.iterator("servlet-name");
1213 while (iter.hasNext())
1214 {
1215 String n = ((XmlParser.Node) iter.next()).toString(false, true);
1216 names.add(n);
1217 }
1218 mapping.setServletNames((String[]) names.toArray(new String[names.size()]));
1219
1220
1221 List<DispatcherType> dispatches = new ArrayList<DispatcherType>();
1222 iter=node.iterator("dispatcher");
1223 while(iter.hasNext())
1224 {
1225 String d=((XmlParser.Node)iter.next()).toString(false,true);
1226 dispatches.add(FilterMapping.dispatch(d));
1227 }
1228
1229 if (dispatches.size()>0)
1230 mapping.setDispatcherTypes(EnumSet.copyOf(dispatches));
1231
1232 context.getServletHandler().addFilterMapping(mapping);
1233 }
1234
1235
1236
1237
1238
1239
1240
1241 protected void visitTagLib(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1242 {
1243
1244 String uri = node.getString("taglib-uri", false, true);
1245 String location = node.getString("taglib-location", false, true);
1246
1247 context.setResourceAlias(uri, location);
1248 }
1249
1250
1251
1252
1253
1254
1255 protected void visitJspConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1256 {
1257 for (int i = 0; i < node.size(); i++)
1258 {
1259 Object o = node.get(i);
1260 if (o instanceof XmlParser.Node && "taglib".equals(((XmlParser.Node) o).getTag()))
1261 visitTagLib(context,descriptor, (XmlParser.Node) o);
1262 }
1263
1264
1265
1266 Iterator<XmlParser.Node> iter = node.iterator("jsp-property-group");
1267 List<String> paths = new ArrayList<String>();
1268 while (iter.hasNext())
1269 {
1270 XmlParser.Node group = iter.next();
1271 Iterator<XmlParser.Node> iter2 = group.iterator("url-pattern");
1272 while (iter2.hasNext())
1273 {
1274 String url = iter2.next().toString(false, true);
1275 url = normalizePattern(url);
1276 paths.add( url);
1277 }
1278 }
1279
1280 if (paths.size() > 0)
1281 {
1282 String jspName = "jsp";
1283 Map.Entry entry = context.getServletHandler().getHolderEntry("test.jsp");
1284 if (entry != null)
1285 {
1286 ServletHolder holder = (ServletHolder) entry.getValue();
1287 jspName = holder.getName();
1288 }
1289
1290 if (jspName != null)
1291 {
1292 ServletMapping mapping = new ServletMapping();
1293 mapping.setServletName(jspName);
1294 mapping.setPathSpecs(paths.toArray(new String[paths.size()]));
1295 context.getServletHandler().addServletMapping(mapping);
1296 }
1297 }
1298 }
1299
1300
1301
1302
1303
1304
1305 protected void visitSecurityConstraint(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1306 {
1307 Constraint scBase = new Constraint();
1308
1309
1310
1311 try
1312 {
1313 XmlParser.Node auths = node.get("auth-constraint");
1314
1315 if (auths != null)
1316 {
1317 scBase.setAuthenticate(true);
1318
1319 Iterator<XmlParser.Node> iter = auths.iterator("role-name");
1320 List<String> roles = new ArrayList<String>();
1321 while (iter.hasNext())
1322 {
1323 String role = iter.next().toString(false, true);
1324 roles.add(role);
1325 }
1326 scBase.setRoles(roles.toArray(new String[roles.size()]));
1327 }
1328
1329 XmlParser.Node data = node.get("user-data-constraint");
1330 if (data != null)
1331 {
1332 data = data.get("transport-guarantee");
1333 String guarantee = data.toString(false, true).toUpperCase();
1334 if (guarantee == null || guarantee.length() == 0 || "NONE".equals(guarantee))
1335 scBase.setDataConstraint(Constraint.DC_NONE);
1336 else if ("INTEGRAL".equals(guarantee))
1337 scBase.setDataConstraint(Constraint.DC_INTEGRAL);
1338 else if ("CONFIDENTIAL".equals(guarantee))
1339 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
1340 else
1341 {
1342 LOG.warn("Unknown user-data-constraint:" + guarantee);
1343 scBase.setDataConstraint(Constraint.DC_CONFIDENTIAL);
1344 }
1345 }
1346 Iterator<XmlParser.Node> iter = node.iterator("web-resource-collection");
1347 while (iter.hasNext())
1348 {
1349 XmlParser.Node collection = iter.next();
1350 String name = collection.getString("web-resource-name", false, true);
1351 Constraint sc = (Constraint) scBase.clone();
1352 sc.setName(name);
1353
1354 Iterator<XmlParser.Node> iter2 = collection.iterator("url-pattern");
1355 while (iter2.hasNext())
1356 {
1357 String url = iter2.next().toString(false, true);
1358 url = normalizePattern(url);
1359
1360 Iterator<XmlParser.Node> iter3 = collection.iterator("http-method");
1361 if (iter3.hasNext())
1362 {
1363 while (iter3.hasNext())
1364 {
1365 String method = ((XmlParser.Node) iter3.next()).toString(false, true);
1366 ConstraintMapping mapping = new ConstraintMapping();
1367 mapping.setMethod(method);
1368 mapping.setPathSpec(url);
1369 mapping.setConstraint(sc);
1370
1371 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1372 }
1373 }
1374 else
1375 {
1376 ConstraintMapping mapping = new ConstraintMapping();
1377 mapping.setPathSpec(url);
1378 mapping.setConstraint(sc);
1379 ((ConstraintAware)context.getSecurityHandler()).addConstraintMapping(mapping);
1380 }
1381 }
1382 }
1383 }
1384 catch (CloneNotSupportedException e)
1385 {
1386 LOG.warn(e);
1387 }
1388 }
1389
1390
1391
1392
1393
1394
1395
1396 protected void visitLoginConfig(WebAppContext context, Descriptor descriptor, XmlParser.Node node) throws Exception
1397 {
1398
1399
1400
1401 XmlParser.Node method = node.get("auth-method");
1402 if (method != null)
1403 {
1404
1405 Origin o = context.getMetaData().getOrigin("auth-method");
1406 switch (o)
1407 {
1408 case NotSet:
1409 {
1410
1411 context.getSecurityHandler().setAuthMethod(method.toString(false, true));
1412 context.getMetaData().setOrigin("auth-method", descriptor);
1413 break;
1414 }
1415 case WebXml:
1416 case WebDefaults:
1417 case WebOverride:
1418 {
1419
1420 if (!(descriptor instanceof FragmentDescriptor))
1421 {
1422 context.getSecurityHandler().setAuthMethod(method.toString(false, true));
1423 context.getMetaData().setOrigin("auth-method", descriptor);
1424 }
1425 break;
1426 }
1427 case WebFragment:
1428 {
1429
1430 if (!context.getSecurityHandler().getAuthMethod().equals(method.toString(false, true)))
1431 throw new IllegalStateException("Conflicting auth-method value in "+descriptor.getResource());
1432 break;
1433 }
1434 }
1435
1436
1437 XmlParser.Node name = node.get("realm-name");
1438 String nameStr = (name == null ? "default" : name.toString(false, true));
1439 o = context.getMetaData().getOrigin("realm-name");
1440 switch (o)
1441 {
1442 case NotSet:
1443 {
1444
1445 context.getSecurityHandler().setRealmName(nameStr);
1446 context.getMetaData().setOrigin("realm-name", descriptor);
1447 break;
1448 }
1449 case WebXml:
1450 case WebDefaults:
1451 case WebOverride:
1452 {
1453
1454 if (!(descriptor instanceof FragmentDescriptor))
1455 {
1456 context.getSecurityHandler().setRealmName(nameStr);
1457 context.getMetaData().setOrigin("realm-name", descriptor);
1458 }
1459 break;
1460 }
1461 case WebFragment:
1462 {
1463
1464 if (!context.getSecurityHandler().getRealmName().equals(nameStr))
1465 throw new IllegalStateException("Conflicting realm-name value in "+descriptor.getResource());
1466 break;
1467 }
1468 }
1469
1470 if (Constraint.__FORM_AUTH.equals(context.getSecurityHandler().getAuthMethod()))
1471 {
1472 XmlParser.Node formConfig = node.get("form-login-config");
1473 if (formConfig != null)
1474 {
1475 String loginPageName = null;
1476 XmlParser.Node loginPage = formConfig.get("form-login-page");
1477 if (loginPage != null)
1478 loginPageName = loginPage.toString(false, true);
1479 String errorPageName = null;
1480 XmlParser.Node errorPage = formConfig.get("form-error-page");
1481 if (errorPage != null)
1482 errorPageName = errorPage.toString(false, true);
1483
1484
1485 o = context.getMetaData().getOrigin("form-login-page");
1486 switch (o)
1487 {
1488 case NotSet:
1489 {
1490
1491 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
1492 context.getMetaData().setOrigin("form-login-page",descriptor);
1493 break;
1494 }
1495 case WebXml:
1496 case WebDefaults:
1497 case WebOverride:
1498 {
1499
1500 if (!(descriptor instanceof FragmentDescriptor))
1501 {
1502 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE,loginPageName);
1503 context.getMetaData().setOrigin("form-login-page",descriptor);
1504 }
1505 break;
1506 }
1507 case WebFragment:
1508 {
1509
1510 if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_LOGIN_PAGE).equals(loginPageName))
1511 throw new IllegalStateException("Conflicting form-login-page value in "+descriptor.getResource());
1512 break;
1513 }
1514 }
1515
1516
1517 o = context.getMetaData().getOrigin("form-error-page");
1518 switch (o)
1519 {
1520 case NotSet:
1521 {
1522
1523 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
1524 context.getMetaData().setOrigin("form-error-page",descriptor);
1525 break;
1526 }
1527 case WebXml:
1528 case WebDefaults:
1529 case WebOverride:
1530 {
1531
1532 if (!(descriptor instanceof FragmentDescriptor))
1533 {
1534 context.getSecurityHandler().setInitParameter(FormAuthenticator.__FORM_ERROR_PAGE,errorPageName);
1535 context.getMetaData().setOrigin("form-error-page",descriptor);
1536 }
1537 break;
1538 }
1539 case WebFragment:
1540 {
1541
1542 if (!context.getSecurityHandler().getInitParameter(FormAuthenticator.__FORM_ERROR_PAGE).equals(errorPageName))
1543 throw new IllegalStateException("Conflicting form-error-page value in "+descriptor.getResource());
1544 break;
1545 }
1546 }
1547 }
1548 else
1549 {
1550 throw new IllegalStateException("!form-login-config");
1551 }
1552 }
1553 }
1554 }
1555
1556
1557
1558
1559
1560
1561 protected void visitSecurityRole(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1562 {
1563
1564 XmlParser.Node roleNode = node.get("role-name");
1565 String role = roleNode.toString(false, true);
1566 ((ConstraintAware)context.getSecurityHandler()).addRole(role);
1567 }
1568
1569
1570
1571
1572
1573
1574
1575 protected void visitFilter(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1576 {
1577 String name = node.getString("filter-name", false, true);
1578 FilterHolder holder = context.getServletHandler().getFilter(name);
1579 if (holder == null)
1580 {
1581 holder = context.getServletHandler().newFilterHolder(Holder.Source.DESCRIPTOR);
1582 holder.setName(name);
1583 context.getServletHandler().addFilter(holder);
1584 }
1585
1586 String filter_class = node.getString("filter-class", false, true);
1587 if (filter_class != null)
1588 {
1589 ((WebDescriptor)descriptor).addClassName(filter_class);
1590
1591 Origin o = context.getMetaData().getOrigin(name+".filter.filter-class");
1592 switch (o)
1593 {
1594 case NotSet:
1595 {
1596
1597 holder.setClassName(filter_class);
1598 context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
1599 break;
1600 }
1601 case WebXml:
1602 case WebDefaults:
1603 case WebOverride:
1604 {
1605
1606 if (!(descriptor instanceof FragmentDescriptor))
1607 {
1608 holder.setClassName(filter_class);
1609 context.getMetaData().setOrigin(name+".filter.filter-class", descriptor);
1610 }
1611 break;
1612 }
1613 case WebFragment:
1614 {
1615
1616 if (!holder.getClassName().equals(filter_class))
1617 throw new IllegalStateException("Conflicting filter-class for filter "+name+" in "+descriptor.getResource());
1618 break;
1619 }
1620 }
1621
1622 }
1623
1624 Iterator<XmlParser.Node> iter = node.iterator("init-param");
1625 while (iter.hasNext())
1626 {
1627 XmlParser.Node paramNode = iter.next();
1628 String pname = paramNode.getString("param-name", false, true);
1629 String pvalue = paramNode.getString("param-value", false, true);
1630
1631 Origin origin = context.getMetaData().getOrigin(name+".filter.init-param."+pname);
1632 switch (origin)
1633 {
1634 case NotSet:
1635 {
1636
1637 holder.setInitParameter(pname, pvalue);
1638 context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
1639 break;
1640 }
1641 case WebXml:
1642 case WebDefaults:
1643 case WebOverride:
1644 {
1645
1646
1647 if (!(descriptor instanceof FragmentDescriptor))
1648 {
1649 holder.setInitParameter(pname, pvalue);
1650 context.getMetaData().setOrigin(name+".filter.init-param."+pname, descriptor);
1651 }
1652 break;
1653 }
1654 case WebFragment:
1655 {
1656
1657 if (!holder.getInitParameter(pname).equals(pvalue))
1658 throw new IllegalStateException("Mismatching init-param "+pname+"="+pvalue+" in "+descriptor.getResource());
1659 break;
1660 }
1661 }
1662 }
1663
1664 String async=node.getString("async-supported",false,true);
1665 if (async!=null)
1666 holder.setAsyncSupported(async.length()==0||Boolean.valueOf(async));
1667 if (async!=null)
1668 {
1669 boolean val = async.length()==0||Boolean.valueOf(async);
1670 Origin o = context.getMetaData().getOrigin(name+".filter.async-supported");
1671 switch (o)
1672 {
1673 case NotSet:
1674 {
1675
1676 holder.setAsyncSupported(val);
1677 context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
1678 break;
1679 }
1680 case WebXml:
1681 case WebDefaults:
1682 case WebOverride:
1683 {
1684
1685 if (!(descriptor instanceof FragmentDescriptor))
1686 {
1687 holder.setAsyncSupported(val);
1688 context.getMetaData().setOrigin(name+".filter.async-supported", descriptor);
1689 }
1690 break;
1691 }
1692 case WebFragment:
1693 {
1694
1695 if (holder.isAsyncSupported() != val)
1696 throw new IllegalStateException("Conflicting async-supported="+async+" for filter "+name+" in "+descriptor.getResource());
1697 break;
1698 }
1699 }
1700 }
1701
1702 }
1703
1704
1705
1706
1707
1708
1709 protected void visitFilterMapping(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1710 {
1711
1712
1713
1714
1715
1716
1717 String filter_name = node.getString("filter-name", false, true);
1718
1719 Origin origin = context.getMetaData().getOrigin(filter_name+".filter.mappings");
1720
1721 switch (origin)
1722 {
1723 case NotSet:
1724 {
1725
1726 context.getMetaData().setOrigin(filter_name+".filter.mappings", descriptor);
1727 addFilterMapping(filter_name, node, context);
1728 break;
1729 }
1730 case WebDefaults:
1731 case WebOverride:
1732 case WebXml:
1733 {
1734
1735 if (!(descriptor instanceof FragmentDescriptor))
1736 {
1737 addFilterMapping(filter_name, node, context);
1738 }
1739 break;
1740 }
1741 case WebFragment:
1742 {
1743
1744 addFilterMapping(filter_name, node, context);
1745 break;
1746 }
1747 }
1748 }
1749
1750
1751
1752
1753
1754
1755
1756 protected void visitListener(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1757 {
1758 String className = node.getString("listener-class", false, true);
1759 EventListener listener = null;
1760 try
1761 {
1762 if (className != null && className.length()> 0)
1763 {
1764
1765
1766 EventListener[] listeners=context.getEventListeners();
1767 if (listeners!=null)
1768 {
1769 for (EventListener l : listeners)
1770 {
1771 if (l.getClass().getName().equals(className))
1772 return;
1773 }
1774 }
1775
1776 ((WebDescriptor)descriptor).addClassName(className);
1777
1778 Class<? extends EventListener> listenerClass = (Class<? extends EventListener>)context.loadClass(className);
1779 listener = newListenerInstance(context,listenerClass);
1780 if (!(listener instanceof EventListener))
1781 {
1782 LOG.warn("Not an EventListener: " + listener);
1783 return;
1784 }
1785 context.addEventListener(listener);
1786 context.getMetaData().setOrigin(className+".listener", descriptor);
1787
1788 }
1789 }
1790 catch (Exception e)
1791 {
1792 LOG.warn("Could not instantiate listener " + className, e);
1793 return;
1794 }
1795 }
1796
1797
1798
1799
1800
1801
1802 protected void visitDistributable(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
1803 {
1804
1805
1806
1807 ((WebDescriptor)descriptor).setDistributable(true);
1808 }
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818 protected EventListener newListenerInstance(WebAppContext context,Class<? extends EventListener> clazz) throws ServletException, InstantiationException, IllegalAccessException
1819 {
1820 try
1821 {
1822 return context.getServletContext().createListener(clazz);
1823 }
1824 catch (ServletException se)
1825 {
1826 Throwable cause = se.getRootCause();
1827 if (cause instanceof InstantiationException)
1828 throw (InstantiationException)cause;
1829 if (cause instanceof IllegalAccessException)
1830 throw (IllegalAccessException)cause;
1831 throw se;
1832 }
1833 }
1834
1835
1836
1837
1838
1839 protected String normalizePattern(String p)
1840 {
1841 if (p != null && p.length() > 0 && !p.startsWith("/") && !p.startsWith("*")) return "/" + p;
1842 return p;
1843 }
1844
1845
1846
1847
1848
1849
1850
1851
1852 protected String getSystemClassPath(WebAppContext context)
1853 {
1854 ClassLoader loader = context.getClassLoader();
1855 if (loader.getParent() != null)
1856 loader = loader.getParent();
1857
1858 StringBuilder classpath=new StringBuilder();
1859 while (loader != null && (loader instanceof URLClassLoader))
1860 {
1861 URL[] urls = ((URLClassLoader)loader).getURLs();
1862 if (urls != null)
1863 {
1864 for (int i=0;i<urls.length;i++)
1865 {
1866 try
1867 {
1868 Resource resource = context.newResource(urls[i]);
1869 File file=resource.getFile();
1870 if (file!=null && file.exists())
1871 {
1872 if (classpath.length()>0)
1873 classpath.append(File.pathSeparatorChar);
1874 classpath.append(file.getAbsolutePath());
1875 }
1876 }
1877 catch (IOException e)
1878 {
1879 LOG.debug(e);
1880 }
1881 }
1882 }
1883 loader = loader.getParent();
1884 }
1885 return classpath.toString();
1886 }
1887 }