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