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