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 public NamingContext newNamingContext(Object obj, ClassLoader loader, Hashtable env, Name name, Context parentCtx)
188 throws Exception
189 {
190 Reference ref = (Reference)obj;
191 StringRefAddr parserAddr = (StringRefAddr)ref.get("parser");
192 String parserClassName = (parserAddr==null?null:(String)parserAddr.getContent());
193 NameParser parser = (NameParser)(parserClassName==null?null:loader.loadClass(parserClassName).newInstance());
194
195 return new NamingContext (env,
196 name.get(0),
197 (NamingContext)parentCtx,
198 parser);
199 }
200
201
202
203
204
205
206 public Context getContextForClassLoader(ClassLoader loader)
207 {
208 if (loader == null)
209 return null;
210
211 return (Context)__contextMap.get(loader);
212 }
213
214
215
216
217
218
219
220
221 public static Context associateContext(final Context ctx)
222 {
223 Context previous = (Context)__threadContext.get();
224 __threadContext.set(ctx);
225 return previous;
226 }
227
228 public static void disassociateContext(final Context ctx)
229 {
230 __threadContext.remove();
231 }
232
233
234 public static ClassLoader associateClassLoader(final ClassLoader loader)
235 {
236 ClassLoader prev = (ClassLoader)__threadClassLoader.get();
237 __threadClassLoader.set(loader);
238 return prev;
239 }
240
241
242 public static void disassociateClassLoader ()
243 {
244 __threadClassLoader.remove();
245 }
246
247 public static void dump(Appendable out, String indent) throws IOException
248 {
249 out.append("o.e.j.jndi.ContextFactory@").append(Long.toHexString(__contextMap.hashCode())).append("\n");
250 int size=__contextMap.size();
251 int i=0;
252 for (Map.Entry<ClassLoader,NamingContext> entry : ((Map<ClassLoader,NamingContext>)__contextMap).entrySet())
253 {
254 boolean last=++i==size;
255 ClassLoader loader=entry.getKey();
256 out.append(indent).append(" +- ").append(loader.getClass().getSimpleName()).append("@").append(Long.toHexString(loader.hashCode())).append(": ");
257
258 NamingContext context = entry.getValue();
259 context.dump(out,indent+(last?" ":" | "));
260 }
261 }
262
263 }