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