/**
* =============================================================================
*
* ORCID (R) Open Source
* http://orcid.org
*
* Copyright (c) 2012-2014 ORCID, Inc.
* Licensed under an MIT-Style License (MIT)
* http://orcid.org/open-source-license
*
* This copyright and license information (including a link to the full license)
* shall be included in its entirety in all copies or substantial portion of
* the software.
*
* =============================================================================
*/
package org.orcid.api.memberV2.server.delegator.impl;
import static org.orcid.core.api.OrcidApiConstants.STATUS_OK_MESSAGE;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.annotation.Resource;
import javax.ws.rs.core.Response;
import org.orcid.api.common.util.ActivityUtils;
import org.orcid.api.common.util.ElementUtils;
import org.orcid.api.memberV2.server.delegator.MemberV2ApiServiceDelegator;
import org.orcid.core.exception.MismatchedPutCodeException;
import org.orcid.core.exception.OrcidAccessControlException;
import org.orcid.core.exception.OrcidBadRequestException;
import org.orcid.core.exception.OrcidNoBioException;
import org.orcid.core.exception.OrcidNoResultException;
import org.orcid.core.locale.LocaleManager;
import org.orcid.core.manager.AddressManager;
import org.orcid.core.manager.AffiliationsManager;
import org.orcid.core.manager.ExternalIdentifierManager;
import org.orcid.core.manager.GroupIdRecordManager;
import org.orcid.core.manager.OrcidSearchManager;
import org.orcid.core.manager.OrcidSecurityManager;
import org.orcid.core.manager.OtherNameManager;
import org.orcid.core.manager.PeerReviewManager;
import org.orcid.core.manager.ProfileEntityManager;
import org.orcid.core.manager.ProfileFundingManager;
import org.orcid.core.manager.ProfileKeywordManager;
import org.orcid.core.manager.ResearcherUrlManager;
import org.orcid.core.manager.WorkManager;
import org.orcid.core.manager.read_only.ActivitiesSummaryManagerReadOnly;
import org.orcid.core.manager.read_only.AddressManagerReadOnly;
import org.orcid.core.manager.read_only.AffiliationsManagerReadOnly;
import org.orcid.core.manager.read_only.BiographyManagerReadOnly;
import org.orcid.core.manager.read_only.ClientDetailsManagerReadOnly;
import org.orcid.core.manager.read_only.EmailManagerReadOnly;
import org.orcid.core.manager.read_only.ExternalIdentifierManagerReadOnly;
import org.orcid.core.manager.read_only.GroupIdRecordManagerReadOnly;
import org.orcid.core.manager.read_only.OtherNameManagerReadOnly;
import org.orcid.core.manager.read_only.PeerReviewManagerReadOnly;
import org.orcid.core.manager.read_only.PersonDetailsManagerReadOnly;
import org.orcid.core.manager.read_only.PersonalDetailsManagerReadOnly;
import org.orcid.core.manager.read_only.ProfileFundingManagerReadOnly;
import org.orcid.core.manager.read_only.ProfileKeywordManagerReadOnly;
import org.orcid.core.manager.read_only.RecordManagerReadOnly;
import org.orcid.core.manager.read_only.ResearcherUrlManagerReadOnly;
import org.orcid.core.manager.read_only.WorkManagerReadOnly;
import org.orcid.core.utils.ContributorUtils;
import org.orcid.core.utils.SourceUtils;
import org.orcid.core.version.impl.Api2_0_LastModifiedDatesHelper;
import org.orcid.jaxb.model.client_v2.Client;
import org.orcid.jaxb.model.groupid_v2.GroupIdRecord;
import org.orcid.jaxb.model.groupid_v2.GroupIdRecords;
import org.orcid.jaxb.model.message.ScopePathType;
import org.orcid.jaxb.model.record.summary_v2.ActivitiesSummary;
import org.orcid.jaxb.model.record.summary_v2.EducationSummary;
import org.orcid.jaxb.model.record.summary_v2.Educations;
import org.orcid.jaxb.model.record.summary_v2.EmploymentSummary;
import org.orcid.jaxb.model.record.summary_v2.Employments;
import org.orcid.jaxb.model.record.summary_v2.FundingSummary;
import org.orcid.jaxb.model.record.summary_v2.Fundings;
import org.orcid.jaxb.model.record.summary_v2.PeerReviewSummary;
import org.orcid.jaxb.model.record.summary_v2.PeerReviews;
import org.orcid.jaxb.model.record.summary_v2.WorkSummary;
import org.orcid.jaxb.model.record.summary_v2.Works;
import org.orcid.jaxb.model.record_v2.Address;
import org.orcid.jaxb.model.record_v2.Addresses;
import org.orcid.jaxb.model.record_v2.Biography;
import org.orcid.jaxb.model.record_v2.Education;
import org.orcid.jaxb.model.record_v2.Email;
import org.orcid.jaxb.model.record_v2.Emails;
import org.orcid.jaxb.model.record_v2.Employment;
import org.orcid.jaxb.model.record_v2.Funding;
import org.orcid.jaxb.model.record_v2.Keyword;
import org.orcid.jaxb.model.record_v2.Keywords;
import org.orcid.jaxb.model.record_v2.OtherName;
import org.orcid.jaxb.model.record_v2.OtherNames;
import org.orcid.jaxb.model.record_v2.PeerReview;
import org.orcid.jaxb.model.record_v2.Person;
import org.orcid.jaxb.model.record_v2.PersonExternalIdentifier;
import org.orcid.jaxb.model.record_v2.PersonExternalIdentifiers;
import org.orcid.jaxb.model.record_v2.PersonalDetails;
import org.orcid.jaxb.model.record_v2.Record;
import org.orcid.jaxb.model.record_v2.ResearcherUrl;
import org.orcid.jaxb.model.record_v2.ResearcherUrls;
import org.orcid.jaxb.model.record_v2.Work;
import org.orcid.jaxb.model.record_v2.WorkBulk;
import org.orcid.jaxb.model.search_v2.Search;
import org.orcid.persistence.jpa.entities.ProfileEntity;
import org.springframework.stereotype.Component;
/**
* <p/>
* The delegator for the tier 2 API.
* <p/>
* The T2 delegator is responsible for the validation, retrieving results and
* passing of objects to be from the core
*
* @author Declan Newman (declan) Date: 07/03/2012
*/
@Component("orcidT2ServiceDelegator")
public class MemberV2ApiServiceDelegatorImpl implements
MemberV2ApiServiceDelegator<Education, Employment, PersonExternalIdentifier, Funding, GroupIdRecord, OtherName, PeerReview, ResearcherUrl, Work, WorkBulk, Address, Keyword> {
// Managers that goes to the primary database
@Resource
private WorkManager workManager;
@Resource
private ProfileFundingManager profileFundingManager;
@Resource
private ProfileEntityManager profileEntityManager;
@Resource
private AffiliationsManager affiliationsManager;
@Resource
private PeerReviewManager peerReviewManager;
@Resource
private OrcidSecurityManager orcidSecurityManager;
@Resource
private GroupIdRecordManager groupIdRecordManager;
@Resource
private LocaleManager localeManager;
@Resource
private ResearcherUrlManager researcherUrlManager;
@Resource
private OtherNameManager otherNameManager;
@Resource
private ExternalIdentifierManager externalIdentifierManager;
@Resource
private ProfileKeywordManager profileKeywordManager;
@Resource
private AddressManager addressManager;
@Resource
private SourceUtils sourceUtils;
@Resource
private ContributorUtils contributorUtils;
@Resource
private OrcidSearchManager orcidSearchManager;
// Managers that goes to the replication database
// Activities managers
@Resource
private WorkManagerReadOnly workManagerReadOnly;
@Resource
private ProfileFundingManagerReadOnly profileFundingManagerReadOnly;
@Resource
private AffiliationsManagerReadOnly affiliationsManagerReadOnly;
@Resource
private PeerReviewManagerReadOnly peerReviewManagerReadOnly;
@Resource
private ActivitiesSummaryManagerReadOnly activitiesSummaryManagerReadOnly;
// Person managers
@Resource
private ResearcherUrlManagerReadOnly researcherUrlManagerReadOnly;
@Resource
private OtherNameManagerReadOnly otherNameManagerReadOnly;
@Resource
private EmailManagerReadOnly emailManagerReadOnly;
@Resource
private ExternalIdentifierManagerReadOnly externalIdentifierManagerReadOnly;
@Resource
private PersonalDetailsManagerReadOnly personalDetailsManagerReadOnly;
@Resource
private ProfileKeywordManagerReadOnly profileKeywordManagerReadOnly;
@Resource
private AddressManagerReadOnly addressManagerReadOnly;
@Resource
private BiographyManagerReadOnly biographyManagerReadOnly;
@Resource
private PersonDetailsManagerReadOnly personDetailsManagerReadOnly;
// Record manager
@Resource
private RecordManagerReadOnly recordManagerReadOnly;
// Other managers
@Resource
private GroupIdRecordManagerReadOnly groupIdRecordManagerReadOnly;
@Resource
private ClientDetailsManagerReadOnly clientDetailsManagerReadOnly;
private long getLastModifiedTime(String orcid) {
return profileEntityManager.getLastModified(orcid);
}
@Override
public Response viewStatusText() {
return Response.ok(STATUS_OK_MESSAGE).build();
}
@Override
public Response viewRecord(String orcid) {
Record record = recordManagerReadOnly.getRecord(orcid);
orcidSecurityManager.checkAndFilter(orcid, record);
if (record.getPerson() != null) {
sourceUtils.setSourceName(record.getPerson());
}
if (record.getActivitiesSummary() != null) {
ActivityUtils.cleanEmptyFields(record.getActivitiesSummary());
sourceUtils.setSourceName(record.getActivitiesSummary());
}
ElementUtils.setPathToRecord(record, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(record);
return Response.ok(record).build();
}
@Override
public Response viewActivities(String orcid) {
ActivitiesSummary as = activitiesSummaryManagerReadOnly.getActivitiesSummary(orcid);
orcidSecurityManager.checkAndFilter(orcid, as);
ActivityUtils.cleanEmptyFields(as);
ActivityUtils.setPathToActivity(as, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(as);
sourceUtils.setSourceName(as);
return Response.ok(as).build();
}
@Override
public Response viewWork(String orcid, Long putCode) {
Work w = workManagerReadOnly.getWork(orcid, putCode, getLastModifiedTime(orcid));
orcidSecurityManager.checkAndFilter(orcid, w, ScopePathType.ORCID_WORKS_READ_LIMITED);
ActivityUtils.cleanEmptyFields(w);
ActivityUtils.setPathToActivity(w, orcid);
sourceUtils.setSourceName(w);
contributorUtils.filterContributorPrivateData(w);
return Response.ok(w).build();
}
@Override
public Response viewWorks(String orcid) {
List<WorkSummary> worksList = workManagerReadOnly.getWorksSummaryList(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
List<WorkSummary> filteredList = null;
if (worksList != null) {
filteredList = new ArrayList<WorkSummary>(worksList);
}
worksList = filteredList;
orcidSecurityManager.checkAndFilter(orcid, worksList, ScopePathType.ORCID_WORKS_READ_LIMITED);
Works works = workManager.groupWorks(worksList, false);
Api2_0_LastModifiedDatesHelper.calculateLastModified(works);
ActivityUtils.cleanEmptyFields(works);
ActivityUtils.setPathToWorks(works, orcid);
sourceUtils.setSourceName(works);
return Response.ok(works).build();
}
@Override
public Response viewWorkSummary(String orcid, Long putCode) {
WorkSummary ws = workManagerReadOnly.getWorkSummary(orcid, putCode, getLastModifiedTime(orcid));
orcidSecurityManager.checkAndFilter(orcid, ws, ScopePathType.ORCID_WORKS_READ_LIMITED);
ActivityUtils.cleanEmptyFields(ws);
ActivityUtils.setPathToActivity(ws, orcid);
sourceUtils.setSourceName(ws);
return Response.ok(ws).build();
}
@Override
public Response createWork(String orcid, Work work) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_WORKS_CREATE);
Work w = workManager.createWork(orcid, work, true);
sourceUtils.setSourceName(w);
try {
return Response.created(new URI(String.valueOf(w.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.creatework_response.exception"), e);
}
}
@Override
public Response updateWork(String orcid, Long putCode, Work work) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_WORKS_UPDATE);
if (!putCode.equals(work.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(work.getPutCode()));
throw new MismatchedPutCodeException(params);
}
Work w = workManager.updateWork(orcid, work, true);
sourceUtils.setSourceName(w);
return Response.ok(w).build();
}
@Override
public Response createWorks(String orcid, WorkBulk works) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_WORKS_CREATE);
works = workManager.createWorks(orcid, works);
sourceUtils.setSourceName(works);
return Response.ok(works).build();
}
@Override
public Response deleteWork(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_WORKS_UPDATE);
workManager.checkSourceAndRemoveWork(orcid, putCode);
return Response.noContent().build();
}
@Override
public Response viewFunding(String orcid, Long putCode) {
Funding f = profileFundingManagerReadOnly.getFunding(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, f, ScopePathType.FUNDING_READ_LIMITED);
ActivityUtils.setPathToActivity(f, orcid);
sourceUtils.setSourceName(f);
contributorUtils.filterContributorPrivateData(f);
return Response.ok(f).build();
}
@Override
public Response viewFundings(String orcid) {
List<FundingSummary> fundingSummaries = profileFundingManagerReadOnly.getFundingSummaryList(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
List<FundingSummary> filteredList = null;
if (fundingSummaries != null) {
filteredList = new ArrayList<FundingSummary>(fundingSummaries);
}
fundingSummaries = filteredList;
orcidSecurityManager.checkAndFilter(orcid, fundingSummaries, ScopePathType.FUNDING_READ_LIMITED);
Fundings fundings = profileFundingManager.groupFundings(fundingSummaries, false);
ActivityUtils.setPathToFundings(fundings, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(fundings);
sourceUtils.setSourceName(fundings);
return Response.ok(fundings).build();
}
@Override
public Response viewFundingSummary(String orcid, Long putCode) {
FundingSummary fs = profileFundingManagerReadOnly.getSummary(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, fs, ScopePathType.FUNDING_READ_LIMITED);
ActivityUtils.setPathToActivity(fs, orcid);
sourceUtils.setSourceName(fs);
return Response.ok(fs).build();
}
@Override
public Response createFunding(String orcid, Funding funding) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.FUNDING_CREATE);
Funding f = profileFundingManager.createFunding(orcid, funding, true);
sourceUtils.setSourceName(f);
try {
return Response.created(new URI(String.valueOf(f.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createfunding_response.exception"), e);
}
}
@Override
public Response updateFunding(String orcid, Long putCode, Funding funding) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.FUNDING_UPDATE);
if (!putCode.equals(funding.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(funding.getPutCode()));
throw new MismatchedPutCodeException(params);
}
Funding f = profileFundingManager.updateFunding(orcid, funding, true);
sourceUtils.setSourceName(f);
return Response.ok(f).build();
}
@Override
public Response deleteFunding(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.FUNDING_UPDATE);
profileFundingManager.checkSourceAndDelete(orcid, putCode);
return Response.noContent().build();
}
@Override
public Response viewEducation(String orcid, Long putCode) {
Education e = affiliationsManagerReadOnly.getEducationAffiliation(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, e, ScopePathType.AFFILIATIONS_READ_LIMITED);
ActivityUtils.setPathToActivity(e, orcid);
sourceUtils.setSourceName(e);
return Response.ok(e).build();
}
@Override
public Response viewEducations(String orcid) {
List<EducationSummary> educationsList = affiliationsManagerReadOnly.getEducationSummaryList(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
List<EducationSummary> filteredList = null;
if (educationsList != null) {
filteredList = new ArrayList<EducationSummary>(educationsList);
}
educationsList = filteredList;
orcidSecurityManager.checkAndFilter(orcid, educationsList, ScopePathType.AFFILIATIONS_READ_LIMITED);
Educations educations = new Educations(educationsList);
ActivityUtils.setPathToEducations(educations, orcid);
sourceUtils.setSourceName(educations);
Api2_0_LastModifiedDatesHelper.calculateLastModified(educations);
return Response.ok(educations).build();
}
@Override
public Response viewEducationSummary(String orcid, Long putCode) {
EducationSummary es = affiliationsManagerReadOnly.getEducationSummary(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, es, ScopePathType.AFFILIATIONS_READ_LIMITED);
ActivityUtils.setPathToActivity(es, orcid);
sourceUtils.setSourceName(es);
return Response.ok(es).build();
}
@Override
public Response createEducation(String orcid, Education education) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.AFFILIATIONS_CREATE);
Education e = affiliationsManager.createEducationAffiliation(orcid, education, true);
sourceUtils.setSourceName(e);
try {
return Response.created(new URI(String.valueOf(e.getPutCode()))).build();
} catch (URISyntaxException ex) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createeducation_response.exception"), ex);
}
}
@Override
public Response updateEducation(String orcid, Long putCode, Education education) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.AFFILIATIONS_UPDATE);
if (!putCode.equals(education.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(education.getPutCode()));
throw new MismatchedPutCodeException(params);
}
Education e = affiliationsManager.updateEducationAffiliation(orcid, education, true);
sourceUtils.setSourceName(e);
return Response.ok(e).build();
}
@Override
public Response viewEmployment(String orcid, Long putCode) {
Employment e = affiliationsManagerReadOnly.getEmploymentAffiliation(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, e, ScopePathType.AFFILIATIONS_READ_LIMITED);
ActivityUtils.setPathToActivity(e, orcid);
sourceUtils.setSourceName(e);
return Response.ok(e).build();
}
@Override
public Response viewEmployments(String orcid) {
List<EmploymentSummary> employmentsList = affiliationsManagerReadOnly.getEmploymentSummaryList(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
List<EmploymentSummary> filteredList = null;
if (employmentsList != null) {
filteredList = new ArrayList<EmploymentSummary>(employmentsList);
}
employmentsList = filteredList;
orcidSecurityManager.checkAndFilter(orcid, employmentsList, ScopePathType.AFFILIATIONS_READ_LIMITED);
Employments employments = new Employments(employmentsList);
ActivityUtils.setPathToEmployments(employments, orcid);
sourceUtils.setSourceName(employments);
Api2_0_LastModifiedDatesHelper.calculateLastModified(employments);
return Response.ok(employments).build();
}
@Override
public Response viewEmploymentSummary(String orcid, Long putCode) {
EmploymentSummary es = affiliationsManagerReadOnly.getEmploymentSummary(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, es, ScopePathType.AFFILIATIONS_READ_LIMITED);
ActivityUtils.setPathToActivity(es, orcid);
sourceUtils.setSourceName(es);
return Response.ok(es).build();
}
@Override
public Response createEmployment(String orcid, Employment employment) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.AFFILIATIONS_CREATE);
Employment e = affiliationsManager.createEmploymentAffiliation(orcid, employment, true);
sourceUtils.setSourceName(e);
try {
return Response.created(new URI(String.valueOf(e.getPutCode()))).build();
} catch (URISyntaxException ex) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createemployment_response.exception"), ex);
}
}
@Override
public Response updateEmployment(String orcid, Long putCode, Employment employment) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.AFFILIATIONS_UPDATE);
if (!putCode.equals(employment.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(employment.getPutCode()));
throw new MismatchedPutCodeException(params);
}
Employment e = affiliationsManager.updateEmploymentAffiliation(orcid, employment, true);
sourceUtils.setSourceName(e);
return Response.ok(e).build();
}
@Override
public Response deleteAffiliation(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.AFFILIATIONS_UPDATE);
affiliationsManager.checkSourceAndDelete(orcid, putCode);
return Response.noContent().build();
}
@Override
public Response viewPeerReview(String orcid, Long putCode) {
PeerReview p = peerReviewManagerReadOnly.getPeerReview(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, p, ScopePathType.PEER_REVIEW_READ_LIMITED);
ActivityUtils.setPathToActivity(p, orcid);
sourceUtils.setSourceName(p);
return Response.ok(p).build();
}
@Override
public Response viewPeerReviews(String orcid) {
List<PeerReviewSummary> peerReviewList = peerReviewManagerReadOnly.getPeerReviewSummaryList(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
List<PeerReviewSummary> filteredList = null;
if (peerReviewList != null) {
filteredList = new ArrayList<PeerReviewSummary>(peerReviewList);
}
peerReviewList = filteredList;
orcidSecurityManager.checkAndFilter(orcid, peerReviewList, ScopePathType.PEER_REVIEW_READ_LIMITED);
PeerReviews peerReviews = peerReviewManager.groupPeerReviews(peerReviewList, false);
ActivityUtils.setPathToPeerReviews(peerReviews, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(peerReviews);
sourceUtils.setSourceName(peerReviews);
return Response.ok(peerReviews).build();
}
@Override
public Response viewPeerReviewSummary(String orcid, Long putCode) {
PeerReviewSummary ps = peerReviewManagerReadOnly.getPeerReviewSummary(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, ps, ScopePathType.PEER_REVIEW_READ_LIMITED);
ActivityUtils.setPathToActivity(ps, orcid);
sourceUtils.setSourceName(ps);
return Response.ok(ps).build();
}
@Override
public Response createPeerReview(String orcid, PeerReview peerReview) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.PEER_REVIEW_CREATE);
PeerReview newPeerReview = peerReviewManager.createPeerReview(orcid, peerReview, true);
sourceUtils.setSourceName(newPeerReview);
try {
return Response.created(new URI(String.valueOf(newPeerReview.getPutCode()))).build();
} catch (URISyntaxException ex) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createpeerreview_response.exception"), ex);
}
}
@Override
public Response updatePeerReview(String orcid, Long putCode, PeerReview peerReview) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.PEER_REVIEW_UPDATE);
if (!putCode.equals(peerReview.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(peerReview.getPutCode()));
throw new MismatchedPutCodeException(params);
}
PeerReview updatedPeerReview = peerReviewManager.updatePeerReview(orcid, peerReview, true);
sourceUtils.setSourceName(updatedPeerReview);
return Response.ok(updatedPeerReview).build();
}
@Override
public Response deletePeerReview(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.PEER_REVIEW_UPDATE);
peerReviewManager.checkSourceAndDelete(orcid, putCode);
return Response.noContent().build();
}
@Override
public Response viewGroupIdRecord(Long putCode) {
orcidSecurityManager.checkScopes(ScopePathType.GROUP_ID_RECORD_READ);
GroupIdRecord record = groupIdRecordManagerReadOnly.getGroupIdRecord(putCode);
return Response.ok(record).build();
}
@Override
public Response createGroupIdRecord(GroupIdRecord groupIdRecord) {
orcidSecurityManager.checkScopes(ScopePathType.GROUP_ID_RECORD_UPDATE);
GroupIdRecord newRecord = groupIdRecordManager.createGroupIdRecord(groupIdRecord);
try {
return Response.created(new URI(String.valueOf(newRecord.getPutCode()))).build();
} catch (URISyntaxException ex) {
throw new RuntimeException(localeManager.resolveMessage("apiError.creategroupidrecord_response.exception"), ex);
}
}
@Override
public Response updateGroupIdRecord(GroupIdRecord groupIdRecord, Long putCode) {
orcidSecurityManager.checkScopes(ScopePathType.GROUP_ID_RECORD_UPDATE);
if (!putCode.equals(groupIdRecord.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(groupIdRecord.getPutCode()));
throw new MismatchedPutCodeException(params);
}
GroupIdRecord updatedRecord = groupIdRecordManager.updateGroupIdRecord(putCode, groupIdRecord);
return Response.ok(updatedRecord).build();
}
@Override
public Response deleteGroupIdRecord(Long putCode) {
orcidSecurityManager.checkScopes(ScopePathType.GROUP_ID_RECORD_UPDATE);
groupIdRecordManager.deleteGroupIdRecord(putCode);
return Response.noContent().build();
}
@Override
public Response viewGroupIdRecords(String pageSize, String pageNum) {
orcidSecurityManager.checkScopes(ScopePathType.GROUP_ID_RECORD_READ);
GroupIdRecords records = groupIdRecordManagerReadOnly.getGroupIdRecords(pageSize, pageNum);
Api2_0_LastModifiedDatesHelper.calculateLastModified(records);
return Response.ok(records).build();
}
@Override
public Response findGroupIdRecordByName(String name) {
orcidSecurityManager.checkScopes(ScopePathType.GROUP_ID_RECORD_READ);
Optional<GroupIdRecord> record = groupIdRecordManager.findGroupIdRecordByName(name);
if (record.isPresent())
return Response.ok(record.get()).build();
return Response.ok(new GroupIdRecord()).build();
}
/**
* BIOGRAPHY ELEMENTS
*/
@Override
public Response viewResearcherUrls(String orcid) {
ResearcherUrls researcherUrls = researcherUrlManagerReadOnly.getResearcherUrls(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
if (researcherUrls.getResearcherUrls() != null) {
List<ResearcherUrl> filteredList = new ArrayList<ResearcherUrl>(researcherUrls.getResearcherUrls());
researcherUrls = new ResearcherUrls();
researcherUrls.setResearcherUrls(filteredList);
}
orcidSecurityManager.checkAndFilter(orcid, researcherUrls.getResearcherUrls(), ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToResearcherUrls(researcherUrls, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(researcherUrls);
sourceUtils.setSourceName(researcherUrls);
return Response.ok(researcherUrls).build();
}
public Response viewResearcherUrl(String orcid, Long putCode) {
ResearcherUrl researcherUrl = researcherUrlManagerReadOnly.getResearcherUrl(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, researcherUrl, ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToResearcherUrl(researcherUrl, orcid);
sourceUtils.setSourceName(researcherUrl);
return Response.ok(researcherUrl).build();
}
@Override
public Response updateResearcherUrl(String orcid, Long putCode, ResearcherUrl researcherUrl) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
if (!putCode.equals(researcherUrl.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(researcherUrl.getPutCode()));
throw new MismatchedPutCodeException(params);
}
ResearcherUrl updatedResearcherUrl = researcherUrlManager.updateResearcherUrl(orcid, researcherUrl, true);
ElementUtils.setPathToResearcherUrl(updatedResearcherUrl, orcid);
sourceUtils.setSourceName(updatedResearcherUrl);
return Response.ok(updatedResearcherUrl).build();
}
@Override
public Response createResearcherUrl(String orcid, ResearcherUrl researcherUrl) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
researcherUrl = researcherUrlManager.createResearcherUrl(orcid, researcherUrl, true);
sourceUtils.setSourceName(researcherUrl);
try {
return Response.created(new URI(String.valueOf(researcherUrl.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createelement_response.exception"), e);
}
}
@Override
public Response deleteResearcherUrl(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
researcherUrlManager.deleteResearcherUrl(orcid, putCode, true);
return Response.noContent().build();
}
@Override
public Response viewEmails(String orcid) {
Emails emails = null;
long lastModified = getLastModifiedTime(orcid);
try {
// return all emails if client has /email/read-private scope
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.EMAIL_READ_PRIVATE);
emails = emailManagerReadOnly.getEmails(orcid, lastModified);
// Lets copy the list so we don't modify the cached collection
List<Email> filteredList = new ArrayList<Email>(emails.getEmails());
emails = new Emails();
emails.setEmails(filteredList);
} catch (OrcidAccessControlException e) {
emails = emailManagerReadOnly.getEmails(orcid, lastModified);
// Lets copy the list so we don't modify the cached collection
List<Email> filteredList = new ArrayList<Email>(emails.getEmails());
emails = new Emails();
emails.setEmails(filteredList);
// Filter just in case client doesn't have the /email/read-private
// scope
orcidSecurityManager.checkAndFilter(orcid, emails.getEmails(), ScopePathType.ORCID_BIO_READ_LIMITED);
}
ElementUtils.setPathToEmail(emails, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(emails);
sourceUtils.setSourceName(emails);
return Response.ok(emails).build();
}
@Override
public Response viewOtherNames(String orcid) {
OtherNames otherNames = otherNameManagerReadOnly.getOtherNames(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
if (otherNames.getOtherNames() != null) {
List<OtherName> filteredList = new ArrayList<OtherName>(otherNames.getOtherNames());
otherNames = new OtherNames();
otherNames.setOtherNames(filteredList);
}
orcidSecurityManager.checkAndFilter(orcid, otherNames.getOtherNames(), ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToOtherNames(otherNames, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(otherNames);
sourceUtils.setSourceName(otherNames);
return Response.ok(otherNames).build();
}
@Override
public Response viewOtherName(String orcid, Long putCode) {
OtherName otherName = otherNameManagerReadOnly.getOtherName(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, otherName, ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToOtherName(otherName, orcid);
sourceUtils.setSourceName(otherName);
return Response.ok(otherName).build();
}
@Override
public Response createOtherName(String orcid, OtherName otherName) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
otherName = otherNameManager.createOtherName(orcid, otherName, true);
sourceUtils.setSourceName(otherName);
try {
return Response.created(new URI(String.valueOf(otherName.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createelement_response.exception"), e);
}
}
@Override
public Response updateOtherName(String orcid, Long putCode, OtherName otherName) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
if (!putCode.equals(otherName.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(otherName.getPutCode()));
throw new MismatchedPutCodeException(params);
}
OtherName updatedOtherName = otherNameManager.updateOtherName(orcid, putCode, otherName, true);
ElementUtils.setPathToOtherName(updatedOtherName, orcid);
sourceUtils.setSourceName(updatedOtherName);
return Response.ok(updatedOtherName).build();
}
@Override
public Response deleteOtherName(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
otherNameManager.deleteOtherName(orcid, putCode, true);
return Response.noContent().build();
}
@Override
public Response viewExternalIdentifiers(String orcid) {
PersonExternalIdentifiers extIds = externalIdentifierManagerReadOnly.getExternalIdentifiers(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
if (extIds.getExternalIdentifiers() != null) {
List<PersonExternalIdentifier> filteredList = new ArrayList<PersonExternalIdentifier>(extIds.getExternalIdentifiers());
extIds = new PersonExternalIdentifiers();
extIds.setExternalIdentifiers(filteredList);
}
orcidSecurityManager.checkAndFilter(orcid, extIds.getExternalIdentifiers(), ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToExternalIdentifiers(extIds, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(extIds);
sourceUtils.setSourceName(extIds);
return Response.ok(extIds).build();
}
@Override
public Response viewExternalIdentifier(String orcid, Long putCode) {
PersonExternalIdentifier extId = externalIdentifierManagerReadOnly.getExternalIdentifier(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, extId, ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToExternalIdentifier(extId, orcid);
sourceUtils.setSourceName(extId);
return Response.ok(extId).build();
}
@Override
public Response updateExternalIdentifier(String orcid, Long putCode, PersonExternalIdentifier externalIdentifier) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_EXTERNAL_IDENTIFIERS_CREATE);
if (!putCode.equals(externalIdentifier.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(externalIdentifier.getPutCode()));
throw new MismatchedPutCodeException(params);
}
PersonExternalIdentifier extId = externalIdentifierManager.updateExternalIdentifier(orcid, externalIdentifier, true);
ElementUtils.setPathToExternalIdentifier(extId, orcid);
sourceUtils.setSourceName(extId);
return Response.ok(extId).build();
}
@Override
public Response createExternalIdentifier(String orcid, PersonExternalIdentifier externalIdentifier) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_EXTERNAL_IDENTIFIERS_CREATE);
externalIdentifier = externalIdentifierManager.createExternalIdentifier(orcid, externalIdentifier, true);
try {
return Response.created(new URI(String.valueOf(externalIdentifier.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createelement_response.exception"), e);
}
}
@Override
public Response deleteExternalIdentifier(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
externalIdentifierManager.deleteExternalIdentifier(orcid, putCode, true);
return Response.noContent().build();
}
@Override
public Response viewKeywords(String orcid) {
Keywords keywords = profileKeywordManagerReadOnly.getKeywords(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
if (keywords.getKeywords() != null) {
List<Keyword> filteredList = new ArrayList<Keyword>(keywords.getKeywords());
keywords = new Keywords();
keywords.setKeywords(filteredList);
}
orcidSecurityManager.checkAndFilter(orcid, keywords.getKeywords(), ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToKeywords(keywords, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(keywords);
sourceUtils.setSourceName(keywords);
return Response.ok(keywords).build();
}
@Override
public Response viewKeyword(String orcid, Long putCode) {
Keyword keyword = profileKeywordManagerReadOnly.getKeyword(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, keyword, ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToKeyword(keyword, orcid);
sourceUtils.setSourceName(keyword);
return Response.ok(keyword).build();
}
@Override
public Response createKeyword(String orcid, Keyword keyword) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
keyword = profileKeywordManager.createKeyword(orcid, keyword, true);
sourceUtils.setSourceName(keyword);
try {
return Response.created(new URI(String.valueOf(keyword.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createelement_response.exception"), e);
}
}
@Override
public Response updateKeyword(String orcid, Long putCode, Keyword keyword) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
if (!putCode.equals(keyword.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(keyword.getPutCode()));
throw new MismatchedPutCodeException(params);
}
keyword = profileKeywordManager.updateKeyword(orcid, putCode, keyword, true);
ElementUtils.setPathToKeyword(keyword, orcid);
sourceUtils.setSourceName(keyword);
return Response.ok(keyword).build();
}
@Override
public Response deleteKeyword(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
profileKeywordManager.deleteKeyword(orcid, putCode, true);
return Response.noContent().build();
}
@Override
public Response viewAddresses(String orcid) {
Addresses addresses = addressManagerReadOnly.getAddresses(orcid, getLastModifiedTime(orcid));
// Lets copy the list so we don't modify the cached collection
if (addresses.getAddress() != null) {
List<Address> filteredAddresses = new ArrayList<Address>(addresses.getAddress());
addresses = new Addresses();
addresses.setAddress(filteredAddresses);
}
orcidSecurityManager.checkAndFilter(orcid, addresses.getAddress(), ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToAddresses(addresses, orcid);
// Set the latest last modified
Api2_0_LastModifiedDatesHelper.calculateLastModified(addresses);
sourceUtils.setSourceName(addresses);
return Response.ok(addresses).build();
}
@Override
public Response viewAddress(String orcid, Long putCode) {
Address address = addressManagerReadOnly.getAddress(orcid, putCode);
orcidSecurityManager.checkAndFilter(orcid, address, ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToAddress(address, orcid);
sourceUtils.setSourceName(address);
return Response.ok(address).build();
}
@Override
public Response createAddress(String orcid, Address address) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
address = addressManager.createAddress(orcid, address, true);
sourceUtils.setSourceName(address);
try {
return Response.created(new URI(String.valueOf(address.getPutCode()))).build();
} catch (URISyntaxException e) {
throw new RuntimeException(localeManager.resolveMessage("apiError.createelement_response.exception"), e);
}
}
@Override
public Response updateAddress(String orcid, Long putCode, Address address) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
if (!putCode.equals(address.getPutCode())) {
Map<String, String> params = new HashMap<String, String>();
params.put("urlPutCode", String.valueOf(putCode));
params.put("bodyPutCode", String.valueOf(address.getPutCode()));
throw new MismatchedPutCodeException(params);
}
address = addressManager.updateAddress(orcid, putCode, address, true);
ElementUtils.setPathToAddress(address, orcid);
sourceUtils.setSourceName(address);
return Response.ok(address).build();
}
@Override
public Response deleteAddress(String orcid, Long putCode) {
orcidSecurityManager.checkClientAccessAndScopes(orcid, ScopePathType.ORCID_BIO_UPDATE);
addressManager.deleteAddress(orcid, putCode);
return Response.noContent().build();
}
@Override
public Response viewBiography(String orcid) {
Biography bio = biographyManagerReadOnly.getBiography(orcid, getLastModifiedTime(orcid));
if (bio == null) {
throw new OrcidNoBioException();
}
orcidSecurityManager.checkAndFilter(orcid, bio, ScopePathType.ORCID_BIO_READ_LIMITED);
ElementUtils.setPathToBiography(bio, orcid);
return Response.ok(bio).build();
}
@Override
public Response viewPersonalDetails(String orcid) {
PersonalDetails personalDetails = personalDetailsManagerReadOnly.getPersonalDetails(orcid);
orcidSecurityManager.checkAndFilter(orcid, personalDetails);
ElementUtils.setPathToPersonalDetails(personalDetails, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(personalDetails);
sourceUtils.setSourceName(personalDetails);
return Response.ok(personalDetails).build();
}
@Override
public Response viewPerson(String orcid) {
Person person = personDetailsManagerReadOnly.getPersonDetails(orcid);
orcidSecurityManager.checkAndFilter(orcid, person);
ElementUtils.setPathToPerson(person, orcid);
Api2_0_LastModifiedDatesHelper.calculateLastModified(person);
sourceUtils.setSourceName(person);
return Response.ok(person).build();
}
@Override
public Response searchByQuery(Map<String, List<String>> solrParams) {
orcidSecurityManager.checkScopes(ScopePathType.READ_PUBLIC);
validateSearchParams(solrParams);
Search search = orcidSearchManager.findOrcidIds(solrParams);
return Response.ok(search).build();
}
@Override
public Response viewBulkWorks(String orcid, String putCodes) {
ProfileEntity profileEntity = profileEntityManager.findByOrcid(orcid);
if (profileEntity == null) {
throw new OrcidNoResultException("No such profile: " + orcid);
}
WorkBulk workBulk = workManagerReadOnly.findWorkBulk(orcid, putCodes, profileEntity.getLastModified().getTime());
orcidSecurityManager.checkAndFilter(orcid, workBulk, ScopePathType.ORCID_WORKS_READ_LIMITED);
ActivityUtils.cleanEmptyFields(workBulk);
sourceUtils.setSourceName(workBulk);
return Response.ok(workBulk).build();
}
private void validateSearchParams(Map<String, List<String>> queryMap) {
List<String> rowsList = queryMap.get("rows");
if (rowsList != null && !rowsList.isEmpty()) {
try {
String rowsString = rowsList.get(0);
int rows = Integer.valueOf(rowsString);
if (rows < 0 || rows > OrcidSearchManager.MAX_SEARCH_ROWS) {
throw new OrcidBadRequestException(
localeManager.resolveMessage("apiError.badrequest_invalid_search_rows.exception", OrcidSearchManager.MAX_SEARCH_ROWS));
}
} catch (NumberFormatException e) {
throw new OrcidBadRequestException(localeManager.resolveMessage("apiError.badrequest_invalid_search_rows.exception"));
}
} else {
// Set the default number of results
queryMap.put("rows", Arrays.asList(String.valueOf(OrcidSearchManager.DEFAULT_SEARCH_ROWS)));
}
}
@Override
public Response viewClient(String clientId) {
orcidSecurityManager.checkScopes(ScopePathType.READ_PUBLIC);
Client client = clientDetailsManagerReadOnly.getClient(clientId);
return Response.ok(client).build();
}
}