1
2
3
4
5
6
7
8
9
10
11
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.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 public enum Source { EMBEDDED, JAVAX_API, DESCRIPTOR, ANNOTATION };
44 final private Source _source;
45 private static final Logger LOG = Log.getLogger(Holder.class);
46
47 protected transient Class<? extends T> _class;
48 protected final Map<String,String> _initParams=new HashMap<String,String>(3);
49 protected String _className;
50 protected String _displayName;
51 protected boolean _extInstance;
52 protected boolean _asyncSupported=true;
53
54
55 protected String _name;
56 protected ServletHandler _servletHandler;
57
58
59 protected Holder(Source source)
60 {
61 _source=source;
62 }
63
64 public Source getSource()
65 {
66 return _source;
67 }
68
69
70
71
72
73 public boolean isInstance()
74 {
75 return _extInstance;
76 }
77
78
79 @SuppressWarnings("unchecked")
80 public void doStart()
81 throws Exception
82 {
83
84 if (_class==null && (_className==null || _className.equals("")))
85 throw new UnavailableException("No class for Servlet or Filter", -1);
86
87
88 if (_class==null)
89 {
90 try
91 {
92 _class=Loader.loadClass(Holder.class, _className);
93 if(LOG.isDebugEnabled())
94 LOG.debug("Holding {}",_class);
95 }
96 catch (Exception e)
97 {
98 LOG.warn(e);
99 throw new UnavailableException(e.getMessage(), -1);
100 }
101 }
102 }
103
104
105 @Override
106 public void doStop()
107 throws Exception
108 {
109 if (!_extInstance)
110 _class=null;
111 }
112
113
114 public String getClassName()
115 {
116 return _className;
117 }
118
119
120 public Class<? extends T> getHeldClass()
121 {
122 return _class;
123 }
124
125
126 public String getDisplayName()
127 {
128 return _displayName;
129 }
130
131
132 public String getInitParameter(String param)
133 {
134 if (_initParams==null)
135 return null;
136 return (String)_initParams.get(param);
137 }
138
139
140 public Enumeration getInitParameterNames()
141 {
142 if (_initParams==null)
143 return Collections.enumeration(Collections.EMPTY_LIST);
144 return Collections.enumeration(_initParams.keySet());
145 }
146
147
148 public Map<String,String> getInitParameters()
149 {
150 return _initParams;
151 }
152
153
154 public String getName()
155 {
156 return _name;
157 }
158
159
160
161
162
163 public ServletHandler getServletHandler()
164 {
165 return _servletHandler;
166 }
167
168
169 public void destroyInstance(Object instance)
170 throws Exception
171 {
172 }
173
174
175
176
177
178 public void setClassName(String className)
179 {
180 _className = className;
181 _class=null;
182 }
183
184
185
186
187
188 public void setHeldClass(Class<? extends T> held)
189 {
190 _class=held;
191 if (held!=null)
192 {
193 _className=held.getName();
194 if (_name==null)
195 _name=held.getName()+"-"+this.hashCode();
196 }
197 }
198
199
200 public void setDisplayName(String name)
201 {
202 _displayName=name;
203 }
204
205
206 public void setInitParameter(String param,String value)
207 {
208 _initParams.put(param,value);
209 }
210
211
212 public void setInitParameters(Map<String,String> map)
213 {
214 _initParams.clear();
215 _initParams.putAll(map);
216 }
217
218
219
220
221
222
223
224
225 public void setName(String name)
226 {
227 _name = name;
228 }
229
230
231
232
233
234 public void setServletHandler(ServletHandler servletHandler)
235 {
236 _servletHandler = servletHandler;
237 }
238
239
240 public void setAsyncSupported(boolean suspendable)
241 {
242 _asyncSupported=suspendable;
243 }
244
245
246 public boolean isAsyncSupported()
247 {
248 return _asyncSupported;
249 }
250
251
252 public String toString()
253 {
254 return _name;
255 }
256
257
258 protected void illegalStateIfContextStarted()
259 {
260 if (_servletHandler!=null)
261 {
262 ContextHandler.Context context=(ContextHandler.Context)_servletHandler.getServletContext();
263 if (context!=null && context.getContextHandler().isStarted())
264 throw new IllegalStateException("Started");
265 }
266 }
267
268
269 public void dump(Appendable out, String indent) throws IOException
270 {
271 out.append(_name).append("==").append(_className).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 (name == null) {
347 throw new IllegalArgumentException("init parameter name required");
348 }
349 if (value == null) {
350 throw new IllegalArgumentException("non-null value required for init parameter " + name);
351 }
352 if (Holder.this.getInitParameter(name)!=null)
353 return false;
354 Holder.this.setInitParameter(name,value);
355 return true;
356 }
357
358 public Set<String> setInitParameters(Map<String, String> initParameters)
359 {
360 illegalStateIfContextStarted();
361 Set<String> clash=null;
362 for (Map.Entry<String, String> entry : initParameters.entrySet())
363 {
364 if (entry.getKey() == null) {
365 throw new IllegalArgumentException("init parameter name required");
366 }
367 if (entry.getValue() == null) {
368 throw new IllegalArgumentException("non-null value required for init parameter " + entry.getKey());
369 }
370 if (Holder.this.getInitParameter(entry.getKey())!=null)
371 {
372 if (clash==null)
373 clash=new HashSet<String>();
374 clash.add(entry.getKey());
375 }
376 }
377 if (clash!=null)
378 return clash;
379 Holder.this.getInitParameters().putAll(initParameters);
380 return Collections.emptySet();
381 }
382
383
384 }
385 }
386
387
388
389
390