/**
* =============================================================================
*
* 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 javax.annotation.Resource;
import org.apache.commons.lang.StringUtils;
import org.orcid.core.manager.SourceNameCacheManager;
import org.orcid.core.utils.RecordNameUtils;
import org.orcid.persistence.dao.ClientDetailsDao;
import org.orcid.persistence.dao.RecordNameDao;
import org.orcid.persistence.jpa.entities.ClientDetailsEntity;
import org.orcid.persistence.jpa.entities.RecordNameEntity;
import org.orcid.utils.ReleaseNameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
/**
*
* @author Angel Montenegro
*
*/
public class SourceNameCacheManagerImpl implements SourceNameCacheManager {
private static final Logger LOGGER = LoggerFactory.getLogger(SourceNameCacheManagerImpl.class);
private static String REQUEST_PROFILE_NAME = "REQUEST_PROFILE_NAME";
@Resource(name = "sourceNameCache")
private Cache sourceNameCache;
LockerObjectsManager lockers = new LockerObjectsManager();
private String releaseName = ReleaseNameUtils.getReleaseName();
private RecordNameDao recordNameDao;
private ClientDetailsDao clientDetailsDao;
public void setRecordNameDao(RecordNameDao recordNameDao) {
this.recordNameDao = recordNameDao;
}
public void setClientDetailsDao(ClientDetailsDao clientDetailsDao) {
this.clientDetailsDao = clientDetailsDao;
}
@Override
public String retrieve(String sourceId) throws IllegalArgumentException {
String cacheKey = getCacheKey(sourceId);
String sourceName = getSourceNameFromCache(sourceNameCache.get(cacheKey));
if (sourceName == null) {
try {
synchronized (lockers.obtainLock(sourceId)) {
sourceName = getSourceNameFromCache(sourceNameCache.get(cacheKey));
if (sourceName == null) {
LOGGER.debug("Fetching source name for: " + sourceId);
sourceName = getProfileSourceNameFromRequest(sourceId);
if (sourceName == null) {
sourceName = getClientSourceName(sourceId);
if (sourceName != null) {
sourceNameCache.put(new Element(cacheKey, sourceName));
} else {
sourceName = getProfileSourceNameFromDb(sourceId);
}
}
}
}
} finally {
lockers.releaseLock(sourceId);
}
}
// If source name is empty, it means the name is not public, so, return
// a null value instead
if (StringUtils.EMPTY.equals(sourceName)) {
return null;
}
return sourceName;
}
@Override
public void removeAll() {
sourceNameCache.removeAll();
}
@Override
public void remove(String sourceId) {
sourceNameCache.remove(getCacheKey(sourceId));
}
private String getSourceNameFromCache(Element element) {
return (String) (element != null ? element.getObjectValue() : null);
}
private String getCacheKey(String sourceId) {
return releaseName + "_" + sourceId;
}
private String getClientSourceName(String clientId) {
if (clientDetailsDao.existsAndIsNotPublicClient(clientId)) {
ClientDetailsEntity clientDetails = clientDetailsDao.find(clientId);
return clientDetails != null ? clientDetails.getClientName() : null;
}
return null;
}
private String getProfileSourceNameFromRequest(String orcid) {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (sra != null) {
Object requestAttribute = sra.getAttribute(getProfileNameSRAKey(orcid), ServletRequestAttributes.SCOPE_REQUEST);
if (requestAttribute != null) {
return (String) requestAttribute;
}
}
return null;
}
private String getProfileSourceNameFromDb(String orcid) {
RecordNameEntity recordName = null;
try {
recordName = recordNameDao.getRecordName(orcid);
if (recordName == null) {
throw new IllegalArgumentException("Unable to find source name for: " + orcid);
}
} catch (Exception e) {
LOGGER.warn("Cannot find source name from profile matching " + orcid, e);
throw new IllegalArgumentException("Unable to find source name for: " + orcid);
}
String name = RecordNameUtils.getPublicName(recordName);
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (sra != null) {
sra.setAttribute(getProfileNameSRAKey(orcid), name != null ? name : StringUtils.EMPTY, ServletRequestAttributes.SCOPE_REQUEST);
}
return name;
}
private String getProfileNameSRAKey(String orcid) {
return REQUEST_PROFILE_NAME + "_" + orcid;
}
}