View Javadoc

1   // ========================================================================
2   // Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.servlet;
15  
16  import java.util.ArrayList;
17  import java.util.Arrays;
18  import java.util.Collections;
19  import java.util.EnumSet;
20  import java.util.EventListener;
21  import java.util.HashMap;
22  import java.util.HashSet;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.Set;
26  
27  import javax.servlet.DispatcherType;
28  import javax.servlet.Filter;
29  import javax.servlet.FilterRegistration;
30  import javax.servlet.RequestDispatcher;
31  import javax.servlet.Servlet;
32  import javax.servlet.ServletContext;
33  import javax.servlet.ServletContextEvent;
34  import javax.servlet.ServletContextListener;
35  import javax.servlet.ServletException;
36  import javax.servlet.ServletRegistration;
37  import javax.servlet.ServletSecurityElement;
38  import javax.servlet.SessionCookieConfig;
39  import javax.servlet.SessionTrackingMode;
40  import javax.servlet.descriptor.JspConfigDescriptor;
41  
42  import org.eclipse.jetty.security.ConstraintAware;
43  import org.eclipse.jetty.security.ConstraintSecurityHandler;
44  import org.eclipse.jetty.security.SecurityHandler;
45  import org.eclipse.jetty.server.Dispatcher;
46  import org.eclipse.jetty.server.Handler;
47  import org.eclipse.jetty.server.HandlerContainer;
48  import org.eclipse.jetty.server.handler.ContextHandler;
49  import org.eclipse.jetty.server.handler.ErrorHandler;
50  import org.eclipse.jetty.server.handler.HandlerCollection;
51  import org.eclipse.jetty.server.handler.HandlerWrapper;
52  import org.eclipse.jetty.server.session.SessionHandler;
53  import org.eclipse.jetty.util.LazyList;
54  
55  
56  /* ------------------------------------------------------------ */
57  /** Servlet Context.
58   * This extension to the ContextHandler allows for
59   * simple construction of a context with ServletHandler and optionally
60   * session and security handlers, et.<pre>
61   *   new ServletContext("/context",Context.SESSIONS|Context.NO_SECURITY);
62   * </pre>
63   * <p/>
64   * This class should have been called ServletContext, but this would have
65   * cause confusion with {@link ServletContext}.
66   */
67  public class ServletContextHandler extends ContextHandler
68  {   
69      public final static int SESSIONS=1;
70      public final static int SECURITY=2;
71      public final static int NO_SESSIONS=0;
72      public final static int NO_SECURITY=0;
73  
74      protected final List<Decorator> _decorators= new ArrayList<Decorator>();
75      protected Class<? extends SecurityHandler> _defaultSecurityHandlerClass=org.eclipse.jetty.security.ConstraintSecurityHandler.class;
76      protected SessionHandler _sessionHandler;
77      protected SecurityHandler _securityHandler;
78      protected ServletHandler _servletHandler;
79      protected HandlerWrapper _wrapper;
80      protected int _options;
81      protected JspConfigDescriptor _jspConfig;
82      protected Object _restrictedContextListeners;
83      private boolean _restrictListeners = true;
84  
85      /* ------------------------------------------------------------ */
86      public ServletContextHandler()
87      {
88          this(null,null,null,null,null);
89      }
90      
91      /* ------------------------------------------------------------ */
92      public ServletContextHandler(int options)
93      {
94          this(null,null,options);
95      }
96      
97      /* ------------------------------------------------------------ */
98      public ServletContextHandler(HandlerContainer parent, String contextPath)
99      {
100         this(parent,contextPath,null,null,null,null);
101     }
102     
103     /* ------------------------------------------------------------ */
104     public ServletContextHandler(HandlerContainer parent, String contextPath, int options)
105     {
106         this(parent,contextPath,null,null,null,null);
107         _options=options;
108     }
109     
110     /* ------------------------------------------------------------ */
111     public ServletContextHandler(HandlerContainer parent, String contextPath, boolean sessions, boolean security)
112     {
113         this(parent,contextPath,(sessions?SESSIONS:0)|(security?SECURITY:0));
114     }
115 
116     /* ------------------------------------------------------------ */
117     public ServletContextHandler(HandlerContainer parent, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
118     {   
119         this(parent,null,sessionHandler,securityHandler,servletHandler,errorHandler);
120     }
121 
122     /* ------------------------------------------------------------ */
123     public ServletContextHandler(HandlerContainer parent, String contextPath, SessionHandler sessionHandler, SecurityHandler securityHandler, ServletHandler servletHandler, ErrorHandler errorHandler)
124     {   
125         super((ContextHandler.Context)null);
126         _scontext = new Context();
127         _sessionHandler = sessionHandler;
128         _securityHandler = securityHandler;
129         _servletHandler = servletHandler;
130             
131         if (errorHandler!=null)
132             setErrorHandler(errorHandler);
133 
134         if (contextPath!=null)
135             setContextPath(contextPath);
136 
137         if (parent instanceof HandlerWrapper)
138             ((HandlerWrapper)parent).setHandler(this);
139         else if (parent instanceof HandlerCollection)
140             ((HandlerCollection)parent).addHandler(this);
141     }    
142 
143     /* ------------------------------------------------------------ */
144     /**
145      * @see org.eclipse.jetty.server.handler.ContextHandler#doStop()
146      */
147     @Override
148     protected void doStop() throws Exception
149     {
150         super.doStop();
151         if (_decorators != null)
152             _decorators.clear();
153         if (_wrapper != null)
154             _wrapper.setHandler(null);
155     }
156 
157     /* ------------------------------------------------------------ */
158     /** Get the defaultSecurityHandlerClass.
159      * @return the defaultSecurityHandlerClass
160      */
161     public Class<? extends SecurityHandler> getDefaultSecurityHandlerClass()
162     {
163         return _defaultSecurityHandlerClass;
164     }
165 
166     /* ------------------------------------------------------------ */
167     /** Set the defaultSecurityHandlerClass.
168      * @param defaultSecurityHandlerClass the defaultSecurityHandlerClass to set
169      */
170     public void setDefaultSecurityHandlerClass(Class<? extends SecurityHandler> defaultSecurityHandlerClass)
171     {
172         _defaultSecurityHandlerClass = defaultSecurityHandlerClass;
173     }
174 
175     /* ------------------------------------------------------------ */
176     protected SessionHandler newSessionHandler()
177     {
178         return new SessionHandler();
179     }
180     
181     /* ------------------------------------------------------------ */
182     protected SecurityHandler newSecurityHandler()
183     {
184         try
185         {
186             return (SecurityHandler)_defaultSecurityHandlerClass.newInstance();
187         }
188         catch(Exception e)
189         {
190             throw new IllegalStateException(e);
191         }
192     }
193 
194     /* ------------------------------------------------------------ */
195     protected ServletHandler newServletHandler()
196     {
197         return new ServletHandler();
198     }
199 
200     /* ------------------------------------------------------------ */
201     /**
202      * Finish constructing handlers and link them together.
203      * 
204      * @see org.eclipse.jetty.server.handler.ContextHandler#startContext()
205      */
206     protected void startContext() throws Exception
207     {
208         // force creation of missing handlers.
209         getSessionHandler();
210         getSecurityHandler();
211         getServletHandler();
212         
213         Handler handler = _servletHandler;
214         if (_securityHandler!=null)
215         {
216             _securityHandler.setHandler(handler);
217             handler=_securityHandler;
218         }
219         
220         if (_sessionHandler!=null)
221         {
222             _sessionHandler.setHandler(handler);
223             handler=_sessionHandler;
224         }
225         
226         // skip any wrapped handlers 
227         _wrapper=this;
228         while (_wrapper!=handler && _wrapper.getHandler() instanceof HandlerWrapper)
229             _wrapper=(HandlerWrapper)_wrapper.getHandler();
230         
231         // if we are not already linked
232         if (_wrapper!=handler)
233         {
234             if (_wrapper.getHandler()!=null )
235                 throw new IllegalStateException("!ScopedHandler");
236             _wrapper.setHandler(handler);
237         }
238         
239     	super.startContext();
240 
241     	// OK to Initialize servlet handler now
242     	if (_servletHandler != null && _servletHandler.isStarted())
243     	{
244     	    for (int i=_decorators.size()-1;i>=0; i--)
245     	    {
246     	        Decorator decorator = _decorators.get(i);
247                 if (_servletHandler.getFilters()!=null)
248                     for (FilterHolder holder:_servletHandler.getFilters())
249                         decorator.decorateFilterHolder(holder);
250     	        if(_servletHandler.getServlets()!=null)
251     	            for (ServletHolder holder:_servletHandler.getServlets())
252     	                decorator.decorateServletHolder(holder);
253     	    }   
254     	        
255     	    _servletHandler.initialize();
256     	}
257     }
258 
259     /* ------------------------------------------------------------ */
260     /**
261      * @return Returns the securityHandler.
262      */
263     public SecurityHandler getSecurityHandler()
264     {
265         if (_securityHandler==null && (_options&SECURITY)!=0 && !isStarted()) 
266             _securityHandler=newSecurityHandler();
267         
268         return _securityHandler;
269     }
270 
271     /* ------------------------------------------------------------ */
272     /**
273      * @return Returns the servletHandler.
274      */
275     public ServletHandler getServletHandler()
276     {
277         if (_servletHandler==null && !isStarted()) 
278             _servletHandler=newServletHandler();
279         return _servletHandler;
280     }
281 
282     /* ------------------------------------------------------------ */
283     /**
284      * @return Returns the sessionHandler.
285      */
286     public SessionHandler getSessionHandler()
287     {
288         if (_sessionHandler==null && (_options&SESSIONS)!=0 && !isStarted()) 
289             _sessionHandler=newSessionHandler();
290         return _sessionHandler;
291     }
292 
293     /* ------------------------------------------------------------ */
294     /** conveniance method to add a servlet.
295      */
296     public ServletHolder addServlet(String className,String pathSpec)
297     {
298         return getServletHandler().addServletWithMapping(className, pathSpec);
299     }
300 
301     /* ------------------------------------------------------------ */
302     /** conveniance method to add a servlet.
303      */
304     public ServletHolder addServlet(Class<? extends Servlet> servlet,String pathSpec)
305     {
306         return getServletHandler().addServletWithMapping(servlet.getName(), pathSpec);
307     }
308     
309     /* ------------------------------------------------------------ */
310     /** conveniance method to add a servlet.
311      */
312     public void addServlet(ServletHolder servlet,String pathSpec)
313     {
314         getServletHandler().addServletWithMapping(servlet, pathSpec);
315     }
316 
317     /* ------------------------------------------------------------ */
318     /** conveniance method to add a filter
319      */
320     public void addFilter(FilterHolder holder,String pathSpec,EnumSet<DispatcherType> dispatches)
321     {
322         getServletHandler().addFilterWithMapping(holder,pathSpec,dispatches);
323     }
324 
325     /* ------------------------------------------------------------ */
326     /** convenience method to add a filter
327      */
328     public FilterHolder addFilter(Class<? extends Filter> filterClass,String pathSpec,EnumSet<DispatcherType> dispatches)
329     {
330         return getServletHandler().addFilterWithMapping(filterClass,pathSpec,dispatches);
331     }
332 
333     /* ------------------------------------------------------------ */
334     /** convenience method to add a filter
335      */
336     public FilterHolder addFilter(String filterClass,String pathSpec,EnumSet<DispatcherType> dispatches)
337     {
338         return getServletHandler().addFilterWithMapping(filterClass,pathSpec,dispatches);
339     }
340 
341     /**
342      * notification that a ServletRegistration has been created so we can track the annotations
343      * @param holder new holder created through the api.
344      * @return the ServletRegistration.Dynamic
345      */
346     protected ServletRegistration.Dynamic dynamicHolderAdded(ServletHolder holder) {
347         return holder.getRegistration();
348     }
349 
350     /**
351      * delegate for ServletContext.declareRole method
352      * @param roleNames role names to add
353      */
354     protected void addRoles(String... roleNames) {
355         //Get a reference to the SecurityHandler, which must be ConstraintAware
356         if (_securityHandler != null && _securityHandler instanceof ConstraintAware)
357         {
358             HashSet<String> union = new HashSet<String>();
359             Set<String> existing = ((ConstraintAware)_securityHandler).getRoles();
360             if (existing != null)
361                 union.addAll(existing);
362             union.addAll(Arrays.asList(roleNames));
363             ((ConstraintSecurityHandler)_securityHandler).setRoles(union);
364         }
365     }
366 
367     /**
368      * Delegate for ServletRegistration.Dynamic.setServletSecurity method
369      * @param registration ServletRegistration.Dynamic instance that setServletSecurity was called on
370      * @param servletSecurityElement new security info
371      * @return the set of exact URL mappings currently associated with the registration that are also present in the web.xml
372      * security constratins and thus will be unaffected by this call.
373      */
374     public Set<String> setServletSecurity(ServletRegistration.Dynamic registration, ServletSecurityElement servletSecurityElement)
375     {
376         return Collections.emptySet();
377     }
378 
379 
380     
381     public void restrictEventListener (EventListener e)
382     {
383         if (_restrictListeners && e instanceof ServletContextListener)
384             _restrictedContextListeners = LazyList.add(_restrictedContextListeners, e);
385     }
386 
387     public boolean isRestrictListeners() {
388         return _restrictListeners;
389     }
390 
391     public void setRestrictListeners(boolean restrictListeners) {
392         this._restrictListeners = restrictListeners;
393     }
394 
395     public void callContextInitialized(ServletContextListener l, ServletContextEvent e)
396     {
397         try
398         {
399             //toggle state of the dynamic API so that the listener cannot use it
400             if (LazyList.contains(_restrictedContextListeners, l))
401                 this.getServletContext().setEnabled(false);
402             
403             super.callContextInitialized(l, e);
404         }
405         finally
406         {
407             //untoggle the state of the dynamic API
408             this.getServletContext().setEnabled(true);
409         }
410     }
411 
412     
413     public void callContextDestroyed(ServletContextListener l, ServletContextEvent e)
414     {
415         super.callContextDestroyed(l, e);
416     }
417 
418   
419 
420     /* ------------------------------------------------------------ */
421     /**
422      * @param sessionHandler The sessionHandler to set.
423      */
424     public void setSessionHandler(SessionHandler sessionHandler)
425     {
426         if (isStarted())
427             throw new IllegalStateException("STARTED");
428 
429         _sessionHandler = sessionHandler;
430     }
431 
432     /* ------------------------------------------------------------ */
433     /**
434      * @param securityHandler The {@link SecurityHandler} to set on this context.
435      */
436     public void setSecurityHandler(SecurityHandler securityHandler)
437     {
438         if (isStarted())
439             throw new IllegalStateException("STARTED");
440 
441         _securityHandler = securityHandler;
442     }
443 
444     /* ------------------------------------------------------------ */
445     /**
446      * @param servletHandler The servletHandler to set.
447      */
448     public void setServletHandler(ServletHandler servletHandler)
449     {
450         if (isStarted())
451             throw new IllegalStateException("STARTED");
452 
453         _servletHandler = servletHandler;
454     }
455 
456     /* ------------------------------------------------------------ */
457     /**
458      * @return The decorator list used to resource inject new Filters, Servlets and EventListeners
459      */
460     public List<Decorator> getDecorators()
461     {
462         return Collections.unmodifiableList(_decorators);
463     }
464 
465     /* ------------------------------------------------------------ */
466     /**
467      * @param decorators The lis of {@link Decorator}s
468      */
469     public void setDecorators(List<Decorator> decorators)
470     {
471         _decorators.clear();
472         _decorators.addAll(decorators);
473     }
474     
475     /* ------------------------------------------------------------ */
476     /**
477      * @param decorator The decorator to add
478      */
479     public void addDecorator(Decorator decorator)
480     {
481         _decorators.add(decorator);
482     }
483 
484     /* ------------------------------------------------------------ */
485     void destroyServlet(Servlet servlet)
486     {
487         for (Decorator decorator : _decorators)
488             decorator.destroyServletInstance(servlet);
489     }
490 
491     /* ------------------------------------------------------------ */
492     void destroyFilter(Filter filter)
493     {
494         for (Decorator decorator : _decorators)
495             decorator.destroyFilterInstance(filter);
496     }
497     
498     /* ------------------------------------------------------------ */
499     public class Context extends ContextHandler.Context
500     {
501         /* ------------------------------------------------------------ */
502         /* 
503          * @see javax.servlet.ServletContext#getNamedDispatcher(java.lang.String)
504          */
505         @Override
506         public RequestDispatcher getNamedDispatcher(String name)
507         {
508             ContextHandler context=org.eclipse.jetty.servlet.ServletContextHandler.this;
509             if (_servletHandler==null || _servletHandler.getServlet(name)==null)
510                 return null;
511             return new Dispatcher(context, name);
512         }
513         
514         /* ------------------------------------------------------------ */
515         /**
516          * @since servlet-api-3.0
517          */
518         @Override
519         public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass)
520         {
521             if (isStarted())
522                 throw new IllegalStateException();
523             
524             if (!_enabled)
525                 throw new UnsupportedOperationException();
526 
527             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
528             final FilterHolder holder= handler.newFilterHolder(Holder.Source.JAVAX_API);
529             holder.setName(filterName);
530             holder.setHeldClass(filterClass);
531             handler.addFilter(holder);
532             return holder.getRegistration();
533         }
534 
535         /* ------------------------------------------------------------ */
536         /**
537          * @since servlet-api-3.0
538          */
539         @Override
540         public FilterRegistration.Dynamic addFilter(String filterName, String className)
541         {
542             if (isStarted())
543                 throw new IllegalStateException();
544             
545             if (!_enabled)
546                 throw new UnsupportedOperationException();
547 
548             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
549             final FilterHolder holder= handler.newFilterHolder(Holder.Source.JAVAX_API);
550             holder.setName(filterName);
551             holder.setClassName(className);
552             handler.addFilter(holder);
553             return holder.getRegistration();
554         }
555 
556 
557         /* ------------------------------------------------------------ */
558         /**
559          * @since servlet-api-3.0
560          */
561         @Override
562         public FilterRegistration.Dynamic addFilter(String filterName, Filter filter)
563         {
564             if (isStarted())
565                 throw new IllegalStateException();
566 
567             if (!_enabled)
568                 throw new UnsupportedOperationException();
569             
570             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
571             final FilterHolder holder= handler.newFilterHolder(Holder.Source.JAVAX_API);
572             holder.setName(filterName);
573             holder.setFilter(filter);
574             handler.addFilter(holder);
575             return holder.getRegistration();
576         }
577         
578         /* ------------------------------------------------------------ */
579         /**
580          * @since servlet-api-3.0
581          */
582         @Override
583         public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass)
584         {
585             if (!isStarting())
586                 throw new IllegalStateException();
587             
588             if (!_enabled)
589                 throw new UnsupportedOperationException();
590 
591             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
592             final ServletHolder holder= handler.newServletHolder(Holder.Source.JAVAX_API);
593             holder.setName(servletName);
594             holder.setHeldClass(servletClass);
595             handler.addServlet(holder);
596             return dynamicHolderAdded(holder);
597         }
598 
599         /* ------------------------------------------------------------ */
600         /**
601          * @since servlet-api-3.0
602          */
603         @Override
604         public ServletRegistration.Dynamic addServlet(String servletName, String className)
605         {
606             if (!isStarting())
607                 throw new IllegalStateException();
608             
609             if (!_enabled)
610                 throw new UnsupportedOperationException();
611 
612             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
613             final ServletHolder holder= handler.newServletHolder(Holder.Source.JAVAX_API);
614             holder.setName(servletName);
615             holder.setClassName(className);
616             handler.addServlet(holder);
617             return dynamicHolderAdded(holder);
618         }
619 
620         /* ------------------------------------------------------------ */
621         /**
622          * @since servlet-api-3.0
623          */
624         @Override
625         public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet)
626         {
627             if (!isStarting())
628                 throw new IllegalStateException();
629 
630             if (!_enabled)
631                 throw new UnsupportedOperationException();
632             
633             final ServletHandler handler = ServletContextHandler.this.getServletHandler();
634             final ServletHolder holder= handler.newServletHolder(Holder.Source.JAVAX_API);
635             holder.setName(servletName);
636             holder.setServlet(servlet);
637             handler.addServlet(holder);
638             return dynamicHolderAdded(holder);
639         }
640 
641         /* ------------------------------------------------------------ */
642         @Override
643         public boolean setInitParameter(String name, String value)
644         {
645             // TODO other started conditions
646             if (!isStarting())
647                 throw new IllegalStateException();
648             
649             if (!_enabled)
650                 throw new UnsupportedOperationException();
651             
652             return super.setInitParameter(name,value);
653         }
654 
655         /* ------------------------------------------------------------ */
656         @Override
657         public <T extends Filter> T createFilter(Class<T> c) throws ServletException
658         {
659             try
660             {
661                 T f = c.newInstance();
662                 for (int i=_decorators.size()-1; i>=0; i--)
663                 {
664                     Decorator decorator = _decorators.get(i);
665                     f=decorator.decorateFilterInstance(f);
666                 }
667                 return f;
668             }
669             catch (InstantiationException e)
670             {
671                 throw new ServletException(e);
672             }
673             catch (IllegalAccessException e)
674             {
675                 throw new ServletException(e);
676             }
677         }
678 
679         /* ------------------------------------------------------------ */
680         @Override
681         public <T extends Servlet> T createServlet(Class<T> c) throws ServletException
682         {
683             try
684             {
685                 T s = c.newInstance();
686                 for (int i=_decorators.size()-1; i>=0; i--)
687                 {
688                     Decorator decorator = _decorators.get(i);
689                     s=decorator.decorateServletInstance(s);
690                 }
691                 return s;
692             }
693             catch (InstantiationException e)
694             {
695                 throw new ServletException(e);
696             }
697             catch (IllegalAccessException e)
698             {
699                 throw new ServletException(e);
700             }
701         }
702 
703         @Override
704         public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
705         {
706             if (_sessionHandler!=null)
707                 return _sessionHandler.getSessionManager().getDefaultSessionTrackingModes();
708             return null;
709         }
710 
711         @Override
712         public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
713         {
714             if (_sessionHandler!=null)
715                 return _sessionHandler.getSessionManager().getEffectiveSessionTrackingModes();
716             return null;
717         }
718 
719         @Override
720         public FilterRegistration getFilterRegistration(String filterName)
721         {
722             if (!_enabled)
723                 throw new UnsupportedOperationException();
724             
725             final FilterHolder holder=ServletContextHandler.this.getServletHandler().getFilter(filterName);
726             return (holder==null)?null:holder.getRegistration();
727         }
728 
729         @Override
730         public Map<String, ? extends FilterRegistration> getFilterRegistrations()
731         {
732             if (!_enabled)
733                 throw new UnsupportedOperationException();
734             
735             HashMap<String, FilterRegistration> registrations = new HashMap<String, FilterRegistration>();
736             ServletHandler handler=ServletContextHandler.this.getServletHandler();
737             FilterHolder[] holders=handler.getFilters();
738             if (holders!=null)
739             {
740                 for (FilterHolder holder : holders)
741                     registrations.put(holder.getName(),holder.getRegistration());
742             }
743             return registrations;
744         }
745 
746         @Override
747         public ServletRegistration getServletRegistration(String servletName)
748         {
749             if (!_enabled)
750                 throw new UnsupportedOperationException();
751             
752             final ServletHolder holder=ServletContextHandler.this.getServletHandler().getServlet(servletName);
753             return (holder==null)?null:holder.getRegistration();
754         }
755 
756         @Override
757         public Map<String, ? extends ServletRegistration> getServletRegistrations()
758         {
759             if (!_enabled)
760                 throw new UnsupportedOperationException();
761             
762             HashMap<String, ServletRegistration> registrations = new HashMap<String, ServletRegistration>();
763             ServletHandler handler=ServletContextHandler.this.getServletHandler();
764             ServletHolder[] holders=handler.getServlets();
765             if (holders!=null)
766             {
767                 for (ServletHolder holder : holders)
768                     registrations.put(holder.getName(),holder.getRegistration());
769             }
770             return registrations;
771         }
772 
773         @Override
774         public SessionCookieConfig getSessionCookieConfig()
775         {
776             // TODO other started conditions
777             if (!_enabled)
778                 throw new UnsupportedOperationException();
779             
780             if (_sessionHandler!=null)
781                 return _sessionHandler.getSessionManager().getSessionCookieConfig();
782             return null;
783         }
784 
785         @Override
786         public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
787         {
788             // TODO other started conditions
789             if (!isStarting())
790                 throw new IllegalStateException();
791             if (!_enabled)
792                 throw new UnsupportedOperationException();
793             
794             
795             if (_sessionHandler!=null)
796                 _sessionHandler.getSessionManager().setSessionTrackingModes(sessionTrackingModes);
797         }
798 
799         @Override
800         public void addListener(String className)
801         {
802             // TODO other started conditions
803             if (!isStarting())
804                 throw new IllegalStateException();
805             if (!_enabled)
806                 throw new UnsupportedOperationException();
807             super.addListener(className);
808         }
809 
810         @Override
811         public <T extends EventListener> void addListener(T t)
812         {
813             // TODO other started conditions
814             if (!isStarting())
815                 throw new IllegalStateException();
816             if (!_enabled)
817                 throw new UnsupportedOperationException();
818             super.addListener(t);
819         }
820 
821         @Override
822         public void addListener(Class<? extends EventListener> listenerClass)
823         {
824             // TODO other started conditions
825             if (!isStarting())
826                 throw new IllegalStateException();
827             if (!_enabled)
828                 throw new UnsupportedOperationException();
829             super.addListener(listenerClass);
830         }
831 
832         @Override
833         public <T extends EventListener> T createListener(Class<T> clazz) throws ServletException
834         {
835             try
836             {
837                 T l = super.createListener(clazz);
838 
839                 for (int i=_decorators.size()-1; i>=0; i--)
840                 {
841                     Decorator decorator = _decorators.get(i);
842                     l=decorator.decorateListenerInstance(l);
843                 }
844                 return l;
845             }
846             catch(ServletException e)
847             {
848                 throw e;
849             }
850             catch(Exception e)
851             {
852                 throw new ServletException(e);
853             }
854         }
855 
856 
857         @Override
858         public JspConfigDescriptor getJspConfigDescriptor()
859         {
860             return _jspConfig;
861         }
862         
863         @Override
864         public void declareRoles(String... roleNames)
865         {
866             if (!isStarting())
867                 throw new IllegalStateException();
868             if (!_enabled)
869                 throw new UnsupportedOperationException();
870             addRoles(roleNames);
871 
872 
873         }
874 
875     }
876 
877 
878 
879     /* ------------------------------------------------------------ */
880     /** Interface to decorate loaded classes.
881      */
882     public interface Decorator
883     {
884         <T extends Filter> T decorateFilterInstance(T filter) throws ServletException;
885         <T extends Servlet> T decorateServletInstance(T servlet) throws ServletException;
886         <T extends EventListener> T decorateListenerInstance(T listener) throws ServletException;
887 
888         void decorateFilterHolder(FilterHolder filter) throws ServletException;
889         void decorateServletHolder(ServletHolder servlet) throws ServletException;
890         
891         void destroyServletInstance(Servlet s);
892         void destroyFilterInstance(Filter f);
893         void destroyListenerInstance(EventListener f);
894     }
895 }