/**
* =============================================================================
*
* 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.OrcidSecurityManager;
import org.orcid.core.manager.ProfileEntityCacheManager;
import org.orcid.core.manager.ResearcherUrlManager;
import org.orcid.core.manager.SourceManager;
import org.orcid.core.manager.read_only.impl.ResearcherUrlManagerReadOnlyImpl;
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.ResearcherUrl;
import org.orcid.jaxb.model.record_v2.ResearcherUrls;
import org.orcid.persistence.jpa.entities.ProfileEntity;
import org.orcid.persistence.jpa.entities.ResearcherUrlEntity;
import org.orcid.persistence.jpa.entities.SourceEntity;
import org.orcid.pojo.ajaxForm.PojoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
public class ResearcherUrlManagerImpl extends ResearcherUrlManagerReadOnlyImpl implements ResearcherUrlManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ResearcherUrlManagerImpl.class);
@Resource
private SourceManager sourceManager;
@Resource
private OrcidSecurityManager orcidSecurityManager;
@Resource
private ProfileEntityCacheManager profileEntityCacheManager;
@Override
public boolean deleteResearcherUrl(String orcid, Long id, boolean checkSource) {
boolean result = true;
ResearcherUrlEntity toDelete = researcherUrlDao.getResearcherUrl(orcid, id);
if(checkSource) {
orcidSecurityManager.checkSource(toDelete);
}
try {
researcherUrlDao.deleteResearcherUrl(orcid, id);
} catch(Exception e) {
LOGGER.error("Unable to delete researcherUrl with ID: " + id);
result = false;
}
return result;
}
/**
* Update the researcher urls associated with a specific account
*
* @param orcid
* @param researcherUrls
* */
@Override
@Transactional
public ResearcherUrls updateResearcherUrls(String orcid, ResearcherUrls researcherUrls) {
List<ResearcherUrlEntity> existingEntities = researcherUrlDao.getResearcherUrls(orcid, getLastModified(orcid));
//Delete the deleted ones
for(ResearcherUrlEntity existingEntity : existingEntities) {
boolean deleteMe = true;
if(researcherUrls.getResearcherUrls() != null) {
for(ResearcherUrl updatedOrNew : researcherUrls.getResearcherUrls()) {
if(existingEntity.getId().equals(updatedOrNew.getPutCode())) {
deleteMe = false;
break;
}
}
}
if(deleteMe) {
try {
researcherUrlDao.deleteResearcherUrl(existingEntity.getProfile().getId(), existingEntity.getId());
} catch (Exception e) {
throw new ApplicationException("Unable to delete researcher url " + existingEntity.getId(), e);
}
}
}
// Update or create new
if(researcherUrls != null && researcherUrls.getResearcherUrls() != null) {
for(ResearcherUrl updatedOrNew : researcherUrls.getResearcherUrls()) {
if(updatedOrNew.getPutCode() != null) {
//Update the existing ones
for(ResearcherUrlEntity existingEntity : existingEntities) {
if(existingEntity.getId().equals(updatedOrNew.getPutCode())) {
existingEntity.setLastModified(new Date());
existingEntity.setVisibility(updatedOrNew.getVisibility());
existingEntity.setUrl(updatedOrNew.getUrl().getValue());
existingEntity.setUrlName(updatedOrNew.getUrlName());
existingEntity.setDisplayIndex(updatedOrNew.getDisplayIndex());
researcherUrlDao.merge(existingEntity);
}
}
} else {
//Add the new ones
ResearcherUrlEntity newResearcherUrl = jpaJaxbResearcherUrlAdapter.toResearcherUrlEntity(updatedOrNew);
SourceEntity sourceEntity = sourceManager.retrieveSourceEntity();
ProfileEntity profile = new ProfileEntity(orcid);
newResearcherUrl.setUser(profile);
newResearcherUrl.setDateCreated(new Date());
newResearcherUrl.setLastModified(new Date());
if(sourceEntity.getSourceProfile() != null) {
newResearcherUrl.setSourceId(sourceEntity.getSourceProfile().getId());
}
if(sourceEntity.getSourceClient() != null) {
newResearcherUrl.setClientSourceId(sourceEntity.getSourceClient().getId());
}
newResearcherUrl.setVisibility(updatedOrNew.getVisibility());
newResearcherUrl.setDisplayIndex(updatedOrNew.getDisplayIndex());
researcherUrlDao.persist(newResearcherUrl);
}
}
}
return researcherUrls;
}
@Override
@Transactional
public ResearcherUrl updateResearcherUrl(String orcid, ResearcherUrl researcherUrl, boolean isApiRequest) {
ResearcherUrlEntity updatedResearcherUrlEntity = researcherUrlDao.getResearcherUrl(orcid, researcherUrl.getPutCode());
Visibility originalVisibility = Visibility.fromValue(updatedResearcherUrlEntity.getVisibility().value());
SourceEntity sourceEntity = sourceManager.retrieveSourceEntity();
//Save the original source
String existingSourceId = updatedResearcherUrlEntity.getSourceId();
String existingClientSourceId = updatedResearcherUrlEntity.getClientSourceId();
// Validate the researcher url
PersonValidator.validateResearcherUrl(researcherUrl, sourceEntity, false, isApiRequest, originalVisibility);
// Validate it is not duplicated
List<ResearcherUrlEntity> existingResearcherUrls = researcherUrlDao.getResearcherUrls(orcid, getLastModified(orcid));
for (ResearcherUrlEntity existing : existingResearcherUrls) {
if (isDuplicated(existing, researcherUrl, sourceEntity)) {
Map<String, String> params = new HashMap<String, String>();
params.put("type", "researcher-url");
params.put("value", researcherUrl.getUrlName());
throw new OrcidDuplicatedElementException(params);
}
}
orcidSecurityManager.checkSource(updatedResearcherUrlEntity);
jpaJaxbResearcherUrlAdapter.toResearcherUrlEntity(researcherUrl, updatedResearcherUrlEntity);
updatedResearcherUrlEntity.setLastModified(new Date());
//Be sure it doesn't overwrite the source
updatedResearcherUrlEntity.setSourceId(existingSourceId);
updatedResearcherUrlEntity.setClientSourceId(existingClientSourceId);
researcherUrlDao.merge(updatedResearcherUrlEntity);
return jpaJaxbResearcherUrlAdapter.toResearcherUrl(updatedResearcherUrlEntity);
}
@Override
public ResearcherUrl createResearcherUrl(String orcid, ResearcherUrl researcherUrl, boolean isApiRequest) {
SourceEntity sourceEntity = sourceManager.retrieveSourceEntity();
// Validate the researcher url
PersonValidator.validateResearcherUrl(researcherUrl, sourceEntity, true, isApiRequest, null);
// Validate it is not duplicated
List<ResearcherUrlEntity> existingResearcherUrls = researcherUrlDao.getResearcherUrls(orcid, getLastModified(orcid));
for (ResearcherUrlEntity existing : existingResearcherUrls) {
if (isDuplicated(existing, researcherUrl, sourceEntity)) {
Map<String, String> params = new HashMap<String, String>();
params.put("type", "researcher-url");
params.put("value", researcherUrl.getUrlName());
throw new OrcidDuplicatedElementException(params);
}
}
ResearcherUrlEntity newEntity = jpaJaxbResearcherUrlAdapter.toResearcherUrlEntity(researcherUrl);
ProfileEntity profile = profileEntityCacheManager.retrieve(orcid);
newEntity.setUser(profile);
newEntity.setDateCreated(new Date());
//Set the source
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);
researcherUrlDao.persist(newEntity);
return jpaJaxbResearcherUrlAdapter.toResearcherUrl(newEntity);
}
private boolean isDuplicated(ResearcherUrlEntity existing, ResearcherUrl newResearcherUrl, SourceEntity source) {
if (!existing.getId().equals(newResearcherUrl.getPutCode())) {
//If they have the same source
String existingSourceId = existing.getElementSourceId();
// If they have the same source
if (!PojoUtil.isEmpty(existingSourceId) && existingSourceId.equals(source.getSourceId())) {
// If the url is the same
if (existing.getUrl() != null && existing.getUrl().equals(newResearcherUrl.getUrl().getValue())) {
return true;
}
}
}
return false;
}
private void setIncomingPrivacy(ResearcherUrlEntity entity, ProfileEntity profile) {
org.orcid.jaxb.model.common_v2.Visibility incomingWorkVisibility = entity.getVisibility();
org.orcid.jaxb.model.common_v2.Visibility defaultResearcherUrlsVisibility = (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(defaultResearcherUrlsVisibility);
} else if (incomingWorkVisibility == null) {
entity.setVisibility(org.orcid.jaxb.model.common_v2.Visibility.PRIVATE);
}
}
}