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.*; 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 = node.get("rdaProperty").asText(); 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()); 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())); 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()); } 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); } else { rdas.forEach(rda1 -> rda1.setLanguage(lang)); } break; } } } } return rdas; } public static Metadatum toRDA(JsonNode node) { Metadatum rda = new Metadatum(); String rdaProperty = node.get("rdaProperty").asText(); 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; } } }