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; import eu.eudat.data.entities.Dataset; import eu.eudat.data.entities.DatasetProfile; import eu.eudat.elastic.entities.Tag; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.proxy.config.entities.DefaultPrefillingMapping; import eu.eudat.logic.proxy.config.entities.PrefillingFixedMapping; import eu.eudat.logic.proxy.config.entities.PrefillingGet; import eu.eudat.logic.proxy.config.entities.PrefillingMapping; import eu.eudat.logic.utilities.helpers.StreamDistinctBy; import eu.eudat.logic.utilities.json.JsonSearcher; import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; import eu.eudat.models.data.datasetprofile.DatasetProfileOverviewModel; import eu.eudat.models.data.datasetprofile.RenderStyle; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.*; import java.util.stream.Collectors; public class PrefillingMapper { private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); public static DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, DatasetProfile profile, DatasetManager datasetManager) throws Exception { DatasetWizardModel datasetWizardModel = new DatasetWizardModel(); datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile)); Dataset dataset = new Dataset(); dataset.setProfile(profile); Map properties = new HashMap<>(); JsonNode parentNode = mapper.readTree(mapper.writeValueAsString(datasetManager.getPagedProfile(datasetWizardModel, dataset))); for (DefaultPrefillingMapping prefillingMapping: prefillingGet.getMappings()) { List 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); } } setValue(prefillingMapping, mapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties); } for (PrefillingFixedMapping fixedMapping: prefillingGet.getFixedMappings()) { setValue(fixedMapping, fixedMapping.getValue(), datasetWizardModel, parentNode, properties); } dataset.setProperties(mapper.writeValueAsString(properties)); datasetWizardModel.setDatasetProfileDefinition(datasetManager.getPagedProfile(datasetWizardModel, dataset)); return datasetWizardModel; } private static void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map properties) throws InvocationTargetException, IllegalAccessException, JsonProcessingException { 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 if (!value.equals("null") && prefillingMapping.getTarget().equals("tags")) { value = mapper.valueToTree(parseTags(value)).toString(); } setterMethod.invoke(datasetWizardModel, mapper.readValue(value, params[0])); }catch (InvocationTargetException | IllegalAccessException | JsonProcessingException e) { throw e; } } else { List nodes = JsonSearcher.findNodes(parentNode, "rdaProperty", prefillingMapping.getMaDmpTarget()); /*if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.available_until") && !value.equals("null")){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd"); LocalDate date = LocalDate.parse(value.replace("\"", ""), formatter); date = date.plusYears(20); value = date.toString(); }*/ String trimRegex = prefillingMapping.getTrimRegex() != null ? prefillingMapping.getTrimRegex() : ""; if (!value.startsWith("\"") && !value.startsWith("[") && !value.equals("null")) { value = "\"" + value + "\""; } JsonNode valueNode = mapper.readTree(value); List parsedValues = new ArrayList<>(); if (valueNode.isArray()) { 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, ""); } 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(); switch (RenderStyle.fromValue(renderStyle)) { case COMBO_BOX: if (parsedValues.isEmpty()) parsedValues.add(parsedValue); properties.put(id, parseComboBoxValues(node, parsedValues)); break; case TAGS: properties.put(id, parseTags(parsedValue)); break; default: if (!parsedValues.isEmpty()) properties.put(id, String.join(", ", parsedValues)); else properties.put(id, parsedValue); break; } /*if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.data_access")){ value = value.replace("\"", ""); if(value.equals("open")){ properties.put(id, value); } else if(value.equals("restricted")){ properties.put(id, "shared"); } else{ properties.put(id, "closed"); } }*/ } } } private static Object parseComboBoxValues(JsonNode node, List parsedValues) throws JsonProcessingException { List 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"); AutoCompleteData autoCompleteData = mapper.treeToValue(dataNode, AutoCompleteData.class); isMultiSelect = autoCompleteData.getMultiAutoComplete(); for (String format : parsedValues) { List result = DatasetProfileManager.getAutocomplete(autoCompleteData, format); result = result.stream().filter(StreamDistinctBy.distinctByKey(ExternalAutocompleteFieldModel::getId)).collect(Collectors.toList()); if(!result.isEmpty()){ List tempValues = new LinkedList<>(); for (ExternalAutocompleteFieldModel f : result) { 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 normalizedStringValues = normalizedValues.stream().map(Object::toString).collect(Collectors.toList()); return !normalizedValues.isEmpty() ? (isMultiSelect ? String.join(", ", normalizedStringValues) : normalizedValues.get(0)) : null; } } private static List parseTags(String value) throws JsonProcessingException { JsonNode rawTags = mapper.readTree(value); List parsedTags = new LinkedList<>(); if (rawTags.isArray()) { for (int i = 0; i < rawTags.size(); i++) { parsedTags.add(new Tag(rawTags.get(i).textValue(), rawTags.get(i).textValue())); } } else if (rawTags.isTextual()){ List tags = Arrays.asList(rawTags.textValue().split(", ")); parsedTags.addAll(tags.stream().map(s -> new Tag(s, s)).collect(Collectors.toList())); } return parsedTags; } }