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.utils.internal;
20
21 import java.io.File;
22 import java.lang.reflect.Field;
23 import java.lang.reflect.Method;
24 import java.net.URI;
25 import java.net.URL;
26 import java.net.URLConnection;
27 import java.net.URLDecoder;
28 import java.util.ArrayList;
29 import java.util.Enumeration;
30 import java.util.zip.ZipFile;
31
32 import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
33 import org.eclipse.jetty.util.URIUtil;
34 import org.eclipse.jetty.util.resource.Resource;
35 import org.eclipse.jetty.util.resource.FileResource;
36 import org.osgi.framework.Bundle;
37
38
39
40
41
42
43
44 public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
45 {
46
47
48
49
50
51
52 private static Field BUNDLE_ENTRY_FIELD = null;
53
54 private static Field FILE_FIELD = null;
55
56 private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null;
57
58
59
60
61 private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;
62
63
64
65
66
67
68
69
70
71
72 public File getBundleInstallLocation(Bundle bundle) throws Exception
73 {
74
75
76
77 URL url = bundle.getEntry("/META-INF/MANIFEST.MF");
78
79 if (url.getProtocol().equals("file"))
80 {
81
82
83
84 return new FileResource(url).getFile().getParentFile().getParentFile();
85 }
86 else if (url.getProtocol().equals("bundleentry"))
87 {
88
89
90
91
92 URLConnection con = url.openConnection();
93 con.setUseCaches(Resource.getDefaultUseCaches());
94
95
96
97
98
99
100 if (BUNDLE_ENTRY_FIELD == null)
101 {
102 BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
103 BUNDLE_ENTRY_FIELD.setAccessible(true);
104 }
105 Object bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
106 if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry"))
107 {
108 if (FILE_FIELD == null)
109 {
110 FILE_FIELD = bundleEntry.getClass().getDeclaredField("file");
111 FILE_FIELD.setAccessible(true);
112 }
113 File f = (File) FILE_FIELD.get(bundleEntry);
114 return f.getParentFile().getParentFile();
115 }
116 else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry"))
117 {
118 url = bundle.getEntry("/");
119
120 con = url.openConnection();
121 con.setDefaultUseCaches(Resource.getDefaultUseCaches());
122
123 if (BUNDLE_ENTRY_FIELD == null)
124 {
125 BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
126 BUNDLE_ENTRY_FIELD.setAccessible(true);
127 }
128 bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
129 if (BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY == null)
130 {
131 BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = bundleEntry.getClass().getDeclaredField("bundleFile");
132 BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.setAccessible(true);
133 }
134 Object zipBundleFile = BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.get(bundleEntry);
135 if (ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE == null)
136 {
137 ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile");
138 ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true);
139 }
140 ZipFile zipFile = (ZipFile) ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile);
141 return new File(zipFile.getName());
142 }
143 else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry"))
144 {
145
146
147 }
148 }
149 else if ("bundle".equals(url.getProtocol()))
150 {
151
152 String location = bundle.getLocation();
153 if (location.startsWith("file:/"))
154 {
155 URI uri = new URI(URIUtil.encodePath(location));
156 return new File(uri);
157 }
158 else if (location.startsWith("file:"))
159 {
160
161
162
163 File res = new File(location.substring("file:".length()));
164 if (!res.exists()) { return null;
165
166
167
168
169
170
171
172
173
174
175
176 }
177 return res;
178 }
179 else if (location.startsWith("reference:file:"))
180 {
181 location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8");
182 File file = new File(location.substring("file:".length()));
183 return file;
184 }
185 }
186 return null;
187 }
188
189
190
191
192
193
194
195
196
197 public File getFileInBundle(Bundle bundle, String path) throws Exception
198 {
199 if (path != null && path.length() > 0 && path.charAt(0) == '/')
200 {
201 path = path.substring(1);
202 }
203 File bundleInstall = getBundleInstallLocation(bundle);
204 File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall;
205 if (!webapp.exists()) { throw new IllegalArgumentException("Unable to locate " + path
206 + " inside "
207 + bundle.getSymbolicName()
208 + " ("
209 + (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ")
210 + ")"); }
211 return webapp;
212 }
213
214
215
216
217
218
219
220
221
222
223 public Enumeration<URL> findEntries(Bundle bundle, String entryPath)
224 {
225 int last = entryPath.lastIndexOf('/');
226 String path = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(0, last) : "/";
227 if (!path.startsWith("/"))
228 {
229 path = "/" + path;
230 }
231 String pattern = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(last + 1) : entryPath;
232 Enumeration<URL> enUrls = bundle.findEntries(path, pattern, false);
233 return enUrls;
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250 public File[] locateJarsInsideBundle(Bundle bundle) throws Exception
251 {
252 File jasperLocation = getBundleInstallLocation(bundle);
253 if (jasperLocation.isDirectory())
254 {
255
256 ArrayList<File> urls = new ArrayList<File>();
257 for (File f : jasperLocation.listFiles())
258 {
259 if (f.getName().endsWith(".jar") && f.isFile())
260 {
261 urls.add(f);
262 }
263 else if (f.isDirectory() && f.getName().equals("lib"))
264 {
265 for (File f2 : jasperLocation.listFiles())
266 {
267 if (f2.getName().endsWith(".jar") && f2.isFile())
268 {
269 urls.add(f2);
270 }
271 }
272 }
273 }
274 return urls.toArray(new File[urls.size()]);
275 }
276 else
277 {
278 return new File[] { jasperLocation };
279 }
280 }
281
282
283
284
285
286 private static Method BUNDLE_URL_CONNECTION_getLocalURL = null;
287
288 private static Method BUNDLE_URL_CONNECTION_getFileURL = null;
289
290
291
292
293
294
295
296
297
298
299
300 public URL getLocalURL(URL url)
301 {
302 if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
303 {
304 try
305 {
306 URLConnection conn = url.openConnection();
307 conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
308 if (BUNDLE_URL_CONNECTION_getLocalURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
309 {
310 BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
311 BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
312 }
313 if (BUNDLE_URL_CONNECTION_getLocalURL != null) { return (URL) BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); }
314 }
315 catch (Throwable t)
316 {
317 System.err.println("Unable to locate the OSGi url: '" + url + "'.");
318 t.printStackTrace();
319 }
320 }
321 return url;
322 }
323
324
325
326
327
328
329
330
331
332
333
334
335
336 public URL getFileURL(URL url)
337 {
338 if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
339 {
340 try
341 {
342 URLConnection conn = url.openConnection();
343 conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
344 if (BUNDLE_URL_CONNECTION_getFileURL == null && conn.getClass().getName().equals("org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
345 {
346 BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
347 BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
348 }
349 if (BUNDLE_URL_CONNECTION_getFileURL != null) { return (URL) BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); }
350 }
351 catch (Throwable t)
352 {
353 t.printStackTrace();
354 }
355 }
356 return url;
357 }
358
359 }