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