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)
272 .append(" - ").append(AbstractLifeCycle.getState(this)).append("\n");
273 AggregateLifeCycle.dump(out,indent,_initParams.entrySet());
274 }
275
276
277 public String dump()
278 {
279 return AggregateLifeCycle.dump(this);
280 }
281
282
283
284
285 protected class HolderConfig
286 {
287
288
289 public ServletContext getServletContext()
290 {
291 return _servletHandler.getServletContext();
292 }
293
294
295 public String getInitParameter(String param)
296 {
297 return Holder.this.getInitParameter(param);
298 }
299
300
301 public Enumeration getInitParameterNames()
302 {
303 return Holder.this.getInitParameterNames();
304 }
305 }
306
307
308
309
310 protected class HolderRegistration implements Registration.Dynamic
311 {
312 public void setAsyncSupported(boolean isAsyncSupported)
313 {
314 illegalStateIfContextStarted();
315 Holder.this.setAsyncSupported(isAsyncSupported);
316 }
317
318 public void setDescription(String description)
319 {
320 if (LOG.isDebugEnabled())
321 LOG.debug(this+" is "+description);
322 }
323
324 public String getClassName()
325 {
326 return Holder.this.getClassName();
327 }
328
329 public String getInitParameter(String name)
330 {
331 return Holder.this.getInitParameter(name);
332 }
333
334 public Map<String, String> getInitParameters()
335 {
336 return Holder.this.getInitParameters();
337 }
338
339 public String getName()
340 {
341 return Holder.this.getName();
342 }
343
344 public boolean setInitParameter(String name, String value)
345 {
346 illegalStateIfContextStarted();
347 if (name == null) {
348 throw new IllegalArgumentException("init parameter name required");
349 }
350 if (value == null) {
351 throw new IllegalArgumentException("non-null value required for init parameter " + name);
352 }
353 if (Holder.this.getInitParameter(name)!=null)
354 return false;
355 Holder.this.setInitParameter(name,value);
356 return true;
357 }
358
359 public Set<String> setInitParameters(Map<String, String> initParameters)
360 {
361 illegalStateIfContextStarted();
362 Set<String> clash=null;
363 for (Map.Entry<String, String> entry : initParameters.entrySet())
364 {
365 if (entry.getKey() == null) {
366 throw new IllegalArgumentException("init parameter name required");
367 }
368 if (entry.getValue() == null) {
369 throw new IllegalArgumentException("non-null value required for init parameter " + entry.getKey());
370 }
371 if (Holder.this.getInitParameter(entry.getKey())!=null)
372 {
373 if (clash==null)
374 clash=new HashSet<String>();
375 clash.add(entry.getKey());
376 }
377 }
378 if (clash!=null)
379 return clash;
380 Holder.this.getInitParameters().putAll(initParameters);
381 return Collections.emptySet();
382 }
383
384
385 }
386 }
387
388
389
390
391