package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.TextNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.Metadatum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; public class MetadataRDAMapper { private static final Logger logger = LoggerFactory.getLogger(MetadataRDAMapper.class); public static List toRDAList(List nodes) { Map rdaMap = new HashMap<>(); List rdas = new ArrayList<>(); for (JsonNode node: nodes) { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.metadata")){ rdaProperty = schematic.asText(); break; } } } else{ continue; } JsonNode rdaValue = node.get("value"); for (PropertyName propertyName: PropertyName.values()) { if (rdaProperty.contains(propertyName.getName())) { switch (propertyName) { case METADATA_STANDARD_ID: if (rdaValue instanceof ArrayNode) { try { ObjectMapper mapper = new ObjectMapper(); for (Iterator it = rdaValue.elements(); it.hasNext(); ) { JsonNode data = null; data = mapper.readTree(it.next().asText()); if (data.get("uri") != null) { rdas.add(new Metadatum()); rdas.get(rdas.size() - 1).setMetadataStandardId(MetadataStandardIdRDAMapper.toRDA(data.get("uri").asText())); rdas.get(rdas.size() - 1).setDescription(data.get("label").asText()); rdas.get(rdas.size() - 1).setAdditionalProperty("fieldId", node.get("id").asText()); rdas.get(rdas.size() - 1).setAdditionalProperty("valueId", data.get("id").asText()); rdaMap.put(data.get("uri").asText(), node.get("numbering").asText()); } } } catch (IOException e) { logger.error(e.getMessage(), e); } } else if (rdaValue instanceof TextNode && rdaProperty.contains("identifier") && !rdaValue.asText().isEmpty()) { rdas.add(new Metadatum()); rdas.get(rdas.size() - 1).setMetadataStandardId(MetadataStandardIdRDAMapper.toRDA(rdaValue.asText())); rdas.get(rdas.size() - 1).setAdditionalProperty("identifierId", node.get("id").asText()); rdaMap.put(rdaValue.asText(), node.get("numbering").asText()); } break; case DESCRIPTION: if (!rdaValue.asText().isEmpty()) { Metadatum rda = getRelative(rdas, rdaMap, node.get("numbering").asText()); if (rda != null) { rda.setDescription(rdaValue.asText()); rda.setAdditionalProperty("descriptionId", node.get("id").asText()); } else { rdas.stream().filter(rda1 -> rda1.getDescription() == null || rda1.getDescription().isEmpty()).forEach(rda1 -> rda1.setDescription(rdaValue.asText())); } } break; case LANGUAGE: String language = rdaValue.asText(); Metadatum.Language lang = Metadatum.Language.fromValue(language); Metadatum rda = getRelative(rdas, rdaMap, node.get("numbering").asText()); if (rda != null) { rda.setLanguage(lang); rda.setAdditionalProperty("languageId", node.get("id").asText()); } else { rdas.forEach(rda1 -> rda1.setLanguage(lang)); } break; } } } } return rdas; } public static Map toProperties(List rdas) { Map properties = new HashMap<>(); List standardIds = new ArrayList<>(); ObjectMapper mapper = new ObjectMapper(); rdas.forEach(rda -> { rda.getAdditionalProperties().entrySet().forEach(entry -> { try { switch (entry.getKey()) { case "fieldId": Map metadata = toMap(rda); standardIds.add(metadata); properties.put(entry.getValue().toString(), mapper.writeValueAsString(standardIds)); break; case "identifierId": properties.put(entry.getValue().toString(), rda.getMetadataStandardId().getIdentifier()); break; case "descriptionId": properties.put(entry.getValue().toString(), rda.getDescription()); break; case "languageId": if (rda.getLanguage() != null) { properties.put(entry.getValue().toString(), rda.getLanguage().value()); } break; } }catch (Exception e) { logger.error(e.getMessage(), e); } }); }); return properties; } public static Metadatum toRDA(JsonNode node) { Metadatum rda = new Metadatum(); String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.metadata")){ rdaProperty = schematic.asText(); break; } } } JsonNode rdaValue = node.get("value"); if (rdaProperty.contains("metadata_standard_id")) { if (rdaValue instanceof ArrayNode) { for (Iterator it = rdaValue.elements(); it.hasNext(); ) { JsonNode data = it.next(); if (data.get("uri") != null) { rda.setMetadataStandardId(MetadataStandardIdRDAMapper.toRDA(data.get("uri").asText())); } } } } else if (rdaProperty.contains("description")) { rda.setDescription(rdaValue.asText()); } else if (rdaProperty.contains("language")) { String language = rdaValue.asText(); Metadatum.Language lang = Metadatum.Language.fromValue(language); rda.setLanguage(lang); } return rda; } private static Metadatum getRelative(List rdas, Map rdaMap, String numbering) { String target = rdaMap.entrySet().stream().filter(entry -> MyStringUtils.getFirstDifference(entry.getValue(), numbering) > 0) .max(Comparator.comparingInt(entry -> MyStringUtils.getFirstDifference(entry.getValue(), numbering))).map(Map.Entry::getKey).orElse(""); return rdas.stream().filter(rda -> rda.getMetadataStandardId().getIdentifier().equals(target)).distinct().findFirst().orElse(null); } private enum PropertyName { METADATA_STANDARD_ID("metadata_standard_id"), DESCRIPTION("description"), LANGUAGE("language"); private final String name; PropertyName(String name) { this.name = name; } public String getName() { return name; } } private static Map toMap(Metadatum rda) { Map result = new HashMap<>(); ObjectMapper mapper = new ObjectMapper(); Map metadata = mapper.convertValue(rda, Map.class); Map additionalProperties = mapper.convertValue(metadata.get("additional_properties"), Map.class); String id = additionalProperties.remove("valueId"); additionalProperties.clear(); additionalProperties.put("id", id); Map metadataStandardId = mapper.convertValue(metadata.get("metadata_standard_id"), Map.class); String url = metadataStandardId.remove("identifier"); metadataStandardId.remove("type"); metadataStandardId.put("uri", url); metadata.remove("additional_properties"); metadata.remove("metadata_standard_id"); Map newMetadata = metadata.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().toString())); String label = newMetadata.remove("description"); newMetadata.put("label", label); result.putAll(newMetadata); result.putAll(metadataStandardId); result.putAll(additionalProperties); return result; } }