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