argos/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java

458 lines
22 KiB
Java

package eu.eudat.models.data.datasetwizard;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.eudat.data.entities.*;
import eu.eudat.elastic.entities.Tag;
import eu.eudat.logic.managers.DataManagementProfileManager;
import eu.eudat.logic.managers.DatasetManager;
import eu.eudat.logic.proxy.config.entities.PrefillingFixedMapping;
import eu.eudat.logic.proxy.config.entities.PrefillingGet;
import eu.eudat.logic.proxy.config.entities.DefaultPrefillingMapping;
import eu.eudat.logic.proxy.config.entities.PrefillingMapping;
import eu.eudat.logic.utilities.json.JsonSearcher;
import eu.eudat.models.DataModel;
import eu.eudat.models.data.dataset.DataRepository;
import eu.eudat.models.data.dataset.Registry;
import eu.eudat.models.data.dataset.Service;
import eu.eudat.models.data.datasetprofile.DatasetProfileOverviewModel;
import eu.eudat.models.data.dmp.DataManagementPlan;
import eu.eudat.models.data.externaldataset.ExternalDatasetListingModel;
import eu.eudat.models.data.helpermodels.Tuple;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import net.minidev.json.JSONValue;
import org.json.JSONArray;
import org.json.JSONObject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel> {
private UUID id;
private String label;
private String reference;
private String uri;
private String description;
private short status;
private Date created;
private DataManagementPlan dmp;
private PagedDatasetProfile datasetProfileDefinition;
private List<Registry> registries;
private List<Service> services;
private List<DataRepository> dataRepositories;
private List<Tag> tags;
private List<ExternalDatasetListingModel> externalDatasets;
private DatasetProfileOverviewModel profile;
private Boolean isProfileLatestVersion;
private Date modified;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getReference() {
return reference;
}
public void setReference(String reference) {
this.reference = reference;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public short getStatus() {
return status;
}
public void setStatus(short status) {
this.status = status;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public DataManagementPlan getDmp() {
return dmp;
}
public void setDmp(DataManagementPlan dmp) {
this.dmp = dmp;
}
public PagedDatasetProfile getDatasetProfileDefinition() {
return datasetProfileDefinition;
}
public void setDatasetProfileDefinition(PagedDatasetProfile datasetProfileDefinition) {
this.datasetProfileDefinition = datasetProfileDefinition;
}
public List<Registry> getRegistries() {
return registries;
}
public void setRegistries(List<Registry> registries) {
this.registries = registries;
}
public List<Service> getServices() {
return services;
}
public void setServices(List<Service> services) {
this.services = services;
}
public List<DataRepository> getDataRepositories() {
return dataRepositories;
}
public void setDataRepositories(List<DataRepository> dataRepositories) {
this.dataRepositories = dataRepositories;
}
public DatasetProfileOverviewModel getProfile() {
return profile;
}
public void setProfile(DatasetProfileOverviewModel profile) {
this.profile = profile;
}
public List<ExternalDatasetListingModel> getExternalDatasets() {
return externalDatasets;
}
public void setExternalDatasets(List<ExternalDatasetListingModel> externalDatasets) {
this.externalDatasets = externalDatasets;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public Boolean getIsProfileLatestVersion() {
return isProfileLatestVersion;
}
public void setIsProfileLatestVersion(Boolean profileLatestVersion) {
isProfileLatestVersion = profileLatestVersion;
}
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
@Override
public DatasetWizardModel fromDataModel(Dataset entity) {
this.id = entity.getId();
this.label = entity.getLabel();
this.status = entity.getStatus();
this.reference = entity.getReference();
this.description = entity.getDescription();
this.profile = new DatasetProfileOverviewModel();
this.profile = this.profile.fromDataModel(entity.getProfile());
this.uri = entity.getUri();
this.registries = entity.getRegistries() != null ? entity.getRegistries().stream().map(item -> new Registry().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.dataRepositories = entity.getDatasetDataRepositories() != null ? entity.getDatasetDataRepositories().stream().map(item -> {
DataRepository dataRepository = new DataRepository().fromDataModel(item.getDataRepository());
if (item.getData() != null) {
Map<String, Map<String, String>> data = (Map<String, Map<String, String>>) JSONValue.parse(item.getData());
Map<String, String> values = data.get("data");
dataRepository.setInfo(values.get("info"));
}
return dataRepository;
}).collect(Collectors.toList()) : new ArrayList<>();
this.services = entity.getServices() != null ? entity.getServices().stream().map(item -> new Service().fromDataModel(item.getService())).collect(Collectors.toList()) : new ArrayList<>();
this.created = entity.getCreated();
this.dmp = new DataManagementPlan().fromDataModelNoDatasets(entity.getDmp());
this.externalDatasets = entity.getDatasetExternalDatasets() != null ? entity.getDatasetExternalDatasets().stream().map(item -> {
ExternalDatasetListingModel externalDatasetListingModel = new ExternalDatasetListingModel().fromDataModel(item.getExternalDataset());
if (item.getData() != null) {
Map<String, Map<String, String>> data = (Map<String, Map<String, String>>) JSONValue.parse(item.getData());
Map<String, String> values = data.get("data");
externalDatasetListingModel.setInfo(values.get("info"));
externalDatasetListingModel.setType(Integer.parseInt(values.get("type")));
}
return externalDatasetListingModel;
}).collect(Collectors.toList()) : new ArrayList<>();
this.modified = entity.getModified();
return this;
}
public DatasetWizardModel fromDataModelNoDmp(Dataset entity) {
this.id = entity.getId();
this.label = entity.getLabel();
this.status = entity.getStatus();
this.reference = entity.getReference();
this.description = entity.getDescription();
this.profile = new DatasetProfileOverviewModel();
this.profile = this.profile.fromDataModel(entity.getProfile());
this.uri = entity.getUri();
this.registries = entity.getRegistries() != null ? entity.getRegistries().stream().map(item -> new Registry().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>();
this.dataRepositories = entity.getDatasetDataRepositories() != null ? entity.getDatasetDataRepositories().stream().map(item -> {
DataRepository dataRepository = new DataRepository().fromDataModel(item.getDataRepository());
if (item.getData() != null) {
Map<String, Map<String, String>> data = (Map<String, Map<String, String>>) JSONValue.parse(item.getData());
Map<String, String> values = data.get("data");
dataRepository.setInfo(values.get("info"));
}
return dataRepository;
}).collect(Collectors.toList()) : new ArrayList<>();
this.services = entity.getServices() != null ? entity.getServices().stream().map(item -> new Service().fromDataModel(item.getService())).collect(Collectors.toList()) : new ArrayList<>();
this.created = entity.getCreated();
this.externalDatasets = entity.getDatasetExternalDatasets() != null ? entity.getDatasetExternalDatasets().stream().map(item -> {
ExternalDatasetListingModel externalDatasetListingModel = new ExternalDatasetListingModel().fromDataModel(item.getExternalDataset());
if (item.getData() != null) {
Map<String, Map<String, String>> data = (Map<String, Map<String, String>>) JSONValue.parse(item.getData());
Map<String, String> values = data.get("data");
externalDatasetListingModel.setInfo(values.get("info"));
externalDatasetListingModel.setType(Integer.parseInt(values.get("type")));
}
return externalDatasetListingModel;
}).collect(Collectors.toList()) : new ArrayList<>();
this.modified = entity.getModified();
return this;
}
@Override
public Dataset toDataModel() throws Exception {
eu.eudat.data.entities.Dataset entity = new eu.eudat.data.entities.Dataset();
entity.setId(this.id);
entity.setLabel(this.label);
entity.setReference(this.reference);
entity.setUri(this.uri);
entity.setStatus(this.status);
if (this.status == (int) Dataset.Status.FINALISED.getValue())
entity.setFinalizedAt(new Date());
DMP dmp = new DMP();
dmp.setId(this.dmp.getId());
entity.setDmp(dmp);
entity.setDescription(this.description);
entity.setCreated(this.created != null ? this.created : new Date());
entity.setModified(new Date());
DatasetProfile profile = new DatasetProfile();
profile.setId(this.profile.getId());
entity.setProfile(profile);
if (this.registries != null && !this.registries.isEmpty()) {
entity.setRegistries(new HashSet<>());
for (Registry registry : this.registries) {
entity.getRegistries().add(registry.toDataModel());
}
}
if (this.dataRepositories != null && !this.dataRepositories.isEmpty()) {
entity.setDatasetDataRepositories(new HashSet<>());
for (DataRepository dataRepositoryModel : this.dataRepositories) {
eu.eudat.data.entities.DataRepository dataRepository = dataRepositoryModel.toDataModel();
DatasetDataRepository datasetDataRepository = new DatasetDataRepository();
datasetDataRepository.setDataRepository(dataRepository);
Map<String, Map<String, String>> data = new HashMap<>();
Map<String, String> values = new HashMap<>();
values.put("info", dataRepositoryModel.getInfo());
data.put("data", values);
datasetDataRepository.setData(JSONValue.toJSONString(data));
entity.getDatasetDataRepositories().add(datasetDataRepository);
}
}
if (this.services != null && !this.services.isEmpty()) {
entity.setServices(new HashSet<>());
for (Service serviceModel : this.services) {
eu.eudat.data.entities.Service service = serviceModel.toDataModel();
DatasetService datasetService = new DatasetService();
datasetService.setService(service);
entity.getServices().add(datasetService);
}
}
if (this.externalDatasets != null && !this.externalDatasets.isEmpty()) {
entity.setDatasetExternalDatasets(new HashSet<>());
for (ExternalDatasetListingModel externalDataset : this.externalDatasets) {
ExternalDataset externalDatasetEntity = externalDataset.toDataModel();
DatasetExternalDataset datasetExternalDataset = new DatasetExternalDataset();
datasetExternalDataset.setExternalDataset(externalDatasetEntity);
Map<String,Map<String,String>> data = new HashMap<>();
Map<String,String> values = new HashMap<>();
values.put("info",externalDataset.getInfo());
values.put("type",externalDataset.getType().toString());
data.put("data",values);
datasetExternalDataset.setData(JSONValue.toJSONString(data));
entity.getDatasetExternalDatasets().add(datasetExternalDataset);
}
}
return entity;
}
public static DatasetWizardModel fromPrefilledEntity(Map<String, Object> prefilledEntity, PrefillingGet prefillingGet,
DatasetProfile profile, DatasetManager datasetManager) throws Exception {
DatasetWizardModel datasetWizardModel = new DatasetWizardModel();
datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile));
Dataset dataset = new Dataset();
dataset.setProfile(profile);
Map<String, Object> properties = new HashMap<>();
ObjectMapper objectMapper = new ObjectMapper();
JsonNode parentNode = objectMapper.readTree(objectMapper.writeValueAsString(datasetManager.getPagedProfile(datasetWizardModel, dataset)));
for (DefaultPrefillingMapping prefillingMapping: prefillingGet.getMappings()) {
List<String> sourceKeys = Arrays.asList(prefillingMapping.getSource().split("\\."));
Object sourceValue = null;
for (String sourceKey: sourceKeys) {
if (sourceValue == null) {
sourceValue = prefilledEntity.get(sourceKey);
} else if (sourceValue instanceof Map) {
sourceValue = ((Map)sourceValue).get(sourceKey);
}
}
setValue(prefillingMapping, objectMapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties);
}
for (PrefillingFixedMapping fixedMapping: prefillingGet.getFixedMappings()) {
setValue(fixedMapping, fixedMapping.getValue(), datasetWizardModel, parentNode, properties);
}
dataset.setProperties(objectMapper.writeValueAsString(properties));
datasetWizardModel.setDatasetProfileDefinition(datasetManager.getPagedProfile(datasetWizardModel, dataset));
return datasetWizardModel;
}
private static void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map<String, Object> properties) throws InvocationTargetException, IllegalAccessException, JsonProcessingException {
if (prefillingMapping.getTarget() != null) {
try {
String methodName = "set" + prefillingMapping.getTarget().substring(0, 1).toUpperCase(Locale.ROOT) + prefillingMapping.getTarget().substring(1);
Method setterMethod = Arrays.stream(DatasetWizardModel.class.getDeclaredMethods())
.filter(method -> method.getName().equals(methodName)).collect(Collectors.toList()).get(0);
Class<?>[] params = setterMethod.getParameterTypes();
ObjectMapper mapper = new ObjectMapper();
//GK: Tags Special logic
if (!value.equals("null") && prefillingMapping.getTarget().equals("tags")) {
List<Object> rawTags = (List<Object>) mapper.readValue(value, params[0]);
if (rawTags.get(0) instanceof String) {
List<Tag> parsedTags = rawTags.stream().map(rawTag -> new Tag((String) rawTag, (String) rawTag)).collect(Collectors.toList());
value = mapper.writeValueAsString(parsedTags);
List<JsonNode> nodes = JsonSearcher.findNodes(parentNode, "rdaProperty", "dataset.keyword");
for (JsonNode node: nodes) {
String id = node.get(0) != null ? node.get(0).get("id").asText() : node.get("id").asText();
properties.put(id, value);
}
}
}
setterMethod.invoke(datasetWizardModel, mapper.readValue(value, params[0]));
}catch (InvocationTargetException | IllegalAccessException | JsonProcessingException e) {
throw e;
}
} else {
List<JsonNode> nodes = JsonSearcher.findNodes(parentNode, "rdaProperty", prefillingMapping.getMaDmpTarget());
if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.available_until") && !value.equals("null")){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse(value.replace("\"", ""), formatter);
date = date.plusYears(20);
value = date.toString();
}
StringBuilder freeTextFormat = new StringBuilder();
for (JsonNode node: nodes) {
String id = node.get(0) != null ? node.get(0).get("id").asText() : node.get("id").asText();
if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.format") && !value.equals("null")) {
JSONArray jsonArr = new JSONArray(value);
List<String> formats = new ArrayList<>();
String extension;
for(int i = 0; i < jsonArr.length(); i++){
JSONObject jsonObj = jsonArr.getJSONObject(i);
String filename = (String) jsonObj.get("filename");
int index = filename.lastIndexOf('.');
extension = (index > 0) ? filename.substring(index+1) : filename;
formats.add(extension);
}
formats = formats.stream().distinct().collect(Collectors.toList());
List<Object> standardFormats = new ArrayList<>();
String renderStyle = node.get(0) != null ? node.get(0).get("viewStyle").get("renderStyle").asText() : node.get("viewStyle").get("renderStyle").asText();
if(renderStyle.equals("combobox")){
String autocomplete = node.get(0) != null ? node.get(0).get("data").get("type").asText() : node.get("data").get("type").asText();
if(autocomplete.equals("autocomplete")) {
JsonNode urlNode = node.get(0) != null ? node.get(0).get("data").get("autoCompleteSingleDataList") : node.get("data").get("autoCompleteSingleDataList");
String url = urlNode.get(0).get("url").asText();
String optionsRoot = urlNode.get(0).get("optionsRoot").asText();
String label = urlNode.get(0).get("autoCompleteOptions").get("label").asText();
String val = urlNode.get(0).get("autoCompleteOptions").get("value").asText();
for (String format : formats) {
List<Tuple<String, String>> result = DataManagementProfileManager.externalAutocompleteRequest(url, optionsRoot, label, val, format);
result = result.stream().distinct().collect(Collectors.toList());
if(!result.isEmpty()){
for (Tuple<String, String> f : result) {
JSONObject cur = new JSONObject();
cur.put("label", f.getLabel());
standardFormats.add(cur.toString());
freeTextFormat.append(f.getLabel()).append(", ");
}
}
else{
freeTextFormat.append(format).append(", ");
}
}
properties.put(id, standardFormats);
}
}
else if(renderStyle.equals("freetext")){
if (freeTextFormat.length() == 0) {
for (String format : formats) {
freeTextFormat.append(format).append(", ");
}
}
freeTextFormat.setLength(freeTextFormat.length() - 2);
properties.put(id, freeTextFormat.toString());
}
}
else if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.data_access")){
value = value.replace("\"", "");
if(value.equals("open")){
properties.put(id, value);
}
else if(value.equals("restricted")){
properties.put(id, "shared");
}
else{
properties.put(id, "closed");
}
}
else{
properties.put(id, value.replace("\"", ""));
}
}
}
}
@Override
public String getHint() {
return "datasetWizardModel";
}
}