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