1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.jndi;
20
21
22 import java.io.IOException;
23 import java.util.Hashtable;
24 import java.util.Map;
25 import java.util.WeakHashMap;
26
27 import javax.naming.Context;
28 import javax.naming.Name;
29 import javax.naming.NameParser;
30 import javax.naming.Reference;
31 import javax.naming.StringRefAddr;
32 import javax.naming.spi.ObjectFactory;
33
34 import org.eclipse.jetty.server.handler.ContextHandler;
35 import org.eclipse.jetty.util.log.Logger;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 public class ContextFactory implements ObjectFactory
66 {
67 private static Logger __log = NamingUtil.__log;
68
69
70
71
72 private static final WeakHashMap __contextMap = new WeakHashMap();
73
74
75
76
77
78 private static final ThreadLocal<Context> __threadContext = new ThreadLocal<Context>();
79
80
81
82
83
84 private static final ThreadLocal<ClassLoader> __threadClassLoader = new ThreadLocal<ClassLoader>();
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 public Object getObjectInstance (Object obj,
104 Name name,
105 Context nameCtx,
106 Hashtable env)
107 throws Exception
108 {
109
110 Context ctx = (Context)__threadContext.get();
111 if (ctx != null)
112 {
113 if(__log.isDebugEnabled()) __log.debug("Using the Context that is bound on the thread");
114 return ctx;
115 }
116
117
118
119 ClassLoader loader = (ClassLoader)__threadClassLoader.get();
120 if (loader != null)
121 {
122 if (__log.isDebugEnabled() && loader != null) __log.debug("Using threadlocal classloader");
123 ctx = getContextForClassLoader(loader);
124 if (ctx == null)
125 {
126 ctx = newNamingContext(obj, loader, env, name, nameCtx);
127 __contextMap.put (loader, ctx);
128 if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader);
129 }
130 return ctx;
131 }
132
133
134 ClassLoader tccl = Thread.currentThread().getContextClassLoader();
135 loader = tccl;
136 if (loader != null)
137 {
138 if (__log.isDebugEnabled() && loader != null) __log.debug("Trying thread context classloader");
139 while (ctx == null && loader != null)
140 {
141 ctx = getContextForClassLoader(loader);
142 if (ctx == null && loader != null)
143 loader = loader.getParent();
144 }
145
146 if (ctx == null)
147 {
148 ctx = newNamingContext(obj, tccl, env, name, nameCtx);
149 __contextMap.put (tccl, ctx);
150 if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+tccl);
151 }
152 return ctx;
153 }
154
155
156
157
158 if (ContextHandler.getCurrentContext() != null)
159 {
160
161 if (__log.isDebugEnabled() && loader != null) __log.debug("Trying classloader of current org.eclipse.jetty.server.handler.ContextHandler");
162 loader = ContextHandler.getCurrentContext().getContextHandler().getClassLoader();
163 ctx = (Context)__contextMap.get(loader);
164
165 if (ctx == null && loader != null)
166 {
167 ctx = newNamingContext(obj, loader, env, name, nameCtx);
168 __contextMap.put (loader, ctx);
169 if(__log.isDebugEnabled())__log.debug("Made context "+name.get(0)+" for classloader: "+loader);
170 }
171
172 return ctx;
173 }
174 return null;
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188 public NamingContext newNamingContext(Object obj, ClassLoader loader, Hashtable env, Name name, Context parentCtx)
189 throws Exception
190 {
191 Reference ref = (Reference)obj;
192 StringRefAddr parserAddr = (StringRefAddr)ref.get("parser");
193 String parserClassName = (parserAddr==null?null:(String)parserAddr.getContent());
194 NameParser parser = (NameParser)(parserClassName==null?null:loader.loadClass(parserClassName).newInstance());
195
196 return new NamingContext (env,
197 name.get(0),
198 (NamingContext)parentCtx,
199 parser);
200 }
201
202
203
204
205
206
207
208 public Context getContextForClassLoader(ClassLoader loader)
209 {
210 if (loader == null)
211 return null;
212
213 return (Context)__contextMap.get(loader);
214 }
215
216
217
218
219
220
221
222
223 public static Context associateContext(final Context ctx)
224 {
225 Context previous = (Context)__threadContext.get();
226 __threadContext.set(ctx);
227 return previous;
228 }
229
230 public static void disassociateContext(final Context ctx)
231 {
232 __threadContext.remove();
233 }
234
235
236 public static ClassLoader associateClassLoader(final ClassLoader loader)
237 {
238 ClassLoader prev = (ClassLoader)__threadClassLoader.get();
239 __threadClassLoader.set(loader);
240 return prev;
241 }
242
243
244 public static void disassociateClassLoader ()
245 {
246 __threadClassLoader.remove();
247 }
248
249 public static void dump(Appendable out, String indent) throws IOException
250 {
251 out.append("o.e.j.jndi.ContextFactory@").append(Long.toHexString(__contextMap.hashCode())).append("\n");
252 int size=__contextMap.size();
253 int i=0;
254 for (Map.Entry<ClassLoader,NamingContext> entry : ((Map<ClassLoader,NamingContext>)__contextMap).entrySet())
255 {
256 boolean last=++i==size;
257 ClassLoader loader=entry.getKey();
258 out.append(indent).append(" +- ").append(loader.getClass().getSimpleName()).append("@").append(Long.toHexString(loader.hashCode())).append(": ");
259
260 NamingContext context = entry.getValue();
261 context.dump(out,indent+(last?" ":" | "));
262 }
263 }
264
265 }