14
14
15
15
package me .zhhe .cli .menu .bean ;
16
16
17
+ import org .apache .commons .lang3 .StringUtils ;
18
+
17
19
import java .lang .reflect .Field ;
18
20
import java .lang .reflect .InvocationTargetException ;
19
21
import java .lang .reflect .Method ;
25
27
import java .util .List ;
26
28
import java .util .Locale ;
27
29
import java .util .Map ;
30
+ import java .util .function .Function ;
31
+ import java .util .function .Predicate ;
28
32
33
+ import me .zhhe .cli .menu .Setter ;
34
+ import me .zhhe .cli .menu .Option ;
29
35
import me .zhhe .cli .menu .util .ExceptionUtil ;
30
36
31
37
/**
@@ -47,15 +53,40 @@ public static BeanParser getInstance() {
47
53
}
48
54
49
55
public Collection <? extends BeanItem > parse (final Object bean ) {
50
- final Field [] fields = bean .getClass ().getDeclaredFields ();
51
- final Map <String , Method > validSetters = extractValidSetters (bean .getClass ());
56
+ final Class <?> clazz = bean .getClass ();
57
+ final Field [] fields = clazz .getDeclaredFields ();
58
+ final Method [] methods = clazz .getMethods ();
59
+
60
+ final Map <String , Method > settersWithAnnotation = extractMethods (methods ,
61
+ m -> m .isAnnotationPresent (Setter .class ),
62
+ m -> m .getAnnotation (Setter .class ).value ().trim ());
63
+ final Map <String , Method > settersViaNaming = extractMethods (methods ,
64
+ m -> m .getName ().startsWith ("set" ), m -> m .getName ());
65
+
52
66
final List <BeanItem > items = new ArrayList <>();
53
67
Arrays .stream (fields ).forEach (field -> {
54
- final String name = field .getName ();
55
- final Method m = validSetters .get (formatSetterName (name ));
56
- if (m !=null ) {
68
+ final String fieldName = field .getName ();
69
+ final Option option = field .getAnnotation (Option .class );
70
+ final String argName = option !=null ? option .name () : "" ;
71
+
72
+ // in case of:
73
+ // a) option is null
74
+ // b) or both argName & longArgName is empty
75
+ // fieldName will be used as longArgName.
76
+ final String longArgName =
77
+ (option == null ||
78
+ (StringUtils .isBlank (option .longArgName ())
79
+ && StringUtils .isBlank (option .name ()))
80
+ ) ? fieldName : option .longArgName ();
81
+
82
+ final String description = option !=null ? option .description () : "" ;
83
+ // annotation has high priority than naming convention.
84
+ final Method m = settersWithAnnotation .containsKey (fieldName ) ?
85
+ settersWithAnnotation .get (fieldName ) : settersViaNaming .get (formatSetterName (fieldName ));
86
+
87
+ if (m != null ) {
57
88
field .setAccessible (true );
58
- items .add (new BeanItem (field . getName () ,
89
+ items .add (new BeanItem (argName , longArgName , description ,
59
90
() -> {
60
91
try {
61
92
final Object o = field .get (bean );
@@ -81,11 +112,11 @@ public Collection<? extends BeanItem> parse(final Object bean) {
81
112
return items ;
82
113
}
83
114
84
- private Map <String , Method > extractValidSetters (final Class <?> clazz ) {
85
- final Map < String , Method > validSetters = new HashMap <>();
86
- final Method [] methods = clazz . getMethods ();
115
+ private Map <String , Method > extractMethods (final Method [] methods ,
116
+ Predicate < Method > predict , Function < Method , String > key ) {
117
+ final Map < String , Method > ret = new HashMap <> ();
87
118
for (final Method m : methods ) {
88
- if (!m . getName (). startsWith ( "set" ))
119
+ if (!predict . test ( m ))
89
120
continue ;
90
121
91
122
if (void .class != m .getReturnType ())
@@ -99,10 +130,10 @@ private Map<String, Method> extractValidSetters(final Class<?> clazz) {
99
130
if (String .class != params [0 ].getType ())
100
131
continue ;
101
132
102
- validSetters .put (m . getName ( ), m );
133
+ ret .put (key . apply ( m ), m );
103
134
}
104
135
105
- return validSetters ;
136
+ return ret ;
106
137
}
107
138
108
139
private String formatSetterName (final String fieldName ) {
0 commit comments