/**
* =============================================================================
*
* 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.core.adapter.impl;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import javax.annotation.Resource;
import javax.xml.datatype.XMLGregorianCalendar;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.orcid.core.adapter.Jaxb2JpaAdapter;
import org.orcid.core.adapter.impl.jsonidentifiers.FundingExternalIdentifiers;
import org.orcid.core.adapter.impl.jsonidentifiers.WorkExternalIdentifiers;
import org.orcid.core.constants.DefaultPreferences;
import org.orcid.core.locale.LocaleManager;
import org.orcid.core.manager.OrgManager;
import org.orcid.core.manager.ProfileEntityManager;
import org.orcid.core.manager.ProfileFundingManager;
import org.orcid.core.manager.RecordNameManager;
import org.orcid.core.manager.SourceManager;
import org.orcid.core.manager.UpdateOptions;
import org.orcid.core.security.visibility.OrcidVisibilityDefaults;
import org.orcid.core.utils.JsonUtils;
import org.orcid.core.utils.Triplet;
import org.orcid.jaxb.model.message.Affiliation;
import org.orcid.jaxb.model.message.Affiliations;
import org.orcid.jaxb.model.message.Biography;
import org.orcid.jaxb.model.message.Citation;
import org.orcid.jaxb.model.message.CompletionDate;
import org.orcid.jaxb.model.message.ContactDetails;
import org.orcid.jaxb.model.message.Country;
import org.orcid.jaxb.model.message.CreationMethod;
import org.orcid.jaxb.model.message.CreditName;
import org.orcid.jaxb.model.message.DeactivationDate;
import org.orcid.jaxb.model.message.Email;
import org.orcid.jaxb.model.message.ExternalIdentifier;
import org.orcid.jaxb.model.message.ExternalIdentifiers;
import org.orcid.jaxb.model.message.FamilyName;
import org.orcid.jaxb.model.message.Funding;
import org.orcid.jaxb.model.message.FundingContributors;
import org.orcid.jaxb.model.message.FundingList;
import org.orcid.jaxb.model.message.FundingTitle;
import org.orcid.jaxb.model.message.FuzzyDate;
import org.orcid.jaxb.model.message.GivenNames;
import org.orcid.jaxb.model.message.Iso3166Country;
import org.orcid.jaxb.model.message.Keyword;
import org.orcid.jaxb.model.message.Keywords;
import org.orcid.jaxb.model.message.OrcidActivities;
import org.orcid.jaxb.model.message.OrcidBio;
import org.orcid.jaxb.model.message.OrcidHistory;
import org.orcid.jaxb.model.message.OrcidInternal;
import org.orcid.jaxb.model.message.OrcidPreferences;
import org.orcid.jaxb.model.message.OrcidProfile;
import org.orcid.jaxb.model.message.OrcidWork;
import org.orcid.jaxb.model.message.OrcidWorks;
import org.orcid.jaxb.model.message.Organization;
import org.orcid.jaxb.model.message.OrganizationAddress;
import org.orcid.jaxb.model.message.OtherName;
import org.orcid.jaxb.model.message.OtherNames;
import org.orcid.jaxb.model.message.PersonalDetails;
import org.orcid.jaxb.model.message.Preferences;
import org.orcid.jaxb.model.message.PublicationDate;
import org.orcid.jaxb.model.message.ResearcherUrl;
import org.orcid.jaxb.model.message.ResearcherUrls;
import org.orcid.jaxb.model.message.SecurityDetails;
import org.orcid.jaxb.model.message.Source;
import org.orcid.jaxb.model.message.SubmissionDate;
import org.orcid.jaxb.model.message.TranslatedTitle;
import org.orcid.jaxb.model.message.Visibility;
import org.orcid.jaxb.model.message.WorkContributors;
import org.orcid.jaxb.model.message.WorkTitle;
import org.orcid.jaxb.model.record_v2.AffiliationType;
import org.orcid.jaxb.model.record_v2.CitationType;
import org.orcid.persistence.dao.ClientDetailsDao;
import org.orcid.persistence.dao.GenericDao;
import org.orcid.persistence.dao.OrgAffiliationRelationDao;
import org.orcid.persistence.dao.OrgDisambiguatedDao;
import org.orcid.persistence.jpa.entities.AddressEntity;
import org.orcid.persistence.jpa.entities.BiographyEntity;
import org.orcid.persistence.jpa.entities.ClientDetailsEntity;
import org.orcid.persistence.jpa.entities.EmailEntity;
import org.orcid.persistence.jpa.entities.EndDateEntity;
import org.orcid.persistence.jpa.entities.ExternalIdentifierEntity;
import org.orcid.persistence.jpa.entities.OrgAffiliationRelationEntity;
import org.orcid.persistence.jpa.entities.OrgEntity;
import org.orcid.persistence.jpa.entities.OtherNameEntity;
import org.orcid.persistence.jpa.entities.ProfileEntity;
import org.orcid.persistence.jpa.entities.ProfileFundingEntity;
import org.orcid.persistence.jpa.entities.ProfileKeywordEntity;
import org.orcid.persistence.jpa.entities.PublicationDateEntity;
import org.orcid.persistence.jpa.entities.RecordNameEntity;
import org.orcid.persistence.jpa.entities.ResearcherUrlEntity;
import org.orcid.persistence.jpa.entities.SecurityQuestionEntity;
import org.orcid.persistence.jpa.entities.SourceAwareEntity;
import org.orcid.persistence.jpa.entities.SourceEntity;
import org.orcid.persistence.jpa.entities.StartDateEntity;
import org.orcid.persistence.jpa.entities.WorkEntity;
import org.orcid.pojo.ajaxForm.PojoUtil;
import org.orcid.utils.OrcidStringUtils;
import org.springframework.util.Assert;
/**
* orcid-persistence - Dec 7, 2011 - Jaxb2JpaAdapterImpl
*
* @author Declan Newman (declan)
*/
public class Jaxb2JpaAdapterImpl implements Jaxb2JpaAdapter {
@Resource(name = "securityQuestionDao")
private GenericDao<SecurityQuestionEntity, Integer> securityQuestionDao;
@Resource
private LocaleManager localeManager;
@Resource
private OrgManager orgManager;
@Resource
private ProfileEntityManager profileEntityManager;
@Resource
private OrgDisambiguatedDao orgDisambiguatedDao;
@Resource
private ProfileFundingManager profileFundingManager;
@Resource
private OrgAffiliationRelationDao orgAffiliationRelationDao;
@Resource
private ClientDetailsDao clientDetailsDao;
@Resource
protected SourceManager sourceManager;
@Resource
protected RecordNameManager recordNameManager;
@Override
public ProfileEntity toProfileEntity(OrcidProfile profile, ProfileEntity existingProfileEntity) {
return toProfileEntity(profile, existingProfileEntity, UpdateOptions.ALL);
}
@Override
public ProfileEntity toProfileEntity(OrcidProfile profile, ProfileEntity existingProfileEntity, UpdateOptions updateOptions) {
Assert.notNull(profile, "Cannot convert a null OrcidProfile");
ProfileEntity profileEntity = existingProfileEntity == null ? new ProfileEntity() : existingProfileEntity;
// if orcid-id exist us it
String orcidString = profile.getOrcidIdentifier().getPath();
if (profile.retrieveOrcidUriAsString() != null && !profile.retrieveOrcidUriAsString().isEmpty()) {
orcidString = OrcidStringUtils.getOrcidNumber(profile.retrieveOrcidUriAsString());
}
profileEntity.setId(orcidString);
profileEntity.setOrcidType(org.orcid.jaxb.model.common_v2.OrcidType.fromValue(profile.getType().value()));
profileEntity.setGroupType(profile.getGroupType());
setBioDetails(profileEntity, profile.getOrcidBio());
setHistoryDetails(profileEntity, profile.getOrcidHistory());
setActivityDetails(profileEntity, profile.getOrcidActivities(), updateOptions);
setInternalDetails(profileEntity, profile.getOrcidInternal());
setPreferencesDetails(profileEntity, profile.getOrcidPreferences());
profileEntity.setUserLastIp(profile.getUserLastIp());
profileEntity.setReviewed(profile.isReviewed());
if(profileEntity.getUsedRecaptchaOnRegistration() == null) {
profileEntity.setUsedRecaptchaOnRegistration(false);
}
return profileEntity;
}
private void setActivityDetails(ProfileEntity profileEntity, OrcidActivities orcidActivities, UpdateOptions updateOptions) {
Affiliations affiliations = null;
FundingList orcidFundings = null;
OrcidWorks orcidWorks = null;
if (orcidActivities != null) {
affiliations = orcidActivities.getAffiliations();
orcidFundings = orcidActivities.getFundings();
orcidWorks = orcidActivities.getOrcidWorks();
}
if (updateOptions.isUpdateAffiliations()) {
setOrgAffiliationRelations(profileEntity, affiliations);
}
if (updateOptions.isUpdateFundings()) {
setFundings(profileEntity, orcidFundings);
}
if (updateOptions.isUpdateWorks()) {
setWorks(profileEntity, orcidWorks);
}
}
private void setWorks(ProfileEntity profileEntity, OrcidWorks orcidWorks) {
SortedSet<WorkEntity> workEntities = getWorkEntities(profileEntity, orcidWorks);
profileEntity.setWorks(workEntities);
}
private SortedSet<WorkEntity> getWorkEntities(ProfileEntity profileEntity, OrcidWorks orcidWorks) {
SortedSet<WorkEntity> existingWorkEntities = profileEntity.getWorks();
Map<String, WorkEntity> existingWorkEntitiesMap = createWorkEntitiesMap(existingWorkEntities);
SortedSet<WorkEntity> workEntities = null;
if (existingWorkEntities == null) {
workEntities = new TreeSet<WorkEntity>();
} else {
// To allow for orphan deletion
existingWorkEntities.clear();
workEntities = existingWorkEntities;
}
if (orcidWorks != null && orcidWorks.getOrcidWork() != null && !orcidWorks.getOrcidWork().isEmpty()) {
List<OrcidWork> orcidWorkList = orcidWorks.getOrcidWork();
for (OrcidWork orcidWork : orcidWorkList) {
WorkEntity workEntity = getWorkEntity(orcidWork, existingWorkEntitiesMap.get(orcidWork.getPutCode()));
if (workEntity != null) {
workEntity.setProfile(profileEntity);
workEntities.add(workEntity);
}
}
}
return workEntities;
}
private Map<String, WorkEntity> createWorkEntitiesMap(SortedSet<WorkEntity> workEntities) {
Map<String, WorkEntity> map = new HashMap<>();
if (workEntities != null) {
for (WorkEntity workEntity : workEntities) {
map.put(String.valueOf(workEntity.getId()), workEntity);
}
}
return map;
}
public WorkEntity getWorkEntity(OrcidWork orcidWork, WorkEntity workEntity) {
if (orcidWork != null) {
if(workEntity == null) {
String putCode = orcidWork.getPutCode();
if (StringUtils.isNotBlank(putCode) && !"-1".equals(putCode)) {
throw new IllegalArgumentException("Invalid put-code was supplied: " + putCode);
}
workEntity = new WorkEntity();
} else {
workEntity.clean();
}
Citation workCitation = orcidWork.getWorkCitation();
if (workCitation != null && StringUtils.isNotBlank(workCitation.getCitation()) && workCitation.getWorkCitationType() != null) {
workEntity.setCitation(workCitation.getCitation());
workEntity.setCitationType(CitationType.fromValue(workCitation.getWorkCitationType().value()));
}
// New way of doing work contributors
workEntity.setContributorsJson(getWorkContributorsJson(orcidWork.getWorkContributors()));
workEntity.setDescription(orcidWork.getShortDescription() != null ? orcidWork.getShortDescription() : null);
// New way of doing work external ids
workEntity.setExternalIdentifiersJson(getWorkExternalIdsJson(orcidWork));
workEntity.setPublicationDate(getWorkPublicationDate(orcidWork));
WorkTitle workTitle = orcidWork.getWorkTitle();
if (workTitle != null) {
workEntity.setSubtitle(workTitle.getSubtitle() != null ? workTitle.getSubtitle().getContent() : null);
workEntity.setTitle(workTitle.getTitle() != null ? workTitle.getTitle().getContent().trim() : null);
TranslatedTitle translatedTitle = workTitle.getTranslatedTitle();
if (translatedTitle != null) {
workEntity.setTranslatedTitle(StringUtils.isEmpty(translatedTitle.getContent()) ? null : translatedTitle.getContent());
workEntity.setTranslatedTitleLanguageCode(StringUtils.isEmpty(translatedTitle.getLanguageCode()) ? null : translatedTitle.getLanguageCode());
}
}
workEntity.setJournalTitle(orcidWork.getJournalTitle() != null ? orcidWork.getJournalTitle().getContent() : null);
workEntity.setLanguageCode(orcidWork.getLanguageCode() != null ? orcidWork.getLanguageCode() : null);
if(orcidWork.getCountry() != null && orcidWork.getCountry().getValue() != null) {
workEntity.setIso2Country(org.orcid.jaxb.model.common_v2.Iso3166Country.fromValue(orcidWork.getCountry().getValue().value()));
}
workEntity.setWorkUrl(orcidWork.getUrl() != null ? orcidWork.getUrl().getValue() : null);
if(orcidWork.getWorkType() != null) {
workEntity.setWorkType(org.orcid.jaxb.model.record_v2.WorkType.fromValue(orcidWork.getWorkType().value()));
}
if(orcidWork.getVisibility() != null) {
workEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(orcidWork.getVisibility().value()));
} else {
workEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.PRIVATE);
}
workEntity.setAddedToProfileDate(new Date());
//Set source
setSource(orcidWork.getSource(), workEntity);
if(workEntity.getDisplayIndex() == null) {
workEntity.setDisplayIndex(0L);
}
return workEntity;
}
return null;
}
private PublicationDateEntity getWorkPublicationDate(OrcidWork orcidWork) {
if (orcidWork != null && orcidWork.getPublicationDate() != null) {
PublicationDate publicationDate = orcidWork.getPublicationDate();
Integer year = publicationDate.getYear() != null ? toInteger(publicationDate.getYear().getValue()) : null;
Integer month = publicationDate.getMonth() != null ? toInteger(publicationDate.getMonth().getValue()) : null;
Integer day = publicationDate.getDay() != null ? toInteger(publicationDate.getDay().getValue()) : null;
return new PublicationDateEntity(year, month, day);
}
return null;
}
private Integer toInteger(String integer) {
try {
return Integer.parseInt(integer);
} catch (NumberFormatException e) {
return null;
}
}
private String getWorkContributorsJson(WorkContributors workContributors) {
if (workContributors == null) {
return null;
}
return JsonUtils.convertToJsonString(workContributors);
}
private String getFundingContributorsJson(FundingContributors fundingContributors) {
if (fundingContributors == null) {
return null;
}
return JsonUtils.convertToJsonString(fundingContributors);
}
private String getWorkExternalIdsJson(OrcidWork work) {
if (work == null || work.getWorkExternalIdentifiers() == null) {
return null;
}
WorkExternalIdentifiers recordExternalIdentifiers = new WorkExternalIdentifiers(work.getWorkExternalIdentifiers(), work.getWorkType());
return recordExternalIdentifiers.toDBJSONString();
}
private void setFundings(ProfileEntity profileEntity, FundingList orcidFundings) {
SortedSet<ProfileFundingEntity> existingProfileFundingEntities = profileEntity.getProfileFunding();
if (existingProfileFundingEntities == null) {
existingProfileFundingEntities = new TreeSet<>();
}
// Create a map containing the existing profile funding entities
Map<String, ProfileFundingEntity> existingProfileFundingEntitiesMap = createProfileFundingEntitiesMap(existingProfileFundingEntities);
// A set that will contain the updated profile funding entities that
// comes from the orcidGrant object
SortedSet<ProfileFundingEntity> updatedProfileFundingEntities = new TreeSet<>();
// Populate a list of the updated profile funding entities that comes
// from the fundingList object
if (orcidFundings != null && orcidFundings.getFundings() != null && !orcidFundings.getFundings().isEmpty()) {
for (Funding orcidFunding : orcidFundings.getFundings()) {
ProfileFundingEntity newProfileGrantEntity = getProfileFundingEntity(orcidFunding, existingProfileFundingEntitiesMap.get(orcidFunding.getPutCode()));
newProfileGrantEntity.setProfile(profileEntity);
updatedProfileFundingEntities.add(newProfileGrantEntity);
}
}
// Create a map containing the profile funding that comes in the
// orcidGrant object and that will be persisted
Map<String, ProfileFundingEntity> updatedProfileGrantEntitiesMap = createProfileFundingEntitiesMap(updatedProfileFundingEntities);
// Remove orphans
for (Iterator<ProfileFundingEntity> iterator = existingProfileFundingEntities.iterator(); iterator.hasNext();) {
ProfileFundingEntity existingEntity = iterator.next();
if (!updatedProfileGrantEntitiesMap.containsKey(String.valueOf(existingEntity.getId()))) {
iterator.remove();
}
}
// Add new
for (ProfileFundingEntity updatedEntity : updatedProfileFundingEntities) {
if (updatedEntity.getId() == null) {
existingProfileFundingEntities.add(updatedEntity);
}
}
profileEntity.setProfileFunding(existingProfileFundingEntities);
}
private void setBioDetails(ProfileEntity profileEntity, OrcidBio orcidBio) {
if (orcidBio != null) {
setBiographyDetails(profileEntity, orcidBio.getBiography());
setContactDetails(profileEntity, orcidBio.getContactDetails());
setExternalIdentifiers(profileEntity, orcidBio.getExternalIdentifiers());
setKeywords(profileEntity, orcidBio.getKeywords());
setPersonalDetails(profileEntity, orcidBio.getPersonalDetails());
setResearcherUrls(profileEntity, orcidBio.getResearcherUrls());
}
}
private void setResearcherUrls(ProfileEntity profileEntity, ResearcherUrls researcherUrls) {
String sourceId = getSourceId();
SortedSet<ResearcherUrlEntity> existingResearcherUrlEntities = profileEntity.getResearcherUrls();
Iterator<ResearcherUrlEntity> existingIt = null;
if(existingResearcherUrlEntities != null) {
existingIt = existingResearcherUrlEntities.iterator();
}
//Iterate over the list of existing elements, to see which ones still exists but preserving all the ones where the calling client is not the source of
if(existingIt != null) {
while(existingIt.hasNext()) {
ResearcherUrlEntity existing = existingIt.next();
String existingElementSource = existing.getElementSourceId();
if(sourceId != null && !sourceId.equals(existingElementSource)) {
//If am not the source of this element, do nothing
} else {
//If am the source, check if the element exists in the list of incoming elements
Pair<String, String> existingPair = createResearcherUrlPair(existing);
boolean found = false;
if(researcherUrls != null && researcherUrls.getResearcherUrl() != null) {
for(ResearcherUrl newResearcherUrl : researcherUrls.getResearcherUrl()){
Pair<String, String> newResearcherUrlPair = createResearcherUrlPair(newResearcherUrl);
if(Objects.equals(existingPair, newResearcherUrlPair)) {
found = true;
break;
}
}
}
//If it doesn't exists, remove it from the existing elements
if(!found) {
existingIt.remove();
}
}
}
}
//Iterate over the list of all new ones and add the ones that doesn't exists yet
if(researcherUrls != null && researcherUrls.getResearcherUrl() != null) {
for(ResearcherUrl newResearcherUrl : researcherUrls.getResearcherUrl()) {
boolean exists = false;
Pair<String, String> newResearcherUrlPair = createResearcherUrlPair(newResearcherUrl);
if(existingResearcherUrlEntities != null) {
for(ResearcherUrlEntity existingEntity : existingResearcherUrlEntities) {
Pair<String, String> existingPair = createResearcherUrlPair(existingEntity);
if(Objects.equals(newResearcherUrlPair, existingPair)) {
exists = true;
//If the profile is not claimed, you can update the visibility
if(profileEntity.getClaimed() == null || !profileEntity.getClaimed()) {
//Update the visibility of existing elements if the profile is not claimed
String existingVisibilityValue = existingEntity.getVisibility() == null ? null : existingEntity.getVisibility().value();
String listVisibilityValue = researcherUrls.getVisibility() == null ? null : researcherUrls.getVisibility().value();
if(listVisibilityValue != null && !Objects.equals(existingVisibilityValue, listVisibilityValue)) {
existingEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(listVisibilityValue));
}
}
break;
}
}
}
if(!exists) {
if (existingResearcherUrlEntities == null) {
existingResearcherUrlEntities = new TreeSet<ResearcherUrlEntity>();
profileEntity.setResearcherUrls(existingResearcherUrlEntities);
}
ResearcherUrlEntity newEntity = new ResearcherUrlEntity();
newEntity.setUser(profileEntity);
//Set source
SourceEntity source = sourceManager.retrieveSourceEntity();
setSource(source, newEntity);
if(newResearcherUrl.getUrl() != null) {
newEntity.setUrl(newResearcherUrl.getUrl().getValue());
}
if(newResearcherUrl.getUrlName() != null) {
newEntity.setUrlName(newResearcherUrl.getUrlName().getContent());
}
newEntity.setVisibility(getDefaultVisibility(profileEntity, researcherUrls.getVisibility(), OrcidVisibilityDefaults.RESEARCHER_URLS_DEFAULT));
newEntity.setDisplayIndex(0L);
for (ResearcherUrlEntity tempEntity:existingResearcherUrlEntities)
tempEntity.setDisplayIndex(tempEntity.getDisplayIndex()+1);
existingResearcherUrlEntities.add(newEntity);
}
}
}
}
private Pair<String, String> createResearcherUrlPair(ResearcherUrl rUrl) {
String url = rUrl.getUrl() == null ? "" : rUrl.getUrl().getValue();
String urlName = rUrl.getUrlName() == null ? "" : rUrl.getUrlName().getContent();
Pair<String, String> pair = Pair.of(url, urlName);
return pair;
}
private Pair<String, String> createResearcherUrlPair(ResearcherUrlEntity entity) {
String url = entity.getUrl() == null ? "" : entity.getUrl();
String urlName = entity.getUrlName() == null ? "" : entity.getUrlName();
Pair<String, String> pair = Pair.of(url, urlName);
return pair;
}
private void setPersonalDetails(ProfileEntity profileEntity, PersonalDetails personalDetails) {
if (personalDetails != null) {
if(profileEntity.getRecordNameEntity() == null) {
profileEntity.setRecordNameEntity(new RecordNameEntity());
}
profileEntity.getRecordNameEntity().setProfile(profileEntity);
setCreditNameDetails(profileEntity, personalDetails.getCreditName());
setFamilyName(profileEntity, personalDetails.getFamilyName());
setGivenNames(profileEntity, personalDetails.getGivenNames());
setOtherNames(profileEntity, personalDetails.getOtherNames());
}
}
private void setOtherNames(ProfileEntity profileEntity, OtherNames otherNames) {
String sourceId = getSourceId();
SortedSet<OtherNameEntity> existingOtherNameEntities = profileEntity.getOtherNames();
Iterator<OtherNameEntity> existingIt = null;
if(existingOtherNameEntities != null) {
existingIt = existingOtherNameEntities.iterator();
}
//Iterate over the list of existing elements, to see which ones still exists but preserving all the ones where the calling client is not the source of
if(existingIt != null) {
while(existingIt.hasNext()) {
OtherNameEntity existing = existingIt.next();
String existingElementSource = existing.getElementSourceId();
if(sourceId != null && !sourceId.equals(existingElementSource)) {
//If am not the source of this element, do nothing
} else {
//If am the source, check if the element exists in the list of incoming elements
String value = existing.getDisplayName();
boolean found = false;
if(otherNames != null && otherNames.getOtherName() != null) {
for(OtherName newOtherName : otherNames.getOtherName()){
if(Objects.equals(value, newOtherName.getContent())) {
found = true;
break;
}
}
}
//If it doesn't exists, remove it from the existing elements
if(!found) {
existingIt.remove();
}
}
}
}
//Iterate over the list of all new ones and add the ones that doesn't exists yet
if(otherNames != null && otherNames.getOtherName() != null) {
for(OtherName newOtherName : otherNames.getOtherName()) {
boolean exists = false;
if(existingOtherNameEntities != null) {
for(OtherNameEntity existingEntity : existingOtherNameEntities) {
if(Objects.equals(newOtherName.getContent(), existingEntity.getDisplayName())) {
exists = true;
//If the profile is not claimed, you can update the visibility
if(profileEntity.getClaimed() == null || !profileEntity.getClaimed()) {
//Update the visibility of existing elements if the profile is not claimed
String existingVisibilityValue = existingEntity.getVisibility() == null ? null : existingEntity.getVisibility().value();
String listVisibilityValue = otherNames.getVisibility() == null ? null : otherNames.getVisibility().value();
if(listVisibilityValue != null && !Objects.equals(existingVisibilityValue, listVisibilityValue)) {
existingEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(listVisibilityValue));
}
}
break;
}
}
}
if(!exists) {
if(existingOtherNameEntities == null) {
existingOtherNameEntities = new TreeSet<OtherNameEntity>();
profileEntity.setOtherNames(existingOtherNameEntities);
}
OtherNameEntity newEntity = new OtherNameEntity();
newEntity.setProfile(profileEntity);
//Set source
SourceEntity source = sourceManager.retrieveSourceEntity();
setSource(source, newEntity);
newEntity.setDisplayName(newOtherName.getContent());
newEntity.setVisibility(getDefaultVisibility(profileEntity, otherNames.getVisibility(), OrcidVisibilityDefaults.OTHER_NAMES_DEFAULT));
newEntity.setDisplayIndex(0L);
for (OtherNameEntity tempEntity:existingOtherNameEntities)
tempEntity.setDisplayIndex(tempEntity.getDisplayIndex()+1);
existingOtherNameEntities.add(newEntity);
}
}
}
}
private void setGivenNames(ProfileEntity profileEntity, GivenNames givenNames) {
if (givenNames != null && StringUtils.isNotBlank(givenNames.getContent())) {
if(profileEntity.getRecordNameEntity() == null) {
profileEntity.setRecordNameEntity(new RecordNameEntity());
profileEntity.getRecordNameEntity().setProfile(profileEntity);
}
profileEntity.getRecordNameEntity().setGivenNames(givenNames.getContent());
}
}
private void setFamilyName(ProfileEntity profileEntity, FamilyName familyName) {
if (familyName != null && StringUtils.isNotBlank(familyName.getContent())) {
if(profileEntity.getRecordNameEntity() == null) {
profileEntity.setRecordNameEntity(new RecordNameEntity());
profileEntity.getRecordNameEntity().setProfile(profileEntity);
}
profileEntity.getRecordNameEntity().setFamilyName(familyName.getContent());
}
}
private void setCreditNameDetails(ProfileEntity profileEntity, CreditName creditName) {
if (creditName != null) {
if(profileEntity.getRecordNameEntity() == null) {
profileEntity.setRecordNameEntity(new RecordNameEntity());
profileEntity.getRecordNameEntity().setProfile(profileEntity);
}
RecordNameEntity recordName = profileEntity.getRecordNameEntity();
//Save the record name entity
if(creditName.getVisibility() != null) {
recordName.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(creditName.getVisibility().value()));
} else {
recordName.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(OrcidVisibilityDefaults.NAMES_DEFAULT.getVisibility().value()));
}
recordName.setCreditName(creditName.getContent());
}
}
private void setKeywords(ProfileEntity profileEntity, Keywords keywords) {
String sourceId = getSourceId();
SortedSet<ProfileKeywordEntity> existingProfileKeywordEntities = profileEntity.getKeywords();
Iterator<ProfileKeywordEntity> existingIt = null;
if(existingProfileKeywordEntities != null){
existingIt = existingProfileKeywordEntities.iterator();
}
//Iterate over the list of existing elements, to see which ones still exists but preserving all the ones where the calling client is not the source of
if(existingIt != null) {
while(existingIt.hasNext()) {
ProfileKeywordEntity existing = existingIt.next();
String existingElementSource = existing.getElementSourceId();
if(sourceId != null && !sourceId.equals(existingElementSource)){
//If am not the source of this element, do nothing
} else {
//If am the source, check if the element exists in the list of incoming elements
String value = existing.getKeywordName();
boolean found = false;
if(keywords != null && keywords.getKeyword() != null) {
for(Keyword newKeyword : keywords.getKeyword()) {
if(Objects.equals(value, newKeyword.getContent())) {
found = true;
break;
}
}
}
//If it doesn't exists, remove it from the existing elements
if(!found) {
existingIt.remove();
}
}
}
}
//Iterate over the list of all new ones and add the ones that doesn't exists yet
if(keywords != null && keywords.getKeyword() != null) {
for(Keyword newKeyword : keywords.getKeyword()) {
boolean exists = false;
if(existingProfileKeywordEntities != null) {
for(ProfileKeywordEntity existingEntity : existingProfileKeywordEntities) {
if(Objects.equals(newKeyword.getContent(), existingEntity.getKeywordName())) {
exists = true;
//If the profile is not claimed, you can update the visibility
if(profileEntity.getClaimed() == null || !profileEntity.getClaimed()) {
//Update the visibility of existing elements if the profile is not claimed
String existingVisibilityValue = existingEntity.getVisibility() == null ? null : existingEntity.getVisibility().value();
String listVisibilityValue = keywords.getVisibility() == null ? null : keywords.getVisibility().value();
if(listVisibilityValue != null && !Objects.equals(existingVisibilityValue, listVisibilityValue)) {
existingEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(listVisibilityValue));
}
}
break;
}
}
}
if(!exists) {
if(existingProfileKeywordEntities == null) {
existingProfileKeywordEntities = new TreeSet<ProfileKeywordEntity>();
profileEntity.setKeywords(existingProfileKeywordEntities);
}
ProfileKeywordEntity newEntity = new ProfileKeywordEntity();
newEntity.setProfile(profileEntity);
//Set source
SourceEntity source = sourceManager.retrieveSourceEntity();
setSource(source, newEntity);
newEntity.setKeywordName(newKeyword.getContent());
newEntity.setVisibility(getDefaultVisibility(profileEntity, keywords.getVisibility(), OrcidVisibilityDefaults.KEYWORD_DEFAULT));
newEntity.setDisplayIndex(0L);
for (ProfileKeywordEntity tempEntity:existingProfileKeywordEntities)
tempEntity.setDisplayIndex(tempEntity.getDisplayIndex()+1);
existingProfileKeywordEntities.add(newEntity);
}
}
}
}
private void setExternalIdentifiers(ProfileEntity profileEntity, ExternalIdentifiers externalIdentifiers) {
String sourceId = getSourceId();
Set<ExternalIdentifierEntity> existingExternalIdentifierEntities = profileEntity.getExternalIdentifiers();
Iterator<ExternalIdentifierEntity> existingIt = null;
if(existingExternalIdentifierEntities != null){
existingIt = existingExternalIdentifierEntities.iterator();
}
//Iterate over the list of existing elements, to see which ones still exists but preserving all the ones where the calling client is not the source of
if(existingIt != null) {
while(existingIt.hasNext()) {
ExternalIdentifierEntity existing = existingIt.next();
String existingElementSource = existing.getElementSourceId();
if(sourceId != null && !sourceId.equals(existingElementSource)){
//If am not the source of this element, do nothing
} else {
//If am the source, check if the element exists in the list of incoming elements
Triplet<String, String, String> existingTriplet = createTripletForExternalIdentifier(existing);
boolean found = false;
if(externalIdentifiers != null && externalIdentifiers.getExternalIdentifier() != null) {
for(ExternalIdentifier newExternalIdentifier : externalIdentifiers.getExternalIdentifier()){
Triplet<String, String, String> newExternalIdentifierTriplet = createTripletForExternalIdentifier(newExternalIdentifier);
if(Objects.equals(existingTriplet, newExternalIdentifierTriplet)) {
found = true;
break;
}
}
}
//If it doesn't exists, remove it from the existing elements
if(!found) {
existingIt.remove();
}
}
}
}
//Iterate over the list of all new ones and add the ones that doesn't exists yet
if(externalIdentifiers != null && externalIdentifiers.getExternalIdentifier() != null) {
for(ExternalIdentifier newExternalIdentifier : externalIdentifiers.getExternalIdentifier()) {
boolean exists = false;
Triplet<String, String, String> newExternalIdentifierTriplet = createTripletForExternalIdentifier(newExternalIdentifier);
String sourceOfNewElement = newExternalIdentifier.getSource() == null ? null : newExternalIdentifier.getSource().retrieveSourcePath();
if(existingExternalIdentifierEntities != null) {
for(ExternalIdentifierEntity existingEntity : existingExternalIdentifierEntities) {
Triplet<String, String, String> existingTriplet = createTripletForExternalIdentifier(existingEntity);
String sourceOfExistingElement = existingEntity.getElementSourceId();
if (Objects.equals(sourceOfNewElement, sourceOfExistingElement) && Objects.equals(newExternalIdentifierTriplet, existingTriplet)) {
exists = true;
// If the profile is not claimed, you can update the
// visibility
if (profileEntity.getClaimed() == null || !profileEntity.getClaimed()) {
// Update the visibility of existing elements if
// the profile is not claimed
String existingVisibilityValue = existingEntity.getVisibility() == null ? null : existingEntity.getVisibility().value();
String listVisibilityValue = externalIdentifiers.getVisibility() == null ? null : externalIdentifiers.getVisibility().value();
if (listVisibilityValue != null && !Objects.equals(existingVisibilityValue, listVisibilityValue)) {
existingEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(listVisibilityValue));
}
}
break;
}
}
}
if(!exists) {
if(existingExternalIdentifierEntities == null) {
existingExternalIdentifierEntities = new TreeSet<ExternalIdentifierEntity>();
profileEntity.setExternalIdentifiers(existingExternalIdentifierEntities);
}
ExternalIdentifierEntity newEntity = new ExternalIdentifierEntity();
newEntity.setOwner(profileEntity);
//Set source
SourceEntity source = sourceManager.retrieveSourceEntity();
setSource(source, newEntity);
if(newExternalIdentifier.getExternalIdCommonName() != null) {
newEntity.setExternalIdCommonName(newExternalIdentifier.getExternalIdCommonName().getContent());
}
if(newExternalIdentifier.getExternalIdReference() != null) {
newEntity.setExternalIdReference(newExternalIdentifier.getExternalIdReference().getContent());
}
if(newExternalIdentifier.getExternalIdUrl() != null) {
newEntity.setExternalIdUrl(newExternalIdentifier.getExternalIdUrl().getValue());
}
newEntity.setVisibility(getDefaultVisibility(profileEntity, externalIdentifiers.getVisibility(), OrcidVisibilityDefaults.EXTERNAL_IDENTIFIER_DEFAULT));
newEntity.setDisplayIndex(0L);
for (ExternalIdentifierEntity tempEntity:existingExternalIdentifierEntities)
tempEntity.setDisplayIndex(tempEntity.getDisplayIndex()+1);
existingExternalIdentifierEntities.add(newEntity);
}
}
}
}
private Triplet<String, String, String> createTripletForExternalIdentifier(ExternalIdentifierEntity entity) {
String first = entity.getExternalIdUrl() == null ? "" : entity.getExternalIdUrl();
String second = entity.getExternalIdReference() == null ? "" : entity.getExternalIdReference();
String third = entity.getExternalIdCommonName() == null ? "" : entity.getExternalIdCommonName();
Triplet<String, String, String> triplet = new Triplet<String, String, String>(first, second, third);
return triplet;
}
private Triplet<String, String, String> createTripletForExternalIdentifier(ExternalIdentifier entity) {
String first = entity.getExternalIdUrl() == null ? "" : entity.getExternalIdUrl().getValue();
String second = entity.getExternalIdReference() == null ? "" : entity.getExternalIdReference().getContent();
String third = entity.getExternalIdCommonName() == null ? "" : entity.getExternalIdCommonName().getContent();
Triplet<String, String, String> triplet = new Triplet<String, String, String>(first, second, third);
return triplet;
}
private void setContactDetails(ProfileEntity profileEntity, ContactDetails contactDetails) {
if (contactDetails != null) {
setEmails(profileEntity, contactDetails);
setCountry(profileEntity, contactDetails);
}
}
private void setCountry(ProfileEntity profileEntity, ContactDetails contactDetails) {
Country contactCountry = contactDetails.getAddress() != null && contactDetails.getAddress().getCountry() != null ? contactDetails.getAddress().getCountry()
: null;
Iso3166Country country = contactCountry != null ? contactCountry.getValue() : null;
if(country != null) {
Set<AddressEntity> addresses = profileEntity.getAddresses();
if(addresses == null) {
addresses = new HashSet<AddressEntity>();
profileEntity.setAddresses(addresses);
}
boolean addIt = true;
//If the address exists, don't add it
for(AddressEntity address : addresses) {
if(Objects.equals(country.value(), address.getIso2Country().value())) {
addIt = false;
}
}
if(addIt) {
AddressEntity newAddress = new AddressEntity();
newAddress.setDateCreated(new Date());
//The default country is the smallest one, so, lets add this one as the biggest display index possible for the record
newAddress.setIso2Country(org.orcid.jaxb.model.common_v2.Iso3166Country.fromValue(country.value()));
newAddress.setLastModified(new Date());
newAddress.setUser(profileEntity);
newAddress.setVisibility(getDefaultVisibility(profileEntity, contactCountry.getVisibility(), OrcidVisibilityDefaults.COUNTRY_DEFAULT));
//Set source
SourceEntity source = sourceManager.retrieveSourceEntity();
setSource(source, newAddress);
newAddress.setDisplayIndex(0L);
for(AddressEntity address : addresses)
address.setDisplayIndex(address.getDisplayIndex()+1L);
addresses.add(newAddress);
}
}
}
private void setEmails(ProfileEntity profileEntity, ContactDetails contactDetails) {
Set<EmailEntity> existingEmailEntities = profileEntity.getEmails();
Map<String, EmailEntity> existingEmailEntitiesMap = createEmailEntitiesMap(existingEmailEntities);
Set<EmailEntity> emailEntities = null;
if (existingEmailEntities == null) {
emailEntities = new HashSet<>();
} else {
// To allow for orphan deletion
existingEmailEntities.clear();
emailEntities = existingEmailEntities;
}
for (Email email : contactDetails.getEmail()) {
String emailId = email.getValue().trim();
EmailEntity emailEntity = null;
EmailEntity existingEmailEntity = existingEmailEntitiesMap.get(emailId);
if (existingEmailEntity == null) {
emailEntity = new EmailEntity();
emailEntity.setId(emailId);
emailEntity.setProfile(profileEntity);
emailEntity.setSourceId(email.getSource());
emailEntity.setClientSourceId(email.getSourceClientId());
} else {
existingEmailEntity.clean();
emailEntity = existingEmailEntity;
}
emailEntity.setPrimary(email.isPrimary());
emailEntity.setCurrent(email.isCurrent());
emailEntity.setVerified(email.isVerified());
if (email.getVisibility() == null) {
emailEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.PRIVATE);
} else {
emailEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(email.getVisibility().value()));
}
emailEntities.add(emailEntity);
}
profileEntity.setEmails(emailEntities);
}
private Map<String, EmailEntity> createEmailEntitiesMap(Set<EmailEntity> existingEmailsEntities) {
if (existingEmailsEntities == null) {
return new HashMap<>();
}
return EmailEntity.mapById(existingEmailsEntities);
}
private void setHistoryDetails(ProfileEntity profileEntity, OrcidHistory orcidHistory) {
if (orcidHistory != null) {
CompletionDate completionDate = orcidHistory.getCompletionDate();
profileEntity.setCompletedDate(completionDate == null ? null : toDate(completionDate.getValue()));
SubmissionDate submissionDate = orcidHistory.getSubmissionDate();
profileEntity.setSubmissionDate(submissionDate == null ? null : toDate(submissionDate.getValue()));
DeactivationDate deactivationDate = orcidHistory.getDeactivationDate();
profileEntity.setDeactivationDate(deactivationDate == null ? null : toDate(deactivationDate.getValue()));
profileEntity.setClaimed(orcidHistory.isClaimed());
CreationMethod creationMethod = orcidHistory.getCreationMethod();
profileEntity.setCreationMethod(creationMethod != null ? creationMethod.value() : null);
Source source = orcidHistory.getSource();
if (source != null) {
SourceEntity sourceEntity = new SourceEntity();
ClientDetailsEntity clientDetailsEntity = new ClientDetailsEntity();
clientDetailsEntity.setId(source.retrieveSourcePath());
sourceEntity.setSourceClient(clientDetailsEntity);
profileEntity.setSource(sourceEntity);
}
}
}
private void setBiographyDetails(ProfileEntity profileEntity, Biography biography) {
if (biography != null) {
Visibility defaultVisibility = profileEntity.getActivitiesVisibilityDefault() == null ? OrcidVisibilityDefaults.BIOGRAPHY_DEFAULT.getVisibility() : Visibility.fromValue(profileEntity.getActivitiesVisibilityDefault().value());
if(profileEntity.getBiographyEntity() == null) {
profileEntity.setBiographyEntity(new BiographyEntity());
profileEntity.getBiographyEntity().setProfile(profileEntity);
}
profileEntity.getBiographyEntity().setBiography(biography.getContent());
if(profileEntity.getClaimed() == null || !profileEntity.getClaimed()) {
if (biography.getVisibility() != null) {
profileEntity.getBiographyEntity().setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(biography.getVisibility().value()));
} else {
profileEntity.getBiographyEntity().setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(defaultVisibility.value()));
}
}
//Fill the visibility in case it is still null
if(profileEntity.getBiographyEntity().getVisibility() == null) {
profileEntity.getBiographyEntity().setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(defaultVisibility.value()));
}
}
}
private void setOrgAffiliationRelations(ProfileEntity profileEntity, Affiliations affiliations) {
SortedSet<OrgAffiliationRelationEntity> existingOrgAffiliationEntities = profileEntity.getOrgAffiliationRelations();
if (existingOrgAffiliationEntities == null) {
existingOrgAffiliationEntities = new TreeSet<>();
}
Map<String, OrgAffiliationRelationEntity> existingOrgAffiliationsEntitiesMap = createOrgAffiliationEntitiesMap(existingOrgAffiliationEntities);
SortedSet<OrgAffiliationRelationEntity> updatedOrgAffiliationEntities = new TreeSet<>();
if (affiliations != null && !affiliations.getAffiliation().isEmpty()) {
for (Affiliation affiliation : affiliations.getAffiliation()) {
OrgAffiliationRelationEntity orgRelationEntity = getOrgAffiliationRelationEntity(affiliation,
existingOrgAffiliationsEntitiesMap.get(affiliation.getPutCode()));
orgRelationEntity.setProfile(profileEntity);
updatedOrgAffiliationEntities.add(orgRelationEntity);
}
}
Map<String, OrgAffiliationRelationEntity> updatedOrgAffiliationEntitiesMap = createOrgAffiliationEntitiesMap(updatedOrgAffiliationEntities);
// Remove orphans
for (Iterator<OrgAffiliationRelationEntity> iterator = existingOrgAffiliationEntities.iterator(); iterator.hasNext();) {
OrgAffiliationRelationEntity existingEntity = iterator.next();
if (!updatedOrgAffiliationEntitiesMap.containsKey(String.valueOf(existingEntity.getId()))) {
iterator.remove();
}
}
// Add new
for (OrgAffiliationRelationEntity updatedEntity : updatedOrgAffiliationEntities) {
if (updatedEntity.getId() == null) {
existingOrgAffiliationEntities.add(updatedEntity);
}
}
profileEntity.setOrgAffiliationRelations(existingOrgAffiliationEntities);
}
private Map<String, OrgAffiliationRelationEntity> createOrgAffiliationEntitiesMap(Set<OrgAffiliationRelationEntity> orgAffiliationEntities) {
Map<String, OrgAffiliationRelationEntity> map = new HashMap<>();
if (orgAffiliationEntities != null) {
for (OrgAffiliationRelationEntity orgAffiliationEntity : orgAffiliationEntities) {
map.put(String.valueOf(orgAffiliationEntity.getId()), orgAffiliationEntity);
}
}
return map;
}
/**
* Create a map with the provided profileGrantEntities
*
* @param profileGrantEntities
* @return Map<String, ProfileFundingEntity>
* */
private Map<String, ProfileFundingEntity> createProfileFundingEntitiesMap(Set<ProfileFundingEntity> profileFundingEntities) {
Map<String, ProfileFundingEntity> map = new HashMap<>();
if (profileFundingEntities != null) {
for (ProfileFundingEntity profileFundingEntity : profileFundingEntities) {
map.put(String.valueOf(profileFundingEntity.getId()), profileFundingEntity);
}
}
return map;
}
private void setInternalDetails(ProfileEntity profileEntity, OrcidInternal orcidInternal) {
if (orcidInternal != null) {
SecurityDetails securityDetails = orcidInternal.getSecurityDetails();
if (securityDetails != null) {
String encryptedPassword = securityDetails.getEncryptedPassword() != null ? securityDetails.getEncryptedPassword().getContent() : null;
profileEntity.setEncryptedPassword(encryptedPassword);
profileEntity.setSecurityQuestion(securityDetails.getSecurityQuestionId() == null ? null : securityQuestionDao.find((int) securityDetails
.getSecurityQuestionId().getValue()));
String encryptedAnswer = securityDetails.getEncryptedSecurityAnswer() != null ? securityDetails.getEncryptedSecurityAnswer().getContent() : null;
profileEntity.setEncryptedSecurityAnswer(encryptedAnswer);
String verificationCode = securityDetails.getEncryptedVerificationCode() != null ? securityDetails.getEncryptedVerificationCode().getContent() : null;
profileEntity.setEncryptedVerificationCode(verificationCode);
}
if (orcidInternal.getReferredBy() != null) {
profileEntity.setReferredBy(orcidInternal.getReferredBy().getPath());
}
Preferences preferences = orcidInternal.getPreferences();
if (preferences != null) {
String sendEmailFrequencyDays = preferences.getSendEmailFrequencyDays();
profileEntity.setSendEmailFrequencyDays(Float.valueOf(sendEmailFrequencyDays == null ? DefaultPreferences.SEND_EMAIL_FREQUENCY_DAYS
: sendEmailFrequencyDays));
profileEntity.setSendChangeNotifications(preferences.getSendChangeNotifications() == null ? null : preferences.getSendChangeNotifications().isValue());
profileEntity.setSendOrcidNews(preferences.getSendOrcidNews() == null ? null : preferences.getSendOrcidNews().isValue());
profileEntity.setSendMemberUpdateRequests(preferences.getSendMemberUpdateRequests() == null ? null : preferences
.getSendMemberUpdateRequests());
// ActivitiesVisibilityDefault default is WorkVisibilityDefault
if (preferences.getActivitiesVisibilityDefault() != null && preferences.getActivitiesVisibilityDefault().getValue() != null) {
profileEntity.setActivitiesVisibilityDefault(org.orcid.jaxb.model.common_v2.Visibility.fromValue(preferences.getActivitiesVisibilityDefault().getValue().value()));
}
if (preferences.getDeveloperToolsEnabled() != null) {
profileEntity.setEnableDeveloperTools(preferences.getDeveloperToolsEnabled().isValue());
}
profileEntity.setEnableNotifications(preferences.getNotificationsEnabled() == null ? DefaultPreferences.NOTIFICATIONS_ENABLED : preferences.getNotificationsEnabled());
}
if (orcidInternal.getSalesforceId() != null) {
profileEntity.setSalesforeId(orcidInternal.getSalesforceId().getContent());
}
}
}
private void setPreferencesDetails(ProfileEntity profileEntity, OrcidPreferences orcidPreferences) {
if (orcidPreferences != null) {
if (orcidPreferences.getLocale() != null)
profileEntity.setLocale(org.orcid.jaxb.model.common_v2.Locale.fromValue(orcidPreferences.getLocale().value()));
else
profileEntity.setLocale(org.orcid.jaxb.model.common_v2.Locale.EN);
}
}
@Override
public OrgAffiliationRelationEntity getNewOrgAffiliationRelationEntity(Affiliation affiliation, ProfileEntity profileEntity) {
OrgAffiliationRelationEntity orgAffiliationRelationEntity = getOrgAffiliationRelationEntity(affiliation, null);
orgAffiliationRelationEntity.setProfile(profileEntity);
return orgAffiliationRelationEntity;
}
@Override
public OrgAffiliationRelationEntity getUpdatedAffiliationRelationEntity(Affiliation updatedAffiliation) {
if (PojoUtil.isEmpty(updatedAffiliation.getPutCode()))
throw new IllegalArgumentException("Affiliation must contain a put code to be edited");
long affiliationId = Long.valueOf(updatedAffiliation.getPutCode());
OrgAffiliationRelationEntity exisitingOrgAffiliationEntity = orgAffiliationRelationDao.find(affiliationId);
OrgAffiliationRelationEntity orgAffiliationRelationEntity = getOrgAffiliationRelationEntity(updatedAffiliation, exisitingOrgAffiliationEntity);
return orgAffiliationRelationEntity;
}
/**
* Transforms a OrcidGrant object into a ProfileFundingEntity object
*
* @param updatedFunding
* @param profileEntity
* @return ProfileFundingEntity
* */
@Override
public ProfileFundingEntity getNewProfileFundingEntity(Funding updatedFunding, ProfileEntity profileEntity) {
ProfileFundingEntity profileFundingEntity = getProfileFundingEntity(updatedFunding, null);
profileFundingEntity.setProfile(profileEntity);
return profileFundingEntity;
}
/**
* Transforms a OrcidGrant object into a ProfileFundingEntity object
*
* @param updatedFunding
* @param profileEntity
* @return ProfileFundingEntity
* */
@Override
public ProfileFundingEntity getUpdatedProfileFundingEntity(Funding updatedFunding) {
ProfileFundingEntity existingProfileFundingEntity = profileFundingManager.getProfileFundingEntity(Long.valueOf(updatedFunding.getPutCode()));
ProfileFundingEntity profileFundingEntity = getProfileFundingEntity(updatedFunding, existingProfileFundingEntity);
return profileFundingEntity;
}
private OrgAffiliationRelationEntity getOrgAffiliationRelationEntity(Affiliation affiliation, OrgAffiliationRelationEntity exisitingOrgAffiliationEntity) {
if (affiliation != null) {
// Get the org
OrgEntity orgEntity = getOrgEntity(affiliation);
OrgAffiliationRelationEntity orgRelationEntity = null;
if (exisitingOrgAffiliationEntity == null) {
String putCode = affiliation.getPutCode();
if (StringUtils.isNotBlank(putCode) && !"-1".equals(putCode)) {
throw new IllegalArgumentException("Invalid put-code was supplied for an affiliation: " + putCode);
}
orgRelationEntity = new OrgAffiliationRelationEntity();
} else {
orgRelationEntity = exisitingOrgAffiliationEntity;
orgRelationEntity.clean();
}
FuzzyDate startDate = affiliation.getStartDate();
FuzzyDate endDate = affiliation.getEndDate();
if(affiliation.getType() != null) {
orgRelationEntity.setAffiliationType(AffiliationType.fromValue(affiliation.getType().value()));
}
if(affiliation.getVisibility() != null) {
orgRelationEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(affiliation.getVisibility().value()));
} else {
orgRelationEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.PRIVATE);
}
//Set source
setSource(affiliation.getSource(), orgRelationEntity);
orgRelationEntity.setDepartment(affiliation.getDepartmentName());
orgRelationEntity.setEndDate(endDate != null ? new EndDateEntity(endDate) : null);
orgRelationEntity.setOrg(orgEntity);
orgRelationEntity.setTitle(affiliation.getRoleTitle());
orgRelationEntity.setStartDate(startDate != null ? new StartDateEntity(startDate) : null);
if (affiliation.getCreatedDate() != null && affiliation.getCreatedDate().getValue() != null)
orgRelationEntity.setDateCreated(affiliation.getCreatedDate().getValue().toGregorianCalendar().getTime());
if (affiliation.getLastModifiedDate() != null && affiliation.getLastModifiedDate().getValue() != null)
orgRelationEntity.setLastModified(affiliation.getLastModifiedDate().getValue().toGregorianCalendar().getTime());
return orgRelationEntity;
}
return null;
}
/**
* Get a ProfileFundingEntity based on a Grant object
*
* @param funding
* @param exisitingProfileFundingEntity
* @return a ProfileFundingEntity created from the provided funding
* */
private ProfileFundingEntity getProfileFundingEntity(Funding funding, ProfileFundingEntity exisitingProfileFundingEntity) {
if (funding != null) {
// Get the org
OrgEntity orgEntity = getOrgEntity(funding);
ProfileFundingEntity profileFundingEntity = null;
if (exisitingProfileFundingEntity == null) {
String putCode = funding.getPutCode();
if (StringUtils.isNotBlank(putCode) && !"-1".equals(putCode)) {
throw new IllegalArgumentException("Invalid put-code was supplied for a funding: " + putCode);
}
profileFundingEntity = new ProfileFundingEntity();
//Set source
setSource(funding.getSource(), profileFundingEntity);
} else {
profileFundingEntity = exisitingProfileFundingEntity;
profileFundingEntity.clean();
}
FuzzyDate startDate = funding.getStartDate();
FuzzyDate endDate = funding.getEndDate();
if (funding.getAmount() != null) {
String amount = StringUtils.isNotBlank(funding.getAmount().getContent()) ? funding.getAmount().getContent() : null;
String currencyCode = funding.getAmount().getCurrencyCode() != null ? funding.getAmount().getCurrencyCode() : null;
if (StringUtils.isNotBlank(amount)) {
try {
BigDecimal bigDecimalAmount = getAmountAsBigDecimal(amount);
profileFundingEntity.setNumericAmount(bigDecimalAmount);
} catch (Exception e) {
String sample = getSampleAmountInProperFormat(localeManager.getLocale());
throw new IllegalArgumentException("Cannot cast amount: " + amount + " proper format is: " + sample);
}
profileFundingEntity.setCurrencyCode(currencyCode);
}
}
profileFundingEntity.setContributorsJson(getFundingContributorsJson(funding.getFundingContributors()));
profileFundingEntity.setDescription(StringUtils.isNotBlank(funding.getDescription()) ? funding.getDescription() : null);
profileFundingEntity.setEndDate(endDate != null ? new EndDateEntity(endDate) : null);
FundingExternalIdentifiers recordExternalIdentifiers = new FundingExternalIdentifiers(funding.getFundingExternalIdentifiers());
profileFundingEntity.setExternalIdentifiersJson(recordExternalIdentifiers.toDBJSONString());
profileFundingEntity.setStartDate(startDate != null ? new StartDateEntity(startDate) : null);
FundingTitle fundingTitle = funding.getTitle();
if (fundingTitle != null) {
String title = null, translatedTitle = null, languageCode = null;
if (fundingTitle.getTitle() != null)
title = fundingTitle.getTitle().getContent();
if (fundingTitle.getTranslatedTitle() != null) {
translatedTitle = fundingTitle.getTranslatedTitle().getContent();
languageCode = fundingTitle.getTranslatedTitle().getLanguageCode();
}
profileFundingEntity.setTitle(StringUtils.isNotBlank(title) ? title : null);
profileFundingEntity.setTranslatedTitle(StringUtils.isNotBlank(translatedTitle) ? translatedTitle : null);
profileFundingEntity.setTranslatedTitleLanguageCode(StringUtils.isNotBlank(languageCode) ? languageCode : null);
}
if(funding.getType() != null) {
profileFundingEntity.setType(org.orcid.jaxb.model.record_v2.FundingType.fromValue(funding.getType().value()));
}
profileFundingEntity.setOrganizationDefinedType(funding.getOrganizationDefinedFundingType() != null ? funding.getOrganizationDefinedFundingType()
.getContent() : null);
if (funding.getUrl() != null)
profileFundingEntity.setUrl(StringUtils.isNotBlank(funding.getUrl().getValue()) ? funding.getUrl().getValue() : null);
if(funding.getVisibility() != null) {
profileFundingEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(funding.getVisibility().value()));
} else {
profileFundingEntity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.fromValue(OrcidVisibilityDefaults.WORKS_DEFAULT.getVisibility().value()));
}
if (funding.getCreatedDate() != null && funding.getCreatedDate().getValue() != null)
profileFundingEntity.setDateCreated(funding.getCreatedDate().getValue().toGregorianCalendar().getTime());
if (funding.getLastModifiedDate() != null && funding.getLastModifiedDate().getValue() != null)
profileFundingEntity.setLastModified(funding.getLastModifiedDate().getValue().toGregorianCalendar().getTime());
profileFundingEntity.setOrg(orgEntity);
if(profileFundingEntity.getDisplayIndex() == null) {
profileFundingEntity.setDisplayIndex(0L);
}
return profileFundingEntity;
}
return null;
}
/**
* Transforms a string into a BigDecimal, it assumes the amount comes
* already formatted
*
* @param amount
* @return a BigDecimal containing the given amount
* @throws Exception
* if the amount cannot be correctly parse into a BigDecimal
* */
public BigDecimal getAmountAsBigDecimal(String amount) throws Exception {
return new BigDecimal(amount);
}
/**
* Get a string with the proper amount format
*
* @param local
* @return an example string showing how the amount should be entered
* */
private String getSampleAmountInProperFormat(java.util.Locale locale) {
double example = 1234567.89;
NumberFormat numberFormatExample = NumberFormat.getNumberInstance(locale);
return numberFormatExample.format(example);
}
private OrgEntity getOrgEntity(Affiliation affiliation) {
if (affiliation != null) {
OrgEntity orgEntity = new OrgEntity();
Organization organization = affiliation.getOrganization();
orgEntity.setName(organization.getName());
OrganizationAddress address = organization.getAddress();
orgEntity.setCity(address.getCity());
orgEntity.setRegion(address.getRegion());
orgEntity.setCountry(address.getCountry());
if (organization.getDisambiguatedOrganization() != null && organization.getDisambiguatedOrganization().getDisambiguatedOrganizationIdentifier() != null) {
orgEntity.setOrgDisambiguated(orgDisambiguatedDao.findBySourceIdAndSourceType(organization.getDisambiguatedOrganization()
.getDisambiguatedOrganizationIdentifier(), organization.getDisambiguatedOrganization().getDisambiguationSource()));
}
return orgManager.createUpdate(orgEntity);
}
return null;
}
/**
* Get an OrgEntity object based on the provided orcidGrant
*
* @param orcidGrant
* @return a OrgEntity based on the provided OrcidGrant
* */
private OrgEntity getOrgEntity(Funding orcidFunding) {
if (orcidFunding != null) {
OrgEntity orgEntity = new OrgEntity();
Organization organization = orcidFunding.getOrganization();
orgEntity.setName(organization.getName());
OrganizationAddress address = organization.getAddress();
orgEntity.setCity(address.getCity());
orgEntity.setRegion(address.getRegion());
orgEntity.setCountry(address.getCountry());
if (organization.getDisambiguatedOrganization() != null && organization.getDisambiguatedOrganization().getDisambiguatedOrganizationIdentifier() != null) {
orgEntity.setOrgDisambiguated(orgDisambiguatedDao.findBySourceIdAndSourceType(organization.getDisambiguatedOrganization()
.getDisambiguatedOrganizationIdentifier(), organization.getDisambiguatedOrganization().getDisambiguationSource()));
}
return orgManager.createUpdate(orgEntity);
}
return null;
}
private void setSource(Source source, SourceAwareEntity<?> entity) {
if (source != null) {
if(source.getSourceOrcid() != null) {
entity.setSourceId(source.getSourceOrcid().getPath());
}
if(source.getSourceClientId() != null) {
entity.setClientSourceId(source.getSourceClientId().getPath());
}
}
}
private void setSource(SourceEntity source, SourceAwareEntity<?> entity) {
if(source != null){
if(source.getSourceProfile() != null) {
entity.setSourceId(source.getSourceProfile().getId());
}
if(source.getSourceClient() != null) {
entity.setClientSourceId(source.getSourceClient().getId());
}
}
}
private Date toDate(XMLGregorianCalendar completionDate) {
if (completionDate != null) {
GregorianCalendar gregorianCalendar = completionDate.toGregorianCalendar();
return gregorianCalendar.getTime();
}
return null;
}
private String getSourceId() {
SourceEntity source = sourceManager.retrieveSourceEntity();
String sourceId = null;
//source mananger should never return null, but for some unit tests it does, so, we return the user id
if(source != null) {
sourceId = source.getSourceId();
}
return sourceId;
}
private org.orcid.jaxb.model.common_v2.Visibility getDefaultVisibility(ProfileEntity profile, Visibility listVisibility, OrcidVisibilityDefaults elementDefault) {
Visibility defaultVisibility = elementDefault.getVisibility();
//If the profile is not claimed, set the list visibility
if(profile.getClaimed() == null || !profile.getClaimed()) {
if(listVisibility != null) {
defaultVisibility = listVisibility;
} else {
defaultVisibility = OrcidVisibilityDefaults.CREATED_BY_MEMBER_DEFAULT.getVisibility();
}
} else {
//If it is claimed, set the default profile visibility
return profile.getActivitiesVisibilityDefault();
}
return org.orcid.jaxb.model.common_v2.Visibility.fromValue(defaultVisibility.value());
}
}