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