diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java index 3d6c11aeb..c6c9b71f3 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetAll.java @@ -9,25 +9,34 @@ import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; @ApiModel(description = "Ответ при получении объектов словаря.") public class DictionaryBackendGetAll extends BasicSpcexResponse { @JsonProperty @ApiModelProperty(value = "Полезная нагрузка") - private DictionaryBackendPayload payload = new DictionaryBackendPayload(); + private IDictionaryPayload payload; public void fromEntity(Collection dictionaryValues) { - var payload = this.getPayload(); + this.payload = new GeneralDictionaryBackendPayload(); + GeneralDictionaryBackendPayload castedPayload = (GeneralDictionaryBackendPayload) payload; for (AbstractDictionary dictionaryValue : dictionaryValues) { var singleItem = new DictionaryBackendGetFields(); singleItem.fromEntity(dictionaryValue); - payload.getItems().add(singleItem); + castedPayload.getItems().add(singleItem); } } + public void addMap(Map m) { + if (this.payload == null) { + this.payload = new SpecificDictionaryBackendPayload(); + } + SpecificDictionaryBackendPayload payloadCasted = (SpecificDictionaryBackendPayload) this.payload; + payloadCasted.getItems().add(m); + } - private static class DictionaryBackendPayload { + public static class GeneralDictionaryBackendPayload implements IDictionaryPayload { private List items = new ArrayList<>(); public List getItems() { @@ -39,11 +48,24 @@ public class DictionaryBackendGetAll extends BasicSpcexResponse { } } - public DictionaryBackendPayload getPayload() { + public static class SpecificDictionaryBackendPayload implements IDictionaryPayload { + @JsonProperty + private List> items = new ArrayList<>(); + + public List> getItems() { + return items; + } + + public void setItems(List> items) { + this.items = items; + } + } + + public IDictionaryPayload getPayload() { return payload; } - public void setPayload(DictionaryBackendPayload payload) { + public void setPayload(IDictionaryPayload payload) { this.payload = payload; } } \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java index fa27898c9..eb91fba9a 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetFields.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.annotations.ApiModelProperty; import ru.clearing.platform.dictionary.AbstractDictionary; -public class DictionaryBackendGetFields { +public class DictionaryBackendGetFields implements IDictionaryPayload { @JsonProperty @ApiModelProperty(value = "Идентификатор", example = "1234") private Long id; diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetSingleValueV2.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetSingleValueV2.java new file mode 100644 index 000000000..4db4ef922 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/DictionaryBackendGetSingleValueV2.java @@ -0,0 +1,25 @@ +package ru.spcex.clearing.backendapi.controller.response.entity.dictionary; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; + +import java.util.HashMap; +import java.util.Map; + +@ApiModel(description = "Ответ при получении объекта словаря.") +public class DictionaryBackendGetSingleValueV2 extends BasicSpcexResponse { + + @JsonProperty + @ApiModelProperty(value = "Поля объекта") + private Map payload = new HashMap<>(); + + public Map getPayload() { + return payload; + } + + public void setPayload(Map payload) { + this.payload = payload; + } +} \ No newline at end of file diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/IDictionaryPayload.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/IDictionaryPayload.java new file mode 100644 index 000000000..2cba7bac3 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/response/entity/dictionary/IDictionaryPayload.java @@ -0,0 +1,4 @@ +package ru.spcex.clearing.backendapi.controller.response.entity.dictionary; + +public interface IDictionaryPayload { +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java index 425bd1876..138735915 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/controller/system/DictionaryController.java @@ -13,10 +13,11 @@ import org.springframework.web.bind.annotation.*; import ru.clearing.platform.dictionary.AbstractDictionary; import ru.spcex.clearing.backendapi.controller.response.BasicSpcexResponse; import ru.spcex.clearing.backendapi.controller.response.entity.dictionary.DictionaryBackendGetAll; -import ru.spcex.clearing.backendapi.controller.response.entity.dictionary.DictionaryBackendGetSingleValue; +import ru.spcex.clearing.backendapi.controller.response.entity.dictionary.DictionaryBackendGetSingleValueV2; import ru.spcex.clearing.backendapi.errors.ActionValidationException; import ru.spcex.clearing.backendapi.errors.BackEndError; import ru.spcex.clearing.backendapi.errors.NotFound404Exception; +import ru.spcex.clearing.backendapi.meta.GetResponseFactory; import ru.spcex.platform.classes.base.SpcexObjectBase; import ru.spcex.platform.imdg.api.Imdg; import ru.spcex.platform.imdg.api.ImdgProvider; @@ -33,10 +34,12 @@ public class DictionaryController { private final Logger log = LoggerFactory.getLogger(getClass()); private final Map> allDictionaryMaps; private final ImdgProvider imdgProvider; + private final GetResponseFactory responseFactory; @Autowired - public DictionaryController(ImdgProvider imdgProvider) { + public DictionaryController(ImdgProvider imdgProvider, GetResponseFactory responseFactory) { this.imdgProvider = imdgProvider; + this.responseFactory = responseFactory; this.allDictionaryMaps = new ConcurrentHashMap<>(); } @@ -49,39 +52,42 @@ public class DictionaryController { Imdg dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class); Collection allValues = dictionary.getAllValues(); DictionaryBackendGetAll response = new DictionaryBackendGetAll(); - response.fromEntity(allValues); + for (AbstractDictionary val : allValues) { + Map fromMeta = responseFactory.responseFromDictionary(dictionaryName, val); + response.addMap(fromMeta); + } return response; } @ApiOperation(value = "get dictionary value by id.") - @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValue.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValueV2.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) @RequestMapping(value = "/{dictionary-name}/{id}", method = RequestMethod.GET) @ResponseBody - public DictionaryBackendGetSingleValue getById(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide") + public DictionaryBackendGetSingleValueV2 getById(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide") @PathVariable("dictionary-name") String dictionaryName, @ApiParam(value = "Идентификатор объекта", required = true, example = "1234") @PathVariable("id") Long id) { Imdg dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class); AbstractDictionary value = dictionary.getSingleObjectByID(id); if (value == null) throw new NotFound404Exception(dictionaryName + " id='" + id + "'"); - DictionaryBackendGetSingleValue response = new DictionaryBackendGetSingleValue(); - response.fromEntity(value); + DictionaryBackendGetSingleValueV2 response = new DictionaryBackendGetSingleValueV2(); + response.setPayload(responseFactory.responseFromDictionary(dictionaryName, value)); return response; } @ApiOperation(value = "get dictionary value by code.") - @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValue.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) + @ApiResponses(value = {@ApiResponse(code = 200, message = "OK", response = DictionaryBackendGetSingleValueV2.class), @ApiResponse(code = 400, message = "Ошибка валидации", response = BasicSpcexResponse.class)}) @RequestMapping(value = "/{dictionary-name}/code/{code}", method = RequestMethod.GET) @ResponseBody - public DictionaryBackendGetSingleValue getByCode(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide") + public DictionaryBackendGetSingleValueV2 getByCode(@ApiParam(value = "Название словаря", required = true, example = "moneyFlowSide") @PathVariable("dictionary-name") String dictionaryName, @ApiParam(value = "Код словаря", required = true, example = "1234") @PathVariable("code") String code) { Imdg dictionary = extractDictionaryImdgFromUrlParameter(dictionaryName, AbstractDictionary.class); AbstractDictionary value = dictionary.getSingleObjectByFieldValues(Map.of("code", code)); if (value == null) throw new NotFound404Exception(dictionaryName + " code='" + code + "'"); - DictionaryBackendGetSingleValue response = new DictionaryBackendGetSingleValue(); - response.fromEntity(value); + DictionaryBackendGetSingleValueV2 response = new DictionaryBackendGetSingleValueV2(); + response.setPayload(responseFactory.responseFromDictionary(dictionaryName, value)); return response; } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingDictionaryExtracted.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingDictionaryExtracted.java new file mode 100644 index 000000000..dabb4f653 --- /dev/null +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ClearingDictionaryExtracted.java @@ -0,0 +1,22 @@ +package ru.spcex.clearing.backendapi.meta; + +import java.util.List; + +public class ClearingDictionaryExtracted extends ObjectExtracted { + + public ClearingDictionaryExtracted(String clazz, List actionFields) { + for (ActionField field : actionFields) { + if (field.getVirtual() != null && field.isVirtual()){ + continue; + } + FieldExtracted fe = getImplFieldExtracted(field); + fields.add(fe); + fieldByCode.put(field.getCode(), fe); + } + } + + @Override + public FieldExtracted getImplFieldExtracted(ActionField field) { + return new ClearingFieldExtracted(field); + } +} diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java index 86f3cb2c1..e6e23ff8d 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/GetResponseFactory.java @@ -31,11 +31,26 @@ public class GetResponseFactory { .collect(Collectors.toList()); } + /** + * dictionaryName - это имя тэга внутри + */ + public Map responseFromDictionary(String dictionaryName, Object o) { + ObjectExtracted objectExtracted = meta.getEnumsExtractedByTagName().get(dictionaryName); + if (objectExtracted == null) { + throw new RuntimeException("cannot find dictionary in meta for " + dictionaryName); + } + return responseFromObjectExtracted(o, objectExtracted); + } + public Map responseFromObject(Object o) { ObjectExtracted objExtr = meta.getObjectsExtractedByClazz().get(o.getClass().getCanonicalName()); if (objExtr == null) { throw new RuntimeException("cannot find object in meta for " + o.getClass().getCanonicalName()); } + return responseFromObjectExtracted(o, objExtr); + } + + private Map responseFromObjectExtracted(Object o, ObjectExtracted objExtr) { Map r = new LinkedHashMap<>(); FieldExtracted currentField = null; try { diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java index be7392a9b..452a5e9af 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/MetaServer.java @@ -2,6 +2,7 @@ package ru.spcex.clearing.backendapi.meta; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ru.spcex.platform.utils.log.ExceptionUtils; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -17,6 +18,8 @@ public class MetaServer extends MetaBase { private Map objectsExtractedByDestination; private Map actionObjectsExtracted; private Map objectElementByDestination; + private Map enumsExtractedByTagName; + private final static Set dictionaryDefaultFields = Set.of("id", "code", "name"); protected ObjectExtracted getImplInstanceObjectExtracted(String clazz, List actionFields) { return new ClearingObjectExtracted(clazz, actionFields); @@ -31,6 +34,7 @@ public class MetaServer extends MetaBase { objectsExtractedByClazz = new ConcurrentHashMap<>(); objectsExtractedByDestination = new ConcurrentHashMap<>(); objectElementByDestination = new ConcurrentHashMap<>(); + enumsExtractedByTagName = new ConcurrentHashMap<>(); try { Map objects = getObjects(); log.info("Meta objects:\n{}", @@ -84,6 +88,37 @@ public class MetaServer extends MetaBase { } catch (Throwable e) { throw new ClearingMetaServerValidationException(e.getLocalizedMessage()); } + try { + Map enums = getEnums(); + for (String key : enums.keySet()) { + ObjectExtracted oe; + ObjectEnumElement objectElement = enums.get(key); + try { + oe = new ClearingDictionaryExtracted(objectElement.getClazz(), objectElement.getFields()); + } catch (Throwable e) { + log.warn("{} {}", key, ExceptionUtils.getStackTrace(e)); + continue; + } + /** + * можно было бы хранить только для нестандартных словарей (где не только id, name, code) + */ +// List dictFields = oe.getFields(); +// boolean add = false; +// for (FieldExtracted dictField : dictFields) { +// if (!dictionaryDefaultFields.contains(dictField.getMemberName())) { +// add = true; +// break; +// } +// } +// if (add) { +// enumsExtractedByTagName.put(key, oe); +// } + enumsExtractedByTagName.put(key, oe); + } + + } catch (Throwable e) { + throw new ClearingMetaServerValidationException(e.getLocalizedMessage()); + } } for (ObjectExtracted o : this.objectsExtracted) { try { @@ -196,4 +231,8 @@ public class MetaServer extends MetaBase { } return partSize; } + + public Map getEnumsExtractedByTagName() { + return enumsExtractedByTagName; + } } diff --git a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ObjectExtracted.java b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ObjectExtracted.java index 5f75b9de5..8e4fc3cda 100644 --- a/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ObjectExtracted.java +++ b/clearing-parent/backend-api/src/main/java/ru/spcex/clearing/backendapi/meta/ObjectExtracted.java @@ -5,12 +5,14 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; public abstract class ObjectExtracted { - private String className; - private Class clazz; - private List fields = new LinkedList<>(); - private Map fieldByCode = new ConcurrentHashMap<>(); - private boolean isArray = false; + protected String className; + protected Class clazz; + protected List fields = new LinkedList<>(); + protected Map fieldByCode = new ConcurrentHashMap<>(); + protected boolean isArray = false; + public ObjectExtracted() { + } public ObjectExtracted(String clazz, List actionFields) { this.className = clazz;