/**
* =============================================================================
*
* 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.read_only.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import org.orcid.core.adapter.JpaJaxbWorkAdapter;
import org.orcid.core.exception.ExceedMaxNumberOfPutCodesException;
import org.orcid.core.exception.OrcidCoreExceptionMapper;
import org.orcid.core.exception.PutCodeFormatException;
import org.orcid.core.manager.WorkEntityCacheManager;
import org.orcid.core.manager.read_only.WorkManagerReadOnly;
import org.orcid.core.utils.activities.ActivitiesGroup;
import org.orcid.core.utils.activities.ActivitiesGroupGenerator;
import org.orcid.core.utils.activities.WorkComparators;
import org.orcid.jaxb.model.record.summary_v2.WorkGroup;
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.BulkElement;
import org.orcid.jaxb.model.record_v2.ExternalID;
import org.orcid.jaxb.model.record_v2.GroupAble;
import org.orcid.jaxb.model.record_v2.GroupableActivity;
import org.orcid.jaxb.model.record_v2.Work;
import org.orcid.jaxb.model.record_v2.WorkBulk;
import org.orcid.persistence.dao.WorkDao;
import org.orcid.persistence.jpa.entities.MinimizedWorkEntity;
import org.orcid.persistence.jpa.entities.WorkEntity;
import org.springframework.cache.annotation.Cacheable;
public class WorkManagerReadOnlyImpl extends ManagerReadOnlyBaseImpl implements WorkManagerReadOnly {
public static final String BULK_PUT_CODES_DELIMITER = ",";
public static final Integer MAX_BULK_PUT_CODES = 50;
@Resource
protected JpaJaxbWorkAdapter jpaJaxbWorkAdapter;
@Resource
protected OrcidCoreExceptionMapper orcidCoreExceptionMapper;
protected WorkDao workDao;
protected WorkEntityCacheManager workEntityCacheManager;
public void setWorkDao(WorkDao workDao) {
this.workDao = workDao;
}
public void setWorkEntityCacheManager(WorkEntityCacheManager workEntityCacheManager) {
this.workEntityCacheManager = workEntityCacheManager;
}
/**
* Find the works for a specific user
*
* @param orcid
* the Id of the user
* @return the list of works associated to the specific user
*/
@Cacheable(value = "works", key = "#orcid.concat('-').concat(#lastModified)")
public List<Work> findWorks(String orcid, long lastModified) {
List<MinimizedWorkEntity> minimizedWorks = workEntityCacheManager.retrieveMinimizedWorks(orcid, lastModified);
return jpaJaxbWorkAdapter.toMinimizedWork(minimizedWorks);
}
/**
* Find the public works for a specific user
*
* @param orcid
* the Id of the user
* @return the list of works associated to the specific user
*/
@Cacheable(value = "public-works", key = "#orcid.concat('-').concat(#lastModified)")
public List<Work> findPublicWorks(String orcid, long lastModified) {
List<MinimizedWorkEntity> minimizedWorks = workEntityCacheManager.retrievePublicMinimizedWorks(orcid, lastModified);
return jpaJaxbWorkAdapter.toMinimizedWork(minimizedWorks);
}
/**
* Get the given Work from the database
*
* @param orcid
* The work owner
* @param workId
* The work id
*/
@Override
@Cacheable(value = "single-work", key = "#orcid.concat('-').concat(#workId).concat('-').concat(#lastModified)")
public Work getWork(String orcid, Long workId, long lastModified) {
WorkEntity work = workDao.getWork(orcid, workId);
return jpaJaxbWorkAdapter.toWork(work);
}
@Override
@Cacheable(value = "single-work-summary", key = "#orcid.concat('-').concat(#workId).concat('-').concat(#lastModified)")
public WorkSummary getWorkSummary(String orcid, Long workId, long lastModified) {
WorkEntity work = workDao.getWork(orcid, workId);
return jpaJaxbWorkAdapter.toWorkSummary(work);
}
/**
* Get the list of works that belongs to a user
*
* @param userOrcid
* @param lastModified
* Last modified date used to check the cache
* @return the list of works that belongs to this user
*/
@Override
@Cacheable(value = "works-summaries", key = "#orcid.concat('-').concat(#lastModified)")
public List<WorkSummary> getWorksSummaryList(String orcid, long lastModified) {
List<MinimizedWorkEntity> works = workEntityCacheManager.retrieveMinimizedWorks(orcid, lastModified);
return jpaJaxbWorkAdapter.toWorkSummaryFromMinimized(works);
}
/**
* Generate a grouped list of works with the given list of works
*
* @param works
* The list of works to group
* @param justPublic
* Specify if we want to group only the public elements in the
* given list
* @return Works element with the WorkSummary elements grouped
*/
@Override
public Works groupWorks(List<WorkSummary> works, boolean justPublic) {
ActivitiesGroupGenerator groupGenerator = new ActivitiesGroupGenerator();
Works result = new Works();
// Group all works
for (WorkSummary work : works) {
if (justPublic && !work.getVisibility().equals(org.orcid.jaxb.model.common_v2.Visibility.PUBLIC)) {
// If it is just public and the work is not public, just ignore
// it
} else {
groupGenerator.group(work);
}
}
List<ActivitiesGroup> groups = groupGenerator.getGroups();
for (ActivitiesGroup group : groups) {
Set<GroupAble> externalIdentifiers = group.getGroupKeys();
Set<GroupableActivity> activities = group.getActivities();
WorkGroup workGroup = new WorkGroup();
// Fill the work groups with the external identifiers
if(externalIdentifiers == null || externalIdentifiers.isEmpty()) {
// Initialize the ids as an empty list
workGroup.getIdentifiers().getExternalIdentifier();
} else {
for (GroupAble extId : externalIdentifiers) {
ExternalID workExtId = (ExternalID) extId;
workGroup.getIdentifiers().getExternalIdentifier().add(workExtId.clone());
}
}
// Fill the work group with the list of activities
for (GroupableActivity activity : activities) {
WorkSummary workSummary = (WorkSummary) activity;
workGroup.getWorkSummary().add(workSummary);
}
// Sort the works
workGroup.getWorkSummary().sort(WorkComparators.ALL);
result.getWorkGroup().add(workGroup);
}
// Sort the groups!
result.getWorkGroup().sort(WorkComparators.GROUP);
return result;
}
@Override
public WorkBulk findWorkBulk(String orcid, String putCodesAsString, long profileLastModified) {
List<BulkElement> works = new ArrayList<>();
String[] putCodes = getPutCodeArray(putCodesAsString);
for (String putCode : putCodes) {
try {
Long id = Long.valueOf(putCode);
WorkEntity workEntity = workEntityCacheManager.retrieveFullWork(orcid, id, profileLastModified);
works.add(jpaJaxbWorkAdapter.toWork(workEntity));
} catch (Exception e) {
works.add(orcidCoreExceptionMapper.getOrcidError(new PutCodeFormatException("'" + putCode + "' is not a valid put code")));
}
}
WorkBulk bulk = new WorkBulk();
bulk.setBulk(works);
return bulk;
}
private String[] getPutCodeArray(String putCodesAsString) {
String[] putCodeArray = putCodesAsString.split(BULK_PUT_CODES_DELIMITER);
if (putCodeArray.length > MAX_BULK_PUT_CODES) {
throw new ExceedMaxNumberOfPutCodesException(MAX_BULK_PUT_CODES);
}
return putCodeArray;
}
}