View Javadoc

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