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.warurl.internal;
20
21 import java.net.URL;
22 import java.util.ArrayList;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map.Entry;
27 import java.util.jar.Attributes;
28 import java.util.jar.JarEntry;
29 import java.util.jar.JarFile;
30 import java.util.jar.Manifest;
31
32 import org.eclipse.jetty.util.MultiMap;
33 import org.eclipse.jetty.util.UrlEncoded;
34 import org.osgi.framework.Constants;
35
36 public class WarBundleManifestGenerator
37 {
38
39
40 private static final String MISSING_VERSION = "0.0.1.unknown";
41 private static final String MISSING_MANIFEST_VERSION = "2";
42
43 public static Manifest createBundleManifest(Manifest originalManifest, URL url, JarFile jarFile)
44 {
45 Manifest res = new Manifest();
46 res.getMainAttributes().putAll(
47 createBundleManifest(originalManifest.getMainAttributes(),
48 url.toString(), jarFile));
49 return res;
50 }
51
52
53 private static Attributes createBundleManifest(Attributes originalManifest, String url, JarFile jarFile)
54 {
55 HashMap<String, String> res = new HashMap<String, String>();
56 for (Entry<Object, Object> entries : originalManifest.entrySet())
57 {
58 res.put(entries.getKey().toString(),String.valueOf(entries.getValue()));
59 }
60 MultiMap<String> params = parseQueryString(url);
61
62
63 String version = params.getString(Constants.BUNDLE_VERSION);
64 if (version != null)
65 {
66 res.put(Constants.BUNDLE_VERSION, version);
67 }
68 else
69 {
70 String versionInManifest = (String) res.get(Constants.BUNDLE_VERSION);
71 if (versionInManifest == null)
72 {
73 res.put(Constants.BUNDLE_VERSION, MISSING_VERSION);
74 }
75 }
76
77
78 String manversion = params.getString(Constants.BUNDLE_MANIFESTVERSION);
79 if (manversion != null)
80 {
81 res.put(Constants.BUNDLE_MANIFESTVERSION, manversion);
82 }
83 else
84 {
85 int manv = 2;
86 try {
87 String versionInManifest = (String) res.get(Constants.BUNDLE_MANIFESTVERSION);
88 if (versionInManifest != null)
89 {
90 manv = Integer.parseInt(versionInManifest.trim());
91 }
92 }
93 catch (NumberFormatException nfe)
94 {
95
96 }
97 res.put(Constants.BUNDLE_MANIFESTVERSION, String.valueOf( manv < 2 ? 2 : manv ));
98 }
99
100
101 String symbname = params.getString(Constants.BUNDLE_SYMBOLICNAME);
102 if (symbname != null)
103 {
104 res.put(Constants.BUNDLE_SYMBOLICNAME, symbname);
105 }
106 else
107 {
108 symbname = (String) res.get(Constants.BUNDLE_SYMBOLICNAME);
109 if (symbname == null)
110 {
111
112 int lastSlash = url.lastIndexOf('/');
113 int beforeQueryString = url.indexOf(lastSlash, '?');
114 if (beforeQueryString == -1)
115 {
116 beforeQueryString = url.indexOf(lastSlash, '#');
117 if (beforeQueryString == -1)
118 {
119 beforeQueryString = url.length();
120 }
121 }
122 symbname = url.substring(lastSlash+1, beforeQueryString);
123
124 res.put(Constants.BUNDLE_SYMBOLICNAME, symbname);
125 }
126 }
127
128
129 String extraBundleClasspath = params.getString(Constants.BUNDLE_CLASSPATH);
130 String alreadyBundleClasspath = res.get(Constants.BUNDLE_CLASSPATH);
131 if (alreadyBundleClasspath == null)
132 {
133 StringBuilder bundleClasspath = new StringBuilder();
134 if (jarFile == null || jarFile.getJarEntry("WEB-INF/classes/") != null)
135 {
136 bundleClasspath.append("WEB-INF/classes");
137 }
138 if (jarFile != null)
139 {
140 List<String> libs = getJarsInWebInfLib(jarFile);
141 if (extraBundleClasspath != null)
142 {
143 libs.add(extraBundleClasspath);
144 }
145 for (String lib : libs)
146 {
147 if (bundleClasspath.length() != 0)
148 {
149 bundleClasspath.append(",");
150 }
151 bundleClasspath.append(lib);
152 }
153 }
154 alreadyBundleClasspath = bundleClasspath.toString();
155 }
156
157
158
159
160
161
162 res.put(Constants.BUNDLE_CLASSPATH,
163 alreadyBundleClasspath + (extraBundleClasspath == null ? "" : "," + extraBundleClasspath ));
164
165
166 String extraImportPackage = params.getString(Constants.IMPORT_PACKAGE);
167 String alreadyImportPackage = res.get(Constants.IMPORT_PACKAGE);
168 if (alreadyImportPackage == null)
169 {
170
171
172 alreadyImportPackage = "javax.servlet; version=\"2.5\"," +
173 "javax.servlet.http;version=\"2.5\"," +
174 "javax.el;version=\"1.0\"" +
175 "javax.jsp;version=\"2.1\";resolution:=optional," +
176 "javax.jsp.tagext;version=\"2.1\";resolution:=optional";
177
178 }
179 if (extraImportPackage != null)
180 {
181
182
183
184
185 res.put(Constants.IMPORT_PACKAGE,
186 (alreadyImportPackage == null ? "" : alreadyImportPackage + ",") +
187 extraImportPackage);
188 }
189
190
191 String extraExportPackage = params.getString(Constants.EXPORT_PACKAGE);
192 String alreadyExportPackage = res.get(Constants.EXPORT_PACKAGE);
193 if (extraExportPackage != null)
194 {
195
196
197
198 res.put(Constants.EXPORT_PACKAGE,
199 (alreadyExportPackage == null ? "" : alreadyExportPackage + ",") +
200 extraImportPackage);
201 }
202
203
204 String webContextPath = params.getString("Web-ContextPath");
205 if (webContextPath != null)
206 {
207 res.put("Web-ContextPath", webContextPath);
208 }
209 else
210 {
211 webContextPath = res.get("Web-ContextPath");
212 if (webContextPath == null)
213 {
214
215 if (symbname.endsWith(".war"))
216 {
217 webContextPath = "/" + symbname.substring(0, symbname.length()-".war".length());
218 }
219 else
220 {
221 webContextPath = "/" + symbname;
222 }
223 res.put("Web-ContextPath", webContextPath);
224 }
225 }
226
227
228 String jspExtractLocation = params.getString("Web-JSPExtractLocation");
229 if (jspExtractLocation != null)
230 {
231 res.put("Web-JSPExtractLocation", jspExtractLocation);
232 }
233 else
234 {
235
236 }
237 Attributes newAttrs = new Attributes();
238 for (Entry<String,String> e : res.entrySet())
239 {
240 newAttrs.putValue(e.getKey(),e.getValue());
241 }
242 return newAttrs;
243 }
244
245
246
247
248
249 private static MultiMap<String> parseQueryString(String url)
250 {
251 MultiMap<String> res = new MultiMap<String>();
252 int questionMarkIndex = url.indexOf('?');
253 if (questionMarkIndex == -1)
254 {
255 return res;
256 }
257 int poundIndex = url.indexOf('#');
258 if (poundIndex == -1)
259 {
260 poundIndex = url.length();
261 }
262 UrlEncoded.decodeUtf8To(url, questionMarkIndex+1,
263 poundIndex - questionMarkIndex - 1, res);
264 return res;
265 }
266
267 private static List<String> getJarsInWebInfLib(JarFile jarFile)
268 {
269 List<String> res = new ArrayList<String>();
270 Enumeration<JarEntry> en = jarFile.entries();
271 while (en.hasMoreElements())
272 {
273 JarEntry e = en.nextElement();
274 if (e.getName().startsWith("WEB-INF/lib/") && e.getName().endsWith(".jar"))
275 {
276 res.add(e.getName());
277 }
278 }
279 return res;
280 }
281
282
283 }