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