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 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import javax.servlet.ServletContext;
27
28 import org.eclipse.jetty.util.log.Log;
29 import org.eclipse.jetty.util.log.Logger;
30 import org.eclipse.jetty.util.resource.Resource;
31
32
33
34
35
36
37
38
39
40 public class MetaData
41 {
42 private static final Logger LOG = Log.getLogger(MetaData.class);
43
44 public static final String ORDERED_LIBS = "javax.servlet.context.orderedLibs";
45
46 protected Map<String, OriginInfo> _origins =new HashMap<String,OriginInfo>();
47 protected WebDescriptor _webDefaultsRoot;
48 protected WebDescriptor _webXmlRoot;
49 protected final List<WebDescriptor> _webOverrideRoots=new ArrayList<WebDescriptor>();
50 protected boolean _metaDataComplete;
51 protected final List<DiscoveredAnnotation> _annotations = new ArrayList<DiscoveredAnnotation>();
52 protected final List<DescriptorProcessor> _descriptorProcessors = new ArrayList<DescriptorProcessor>();
53 protected final List<FragmentDescriptor> _webFragmentRoots = new ArrayList<FragmentDescriptor>();
54 protected final Map<String,FragmentDescriptor> _webFragmentNameMap = new HashMap<String,FragmentDescriptor>();
55 protected final Map<Resource, FragmentDescriptor> _webFragmentResourceMap = new HashMap<Resource, FragmentDescriptor>();
56 protected final Map<Resource, List<DiscoveredAnnotation>> _webFragmentAnnotations = new HashMap<Resource, List<DiscoveredAnnotation>>();
57 protected final List<Resource> _webInfJars = new ArrayList<Resource>();
58 protected final List<Resource> _orderedWebInfJars = new ArrayList<Resource>();
59 protected final List<Resource> _orderedContainerJars = new ArrayList<Resource>();
60 protected Ordering _ordering;
61 protected boolean allowDuplicateFragmentNames = false;
62
63
64
65
66
67 public static class OriginInfo
68 {
69 protected String name;
70 protected Origin origin;
71 protected Descriptor descriptor;
72
73 public OriginInfo (String n, Descriptor d)
74 {
75 name = n;
76 descriptor = d;
77 if (d == null)
78 throw new IllegalArgumentException("No descriptor");
79 if (d instanceof FragmentDescriptor)
80 origin = Origin.WebFragment;
81 else if (d instanceof OverrideDescriptor)
82 origin = Origin.WebOverride;
83 else if (d instanceof DefaultsDescriptor)
84 origin = Origin.WebDefaults;
85 else
86 origin = Origin.WebXml;
87 }
88
89 public OriginInfo (String n)
90 {
91 name = n;
92 origin = Origin.Annotation;
93 }
94
95 public OriginInfo(String n, Origin o)
96 {
97 name = n;
98 origin = o;
99 }
100
101 public String getName()
102 {
103 return name;
104 }
105
106 public Origin getOriginType()
107 {
108 return origin;
109 }
110
111 public Descriptor getDescriptor()
112 {
113 return descriptor;
114 }
115 }
116
117 public MetaData ()
118 {
119 }
120
121
122
123
124 public void clear ()
125 {
126 _webDefaultsRoot = null;
127 _origins.clear();
128 _webXmlRoot = null;
129 _webOverrideRoots.clear();
130 _metaDataComplete = false;
131 _annotations.clear();
132 _descriptorProcessors.clear();
133 _webFragmentRoots.clear();
134 _webFragmentNameMap.clear();
135 _webFragmentResourceMap.clear();
136 _webFragmentAnnotations.clear();
137 _webInfJars.clear();
138 _orderedWebInfJars.clear();
139 _orderedContainerJars.clear();
140 _ordering = null;
141 allowDuplicateFragmentNames = false;
142 }
143
144 public void setDefaults (Resource webDefaults)
145 throws Exception
146 {
147 _webDefaultsRoot = new DefaultsDescriptor(webDefaults);
148 _webDefaultsRoot.parse();
149 if (_webDefaultsRoot.isOrdered())
150 {
151 if (_ordering == null)
152 _ordering = new Ordering.AbsoluteOrdering(this);
153
154 List<String> order = _webDefaultsRoot.getOrdering();
155 for (String s:order)
156 {
157 if (s.equalsIgnoreCase("others"))
158 ((Ordering.AbsoluteOrdering)_ordering).addOthers();
159 else
160 ((Ordering.AbsoluteOrdering)_ordering).add(s);
161 }
162 }
163 }
164
165 public void setWebXml (Resource webXml)
166 throws Exception
167 {
168 _webXmlRoot = new WebDescriptor(webXml);
169 _webXmlRoot.parse();
170 _metaDataComplete=_webXmlRoot.getMetaDataComplete() == MetaDataComplete.True;
171
172
173
174 if (_webXmlRoot.isOrdered())
175 {
176 if (_ordering == null)
177 _ordering = new Ordering.AbsoluteOrdering(this);
178
179 List<String> order = _webXmlRoot.getOrdering();
180 for (String s:order)
181 {
182 if (s.equalsIgnoreCase("others"))
183 ((Ordering.AbsoluteOrdering)_ordering).addOthers();
184 else
185 ((Ordering.AbsoluteOrdering)_ordering).add(s);
186 }
187 }
188 }
189
190 public void addOverride (Resource override)
191 throws Exception
192 {
193 OverrideDescriptor webOverrideRoot = new OverrideDescriptor(override);
194 webOverrideRoot.setValidating(false);
195 webOverrideRoot.parse();
196
197 switch(webOverrideRoot.getMetaDataComplete())
198 {
199 case True:
200 _metaDataComplete=true;
201 break;
202 case False:
203 _metaDataComplete=true;
204 break;
205 case NotSet:
206 break;
207 }
208
209 if (webOverrideRoot.isOrdered())
210 {
211 if (_ordering == null)
212 _ordering = new Ordering.AbsoluteOrdering(this);
213
214 List<String> order = webOverrideRoot.getOrdering();
215 for (String s:order)
216 {
217 if (s.equalsIgnoreCase("others"))
218 ((Ordering.AbsoluteOrdering)_ordering).addOthers();
219 else
220 ((Ordering.AbsoluteOrdering)_ordering).add(s);
221 }
222 }
223 _webOverrideRoots.add(webOverrideRoot);
224 }
225
226
227
228
229
230
231
232
233
234 public void addFragment (Resource jarResource, Resource xmlResource)
235 throws Exception
236 {
237 if (_metaDataComplete)
238 return;
239
240
241 FragmentDescriptor descriptor = new FragmentDescriptor(xmlResource);
242 _webFragmentResourceMap.put(jarResource, descriptor);
243 _webFragmentRoots.add(descriptor);
244
245 descriptor.parse();
246
247 if (descriptor.getName() != null)
248 {
249 Descriptor existing = _webFragmentNameMap.get(descriptor.getName());
250 if (existing != null && !isAllowDuplicateFragmentNames())
251 {
252 throw new IllegalStateException("Duplicate fragment name: "+descriptor.getName()+" for "+existing.getResource()+" and "+descriptor.getResource());
253 }
254 else
255 _webFragmentNameMap.put(descriptor.getName(), descriptor);
256 }
257
258
259 if (_ordering != null && _ordering.isAbsolute())
260 return;
261
262 if (_ordering == null && descriptor.isOrdered())
263 _ordering = new Ordering.RelativeOrdering(this);
264 }
265
266
267
268
269
270
271 public void addDiscoveredAnnotations(List<DiscoveredAnnotation> annotations)
272 {
273 _annotations.addAll(annotations);
274 }
275
276 public void addDiscoveredAnnotations(Resource resource, List<DiscoveredAnnotation> annotations)
277 {
278 _webFragmentAnnotations.put(resource, new ArrayList<DiscoveredAnnotation>(annotations));
279 }
280
281 public void addDescriptorProcessor(DescriptorProcessor p)
282 {
283 _descriptorProcessors.add(p);
284 }
285
286 public void orderFragments ()
287 {
288
289 if (_orderedWebInfJars.size()==_webInfJars.size())
290 return;
291
292 if (_ordering != null)
293 _orderedWebInfJars.addAll(_ordering.order(_webInfJars));
294 else
295 _orderedWebInfJars.addAll(_webInfJars);
296 }
297
298
299
300
301
302
303 public void resolve (WebAppContext context)
304 throws Exception
305 {
306 LOG.debug("metadata resolve {}",context);
307
308
309 _origins.clear();
310
311
312 if (_ordering != null)
313 {
314 List<String> orderedLibs = new ArrayList<String>();
315 for (Resource webInfJar:_orderedWebInfJars)
316 {
317
318 String fullname = webInfJar.getName();
319 int i = fullname.indexOf(".jar");
320 int j = fullname.lastIndexOf("/", i);
321 orderedLibs.add(fullname.substring(j+1,i+4));
322 }
323 context.setAttribute(ServletContext.ORDERED_LIBS, orderedLibs);
324 }
325
326
327 if (_webXmlRoot != null)
328 {
329 context.getServletContext().setEffectiveMajorVersion(_webXmlRoot.getMajorVersion());
330 context.getServletContext().setEffectiveMinorVersion(_webXmlRoot.getMinorVersion());
331 }
332
333 for (DescriptorProcessor p:_descriptorProcessors)
334 {
335 p.process(context,getWebDefault());
336 p.process(context,getWebXml());
337 for (WebDescriptor wd : getOverrideWebs())
338 {
339 LOG.debug("process {} {}",context,wd);
340 p.process(context,wd);
341 }
342 }
343
344 for (DiscoveredAnnotation a:_annotations)
345 {
346 LOG.debug("apply {}",a);
347 a.apply();
348 }
349
350
351 List<Resource> resources = getOrderedWebInfJars();
352 for (Resource r:resources)
353 {
354 FragmentDescriptor fd = _webFragmentResourceMap.get(r);
355 if (fd != null)
356 {
357 for (DescriptorProcessor p:_descriptorProcessors)
358 {
359 LOG.debug("process {} {}",context,fd);
360 p.process(context,fd);
361 }
362 }
363
364 List<DiscoveredAnnotation> fragAnnotations = _webFragmentAnnotations.get(r);
365 if (fragAnnotations != null)
366 {
367 for (DiscoveredAnnotation a:fragAnnotations)
368 {
369 LOG.debug("apply {}",a);
370 a.apply();
371 }
372 }
373 }
374
375 }
376
377 public boolean isDistributable ()
378 {
379 boolean distributable = (
380 (_webDefaultsRoot != null && _webDefaultsRoot.isDistributable())
381 || (_webXmlRoot != null && _webXmlRoot.isDistributable()));
382
383 for (WebDescriptor d : _webOverrideRoots)
384 distributable&=d.isDistributable();
385
386 List<Resource> orderedResources = getOrderedWebInfJars();
387 for (Resource r: orderedResources)
388 {
389 FragmentDescriptor d = _webFragmentResourceMap.get(r);
390 if (d!=null)
391 distributable = distributable && d.isDistributable();
392 }
393 return distributable;
394 }
395
396
397 public WebDescriptor getWebXml ()
398 {
399 return _webXmlRoot;
400 }
401
402 public List<WebDescriptor> getOverrideWebs ()
403 {
404 return _webOverrideRoots;
405 }
406
407 public WebDescriptor getWebDefault ()
408 {
409 return _webDefaultsRoot;
410 }
411
412 public List<FragmentDescriptor> getFragments ()
413 {
414 return _webFragmentRoots;
415 }
416
417 public List<Resource> getOrderedWebInfJars()
418 {
419 return _orderedWebInfJars == null? new ArrayList<Resource>(): _orderedWebInfJars;
420 }
421
422 public List<FragmentDescriptor> getOrderedFragments ()
423 {
424 List<FragmentDescriptor> list = new ArrayList<FragmentDescriptor>();
425 if (_orderedWebInfJars == null)
426 return list;
427
428 for (Resource r:_orderedWebInfJars)
429 {
430 FragmentDescriptor fd = _webFragmentResourceMap.get(r);
431 if (fd != null)
432 list.add(fd);
433 }
434 return list;
435 }
436
437 public Ordering getOrdering()
438 {
439 return _ordering;
440 }
441
442 public void setOrdering (Ordering o)
443 {
444 _ordering = o;
445 }
446
447 public FragmentDescriptor getFragment (Resource jar)
448 {
449 return _webFragmentResourceMap.get(jar);
450 }
451
452 public FragmentDescriptor getFragment(String name)
453 {
454 return _webFragmentNameMap.get(name);
455 }
456
457 public Resource getJarForFragment (String name)
458 {
459 FragmentDescriptor f = getFragment(name);
460 if (f == null)
461 return null;
462
463 Resource jar = null;
464 for (Resource r: _webFragmentResourceMap.keySet())
465 {
466 if (_webFragmentResourceMap.get(r).equals(f))
467 jar = r;
468 }
469 return jar;
470 }
471
472 public Map<String,FragmentDescriptor> getNamedFragments ()
473 {
474 return Collections.unmodifiableMap(_webFragmentNameMap);
475 }
476
477
478 public Origin getOrigin (String name)
479 {
480 OriginInfo x = _origins.get(name);
481 if (x == null)
482 return Origin.NotSet;
483
484 return x.getOriginType();
485 }
486
487
488 public Descriptor getOriginDescriptor (String name)
489 {
490 OriginInfo o = _origins.get(name);
491 if (o == null)
492 return null;
493 return o.getDescriptor();
494 }
495
496 public void setOrigin (String name, Descriptor d)
497 {
498 OriginInfo x = new OriginInfo (name, d);
499 _origins.put(name, x);
500 }
501
502 public void setOrigin (String name)
503 {
504 if (name == null)
505 return;
506
507 OriginInfo x = new OriginInfo (name, Origin.Annotation);
508 _origins.put(name, x);
509 }
510
511 public boolean isMetaDataComplete()
512 {
513 return _metaDataComplete;
514 }
515
516
517 public void addWebInfJar(Resource newResource)
518 {
519 _webInfJars.add(newResource);
520 }
521
522 public List<Resource> getWebInfJars()
523 {
524 return Collections.unmodifiableList(_webInfJars);
525 }
526
527 public List<Resource> getOrderedContainerJars()
528 {
529 return _orderedContainerJars;
530 }
531
532 public void addContainerJar(Resource jar)
533 {
534 _orderedContainerJars.add(jar);
535 }
536 public boolean isAllowDuplicateFragmentNames()
537 {
538 return allowDuplicateFragmentNames;
539 }
540
541 public void setAllowDuplicateFragmentNames(boolean allowDuplicateFragmentNames)
542 {
543 this.allowDuplicateFragmentNames = allowDuplicateFragmentNames;
544 }
545 }