88
99import java .lang .annotation .Annotation ;
1010import java .lang .reflect .Method ;
11+ import java .lang .reflect .Modifier ;
1112import java .lang .reflect .ParameterizedType ;
1213import java .lang .reflect .Type ;
1314import java .util .Arrays ;
1415import java .util .Collection ;
1516import java .util .LinkedHashSet ;
1617import java .util .List ;
1718import java .util .Set ;
19+ import java .util .stream .Stream ;
1820
1921import static com .github .rschmitt .dynamicobject .internal .ClojureStuff .cachedRead ;
2022import static java .util .stream .Collectors .toSet ;
@@ -27,24 +29,51 @@ static <D extends DynamicObject<D>> Collection<Method> requiredFields(Class<D> t
2729
2830 static <D extends DynamicObject <D >> Set <Object > cachedKeys (Class <D > type ) {
2931 return Arrays .stream (type .getMethods ())
30- .filter (method -> method .getAnnotation (Cached .class ) != null )
31- .map (method -> method .getAnnotation (Key .class ))
32- .filter (key -> key != null )
33- .map (Key ::value )
34- .map (Reflection ::stringToKey )
32+ .flatMap (Reflection ::getCachedKeysForMethod )
3533 .collect (toSet ());
3634 }
3735
36+ private static Stream <Object > getCachedKeysForMethod (Method method ) {
37+ if (isGetter (method )) {
38+ if (method .getAnnotation (Cached .class ) != null ) {
39+ return Stream .of (getKeyForGetter (method ));
40+ } else {
41+ return Stream .empty ();
42+ }
43+ } else if (isBuilder (method )) {
44+ if (method .getAnnotation (Cached .class ) != null ) {
45+ return Stream .of (getKeyForBuilder (method ));
46+ } else {
47+ // If the getter has an annotation it'll contribute it directly
48+ return Stream .empty ();
49+ }
50+ } else {
51+ return Stream .empty ();
52+ }
53+ }
54+
3855 static <D extends DynamicObject <D >> Collection <Method > fieldGetters (Class <D > type ) {
3956 Collection <Method > ret = new LinkedHashSet <>();
4057 for (Method method : type .getDeclaredMethods ())
41- if (method . getParameterCount () == 0 && ! method . isDefault () && ! method . isSynthetic () && ! isMetadataGetter (method ))
58+ if (isGetter (method ))
4259 ret .add (method );
4360 return ret ;
4461 }
4562
46- static boolean isMetadataGetter (Method getter ) {
47- return getter .getParameterCount () == 0 && hasAnnotation (getter , Meta .class );
63+ private static boolean isBuilder (Method method ) {
64+ return method .getParameterCount () == 1 && method .getDeclaringClass ().isAssignableFrom (method .getReturnType ());
65+ }
66+
67+ private static boolean isAnyGetter (Method method ) {
68+ return method .getParameterCount () == 0 && !method .isDefault () && !method .isSynthetic ();
69+ }
70+
71+ private static boolean isGetter (Method method ) {
72+ return isAnyGetter (method ) && !isMetadataGetter (method );
73+ }
74+
75+ static boolean isMetadataGetter (Method method ) {
76+ return isAnyGetter (method ) && hasAnnotation (method , Meta .class );
4877 }
4978
5079 static boolean isRequired (Method getter ) {
@@ -107,7 +136,7 @@ private static Method getCorrespondingGetter(Method builderMethod) {
107136 Method correspondingGetter = type .getMethod (builderMethod .getName ());
108137 return correspondingGetter ;
109138 } catch (NoSuchMethodException ex ) {
110- throw new IllegalStateException ("Builder methods must have a corresponding getter method or a @Key annotation." , ex );
139+ throw new IllegalStateException ("Builder method " + builderMethod + " must have a corresponding getter method or a @Key annotation." , ex );
111140 }
112141 }
113142
0 commit comments