argos/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java

192 lines
6.8 KiB
Java

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<Metadatum> toRDAList(List<JsonNode> nodes) {
Map<String, String> rdaMap = new HashMap<>();
List<Metadatum> 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<JsonNode> 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());
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<String, String> toProperties(List<Metadatum> rdas) {
Map<String, String> properties = new HashMap<>();
List<Object> standardIds = new ArrayList<>();
ObjectMapper mapper = new ObjectMapper();
rdas.forEach(rda -> {
rda.getAdditionalProperties().entrySet().forEach(entry -> {
try {
switch (entry.getKey()) {
case "fieldId":
Map<String, String> 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 = node.get("rdaProperty").asText();
JsonNode rdaValue = node.get("value");
if (rdaProperty.contains("metadata_standard_id")) {
if (rdaValue instanceof ArrayNode) {
for (Iterator<JsonNode> 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<Metadatum> rdas, Map<String, String> 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<String, String> toMap(Metadatum rda) {
Map<String, String> result = new HashMap<>();
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> metadata = mapper.convertValue(rda, Map.class);
Map<String, String> 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<String, String> 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);
return result;
}
}