View Javadoc

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