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.util.ArrayList;
22 import java.util.zip.ZipFile;
23
24 import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
25 import org.eclipse.jetty.util.URIUtil;
26 import org.osgi.framework.Bundle;
27
28
29
30
31
32
33
34 public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
35 {
36
37
38
39
40
41
42 private static Field BUNDLE_ENTRY_FIELD = null;
43 private static Field FILE_FIELD = null;
44
45 private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null;
46
47
48
49 private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;
50
51
52
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
72 if (url.getProtocol().equals("file"))
73 {
74
75
76 return new File(url.toURI()).getParentFile().getParentFile();
77 }
78 else if (url.getProtocol().equals("bundleentry"))
79 {
80
81
82
83 URLConnection con = url.openConnection();
84 if (BUNDLE_ENTRY_FIELD == null)
85 {
86 BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
87 BUNDLE_ENTRY_FIELD.setAccessible(true);
88 }
89 Object bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
90 if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry"))
91 {
92 if (FILE_FIELD == null)
93 {
94 FILE_FIELD = bundleEntry.getClass().getDeclaredField("file");
95 FILE_FIELD.setAccessible(true);
96 }
97 File f = (File)FILE_FIELD.get(bundleEntry);
98 return f.getParentFile().getParentFile();
99 }
100 else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry"))
101 {
102 url = bundle.getEntry("/");
103 con = url.openConnection();
104 if (BUNDLE_ENTRY_FIELD == null)
105 {
106 BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
107 BUNDLE_ENTRY_FIELD.setAccessible(true);
108 }
109 bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
110 if (BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY == null)
111 {
112 BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = bundleEntry.getClass().getDeclaredField("bundleFile");
113 BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.setAccessible(true);
114 }
115 Object zipBundleFile = BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.get(bundleEntry);
116 if (ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE == null)
117 {
118 ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile");
119 ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true);
120 }
121 ZipFile zipFile = (ZipFile)ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile);
122 return new File(zipFile.getName());
123 }
124 else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry"))
125 {
126
127
128 }
129 }
130 else if ("bundle".equals(url.getProtocol()))
131 {
132
133 String location = bundle.getLocation();
134 if (location.startsWith("file:/"))
135 {
136 URI uri = new URI(URIUtil.encodePath(location));
137 return new File(uri);
138 }
139 }
140 return null;
141 }
142
143
144
145
146
147
148
149
150
151 public File getFileInBundle(Bundle bundle, String path) throws Exception
152 {
153 if (path != null && path.length() > 0 && path.charAt(0) == '/')
154 {
155 path = path.substring(1);
156 }
157 File bundleInstall = getBundleInstallLocation(bundle);
158 File webapp = path != null && path.length() != 0?new File(bundleInstall,path):bundleInstall;
159 if (!webapp.exists())
160 {
161 throw new IllegalArgumentException("Unable to locate " + path + " inside " + bundle.getSymbolicName() + " ("
162 + (bundleInstall != null?bundleInstall.getAbsolutePath():" no_bundle_location ") + ")");
163 }
164 return webapp;
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 public File[] locateJarsInsideBundle(Bundle bundle) throws Exception
182 {
183 File jasperLocation = getBundleInstallLocation(bundle);
184 if (jasperLocation.isDirectory())
185 {
186
187 ArrayList<File> urls = new ArrayList<File>();
188 for (File f : jasperLocation.listFiles())
189 {
190 if (f.getName().endsWith(".jar") && f.isFile())
191 {
192 urls.add(f);
193 }
194 else if (f.isDirectory() && f.getName().equals("lib"))
195 {
196 for (File f2 : jasperLocation.listFiles())
197 {
198 if (f2.getName().endsWith(".jar") && f2.isFile())
199 {
200 urls.add(f2);
201 }
202 }
203 }
204 }
205 return urls.toArray(new File[urls.size()]);
206 }
207 else
208 {
209 return new File[]
210 { jasperLocation };
211 }
212 }
213
214
215
216 private static Method BUNDLE_URL_CONNECTION_getLocalURL = null;
217 private static Method BUNDLE_URL_CONNECTION_getFileURL = null;
218
219
220
221
222
223
224
225
226
227 public static URL getLocalURL(URL url) {
228 if ("bundleresource".equals(url.getProtocol())) {
229 try {
230 URLConnection conn = url.openConnection();
231 if (BUNDLE_URL_CONNECTION_getLocalURL == null &&
232 conn.getClass().getName().equals(
233 "org.eclipse.osgi.framework.internal.core.BundleURLConnection")) {
234 BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
235 BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
236 }
237 if (BUNDLE_URL_CONNECTION_getLocalURL != null) {
238 return (URL)BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null);
239 }
240 } catch (Throwable t) {
241 t.printStackTrace();
242 }
243 }
244 return url;
245 }
246
247
248
249
250
251
252
253
254
255
256 public static URL getFileURL(URL url)
257 {
258 if ("bundleresource".equals(url.getProtocol()))
259 {
260 try
261 {
262 URLConnection conn = url.openConnection();
263 if (BUNDLE_URL_CONNECTION_getFileURL == null &&
264 conn.getClass().getName().equals(
265 "org.eclipse.osgi.framework.internal.core.BundleURLConnection"))
266 {
267 BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
268 BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
269 }
270 if (BUNDLE_URL_CONNECTION_getFileURL != null)
271 {
272 return (URL)BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null);
273 }
274 }
275 catch (Throwable t)
276 {
277 t.printStackTrace();
278 }
279 }
280 return url;
281 }
282
283 }