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.decorateFilterHolder(holder);
278     	        if(_servletHandler.getServlets()!=null)
279     	            for (ServletHolder holder:_servletHandler.getServlets())
280     	                decorator.decorateServletHolder(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.destroyServletInstance(servlet);
578     }
579 
580     /* ------------------------------------------------------------ */
581     void destroyFilter(Filter filter)
582     {
583         for (Decorator decorator : _decorators)
584             decorator.destroyFilterInstance(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 (!_enabled)
901                 throw new UnsupportedOperationException();
902 
903             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
904             FilterHolder holder = handler.getFilter(filterName);
905             if (holder == null)
906             {
907                 //new filter
908                 holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
909                 holder.setName(filterName);
910                 holder.setHeldClass(filterClass);
911                 handler.addFilter(holder);
912                 return holder.getRegistration();
913             }
914             if (holder.getClassName()==null && holder.getHeldClass()==null)
915             {
916                 //preliminary filter registration completion
917                 holder.setHeldClass(filterClass);
918                 return holder.getRegistration();
919             }
920             else
921                 return null; //existing filter
922         }
923 
924         /* ------------------------------------------------------------ */
925         /**
926          * @since servlet-api-3.0
927          */
928         @Override
929         public FilterRegistration.Dynamic addFilter(String filterName, String className)
930         {
931             if (isStarted())
932                 throw new IllegalStateException();
933 
934             if (!_enabled)
935                 throw new UnsupportedOperationException();
936 
937             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
938             FilterHolder holder = handler.getFilter(filterName);
939             if (holder == null)
940             {
941                 //new filter
942                 holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
943                 holder.setName(filterName);
944                 holder.setClassName(className);
945                 handler.addFilter(holder);
946                 return holder.getRegistration();
947             }
948             if (holder.getClassName()==null && holder.getHeldClass()==null)
949             {
950                 //preliminary filter registration completion
951                 holder.setClassName(className);
952                 return holder.getRegistration();
953             }
954             else
955                 return null; //existing filter
956         }
957 
958 
959         /* ------------------------------------------------------------ */
960         /**
961          * @since servlet-api-3.0
962          */
963         @Override
964         public FilterRegistration.Dynamic addFilter(String filterName, Filter filter)
965         {
966             if (isStarted())
967                 throw new IllegalStateException();
968 
969             if (!_enabled)
970                 throw new UnsupportedOperationException();
971 
972             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
973             FilterHolder holder = handler.getFilter(filterName);
974             if (holder == null)
975             {
976                 //new filter
977                 holder = handler.newFilterHolder(Holder.Source.JAVAX_API);
978                 holder.setName(filterName);
979                 holder.setFilter(filter);
980                 handler.addFilter(holder);
981                 return holder.getRegistration();
982             }
983 
984             if (holder.getClassName()==null && holder.getHeldClass()==null)
985             {
986                 //preliminary filter registration completion
987                 holder.setFilter(filter);
988                 return holder.getRegistration();
989             }
990             else
991                 return null; //existing filter
992         }
993 
994         /* ------------------------------------------------------------ */
995         /**
996          * @since servlet-api-3.0
997          */
998         @Override
999         public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)
1000         {
1001             if (!isStarting())
1002                 throw new IllegalStateException();
1003 
1004             if (!_enabled)
1005                 throw new UnsupportedOperationException();
1006 
1007             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
1008             ServletHolder holder = handler.getServlet(servletName);
1009             if (holder == null)
1010             {
1011                 //new servlet
1012                 holder = handler.newServletHolder(Holder.Source.JAVAX_API);
1013                 holder.setName(servletName);
1014                 holder.setHeldClass(servletClass);
1015                 handler.addServlet(holder);
1016                 return dynamicHolderAdded(holder);
1017             }
1018 
1019             //complete a partial registration
1020             if (holder.getClassName()==null && holder.getHeldClass()==null)
1021             {
1022                 holder.setHeldClass(servletClass);
1023                 return holder.getRegistration();
1024             }
1025             else
1026                 return null; //existing completed registration for servlet name
1027         }
1028 
1029         /* ------------------------------------------------------------ */
1030         /**
1031          * @since servlet-api-3.0
1032          */
1033         @Override
1034         public ServletRegistration.Dynamic addServlet(String servletName, String className)
1035         {
1036             if (!isStarting())
1037                 throw new IllegalStateException();
1038 
1039             if (!_enabled)
1040                 throw new UnsupportedOperationException();
1041 
1042 
1043             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
1044             ServletHolder holder = handler.getServlet(servletName);
1045             if (holder == null)
1046             {
1047                 //new servlet
1048                 holder = handler.newServletHolder(Holder.Source.JAVAX_API);
1049                 holder.setName(servletName);
1050                 holder.setClassName(className);
1051                 handler.addServlet(holder);
1052                 return dynamicHolderAdded(holder);
1053             }
1054 
1055             //complete a partial registration
1056             if (holder.getClassName()==null && holder.getHeldClass()==null)
1057             {
1058                 holder.setClassName(className);
1059                 return holder.getRegistration();
1060             }
1061             else
1062                 return null; //existing completed registration for servlet name
1063         }
1064 
1065         /* ------------------------------------------------------------ */
1066         /**
1067          * @since servlet-api-3.0
1068          */
1069         @Override
1070         public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
1071         {
1072             if (!isStarting())
1073                 throw new IllegalStateException();
1074 
1075             if (!_enabled)
1076                 throw new UnsupportedOperationException();
1077 
1078             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
1079             ServletHolder holder = handler.getServlet(servletName);
1080             if (holder == null)
1081             {
1082                 holder = handler.newServletHolder(Holder.Source.JAVAX_API);
1083                 holder.setName(servletName);
1084                 holder.setServlet(servlet);
1085                 handler.addServlet(holder);
1086                 return dynamicHolderAdded(holder);
1087             }
1088 
1089             //complete a partial registration
1090             if (holder.getClassName()==null && holder.getHeldClass()==null)
1091             {
1092                 holder.setServlet(servlet);
1093                 return holder.getRegistration();
1094             }
1095             else
1096                 return null; //existing completed registration for servlet name
1097         }
1098 
1099         /* ------------------------------------------------------------ */
1100         @Override
1101         public boolean setInitParameter(String name, String value)
1102         {
1103             if (!isStarting())
1104                 throw new IllegalStateException();
1105 
1106             if (!_enabled)
1107                 throw new UnsupportedOperationException();
1108 
1109             return super.setInitParameter(name,value);
1110         }
1111 
1112         /* ------------------------------------------------------------ */
1113         @Override
1114         public <T extends Filter> T createFilter(Class<T> c) throws ServletException
1115         {
1116             try
1117             {
1118                 T f = c.newInstance();
1119                 for (int i=_decorators.size()-1; i>=0; i--)
1120                 {
1121                     Decorator decorator = _decorators.get(i);
1122                     f=decorator.decorateFilterInstance(f);
1123                 }
1124                 return f;
1125             }
1126             catch (InstantiationException e)
1127             {
1128                 throw new ServletException(e);
1129             }
1130             catch (IllegalAccessException e)
1131             {
1132                 throw new ServletException(e);
1133             }
1134         }
1135 
1136         /* ------------------------------------------------------------ */
1137         @Override
1138         public <T extends Servlet> T createServlet(Class<T> c) throws ServletException
1139         {
1140             try
1141             {
1142                 T s = c.newInstance();
1143                 for (int i=_decorators.size()-1; i>=0; i--)
1144                 {
1145                     Decorator decorator = _decorators.get(i);
1146                     s=decorator.decorateServletInstance(s);
1147                 }
1148                 return s;
1149             }
1150             catch (InstantiationException e)
1151             {
1152                 throw new ServletException(e);
1153             }
1154             catch (IllegalAccessException e)
1155             {
1156                 throw new ServletException(e);
1157             }
1158         }
1159 
1160         @Override
1161         public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
1162         {
1163             if (_sessionHandler!=null)
1164                 return _sessionHandler.getSessionManager().getDefaultSessionTrackingModes();
1165             return null;
1166         }
1167 
1168         @Override
1169         public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
1170         {
1171             if (_sessionHandler!=null)
1172                 return _sessionHandler.getSessionManager().getEffectiveSessionTrackingModes();
1173             return null;
1174         }
1175 
1176         @Override
1177         public FilterRegistration getFilterRegistration(String filterName)
1178         {
1179             if (!_enabled)
1180                 throw new UnsupportedOperationException();
1181 
1182             final FilterHolder holder=ServletContextHandler.this.getServletHandler().getFilter(filterName);
1183             return (holder==null)?null:holder.getRegistration();
1184         }
1185 
1186         @Override
1187         public Map<String, ? extends FilterRegistration> getFilterRegistrations()
1188         {
1189             if (!_enabled)
1190                 throw new UnsupportedOperationException();
1191 
1192             HashMap<String, FilterRegistration> registrations = new HashMap<String, FilterRegistration>();
1193             ServletHandler handler=ServletContextHandler.this.getServletHandler();
1194             FilterHolder[] holders=handler.getFilters();
1195             if (holders!=null)
1196             {
1197                 for (FilterHolder holder : holders)
1198                     registrations.put(holder.getName(),holder.getRegistration());
1199             }
1200             return registrations;
1201         }
1202 
1203         @Override
1204         public ServletRegistration getServletRegistration(String servletName)
1205         {
1206             if (!_enabled)
1207                 throw new UnsupportedOperationException();
1208 
1209             final ServletHolder holder=ServletContextHandler.this.getServletHandler().getServlet(servletName);
1210             return (holder==null)?null:holder.getRegistration();
1211         }
1212 
1213         @Override
1214         public Map<String, ? extends ServletRegistration> getServletRegistrations()
1215         {
1216             if (!_enabled)
1217                 throw new UnsupportedOperationException();
1218 
1219             HashMap<String, ServletRegistration> registrations = new HashMap<String, ServletRegistration>();
1220             ServletHandler handler=ServletContextHandler.this.getServletHandler();
1221             ServletHolder[] holders=handler.getServlets();
1222             if (holders!=null)
1223             {
1224                 for (ServletHolder holder : holders)
1225                     registrations.put(holder.getName(),holder.getRegistration());
1226             }
1227             return registrations;
1228         }
1229 
1230         @Override
1231         public SessionCookieConfig getSessionCookieConfig()
1232         {
1233             if (!_enabled)
1234                 throw new UnsupportedOperationException();
1235 
1236             if (_sessionHandler!=null)
1237                 return _sessionHandler.getSessionManager().getSessionCookieConfig();
1238             return null;
1239         }
1240 
1241         @Override
1242         public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
1243         {
1244             if (!isStarting())
1245                 throw new IllegalStateException();
1246             if (!_enabled)
1247                 throw new UnsupportedOperationException();
1248 
1249 
1250             if (_sessionHandler!=null)
1251                 _sessionHandler.getSessionManager().setSessionTrackingModes(sessionTrackingModes);
1252         }
1253 
1254         @Override
1255         public void addListener(String className)
1256         {
1257             if (!isStarting())
1258                 throw new IllegalStateException();
1259             if (!_enabled)
1260                 throw new UnsupportedOperationException();
1261             super.addListener(className);
1262         }
1263 
1264         @Override
1265         public <T extends EventListener> void addListener(T t)
1266         {
1267             if (!isStarting())
1268                 throw new IllegalStateException();
1269             if (!_enabled)
1270                 throw new UnsupportedOperationException();
1271             super.addListener(t);
1272         }
1273 
1274         @Override
1275         public void addListener(Class<? extends EventListener> listenerClass)
1276         {
1277             if (!isStarting())
1278                 throw new IllegalStateException();
1279             if (!_enabled)
1280                 throw new UnsupportedOperationException();
1281             super.addListener(listenerClass);
1282         }
1283 
1284         @Override
1285         public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
1286         {
1287             try
1288             {
1289                 T l = super.createListener(clazz);
1290 
1291                 for (int i=_decorators.size()-1; i>=0; i--)
1292                 {
1293                     Decorator decorator = _decorators.get(i);
1294                     l=decorator.decorateListenerInstance(l);
1295                 }
1296                 return l;
1297             }
1298             catch(ServletException e)
1299             {
1300                 throw e;
1301             }
1302             catch(Exception e)
1303             {
1304                 throw new ServletException(e);
1305             }
1306         }
1307 
1308 
1309         @Override
1310         public JspConfigDescriptor getJspConfigDescriptor()
1311         {
1312             return _jspConfig;
1313         }
1314 
1315         @Override
1316         public void setJspConfigDescriptor(JspConfigDescriptor d)
1317         {
1318             _jspConfig = d;
1319         }
1320 
1321 
1322         @Override
1323         public void declareRoles(String... roleNames)
1324         {
1325             if (!isStarting())
1326                 throw new IllegalStateException();
1327             if (!_enabled)
1328                 throw new UnsupportedOperationException();
1329             addRoles(roleNames);
1330 
1331 
1332         }
1333 
1334     }
1335 
1336 
1337 
1338     /* ------------------------------------------------------------ */
1339     /** Interface to decorate loaded classes.
1340      */
1341     public interface Decorator
1342     {
1343         <T extends Filter> T decorateFilterInstance(T filter) throws ServletException;
1344         <T extends Servlet> T decorateServletInstance(T servlet) throws ServletException;
1345         <T extends EventListener> T decorateListenerInstance(T listener) throws ServletException;
1346 
1347         void decorateFilterHolder(FilterHolder filter) throws ServletException;
1348         void decorateServletHolder(ServletHolder servlet) throws ServletException;
1349 
1350         void destroyServletInstance(Servlet s);
1351         void destroyFilterInstance(Filter f);
1352         void destroyListenerInstance(EventListener f);
1353     }
1354 }