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