/** * ============================================================================= * * 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.manager.impl; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.orcid.core.exception.ApplicationException; import org.orcid.core.exception.OrcidDuplicatedElementException; import org.orcid.core.manager.ExternalIdentifierManager; import org.orcid.core.manager.OrcidSecurityManager; import org.orcid.core.manager.ProfileEntityCacheManager; import org.orcid.core.manager.ProfileEntityManager; import org.orcid.core.manager.SourceManager; import org.orcid.core.manager.read_only.impl.ExternalIdentifierManagerReadOnlyImpl; import org.orcid.core.manager.validator.PersonValidator; import org.orcid.core.utils.DisplayIndexCalculatorHelper; import org.orcid.jaxb.model.common_v2.Visibility; import org.orcid.jaxb.model.record_v2.PersonExternalIdentifier; import org.orcid.jaxb.model.record_v2.PersonExternalIdentifiers; import org.orcid.persistence.jpa.entities.ExternalIdentifierEntity; import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.persistence.jpa.entities.SourceEntity; import org.orcid.pojo.ajaxForm.PojoUtil; import org.springframework.beans.factory.annotation.Value; public class ExternalIdentifierManagerImpl extends ExternalIdentifierManagerReadOnlyImpl implements ExternalIdentifierManager { @Value("${org.orcid.core.validations.requireRelationship:false}") private boolean requireRelationshipOnExternalIdentifier; @Resource private SourceManager sourceManager; @Resource private OrcidSecurityManager orcidSecurityManager; @Resource private ProfileEntityManager profileEntityManager; @Resource private ProfileEntityCacheManager profileEntityCacheManager; @Override public PersonExternalIdentifier createExternalIdentifier(String orcid, PersonExternalIdentifier externalIdentifier, boolean isApiRequest) { SourceEntity sourceEntity = sourceManager.retrieveSourceEntity(); // Validate external identifier PersonValidator.validateExternalIdentifier(externalIdentifier, sourceEntity, true, isApiRequest, null, requireRelationshipOnExternalIdentifier); // Validate it is not duplicated List<ExternalIdentifierEntity> existingExternalIdentifiers = externalIdentifierDao.getExternalIdentifiers(orcid, getLastModified(orcid)); for (ExternalIdentifierEntity existing : existingExternalIdentifiers) { if (isDuplicated(existing, externalIdentifier, sourceEntity)) { Map<String, String> params = new HashMap<String, String>(); params.put("type", "external-identifier"); params.put("value", externalIdentifier.getUrl().getValue()); throw new OrcidDuplicatedElementException(params); } } ExternalIdentifierEntity newEntity = jpaJaxbExternalIdentifierAdapter.toExternalIdentifierEntity(externalIdentifier); ProfileEntity profile = profileEntityCacheManager.retrieve(orcid); newEntity.setOwner(profile); newEntity.setDateCreated(new Date()); if(sourceEntity.getSourceProfile() != null) { newEntity.setSourceId(sourceEntity.getSourceProfile().getId()); } if(sourceEntity.getSourceClient() != null) { newEntity.setClientSourceId(sourceEntity.getSourceClient().getId()); } setIncomingPrivacy(newEntity, profile); DisplayIndexCalculatorHelper.setDisplayIndexOnNewEntity(newEntity, isApiRequest); externalIdentifierDao.persist(newEntity); return jpaJaxbExternalIdentifierAdapter.toExternalIdentifier(newEntity); } @Override public PersonExternalIdentifier updateExternalIdentifier(String orcid, PersonExternalIdentifier externalIdentifier, boolean isApiRequest) { SourceEntity sourceEntity = sourceManager.retrieveSourceEntity(); ExternalIdentifierEntity updatedExternalIdentifierEntity = externalIdentifierDao.getExternalIdentifierEntity(orcid, externalIdentifier.getPutCode()); //Save the original source String existingSourceId = updatedExternalIdentifierEntity.getSourceId(); String existingClientSourceId = updatedExternalIdentifierEntity.getClientSourceId(); Visibility originalVisibility = Visibility.fromValue(updatedExternalIdentifierEntity.getVisibility().value()); // Validate external identifier PersonValidator.validateExternalIdentifier(externalIdentifier, sourceEntity, false, isApiRequest, originalVisibility, requireRelationshipOnExternalIdentifier); // Validate it is not duplicated List<ExternalIdentifierEntity> existingExternalIdentifiers = externalIdentifierDao.getExternalIdentifiers(orcid, getLastModified(orcid)); for (ExternalIdentifierEntity existing : existingExternalIdentifiers) { if (isDuplicated(existing, externalIdentifier, sourceEntity)) { Map<String, String> params = new HashMap<String, String>(); params.put("type", "external-identifier"); params.put("value", externalIdentifier.getUrl().getValue()); throw new OrcidDuplicatedElementException(params); } } orcidSecurityManager.checkSource(updatedExternalIdentifierEntity); jpaJaxbExternalIdentifierAdapter.toExternalIdentifierEntity(externalIdentifier, updatedExternalIdentifierEntity); updatedExternalIdentifierEntity.setLastModified(new Date()); //Set source updatedExternalIdentifierEntity.setSourceId(existingSourceId); updatedExternalIdentifierEntity.setClientSourceId(existingClientSourceId); externalIdentifierDao.merge(updatedExternalIdentifierEntity); return jpaJaxbExternalIdentifierAdapter.toExternalIdentifier(updatedExternalIdentifierEntity); } private boolean isDuplicated(ExternalIdentifierEntity existing, PersonExternalIdentifier newExternalIdentifier, SourceEntity source) { if (!existing.getId().equals(newExternalIdentifier.getPutCode())) { // If they have the same source String existingSourceId = existing.getElementSourceId(); if (!PojoUtil.isEmpty(existingSourceId) && existingSourceId.equals(source.getSourceId())) { // And they have the same reference if ((PojoUtil.isEmpty(existing.getExternalIdReference()) && PojoUtil.isEmpty(newExternalIdentifier.getValue())) || (!PojoUtil.isEmpty(existing.getExternalIdReference()) && existing.getExternalIdReference().equals(newExternalIdentifier.getValue()))) { // And they have the same type if ((PojoUtil.isEmpty(existing.getExternalIdCommonName()) && PojoUtil.isEmpty(newExternalIdentifier.getType())) || (!PojoUtil.isEmpty(existing.getExternalIdCommonName()) && existing.getExternalIdCommonName().equals(newExternalIdentifier.getType()))) { return true; } } } } return false; } private void setIncomingPrivacy(ExternalIdentifierEntity entity, ProfileEntity profile) { org.orcid.jaxb.model.common_v2.Visibility incomingExternalIdentifierVisibility = entity.getVisibility(); org.orcid.jaxb.model.common_v2.Visibility defaultExternalIdentifierVisibility = (profile.getActivitiesVisibilityDefault() == null) ? org.orcid.jaxb.model.common_v2.Visibility.PRIVATE : org.orcid.jaxb.model.common_v2.Visibility.fromValue(profile.getActivitiesVisibilityDefault().value()); if (profile.getClaimed() != null && profile.getClaimed()) { entity.setVisibility(defaultExternalIdentifierVisibility); } else if (incomingExternalIdentifierVisibility == null) { entity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.PRIVATE); } } @Override public boolean deleteExternalIdentifier(String orcid, Long id, boolean checkSource) { ExternalIdentifierEntity extIdEntity = externalIdentifierDao.getExternalIdentifierEntity(orcid, id); if (extIdEntity == null) { return false; } if(checkSource) { orcidSecurityManager.checkSource(extIdEntity); } try { externalIdentifierDao.removeExternalIdentifier(orcid, id); } catch (Exception e) { return false; } return true; } @Override public PersonExternalIdentifiers updateExternalIdentifiers(String orcid, PersonExternalIdentifiers externalIdentifiers) { List<ExternalIdentifierEntity> existingExternalIdentifiersList = externalIdentifierDao.getExternalIdentifiers(orcid, getLastModified(orcid)); // Delete the deleted ones for (ExternalIdentifierEntity existing : existingExternalIdentifiersList) { boolean deleteMe = true; if(externalIdentifiers.getExternalIdentifiers() != null) { for (PersonExternalIdentifier updatedOrNew : externalIdentifiers.getExternalIdentifiers()) { if (existing.getId().equals(updatedOrNew.getPutCode())) { deleteMe = false; break; } } } if (deleteMe) { try { externalIdentifierDao.removeExternalIdentifier(orcid, existing.getId()); } catch (Exception e) { throw new ApplicationException("Unable to delete external identifier " + existing.getId(), e); } } } if (externalIdentifiers != null && externalIdentifiers.getExternalIdentifiers() != null) { for (PersonExternalIdentifier updatedOrNew : externalIdentifiers.getExternalIdentifiers()) { if (updatedOrNew.getPutCode() != null) { // Update the existing ones for (ExternalIdentifierEntity existingExtId : existingExternalIdentifiersList) { if (existingExtId.getId().equals(updatedOrNew.getPutCode())) { existingExtId.setLastModified(new Date()); existingExtId.setVisibility(updatedOrNew.getVisibility()); existingExtId.setDisplayIndex(updatedOrNew.getDisplayIndex()); externalIdentifierDao.merge(existingExtId); } } } } } return externalIdentifiers; } }