2022-02-18 16:51:32 +01:00
|
|
|
package eu.eudat.logic.mapper.prefilling;
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
2023-11-06 15:17:57 +01:00
|
|
|
import eu.eudat.data.DescriptionEntity;
|
2023-10-27 17:46:34 +02:00
|
|
|
import eu.eudat.data.DescriptionTemplateEntity;
|
2023-11-14 12:41:57 +01:00
|
|
|
import eu.eudat.data.TagEntity;
|
2022-02-18 16:51:32 +01:00
|
|
|
import eu.eudat.logic.managers.DatasetManager;
|
|
|
|
import eu.eudat.logic.managers.DatasetProfileManager;
|
2024-01-05 17:32:24 +01:00
|
|
|
import eu.eudat.service.remotefetcher.config.entities.DefaultPrefillingMapping;
|
|
|
|
import eu.eudat.service.remotefetcher.config.entities.PrefillingFixedMapping;
|
|
|
|
import eu.eudat.service.remotefetcher.config.entities.PrefillingGet;
|
|
|
|
import eu.eudat.service.remotefetcher.config.entities.PrefillingMapping;
|
2024-01-18 09:28:16 +01:00
|
|
|
import eu.eudat.utilities.helpers.StreamDistinctBy;
|
2022-02-18 16:51:32 +01:00
|
|
|
import eu.eudat.logic.utilities.json.JsonSearcher;
|
2023-10-27 17:46:34 +02:00
|
|
|
import eu.eudat.commons.types.descriptiontemplate.fielddata.AutoCompleteDataEntity;
|
2022-02-18 16:51:32 +01:00
|
|
|
import eu.eudat.models.data.datasetprofile.DatasetProfileOverviewModel;
|
|
|
|
import eu.eudat.models.data.datasetwizard.DatasetWizardModel;
|
2024-01-08 11:58:00 +01:00
|
|
|
import eu.eudat.service.remotefetcher.models.ExternalAutocompleteFieldResult;
|
2022-02-22 14:53:25 +01:00
|
|
|
import org.json.JSONObject;
|
2023-07-03 16:09:15 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2023-10-06 17:07:58 +02:00
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.stereotype.Component;
|
2022-02-18 16:51:32 +01:00
|
|
|
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import java.lang.reflect.Method;
|
2022-02-21 16:38:16 +01:00
|
|
|
import java.time.LocalDate;
|
|
|
|
import java.time.format.DateTimeFormatter;
|
2022-02-18 16:51:32 +01:00
|
|
|
import java.util.*;
|
|
|
|
import java.util.stream.Collectors;
|
2023-11-02 17:37:12 +01:00
|
|
|
import eu.eudat.commons.enums.FieldType;
|
2022-02-18 16:51:32 +01:00
|
|
|
|
2023-10-06 17:07:58 +02:00
|
|
|
@Component
|
2022-02-18 16:51:32 +01:00
|
|
|
public class PrefillingMapper {
|
2023-07-03 16:09:15 +02:00
|
|
|
private static final Logger logger = LoggerFactory.getLogger(PrefillingMapper.class);
|
2022-02-18 16:51:32 +01:00
|
|
|
private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
|
2023-10-06 17:07:58 +02:00
|
|
|
private final DatasetProfileManager datasetProfileManager;
|
2022-02-18 16:51:32 +01:00
|
|
|
|
2023-10-06 17:07:58 +02:00
|
|
|
@Autowired
|
|
|
|
public PrefillingMapper(DatasetProfileManager datasetProfileManager) {
|
|
|
|
this.datasetProfileManager = datasetProfileManager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map<String, Object> prefilledEntity, PrefillingGet prefillingGet, String type,
|
2024-01-04 11:55:42 +01:00
|
|
|
DescriptionTemplateEntity profile, DatasetManager datasetManager /*, LicenseManager licenseManager*/) throws Exception {
|
2022-02-18 16:51:32 +01:00
|
|
|
DatasetWizardModel datasetWizardModel = new DatasetWizardModel();
|
|
|
|
datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile));
|
2023-11-06 15:17:57 +01:00
|
|
|
DescriptionEntity descriptionEntity = new DescriptionEntity();
|
2023-11-07 13:53:36 +01:00
|
|
|
//descriptionEntity.setDescriptionTemplateId(profile.getId()); //TODO
|
2022-02-18 16:51:32 +01:00
|
|
|
Map<String, Object> properties = new HashMap<>();
|
2023-11-06 15:17:57 +01:00
|
|
|
JsonNode parentNode = mapper.readTree(mapper.writeValueAsString(datasetManager.getPagedProfile(datasetWizardModel, descriptionEntity)));
|
2022-02-18 16:51:32 +01:00
|
|
|
for (DefaultPrefillingMapping prefillingMapping: prefillingGet.getMappings()) {
|
|
|
|
List<String> sourceKeys = Arrays.asList(prefillingMapping.getSource().split("\\."));
|
|
|
|
Object sourceValue = null;
|
|
|
|
for (String sourceKey: sourceKeys) {
|
|
|
|
if (sourceValue == null) {
|
|
|
|
sourceValue = prefilledEntity.get(sourceKey);
|
|
|
|
} else if (sourceValue instanceof Map) {
|
|
|
|
sourceValue = ((Map)sourceValue).get(sourceKey);
|
|
|
|
}
|
|
|
|
}
|
2023-07-20 12:00:24 +02:00
|
|
|
try {
|
2024-01-04 11:55:42 +01:00
|
|
|
setValue(prefillingMapping, mapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties, type/*, licenseManager*/);
|
2023-07-20 12:00:24 +02:00
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
if (prefillingMapping.getSemanticTarget() != null && !prefillingMapping.getSemanticTarget().isEmpty()) {
|
|
|
|
logger.warn("Couldn't map " + prefillingMapping.getSemanticTarget());
|
|
|
|
}
|
|
|
|
else if (prefillingMapping.getTarget() != null && !prefillingMapping.getTarget().isEmpty()) {
|
|
|
|
logger.warn("Couldn't map " + prefillingMapping.getTarget());
|
|
|
|
}
|
|
|
|
}
|
2022-02-18 16:51:32 +01:00
|
|
|
}
|
|
|
|
for (PrefillingFixedMapping fixedMapping: prefillingGet.getFixedMappings()) {
|
2024-01-04 11:55:42 +01:00
|
|
|
setValue(fixedMapping, fixedMapping.getValue(), datasetWizardModel, parentNode, properties, type/*, licenseManager*/);
|
2022-02-18 16:51:32 +01:00
|
|
|
}
|
2023-11-06 15:17:57 +01:00
|
|
|
descriptionEntity.setProperties(mapper.writeValueAsString(properties));
|
|
|
|
datasetWizardModel.setDatasetProfileDefinition(datasetManager.getPagedProfile(datasetWizardModel, descriptionEntity));
|
2022-02-18 16:51:32 +01:00
|
|
|
return datasetWizardModel;
|
|
|
|
}
|
|
|
|
|
2024-01-04 11:55:42 +01:00
|
|
|
private void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map<String, Object> properties, String type/*, LicenseManager licenseManager*/) throws InvocationTargetException, IllegalAccessException, JsonProcessingException {
|
2022-02-22 13:15:51 +01:00
|
|
|
String trimRegex = prefillingMapping.getTrimRegex() != null ? prefillingMapping.getTrimRegex() : "";
|
|
|
|
if (!value.startsWith("\"") && !value.startsWith("[") && !value.equals("null")) {
|
|
|
|
value = "\"" + value + "\"";
|
|
|
|
}
|
|
|
|
JsonNode valueNode = mapper.readTree(value);
|
|
|
|
List<String> parsedValues = new ArrayList<>();
|
2022-03-15 16:55:40 +01:00
|
|
|
if (valueNode.isArray() && (valueNode.get(0) != null && !valueNode.get(0).isTextual())) {
|
2022-02-22 13:15:51 +01:00
|
|
|
if (prefillingMapping.getSubSource() == null || prefillingMapping.getSubSource().isEmpty()) {
|
|
|
|
throw new IllegalArgumentException("Source value is an array but no subSource field have been set");
|
|
|
|
}
|
|
|
|
String parsedValue;
|
|
|
|
for(int i = 0; i < valueNode.size(); i++){
|
|
|
|
JsonNode jsonObj = valueNode.get(i);
|
|
|
|
String subSource = jsonObj.get(prefillingMapping.getSubSource()).asText();
|
|
|
|
parsedValue = subSource.replaceAll(trimRegex, "");
|
|
|
|
parsedValues.add(parsedValue);
|
|
|
|
}
|
|
|
|
parsedValues = parsedValues.stream().distinct().collect(Collectors.toList());
|
|
|
|
}
|
|
|
|
String parsedValue = null;
|
|
|
|
if (valueNode.isTextual()) {
|
|
|
|
parsedValue = valueNode.textValue().replace(trimRegex, "");
|
2022-03-15 16:55:40 +01:00
|
|
|
}else if (valueNode.isArray() && (valueNode.get(0) != null && valueNode.get(0).isTextual())) {
|
2022-02-22 13:15:51 +01:00
|
|
|
List<String> values = new LinkedList<>();
|
|
|
|
for (int i = 0; i < valueNode.size(); i++) {
|
|
|
|
values.add(valueNode.get(i).textValue().replace(trimRegex, ""));
|
|
|
|
}
|
|
|
|
parsedValue = String.join(", ", values);
|
|
|
|
}
|
|
|
|
|
2022-02-18 16:51:32 +01:00
|
|
|
if (prefillingMapping.getTarget() != null) {
|
|
|
|
try {
|
|
|
|
String methodName = "set" + prefillingMapping.getTarget().substring(0, 1).toUpperCase(Locale.ROOT) + prefillingMapping.getTarget().substring(1);
|
|
|
|
Method setterMethod = Arrays.stream(DatasetWizardModel.class.getDeclaredMethods())
|
|
|
|
.filter(method -> method.getName().equals(methodName)).collect(Collectors.toList()).get(0);
|
|
|
|
Class<?>[] params = setterMethod.getParameterTypes();
|
|
|
|
//GK: Tags Special logic
|
2022-02-22 13:15:51 +01:00
|
|
|
if (parsedValue != null && !parsedValue.equals("null") && prefillingMapping.getTarget().equals("tags")) {
|
|
|
|
parsedValue = mapper.valueToTree(parseTags(parsedValue)).toString();
|
2023-07-14 12:47:01 +02:00
|
|
|
}
|
|
|
|
else if(!parsedValues.isEmpty() && prefillingMapping.getTarget().equals("tags")) {
|
|
|
|
parsedValue = mapper.valueToTree(parseTags(String.join(", ", parsedValues))).toString();
|
|
|
|
}
|
|
|
|
else {
|
2022-02-22 13:15:51 +01:00
|
|
|
parsedValue = mapper.valueToTree(parsedValue).toString();
|
2022-02-18 16:51:32 +01:00
|
|
|
}
|
2022-02-22 13:15:51 +01:00
|
|
|
setterMethod.invoke(datasetWizardModel, mapper.readValue(parsedValue, params[0]));
|
2022-02-18 16:51:32 +01:00
|
|
|
}catch (InvocationTargetException | IllegalAccessException | JsonProcessingException e) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
} else {
|
2023-06-22 12:47:01 +02:00
|
|
|
List<JsonNode> nodes = JsonSearcher.findNodes(parentNode, "schematics", prefillingMapping.getSemanticTarget());
|
2022-02-22 10:58:39 +01:00
|
|
|
|
2022-02-22 14:53:25 +01:00
|
|
|
// zenodo prefilling customizations
|
|
|
|
if(type.equals("zenodo")){
|
2023-06-22 12:47:01 +02:00
|
|
|
if(prefillingMapping.getSemanticTarget().equals("rda.dataset.distribution.data_access")){
|
2022-02-22 14:53:25 +01:00
|
|
|
if(parsedValue != null && parsedValue.equals("open")){
|
2023-02-21 11:44:48 +01:00
|
|
|
List<JsonNode> issuedNodes = JsonSearcher.findNodes(parentNode, "schematics", "rda.dataset.issued");
|
2022-02-22 14:53:25 +01:00
|
|
|
if(!issuedNodes.isEmpty()){
|
|
|
|
String issuedIdNode = issuedNodes.get(0).get("id").asText();
|
|
|
|
String issuedValue = (String) properties.get(issuedIdNode);
|
2023-02-21 11:44:48 +01:00
|
|
|
List<JsonNode> licStartDateNodes = JsonSearcher.findNodes(parentNode, "schematics", "rda.dataset.distribution.license.start_date");
|
2022-02-22 14:53:25 +01:00
|
|
|
for (JsonNode licStartDateNode : licStartDateNodes) {
|
|
|
|
String licStartDateId = licStartDateNode.get(0) != null ? licStartDateNode.get(0).get("id").asText() : licStartDateNode.get("id").asText();
|
|
|
|
properties.put(licStartDateId, issuedValue);
|
|
|
|
}
|
|
|
|
}
|
2022-02-22 10:58:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-22 12:47:01 +02:00
|
|
|
if (prefillingMapping.getSemanticTarget().equals("rda.dataset.distribution.available_until") && parsedValue != null && !parsedValue.equals("null")) {
|
2022-02-22 14:53:25 +01:00
|
|
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
|
|
|
|
LocalDate date = LocalDate.parse(parsedValue, formatter);
|
|
|
|
date = date.plusYears(20);
|
|
|
|
parsedValue = date.toString();
|
|
|
|
}
|
2022-02-18 16:51:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for (JsonNode node: nodes) {
|
|
|
|
String id = node.isArray() ? node.get(0).get("id").asText() : node.get("id").asText();
|
|
|
|
String renderStyle = node.isArray() ? node.get(0).get("viewStyle").get("renderStyle").asText() : node.get("viewStyle").get("renderStyle").asText();
|
|
|
|
|
2023-11-02 17:37:12 +01:00
|
|
|
switch (FieldType.of(renderStyle)) {
|
2022-02-18 16:51:32 +01:00
|
|
|
case COMBO_BOX:
|
|
|
|
if (parsedValues.isEmpty())
|
|
|
|
parsedValues.add(parsedValue);
|
2022-03-01 16:11:14 +01:00
|
|
|
if (!parsedValues.stream().allMatch(Objects::isNull)) {
|
|
|
|
properties.put(id, parseComboBoxValues(node, parsedValues));
|
|
|
|
}
|
2022-02-18 16:51:32 +01:00
|
|
|
break;
|
|
|
|
case TAGS:
|
2023-07-14 12:47:01 +02:00
|
|
|
if(parsedValues.isEmpty()) {
|
|
|
|
properties.put(id, mapper.valueToTree(parseTags(parsedValue)).toString());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
properties.put(id, mapper.valueToTree(parseTags(String.join(", ", parsedValues))).toString());
|
|
|
|
}
|
2022-02-18 16:51:32 +01:00
|
|
|
break;
|
2022-02-22 14:53:25 +01:00
|
|
|
case DATASET_IDENTIFIER:
|
|
|
|
JSONObject datasetID = new JSONObject();
|
|
|
|
datasetID.put("identifier", parsedValue);
|
|
|
|
if(type.equals("zenodo")){
|
|
|
|
datasetID.put("type", "doi");
|
|
|
|
}
|
|
|
|
properties.put(id, datasetID.toString());
|
|
|
|
break;
|
2022-05-04 10:11:25 +02:00
|
|
|
case LICENSES:
|
2024-01-04 11:55:42 +01:00
|
|
|
// try {
|
|
|
|
// List<LicenseModel> licenses = licenseManager.getLicenses("", "");
|
|
|
|
// String finalParsedValue = parsedValue;
|
|
|
|
// licenses = licenses.stream().filter(license -> license.getPid().equals(finalParsedValue)).collect(Collectors.toList());
|
|
|
|
// boolean isMultiAutocomplete = node.isArray() ? node.get(0).get("data").get("multiAutoComplete").booleanValue() : node.get("data").get("multiAutoComplete").booleanValue();
|
|
|
|
// if(isMultiAutocomplete){
|
|
|
|
// List<String> lic = new ArrayList<>();
|
|
|
|
// for(LicenseModel license: licenses){
|
|
|
|
// lic.add(mapper.writeValueAsString(license));
|
|
|
|
// }
|
|
|
|
// properties.put(id, mapper.writeValueAsString(lic));
|
|
|
|
// } else {
|
|
|
|
// properties.put(id, mapper.writeValueAsString(licenses.get(0)));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// catch (MyNotFoundException | HugeResultSetException e){
|
|
|
|
// properties.put(id, parsedValue);
|
|
|
|
// }
|
2022-05-04 10:11:25 +02:00
|
|
|
break;
|
2022-02-18 16:51:32 +01:00
|
|
|
default:
|
|
|
|
if (!parsedValues.isEmpty())
|
|
|
|
properties.put(id, String.join(", ", parsedValues));
|
2022-02-21 16:38:16 +01:00
|
|
|
else {
|
2022-02-22 10:58:39 +01:00
|
|
|
properties.put(id, parsedValue);
|
2022-02-21 16:38:16 +01:00
|
|
|
}
|
2022-02-18 16:51:32 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-06 17:07:58 +02:00
|
|
|
private Object parseComboBoxValues(JsonNode node, List<String> parsedValues) throws JsonProcessingException {
|
2022-02-18 16:51:32 +01:00
|
|
|
List<Object> normalizedValues = new ArrayList<>();
|
|
|
|
boolean isMultiSelect;
|
|
|
|
String type = node.isArray() ? node.get(0).get("data").get("type").asText() : node.get("data").get("type").asText();
|
|
|
|
if(type.equals("autocomplete")) {
|
|
|
|
JsonNode dataNode = node.isArray() ? node.get(0).get("data") : node.get("data");
|
2023-10-27 17:46:34 +02:00
|
|
|
AutoCompleteDataEntity autoCompleteDataEntity = mapper.treeToValue(dataNode, AutoCompleteDataEntity.class);
|
|
|
|
isMultiSelect = autoCompleteDataEntity.getMultiAutoComplete();
|
2022-02-18 16:51:32 +01:00
|
|
|
for (String format : parsedValues) {
|
2024-01-08 11:58:00 +01:00
|
|
|
List<ExternalAutocompleteFieldResult> result = new ArrayList<>();
|
2023-06-26 13:16:41 +02:00
|
|
|
try {
|
2023-10-27 17:46:34 +02:00
|
|
|
result = datasetProfileManager.getAutocomplete(autoCompleteDataEntity, format);
|
2023-06-26 13:16:41 +02:00
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
logger.error(e.getMessage(), e);
|
|
|
|
}
|
2024-01-08 11:58:00 +01:00
|
|
|
result = result.stream().filter(StreamDistinctBy.distinctByKey(ExternalAutocompleteFieldResult::getId)).collect(Collectors.toList());
|
2022-02-18 16:51:32 +01:00
|
|
|
if(!result.isEmpty()){
|
|
|
|
List<String> tempValues = new LinkedList<>();
|
2024-01-08 11:58:00 +01:00
|
|
|
for (ExternalAutocompleteFieldResult f : result) {
|
2022-02-18 16:51:32 +01:00
|
|
|
if (format.equals(f.getId()) || f.getLabel().toUpperCase(Locale.ROOT).contains(format.toUpperCase(Locale.ROOT)))
|
|
|
|
tempValues.add(mapper.valueToTree(f).toString());
|
|
|
|
}
|
|
|
|
if (isMultiSelect)
|
|
|
|
normalizedValues.addAll(tempValues);
|
|
|
|
else if (!tempValues.isEmpty())
|
|
|
|
normalizedValues.add(tempValues.get(0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return !normalizedValues.isEmpty() ? (isMultiSelect ? normalizedValues : normalizedValues.get(0)) : null;
|
|
|
|
} else {
|
|
|
|
JsonNode optionsNode = node.isArray() ? node.get(0).get("data").get("options") : node.get("data").get("options");
|
|
|
|
isMultiSelect = node.isArray() ? node.get(0).get("data").get("multiList").booleanValue() : node.get("data").get("multiList").booleanValue();
|
|
|
|
for (int i = 0; i < optionsNode.size(); i++) {
|
|
|
|
String value = optionsNode.get(i).get("value").textValue();
|
|
|
|
if (parsedValues.contains(value)) {
|
|
|
|
normalizedValues.add(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
List<String> normalizedStringValues = normalizedValues.stream().map(Object::toString).collect(Collectors.toList());
|
|
|
|
|
|
|
|
return !normalizedValues.isEmpty() ? (isMultiSelect ? String.join(", ", normalizedStringValues) : normalizedValues.get(0)) : null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-14 12:41:57 +01:00
|
|
|
private static List<TagEntity> parseTags(String value) throws JsonProcessingException {
|
2022-02-22 12:39:52 +01:00
|
|
|
if (value == null || value.isEmpty())
|
2022-02-22 13:00:22 +01:00
|
|
|
return new LinkedList<>();
|
2022-02-22 13:15:51 +01:00
|
|
|
String[] rawTags = value.split(", ");
|
2023-11-14 12:41:57 +01:00
|
|
|
List<TagEntity> parsedTags = new LinkedList<>();
|
2022-02-22 13:15:51 +01:00
|
|
|
for (String rawTag : rawTags) {
|
2023-11-14 12:41:57 +01:00
|
|
|
parsedTags.add(new TagEntity());
|
2022-02-18 16:51:32 +01:00
|
|
|
}
|
|
|
|
return parsedTags;
|
|
|
|
}
|
|
|
|
}
|