Refactor Zenodo deposit creation. Add model for mapping instead of relying on stringBuilder

This commit is contained in:
George Kalampokis 2022-04-07 17:30:40 +03:00
parent e373baee7e
commit 7c933d9f32
10 changed files with 441 additions and 129 deletions

View File

@ -328,7 +328,7 @@ public class DMPs extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = {"/createZenodoDoi/{id}"})
public ResponseEntity<ResponseItem<String>> createZenodoDoi(@PathVariable String id, Principal principal) {
try {
String zenodoDOI = this.dataManagementPlanManager.createZenodoDoi(UUID.fromString(id), principal, configLoader);
String zenodoDOI = this.dataManagementPlanManager.createZenodoDoi(UUID.fromString(id), principal);
return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem<String>().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully created DOI for Data Datamanagement Plan in question.").payload(zenodoDOI));
} catch (Exception e) {
logger.error(e.getMessage(), e);

View File

@ -28,13 +28,11 @@ import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.builders.entity.UserInfoBuilder;
import eu.eudat.logic.mapper.elastic.DmpMapper;
import eu.eudat.logic.mapper.elastic.criteria.DmpCriteriaMapper;
import eu.eudat.logic.proxy.config.DOIFunder;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.forms.VisibilityRuleService;
import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl;
import eu.eudat.logic.services.operations.DatabaseRepository;
import eu.eudat.logic.services.utilities.UtilitiesService;
import eu.eudat.logic.utilities.builders.XmlBuilder;
import eu.eudat.logic.utilities.documents.helpers.FileEnvelope;
import eu.eudat.logic.utilities.documents.pdf.PDFUtils;
@ -59,6 +57,8 @@ import eu.eudat.models.data.project.ProjectDMPEditorModel;
import eu.eudat.models.data.security.Principal;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import eu.eudat.models.data.userinfo.UserListingModel;
import eu.eudat.models.deposit.zenodo.ZenodoDeposit;
import eu.eudat.models.deposit.zenodo.mapper.DMPToZenodoMapper;
import eu.eudat.queryable.QueryableList;
import eu.eudat.types.Authorities;
import eu.eudat.types.MetricNames;
@ -113,9 +113,10 @@ public class DataManagementPlanManager {
private RDAManager rdaManager;
private UserManager userManager;
private final MetricsManager metricsManager;
private final ConfigLoader configLoader;
@Autowired
public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, MetricsManager metricsManager) {
public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, MetricsManager metricsManager, ConfigLoader configLoader) {
this.apiContext = apiContext;
this.datasetManager = datasetManager;
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
@ -123,6 +124,7 @@ public class DataManagementPlanManager {
this.rdaManager = rdaManager;
this.userManager = userManager;
this.metricsManager = metricsManager;
this.configLoader = configLoader;
}
/*
@ -1055,7 +1057,7 @@ public class DataManagementPlanManager {
UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId());
sendNotification(dmp, user, NotificationType.DMP_PUBLISH);
if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) {
this.createZenodoDoi(dmp.getId(), principal, null, true);
this.createZenodoDoi(dmp.getId(), principal, true);
}
}
@ -2013,11 +2015,11 @@ public class DataManagementPlanManager {
}
}
public String createZenodoDoi(UUID id, Principal principal, ConfigLoader configLoader) throws Exception {
return this.createZenodoDoi(id, principal, configLoader, false);
public String createZenodoDoi(UUID id, Principal principal) throws Exception {
return this.createZenodoDoi(id, principal, false);
}
public String createZenodoDoi(UUID id, Principal principal, ConfigLoader configLoader, boolean update) throws Exception {
public String createZenodoDoi(UUID id, Principal principal, boolean update) throws Exception {
DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id);
if (!isUserOwnerOfDmp(dmp, principal))
throw new Exception("User is not authorized to invoke this action");
@ -2039,129 +2041,18 @@ public class DataManagementPlanManager {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
String createData = null;
Map<String, Object> extraProperties = dmp.getExtraProperties() != null ? new org.json.JSONObject(dmp.getExtraProperties()).toMap() : new HashMap<>();
StringBuilder dataBuilder = new StringBuilder();
dataBuilder.append("{\n \"metadata\": {\n");
dataBuilder.append( " \"title\": \"").append(dmp.getLabel()).append("\",\n");
dataBuilder.append(" \"upload_type\": \"publication\",\n");
dataBuilder.append(" \"publication_type\": \"datamanagementplan\",\n");
dataBuilder.append(" \"description\": \"").append((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "<p></p>")).append("\",\n");
dataBuilder.append(" \"version\": \"").append(dmp.getVersion()).append("\",\n");
dataBuilder.append(" \"communities\": [{\n \t\t\"identifier\": \"").append(environment.getProperty("zenodo.community")).append("\"\n \t\t}],\n");
dataBuilder.append(" \"access_right\": \"");
if (extraProperties.get("visible") == null) {
dataBuilder.append("restricted\",\n");
dataBuilder.append(" \"access_conditions\": \"\",\n");
} else {
if (((Boolean) extraProperties.get("visible"))) {
Instant publicationDate = Instant.parse(extraProperties.get("publicDate").toString());
if (publicationDate.isBefore(Instant.now())) {
dataBuilder.append("open\",\n");
} else {
dataBuilder.append("embargoed\",\n");
dataBuilder.append(" \"embargo_date\": \"" + publicationDate + "\",\n");
}
if (extraProperties.get("license") != null) {
dataBuilder.append(" \"license\": \"").append(((Map) extraProperties.get("license")).get("pid")).append("\",\n");
}
} else {
dataBuilder.append("restricted\",\n");
dataBuilder.append(" \"access_conditions\": \"\",\n");
}
}
if (dmp.isPublic()) {
dataBuilder.append(" \"related_identifiers\": [{\n");
dataBuilder.append(" \t\t\"identifier\": \"").append((this.environment.getProperty("dmp.domain") + "/external/zenodo/" + id.toString())).append("\",\n");
dataBuilder.append(" \t\t\"relation\": \"isIdenticalTo\"}],\n");
}
dataBuilder.append(" \"contributors\": [");
int i = 0;
for(UserDMP userDMP: dmp.getUsers()) {
if (i > 0) {
dataBuilder.append(",\n");
}
dataBuilder.append("{\n");
dataBuilder.append(" \t\t\"name\": \"").append(userDMP.getUser().getName()).append("\",\n");
dataBuilder.append(" \t\t\"type\": \"").append("ProjectMember").append("\",\n");
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
dataBuilder.append(" \t\t\"affiliation\": \"");
int j = 0;
for (Organisation organization: dmp.getOrganisations()) {
if (j > 0) {
dataBuilder.append(", ");
}
dataBuilder.append(organization.getLabel());
j++;
}
dataBuilder.append("\"\n}");
} else {
dataBuilder.append(" \t\t\"affiliation\": \"" + this.environment.getProperty("zenodo.affiliation") +"\"\n}");
}
i++;
}
for(Researcher researcher: dmp.getResearchers()) {
if (i > 0) {
dataBuilder.append(",\n");
}
dataBuilder.append("{\n");
dataBuilder.append(" \t\t\"name\": \"").append(researcher.getLabel()).append("\",\n");
dataBuilder.append(" \t\t\"type\": \"").append("Researcher").append("\",\n");
String referenceHead = researcher.getReference().split(":")[0];
String referenceTail = researcher.getReference().replace(referenceHead + ":", "");
dataBuilder.append(" \t\t\"affiliation\": \"" + referenceHead + "\"");
if (referenceHead.toUpperCase().equals("ORCID")) {
dataBuilder.append(",\n \t\t\"orcid\": \"" + referenceTail + "\"");
}
dataBuilder.append("\n}");
i++;
}
dataBuilder.append("],\n");
if (dmp.getGrant().getReference() == null) {
dmp.getGrant().setReference("dmp:" + dmp.getGrant().getId());
}
String grantReferenceHead = dmp.getGrant().getReference().split(":")[0];
if (grantReferenceHead.equals("openaire")) {
String grantReferenceTail = dmp.getGrant().getReference().split(":")[3];
DOIFunder doiFunder = configLoader.getDOIFunders().stream()
.filter(doiFunder1 -> dmp.getGrant().getFunder().getLabel().contains(doiFunder1.getFunder()) || doiFunder1.getFunder().contains(dmp.getGrant().getFunder().getLabel()))
.findFirst().orElse(null);
if (doiFunder != null) {
String finalId = doiFunder.getDOI() + "::" + grantReferenceTail;
dataBuilder.append(" \"grants\": [{\n");
dataBuilder.append(" \t\t\"id\": \"").append(finalId).append("\"\n}],\n");
}
}
dataBuilder.append(" \"creators\": [{\n");
dataBuilder.append(" \t\t\"name\": \"").append(dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName()).append("\",\n");
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
dataBuilder.append(" \t\t\"affiliation\": \"");
int j = 0;
for (Organisation organization: dmp.getOrganisations()) {
if (j > 0) {
dataBuilder.append(", ");
}
dataBuilder.append(organization.getLabel());
j++;
}
dataBuilder.append("\"}]\n");
} else {
dataBuilder.append(" \t\t\"affiliation\": \"" + this.environment.getProperty("zenodo.affiliation") +"\"}]\n");
}
dataBuilder.append(" }\n").append("}");
createData = dataBuilder.toString();
/*ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
JsonNode createDataJSON = mapper.readTree(createData);*/
HttpEntity<String> request = new HttpEntity<>(createData, headers);
Map createResponse = null;
LinkedHashMap<String, String> links = null;
ZenodoDeposit deposit = DMPToZenodoMapper.fromDMP(dmp, environment, configLoader);
//if (Objects.requireNonNull(environment.getProperty("spring.profiles.active")).contains("devel")) {
String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(deposit);
logger.info(json);
//}
HttpEntity<ZenodoDeposit> request = new HttpEntity<>(deposit, headers);
Map createResponse;
LinkedHashMap<String, String> links;
String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId());
String unpublishedUrl = null;
String publishUrl = null;
String finalDoi = null;
String publishUrl;
String finalDoi;
try {
if (previousDOI == null) {

View File

@ -0,0 +1,18 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonValue;
public enum ZenodoAccessRight {
RESTRICTED("restricted"), EMBARGOED("embargoed"), OPEN("open");
private final String value;
ZenodoAccessRight(String value) {
this.value = value;
}
@JsonValue
public String getValue() {
return value;
}
}

View File

@ -0,0 +1,19 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoComunity {
private String identifier;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
}

View File

@ -0,0 +1,45 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoContributor {
private String name;
private String type;
private String affiliation;
private String orcid;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAffiliation() {
return affiliation;
}
public void setAffiliation(String affiliation) {
this.affiliation = affiliation;
}
public String getOrcid() {
return orcid;
}
public void setOrcid(String orcid) {
this.orcid = orcid;
}
}

View File

@ -0,0 +1,19 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoDeposit {
private ZenodoDepositMetadata metadata;
public ZenodoDepositMetadata getMetadata() {
return metadata;
}
public void setMetadata(ZenodoDepositMetadata metadata) {
this.metadata = metadata;
}
}

View File

@ -0,0 +1,159 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.Instant;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoDepositMetadata {
private String title;
@JsonProperty("upload_type")
private String uploadType;
@JsonProperty("publication_type")
private String publicationType;
private String description;
private String version;
private List<ZenodoComunity> communities;
@JsonProperty("access_right")
private ZenodoAccessRight accessRight;
@JsonProperty("access_conditions")
private String accessConditions;
@JsonProperty("embargo_date")
private String embargoDate;
private String license;
@JsonProperty("related_identifiers")
private List<ZenodoRelator> relatedIdentifiers;
private List<ZenodoContributor> contributors;
private List<ZenodoGrant> grants;
private List<ZenodoContributor> creators;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUploadType() {
return uploadType;
}
public void setUploadType(String uploadType) {
this.uploadType = uploadType;
}
public String getPublicationType() {
return publicationType;
}
public void setPublicationType(String publicationType) {
this.publicationType = publicationType;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public List<ZenodoComunity> getCommunities() {
return communities;
}
public void setCommunities(List<ZenodoComunity> communities) {
this.communities = communities;
}
public ZenodoAccessRight getAccessRight() {
return accessRight;
}
public void setAccessRight(ZenodoAccessRight accessRight) {
this.accessRight = accessRight;
}
public String getAccessConditions() {
return accessConditions;
}
public void setAccessConditions(String accessConditions) {
this.accessConditions = accessConditions;
}
public String getEmbargoDate() {
return embargoDate;
}
public void setEmbargoDate(String embargoDate) {
this.embargoDate = embargoDate;
}
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
public List<ZenodoRelator> getRelatedIdentifiers() {
return relatedIdentifiers;
}
public void setRelatedIdentifiers(List<ZenodoRelator> relatedIdentifiers) {
this.relatedIdentifiers = relatedIdentifiers;
}
public List<ZenodoContributor> getContributors() {
return contributors;
}
public void setContributors(List<ZenodoContributor> contributors) {
this.contributors = contributors;
}
public List<ZenodoGrant> getGrants() {
return grants;
}
public void setGrants(List<ZenodoGrant> grants) {
this.grants = grants;
}
public List<ZenodoContributor> getCreators() {
return creators;
}
public void setCreators(List<ZenodoContributor> creators) {
this.creators = creators;
}
}

View File

@ -0,0 +1,18 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoGrant {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View File

@ -0,0 +1,28 @@
package eu.eudat.models.deposit.zenodo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ZenodoRelator {
private String identifier;
private String relation;
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
public String getRelation() {
return relation;
}
public void setRelation(String relation) {
this.relation = relation;
}
}

View File

@ -0,0 +1,115 @@
package eu.eudat.models.deposit.zenodo.mapper;
import eu.eudat.data.entities.DMP;
import eu.eudat.data.entities.Organisation;
import eu.eudat.data.entities.UserDMP;
import eu.eudat.logic.proxy.config.DOIFunder;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;
import eu.eudat.models.deposit.zenodo.*;
import org.springframework.core.env.Environment;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
public class DMPToZenodoMapper {
public static ZenodoDeposit fromDMP(DMP dmp, Environment environment, ConfigLoader configLoader) {
Map<String, Object> extraProperties = dmp.getExtraProperties() != null ? new org.json.JSONObject(dmp.getExtraProperties()).toMap() : new HashMap<>();
ZenodoDeposit deposit = new ZenodoDeposit();
deposit.setMetadata(new ZenodoDepositMetadata());
deposit.getMetadata().setTitle(dmp.getLabel());
deposit.getMetadata().setUploadType("publication");
deposit.getMetadata().setPublicationType("datamanagementplan");
deposit.getMetadata().setDescription((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "<p></p>"));
deposit.getMetadata().setVersion(dmp.getVersion().toString());
ZenodoComunity community = new ZenodoComunity();
community.setIdentifier(environment.getProperty("zenodo.community"));
deposit.getMetadata().setCommunities(Collections.singletonList(community));
if (extraProperties.get("visible") == null) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
} else {
if (((Boolean) extraProperties.get("visible"))) {
Instant publicationDate = Instant.parse(extraProperties.get("publicDate").toString());
if (publicationDate.isBefore(Instant.now())) {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.OPEN);
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.EMBARGOED);
deposit.getMetadata().setEmbargoDate(publicationDate.toString());
}
if (extraProperties.get("license") != null) {
deposit.getMetadata().setLicense(((Map<?, ?>) extraProperties.get("license")).get("pid").toString());
}
} else {
deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED);
deposit.getMetadata().setAccessConditions("");
}
}
if (dmp.isPublic()) {
ZenodoRelator relator = new ZenodoRelator();
relator.setIdentifier((environment.getProperty("dmp.domain") + "/external/zenodo/" + dmp.getId().toString()));
relator.setRelation("isIdenticalTo");
deposit.getMetadata().setRelatedIdentifiers(Collections.singletonList(relator));
}
deposit.getMetadata().setContributors(new LinkedList<>());
List<ZenodoContributor> contributors = dmp.getUsers().stream().map(userDMP -> {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(userDMP.getUser().getName());
contributor.setType("ProjectMember");
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
contributor.setAffiliation(dmp.getOrganisations()
.stream().map(Organisation::getLabel).collect(Collectors.joining(", ")));
} else {
contributor.setAffiliation(environment.getProperty("zenodo.affiliation"));
}
return contributor;
}).collect(Collectors.toList());
List<ZenodoContributor> researchers = dmp.getResearchers().stream().map(researcher -> {
ZenodoContributor contributor = new ZenodoContributor();
contributor.setName(researcher.getLabel());
contributor.setType("Researcher");
String referenceHead = researcher.getReference().split(":")[0];
String referenceTail = researcher.getReference().replace(referenceHead + ":", "");
contributor.setAffiliation(referenceHead);
if (referenceHead.equalsIgnoreCase("ORCID")) {
contributor.setOrcid(referenceTail);
}
return contributor;
}).collect(Collectors.toList());
deposit.getMetadata().getContributors().addAll(contributors);
deposit.getMetadata().getContributors().addAll(researchers);
if (dmp.getGrant().getReference() == null) {
dmp.getGrant().setReference("dmp:" + dmp.getGrant().getId());
}
String grantReferenceHead = dmp.getGrant().getReference().split(":")[0];
if (grantReferenceHead.equals("openaire")) {
String grantReferenceTail = dmp.getGrant().getReference().split(":")[3];
DOIFunder doiFunder = configLoader.getDOIFunders().stream()
.filter(doiFunder1 -> dmp.getGrant().getFunder().getLabel().contains(doiFunder1.getFunder()) || doiFunder1.getFunder().contains(dmp.getGrant().getFunder().getLabel()))
.findFirst().orElse(null);
if (doiFunder != null) {
String finalId = doiFunder.getDOI() + "::" + grantReferenceTail;
ZenodoGrant grant = new ZenodoGrant();
grant.setId(finalId);
deposit.getMetadata().setGrants(Collections.singletonList(grant));
}
}
ZenodoContributor creator = new ZenodoContributor();
creator.setName(dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName());
if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) {
creator.setAffiliation(dmp.getOrganisations()
.stream().map(Organisation::getLabel).collect(Collectors.joining(", ")));
} else {
creator.setAffiliation(environment.getProperty("zenodo.affiliation"));
}
deposit.getMetadata().setCreators(Collections.singletonList(creator));
return deposit;
}
}