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