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