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