1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jetty.osgi.boot.internal.webapp;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
21 import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
22 import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
23 import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
24 import org.eclipse.jetty.osgi.boot.internal.serverfactory.IManagedJettyServerRegistry;
25 import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
26 import org.eclipse.jetty.server.handler.ContextHandler;
27 import org.eclipse.jetty.util.Scanner;
28 import org.eclipse.jetty.webapp.WebAppContext;
29 import org.osgi.framework.Bundle;
30 import org.osgi.framework.BundleContext;
31 import org.osgi.framework.FrameworkUtil;
32 import org.osgi.framework.ServiceEvent;
33 import org.osgi.framework.ServiceListener;
34 import org.osgi.framework.ServiceReference;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class JettyContextHandlerServiceTracker implements ServiceListener
54 {
55
56
57 private final IManagedJettyServerRegistry _registry;
58
59
60 private Map<ServiceReference, ContextHandler> _indexByServiceReference = new HashMap<ServiceReference, ContextHandler>();
61
62
63
64
65 private Map<String, ServiceReference> _indexByContextFile = new HashMap<String, ServiceReference>();
66
67
68 private Scanner _scanner;
69
70
71
72
73 public JettyContextHandlerServiceTracker(IManagedJettyServerRegistry registry) throws Exception
74 {
75 _registry = registry;
76 }
77
78 public void stop() throws Exception
79 {
80 if (_scanner != null)
81 {
82 _scanner.stop();
83 }
84
85
86
87 }
88
89
90
91
92
93
94
95 protected void setupContextHomeScanner(File contextHome) throws IOException
96 {
97 if (contextHome == null)
98 {
99 return;
100 }
101 final String osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath();
102 _scanner = new Scanner();
103 _scanner.setRecursive(true);
104 _scanner.setReportExistingFilesOnStartup(false);
105 _scanner.addListener(new Scanner.DiscreteListener()
106 {
107 public void fileAdded(String filename) throws Exception
108 {
109
110
111
112
113 reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
114 }
115
116 public void fileChanged(String filename) throws Exception
117 {
118 reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
119 }
120
121 public void fileRemoved(String filename) throws Exception
122 {
123
124
125
126 reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
127 }
128 });
129
130 }
131
132
133
134
135
136
137
138 public void serviceChanged(ServiceEvent ev)
139 {
140 ServiceReference sr = ev.getServiceReference();
141 switch (ev.getType())
142 {
143 case ServiceEvent.MODIFIED:
144 case ServiceEvent.UNREGISTERING:
145 {
146 ContextHandler ctxtHandler = unregisterInIndex(ev.getServiceReference());
147 if (ctxtHandler != null && !ctxtHandler.isStopped())
148 {
149 try
150 {
151 getWebBundleDeployerHelp(sr).unregister(ctxtHandler);
152 }
153 catch (Exception e)
154 {
155
156 e.printStackTrace();
157 }
158 }
159 }
160 if (ev.getType() == ServiceEvent.UNREGISTERING)
161 {
162 break;
163 }
164 else
165 {
166
167
168 }
169 case ServiceEvent.REGISTERED:
170 {
171 Bundle contributor = sr.getBundle();
172 BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
173 ContextHandler contextHandler = (ContextHandler)context.getService(sr);
174 if (contextHandler.getServer() != null)
175 {
176
177 return;
178 }
179 String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
180 if (contextHandler instanceof WebAppContext && contextFilePath == null)
181
182
183
184 {
185 WebAppContext webapp = (WebAppContext)contextHandler;
186 String contextPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
187 if (contextPath == null)
188 {
189 contextPath = webapp.getContextPath();
190 }
191 String webXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH);
192 if (webXmlPath == null)
193 {
194 webXmlPath = webapp.getDescriptor();
195 }
196 String defaultWebXmlPath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH);
197 if (defaultWebXmlPath == null)
198 {
199 String jettyHome = System.getProperty(DefaultJettyAtJettyHomeHelper.SYS_PROP_JETTY_HOME);
200 if (jettyHome != null)
201 {
202 File etc = new File(jettyHome, "etc");
203 if (etc.exists() && etc.isDirectory())
204 {
205 File webDefault = new File (etc, "webdefault.xml");
206 if (webDefault.exists())
207 defaultWebXmlPath = webDefault.getAbsolutePath();
208 else
209 defaultWebXmlPath = webapp.getDefaultsDescriptor();
210 }
211 else
212 defaultWebXmlPath = webapp.getDefaultsDescriptor();
213 }
214 }
215 String war = (String)sr.getProperty("war");
216 try
217 {
218 IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr);
219 if (deployerHelper == null)
220 {
221
222 }
223 else
224 {
225 WebAppContext handler = deployerHelper
226 .registerWebapplication(contributor,war,contextPath,
227 (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),
228 (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE),
229 (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE),
230 webXmlPath,defaultWebXmlPath,webapp);
231 if (handler != null)
232 {
233 registerInIndex(handler,sr);
234 }
235 }
236 }
237 catch (Throwable e)
238 {
239 e.printStackTrace();
240 }
241 }
242 else
243 {
244
245 if (contextFilePath == null)
246 {
247 throw new IllegalArgumentException("the property contextFilePath is required");
248 }
249 try
250 {
251 IWebBundleDeployerHelper deployerHelper = getWebBundleDeployerHelp(sr);
252 if (deployerHelper == null)
253 {
254
255 }
256 else
257 {
258 if (Boolean.TRUE.toString().equals(sr.getProperty(
259 IWebBundleDeployerHelper.INTERNAL_SERVICE_PROP_UNKNOWN_CONTEXT_HANDLER_TYPE)))
260 {
261 contextHandler = null;
262 }
263 ContextHandler handler = deployerHelper.registerContext(contributor,contextFilePath,
264 (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH),
265 (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE),
266 (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE),
267 contextHandler);
268 if (handler != null)
269 {
270 registerInIndex(handler,sr);
271 }
272 }
273 }
274 catch (Throwable e)
275 {
276
277 e.printStackTrace();
278 }
279 }
280 }
281 break;
282 }
283 }
284
285 private void registerInIndex(ContextHandler handler, ServiceReference sr)
286 {
287 _indexByServiceReference.put(sr,handler);
288 String key = getSymbolicNameAndContextFileKey(sr);
289 if (key != null)
290 {
291 _indexByContextFile.put(key,sr);
292 }
293 }
294
295
296
297
298
299
300
301 private ContextHandler unregisterInIndex(ServiceReference sr)
302 {
303 ContextHandler handler = _indexByServiceReference.remove(sr);
304 String key = getSymbolicNameAndContextFileKey(sr);
305 if (key != null)
306 {
307 _indexByContextFile.remove(key);
308 }
309 if (handler == null)
310 {
311
312 return null;
313 }
314 return handler;
315 }
316
317
318
319
320
321 private String getSymbolicNameAndContextFileKey(ServiceReference sr)
322 {
323 String contextFilePath = (String)sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
324 if (contextFilePath != null)
325 {
326 return sr.getBundle().getSymbolicName() + "/" + contextFilePath;
327 }
328 return null;
329 }
330
331
332
333
334
335
336 public void reloadJettyContextHandler(String canonicalNameOfFileChanged, String osgiContextHomeFolderCanonicalPath)
337 {
338 String key = getNormalizedRelativePath(canonicalNameOfFileChanged, osgiContextHomeFolderCanonicalPath);
339 if (key == null)
340 {
341 return;
342 }
343 ServiceReference sr = _indexByContextFile.get(key);
344 if (sr == null)
345 {
346
347 return;
348 }
349 serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED,sr));
350 }
351
352
353
354
355
356 private String getNormalizedRelativePath(String canFilename, String osgiContextHomeFolderCanonicalPath)
357 {
358 if (!canFilename.startsWith(osgiContextHomeFolderCanonicalPath))
359 {
360
361
362
363 return null;
364 }
365 return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\','/');
366 }
367
368
369
370
371 private ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
372 {
373 if (_registry == null)
374 {
375 return null;
376 }
377 if (managedServerName == null)
378 {
379 managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
380 }
381 ServerInstanceWrapper wrapper = _registry.getServerInstanceWrapper(managedServerName);
382
383 return wrapper;
384 }
385
386 private IWebBundleDeployerHelper getWebBundleDeployerHelp(ServiceReference sr)
387 {
388 if (_registry == null)
389 {
390 return null;
391 }
392 String managedServerName = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
393 ServerInstanceWrapper wrapper = getServerInstanceWrapper(managedServerName);
394 return wrapper != null ? wrapper.getWebBundleDeployerHelp() : null;
395 }
396
397 }