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