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