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