View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.servlet;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.EnumSet;
26  import java.util.EventListener;
27  import java.util.HashMap;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Set;
32  
33  import javax.servlet.DispatcherType;
34  import javax.servlet.Filter;
35  import javax.servlet.FilterRegistration;
36  import javax.servlet.RequestDispatcher;
37  import javax.servlet.Servlet;
38  import javax.servlet.ServletContext;
39  import javax.servlet.ServletContextEvent;
40  import javax.servlet.ServletContextListener;
41  import javax.servlet.ServletException;
42  import javax.servlet.ServletRegistration;
43  import javax.servlet.ServletSecurityElement;
44  import javax.servlet.SessionCookieConfig;
45  import javax.servlet.SessionTrackingMode;
46  import javax.servlet.descriptor.JspConfigDescriptor;
47  import javax.servlet.descriptor.JspPropertyGroupDescriptor;
48  import javax.servlet.descriptor.TaglibDescriptor;
49  
50  import org.eclipse.jetty.security.ConstraintAware;
51  import org.eclipse.jetty.security.ConstraintMapping;
52  import org.eclipse.jetty.security.ConstraintSecurityHandler;
53  import org.eclipse.jetty.security.SecurityHandler;
54  import org.eclipse.jetty.server.Dispatcher;
55  import org.eclipse.jetty.server.Handler;
56  import org.eclipse.jetty.server.HandlerContainer;
57  import org.eclipse.jetty.server.handler.ContextHandler;
58  import org.eclipse.jetty.server.handler.ErrorHandler;
59  import org.eclipse.jetty.server.handler.HandlerCollection;
60  import org.eclipse.jetty.server.handler.HandlerWrapper;
61  import org.eclipse.jetty.server.session.SessionHandler;
62  import org.eclipse.jetty.util.annotation.ManagedAttribute;
63  import org.eclipse.jetty.util.annotation.ManagedObject;
64  
65  
66  /* ------------------------------------------------------------ */
67  /** Servlet Context.
68   * This extension to the ContextHandler allows for
69   * simple construction of a context with ServletHandler and optionally
70   * session and security handlers, et.<pre>
71   *   new ServletContext("/context",Context.SESSIONS|Context.NO_SECURITY);
72   * </pre>
73   * <p/>
74   * This class should have been called ServletContext, but this would have
75   * cause confusion with {@link ServletContext}.
76   */
77  @ManagedObject("Servlet Context Handler")
78  public class ServletContextHandler extends ContextHandler
79  {
80      public final static int SESSIONS=1;
81      public final static int SECURITY=2;
82      public final static int NO_SESSIONS=0;
83      public final static int NO_SECURITY=0;
84  
85      protected final List<Decorator> _decorators= new ArrayList<>();
86      protected Class<? extends SecurityHandler> _defaultSecurityHandlerClass=org.eclipse.jetty.security.ConstraintSecurityHandler.class;
87      protected SessionHandler _sessionHandler;
88      protected SecurityHandler _securityHandler;
89      protected ServletHandler _servletHandler;
90      protected int _options;
91      protected JspConfigDescriptor _jspConfig;
92  
93      /* ------------------------------------------------------------ */
94      public ServletContextHandler()
95      {
96          this(null,null,null,null,null);
97      }
98  
99      /* ------------------------------------------------------------ */
100     public ServletContextHandler(int options)
101     {
102         this(null,null,options);
103     }
104 
105     /* ------------------------------------------------------------ */
106     public ServletContextHandler(HandlerContainer parent, String contextPath)
107     {
108         this(parent,contextPath,null,null,null,null);
109     }
110 
111     /* ------------------------------------------------------------ */
112     public ServletContextHandler(HandlerContainer parent, String contextPath, int options)
113     {
114         this(parent,contextPath,null,null,null,null,options);
115     }
116 
117     /* ------------------------------------------------------------ */
118     public ServletContextHandler(HandlerContainer parent, String contextPath, boolean sessions, boolean security)
119     {
120         this(parent,contextPath,(sessions?SESSIONS:0)|(security?SECURITY:0));
121     }
122 
123     /* ------------------------------------------------------------ */
124     public ServletContextHandler(HandlerContainer parent, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
125     {
126         this(parent,null,sessionHandler,securityHandler,servletHandler,errorHandler);
127     }
128 
129     /* ------------------------------------------------------------ */
130     public ServletContextHandler(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
131     {
132         this(parent,contextPath,sessionHandler,securityHandler,servletHandler,errorHandler,0);
133     }
134     
135     public ServletContextHandler(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler,int options)
136     {
137         super((ContextHandler.Context)null);
138         _options=options;
139         _scontext = new Context();
140         _sessionHandler = sessionHandler;
141         _securityHandler = securityHandler;
142         _servletHandler = servletHandler;
143 
144         if (contextPath!=null)
145             setContextPath(contextPath);
146         
147         if (parent instanceof HandlerWrapper)
148             ((HandlerWrapper)parent).setHandler(this);
149         else if (parent instanceof HandlerCollection)
150             ((HandlerCollection)parent).addHandler(this);
151         
152         
153         // Link the handlers
154         relinkHandlers();
155         
156         if (errorHandler!=null)
157             setErrorHandler(errorHandler);
158 
159     }
160     
161     /* ------------------------------------------------------------ */
162     private void relinkHandlers()
163     {
164         HandlerWrapper handler=this;
165         
166         // Skip any injected handlers
167         while (handler.getHandler() instanceof HandlerWrapper)
168         {
169             HandlerWrapper wrapper = (HandlerWrapper)handler.getHandler();
170             if (wrapper instanceof SessionHandler ||
171                 wrapper instanceof SecurityHandler ||
172                 wrapper instanceof ServletHandler)
173                 break;
174             handler=wrapper;
175         }
176         
177         if (getSessionHandler()!=null)
178         {
179             if (handler==this)
180                 super.setHandler(_sessionHandler);
181             else
182                 handler.setHandler(_sessionHandler);
183             handler=_sessionHandler;
184         }
185 
186         if (getSecurityHandler()!=null)
187         {
188             if (handler==this)
189                 super.setHandler(_securityHandler);
190             else
191                 handler.setHandler(_securityHandler);
192             handler=_securityHandler;
193         }
194 
195         if (getServletHandler()!=null)
196         {
197             if (handler==this)
198                 super.setHandler(_servletHandler);
199             else
200                 handler.setHandler(_servletHandler);
201             handler=_servletHandler;
202         } 
203     }
204     
205     /* ------------------------------------------------------------ */
206     /**
207      * @see org.eclipse.jetty.server.handler.ContextHandler#doStop()
208      */
209     @Override
210     protected void doStop() throws Exception
211     {
212         super.doStop();
213         if (_decorators != null)
214             _decorators.clear();
215     }
216 
217     /* ------------------------------------------------------------ */
218     /** Get the defaultSecurityHandlerClass.
219      * @return the defaultSecurityHandlerClass
220      */
221     public Class<? extends SecurityHandler> getDefaultSecurityHandlerClass()
222     {
223         return _defaultSecurityHandlerClass;
224     }
225 
226     /* ------------------------------------------------------------ */
227     /** Set the defaultSecurityHandlerClass.
228      * @param defaultSecurityHandlerClass the defaultSecurityHandlerClass to set
229      */
230     public void setDefaultSecurityHandlerClass(Class<? extends SecurityHandler> defaultSecurityHandlerClass)
231     {
232         _defaultSecurityHandlerClass = defaultSecurityHandlerClass;
233     }
234 
235     /* ------------------------------------------------------------ */
236     protected SessionHandler newSessionHandler()
237     {
238         return new SessionHandler();
239     }
240 
241     /* ------------------------------------------------------------ */
242     protected SecurityHandler newSecurityHandler()
243     {
244         try
245         {
246             return (SecurityHandler)_defaultSecurityHandlerClass.newInstance();
247         }
248         catch(Exception e)
249         {
250             throw new IllegalStateException(e);
251         }
252     }
253 
254     /* ------------------------------------------------------------ */
255     protected ServletHandler newServletHandler()
256     {
257         return new ServletHandler();
258     }
259 
260     /* ------------------------------------------------------------ */
261     /**
262      * Finish constructing handlers and link them together.
263      *
264      * @see org.eclipse.jetty.server.handler.ContextHandler#startContext()
265      */
266     @Override
267     protected void startContext() throws Exception
268     {
269     	
270     	if (_servletHandler != null)
271     	{
272     	    for (int i=_decorators.size()-1;i>=0; i--)
273     	    {
274     	        Decorator decorator = _decorators.get(i);
275                 if (_servletHandler.getFilters()!=null)
276                     for (FilterHolder holder:_servletHandler.getFilters())
277                         decorator.decorate(holder);
278     	        if(_servletHandler.getServlets()!=null)
279     	            for (ServletHolder holder:_servletHandler.getServlets())
280     	                decorator.decorate(holder);
281     	    }
282     	}
283     	
284         super.startContext();
285 
286         // OK to Initialize servlet handler now that all relevant object trees have been started
287         if (_servletHandler != null)
288             _servletHandler.initialize();
289     }
290 
291     /* ------------------------------------------------------------ */
292     /**
293      * @return Returns the securityHandler.
294      */
295     @ManagedAttribute(value="context security handler", readonly=true)
296     public SecurityHandler getSecurityHandler()
297     {
298         if (_securityHandler==null && (_options&SECURITY)!=0 && !isStarted())
299             _securityHandler=newSecurityHandler();
300 
301         return _securityHandler;
302     }
303 
304     /* ------------------------------------------------------------ */
305     /**
306      * @return Returns the servletHandler.
307      */
308     @ManagedAttribute(value="context servlet handler", readonly=true)
309     public ServletHandler getServletHandler()
310     {
311         if (_servletHandler==null && !isStarted())
312             _servletHandler=newServletHandler();
313         return _servletHandler;
314     }
315 
316     /* ------------------------------------------------------------ */
317     /**
318      * @return Returns the sessionHandler.
319      */
320     @ManagedAttribute(value="context session handler", readonly=true)
321     public SessionHandler getSessionHandler()
322     {
323         if (_sessionHandler==null && (_options&SESSIONS)!=0 && !isStarted())
324             _sessionHandler=newSessionHandler();
325         return _sessionHandler;
326     }
327 
328     /* ------------------------------------------------------------ */
329     /** conveniance method to add a servlet.
330      */
331     public ServletHolder addServlet(String className,String pathSpec)
332     {
333         return getServletHandler().addServletWithMapping(className, pathSpec);
334     }
335 
336     /* ------------------------------------------------------------ */
337     /** conveniance method to add a servlet.
338      */
339     public ServletHolder addServlet(Class<? extends Servlet> servlet,String pathSpec)
340     {
341         return getServletHandler().addServletWithMapping(servlet.getName(), pathSpec);
342     }
343 
344     /* ------------------------------------------------------------ */
345     /** conveniance method to add a servlet.
346      */
347     public void addServlet(ServletHolder servlet,String pathSpec)
348     {
349         getServletHandler().addServletWithMapping(servlet, pathSpec);
350     }
351 
352     /* ------------------------------------------------------------ */
353     /** conveniance method to add a filter
354      */
355     public void addFilter(FilterHolder holder,String pathSpec,EnumSet<DispatcherType> dispatches)
356     {
357         getServletHandler().addFilterWithMapping(holder,pathSpec,dispatches);
358     }
359 
360     /* ------------------------------------------------------------ */
361     /** convenience method to add a filter
362      */
363     public FilterHolder addFilter(Class<? extends Filter> filterClass,String pathSpec,EnumSet<DispatcherType> dispatches)
364     {
365         return getServletHandler().addFilterWithMapping(filterClass,pathSpec,dispatches);
366     }
367 
368     /* ------------------------------------------------------------ */
369     /** convenience method to add a filter
370      */
371     public FilterHolder addFilter(String filterClass,String pathSpec,EnumSet<DispatcherType> dispatches)
372     {
373         return getServletHandler().addFilterWithMapping(filterClass,pathSpec,dispatches);
374     }
375 
376     /**
377      * notification that a ServletRegistration has been created so we can track the annotations
378      * @param holder new holder created through the api.
379      * @return the ServletRegistration.Dynamic
380      */
381     protected ServletRegistration.Dynamic dynamicHolderAdded(ServletHolder holder) {
382         return holder.getRegistration();
383     }
384 
385     /**
386      * delegate for ServletContext.declareRole method
387      * @param roleNames role names to add
388      */
389     protected void addRoles(String... roleNames) {
390         //Get a reference to the SecurityHandler, which must be ConstraintAware
391         if (_securityHandler != null && _securityHandler instanceof ConstraintAware)
392         {
393             HashSet<String> union = new HashSet<String>();
394             Set<String> existing = ((ConstraintAware)_securityHandler).getRoles();
395             if (existing != null)
396                 union.addAll(existing);
397             union.addAll(Arrays.asList(roleNames));
398             ((ConstraintSecurityHandler)_securityHandler).setRoles(union);
399         }
400     }
401 
402     /**
403      * Delegate for ServletRegistration.Dynamic.setServletSecurity method
404      * @param registration ServletRegistration.Dynamic instance that setServletSecurity was called on
405      * @param servletSecurityElement new security info
406      * @return the set of exact URL mappings currently associated with the registration that are also present in the web.xml
407      * security constraints and thus will be unaffected by this call.
408      */
409     public Set<String> setServletSecurity(ServletRegistration.Dynamic registration, ServletSecurityElement servletSecurityElement)
410     {
411         //Default implementation is to just accept them all. If using a webapp, then this behaviour is overridden in WebAppContext.setServletSecurity       
412         Collection<String> pathSpecs = registration.getMappings();
413         if (pathSpecs != null)
414         {
415             for (String pathSpec:pathSpecs)
416             {
417                 List<ConstraintMapping> mappings = ConstraintSecurityHandler.createConstraintsWithMappingsForPath(registration.getName(), pathSpec, servletSecurityElement);
418                 for (ConstraintMapping m:mappings)
419                     ((ConstraintAware)getSecurityHandler()).addConstraintMapping(m);
420             }
421         }
422         return Collections.emptySet();
423     }
424 
425     @Override
426     public void callContextInitialized(ServletContextListener l, ServletContextEvent e)
427     {
428         try
429         {
430             //toggle state of the dynamic API so that the listener cannot use it
431             if(isProgrammaticListener(l))
432                 this.getServletContext().setEnabled(false);
433 
434             super.callContextInitialized(l, e);
435         }
436         finally
437         {
438             //untoggle the state of the dynamic API
439             this.getServletContext().setEnabled(true);
440         }
441     }
442 
443 
444     @Override
445     public void callContextDestroyed(ServletContextListener l, ServletContextEvent e)
446     {
447         super.callContextDestroyed(l, e);
448     }
449 
450     /* ------------------------------------------------------------ */
451     /**
452      * @param sessionHandler The sessionHandler to set.
453      */
454     public void setSessionHandler(SessionHandler sessionHandler)
455     {
456         if (isStarted())
457             throw new IllegalStateException("STARTED");
458 
459         if (_sessionHandler!=null)
460             _sessionHandler.setHandler(null);
461 
462         _sessionHandler = sessionHandler;
463         relinkHandlers();
464     }
465 
466     /* ------------------------------------------------------------ */
467     /**
468      * @param securityHandler The {@link SecurityHandler} to set on this context.
469      */
470     public void setSecurityHandler(SecurityHandler securityHandler)
471     {
472         if (isStarted())
473             throw new IllegalStateException("STARTED");
474 
475         if (_securityHandler!=null)
476             _securityHandler.setHandler(null);
477         _securityHandler = securityHandler;
478         relinkHandlers();
479     }
480 
481     /* ------------------------------------------------------------ */
482     /**
483      * @param servletHandler The servletHandler to set.
484      */
485     public void setServletHandler(ServletHandler servletHandler)
486     {
487         if (isStarted())
488             throw new IllegalStateException("STARTED");
489 
490         Handler next=null;
491         if (_servletHandler!=null)
492         {
493             next=_servletHandler.getHandler();
494             _servletHandler.setHandler(null);
495         }
496         _servletHandler = servletHandler;
497         relinkHandlers();
498         _servletHandler.setHandler(next);
499     }
500     
501     /* ------------------------------------------------------------ */
502     @Override
503     public void setHandler(Handler handler)
504     {
505         if (handler instanceof ServletHandler)
506             setServletHandler((ServletHandler) handler);
507         else if (handler instanceof SessionHandler)
508             setSessionHandler((SessionHandler) handler);
509         else if (handler instanceof SecurityHandler)
510             setSecurityHandler((SecurityHandler)handler);
511         else if (handler == null || handler instanceof HandlerWrapper)
512         {
513             super.setHandler(handler);
514             relinkHandlers();
515         }
516         else
517             throw new IllegalArgumentException();
518     }
519     
520     
521     /* ------------------------------------------------------------ */
522     /**
523      * Insert a HandlerWrapper before the first Session,Security or ServletHandler
524      * but after any other HandlerWrappers.
525      */
526     public void insertHandler(HandlerWrapper handler)
527     {
528         HandlerWrapper h=this;
529         
530         // Skip any injected handlers
531         while (h.getHandler() instanceof HandlerWrapper)
532         {
533             HandlerWrapper wrapper = (HandlerWrapper)h.getHandler();
534             if (wrapper instanceof SessionHandler ||
535                 wrapper instanceof SecurityHandler ||
536                 wrapper instanceof ServletHandler)
537                 break;
538             h=wrapper;
539         }
540         
541         h.setHandler(handler);
542         relinkHandlers();
543     }
544 
545     /* ------------------------------------------------------------ */
546     /**
547      * @return The decorator list used to resource inject new Filters, Servlets and EventListeners
548      */
549     public List<Decorator> getDecorators()
550     {
551         return Collections.unmodifiableList(_decorators);
552     }
553 
554     /* ------------------------------------------------------------ */
555     /**
556      * @param decorators The lis of {@link Decorator}s
557      */
558     public void setDecorators(List<Decorator> decorators)
559     {
560         _decorators.clear();
561         _decorators.addAll(decorators);
562     }
563 
564     /* ------------------------------------------------------------ */
565     /**
566      * @param decorator The decorator to add
567      */
568     public void addDecorator(Decorator decorator)
569     {
570         _decorators.add(decorator);
571     }
572 
573     /* ------------------------------------------------------------ */
574     void destroyServlet(Servlet servlet)
575     {
576         for (Decorator decorator : _decorators)
577             decorator.destroy(servlet);
578     }
579 
580     /* ------------------------------------------------------------ */
581     void destroyFilter(Filter filter)
582     {
583         for (Decorator decorator : _decorators)
584             decorator.destroy(filter);
585     }
586 
587     /* ------------------------------------------------------------ */
588     public static class JspPropertyGroup implements JspPropertyGroupDescriptor
589     {
590         private List<String> _urlPatterns = new ArrayList<String>();
591         private String _elIgnored;
592         private String _pageEncoding;
593         private String _scriptingInvalid;
594         private String _isXml;
595         private List<String> _includePreludes = new ArrayList<String>();
596         private List<String> _includeCodas = new ArrayList<String>();
597         private String _deferredSyntaxAllowedAsLiteral;
598         private String _trimDirectiveWhitespaces;
599         private String _defaultContentType;
600         private String _buffer;
601         private String _errorOnUndeclaredNamespace;
602 
603 
604 
605         /**
606          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getUrlPatterns()
607          */
608         public Collection<String> getUrlPatterns()
609         {
610             return new ArrayList<String>(_urlPatterns); // spec says must be a copy
611         }
612 
613         public void addUrlPattern (String s)
614         {
615             if (!_urlPatterns.contains(s))
616                 _urlPatterns.add(s);
617         }
618 
619         /**
620          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getElIgnored()
621          */
622         public String getElIgnored()
623         {
624             return _elIgnored;
625         }
626 
627         public void setElIgnored (String s)
628         {
629             _elIgnored = s;
630         }
631 
632         /**
633          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getPageEncoding()
634          */
635         public String getPageEncoding()
636         {
637             return _pageEncoding;
638         }
639 
640         public void setPageEncoding(String pageEncoding)
641         {
642             _pageEncoding = pageEncoding;
643         }
644 
645         public void setScriptingInvalid(String scriptingInvalid)
646         {
647             _scriptingInvalid = scriptingInvalid;
648         }
649 
650         public void setIsXml(String isXml)
651         {
652             _isXml = isXml;
653         }
654 
655         public void setDeferredSyntaxAllowedAsLiteral(String deferredSyntaxAllowedAsLiteral)
656         {
657             _deferredSyntaxAllowedAsLiteral = deferredSyntaxAllowedAsLiteral;
658         }
659 
660         public void setTrimDirectiveWhitespaces(String trimDirectiveWhitespaces)
661         {
662             _trimDirectiveWhitespaces = trimDirectiveWhitespaces;
663         }
664 
665         public void setDefaultContentType(String defaultContentType)
666         {
667             _defaultContentType = defaultContentType;
668         }
669 
670         public void setBuffer(String buffer)
671         {
672             _buffer = buffer;
673         }
674 
675         public void setErrorOnUndeclaredNamespace(String errorOnUndeclaredNamespace)
676         {
677             _errorOnUndeclaredNamespace = errorOnUndeclaredNamespace;
678         }
679 
680         /**
681          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getScriptingInvalid()
682          */
683         public String getScriptingInvalid()
684         {
685             return _scriptingInvalid;
686         }
687 
688         /**
689          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getIsXml()
690          */
691         public String getIsXml()
692         {
693             return _isXml;
694         }
695 
696         /**
697          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getIncludePreludes()
698          */
699         public Collection<String> getIncludePreludes()
700         {
701             return new ArrayList<String>(_includePreludes); //must be a copy
702         }
703 
704         public void addIncludePrelude(String prelude)
705         {
706             if (!_includePreludes.contains(prelude))
707                 _includePreludes.add(prelude);
708         }
709 
710         /**
711          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getIncludeCodas()
712          */
713         public Collection<String> getIncludeCodas()
714         {
715             return new ArrayList<String>(_includeCodas); //must be a copy
716         }
717 
718         public void addIncludeCoda (String coda)
719         {
720             if (!_includeCodas.contains(coda))
721                 _includeCodas.add(coda);
722         }
723 
724         /**
725          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getDeferredSyntaxAllowedAsLiteral()
726          */
727         public String getDeferredSyntaxAllowedAsLiteral()
728         {
729             return _deferredSyntaxAllowedAsLiteral;
730         }
731 
732         /**
733          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getTrimDirectiveWhitespaces()
734          */
735         public String getTrimDirectiveWhitespaces()
736         {
737             return _trimDirectiveWhitespaces;
738         }
739 
740         /**
741          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getDefaultContentType()
742          */
743         public String getDefaultContentType()
744         {
745             return _defaultContentType;
746         }
747 
748         /**
749          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getBuffer()
750          */
751         public String getBuffer()
752         {
753             return _buffer;
754         }
755 
756         /**
757          * @see javax.servlet.descriptor.JspPropertyGroupDescriptor#getErrorOnUndeclaredNamespace()
758          */
759         public String getErrorOnUndeclaredNamespace()
760         {
761             return _errorOnUndeclaredNamespace;
762         }
763 
764         public String toString ()
765         {
766             StringBuffer sb = new StringBuffer();
767             sb.append("JspPropertyGroupDescriptor:");
768             sb.append(" el-ignored="+_elIgnored);
769             sb.append(" is-xml="+_isXml);
770             sb.append(" page-encoding="+_pageEncoding);
771             sb.append(" scripting-invalid="+_scriptingInvalid);
772             sb.append(" deferred-syntax-allowed-as-literal="+_deferredSyntaxAllowedAsLiteral);
773             sb.append(" trim-directive-whitespaces"+_trimDirectiveWhitespaces);
774             sb.append(" default-content-type="+_defaultContentType);
775             sb.append(" buffer="+_buffer);
776             sb.append(" error-on-undeclared-namespace="+_errorOnUndeclaredNamespace);
777             for (String prelude:_includePreludes)
778                 sb.append(" include-prelude="+prelude);
779             for (String coda:_includeCodas)
780                 sb.append(" include-coda="+coda);
781             return sb.toString();
782         }
783     }
784 
785     /* ------------------------------------------------------------ */
786     public static class TagLib implements TaglibDescriptor
787     {
788         private String _uri;
789         private String _location;
790 
791         /**
792          * @see javax.servlet.descriptor.TaglibDescriptor#getTaglibURI()
793          */
794         public String getTaglibURI()
795         {
796            return _uri;
797         }
798 
799         public void setTaglibURI(String uri)
800         {
801             _uri = uri;
802         }
803 
804         /**
805          * @see javax.servlet.descriptor.TaglibDescriptor#getTaglibLocation()
806          */
807         public String getTaglibLocation()
808         {
809             return _location;
810         }
811 
812         public void setTaglibLocation(String location)
813         {
814             _location = location;
815         }
816 
817         public String toString()
818         {
819             return ("TagLibDescriptor: taglib-uri="+_uri+" location="+_location);
820         }
821     }
822 
823 
824     /* ------------------------------------------------------------ */
825     public static class JspConfig implements JspConfigDescriptor
826     {
827         private List<TaglibDescriptor> _taglibs = new ArrayList<TaglibDescriptor>();
828         private List<JspPropertyGroupDescriptor> _jspPropertyGroups = new ArrayList<JspPropertyGroupDescriptor>();
829 
830         public JspConfig() {}
831 
832         /**
833          * @see javax.servlet.descriptor.JspConfigDescriptor#getTaglibs()
834          */
835         public Collection<TaglibDescriptor> getTaglibs()
836         {
837             return new ArrayList<TaglibDescriptor>(_taglibs);
838         }
839 
840         public void addTaglibDescriptor (TaglibDescriptor d)
841         {
842             _taglibs.add(d);
843         }
844 
845         /**
846          * @see javax.servlet.descriptor.JspConfigDescriptor#getJspPropertyGroups()
847          */
848         public Collection<JspPropertyGroupDescriptor> getJspPropertyGroups()
849         {
850            return new ArrayList<JspPropertyGroupDescriptor>(_jspPropertyGroups);
851         }
852 
853         public void addJspPropertyGroup(JspPropertyGroupDescriptor g)
854         {
855             _jspPropertyGroups.add(g);
856         }
857 
858         public String toString()
859         {
860             StringBuffer sb = new StringBuffer();
861             sb.append("JspConfigDescriptor: \n");
862             for (TaglibDescriptor taglib:_taglibs)
863                 sb.append(taglib+"\n");
864             for (JspPropertyGroupDescriptor jpg:_jspPropertyGroups)
865                 sb.append(jpg+"\n");
866             return sb.toString();
867         }
868     }
869 
870 
871     /* ------------------------------------------------------------ */
872     public class Context extends ContextHandler.Context
873     {
874         /* ------------------------------------------------------------ */
875         /*
876          * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
877          */
878         @Override
879         public RequestDispatcher getNamedDispatcher(String name)
880         {
881             ContextHandler context=org.eclipse.jetty.servlet.ServletContextHandler.this;
882             if (_servletHandler==null)
883                 return null;
884             ServletHolder holder = _servletHandler.getServlet(name);
885             if (holder==null || !holder.isEnabled())
886                 return null;
887             return new Dispatcher(context, name);
888         }
889 
890         /* ------------------------------------------------------------ */
891         /**
892          * @since servlet-api-3.0
893          */
894         @Override
895         public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass)
896         {
897             if (isStarted())
898                 throw new IllegalStateException();
899             
900             if (filterName == null || "".equals(filterName.trim()))
901                 throw new IllegalStateException("Missing filter name");
902 
903             if (!_enabled)
904                 throw new UnsupportedOperationException();
905 
906             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
907             FilterHolder holder = handler.getFilter(filterName);
908             if (holder == null)
909             {
910                 //new filter
911                 holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
912                 holder.setName(filterName);
913                 holder.setHeldClass(filterClass);
914                 handler.addFilter(holder);
915                 return holder.getRegistration();
916             }
917             if (holder.getClassName()==null && holder.getHeldClass()==null)
918             {
919                 //preliminary filter registration completion
920                 holder.setHeldClass(filterClass);
921                 return holder.getRegistration();
922             }
923             else
924                 return null; //existing filter
925         }
926 
927         /* ------------------------------------------------------------ */
928         /**
929          * @since servlet-api-3.0
930          */
931         @Override
932         public FilterRegistration.Dynamic addFilter(String filterName, String className)
933         {
934             if (isStarted())
935                 throw new IllegalStateException();
936             
937             if (filterName == null || "".equals(filterName.trim()))
938                 throw new IllegalStateException("Missing filter name");
939 
940             if (!_enabled)
941                 throw new UnsupportedOperationException();
942 
943             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
944             FilterHolder holder = handler.getFilter(filterName);
945             if (holder == null)
946             {
947                 //new filter
948                 holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
949                 holder.setName(filterName);
950                 holder.setClassName(className);
951                 handler.addFilter(holder);
952                 return holder.getRegistration();
953             }
954             if (holder.getClassName()==null && holder.getHeldClass()==null)
955             {
956                 //preliminary filter registration completion
957                 holder.setClassName(className);
958                 return holder.getRegistration();
959             }
960             else
961                 return null; //existing filter
962         }
963 
964 
965         /* ------------------------------------------------------------ */
966         /**
967          * @since servlet-api-3.0
968          */
969         @Override
970         public FilterRegistration.Dynamic addFilter(String filterName, Filter filter)
971         {
972             if (isStarted())
973                 throw new IllegalStateException();
974 
975             if (filterName == null || "".equals(filterName.trim()))
976                 throw new IllegalStateException("Missing filter name");
977             
978             if (!_enabled)
979                 throw new UnsupportedOperationException();
980 
981             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
982             FilterHolder holder = handler.getFilter(filterName);
983             if (holder == null)
984             {
985                 //new filter
986                 holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
987                 holder.setName(filterName);
988                 holder.setFilter(filter);
989                 handler.addFilter(holder);
990                 return holder.getRegistration();
991             }
992 
993             if (holder.getClassName()==null && holder.getHeldClass()==null)
994             {
995                 //preliminary filter registration completion
996                 holder.setFilter(filter);
997                 return holder.getRegistration();
998             }
999             else
1000                 return null; //existing filter
1001         }
1002 
1003         /* ------------------------------------------------------------ */
1004         /**
1005          * @since servlet-api-3.0
1006          */
1007         @Override
1008         public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)
1009         {
1010             if (!isStarting())
1011                 throw new IllegalStateException();
1012 
1013             if (servletName == null || "".equals(servletName.trim()))
1014                 throw new IllegalStateException("Missing servlet name");
1015             
1016             if (!_enabled)
1017                 throw new UnsupportedOperationException();
1018 
1019             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
1020             ServletHolder holder = handler.getServlet(servletName);
1021             if (holder == null)
1022             {
1023                 //new servlet
1024                 holder = handler.newServletHolder(Holder.Source.JAVAX_API);
1025                 holder.setName(servletName);
1026                 holder.setHeldClass(servletClass);
1027                 handler.addServlet(holder);
1028                 return dynamicHolderAdded(holder);
1029             }
1030 
1031             //complete a partial registration
1032             if (holder.getClassName()==null && holder.getHeldClass()==null)
1033             {
1034                 holder.setHeldClass(servletClass);
1035                 return holder.getRegistration();
1036             }
1037             else
1038                 return null; //existing completed registration for servlet name
1039         }
1040 
1041         /* ------------------------------------------------------------ */
1042         /**
1043          * @since servlet-api-3.0
1044          */
1045         @Override
1046         public ServletRegistration.Dynamic addServlet(String servletName, String className)
1047         {
1048             if (!isStarting())
1049                 throw new IllegalStateException();
1050 
1051             if (servletName == null || "".equals(servletName.trim()))
1052                 throw new IllegalStateException("Missing servlet name");
1053             
1054             if (!_enabled)
1055                 throw new UnsupportedOperationException();
1056 
1057 
1058             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
1059             ServletHolder holder = handler.getServlet(servletName);
1060             if (holder == null)
1061             {
1062                 //new servlet
1063                 holder = handler.newServletHolder(Holder.Source.JAVAX_API);
1064                 holder.setName(servletName);
1065                 holder.setClassName(className);
1066                 handler.addServlet(holder);
1067                 return dynamicHolderAdded(holder);
1068             }
1069 
1070             //complete a partial registration
1071             if (holder.getClassName()==null && holder.getHeldClass()==null)
1072             {
1073                 holder.setClassName(className);
1074                 return holder.getRegistration();
1075             }
1076             else
1077                 return null; //existing completed registration for servlet name
1078         }
1079 
1080         /* ------------------------------------------------------------ */
1081         /**
1082          * @since servlet-api-3.0
1083          */
1084         @Override
1085         public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
1086         {
1087             if (!isStarting())
1088                 throw new IllegalStateException();
1089             
1090             if (servletName == null || "".equals(servletName.trim()))
1091                 throw new IllegalStateException("Missing servlet name");
1092             
1093             if (!_enabled)
1094                 throw new UnsupportedOperationException();
1095 
1096             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
1097             ServletHolder holder = handler.getServlet(servletName);
1098             if (holder == null)
1099             {
1100                 holder = handler.newServletHolder(Holder.Source.JAVAX_API);
1101                 holder.setName(servletName);
1102                 holder.setServlet(servlet);
1103                 handler.addServlet(holder);
1104                 return dynamicHolderAdded(holder);
1105             }
1106 
1107             //complete a partial registration
1108             if (holder.getClassName()==null && holder.getHeldClass()==null)
1109             {
1110                 holder.setServlet(servlet);
1111                 return holder.getRegistration();
1112             }
1113             else
1114                 return null; //existing completed registration for servlet name
1115         }
1116 
1117         /* ------------------------------------------------------------ */
1118         @Override
1119         public boolean setInitParameter(String name, String value)
1120         {
1121             if (!isStarting())
1122                 throw new IllegalStateException();
1123 
1124             if (!_enabled)
1125                 throw new UnsupportedOperationException();
1126 
1127             return super.setInitParameter(name,value);
1128         }
1129 
1130         /* ------------------------------------------------------------ */
1131         @Override
1132         public <T extends Filter> T createFilter(Class<T> c) throws ServletException
1133         {
1134             try
1135             {
1136                 T f = createInstance(c);
1137                 return f;
1138             }
1139             catch (Exception e)
1140             {
1141                 throw new ServletException(e);
1142             }
1143         }
1144 
1145         /* ------------------------------------------------------------ */
1146         @Override
1147         public <T extends Servlet> T createServlet(Class<T> c) throws ServletException
1148         {
1149             try
1150             {
1151                 T s = createInstance(c);
1152                 return s;
1153             }
1154             catch (Exception e)
1155             {
1156                 throw new ServletException(e);
1157             }
1158         }
1159         
1160         
1161         
1162         public <T> T createInstance (Class<T> c) throws Exception
1163         {
1164               T o = super.createInstance(c);
1165               for (int i=_decorators.size()-1; i>=0; i--)
1166               {
1167                   Decorator decorator = _decorators.get(i);
1168                   o=decorator.decorate(o);
1169               }
1170               return o;
1171         }
1172         
1173         
1174 
1175         @Override
1176         public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
1177         {
1178             if (_sessionHandler!=null)
1179                 return _sessionHandler.getSessionManager().getDefaultSessionTrackingModes();
1180             return null;
1181         }
1182 
1183         @Override
1184         public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
1185         {
1186             if (_sessionHandler!=null)
1187                 return _sessionHandler.getSessionManager().getEffectiveSessionTrackingModes();
1188             return null;
1189         }
1190 
1191         @Override
1192         public FilterRegistration getFilterRegistration(String filterName)
1193         {
1194             if (!_enabled)
1195                 throw new UnsupportedOperationException();
1196 
1197             final FilterHolder holder=ServletContextHandler.this.getServletHandler().getFilter(filterName);
1198             return (holder==null)?null:holder.getRegistration();
1199         }
1200 
1201         @Override
1202         public Map<String, ? extends FilterRegistration> getFilterRegistrations()
1203         {
1204             if (!_enabled)
1205                 throw new UnsupportedOperationException();
1206 
1207             HashMap<String, FilterRegistration> registrations = new HashMap<String, FilterRegistration>();
1208             ServletHandler handler=ServletContextHandler.this.getServletHandler();
1209             FilterHolder[] holders=handler.getFilters();
1210             if (holders!=null)
1211             {
1212                 for (FilterHolder holder : holders)
1213                     registrations.put(holder.getName(),holder.getRegistration());
1214             }
1215             return registrations;
1216         }
1217 
1218         @Override
1219         public ServletRegistration getServletRegistration(String servletName)
1220         {
1221             if (!_enabled)
1222                 throw new UnsupportedOperationException();
1223 
1224             final ServletHolder holder=ServletContextHandler.this.getServletHandler().getServlet(servletName);
1225             return (holder==null)?null:holder.getRegistration();
1226         }
1227 
1228         @Override
1229         public Map<String, ? extends ServletRegistration> getServletRegistrations()
1230         {
1231             if (!_enabled)
1232                 throw new UnsupportedOperationException();
1233 
1234             HashMap<String, ServletRegistration> registrations = new HashMap<String, ServletRegistration>();
1235             ServletHandler handler=ServletContextHandler.this.getServletHandler();
1236             ServletHolder[] holders=handler.getServlets();
1237             if (holders!=null)
1238             {
1239                 for (ServletHolder holder : holders)
1240                     registrations.put(holder.getName(),holder.getRegistration());
1241             }
1242             return registrations;
1243         }
1244 
1245         @Override
1246         public SessionCookieConfig getSessionCookieConfig()
1247         {
1248             if (!_enabled)
1249                 throw new UnsupportedOperationException();
1250 
1251             if (_sessionHandler!=null)
1252                 return _sessionHandler.getSessionManager().getSessionCookieConfig();
1253             return null;
1254         }
1255 
1256         @Override
1257         public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
1258         {
1259             if (!isStarting())
1260                 throw new IllegalStateException();
1261             if (!_enabled)
1262                 throw new UnsupportedOperationException();
1263 
1264 
1265             if (_sessionHandler!=null)
1266                 _sessionHandler.getSessionManager().setSessionTrackingModes(sessionTrackingModes);
1267         }
1268 
1269         @Override
1270         public void addListener(String className)
1271         {
1272             if (!isStarting())
1273                 throw new IllegalStateException();
1274             if (!_enabled)
1275                 throw new UnsupportedOperationException();
1276             super.addListener(className);
1277         }
1278 
1279         @Override
1280         public <T extends EventListener> void addListener(T t)
1281         {
1282             if (!isStarting())
1283                 throw new IllegalStateException();
1284             if (!_enabled)
1285                 throw new UnsupportedOperationException();
1286             super.addListener(t);
1287         }
1288 
1289         @Override
1290         public void addListener(Class<? extends EventListener> listenerClass)
1291         {
1292             if (!isStarting())
1293                 throw new IllegalStateException();
1294             if (!_enabled)
1295                 throw new UnsupportedOperationException();
1296             super.addListener(listenerClass);
1297         }
1298 
1299         @Override
1300         public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
1301         {
1302             try
1303             {
1304                 T l = createInstance(clazz);
1305                 return l;
1306             }            
1307             catch (Exception e)
1308             {
1309                 throw new ServletException(e);
1310             }
1311         }
1312 
1313 
1314         @Override
1315         public JspConfigDescriptor getJspConfigDescriptor()
1316         {
1317             return _jspConfig;
1318         }
1319 
1320         @Override
1321         public void setJspConfigDescriptor(JspConfigDescriptor d)
1322         {
1323             _jspConfig = d;
1324         }
1325 
1326 
1327         @Override
1328         public void declareRoles(String... roleNames)
1329         {
1330             if (!isStarting())
1331                 throw new IllegalStateException();
1332             if (!_enabled)
1333                 throw new UnsupportedOperationException();
1334             addRoles(roleNames);
1335 
1336 
1337         }
1338 
1339     }
1340 
1341 
1342 
1343     /* ------------------------------------------------------------ */
1344     /** Interface to decorate loaded classes.
1345      */
1346     public interface Decorator
1347     {
1348         <T> T decorate (T o);
1349         void destroy (Object o);
1350     }
1351 }