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