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;
20
21 import java.io.File;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.StringTokenizer;
28 import java.util.TreeMap;
29 import java.util.regex.Pattern;
30
31 import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
32 import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
33 import org.eclipse.jetty.util.log.Log;
34 import org.eclipse.jetty.util.log.Logger;
35 import org.eclipse.jetty.util.resource.Resource;
36 import org.eclipse.jetty.util.resource.ResourceCollection;
37 import org.eclipse.jetty.webapp.WebAppContext;
38 import org.eclipse.jetty.webapp.WebInfConfiguration;
39 import org.osgi.framework.Bundle;
40 import org.osgi.framework.FrameworkUtil;
41
42
43
44
45
46
47
48
49 public class OSGiWebInfConfiguration extends WebInfConfiguration
50 {
51 private static final Logger LOG = Log.getLogger(WebInfConfiguration.class);
52
53
54
55
56
57 public static final String SYS_PROP_TLD_BUNDLES = "org.eclipse.jetty.osgi.tldbundles";
58
59
60
61 public static final String CONTAINER_BUNDLE_PATTERN = "org.eclipse.jetty.server.webapp.containerIncludeBundlePattern";
62 public static final String FRAGMENT_AND_REQUIRED_BUNDLES = "org.eclipse.jetty.osgi.fragmentAndRequiredBundles";
63 public static final String FRAGMENT_AND_REQUIRED_RESOURCES = "org.eclipse.jetty.osgi.fragmentAndRequiredResources";
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 @Override
82 public void preConfigure(final WebAppContext context) throws Exception
83 {
84 super.preConfigure(context);
85
86
87
88
89
90
91 String tmp = (String)context.getAttribute(CONTAINER_BUNDLE_PATTERN);
92 Pattern pattern = (tmp==null?null:Pattern.compile(tmp));
93 List<String> names = new ArrayList<String>();
94 tmp = System.getProperty(SYS_PROP_TLD_BUNDLES);
95 if (tmp != null)
96 {
97 StringTokenizer tokenizer = new StringTokenizer(tmp, ", \n\r\t", false);
98 while (tokenizer.hasMoreTokens())
99 names.add(tokenizer.nextToken());
100 }
101 HashSet<Resource> matchingResources = new HashSet<Resource>();
102 if ( !names.isEmpty() || pattern != null)
103 {
104 Bundle[] bundles = FrameworkUtil.getBundle(OSGiWebInfConfiguration.class).getBundleContext().getBundles();
105
106 for (Bundle bundle : bundles)
107 {
108 LOG.debug("Checking bundle {}:{}", bundle.getBundleId(), bundle.getSymbolicName());
109 if (pattern != null)
110 {
111
112 if (pattern.matcher(bundle.getSymbolicName()).matches())
113 {
114
115 matchingResources.addAll(getBundleAsResource(bundle));
116 }
117 }
118 if (names != null)
119 {
120
121 if (names.contains(bundle.getSymbolicName()))
122 matchingResources.addAll(getBundleAsResource(bundle));
123 }
124 }
125 }
126 for (Resource r:matchingResources)
127 {
128 context.getMetaData().addContainerResource(r);
129 }
130 }
131
132 @Override
133 public void postConfigure(WebAppContext context) throws Exception
134 {
135 context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, null);
136 context.setAttribute(FRAGMENT_AND_REQUIRED_RESOURCES, null);
137 super.postConfigure(context);
138 }
139
140
141
142
143
144
145
146
147 @Override
148 protected List<Resource> findJars (WebAppContext context)
149 throws Exception
150 {
151 List<Resource> mergedResources = new ArrayList<Resource>();
152
153 List<Resource> webInfJars = super.findJars(context);
154 if (webInfJars != null)
155 mergedResources.addAll(webInfJars);
156
157
158 Bundle[] bundles = PackageAdminServiceTracker.INSTANCE.getFragmentsAndRequiredBundles((Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE));
159 if (bundles != null && bundles.length > 0)
160 {
161 Set<Bundle> fragsAndReqsBundles = (Set<Bundle>)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES);
162 if (fragsAndReqsBundles == null)
163 {
164 fragsAndReqsBundles = new HashSet<Bundle>();
165 context.setAttribute(FRAGMENT_AND_REQUIRED_BUNDLES, fragsAndReqsBundles);
166 }
167
168 Set<Resource> fragsAndReqsResources = (Set<Resource>)context.getAttribute(FRAGMENT_AND_REQUIRED_RESOURCES);
169 if (fragsAndReqsResources == null)
170 {
171 fragsAndReqsResources = new HashSet<Resource>();
172 context.setAttribute(FRAGMENT_AND_REQUIRED_RESOURCES, fragsAndReqsResources);
173 }
174
175 for (Bundle b : bundles)
176 {
177
178 fragsAndReqsBundles.add(b);
179 File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(b);
180 Resource r = Resource.newResource(f.toURI());
181
182 fragsAndReqsResources.add(r);
183 mergedResources.add(r);
184 }
185 }
186
187 return mergedResources;
188 }
189
190
191
192
193
194
195
196
197
198 @Override
199 public void configure(WebAppContext context) throws Exception
200 {
201 TreeMap<String, Resource> patchResourcesPath = new TreeMap<String, Resource>();
202 TreeMap<String, Resource> appendedResourcesPath = new TreeMap<String, Resource>();
203
204 Bundle bundle = (Bundle)context.getAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE);
205 if (bundle != null)
206 {
207 Set<Bundle> fragments = (Set<Bundle>)context.getAttribute(FRAGMENT_AND_REQUIRED_BUNDLES);
208 if (fragments != null && !fragments.isEmpty())
209 {
210
211
212
213
214
215
216
217
218
219
220
221
222
223 for (Bundle frag : fragments)
224 {
225 String fragFolder = (String) frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_FRAGMENT_FOLDER_PATH);
226 String patchFragFolder = (String) frag.getHeaders().get(OSGiWebappConstants.JETTY_WAR_PATCH_FRAGMENT_FOLDER_PATH);
227 if (fragFolder != null)
228 {
229 URL fragUrl = frag.getEntry(fragFolder);
230 if (fragUrl == null) { throw new IllegalArgumentException("Unable to locate " + fragFolder
231 + " inside "
232 + " the fragment '"
233 + frag.getSymbolicName()
234 + "'"); }
235 fragUrl = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(fragUrl);
236 String key = fragFolder.startsWith("/") ? fragFolder.substring(1) : fragFolder;
237 appendedResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(fragUrl));
238 }
239 if (patchFragFolder != null)
240 {
241 URL patchFragUrl = frag.getEntry(patchFragFolder);
242 if (patchFragUrl == null)
243 {
244 throw new IllegalArgumentException("Unable to locate " + patchFragUrl
245 + " inside fragment '"+frag.getSymbolicName()+ "'");
246 }
247 patchFragUrl = BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(patchFragUrl);
248 String key = patchFragFolder.startsWith("/") ? patchFragFolder.substring(1) : patchFragFolder;
249 patchResourcesPath.put(key + ";" + frag.getSymbolicName(), Resource.newResource(patchFragUrl));
250 }
251 }
252 if (!appendedResourcesPath.isEmpty())
253 context.setAttribute(WebInfConfiguration.RESOURCE_DIRS, new HashSet<Resource>(appendedResourcesPath.values()));
254 }
255 }
256
257 super.configure(context);
258
259
260 if (!patchResourcesPath.isEmpty())
261 {
262 Resource[] resources = new Resource[1+patchResourcesPath.size()];
263 ResourceCollection mergedResources = new ResourceCollection (patchResourcesPath.values().toArray(new Resource[patchResourcesPath.size()]));
264 System.arraycopy(patchResourcesPath.values().toArray(new Resource[patchResourcesPath.size()]), 0, resources, 0, patchResourcesPath.size());
265 resources[resources.length-1] = context.getBaseResource();
266 context.setBaseResource(new ResourceCollection(resources));
267 }
268 }
269
270
271
272
273
274
275
276 private List<Resource> getBundleAsResource(Bundle bundle)
277 throws Exception
278 {
279 List<Resource> resources = new ArrayList<Resource>();
280
281 File file = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle);
282 if (file.isDirectory())
283 {
284 for (File f : file.listFiles())
285 {
286 if (f.getName().endsWith(".jar") && f.isFile())
287 {
288 resources.add(Resource.newResource(f));
289 }
290 else if (f.isDirectory() && f.getName().equals("lib"))
291 {
292 for (File f2 : file.listFiles())
293 {
294 if (f2.getName().endsWith(".jar") && f2.isFile())
295 {
296 resources.add(Resource.newResource(f));
297 }
298 }
299 }
300 }
301 resources.add(Resource.newResource(file));
302 }
303 else
304 {
305 resources.add(Resource.newResource(file));
306 }
307
308 return resources;
309 }
310 }