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.io.IOException;
22  import java.util.Collections;
23  import java.util.Enumeration;
24  import java.util.HashMap;
25  import java.util.HashSet;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import javax.servlet.ServletContext;
30  import javax.servlet.UnavailableException;
31  
32  import org.eclipse.jetty.server.handler.ContextHandler;
33  import org.eclipse.jetty.servlet.api.Registration;
34  import org.eclipse.jetty.util.Loader;
35  import org.eclipse.jetty.util.component.AbstractLifeCycle;
36  import org.eclipse.jetty.util.component.AggregateLifeCycle;
37  import org.eclipse.jetty.util.component.Dumpable;
38  import org.eclipse.jetty.util.log.Log;
39  import org.eclipse.jetty.util.log.Logger;
40  
41  
42  /* --------------------------------------------------------------------- */
43  /** 
44   * 
45   */
46  public class Holder<T> extends AbstractLifeCycle implements Dumpable
47  {
48      private static final Logger LOG = Log.getLogger(Holder.class);
49  
50      protected transient Class<? extends T> _class;
51      protected final Map<String,String> _initParams=new HashMap<String,String>(3);
52      protected String _className;
53      protected String _displayName;
54      protected boolean _extInstance;
55      protected boolean _asyncSupported=true;
56  
57      /* ---------------------------------------------------------------- */
58      protected String _name;
59      protected ServletHandler _servletHandler;
60  
61      /* ---------------------------------------------------------------- */
62      protected Holder()
63      {
64      }
65  
66      /* ------------------------------------------------------------ */
67      /**
68       * @return True if this holder was created for a specific instance.
69       */
70      public boolean isInstance()
71      {
72          return _extInstance;
73      }
74      
75      /* ------------------------------------------------------------ */
76      @SuppressWarnings("unchecked")
77      public void doStart()
78          throws Exception
79      {
80          //if no class already loaded and no classname, make servlet permanently unavailable
81          if (_class==null && (_className==null || _className.equals("")))
82              throw new UnavailableException("No class for Servlet or Filter", -1);
83          
84          //try to load class
85          if (_class==null)
86          {
87              try
88              {
89                  _class=Loader.loadClass(Holder.class, _className);
90                  if(LOG.isDebugEnabled())
91                      LOG.debug("Holding {}",_class);
92              }
93              catch (Exception e)
94              {
95                  LOG.warn(e);
96                  throw new UnavailableException(e.getMessage(), -1);
97              }
98          }
99      }
100     
101     /* ------------------------------------------------------------ */
102     @Override
103     public void doStop()
104         throws Exception
105     {
106         if (!_extInstance)
107             _class=null;
108     }
109     
110     /* ------------------------------------------------------------ */
111     public String getClassName()
112     {
113         return _className;
114     }
115     
116     /* ------------------------------------------------------------ */
117     public Class<? extends T> getHeldClass()
118     {
119         return _class;
120     }
121     
122     /* ------------------------------------------------------------ */
123     public String getDisplayName()
124     {
125         return _displayName;
126     }
127 
128     /* ---------------------------------------------------------------- */
129     public String getInitParameter(String param)
130     {
131         if (_initParams==null)
132             return null;
133         return (String)_initParams.get(param);
134     }
135     
136     /* ------------------------------------------------------------ */
137     public Enumeration getInitParameterNames()
138     {
139         if (_initParams==null)
140             return Collections.enumeration(Collections.EMPTY_LIST);
141         return Collections.enumeration(_initParams.keySet());
142     }
143 
144     /* ---------------------------------------------------------------- */
145     public Map<String,String> getInitParameters()
146     {
147         return _initParams;
148     }
149     
150     /* ------------------------------------------------------------ */
151     public String getName()
152     {
153         return _name;
154     }
155     
156     /* ------------------------------------------------------------ */
157     /**
158      * @return Returns the servletHandler.
159      */
160     public ServletHandler getServletHandler()
161     {
162         return _servletHandler;
163     }
164     
165     /* ------------------------------------------------------------ */
166     public void destroyInstance(Object instance)
167     throws Exception
168     {
169     }
170     
171     /* ------------------------------------------------------------ */
172     /**
173      * @param className The className to set.
174      */
175     public void setClassName(String className)
176     {
177         _className = className;
178         _class=null;
179         if (_name==null)
180             _name=className+"-"+Integer.toHexString(this.hashCode());
181     }
182     
183     /* ------------------------------------------------------------ */
184     /**
185      * @param held The class to hold
186      */
187     public void setHeldClass(Class<? extends T> held)
188     {
189         _class=held;
190         if (held!=null)
191         {
192             _className=held.getName();
193             if (_name==null)
194                 _name=held.getName()+"-"+Integer.toHexString(this.hashCode());
195         }
196     }
197     
198     /* ------------------------------------------------------------ */
199     public void setDisplayName(String name)
200     {
201         _displayName=name;
202     }
203     
204     /* ------------------------------------------------------------ */
205     public void setInitParameter(String param,String value)
206     {
207         _initParams.put(param,value);
208     }
209     
210     /* ---------------------------------------------------------------- */
211     public void setInitParameters(Map<String,String> map)
212     {
213         _initParams.clear();
214         _initParams.putAll(map);
215     }
216     
217     /* ------------------------------------------------------------ */
218     /**
219      * The name is a primary key for the held object.
220      * Ensure that the name is set BEFORE adding a Holder
221      * (eg ServletHolder or FilterHolder) to a ServletHandler.
222      * @param name The name to set.
223      */
224     public void setName(String name)
225     {
226         _name = name;
227     }
228     
229     /* ------------------------------------------------------------ */
230     /**
231      * @param servletHandler The {@link ServletHandler} that will handle requests dispatched to this servlet.
232      */
233     public void setServletHandler(ServletHandler servletHandler)
234     {
235         _servletHandler = servletHandler;
236     }
237 
238     /* ------------------------------------------------------------ */
239     public void setAsyncSupported(boolean suspendable)
240     {
241         _asyncSupported=suspendable;
242     }
243 
244     /* ------------------------------------------------------------ */
245     public boolean isAsyncSupported()
246     {
247         return _asyncSupported;
248     }
249     
250     /* ------------------------------------------------------------ */
251     public String toString()
252     {
253         return _name;
254     }
255 
256     /* ------------------------------------------------------------ */
257     protected void illegalStateIfContextStarted()
258     {
259         if (_servletHandler!=null)
260         {
261             ContextHandler.Context context=(ContextHandler.Context)_servletHandler.getServletContext();
262             if (context!=null && context.getContextHandler().isStarted())
263                 throw new IllegalStateException("Started");
264         }
265     }
266 
267     /* ------------------------------------------------------------ */
268     public void dump(Appendable out, String indent) throws IOException
269     {
270         out.append(_name).append("==").append(_className)
271         .append(" - ").append(AbstractLifeCycle.getState(this)).append("\n");
272         AggregateLifeCycle.dump(out,indent,_initParams.entrySet());
273     }
274 
275     /* ------------------------------------------------------------ */
276     public String dump()
277     {
278         return AggregateLifeCycle.dump(this);
279     }    
280     
281     /* ------------------------------------------------------------ */
282     /* ------------------------------------------------------------ */
283     /* ------------------------------------------------------------ */
284     protected class HolderConfig 
285     {   
286         
287         /* -------------------------------------------------------- */
288         public ServletContext getServletContext()
289         {
290             return _servletHandler.getServletContext();
291         }
292 
293         /* -------------------------------------------------------- */
294         public String getInitParameter(String param)
295         {
296             return Holder.this.getInitParameter(param);
297         }
298     
299         /* -------------------------------------------------------- */
300         public Enumeration getInitParameterNames()
301         {
302             return Holder.this.getInitParameterNames();
303         }
304     }
305 
306     /* -------------------------------------------------------- */
307     /* -------------------------------------------------------- */
308     /* -------------------------------------------------------- */
309     protected class HolderRegistration implements Registration.Dynamic
310     {
311         public void setAsyncSupported(boolean isAsyncSupported)
312         {
313             illegalStateIfContextStarted();
314             Holder.this.setAsyncSupported(isAsyncSupported);
315         }
316 
317         public void setDescription(String description)
318         {
319             if (LOG.isDebugEnabled())
320                 LOG.debug(this+" is "+description);
321         }
322 
323         public String getClassName()
324         {
325             return Holder.this.getClassName();
326         }
327 
328         public String getInitParameter(String name)
329         {
330             return Holder.this.getInitParameter(name);
331         }
332 
333         public Map<String, String> getInitParameters()
334         {
335             return Holder.this.getInitParameters();
336         }
337 
338         public String getName()
339         {
340             return Holder.this.getName();
341         }
342 
343         public boolean setInitParameter(String name, String value)
344         {
345             illegalStateIfContextStarted();
346             if (Holder.this.getInitParameter(name)!=null)
347                 return false;
348             Holder.this.setInitParameter(name,value);
349             return true;
350         }
351 
352         public Set<String> setInitParameters(Map<String, String> initParameters)
353         {
354             illegalStateIfContextStarted();
355             Set<String> clash=null;
356             for (String name : initParameters.keySet())
357             {
358                 if (Holder.this.getInitParameter(name)!=null)
359                 {
360                     if (clash==null)
361                         clash=new HashSet<String>();
362                     clash.add(name);
363                 }
364             }
365             if (clash!=null)
366                 return clash;
367             Holder.this.setInitParameters(initParameters);
368             return Collections.emptySet();
369         }; 
370     }
371 }
372 
373 
374 
375 
376