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