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