1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.webapp;
20
21
22 import java.net.URI;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.concurrent.ConcurrentHashMap;
31
32 import org.eclipse.jetty.util.log.Log;
33 import org.eclipse.jetty.util.log.Logger;
34 import org.eclipse.jetty.util.resource.EmptyResource;
35 import org.eclipse.jetty.util.resource.Resource;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class MetaInfConfiguration extends AbstractConfiguration
54 {
55 private static final Logger LOG = Log.getLogger(MetaInfConfiguration.class);
56
57 public static final String USE_CONTAINER_METAINF_CACHE = "org.eclipse.jetty.metainf.useCache";
58 public static final boolean DEFAULT_USE_CONTAINER_METAINF_CACHE = true;
59 public static final String CACHED_CONTAINER_TLDS = "org.eclipse.jetty.tlds.cache";
60 public static final String CACHED_CONTAINER_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES+".cache";
61 public static final String CACHED_CONTAINER_RESOURCES = WebInfConfiguration.RESOURCE_DIRS+".cache";
62 public static final String METAINF_TLDS = "org.eclipse.jetty.tlds";
63 public static final String METAINF_FRAGMENTS = FragmentConfiguration.FRAGMENT_RESOURCES;
64 public static final String METAINF_RESOURCES = WebInfConfiguration.RESOURCE_DIRS;
65
66 @Override
67 public void preConfigure(final WebAppContext context) throws Exception
68 {
69 boolean useContainerCache = DEFAULT_USE_CONTAINER_METAINF_CACHE;
70 Boolean attr = (Boolean)context.getServer().getAttribute(USE_CONTAINER_METAINF_CACHE);
71 if (attr != null)
72 useContainerCache = attr.booleanValue();
73
74 if (LOG.isDebugEnabled()) LOG.debug("{} = {}", USE_CONTAINER_METAINF_CACHE, useContainerCache);
75 scanJars(context, context.getMetaData().getContainerResources(), useContainerCache);
76 scanJars(context, context.getMetaData().getWebInfJars(), false);
77 }
78
79
80
81
82
83
84
85
86
87
88
89 public void scanJars (final WebAppContext context, Collection<Resource> jars, boolean useCaches)
90 throws Exception
91 {
92 ConcurrentHashMap<Resource, Resource> metaInfResourceCache = null;
93 ConcurrentHashMap<Resource, Resource> metaInfFragmentCache = null;
94 ConcurrentHashMap<Resource, Collection<URL>> metaInfTldCache = null;
95 if (useCaches)
96 {
97 metaInfResourceCache = (ConcurrentHashMap<Resource, Resource>)context.getServer().getAttribute(CACHED_CONTAINER_RESOURCES);
98 if (metaInfResourceCache == null)
99 {
100 metaInfResourceCache = new ConcurrentHashMap<Resource,Resource>();
101 context.getServer().setAttribute(CACHED_CONTAINER_RESOURCES, metaInfResourceCache);
102 }
103 metaInfFragmentCache = (ConcurrentHashMap<Resource, Resource>)context.getServer().getAttribute(CACHED_CONTAINER_FRAGMENTS);
104 if (metaInfFragmentCache == null)
105 {
106 metaInfFragmentCache = new ConcurrentHashMap<Resource,Resource>();
107 context.getServer().setAttribute(CACHED_CONTAINER_FRAGMENTS, metaInfFragmentCache);
108 }
109 metaInfTldCache = (ConcurrentHashMap<Resource, Collection<URL>>)context.getServer().getAttribute(CACHED_CONTAINER_TLDS);
110 if (metaInfTldCache == null)
111 {
112 metaInfTldCache = new ConcurrentHashMap<Resource,Collection<URL>>();
113 context.getServer().setAttribute(CACHED_CONTAINER_TLDS, metaInfTldCache);
114 }
115 }
116
117
118 if (jars != null)
119 {
120 for (Resource r : jars)
121 {
122
123 scanForResources(context, r, metaInfResourceCache);
124 scanForFragment(context, r, metaInfFragmentCache);
125 scanForTlds(context, r, metaInfTldCache);
126 }
127 }
128 }
129
130
131
132
133
134
135
136
137
138 public void scanForResources (WebAppContext context, Resource jar, ConcurrentHashMap<Resource,Resource> cache)
139 throws Exception
140 {
141 Resource resourcesDir = null;
142 if (cache != null && cache.containsKey(jar))
143 {
144 resourcesDir = cache.get(jar);
145 if (resourcesDir == EmptyResource.INSTANCE)
146 {
147 if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no META-INF/resources");
148 return;
149 }
150 else
151 if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/resources found in cache ");
152 }
153 else
154 {
155
156 if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/resources checked");
157 URI uri = jar.getURI();
158 resourcesDir = Resource.newResource("jar:"+uri+"!/META-INF/resources");
159 if (!resourcesDir.exists() || !resourcesDir.isDirectory())
160 resourcesDir = EmptyResource.INSTANCE;
161
162 if (cache != null)
163 {
164 Resource old = cache.putIfAbsent(jar, resourcesDir);
165 if (old != null)
166 resourcesDir = old;
167 else
168 if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/resources cache updated");
169 }
170
171 if (resourcesDir == EmptyResource.INSTANCE)
172 return;
173 }
174
175
176 Set<Resource> dirs = (Set<Resource>)context.getAttribute(METAINF_RESOURCES);
177 if (dirs == null)
178 {
179 dirs = new HashSet<Resource>();
180 context.setAttribute(METAINF_RESOURCES, dirs);
181 }
182 if (LOG.isDebugEnabled()) LOG.debug(resourcesDir+" added to context");
183 dirs.add(resourcesDir);
184 }
185
186
187
188
189
190
191
192
193
194 public void scanForFragment (WebAppContext context, Resource jar, ConcurrentHashMap<Resource,Resource> cache)
195 throws Exception
196 {
197 Resource webFrag = null;
198 if (cache != null && cache.containsKey(jar))
199 {
200 webFrag = cache.get(jar);
201 if (webFrag == EmptyResource.INSTANCE)
202 {
203 if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no META-INF/web-fragment.xml");
204 return;
205 }
206 else
207 if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml found in cache ");
208 }
209 else
210 {
211
212 if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml checked");
213 URI uri = jar.getURI();
214 webFrag = Resource.newResource("jar:"+uri+"!/META-INF/web-fragment.xml");
215 if (!webFrag.exists() || webFrag.isDirectory())
216 webFrag = EmptyResource.INSTANCE;
217
218 if (cache != null)
219 {
220
221 Resource old = cache.putIfAbsent(jar, webFrag);
222 if (old != null)
223 webFrag = old;
224 else
225 if (LOG.isDebugEnabled()) LOG.debug(jar+" META-INF/web-fragment.xml cache updated");
226 }
227
228 if (webFrag == EmptyResource.INSTANCE)
229 return;
230 }
231
232 Map<Resource, Resource> fragments = (Map<Resource,Resource>)context.getAttribute(METAINF_FRAGMENTS);
233 if (fragments == null)
234 {
235 fragments = new HashMap<Resource, Resource>();
236 context.setAttribute(METAINF_FRAGMENTS, fragments);
237 }
238 fragments.put(jar, webFrag);
239 if (LOG.isDebugEnabled()) LOG.debug(webFrag+" added to context");
240 }
241
242
243
244
245
246
247
248
249
250
251 public void scanForTlds (WebAppContext context, Resource jar, ConcurrentHashMap<Resource, Collection<URL>> cache)
252 throws Exception
253 {
254 Collection<URL> tlds = null;
255
256 if (cache != null && cache.containsKey(jar))
257 {
258 Collection<URL> tmp = cache.get(jar);
259 if (tmp.isEmpty())
260 {
261 if (LOG.isDebugEnabled()) LOG.debug(jar+" cached as containing no tlds");
262 return;
263 }
264 else
265 {
266 tlds = tmp;
267 if (LOG.isDebugEnabled()) LOG.debug(jar+" tlds found in cache ");
268 }
269 }
270 else
271 {
272
273 URI uri = jar.getURI();
274 Resource metaInfDir = Resource.newResource("jar:"+uri+"!/META-INF/");
275
276
277 tlds = new HashSet<URL>();
278 Collection<Resource> resources = metaInfDir.getAllResources();
279 for (Resource t:resources)
280 {
281 String name = t.toString();
282 if (name.endsWith(".tld"))
283 {
284 if (LOG.isDebugEnabled()) LOG.debug(t+" tld discovered");
285 tlds.add(t.getURL());
286 }
287 }
288 if (cache != null)
289 {
290 if (LOG.isDebugEnabled()) LOG.debug(jar+" tld cache updated");
291 Collection<URL> old = (Collection<URL>)cache.putIfAbsent(jar, tlds);
292 if (old != null)
293 tlds = old;
294 }
295
296 if (tlds.isEmpty())
297 return;
298 }
299
300 Collection<URL> tld_resources=(Collection<URL>)context.getAttribute(METAINF_TLDS);
301 if (tld_resources == null)
302 {
303 tld_resources = new HashSet<URL>();
304 context.setAttribute(METAINF_TLDS, tld_resources);
305 }
306 tld_resources.addAll(tlds);
307 if (LOG.isDebugEnabled()) LOG.debug("tlds added to context");
308 }
309
310
311 @Override
312 public void postConfigure(WebAppContext context) throws Exception
313 {
314 context.setAttribute(METAINF_FRAGMENTS, null);
315 context.setAttribute(METAINF_RESOURCES, null);
316 context.setAttribute(METAINF_TLDS, null);
317 }
318 }