1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.annotations;
20
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URI;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.ServiceLoader;
33 import java.util.Set;
34 import java.util.concurrent.Callable;
35 import java.util.concurrent.ConcurrentHashMap;
36 import java.util.concurrent.CountDownLatch;
37 import java.util.concurrent.Semaphore;
38 import java.util.concurrent.TimeUnit;
39
40 import javax.servlet.ServletContainerInitializer;
41 import javax.servlet.annotation.HandlesTypes;
42
43 import org.eclipse.jetty.annotations.AnnotationParser.Handler;
44 import org.eclipse.jetty.plus.annotation.ContainerInitializer;
45 import org.eclipse.jetty.util.ConcurrentHashSet;
46 import org.eclipse.jetty.util.MultiException;
47 import org.eclipse.jetty.util.log.Log;
48 import org.eclipse.jetty.util.log.Logger;
49 import org.eclipse.jetty.util.resource.Resource;
50 import org.eclipse.jetty.util.statistic.CounterStatistic;
51 import org.eclipse.jetty.webapp.AbstractConfiguration;
52 import org.eclipse.jetty.webapp.FragmentDescriptor;
53 import org.eclipse.jetty.webapp.MetaDataComplete;
54 import org.eclipse.jetty.webapp.WebAppContext;
55 import org.eclipse.jetty.webapp.WebDescriptor;
56
57
58
59
60
61
62 public class AnnotationConfiguration extends AbstractConfiguration
63 {
64 private static final Logger LOG = Log.getLogger(AnnotationConfiguration.class);
65
66 public static final String SERVLET_CONTAINER_INITIALIZER_ORDER = "org.eclipse.jetty.containerInitializerOrder";
67 public static final String CLASS_INHERITANCE_MAP = "org.eclipse.jetty.classInheritanceMap";
68 public static final String CONTAINER_INITIALIZERS = "org.eclipse.jetty.containerInitializers";
69 public static final String CONTAINER_INITIALIZER_STARTER = "org.eclipse.jetty.containerInitializerStarter";
70 public static final String MULTI_THREADED = "org.eclipse.jetty.annotations.multiThreaded";
71 public static final String MAX_SCAN_WAIT = "org.eclipse.jetty.annotations.maxWait";
72
73 public static final int DEFAULT_MAX_SCAN_WAIT = 60;
74 public static final boolean DEFAULT_MULTI_THREADED = true;
75
76 protected List<AbstractDiscoverableAnnotationHandler> _discoverableAnnotationHandlers = new ArrayList<AbstractDiscoverableAnnotationHandler>();
77 protected ClassInheritanceHandler _classInheritanceHandler;
78 protected List<ContainerInitializerAnnotationHandler> _containerInitializerAnnotationHandlers = new ArrayList<ContainerInitializerAnnotationHandler>();
79
80 protected List<ParserTask> _parserTasks;
81 protected WebAppClassNameResolver _webAppClassNameResolver;
82 protected ContainerClassNameResolver _containerClassNameResolver;
83
84 protected CounterStatistic _containerPathStats;
85 protected CounterStatistic _webInfLibStats;
86 protected CounterStatistic _webInfClassesStats;
87
88
89
90
91
92
93
94 public class TimeStatistic
95 {
96 public long _start = 0;
97 public long _end = 0;
98
99 public void start ()
100 {
101 _start = System.nanoTime();
102 }
103
104 public void end ()
105 {
106 _end = System.nanoTime();
107 }
108
109 public long getStart()
110 {
111 return _start;
112 }
113
114 public long getEnd ()
115 {
116 return _end;
117 }
118
119 public long getElapsed ()
120 {
121 return (_end > _start?(_end-_start):0);
122 }
123 }
124
125
126
127
128
129
130
131
132 public class ParserTask implements Callable<Void>
133 {
134 protected Exception _exception;
135 protected final AnnotationParser _parser;
136 protected final Set<? extends Handler> _handlers;
137 protected final ClassNameResolver _resolver;
138 protected final Resource _resource;
139 protected TimeStatistic _stat;
140
141 public ParserTask (AnnotationParser parser, Set<? extends Handler>handlers, Resource resource, ClassNameResolver resolver)
142 {
143 _parser = parser;
144 _handlers = handlers;
145 _resolver = resolver;
146 _resource = resource;
147 }
148
149 public void setStatistic(TimeStatistic stat)
150 {
151 _stat = stat;
152 }
153
154 public Void call() throws Exception
155 {
156 if (_stat != null)
157 _stat.start();
158 if (_parser != null)
159 _parser.parse(_handlers, _resource, _resolver);
160 if (_stat != null)
161 _stat.end();
162 return null;
163 }
164
165 public TimeStatistic getStatistic()
166 {
167 return _stat;
168 }
169
170 public Resource getResource()
171 {
172 return _resource;
173 }
174
175 }
176
177
178
179
180
181
182
183
184
185
186
187
188
189 public class WebAppClassNameResolver implements ClassNameResolver
190 {
191 private WebAppContext _context;
192
193 public WebAppClassNameResolver (WebAppContext context)
194 {
195 _context = context;
196 }
197
198 public boolean isExcluded (String name)
199 {
200 if (_context.isSystemClass(name)) return true;
201 if (_context.isServerClass(name)) return false;
202 return false;
203 }
204
205 public boolean shouldOverride (String name)
206 {
207
208
209 if (_context.isParentLoaderPriority())
210 return false;
211 return true;
212 }
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 public class ContainerClassNameResolver implements ClassNameResolver
229 {
230 private WebAppContext _context;
231
232 public ContainerClassNameResolver (WebAppContext context)
233 {
234 _context = context;
235 }
236 public boolean isExcluded (String name)
237 {
238 if (_context.isSystemClass(name)) return false;
239 if (_context.isServerClass(name)) return true;
240 return false;
241 }
242
243 public boolean shouldOverride (String name)
244 {
245
246 if (_context.isParentLoaderPriority())
247 return true;
248 return false;
249 }
250 }
251
252
253
254
255
256
257
258
259
260
261 public class ServletContainerInitializerOrdering
262 {
263 private Map<String, Integer> _indexMap = new HashMap<String, Integer>();
264 private Integer _star = null;
265 private String _ordering = null;
266
267 public ServletContainerInitializerOrdering (String ordering)
268 {
269 if (ordering != null)
270 {
271 _ordering = ordering;
272
273 String[] tmp = ordering.split(",");
274
275 for (int i=0; i<tmp.length; i++)
276 {
277 String s = tmp[i].trim();
278 _indexMap.put(s, Integer.valueOf(i));
279 if ("*".equals(s))
280 {
281 if (_star != null)
282 throw new IllegalArgumentException("Duplicate wildcards in ServletContainerInitializer ordering "+ordering);
283 _star = Integer.valueOf(i);
284 }
285
286 }
287 }
288 }
289
290
291
292
293
294 public boolean hasWildcard()
295 {
296 return _star != null;
297 }
298
299
300
301
302
303 public int getWildcardIndex()
304 {
305 if (!hasWildcard())
306 return -1;
307 return _star.intValue();
308 }
309
310
311
312
313
314 public boolean isDefaultOrder ()
315 {
316 return (getSize() == 1 && hasWildcard());
317 }
318
319
320
321
322
323
324 public int getIndexOf (String name)
325 {
326 Integer i = _indexMap.get(name);
327 if (i == null)
328 return -1;
329 return i.intValue();
330 }
331
332
333
334
335
336 public int getSize()
337 {
338 return _indexMap.size();
339 }
340
341 public String toString()
342 {
343 if (_ordering == null)
344 return "";
345 return _ordering;
346 }
347 }
348
349
350
351
352
353
354
355
356
357
358
359 public class ServletContainerInitializerComparator implements Comparator<ServletContainerInitializer>
360 {
361 private ServletContainerInitializerOrdering _ordering;
362
363
364 public ServletContainerInitializerComparator (ServletContainerInitializerOrdering ordering)
365 {
366 _ordering = ordering;
367 }
368
369 @Override
370 public int compare(ServletContainerInitializer sci1, ServletContainerInitializer sci2)
371 {
372 String c1 = (sci1 != null? sci1.getClass().getName() : null);
373 String c2 = (sci2 != null? sci2.getClass().getName() : null);
374
375 if (c1 == null && c2 == null)
376 return 0;
377
378 int i1 = _ordering.getIndexOf(c1);
379 if (i1 < 0 && _ordering.hasWildcard())
380 i1 = _ordering.getWildcardIndex();
381 int i2 = _ordering.getIndexOf(c2);
382 if (i2 < 0 && _ordering.hasWildcard())
383 i2 = _ordering.getWildcardIndex();
384
385 return Integer.compare(i1, i2);
386 }
387 }
388
389 @Override
390 public void preConfigure(final WebAppContext context) throws Exception
391 {
392 _webAppClassNameResolver = new WebAppClassNameResolver(context);
393 _containerClassNameResolver = new ContainerClassNameResolver(context);
394 }
395
396
397 public void addDiscoverableAnnotationHandler(AbstractDiscoverableAnnotationHandler handler)
398 {
399 _discoverableAnnotationHandlers.add(handler);
400 }
401
402 @Override
403 public void deconfigure(WebAppContext context) throws Exception
404 {
405 context.removeAttribute(CLASS_INHERITANCE_MAP);
406 context.removeAttribute(CONTAINER_INITIALIZERS);
407 ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(CONTAINER_INITIALIZER_STARTER);
408 if (starter != null)
409 {
410 context.removeBean(starter);
411 context.removeAttribute(CONTAINER_INITIALIZER_STARTER);
412 }
413 }
414
415
416
417
418 @Override
419 public void configure(WebAppContext context) throws Exception
420 {
421 context.addDecorator(new AnnotationDecorator(context));
422
423
424
425 if (!context.getMetaData().isMetaDataComplete())
426 {
427
428 if (context.getServletContext().getEffectiveMajorVersion() >= 3 || context.isConfigurationDiscovered())
429 {
430 _discoverableAnnotationHandlers.add(new WebServletAnnotationHandler(context));
431 _discoverableAnnotationHandlers.add(new WebFilterAnnotationHandler(context));
432 _discoverableAnnotationHandlers.add(new WebListenerAnnotationHandler(context));
433 }
434 }
435
436
437
438 createServletContainerInitializerAnnotationHandlers(context, getNonExcludedInitializers(context));
439
440 if (!_discoverableAnnotationHandlers.isEmpty() || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty())
441 scanForAnnotations(context);
442
443
444 List<ContainerInitializer> initializers =
445 (List<ContainerInitializer>)context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
446 if (initializers != null && initializers.size()>0)
447 {
448 Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
449 if (map == null)
450 LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
451 for (ContainerInitializer i : initializers)
452 i.resolveClasses(context,map);
453 }
454 }
455
456
457
458
459
460 @Override
461 public void postConfigure(WebAppContext context) throws Exception
462 {
463 ConcurrentHashMap<String, ConcurrentHashSet<String>> classMap = (ClassInheritanceMap)context.getAttribute(CLASS_INHERITANCE_MAP);
464 List<ContainerInitializer> initializers = (List<ContainerInitializer>)context.getAttribute(CONTAINER_INITIALIZERS);
465
466 context.removeAttribute(CLASS_INHERITANCE_MAP);
467 if (classMap != null)
468 classMap.clear();
469
470 context.removeAttribute(CONTAINER_INITIALIZERS);
471 if (initializers != null)
472 initializers.clear();
473
474 if (_discoverableAnnotationHandlers != null)
475 _discoverableAnnotationHandlers.clear();
476
477 _classInheritanceHandler = null;
478 if (_containerInitializerAnnotationHandlers != null)
479 _containerInitializerAnnotationHandlers.clear();
480
481 if (_parserTasks != null)
482 {
483 _parserTasks.clear();
484 _parserTasks = null;
485 }
486
487 super.postConfigure(context);
488 }
489
490
491
492
493
494
495
496
497
498 protected void scanForAnnotations (WebAppContext context)
499 throws Exception
500 {
501 AnnotationParser parser = createAnnotationParser();
502 _parserTasks = new ArrayList<ParserTask>();
503
504 long start = 0;
505
506
507 if (LOG.isDebugEnabled())
508 LOG.debug("Annotation scanning commencing: webxml={}, metadatacomplete={}, configurationDiscovered={}, multiThreaded={}, maxScanWait={}",
509 context.getServletContext().getEffectiveMajorVersion(),
510 context.getMetaData().isMetaDataComplete(),
511 context.isConfigurationDiscovered(),
512 isUseMultiThreading(context),
513 getMaxScanWait(context));
514
515
516 parseContainerPath(context, parser);
517
518
519
520
521
522 parseWebInfClasses(context, parser);
523 parseWebInfLib (context, parser);
524
525 start = System.nanoTime();
526
527
528 final Semaphore task_limit = (isUseMultiThreading(context)? new Semaphore(Runtime.getRuntime().availableProcessors()):new Semaphore(1));
529 final CountDownLatch latch = new CountDownLatch(_parserTasks.size());
530 final MultiException me = new MultiException();
531
532 for (final ParserTask p:_parserTasks)
533 {
534 task_limit.acquire();
535 context.getServer().getThreadPool().execute(new Runnable()
536 {
537 @Override
538 public void run()
539 {
540 try
541 {
542 p.call();
543 }
544 catch (Exception e)
545 {
546 me.add(e);
547 }
548 finally
549 {
550 task_limit.release();
551 latch.countDown();
552 }
553 }
554 });
555 }
556
557 boolean timeout = !latch.await(getMaxScanWait(context), TimeUnit.SECONDS);
558
559 if (LOG.isDebugEnabled())
560 {
561 for (ParserTask p:_parserTasks)
562 LOG.debug("Scanned {} in {}ms", p.getResource(), TimeUnit.MILLISECONDS.convert(p.getStatistic().getElapsed(), TimeUnit.NANOSECONDS));
563 }
564
565 LOG.debug("Scanned {} container path jars, {} WEB-INF/lib jars, {} WEB-INF/classes dirs in {}ms for context {}",
566 _containerPathStats.getTotal(), _webInfLibStats.getTotal(), _webInfClassesStats.getTotal(),
567 (TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)),
568 context);
569
570 if (timeout)
571 me.add(new Exception("Timeout scanning annotations"));
572 me.ifExceptionThrow();
573 }
574
575
576
577
578
579
580
581 protected AnnotationParser createAnnotationParser()
582 {
583 return new AnnotationParser();
584 }
585
586
587
588
589
590
591 protected boolean isUseMultiThreading(WebAppContext context)
592 {
593
594 Object o = context.getAttribute(MULTI_THREADED);
595 if (o instanceof Boolean)
596 {
597 return ((Boolean)o).booleanValue();
598 }
599
600 o = context.getServer().getAttribute(MULTI_THREADED);
601 if (o instanceof Boolean)
602 {
603 return ((Boolean)o).booleanValue();
604 }
605
606 return Boolean.valueOf(System.getProperty(MULTI_THREADED, Boolean.toString(DEFAULT_MULTI_THREADED)));
607 }
608
609
610
611
612
613
614
615
616
617 protected int getMaxScanWait (WebAppContext context)
618 {
619
620 Object o = context.getAttribute(MAX_SCAN_WAIT);
621 if (o != null && o instanceof Number)
622 {
623 return ((Number)o).intValue();
624 }
625
626 o = context.getServer().getAttribute(MAX_SCAN_WAIT);
627 if (o != null && o instanceof Number)
628 {
629 return ((Number)o).intValue();
630 }
631
632 return Integer.getInteger(MAX_SCAN_WAIT, DEFAULT_MAX_SCAN_WAIT).intValue();
633 }
634
635
636
637
638
639
640 @Override
641 public void cloneConfigure(WebAppContext template, WebAppContext context) throws Exception
642 {
643 context.addDecorator(new AnnotationDecorator(context));
644 }
645
646
647
648
649
650
651
652
653 public void createServletContainerInitializerAnnotationHandlers (WebAppContext context, List<ServletContainerInitializer> scis)
654 throws Exception
655 {
656 if (scis == null || scis.isEmpty())
657 return;
658
659 List<ContainerInitializer> initializers = new ArrayList<ContainerInitializer>();
660 context.setAttribute(CONTAINER_INITIALIZERS, initializers);
661
662 for (ServletContainerInitializer service : scis)
663 {
664 HandlesTypes annotation = service.getClass().getAnnotation(HandlesTypes.class);
665 ContainerInitializer initializer = null;
666 if (annotation != null)
667 {
668
669 Class<?>[] classes = annotation.value();
670 if (classes != null)
671 {
672 initializer = new ContainerInitializer(service, classes);
673
674
675
676 if (context.getAttribute(CLASS_INHERITANCE_MAP) == null)
677 {
678
679 ConcurrentHashMap<String, ConcurrentHashSet<String>> map = new ClassInheritanceMap();
680 context.setAttribute(CLASS_INHERITANCE_MAP, map);
681 _classInheritanceHandler = new ClassInheritanceHandler(map);
682 }
683
684 for (Class<?> c: classes)
685 {
686
687
688 if (c.isAnnotation())
689 {
690 if (LOG.isDebugEnabled()) LOG.debug("Registering annotation handler for "+c.getName());
691 _containerInitializerAnnotationHandlers.add(new ContainerInitializerAnnotationHandler(initializer, c));
692 }
693 }
694 }
695 else
696 {
697 initializer = new ContainerInitializer(service, null);
698 if (LOG.isDebugEnabled()) LOG.debug("No classes in HandlesTypes on initializer "+service.getClass());
699 }
700 }
701 else
702 {
703 initializer = new ContainerInitializer(service, null);
704 if (LOG.isDebugEnabled()) LOG.debug("No annotation on initializer "+service.getClass());
705 }
706
707 initializers.add(initializer);
708 }
709
710
711
712 ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(CONTAINER_INITIALIZER_STARTER);
713 if (starter != null)
714 throw new IllegalStateException("ServletContainerInitializersStarter already exists");
715 starter = new ServletContainerInitializersStarter(context);
716 context.setAttribute(CONTAINER_INITIALIZER_STARTER, starter);
717 context.addBean(starter, true);
718 }
719
720
721 public Resource getJarFor (ServletContainerInitializer service)
722 throws MalformedURLException, IOException
723 {
724 String loadingJarName = Thread.currentThread().getContextClassLoader().getResource(service.getClass().getName().replace('.','/')+".class").toString();
725
726 int i = loadingJarName.indexOf(".jar");
727 if (i < 0)
728 return null;
729
730 loadingJarName = loadingJarName.substring(0,i+4);
731 loadingJarName = (loadingJarName.startsWith("jar:")?loadingJarName.substring(4):loadingJarName);
732 return Resource.newResource(loadingJarName);
733 }
734
735
736
737
738
739
740
741
742
743 public boolean isFromExcludedJar (WebAppContext context, ServletContainerInitializer sci, Resource sciResource)
744 throws Exception
745 {
746 if (sci == null)
747 throw new IllegalArgumentException("ServletContainerInitializer null");
748 if (context == null)
749 throw new IllegalArgumentException("WebAppContext null");
750
751
752
753 if (sci.getClass().getClassLoader()==context.getClassLoader().getParent())
754 return false;
755
756 List<Resource> orderedJars = context.getMetaData().getOrderedWebInfJars();
757
758
759 if (context.getMetaData().getOrdering() == null)
760 return false;
761
762
763 if (orderedJars.isEmpty())
764 return true;
765
766 if (sciResource == null)
767 return false;
768
769 URI loadingJarURI = sciResource.getURI();
770 boolean found = false;
771 Iterator<Resource> itor = orderedJars.iterator();
772 while (!found && itor.hasNext())
773 {
774 Resource r = itor.next();
775 found = r.getURI().equals(loadingJarURI);
776 }
777
778 return !found;
779 }
780
781
782
783
784
785
786
787
788 public List<ServletContainerInitializer> getNonExcludedInitializers (WebAppContext context)
789 throws Exception
790 {
791 ArrayList<ServletContainerInitializer> nonExcludedInitializers = new ArrayList<ServletContainerInitializer>();
792
793
794
795 long start = 0;
796
797 ClassLoader old = Thread.currentThread().getContextClassLoader();
798 ServiceLoader<ServletContainerInitializer> loadedInitializers = null;
799 try
800 {
801 if (LOG.isDebugEnabled())
802 start = System.nanoTime();
803 Thread.currentThread().setContextClassLoader(context.getClassLoader());
804 loadedInitializers = ServiceLoader.load(ServletContainerInitializer.class);
805 }
806 finally
807 {
808 Thread.currentThread().setContextClassLoader(old);
809 }
810
811 if (LOG.isDebugEnabled())
812 LOG.debug("Service loaders found in {}ms", (TimeUnit.MILLISECONDS.convert((System.nanoTime()-start), TimeUnit.NANOSECONDS)));
813
814 ServletContainerInitializerOrdering initializerOrdering = getInitializerOrdering(context);
815
816 if (initializerOrdering != null && !initializerOrdering.isDefaultOrder())
817 {
818 if (LOG.isDebugEnabled())
819 LOG.debug("Ordering ServletContainerInitializers with "+initializerOrdering);
820
821
822
823 for (ServletContainerInitializer sci:loadedInitializers)
824 {
825 Resource sciResource = getJarFor(sci);
826 if (!isFromExcludedJar(context, sci, sciResource))
827 {
828 String name = sci.getClass().getName();
829 if (initializerOrdering.getIndexOf(name) >= 0 || initializerOrdering.hasWildcard())
830 nonExcludedInitializers.add(sci);
831 }
832 }
833
834
835 Collections.sort(nonExcludedInitializers, new ServletContainerInitializerComparator(initializerOrdering));
836 }
837 else
838 {
839
840
841
842 if (LOG.isDebugEnabled())
843 LOG.debug("Ordering ServletContainerInitializers as container path, webapp path");
844
845 Map<ServletContainerInitializer,Resource> webappPathInitializerResourceMap = new HashMap<ServletContainerInitializer,Resource>();
846 for (ServletContainerInitializer sci : loadedInitializers)
847 {
848
849 if (sci.getClass().getClassLoader() == context.getClassLoader().getParent())
850 {
851 nonExcludedInitializers.add(sci);
852 }
853 else
854 {
855
856 Resource sciResource = getJarFor(sci);
857 if (!isFromExcludedJar(context, sci, sciResource))
858 {
859 webappPathInitializerResourceMap.put(sci, sciResource);
860 }
861 }
862 }
863
864
865 if (context.getMetaData().getOrdering() == null)
866 nonExcludedInitializers.addAll(webappPathInitializerResourceMap.keySet());
867 else
868 {
869
870 for (Map.Entry<ServletContainerInitializer, Resource> entry:webappPathInitializerResourceMap.entrySet())
871 {
872 if (entry.getValue() == null)
873 nonExcludedInitializers.add(entry.getKey());
874 }
875
876
877 for (Resource webInfJar:context.getMetaData().getOrderedWebInfJars())
878 {
879 for (Map.Entry<ServletContainerInitializer, Resource> entry:webappPathInitializerResourceMap.entrySet())
880 {
881 if (webInfJar.equals(entry.getValue()))
882 nonExcludedInitializers.add(entry.getKey());
883 }
884 }
885 }
886 }
887
888 return nonExcludedInitializers;
889 }
890
891
892
893
894
895
896
897 public ServletContainerInitializerOrdering getInitializerOrdering (WebAppContext context)
898 {
899 if (context == null)
900 return null;
901
902 String tmp = (String)context.getAttribute(SERVLET_CONTAINER_INITIALIZER_ORDER);
903 if (tmp == null || "".equals(tmp.trim()))
904 return null;
905
906 return new ServletContainerInitializerOrdering(tmp);
907 }
908
909
910
911
912
913
914
915
916
917 public void parseContainerPath (final WebAppContext context, final AnnotationParser parser) throws Exception
918 {
919
920 final Set<Handler> handlers = new HashSet<Handler>();
921 handlers.addAll(_discoverableAnnotationHandlers);
922 handlers.addAll(_containerInitializerAnnotationHandlers);
923 if (_classInheritanceHandler != null)
924 handlers.add(_classInheritanceHandler);
925
926 _containerPathStats = new CounterStatistic();
927
928 for (Resource r : context.getMetaData().getContainerResources())
929 {
930
931 if (_parserTasks != null)
932 {
933 ParserTask task = new ParserTask(parser, handlers, r, _containerClassNameResolver);
934 _parserTasks.add(task);
935 _containerPathStats.increment();
936 if (LOG.isDebugEnabled())
937 task.setStatistic(new TimeStatistic());
938 }
939 }
940 }
941
942
943
944
945
946
947
948
949
950 public void parseWebInfLib (final WebAppContext context, final AnnotationParser parser) throws Exception
951 {
952 List<FragmentDescriptor> frags = context.getMetaData().getFragments();
953
954
955
956
957 ArrayList<URI> webInfUris = new ArrayList<URI>();
958
959 List<Resource> jars = context.getMetaData().getOrderedWebInfJars();
960
961
962 if (jars == null || jars.isEmpty())
963 jars = context.getMetaData().getWebInfJars();
964
965 _webInfLibStats = new CounterStatistic();
966
967 for (Resource r : jars)
968 {
969
970 final Set<Handler> handlers = new HashSet<Handler>();
971
972 FragmentDescriptor f = getFragmentFromJar(r, frags);
973
974
975
976
977
978 if (f == null || !isMetaDataComplete(f) || _classInheritanceHandler != null || !_containerInitializerAnnotationHandlers.isEmpty())
979 {
980
981 if (_classInheritanceHandler != null)
982 handlers.add(_classInheritanceHandler);
983
984
985 handlers.addAll(_containerInitializerAnnotationHandlers);
986
987
988 if (f == null || !isMetaDataComplete(f))
989 handlers.addAll(_discoverableAnnotationHandlers);
990
991 if (_parserTasks != null)
992 {
993 ParserTask task = new ParserTask(parser, handlers,r, _webAppClassNameResolver);
994 _parserTasks.add (task);
995 _webInfLibStats.increment();
996 if (LOG.isDebugEnabled())
997 task.setStatistic(new TimeStatistic());
998 }
999 }
1000 }
1001 }
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011 public void parseWebInfClasses (final WebAppContext context, final AnnotationParser parser)
1012 throws Exception
1013 {
1014 Set<Handler> handlers = new HashSet<Handler>();
1015 handlers.addAll(_discoverableAnnotationHandlers);
1016 if (_classInheritanceHandler != null)
1017 handlers.add(_classInheritanceHandler);
1018 handlers.addAll(_containerInitializerAnnotationHandlers);
1019
1020 _webInfClassesStats = new CounterStatistic();
1021
1022 for (Resource dir : context.getMetaData().getWebInfClassesDirs())
1023 {
1024 if (_parserTasks != null)
1025 {
1026 ParserTask task = new ParserTask(parser, handlers, dir, _webAppClassNameResolver);
1027 _parserTasks.add(task);
1028 _webInfClassesStats.increment();
1029 if (LOG.isDebugEnabled())
1030 task.setStatistic(new TimeStatistic());
1031 }
1032 }
1033 }
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 public FragmentDescriptor getFragmentFromJar (Resource jar, List<FragmentDescriptor> frags)
1046 throws Exception
1047 {
1048
1049 FragmentDescriptor d = null;
1050 for (FragmentDescriptor frag: frags)
1051 {
1052 Resource fragResource = frag.getResource();
1053 if (Resource.isContainedIn(fragResource,jar))
1054 {
1055 d = frag;
1056 break;
1057 }
1058 }
1059 return d;
1060 }
1061
1062 public boolean isMetaDataComplete (WebDescriptor d)
1063 {
1064 return (d!=null && d.getMetaDataComplete() == MetaDataComplete.True);
1065 }
1066
1067 public static class ClassInheritanceMap extends ConcurrentHashMap<String, ConcurrentHashSet<String>>
1068 {
1069
1070 @Override
1071 public String toString()
1072 {
1073 return String.format("ClassInheritanceMap@%x{size=%d}",hashCode(),size());
1074 }
1075 }
1076 }
1077
1078