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