1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.plus.webapp;
15
16 import java.net.URL;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.Iterator;
20 import java.util.List;
21
22 import javax.naming.Binding;
23 import javax.naming.Context;
24 import javax.naming.InitialContext;
25 import javax.naming.Name;
26 import javax.naming.NameNotFoundException;
27 import javax.naming.NamingException;
28
29 import org.eclipse.jetty.jndi.NamingContext;
30 import org.eclipse.jetty.jndi.NamingUtil;
31 import org.eclipse.jetty.jndi.local.localContextRoot;
32 import org.eclipse.jetty.plus.jndi.EnvEntry;
33 import org.eclipse.jetty.plus.jndi.NamingEntryUtil;
34 import org.eclipse.jetty.util.log.Log;
35 import org.eclipse.jetty.webapp.AbstractConfiguration;
36 import org.eclipse.jetty.webapp.Configuration;
37 import org.eclipse.jetty.webapp.WebAppContext;
38 import org.eclipse.jetty.xml.XmlConfiguration;
39
40
41
42
43
44
45
46 public class EnvConfiguration extends AbstractConfiguration
47 {
48 private static final String JETTY_ENV_BINDINGS = "org.eclipse.jetty.jndi.EnvConfiguration";
49 private URL jettyEnvXmlUrl;
50
51 public void setJettyEnvXml (URL url)
52 {
53 this.jettyEnvXmlUrl = url;
54 }
55
56
57
58
59
60 @Override
61 public void preConfigure (WebAppContext context) throws Exception
62 {
63
64 createEnvContext(context);
65 }
66
67
68
69
70 @Override
71 public void configure (WebAppContext context) throws Exception
72 {
73 if (Log.isDebugEnabled())
74 Log.debug("Created java:comp/env for webapp "+context.getContextPath());
75
76
77
78 if (jettyEnvXmlUrl == null)
79 {
80
81
82 org.eclipse.jetty.util.resource.Resource web_inf = context.getWebInf();
83 if(web_inf!=null && web_inf.isDirectory())
84 {
85 org.eclipse.jetty.util.resource.Resource jettyEnv = web_inf.addPath("jetty-env.xml");
86 if(jettyEnv.exists())
87 {
88 jettyEnvXmlUrl = jettyEnv.getURL();
89 }
90 }
91 }
92
93 if (jettyEnvXmlUrl != null)
94 {
95 synchronized (localContextRoot.getRoot())
96 {
97
98 final List<Bound> bindings = new ArrayList<Bound>();
99 NamingContext.Listener listener = new NamingContext.Listener()
100 {
101 public void unbind(NamingContext ctx, Binding binding)
102 {
103 }
104
105 public Binding bind(NamingContext ctx, Binding binding)
106 {
107 bindings.add(new Bound(ctx,binding.getName()));
108 return binding;
109 }
110 };
111
112 try
113 {
114 localContextRoot.getRoot().addListener(listener);
115 XmlConfiguration configuration = new XmlConfiguration(jettyEnvXmlUrl);
116 configuration.configure(context);
117 }
118 finally
119 {
120 localContextRoot.getRoot().removeListener(listener);
121 context.setAttribute(JETTY_ENV_BINDINGS,bindings);
122 }
123 }
124 }
125
126
127 bindEnvEntries(context);
128 }
129
130
131
132
133
134
135
136 @Override
137 public void deconfigure (WebAppContext context) throws Exception
138 {
139
140 ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
141 Thread.currentThread().setContextClassLoader(context.getClassLoader());
142 try
143 {
144 Context ic = new InitialContext();
145 Context compCtx = (Context)ic.lookup ("java:comp");
146 compCtx.destroySubcontext("env");
147
148
149 @SuppressWarnings("unchecked")
150 List<Bound> bindings = (List<Bound>)context.getAttribute(JETTY_ENV_BINDINGS);
151 context.setAttribute(JETTY_ENV_BINDINGS,null);
152 if (bindings!=null)
153 {
154 Collections.reverse(bindings);
155 for (Bound b:bindings)
156 b._context.destroySubcontext(b._name);
157 }
158 }
159 catch (NameNotFoundException e)
160 {
161 Log.warn(e);
162 }
163 finally
164 {
165 Thread.currentThread().setContextClassLoader(oldLoader);
166 }
167 }
168
169
170
171
172
173
174
175 @Override
176 public void destroy (WebAppContext context) throws Exception
177 {
178 try
179 {
180
181 NamingContext scopeContext = (NamingContext)NamingEntryUtil.getContextForScope(context);
182 scopeContext.getParent().destroySubcontext(scopeContext.getName());
183 }
184 catch (NameNotFoundException e)
185 {
186 Log.ignore(e);
187 Log.debug("No naming entries configured in environment for webapp "+context);
188 }
189 }
190
191
192
193
194
195
196
197
198 public void bindEnvEntries (WebAppContext context)
199 throws NamingException
200 {
201 Log.debug("Binding env entries from the jvm scope");
202 InitialContext ic = new InitialContext();
203 Context envCtx = (Context)ic.lookup("java:comp/env");
204 Object scope = null;
205 List<Object> list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
206 Iterator<Object> itor = list.iterator();
207 while (itor.hasNext())
208 {
209 EnvEntry ee = (EnvEntry)itor.next();
210 ee.bindToENC(ee.getJndiName());
211 Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
212 NamingUtil.bind(envCtx, namingEntryName.toString(), ee);
213 }
214
215 Log.debug("Binding env entries from the server scope");
216
217 scope = context.getServer();
218 list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
219 itor = list.iterator();
220 while (itor.hasNext())
221 {
222 EnvEntry ee = (EnvEntry)itor.next();
223 ee.bindToENC(ee.getJndiName());
224 Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
225 NamingUtil.bind(envCtx, namingEntryName.toString(), ee);
226 }
227
228 Log.debug("Binding env entries from the context scope");
229 scope = context;
230 list = NamingEntryUtil.lookupNamingEntries(scope, EnvEntry.class);
231 itor = list.iterator();
232 while (itor.hasNext())
233 {
234 EnvEntry ee = (EnvEntry)itor.next();
235 ee.bindToENC(ee.getJndiName());
236 Name namingEntryName = NamingEntryUtil.makeNamingEntryName(null, ee);
237 NamingUtil.bind(envCtx, namingEntryName.toString(), ee);
238 }
239 }
240
241 protected void createEnvContext (WebAppContext wac)
242 throws NamingException
243 {
244 ClassLoader old_loader = Thread.currentThread().getContextClassLoader();
245 Thread.currentThread().setContextClassLoader(wac.getClassLoader());
246 try
247 {
248 Context context = new InitialContext();
249 Context compCtx = (Context)context.lookup ("java:comp");
250 compCtx.createSubcontext("env");
251 }
252 finally
253 {
254 Thread.currentThread().setContextClassLoader(old_loader);
255 }
256 }
257
258 private static class Bound
259 {
260 final NamingContext _context;
261 final String _name;
262 Bound(NamingContext context, String name)
263 {
264 _context=context;
265 _name=name;
266 }
267 }
268 }