View Javadoc

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