11package com .g2forge .habitat .metadata .access .annotation ;
22
33import java .lang .annotation .Annotation ;
4+ import java .lang .annotation .Inherited ;
5+ import java .util .ArrayList ;
6+ import java .util .List ;
7+ import java .util .Optional ;
8+ import java .util .stream .Collectors ;
49
10+ import com .g2forge .alexandria .java .core .helpers .HCollection ;
11+ import com .g2forge .alexandria .java .core .helpers .HTree ;
512import com .g2forge .alexandria .java .reflect .annotations .IJavaAnnotations ;
613import com .g2forge .habitat .metadata .annotations .ContainerAnnotationReflection ;
714import com .g2forge .habitat .metadata .type .predicate .IAnnotationPredicateType ;
@@ -30,25 +37,67 @@ public class AnnotationPredicate<T extends Annotation> implements IPredicate<T>
3037 @ Override
3138 public T get0 () {
3239 final Class <T > annotationType = getType ().getAnnotationType ();
33- final IJavaAnnotations annotations = getSubject ().getAnnotations ();
34- final T retVal = annotations .getAnnotation (annotationType );
35- if (retVal != null ) return retVal ;
36-
37- final ContainerAnnotationReflection <T , Annotation > containerAnnotationReflection = getContainerAnnotationReflection ();
38- if (containerAnnotationReflection == null ) return null ;
39- final Annotation repeatable = annotations .getAnnotation (containerAnnotationReflection .getRepeatable ());
40- if (repeatable == null ) return null ;
41- return containerAnnotationReflection .getCollectionStrategy ().builder ().add (repeatable ).get ();
40+ if (annotationType .isAnnotationPresent (Inherited .class )) {
41+ // Inherited annotations
42+ final ContainerAnnotationReflection <T , Annotation > containerAnnotationReflection = getContainerAnnotationReflection ();
43+ if (containerAnnotationReflection == null ) {
44+ final Optional <IElementSubject > subject = HTree .find (getSubject (), IElementSubject ::getParents , s -> s .getAnnotations ().isAnnotated (annotationType ));
45+ if (!subject .isPresent ()) return null ;
46+ final IJavaAnnotations annotations = subject .get ().getAnnotations ();
47+ return annotations .getAnnotation (annotationType );
48+ } else {
49+ final Class <Annotation > repeatableAnnotationType = containerAnnotationReflection .getRepeatable ();
50+ final List <Annotation > repeatableAnnotationValues = HTree .dfs (getSubject (), IElementSubject ::getParents , false ).flatMap (s -> {
51+ final IJavaAnnotations annotations = s .getAnnotations ();
52+ final List <Annotation > retVal = new ArrayList <>();
53+
54+ final T annotation = annotations .getAnnotation (annotationType );
55+ if (annotation != null ) retVal .addAll (HCollection .asListIterable (containerAnnotationReflection .getCollectionStrategy ().iterable (annotation )));
56+
57+ final Annotation repeatable = annotations .getAnnotation (repeatableAnnotationType );
58+ if (repeatable != null ) retVal .add (repeatable );
59+
60+ return retVal .stream ();
61+ }).collect (Collectors .toList ());
62+ return containerAnnotationReflection .getCollectionStrategy ().builder ().add (repeatableAnnotationValues ).get ();
63+ }
64+ } else {
65+ // Non-inherited annotations present on the subject
66+ final IJavaAnnotations annotations = getSubject ().getAnnotations ();
67+ final T retVal = annotations .getAnnotation (annotationType );
68+ if (retVal != null ) return retVal ;
69+
70+ // Non-inherited annotations which are repeated, and whose repeatable child is on the subject
71+ final ContainerAnnotationReflection <T , Annotation > containerAnnotationReflection = getContainerAnnotationReflection ();
72+ if (containerAnnotationReflection == null ) return null ;
73+ final Annotation repeatable = annotations .getAnnotation (containerAnnotationReflection .getRepeatable ());
74+ if (repeatable == null ) return null ;
75+ return containerAnnotationReflection .getCollectionStrategy ().builder ().add (repeatable ).get ();
76+ }
4277 }
4378
4479 @ Override
4580 public boolean isPresent () {
46- final IJavaAnnotations annotations = getSubject ().getAnnotations ();
47- final boolean retVal = annotations .isAnnotated (getType ().getAnnotationType ());
48- if (retVal ) return true ;
81+ final Class <T > annotationType = getType ().getAnnotationType ();
82+ if (annotationType .isAnnotationPresent (Inherited .class )) {
83+ // Inherited annotations
84+ final ContainerAnnotationReflection <T , Annotation > containerAnnotationReflection = getContainerAnnotationReflection ();
85+ if (containerAnnotationReflection == null ) return HTree .find (getSubject (), IElementSubject ::getParents , s -> s .getAnnotations ().isAnnotated (annotationType )).isPresent ();
86+ else {
87+ final Class <Annotation > repeatableAnnotationType = containerAnnotationReflection .getRepeatable ();
88+ return HTree .find (getSubject (), IElementSubject ::getParents , s -> {
89+ final IJavaAnnotations annotations = s .getAnnotations ();
90+ return annotations .isAnnotated (annotationType ) || annotations .isAnnotated (repeatableAnnotationType );
91+ }).isPresent ();
92+ }
93+ } else {
94+ final IJavaAnnotations annotations = getSubject ().getAnnotations ();
95+ final boolean retVal = annotations .isAnnotated (annotationType );
96+ if (retVal ) return true ;
4997
50- final ContainerAnnotationReflection <T , Annotation > containerAnnotationReflection = getContainerAnnotationReflection ();
51- if (containerAnnotationReflection == null ) return false ;
52- return annotations .isAnnotated (containerAnnotationReflection .getRepeatable ());
98+ final ContainerAnnotationReflection <T , Annotation > containerAnnotationReflection = getContainerAnnotationReflection ();
99+ if (containerAnnotationReflection == null ) return false ;
100+ return annotations .isAnnotated (containerAnnotationReflection .getRepeatable ());
101+ }
53102 }
54103}
0 commit comments