1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.osgi.boot.internal.serverfactory;
20
21 import java.io.File;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Dictionary;
26 import java.util.Enumeration;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.StringTokenizer;
33
34 import org.eclipse.jetty.deploy.AppLifeCycle;
35 import org.eclipse.jetty.deploy.AppProvider;
36 import org.eclipse.jetty.deploy.DeploymentManager;
37 import org.eclipse.jetty.deploy.bindings.StandardStarter;
38 import org.eclipse.jetty.deploy.bindings.StandardStopper;
39 import org.eclipse.jetty.osgi.boot.BundleContextProvider;
40 import org.eclipse.jetty.osgi.boot.BundleWebAppProvider;
41 import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
42 import org.eclipse.jetty.osgi.boot.OSGiDeployer;
43 import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
44 import org.eclipse.jetty.osgi.boot.OSGiUndeployer;
45 import org.eclipse.jetty.osgi.boot.ServiceContextProvider;
46 import org.eclipse.jetty.osgi.boot.ServiceWebAppProvider;
47 import org.eclipse.jetty.osgi.boot.internal.webapp.LibExtClassLoaderHelper;
48 import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
49 import org.eclipse.jetty.osgi.boot.utils.FakeURLClassLoader;
50 import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
51 import org.eclipse.jetty.osgi.boot.utils.Util;
52 import org.eclipse.jetty.server.Server;
53 import org.eclipse.jetty.server.handler.ContextHandlerCollection;
54 import org.eclipse.jetty.util.log.Log;
55 import org.eclipse.jetty.util.log.Logger;
56 import org.eclipse.jetty.util.resource.Resource;
57 import org.eclipse.jetty.xml.XmlConfiguration;
58
59
60
61
62
63
64 public class ServerInstanceWrapper
65 {
66
67
68
69
70
71
72 public static final String PROPERTY_THIS_JETTY_XML_FOLDER_URL = "this.jetty.xml.parent.folder.url";
73
74
75 private static Collection<TldBundleDiscoverer> __containerTldBundleDiscoverers = new ArrayList<TldBundleDiscoverer>();
76
77 private static Logger LOG = Log.getLogger(ServerInstanceWrapper.class.getName());
78
79
80
81 private final String _managedServerName;
82
83
84
85
86 private Server _server;
87
88 private ContextHandlerCollection _ctxtCollection;
89
90
91
92
93
94
95 private ClassLoader _commonParentClassLoaderForWebapps;
96
97 private DeploymentManager _deploymentManager;
98
99
100
101
102 public static void addContainerTldBundleDiscoverer (TldBundleDiscoverer tldBundleDiscoverer)
103 {
104 __containerTldBundleDiscoverers.add(tldBundleDiscoverer);
105 }
106
107
108 public static Collection<TldBundleDiscoverer> getContainerTldBundleDiscoverers()
109 {
110 return __containerTldBundleDiscoverers;
111 }
112
113
114
115
116
117 public static Server configure(Server server, List<URL> jettyConfigurations, Dictionary props) throws Exception
118 {
119
120 if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return server; }
121
122 Map<String, Object> id_map = new HashMap<String, Object>();
123 if (server != null)
124 {
125
126 id_map.put("Server", server);
127 id_map.put((String)props.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME), server);
128 }
129
130 Map<String, String> properties = new HashMap<String, String>();
131 if (props != null)
132 {
133 Enumeration<Object> en = props.keys();
134 while (en.hasMoreElements())
135 {
136 Object key = en.nextElement();
137 Object value = props.get(key);
138 String keyStr = String.valueOf(key);
139 String valStr = String.valueOf(value);
140 properties.put(keyStr, valStr);
141 if (server != null) server.setAttribute(keyStr, valStr);
142 }
143 }
144
145 for (URL jettyConfiguration : jettyConfigurations)
146 {
147 try(Resource r = Resource.newResource(jettyConfiguration))
148 {
149
150 if (!r.exists())
151 {
152 LOG.warn("File does not exist "+r);
153 throw new IllegalStateException("No such jetty server config file: "+r);
154 }
155
156 XmlConfiguration config = new XmlConfiguration(r.getURL());
157
158 config.getIdMap().putAll(id_map);
159 config.getProperties().putAll(properties);
160
161
162
163
164 String urlPath = jettyConfiguration.toString();
165 int lastSlash = urlPath.lastIndexOf('/');
166 if (lastSlash > 4)
167 {
168 urlPath = urlPath.substring(0, lastSlash);
169 config.getProperties().put(PROPERTY_THIS_JETTY_XML_FOLDER_URL, urlPath);
170 }
171
172 Object o = config.configure();
173 if (server == null)
174 server = (Server)o;
175
176 id_map = config.getIdMap();
177 }
178 catch (Exception e)
179 {
180 LOG.warn("Configuration error in " + jettyConfiguration);
181 throw e;
182 }
183 }
184
185 return server;
186 }
187
188
189
190
191
192 public ServerInstanceWrapper(String managedServerName)
193 {
194 _managedServerName = managedServerName;
195 }
196
197
198 public String getManagedServerName()
199 {
200 return _managedServerName;
201 }
202
203
204
205
206
207
208
209
210
211 public ClassLoader getParentClassLoaderForWebapps()
212 {
213 return _commonParentClassLoaderForWebapps;
214 }
215
216
217
218
219
220
221 public DeploymentManager getDeploymentManager()
222 {
223 return _deploymentManager;
224 }
225
226
227
228
229
230
231 public Server getServer()
232 {
233 return _server;
234 }
235
236
237
238
239
240 public ContextHandlerCollection getContextHandlerCollection()
241 {
242 return _ctxtCollection;
243 }
244
245
246 public void start(Server server, Dictionary props) throws Exception
247 {
248 _server = server;
249 ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
250 try
251 {
252
253
254 ClassLoader libExtClassLoader = null;
255 String sharedURLs = (String) props.get(OSGiServerConstants.MANAGED_JETTY_SHARED_LIB_FOLDER_URLS);
256
257 List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
258 libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null,JettyBootstrapActivator.class.getClassLoader());
259
260 if (LOG.isDebugEnabled()) LOG.debug("LibExtClassLoader = "+libExtClassLoader);
261
262 Thread.currentThread().setContextClassLoader(libExtClassLoader);
263
264 String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
265 List<URL> jettyConfigurations = jettyConfigurationUrls != null ? Util.fileNamesAsURLs(jettyConfigurationUrls, Util.DEFAULT_DELIMS) : null;
266
267 _server = configure(server, jettyConfigurations, props);
268
269 init();
270
271
272
273
274
275 if (!__containerTldBundleDiscoverers.isEmpty())
276 {
277 Set<URL> urls = new HashSet<URL>();
278
279 for (TldBundleDiscoverer d:__containerTldBundleDiscoverers)
280 {
281 URL[] list = d.getUrlsForBundlesWithTlds(_deploymentManager, BundleFileLocatorHelperFactory.getFactory().getHelper());
282 if (list != null)
283 {
284 for (URL u:list)
285 urls.add(u);
286 }
287 }
288 _commonParentClassLoaderForWebapps = new FakeURLClassLoader(libExtClassLoader, urls.toArray(new URL[urls.size()]));
289 }
290 else
291 _commonParentClassLoaderForWebapps = libExtClassLoader;
292
293
294 if (LOG.isDebugEnabled()) LOG.debug("common classloader = "+_commonParentClassLoaderForWebapps);
295
296 server.start();
297 }
298 catch (Exception e)
299 {
300 if (server != null)
301 {
302 try
303 {
304 server.stop();
305 }
306 catch (Exception x)
307 {
308 LOG.ignore(x);
309 }
310 }
311 throw e;
312 }
313 finally
314 {
315 Thread.currentThread().setContextClassLoader(contextCl);
316 }
317 }
318
319
320 public void stop()
321 {
322 try
323 {
324 if (_server.isRunning())
325 {
326 _server.stop();
327 }
328 }
329 catch (Exception e)
330 {
331 LOG.warn(e);
332 }
333 }
334
335
336
337
338
339
340
341
342
343
344
345 private void init()
346 {
347
348 _ctxtCollection = (ContextHandlerCollection) _server.getChildHandlerByClass(ContextHandlerCollection.class);
349
350 if (_ctxtCollection == null)
351 throw new IllegalStateException("ERROR: No ContextHandlerCollection configured in Server");
352
353 List<String> providerClassNames = new ArrayList<String>();
354
355
356 Collection<DeploymentManager> deployers = _server.getBeans(DeploymentManager.class);
357 if (deployers != null && !deployers.isEmpty())
358 {
359 _deploymentManager = deployers.iterator().next();
360
361 for (AppProvider provider : _deploymentManager.getAppProviders())
362 {
363 providerClassNames.add(provider.getClass().getName());
364 }
365 }
366 else
367 {
368
369 _deploymentManager = new DeploymentManager();
370 _deploymentManager.setContexts(_ctxtCollection);
371 _server.addBean(_deploymentManager);
372 }
373
374 _deploymentManager.setUseStandardBindings(false);
375 List<AppLifeCycle.Binding> deploymentLifeCycleBindings = new ArrayList<AppLifeCycle.Binding>();
376 deploymentLifeCycleBindings.add(new OSGiDeployer(this));
377 deploymentLifeCycleBindings.add(new StandardStarter());
378 deploymentLifeCycleBindings.add(new StandardStopper());
379 deploymentLifeCycleBindings.add(new OSGiUndeployer(this));
380 _deploymentManager.setLifeCycleBindings(deploymentLifeCycleBindings);
381
382 if (!providerClassNames.contains(BundleWebAppProvider.class.getName()))
383 {
384
385 try
386 {
387 BundleWebAppProvider webAppProvider = new BundleWebAppProvider(this);
388 _deploymentManager.addAppProvider(webAppProvider);
389 }
390 catch (Exception e)
391 {
392 LOG.warn(e);
393 }
394 }
395
396 if (!providerClassNames.contains(ServiceWebAppProvider.class.getName()))
397 {
398
399 try
400 {
401 ServiceWebAppProvider webAppProvider = new ServiceWebAppProvider(this);
402 _deploymentManager.addAppProvider(webAppProvider);
403 }
404 catch (Exception e)
405 {
406 LOG.warn(e);
407 }
408 }
409
410 if (!providerClassNames.contains(BundleContextProvider.class.getName()))
411 {
412 try
413 {
414 BundleContextProvider contextProvider = new BundleContextProvider(this);
415 _deploymentManager.addAppProvider(contextProvider);
416 }
417 catch (Exception e)
418 {
419 LOG.warn(e);
420 }
421 }
422
423 if (!providerClassNames.contains(ServiceContextProvider.class.getName()))
424 {
425 try
426 {
427 ServiceContextProvider contextProvider = new ServiceContextProvider(this);
428 _deploymentManager.addAppProvider(contextProvider);
429 }
430 catch (Exception e)
431 {
432 LOG.warn(e);
433 }
434 }
435 }
436
437
438
439
440
441
442
443
444
445
446 private List<File> extractFiles(String propertyValue)
447 {
448 StringTokenizer tokenizer = new StringTokenizer(propertyValue, ",;", false);
449 List<File> files = new ArrayList<File>();
450 while (tokenizer.hasMoreTokens())
451 {
452 String tok = tokenizer.nextToken();
453 try
454 {
455 URL url = new URL(tok);
456 url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(url);
457 if (url.getProtocol().equals("file"))
458 {
459 Resource res = Resource.newResource(url);
460 File folder = res.getFile();
461 if (folder != null)
462 {
463 files.add(folder);
464 }
465 }
466 }
467 catch (Throwable mfe)
468 {
469 LOG.warn(mfe);
470 }
471 }
472 return files;
473 }
474
475 }