package eu.eudat.file.transformer.rda.mapper; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; 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.file.transformer.models.descriptiontemplate.definition.FieldFileTransformerModel; import eu.eudat.file.transformer.rda.Metadatum; import eu.eudat.file.transformer.utils.string.MyStringUtils; 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) { ObjectMapper mapper = new ObjectMapper(); Map rdaMap = new HashMap<>(); List rdas = new ArrayList<>(); for (FieldFileTransformerModel node: nodes) { String rdaProperty = node.getSchematics().stream().filter(schematic -> schematic.startsWith("rda.dataset.metadata")).findFirst().orElse(""); try { if (node.getData() == null) { continue; } String stringValue = node.getData().getValue().startsWith("[") ? node.getData().getValue() : "\"" + node.getData().getValue() + "\""; JsonNode rdaValue = mapper.readTree(stringValue); for (PropertyName propertyName : PropertyName.values()) { if (rdaProperty.contains(propertyName.getName())) { switch (propertyName) { case METADATA_STANDARD_ID: if (rdaValue instanceof ArrayNode) { 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.getId()); rdas.get(rdas.size() - 1).setAdditionalProperty("valueId", data.get("id").asText()); rdaMap.put(data.get("uri").asText(), node.getNumbering()); } } } 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.getId()); rdaMap.put(rdaValue.asText(), node.getNumbering()); } break; case DESCRIPTION: if (!rdaValue.asText().isEmpty()) { Metadatum rda = getRelative(rdas, rdaMap, node.getNumbering()); if (rda != null) { rda.setDescription(rdaValue.asText()); rda.setAdditionalProperty("descriptionId", node.getId()); } 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.getNumbering()); if (rda != null) { rda.setLanguage(lang); rda.setAdditionalProperty("languageId", node.getId()); } else { rdas.forEach(rda1 -> rda1.setLanguage(lang)); } break; } } } } catch (JsonProcessingException e) { logger.error(e.getMessage(), e); } } return rdas; } //TODO /* public static void toProperties(List rdas, List fields) { 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); Field field1 = new Field(); field1.setKey(entry.getValue().toString()); field1.setValue(mapper.writeValueAsString(standardIds)); properties.add(field1); break; case "identifierId": Field field2 = new Field(); field2.setKey(entry.getValue().toString()); field2.setValue(rda.getMetadataStandardId().getIdentifier()); properties.add(field2); break; case "descriptionId": Field field3 = new Field(); field3.setKey(entry.getValue().toString()); field3.setValue(rda.getDescription()); properties.add(field3); break; case "languageId": if (rda.getLanguage() != null) { Field field4 = new Field(); field4.setKey(entry.getValue().toString()); field4.setValue(rda.getLanguage().value()); properties.add(field4); } 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; } }