Skip to content

Commit

Permalink
orcid: get contributor info from orcid
Browse files Browse the repository at this point in the history
  • Loading branch information
rekt-hard committed Jan 22, 2024
1 parent e8ba6d0 commit 9dfaafa
Show file tree
Hide file tree
Showing 22 changed files with 461 additions and 64 deletions.
68 changes: 47 additions & 21 deletions src/main/java/at/ac/tuwien/damap/rest/dmp/service/DmpService.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,44 @@
package at.ac.tuwien.damap.rest.dmp.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.validation.Valid;

import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;

import at.ac.tuwien.damap.domain.Access;
import at.ac.tuwien.damap.domain.Contributor;
import at.ac.tuwien.damap.domain.Dmp;
import at.ac.tuwien.damap.enums.EContributorRole;
import at.ac.tuwien.damap.enums.EFunctionRole;
import at.ac.tuwien.damap.enums.EIdentifierType;
import at.ac.tuwien.damap.repo.AccessRepo;
import at.ac.tuwien.damap.repo.DmpRepo;
import at.ac.tuwien.damap.rest.dmp.domain.ContributorDO;
import at.ac.tuwien.damap.rest.dmp.domain.DmpDO;
import at.ac.tuwien.damap.rest.dmp.domain.DmpListItemDO;
import at.ac.tuwien.damap.rest.dmp.domain.IdentifierDO;
import at.ac.tuwien.damap.rest.dmp.domain.ProjectDO;
import at.ac.tuwien.damap.rest.dmp.mapper.ContributorDOMapper;
import at.ac.tuwien.damap.rest.dmp.mapper.DmpDOMapper;
import at.ac.tuwien.damap.rest.dmp.mapper.DmpListItemDOMapper;
import at.ac.tuwien.damap.rest.dmp.mapper.MapperService;
import at.ac.tuwien.damap.rest.dmp.mapper.ProjectSupplementDOMapper;
import at.ac.tuwien.damap.rest.persons.orcid.ORCIDPersonServiceImpl;
import at.ac.tuwien.damap.rest.projects.ProjectService;
import at.ac.tuwien.damap.rest.projects.ProjectSupplementDO;
import at.ac.tuwien.damap.rest.version.VersionDO;
import at.ac.tuwien.damap.rest.version.VersionService;
import lombok.extern.jbosslog.JBossLog;
import org.hibernate.envers.AuditReader;
import org.hibernate.envers.AuditReaderFactory;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@ApplicationScoped
@JBossLog
Expand All @@ -54,6 +59,9 @@ public class DmpService {
@Inject
VersionService versionService;

@Inject
ORCIDPersonServiceImpl orcidPersonService;

public List<DmpListItemDO> getAll() {

List<Dmp> dmpList = dmpRepo.getAll();
Expand Down Expand Up @@ -83,6 +91,7 @@ public DmpDO create(@Valid DmpDO dmpDO, String editedBy) {
DmpConsistencyUtility.enforceDmpConsistency(dmpDO);
Dmp dmp = DmpDOMapper.mapDOtoEntity(dmpDO, new Dmp(), mapperService);
dmp.setCreated(new Date());
fetchORCIDContributorInfo(dmp);
updateDmpSupplementalInfo(dmp);
updateProjectLead(dmp);
dmp.persistAndFlush();
Expand All @@ -98,6 +107,7 @@ public DmpDO update(@Valid DmpDO dmpDO) {
boolean projectSelectionChanged = projectSelectionChanged(dmp, dmpDO);
DmpDOMapper.mapDOtoEntity(dmpDO, dmp, mapperService);
dmp.setModified(new Date());
fetchORCIDContributorInfo(dmp);
if (projectSelectionChanged) {
updateDmpSupplementalInfo(dmp);
updateProjectLead(dmp);
Expand Down Expand Up @@ -145,8 +155,10 @@ public String getDefaultFileName(long id) {
Dmp dmp = dmpRepo.findById(id);
if (dmp != null) {
if (dmp.getProject() != null) {
if (dmp.getProject().getUniversityId() != null && projectService.read(dmp.getProject().getUniversityId()) != null) {
filename = "DMP_" + projectService.read(dmp.getProject().getUniversityId()).getAcronym() + "_" + formatter.format(date);
if (dmp.getProject().getUniversityId() != null
&& projectService.read(dmp.getProject().getUniversityId()) != null) {
filename = "DMP_" + projectService.read(dmp.getProject().getUniversityId()).getAcronym() + "_"
+ formatter.format(date);
} else if (dmp.getProject().getTitle() != null)
filename = "DMP_" + dmp.getProject().getTitle() + "_" + formatter.format(date);
} else {
Expand Down Expand Up @@ -174,8 +186,9 @@ public List<ProjectDO> checkExistingDmps(List<ProjectDO> projectDOList) {
return projectDOList;
}

// This method will retrieve the Project Supplement values from the connected CRIS System
// and it will reset them to null in case the project is not from a connected system.
// This method will retrieve the Project Supplement values from the connected
// CRIS System and it will reset them to null in case the project is not from a
// connected system.
private void updateDmpSupplementalInfo(Dmp dmp) {
if (dmp.getProject() != null) {
ProjectSupplementDO projectSupplementDO = null;
Expand All @@ -199,8 +212,7 @@ private void updateProjectLead(Dmp dmp) {
if (dmp.getProject() == null || dmp.getProject().getUniversityId() == null)
return;

ContributorDO projectLeaderDO =
projectService.getProjectLeader(dmp.getProject().getUniversityId());
ContributorDO projectLeaderDO = projectService.getProjectLeader(dmp.getProject().getUniversityId());
if (projectLeaderDO == null)
return;

Expand All @@ -211,8 +223,7 @@ private void updateProjectLead(Dmp dmp) {
projectLeaderDO.getUniversityId()))
.findFirst();

Contributor projectLeaderContributor =
alreadyExistingContributorLeader.orElse(new Contributor());
Contributor projectLeaderContributor = alreadyExistingContributorLeader.orElse(new Contributor());

// Adding project leader as contributor if it was not there yet.
if (alreadyExistingContributorLeader.isEmpty()) {
Expand All @@ -234,6 +245,21 @@ private void updateProjectLead(Dmp dmp) {
}
}

private void fetchORCIDContributorInfo(Dmp dmp) {
dmp.getContributorList().forEach(contributor -> {
// Existing contributor? Do not fetch data.
if (contributor.id != null) {
return;
}

var identifier = contributor.getPersonIdentifier();
if (identifier != null
&& identifier.getIdentifierType().equals(EIdentifierType.ORCID)) {
ContributorDOMapper.mapDOtoEntity(orcidPersonService.read(identifier.getIdentifier()), contributor);
}
});
}

private boolean projectSelectionChanged(Dmp dmp, DmpDO dmpDO) {

if (dmpDO.getProject() == null)
Expand Down
121 changes: 121 additions & 0 deletions src/main/java/at/ac/tuwien/damap/rest/persons/orcid/ORCIDMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package at.ac.tuwien.damap.rest.persons.orcid;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import at.ac.tuwien.damap.enums.EIdentifierType;
import at.ac.tuwien.damap.rest.dmp.domain.ContributorDO;
import at.ac.tuwien.damap.rest.dmp.domain.IdentifierDO;
import at.ac.tuwien.damap.rest.persons.orcid.models.ORCIDExpandedSearchPerson;
import at.ac.tuwien.damap.rest.persons.orcid.models.ORCIDRecord;
import at.ac.tuwien.damap.rest.persons.orcid.models.base.ORCIDAffiliation;
import at.ac.tuwien.damap.rest.persons.orcid.models.base.ORCIDDate;
import at.ac.tuwien.damap.rest.persons.orcid.models.base.ORCIDEmail;
import lombok.experimental.UtilityClass;

@UtilityClass
public class ORCIDMapper {
public ContributorDO mapExpandedSearchPersonEntityToDO(ORCIDExpandedSearchPerson orcidPerson,
ContributorDO contributorDO) {

contributorDO.setId(null);
contributorDO.setFirstName(orcidPerson.getGivenNames());
contributorDO.setLastName(orcidPerson.getFamilyNames());

String firstMail = orcidPerson.getEmails().isEmpty() ? null : orcidPerson.getEmails().get(0);
contributorDO.setMbox(firstMail);

String firstAffiliation = orcidPerson.getAffiliations().isEmpty() ? null
: orcidPerson.getAffiliations().get(0);
contributorDO.setAffiliation(firstAffiliation);

IdentifierDO identifierContributorDO = new IdentifierDO();
identifierContributorDO.setIdentifier(orcidPerson.getOrcidId());
identifierContributorDO.setType(EIdentifierType.ORCID);

contributorDO.setPersonId(identifierContributorDO);

return contributorDO;
}

public ContributorDO mapRecordEntityToPersonDO(ORCIDRecord orcidRecord,
ContributorDO contributorDO) {

contributorDO.setId(null);
contributorDO.setFirstName(orcidRecord.getPerson().getName().getGivenNames().getValue());
contributorDO.setLastName(orcidRecord.getPerson().getName().getFamilyName().getValue());

var primaryMail = orcidRecord.getPerson().getEmails().getEmail().stream().filter(ORCIDEmail::isPrimary)
.findFirst();
contributorDO.setMbox(primaryMail.isPresent() ? primaryMail.get().getEmail() : null);

List<ORCIDAffiliation> affiliations = new ArrayList<>();

for (var groupListItem : List.of(
orcidRecord.getActivitiesSummary().getEducations().getAffiliationGroup(),
orcidRecord.getActivitiesSummary().getEmployments().getAffiliationGroup())) {

for (var group : groupListItem) {

for (var summary : group.getSummaries()) {
affiliations.add(summary.getSummary());
}
}

}

if (!affiliations.isEmpty()) {
affiliations.sort(sortByCurrentStartDate);
contributorDO.setAffiliation(affiliations.get(affiliations.size() - 1).getOrganization().getName());
}

IdentifierDO identifierContributorDO = new IdentifierDO();
identifierContributorDO.setIdentifier(orcidRecord.getPerson().getName().getPath());
identifierContributorDO.setType(EIdentifierType.ORCID);

contributorDO.setPersonId(identifierContributorDO);
return contributorDO;
}

private final Comparator<? super ORCIDAffiliation> sortByCurrentStartDate = ((ORCIDAffiliation a,
ORCIDAffiliation b) -> {
ORCIDDate aEndDate = a.getEndDate();
ORCIDDate bEndDate = b.getEndDate();

// both end dates set, so we can directly compare
if (aEndDate != null && bEndDate != null) {
return aEndDate.getAsDate().compareTo(bEndDate.getAsDate());
}

// if only one is set, it means the other is current
if (aEndDate != null || bEndDate != null) {
if (aEndDate == null)
return 1;
if (bEndDate == null)
return -1;
}

// both end dates are null. lets compare via start date
ORCIDDate aStartDate = a.getStartDate();
ORCIDDate bStartDate = b.getStartDate();

// both start dates set. compare directly
if (aStartDate != null && bStartDate != null) {
return aStartDate.getAsDate().compareTo(bStartDate.getAsDate());
}

// basically nothing set. considered equal
if (aStartDate == null && bStartDate == null)
return 0;

// one not set.
if (aStartDate == null)
return 1;
if (bStartDate == null)
return -1;

// fall back. Should never reach this.
return 0;
});
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ORCIDPersonServiceImpl implements PersonService {

@Override
public ContributorDO read(String id, MultivaluedMap<String, String> queryParams) {
return ORCIDPersonMapper.mapEntityToDO(orcidRestClient.get(id), new ContributorDO());
return ORCIDMapper.mapRecordEntityToPersonDO(orcidRestClient.get(id), new ContributorDO());
}

@Override
Expand All @@ -39,7 +39,7 @@ public ResultList<ContributorDO> search(MultivaluedMap<String, String> queryPara
if (orcidSearch.getNumFound() > 0 && orcidSearch.getPersons() != null) {
contributors = orcidSearch.getPersons().stream().map(o -> {
var c = new ContributorDO();
ORCIDPersonMapper.mapEntityToDO(o, c);
ORCIDMapper.mapExpandedSearchPersonEntityToDO(o, c);
return c;
}).collect(Collectors.toList());
}
Expand All @@ -48,6 +48,5 @@ public ResultList<ContributorDO> search(MultivaluedMap<String, String> queryPara
}

return ResultList.fromItemsAndSearch(contributors, search);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import at.ac.tuwien.damap.rest.persons.orcid.models.ORCIDExpandedSearchResult;
import at.ac.tuwien.damap.rest.persons.orcid.models.ORCIDRecord;

@RegisterRestClient(configKey = "rest.orcid.search")
@Path("/v3.0")
@Produces(MediaType.APPLICATION_JSON)
Expand All @@ -20,8 +23,8 @@ public interface OrcidPersonService {
@ClientHeaderParam(name = "accept", value = MediaType.APPLICATION_JSON)
ORCIDExpandedSearchResult getAll(@QueryParam("q") String query, @QueryParam("rows") int rows);

@Path("/{orcid}/person")
@Path("/{orcid}/record")
@GET
@ClientHeaderParam(name = "accept", value = MediaType.APPLICATION_JSON)
ORCIDPerson get(@PathParam(value = "orcid") String orcid);
ORCIDRecord get(@PathParam(value = "orcid") String orcid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package at.ac.tuwien.damap.rest.persons.orcid.models;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.Data;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ORCIDActivitiesSummary {
@JsonProperty
ORCIDAffiliationGroup<ORCIDEmploymentSummary> employments;

@JsonProperty
ORCIDAffiliationGroup<ORCIDEducationSummary> educations;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package at.ac.tuwien.damap.rest.persons.orcid.models;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;

import lombok.Data;

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class ORCIDAffiliationGroup<S extends ORCIDAffiliationSummary> {
@JsonProperty(value = "affiliation-group")
@JsonSetter(nulls = Nulls.AS_EMPTY)
List<ORCIDGroup<S>> affiliationGroup;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package at.ac.tuwien.damap.rest.persons.orcid.models;

import at.ac.tuwien.damap.rest.persons.orcid.models.base.ORCIDAffiliation;

public interface ORCIDAffiliationSummary {
ORCIDAffiliation getSummary();
}
Loading

0 comments on commit 9dfaafa

Please sign in to comment.