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