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