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