11
11
import java .util .List ;
12
12
import java .util .Map ;
13
13
import java .util .Map .Entry ;
14
+ import java .util .Optional ;
14
15
import java .util .function .Predicate ;
15
16
import java .util .stream .Collectors ;
16
17
23
24
import com .fasterxml .jackson .module .jsonSchema .JsonSchemaGenerator ;
24
25
25
26
import io .asfjava .ui .core .FormDefinitionGeneratorFactory ;
27
+ import io .asfjava .ui .core .form .Action ;
28
+ import io .asfjava .ui .core .form .ActionsGroup ;
29
+ import io .asfjava .ui .core .form .FieldSet ;
26
30
import io .asfjava .ui .core .form .Index ;
27
31
import io .asfjava .ui .core .form .Tab ;
28
32
import io .asfjava .ui .dto .UiForm ;
@@ -38,39 +42,81 @@ public UiForm generate(Class<? extends Serializable> formDto) throws JsonMapping
38
42
JsonSchemaGenerator schemaGen = initSchemaGen (mapper );
39
43
JsonSchema schema = generateSchema (formDto , schemaGen );
40
44
41
- Map <Field , JsonNode > nodes = initFieldFormDefinition (mapper , declaredFields );
45
+ Map <Field , JsonNode > nodes = initFieldsFormDefinition (mapper , declaredFields );
42
46
43
47
Map <Field , JsonNode > sortedNodes = reorderFieldsBasedOnIndex (nodes );
44
48
45
- handlerGroupedFields ();
49
+ handlerGroupedFields (mapper , declaredFields , sortedNodes );
46
50
47
- ObjectNode tabbedFields = handleTabbedFields (mapper , declaredFields , sortedNodes );
51
+ Optional <ObjectNode > tabbedFields = Optional
52
+ .ofNullable (handleTabbedFields (mapper , declaredFields , sortedNodes ));
48
53
49
54
ArrayNode formDefinition = mapper .createArrayNode ();
50
- formDefinition . add ( tabbedFields );
55
+ tabbedFields . ifPresent ( formDefinition :: add );
51
56
sortedNodes .entrySet ().stream ().forEach (nodesElement -> formDefinition .add (nodesElement .getValue ()));
52
57
58
+ handleActionsAnnotation (mapper , formDto , formDefinition );
59
+
53
60
return new UiForm (schema , formDefinition );
54
61
}
55
62
56
- private Map <Field , JsonNode > reorderFieldsBasedOnIndex (Map <Field , JsonNode > nodes ) {
63
+ private void handleActionsAnnotation (ObjectMapper mapper , Class <? extends Serializable > formDto ,
64
+ ArrayNode formDefinition ) {
65
+ ObjectNode groupedActionsNode = mapper .createObjectNode ();
66
+ ObjectNode actionsNode = mapper .createObjectNode ();
57
67
58
- Comparator <? super Entry <Field , JsonNode >> tabIndexComparator = (entry1 , entry2 ) -> {
68
+ buildActions (mapper , formDto , actionsNode , formDefinition );
69
+ buildGroupedActions (mapper , formDto , groupedActionsNode , formDefinition );
70
+ }
59
71
60
- Index field1Index = entry1 . getKey (). getAnnotation ( Index . class );
61
- Index field2Index = entry2 . getKey (). getAnnotation ( Index . class );
72
+ private void buildActions ( ObjectMapper mapper , Class <? extends Serializable > formDto , ObjectNode actionsNode ,
73
+ ArrayNode formDefinition ) {
62
74
63
- return Integer .compare ((field1Index != null ? field1Index .value () : Integer .MAX_VALUE ),
64
- field2Index != null ? field2Index .value () : Integer .MAX_VALUE );
65
- };
75
+ Action [] actionsAnnotations = formDto .getAnnotationsByType (Action .class );
76
+ Arrays .stream (actionsAnnotations ).forEach (action -> {
77
+ formDefinition .add (buildActionNode (mapper , action ));
78
+ });
79
+ }
66
80
67
- return nodes .entrySet ().stream ().sorted (tabIndexComparator ).collect (Collectors .toMap (Map .Entry ::getKey ,
68
- Map .Entry ::getValue , (oldValue , newValue ) -> oldValue , LinkedHashMap ::new ));
81
+ private void buildGroupedActions (ObjectMapper mapper , Class <? extends Serializable > formDto , ObjectNode actionsNode ,
82
+ ArrayNode formDefinition ) {
83
+ Optional <ActionsGroup > actionsAnnotation = Optional .ofNullable (formDto .getAnnotation (ActionsGroup .class ));
84
+ actionsAnnotation .ifPresent (actions -> {
85
+ actionsNode .put ("type" , "actions" );
86
+ ArrayNode items = mapper .createArrayNode ();
87
+ Arrays .stream (actions .value ()).forEach (action -> {
88
+ ObjectNode node = buildActionNode (mapper , action );
89
+ items .add (node );
90
+ });
91
+ actionsNode .set ("items" , items );
92
+
93
+ formDefinition .add (actionsNode );
94
+ });
95
+ }
69
96
97
+ private ObjectNode buildActionNode (ObjectMapper mapper , Action action ) {
98
+ ObjectNode node = mapper .createObjectNode ();
99
+ node .put ("type" , action .type ());
100
+ node .put ("title" , action .title ());
101
+ node .put ("onClick" , action .onClick ());
102
+ return node ;
70
103
}
71
104
72
- private void handlerGroupedFields () {
73
- // TODO Grouping fieldset must handle it
105
+ private ObjectNode handlerGroupedFields (ObjectMapper mapper , Field [] declaredFields ,
106
+ Map <Field , JsonNode > sortedNodes ) {
107
+ Predicate <? super Field > checkFieldSetAnnotation = field -> field .isAnnotationPresent (FieldSet .class );
108
+
109
+ Map <String , List <JsonNode >> groupedFields = new LinkedHashMap <>();
110
+
111
+ Arrays .stream (declaredFields ).filter (checkFieldSetAnnotation )
112
+ .forEach (field -> groupFieldsByTab (sortedNodes , field , groupedFields ));
113
+
114
+ ArrayNode groups = mapper .createArrayNode ();
115
+
116
+ ObjectNode tabsNode = mapper .createObjectNode ();
117
+ tabsNode .put ("type" , "fieldset" );
118
+ tabsNode .set ("items" , groups );
119
+ return tabsNode ;
74
120
75
121
}
76
122
@@ -83,7 +129,6 @@ private ObjectNode handleTabbedFields(ObjectMapper mapper, Field[] declaredField
83
129
Comparator <? super Field > fieldIndexComparator = (entry1 , entry2 ) -> {
84
130
Index field1Index = entry1 .getAnnotation (Index .class );
85
131
Index field2Index = entry2 .getAnnotation (Index .class );
86
-
87
132
return Integer .compare ((field1Index != null ? field1Index .value () : Integer .MAX_VALUE ),
88
133
field2Index != null ? field2Index .value () : Integer .MAX_VALUE );
89
134
};
@@ -103,15 +148,17 @@ private ObjectNode handleTabbedFields(ObjectMapper mapper, Field[] declaredField
103
148
tabNode .set ("items" , tabItems );
104
149
tabs .add (tabNode );
105
150
});
106
-
107
- ObjectNode tabsNode = mapper .createObjectNode ();
108
- tabsNode .put ("type" , "tabs" );
109
- tabsNode .set ("tabs" , tabs );
110
- return tabsNode ;
151
+ if (tabs .size () > 0 ) {
152
+ ObjectNode tabsNode = mapper .createObjectNode ();
153
+ tabsNode .put ("type" , "tabs" );
154
+ tabsNode .set ("tabs" , tabs );
155
+ return tabsNode ;
156
+ }
157
+ return null ;
111
158
112
159
}
113
160
114
- private Map <Field , JsonNode > initFieldFormDefinition (ObjectMapper mapper , Field [] declaredFields ) {
161
+ private Map <Field , JsonNode > initFieldsFormDefinition (ObjectMapper mapper , Field [] declaredFields ) {
115
162
Map <Field , JsonNode > nodes = new HashMap <>();
116
163
117
164
Arrays .stream (declaredFields ).forEach (field -> buildFormDefinition (nodes , mapper , field ));
@@ -154,6 +201,22 @@ private void buildFieldDefinition(Field field, Annotation annotation, ObjectMapp
154
201
});
155
202
}
156
203
204
+ private Map <Field , JsonNode > reorderFieldsBasedOnIndex (Map <Field , JsonNode > nodes ) {
205
+
206
+ Comparator <? super Entry <Field , JsonNode >> tabIndexComparator = (entry1 , entry2 ) -> {
207
+
208
+ Index field1Index = entry1 .getKey ().getAnnotation (Index .class );
209
+ Index field2Index = entry2 .getKey ().getAnnotation (Index .class );
210
+
211
+ return Integer .compare ((field1Index != null ? field1Index .value () : Integer .MAX_VALUE ),
212
+ field2Index != null ? field2Index .value () : Integer .MAX_VALUE );
213
+ };
214
+
215
+ return nodes .entrySet ().stream ().sorted (tabIndexComparator ).collect (Collectors .toMap (Map .Entry ::getKey ,
216
+ Map .Entry ::getValue , (oldValue , newValue ) -> oldValue , LinkedHashMap ::new ));
217
+
218
+ }
219
+
157
220
public static UiFormSchemaGenerator get () {
158
221
if (instance == null ) {
159
222
instance = new UiFormSchemaGenerator ();
0 commit comments