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