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