Skip to content

Commit

Permalink
merge ORCID API_v3.0 into master
Browse files Browse the repository at this point in the history
  • Loading branch information
rpereira-fccn committed Nov 30, 2021
1 parent f692593 commit 01d6def
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 72 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<modelVersion>4.0.0</modelVersion>
<groupId>pt.ptcris</groupId>
<artifactId>ptcrisync</artifactId>
<version>1.0</version>
<version>1.1</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<orcid-api-client.version>2.0</orcid-api-client.version>
<orcid-api-client.version>3.0</orcid-api-client.version>
<logback-version>1.1.9</logback-version>
<junit.version>4.12</junit.version>
</properties>
Expand Down
91 changes: 84 additions & 7 deletions src/main/java/pt/ptcris/PTCRISync.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
import org.um.dsi.gavea.orcid.model.common.ElementSummary;
import org.um.dsi.gavea.orcid.model.common.ExternalId;
import org.um.dsi.gavea.orcid.model.common.ExternalIds;
import org.um.dsi.gavea.orcid.model.common.FundingType;
import org.um.dsi.gavea.orcid.model.common.WorkType;
import org.um.dsi.gavea.orcid.model.funding.Funding;
import org.um.dsi.gavea.orcid.model.funding.FundingType;
import org.um.dsi.gavea.orcid.model.person.externalidentifier.ExternalIdentifier;
import org.um.dsi.gavea.orcid.model.work.Work;
import org.um.dsi.gavea.orcid.model.work.WorkType;
import org.um.dsi.gavea.orcid.model.work.WorkSummary;

import pt.ptcris.exceptions.InvalidActivityException;
import pt.ptcris.handlers.ProgressHandler;
Expand Down Expand Up @@ -517,6 +518,7 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
// detect which remote works should be deleted or updated
handler.setCurrentStatus("ORCID_SYNC_EXPORT_ITERATION",orcids.size());
List<UpdateRecord<E,S>> toUpdate = new LinkedList<UpdateRecord<E,S>>();
List<UpdateRecord<E,S>> toUpdateFundedBy = new LinkedList<UpdateRecord<E,S>>();
for (int c = 0; c != orcids.size(); c++) {
S orcid = orcids.get(c);

Expand All @@ -528,14 +530,24 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
}
// there is at least one local work matching a CRIS sourced remote work
else {
boolean isIncluded = false;
E local = worksDiffs.keySet().iterator().next();
// if the remote work is not up-to-date or forced updates
if (forced || !helper.isUpToDateS(local, orcid))
if (forced || !helper.isUpToDateS(local, orcid)) {
toUpdate.add(new UpdateRecord<E,S>(local, orcid, worksDiffs.get(local)));
isIncluded = true;
}
else
result.put(ORCIDHelper.getActivityLocalKey(local, BigInteger.valueOf(c)),
PTCRISyncResult.<E>uptodate());
locals.remove(local);

// if the remote work isn't update in what concerns of FundedBy identifiers
ExternalIdsDiff fundedByExternalIdsDiff = helper.getFundedByExternalIdsDiff(local, orcid);
if (!isIncluded && (forced || !(fundedByExternalIdsDiff.more.isEmpty() && fundedByExternalIdsDiff.less.isEmpty())) ) {
fundedByExternalIdsDiff.same.addAll(worksDiffs.get(local).same);
toUpdateFundedBy.add(new UpdateRecord<E,S>(local, orcid, fundedByExternalIdsDiff));
}
}
handler.step();
}
Expand All @@ -551,6 +563,7 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
ExternalIds weids = new ExternalIds();
List<ExternalId> ids = new ArrayList<ExternalId>(update.eidsDiff.same);
ids.addAll(helper.getPartOfExternalIdsE(local).getExternalId());
ids.addAll(helper.getFundedByExternalIdsE(local).getExternalId());
weids.setExternalId(ids);
helper.setExternalIdsE(local,weids);

Expand All @@ -559,6 +572,9 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
}
handler.step();
}

// Outputs with changes only on "Funded by" identifiers. first update phase, remove spurious identifiers.
treatOuputWithChangesOnlyOnFundedBy_1Phase(helper, handler, result, toUpdateFundedBy);

// second update phase, add missing identifiers
handler.setCurrentStatus("ORCID_SYNC_EXPORT_UPDATING_PHASE_2",toUpdate.size());
Expand All @@ -572,6 +588,7 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
List<ExternalId> ids = new ArrayList<ExternalId>(update.eidsDiff.same);
ids.addAll(update.eidsDiff.less);
ids.addAll(helper.getPartOfExternalIdsE(local).getExternalId());
ids.addAll(helper.getFundedByExternalIdsE(local).getExternalId());
weids.setExternalId(ids);
helper.setExternalIdsE(local,weids);

Expand All @@ -581,6 +598,9 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
handler.step();
}

// Outputs with changes only on "Funded by" identifiers. second update phase, add missing identifiers
treatOuputWithChangesOnlyOnFundedBy_2Phase(helper, handler, result, toUpdateFundedBy);

// add the local works that had no match
// the progress handler must be moved to the helper due to bulk additions
handler.setCurrentStatus("ORCID_SYNC_EXPORT_ADDING",locals.size());
Expand All @@ -594,6 +614,52 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
return result;
}

private static <E extends ElementSummary, S extends ElementSummary, G, T extends Enum<T>> void treatOuputWithChangesOnlyOnFundedBy_2Phase(
ORCIDHelper<E, S, G, T> helper, ProgressHandler handler, Map<BigInteger, PTCRISyncResult<E>> result,
List<UpdateRecord<E, S>> toUpdateFundedBy) {
for (int c = 0; c != toUpdateFundedBy.size(); c++) {

// the remote work is missing external identifiers or not updated in the 1st phase
UpdateRecord<E,S> update = toUpdateFundedBy.get(c);
if (!update.eidsDiff.less.isEmpty() || update.eidsDiff.more.isEmpty()) {
E local = update.preElement;
ExternalIds weids = new ExternalIds();
List<ExternalId> ids = new ArrayList<ExternalId>(update.eidsDiff.same);
ids.addAll(update.eidsDiff.less);
ids.addAll(helper.getPartOfExternalIdsE(local).getExternalId());
weids.setExternalId(ids);
helper.setExternalIdsE(local,weids);

PTCRISyncResult<E> res = helper.update(update.posElement.getPutCode(), local);
result.put(ORCIDHelper.getActivityLocalKey(local, BigInteger.valueOf(c)),res);
}
handler.step();
}
}

private static <E extends ElementSummary, S extends ElementSummary, G, T extends Enum<T>> void treatOuputWithChangesOnlyOnFundedBy_1Phase(
ORCIDHelper<E, S, G, T> helper, ProgressHandler handler, Map<BigInteger, PTCRISyncResult<E>> result,
List<UpdateRecord<E, S>> toUpdateFundedBy) {
for (int c = 0; c != toUpdateFundedBy.size(); c++) {

UpdateRecord<E,S> update = toUpdateFundedBy.get(c);
// the remote work has spurious external identifiers
if (!update.eidsDiff.more.isEmpty()) {
E local = update.preElement;
ExternalIds weids = new ExternalIds();
List<ExternalId> ids = new ArrayList<ExternalId>(update.eidsDiff.same);
ids.addAll(helper.getPartOfExternalIdsE(local).getExternalId());
weids.setExternalId(ids);
helper.setExternalIdsE(local,weids);

PTCRISyncResult<E> res = helper.update(update.posElement.getPutCode(), local);
result.put(ORCIDHelper.getActivityLocalKey(local, BigInteger.valueOf(c)),res);
}
handler.step();

}
}

/**
* <p>
* Discovers new valid works in an ORCID profile given a set of known local
Expand Down Expand Up @@ -1265,9 +1331,14 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
* @throws IllegalArgumentException
* if null arguments
*/
public static List<Work> importWorkUpdates(ORCIDClient client, List<Work> locals, ProgressHandler handler, List<Work> orcids)
throws OrcidClientException, IllegalArgumentException {
return importUpdatesBase(new ORCIDWorkHelper(client), locals, Arrays.asList(WorkType.values()), handler, orcids);
}

public static List<Work> importWorkUpdates(ORCIDClient client, List<Work> locals, ProgressHandler handler)
throws OrcidClientException, IllegalArgumentException {
return importUpdatesBase(new ORCIDWorkHelper(client), locals, Arrays.asList(WorkType.values()), handler);
return importUpdatesBase(new ORCIDWorkHelper(client), locals, Arrays.asList(WorkType.values()), handler, new ArrayList<>());
}

/**
Expand All @@ -1292,7 +1363,7 @@ public static List<Work> importWorkUpdates(ORCIDClient client, List<Work> locals
@Deprecated
public static List<Work> importUpdates(ORCIDClient client, List<Work> locals, ProgressHandler handler)
throws OrcidClientException, IllegalArgumentException {
return importWorkUpdates(client, locals, handler);
return importWorkUpdates(client, locals, handler, new ArrayList<>());
}

/**
Expand Down Expand Up @@ -1360,7 +1431,7 @@ public static List<Work> importUpdates(ORCIDClient client, List<Work> locals, Pr
*/
public static List<Funding> importFundingUpdates(ORCIDClient client, List<Funding> locals, Collection<FundingType> types, ProgressHandler handler)
throws OrcidClientException, IllegalArgumentException {
return importUpdatesBase(new ORCIDFundingHelper(client), locals, types, handler);
return importUpdatesBase(new ORCIDFundingHelper(client), locals, types, handler, new ArrayList<>());
}

/**
Expand Down Expand Up @@ -1429,7 +1500,7 @@ public static List<Funding> importFundingUpdates(ORCIDClient client, List<Fundin
*/
private static <E extends ElementSummary, S extends ElementSummary, G, T extends Enum<T>> List<E> importUpdatesBase(
ORCIDHelper<E, S, G, T> helper, List<E> locals,
Collection<T> types, ProgressHandler handler)
Collection<T> types, ProgressHandler handler, List<E> toUpdateFundedBy )
throws OrcidClientException, IllegalArgumentException {

if (helper == null || locals == null || handler == null)
Expand All @@ -1455,8 +1526,14 @@ private static <E extends ElementSummary, S extends ElementSummary, G, T extends
if (!helper.hasNewSelfIDs(mathingLocal, orcid)) {
toUpdate.add(helper.createUpdate(mathingLocal, matchingLocals.get(mathingLocal)));
}

ExternalIdsDiff fundedByIDs = helper.getFundedByExternalIdsDiff(mathingLocal, orcid);
if (!fundedByIDs.more.isEmpty()) {
toUpdateFundedBy.add(helper.createUpdate(mathingLocal, fundedByIDs));
}
}
}

handler.step();
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/pt/ptcris/utils/ORCIDFundingHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import org.um.dsi.gavea.orcid.model.activities.FundingGroup;
import org.um.dsi.gavea.orcid.model.common.ExternalId;
import org.um.dsi.gavea.orcid.model.common.ExternalIds;
import org.um.dsi.gavea.orcid.model.common.FundingType;
import org.um.dsi.gavea.orcid.model.funding.Funding;
import org.um.dsi.gavea.orcid.model.funding.FundingSummary;
import org.um.dsi.gavea.orcid.model.funding.FundingType;

import pt.ptcris.ORCIDClient;
import pt.ptcris.PTCRISyncResult;
Expand Down Expand Up @@ -198,7 +198,7 @@ protected String getYearS(FundingSummary summary) {
if (summary.getStartDate() == null
|| summary.getStartDate().getYear() == null)
return null;
return summary.getStartDate().getYear().getValue();
return String.valueOf(summary.getStartDate().getYear().getValue());
}

/** {@inheritDoc} */
Expand Down
55 changes: 47 additions & 8 deletions src/main/java/pt/ptcris/utils/ORCIDHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,21 @@
import org.um.dsi.gavea.orcid.model.common.ElementSummary;
import org.um.dsi.gavea.orcid.model.common.ExternalId;
import org.um.dsi.gavea.orcid.model.common.ExternalIds;
import org.um.dsi.gavea.orcid.model.common.FundingType;
import org.um.dsi.gavea.orcid.model.common.FuzzyDate;
import org.um.dsi.gavea.orcid.model.common.RelationshipType;
import org.um.dsi.gavea.orcid.model.common.Relationship;
import org.um.dsi.gavea.orcid.model.common.WorkType;
import org.um.dsi.gavea.orcid.model.funding.Funding;
import org.um.dsi.gavea.orcid.model.funding.FundingSummary;
import org.um.dsi.gavea.orcid.model.funding.FundingType;
import org.um.dsi.gavea.orcid.model.person.externalidentifier.ExternalIdentifier;
import org.um.dsi.gavea.orcid.model.work.Work;
import org.um.dsi.gavea.orcid.model.work.WorkSummary;
import org.um.dsi.gavea.orcid.model.work.WorkType;

import pt.ptcris.ORCIDClient;
import pt.ptcris.PTCRISyncResult;
import pt.ptcris.exceptions.InvalidActivityException;
import pt.ptcris.handlers.ProgressHandler;
import pt.ptcris.utils.ORCIDWorkHelper.EIdType;

/**
* An abstract helper to help manage ORCID activities and simplify the usage of
Expand Down Expand Up @@ -892,7 +893,27 @@ final ExternalIds getPartOfExternalIdsS(S summary) {

List<ExternalId> res = new ArrayList<ExternalId>();
for (ExternalId eid : getNonNullExternalIdsS(summary).getExternalId())
if (eid.getExternalIdRelationship() == RelationshipType.PART_OF)
if (eid.getExternalIdRelationship() == Relationship.PART_OF)
res.add(eid);
return new ExternalIds(res);
}

/**
* Returns the non-null funded-by external identifiers of an activity summary
* (null becomes empty list).
*
* @param summary
* the ORCID activity summary from which to retrieve the external
* identifiers
* @return the non-null part-of external identifiers
*/
final ExternalIds getFundedByExternalIdsS(S summary) {
if (summary == null)
throw new IllegalArgumentException("Null element.");

List<ExternalId> res = new ArrayList<ExternalId>();
for (ExternalId eid : getNonNullExternalIdsS(summary).getExternalId())
if (eid.getExternalIdRelationship() == Relationship.FUNDED_BY && eid.getExternalIdType().equalsIgnoreCase(EIdType.DOI.value))
res.add(eid);
return new ExternalIds(res);
}
Expand Down Expand Up @@ -926,7 +947,7 @@ final ExternalIds getSelfExternalIdsS(S summary) {

List<ExternalId> res = new ArrayList<ExternalId>();
for (ExternalId eid : getNonNullExternalIdsS(summary).getExternalId())
if (eid.getExternalIdRelationship() == RelationshipType.SELF)
if (eid.getExternalIdRelationship() == Relationship.SELF)
res.add(eid);
return new ExternalIds(res);
}
Expand Down Expand Up @@ -973,6 +994,12 @@ public final Map<E, ExternalIdsDiff> getSelfExternalIdsDiffS(S summary, Collecti
}
return matches;
}


public final ExternalIds getFundedByExternalIdsE(E activity) {
return getFundedByExternalIdsS(summarize(activity));
}


/**
* Tests whether two sets of (non-exclusively self or part-of) external
Expand Down Expand Up @@ -1020,6 +1047,18 @@ public final boolean hasNewSelfIDs(E preElement, S posElement) {

return diff.more.isEmpty();
}


public final ExternalIdsDiff getFundedByExternalIdsDiff(E preElement, S posElement) {
if (preElement == null || posElement == null)
throw new IllegalArgumentException("Null element.");

final ExternalIdsDiff diff = new ExternalIdsDiff(
getFundedByExternalIdsE(preElement),
getFundedByExternalIdsS(posElement));

return diff;
}

/**
* Checks whether an activity is already up to date regarding another one,
Expand Down Expand Up @@ -1143,11 +1182,11 @@ public final Set<String> testMinimalQuality(S summary) {
* @return whether the date is well formed
*/
static boolean testQualityFuzzyDate(FuzzyDate date) {
if (date.getYear() != null && date.getYear().getValue().length() != 4)
if (date.getYear() != null && String.valueOf(date.getYear().getValue()).length() != 4)
return false;
if (date.getMonth() != null && date.getMonth().getValue().length() != 2)
if (date.getMonth() != null && date.getMonth().getValue() < 1 && date.getMonth().getValue() > 12 )
return false;
if (date.getDay() != null && date.getDay().getValue().length() != 2)
if (date.getDay() != null && date.getDay().getValue() < 1 && date.getDay().getValue() > 31)
return false;

return true;
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/pt/ptcris/utils/ORCIDWorkHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.um.dsi.gavea.orcid.client.exception.OrcidClientException;
import org.um.dsi.gavea.orcid.model.activities.WorkGroup;
import org.um.dsi.gavea.orcid.model.common.ExternalId;
import org.um.dsi.gavea.orcid.model.common.ExternalIds;
import org.um.dsi.gavea.orcid.model.common.WorkType;
import org.um.dsi.gavea.orcid.model.work.Work;
import org.um.dsi.gavea.orcid.model.work.WorkSummary;
import org.um.dsi.gavea.orcid.model.work.WorkType;

import pt.ptcris.ORCIDClient;
import pt.ptcris.PTCRISyncResult;
Expand Down Expand Up @@ -235,7 +236,7 @@ protected String getYearS(WorkSummary summary) {
if (summary.getPublicationDate() == null
|| summary.getPublicationDate().getYear() == null)
return null;
return summary.getPublicationDate().getYear().getValue();
return String.valueOf(summary.getPublicationDate().getYear().getValue());
}

/** {@inheritDoc} */
Expand All @@ -257,13 +258,28 @@ protected WorkSummary group(WorkGroup group) throws IllegalArgumentException {

final List<ExternalId> eids = getPartOfExternalIdsS(dummy)
.getExternalId();

addFundedByEidsFromAllWorkSummaries(group, eids);

for (ExternalId id : group.getExternalIds().getExternalId())
eids.add(clone(id));
dummy.setExternalIds(new ExternalIds(eids));

return dummy;
}

private void addFundedByEidsFromAllWorkSummaries(WorkGroup group, final List<ExternalId> eids) {
Set<String> set = new HashSet<>(eids.size());
for (int i = 0 ; i < group.getWorkSummary().size(); i++){
WorkSummary cloned = cloneS(group.getWorkSummary().get(i));
List<ExternalId> fundedByEids = getFundedByExternalIdsS(cloned).getExternalId();
List<ExternalId> fundedByEidsWithoutDuplicates = fundedByEids.stream()
.filter(eid -> set.add(eid.getExternalIdValue()))
.collect(Collectors.toList());
eids.addAll(fundedByEidsWithoutDuplicates);
}
}

/**
* {@inheritDoc}
*
Expand Down
Loading

0 comments on commit 01d6def

Please sign in to comment.