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

396 lines
14 KiB
Java

package eu.eudat.models.rda.mapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.logic.utilities.helpers.MyStringUtils;
import eu.eudat.logic.utilities.json.JavaToJson;
import eu.eudat.logic.utilities.json.JsonSearcher;
import eu.eudat.models.rda.Distribution;
import eu.eudat.models.rda.License;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URI;
import java.util.*;
import java.util.stream.Collectors;
public class DistributionRDAMapper {
private static final Logger logger = LoggerFactory.getLogger(DistributionRDAMapper.class);
private static final ObjectMapper mapper = new ObjectMapper();
public static List<Distribution> toRDAList(List<JsonNode> nodes) {
Map<String, Distribution> rdaMap = new HashMap<>();
for (JsonNode node: nodes) {
String rdaProperty = node.get("rdaProperty").asText();
String rdaValue = node.get("value").asText();
//if(rdaValue == null || rdaValue.isEmpty()){
if(rdaValue == null || (rdaValue.isEmpty() && !node.get("value").isArray())){
continue;
}
String key = node.get("numbering").asText();
if(!key.contains("mult")){
key = "0";
}
else{
key = "" + key.charAt(4);
}
Distribution rda;
if(rdaMap.containsKey(key)){
rda = rdaMap.get(key);
}
else {
rda = new Distribution();
rdaMap.put(key, rda);
}
/* Distribution rda = getRelative(rdaMap, node.get("numbering").asText());
if (!rdaMap.containsValue(rda)) {
rdaMap.put(node.get("numbering").asText(), rda);
} */
for (ExportPropertyName exportPropertyName : ExportPropertyName.values()) {
if (rdaProperty.contains(exportPropertyName.getName())) {
switch (exportPropertyName) {
case ACCESS_URL:
rda.setAccessUrl(rdaValue);
rda.setAdditionalProperty(ImportPropertyName.ACCESS_URL.getName(), node.get("id").asText());
break;
case AVAILABLE_UNTIL:
rda.setAvailableUntil(rdaValue);
rda.setAdditionalProperty(ImportPropertyName.AVAILABLE_UNTIL.getName(), node.get("id").asText());
break;
case DOWNLOAD_URL:
rda.setDownloadUrl(URI.create(rdaValue));
rda.setAdditionalProperty(ImportPropertyName.DOWNLOAD_URL.getName(), node.get("id").asText());
break;
case DESCRIPTION:
if(!rdaProperty.contains("host")) {
rda.setDescription(rdaValue);
rda.setAdditionalProperty(ImportPropertyName.DESCRIPTION.getName(), node.get("id").asText());
}
break;
case DATA_ACCESS:
rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue));
rda.setAdditionalProperty(ImportPropertyName.DATA_ACCESS.getName(), node.get("id").asText());
break;
case BYTE_SIZE:
rda.setByteSize(Integer.parseInt(rdaValue));
rda.setAdditionalProperty(ImportPropertyName.BYTE_SIZE.getName(), node.get("id").asText());
break;
case LICENSE:
List<JsonNode> licenseNodes = nodes.stream().filter(lnode -> lnode.get("rdaProperty").asText().toLowerCase().contains("license")).collect(Collectors.toList());
License license = LicenseRDAMapper.toRDA(licenseNodes);
rda.setLicense(license != null? Collections.singletonList(license): new ArrayList<>());
break;
case FORMAT:
if(node.get("value").isArray()){
Iterator<JsonNode> iter = node.get("value").elements();
List<String> formats = new ArrayList<>();
int i = 1;
while(iter.hasNext()) {
JsonNode current = iter.next();
String format = current.toString();
try {
Map<String, String> result = mapper.readValue(format, HashMap.class);
format = result.get("label");
formats.add(format);
rda.setAdditionalProperty("format" + i++, mapper.readTree(current.toString()));
}
catch(JsonProcessingException e){
logger.warn(e.getMessage());
}
}
rda.setFormat(formats);
}
else{
if(rda.getFormat() == null || rda.getFormat().isEmpty()){
rda.setFormat(new ArrayList<>(Arrays.asList(rdaValue.replace(" ", "").split(","))));
}
else{
rda.getFormat().addAll(Arrays.asList(rdaValue.replace(" ", "").split(",")));
}
}
rda.setAdditionalProperty(ImportPropertyName.FORMAT.getName(), node.get("id").asText());
break;
case TITLE:
if(!rdaProperty.contains("host")) {
rda.setTitle(rdaValue);
rda.setAdditionalProperty(ImportPropertyName.TITLE.getName(), node.get("id").asText());
}
break;
case HOST:
rda.setHost(HostRDAMapper.toRDA(nodes, node.get("numbering").asText()));
break;
}
}
}
}
return rdaMap.values().stream()
.filter(distro -> distro.getTitle() != null).collect(Collectors.toList());
}
public static Map<String, String> toProperties(List<Distribution> rdas) {
Map<String, String> properties = new HashMap<>();
rdas.forEach(rda -> {
rda.getAdditionalProperties().entrySet().forEach(entry -> {
try {
ImportPropertyName importPropertyName = ImportPropertyName.fromString(entry.getKey());
switch (importPropertyName) {
case ACCESS_URL:
properties.put(entry.getValue().toString(), rda.getAccessUrl());
break;
case TITLE:
properties.put(entry.getValue().toString(), rda.getTitle());
break;
case DESCRIPTION:
properties.put(entry.getValue().toString(), rda.getDescription());
break;
case FORMAT:
properties.put(entry.getValue().toString(), rda.getFormat().get(0));
break;
case BYTE_SIZE:
properties.put(entry.getValue().toString(), rda.getByteSize().toString());
break;
case DATA_ACCESS:
properties.put(entry.getValue().toString(), rda.getDataAccess().value());
break;
case DOWNLOAD_URL:
properties.put(entry.getValue().toString(), rda.getDownloadUrl().toString());
break;
case AVAILABLE_UNTIL:
properties.put(entry.getValue().toString(), rda.getAvailableUntil());
break;
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
});
if (rda.getHost() != null) {
properties.putAll(HostRDAMapper.toProperties(rda.getHost()));
}
if (rda.getLicense() != null && !rda.getLicense().isEmpty()) {
properties.putAll(LicenseRDAMapper.toProperties(rda.getLicense()));
}
});
return properties;
}
public static Map<String, String> toProperties(Distribution rda, JsonNode root) {
Map<String, String> properties = new HashMap<>();
List<JsonNode> distributionNodes = JsonSearcher.findNodes(root, "rdaProperty", "dataset.distribution");
for (JsonNode distributionNode: distributionNodes) {
for (ExportPropertyName exportPropertyName: ExportPropertyName.values()) {
if (distributionNode.get("rdaProperty").asText().contains(exportPropertyName.getName())) {
switch (exportPropertyName) {
case ACCESS_URL:
properties.put(distributionNode.get("id").asText(), rda.getAccessUrl());
break;
case DESCRIPTION:
properties.put(distributionNode.get("id").asText(), rda.getDescription());
break;
case TITLE:
properties.put(distributionNode.get("id").asText(), rda.getTitle());
break;
case AVAILABLE_UNTIL:
properties.put(distributionNode.get("id").asText(), rda.getAvailableUntil());
break;
case DOWNLOAD_URL:
if (rda.getDownloadUrl() != null) {
properties.put(distributionNode.get("id").asText(), rda.getDownloadUrl().toString());
}
break;
case DATA_ACCESS:
properties.put(distributionNode.get("id").asText(), rda.getDataAccess().value());
break;
case BYTE_SIZE:
if (rda.getByteSize() != null) {
properties.put(distributionNode.get("id").asText(), rda.getByteSize().toString());
}
break;
case FORMAT:
if (rda.getFormat() != null && !rda.getFormat().isEmpty()) {
String style = distributionNode.get("viewStyle").get("renderStyle").asText();
if(style.equals("combobox")) {
if (distributionNode.get("data").get("type").asText().equals("autocomplete")) {
Map<String, Object> additionalProperties = rda.getAdditionalProperties();
List<Object> standardFormats = new ArrayList<>();
rda.getAdditionalProperties().forEach((key, value) -> {
try {
if (key.matches("format\\d+")) {
standardFormats.add(additionalProperties.get(key));
properties.put(distributionNode.get("id").asText(), mapper.writeValueAsString(standardFormats));
}
} catch (JsonProcessingException e) {
logger.error(e.getMessage(), e);
}
});
}
}
else if(style.equals("freetext")){
properties.put(distributionNode.get("id").asText(), String.join(", ", rda.getFormat()));
}
}
break;
case LICENSE:
if (rda.getLicense() != null && !rda.getLicense().isEmpty()) {
properties.putAll(LicenseRDAMapper.toProperties(rda.getLicense().get(0), root));
}
break;
case HOST:
if (rda.getHost() != null) {
properties.putAll(HostRDAMapper.toProperties(rda.getHost()));
}
break;
}
}
}
}
return properties;
}
public static Distribution toRDA(List<JsonNode> nodes) {
Distribution rda = new Distribution();
for (JsonNode node: nodes) {
String rdaProperty = node.get("rdaProperty").asText();
String rdaValue = node.get("value").asText();
for (ExportPropertyName exportPropertyName: ExportPropertyName.values()) {
if (rdaProperty.contains(exportPropertyName.getName())) {
switch (exportPropertyName) {
case ACCESS_URL:
rda.setAccessUrl(rdaValue);
break;
case DESCRIPTION:
rda.setDescription(rdaValue);
break;
case TITLE:
rda.setTitle(rdaValue);
break;
case AVAILABLE_UNTIL:
rda.setAvailableUntil(rdaValue);
break;
case DOWNLOAD_URL:
rda.setDownloadUrl(URI.create(rdaValue));
break;
case DATA_ACCESS:
rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue));
break;
case BYTE_SIZE:
rda.setByteSize(Integer.parseInt(rdaValue));
break;
case FORMAT:
rda.setFormat(Collections.singletonList(rdaValue));
break;
case LICENSE:
List<JsonNode> licenseNodes = nodes.stream().filter(lnode -> lnode.get("rdaProperty").asText().toLowerCase().contains("license")).collect(Collectors.toList());
rda.setLicense(Collections.singletonList(LicenseRDAMapper.toRDA(licenseNodes)));
break;
case HOST:
List<JsonNode> hostNodes = nodes.stream().filter(lnode -> lnode.get("rdaProperty").asText().toLowerCase().contains("host")).collect(Collectors.toList());
rda.setHost(HostRDAMapper.toRDA(hostNodes, "0"));
break;
}
}
}
/*if (rdaProperty.contains("access_url")) {
rda.setAccessUrl(rdaValue);
} else if (rdaProperty.contains("available_util")) {
rda.setAvailableUntil(rdaValue);
} else if (rdaProperty.contains("byte_size")) {
rda.setByteSize(Integer.parseInt(rdaValue));
} else if (rdaProperty.contains("data_access")) {
rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue));
} else if (rdaProperty.contains("description")) {
rda.setDescription(rdaValue);
} else if (rdaProperty.contains("download_url")) {
rda.setDownloadUrl(URI.create(rdaValue));
} else if (rdaProperty.contains("format")) {
rda.setFormat(Collections.singletonList(rdaValue));
} else if (rdaProperty.contains("host")) {
// rda.setHost(HostRDAMapper.toRDA(node));
} else if (rdaProperty.contains("license")) {
rda.setLicense(Collections.singletonList(LicenseRDAMapper.toRDA(node)));
} else if (rdaProperty.contains("title")) {
rda.setTitle(rdaValue);
}*/
}
if (rda.getTitle() == null) {
throw new IllegalArgumentException("Distribution title is missing");
}
if (rda.getDataAccess() == null) {
throw new IllegalArgumentException("Distribution Data Access is missing");
}
return rda;
}
private static Distribution getRelative( Map<String, Distribution> rdaMap, String numbering) {
return rdaMap.entrySet().stream().filter(entry -> MyStringUtils.getFirstDifference(entry.getKey(), numbering) > 0)
.max(Comparator.comparingInt(entry -> MyStringUtils.getFirstDifference(entry.getKey(), numbering))).map(Map.Entry::getValue).orElse(new Distribution());
}
private enum ExportPropertyName {
ACCESS_URL("access_url"),
AVAILABLE_UNTIL("available_until"),
BYTE_SIZE("byte_size"),
DATA_ACCESS("data_access"),
DESCRIPTION("description"),
DOWNLOAD_URL("download_url"),
FORMAT("format"),
HOST("host"),
LICENSE("license"),
TITLE("title");
private final String name;
ExportPropertyName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
private enum ImportPropertyName {
ACCESS_URL("accessurlId"),
AVAILABLE_UNTIL("availableUtilId"),
BYTE_SIZE("byteSizeId"),
DATA_ACCESS("dataAccessId"),
DESCRIPTION("descriptionId"),
DOWNLOAD_URL("downloadUrlId"),
FORMAT("formatId"),
/*HOST("host"),
LICENSE("license"),*/
TITLE("titleId");
private final String name;
ImportPropertyName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static ImportPropertyName fromString(String name) throws Exception {
for (ImportPropertyName importPropertyName: ImportPropertyName.values()) {
if (importPropertyName.getName().equals(name)) {
return importPropertyName;
}
}
throw new Exception("No name available");
}
}
}