55import java .util .List ;
66import java .util .Map ;
77import java .util .Optional ;
8+ import java .util .Set ;
89import java .util .function .Function ;
910import java .util .function .Predicate ;
1011import java .util .function .Supplier ;
3334import de .symeda .sormas .api .patch .DataPatcher ;
3435import de .symeda .sormas .api .patch .DataReplacementStrategy ;
3536import de .symeda .sormas .api .patch .EmptyValueBehavior ;
37+ import de .symeda .sormas .api .patch .SinglePatchResult ;
3638import de .symeda .sormas .api .patch .mapping .FieldCustomMapper ;
3739import de .symeda .sormas .api .patch .mapping .FieldPatchRequest ;
40+ import de .symeda .sormas .api .patch .mapping .GroupedFieldsRequest ;
3841import de .symeda .sormas .api .patch .mapping .ValueMappingResult ;
3942import de .symeda .sormas .api .patch .mapping .ValuePatchRequest ;
4043import de .symeda .sormas .api .person .PersonDto ;
@@ -126,27 +129,31 @@ public DataPatchResponse patch(CaseDataPatchRequest request) {
126129
127130 List <Tuple <String , Tuple <DataPatchFailureCause , Object >>> patchingTuples = computePatchingTuples (request );
128131
129- groupedFieldMapperRegistry .aggregatedPatch ()
132+ List <SinglePatchResult > groupedFieldsSinglePatchResults = groupedFieldMapperRegistry .aggregatedPatch (from (request ));
133+ Set <String > alreadyProcessedFields =
134+ groupedFieldsSinglePatchResults .stream ().map (SinglePatchResult ::getFieldName ).collect (Collectors .toSet ());
130135
131136 // TODO: patchingTuples (transform to map ?) must be passed to the group field handler so that it can be handled.
132137 // TODO: provide only the valid one as simple object ? Once this is done the actual dictionary must be not contain does anymore
133138
134- List <de .symeda .sormas .api .patch .SinglePatchResult > results = patchingTuples .stream ().map (entry -> {
135- String fullFieldName = entry .getFirst ();
136- de .symeda .sormas .api .patch .SinglePatchResult singlePatchResult = new de .symeda .sormas .api .patch .SinglePatchResult ().setFieldName (fullFieldName );
137-
138- Supplier <Object > target = () -> findAppropriateTarget (fullFieldName , caseData , personSupplier );
139-
140- try {
141- return invalidFieldResult (entry ).or (() -> fieldMappingResult (entry , disease , request , target ))
142- .orElseGet (() -> valueMappingResult (entry , disease , request , target ));
143- } catch (RuntimeException e ) {
144- logger .error ("Failure during patch operation" , e );
145- return singlePatchResult
146- .setFailure (new DataPatchFailure ().setDataPatchFailureCause (DataPatchFailureCause .TECHNICAL ).setDescription (e .getMessage ()));
147- }
139+ List <de .symeda .sormas .api .patch .SinglePatchResult > results =
140+ Stream .concat (patchingTuples .stream ().filter (tuple -> !alreadyProcessedFields .contains (tuple .getFirst ())).map (entry -> {
141+ String fullFieldName = entry .getFirst ();
142+ de .symeda .sormas .api .patch .SinglePatchResult singlePatchResult =
143+ new de .symeda .sormas .api .patch .SinglePatchResult ().setFieldName (fullFieldName );
144+
145+ Supplier <Object > target = () -> findAppropriateTarget (fullFieldName , caseData , personSupplier );
146+
147+ try {
148+ return invalidFieldResult (entry ).or (() -> fieldMappingResult (entry , disease , request , target ))
149+ .orElseGet (() -> valueMappingResult (entry , disease , request , target ));
150+ } catch (RuntimeException e ) {
151+ logger .error ("Failure during patch operation" , e );
152+ return singlePatchResult
153+ .setFailure (new DataPatchFailure ().setDataPatchFailureCause (DataPatchFailureCause .TECHNICAL ).setDescription (e .getMessage ()));
154+ }
148155
149- } ).collect (Collectors .toList ());
156+ }), groupedFieldsSinglePatchResults . stream () ).collect (Collectors .toList ());
150157
151158 Map <String , Object > validPatchDictionary = buildDictionaryFor (results , de .symeda .sormas .api .patch .SinglePatchResult ::getValue , true );
152159 DataPatchResponse response = new DataPatchResponse ().setApplied (false )
@@ -168,6 +175,16 @@ public DataPatchResponse patch(CaseDataPatchRequest request) {
168175 return response .setApplied (true );
169176 }
170177
178+ private GroupedFieldsRequest from (CaseDataPatchRequest request ) {
179+ return new GroupedFieldsRequest ().setPartialPatchDictionary (request .getPatchDictionary ())
180+ .setInputLanguages (request .getInputLanguages ())
181+ .setOrigin (request .getOrigin ())
182+ .setAllowFallbackValues (request .isAllowFallbackValues ())
183+ .setPatchedInCaseOfFailures (request .isPatchedInCaseOfFailures ())
184+ .setReplacementStrategy (request .getReplacementStrategy ())
185+ .setEmptyValueBehavior (request .getEmptyValueBehavior ());
186+ }
187+
171188 private void saveDTOsIfAppropriate (Map <String , Object > validPatchDictionary , CaseDataDto caseData , Supplier <PersonDto > personSupplier ) {
172189 if (anyFieldPatchedWithPrefix (validPatchDictionary , PatchFieldHelper .CASE_DATA_PREFIX )) {
173190 logger .info ("CaseData was modified will be applied for: [{}]. Enable debug to see fully patched object" , caseData );
0 commit comments