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