/**
* =============================================================================
*
* 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 javax.annotation.Resource;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.orcid.core.manager.ClientDetailsEntityCacheManager;
import org.orcid.core.manager.ClientDetailsManager;
import org.orcid.persistence.jpa.entities.ClientDetailsEntity;
import org.orcid.utils.ReleaseNameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ClientDetailsEntityCacheManagerImpl implements ClientDetailsEntityCacheManager {
private static final Logger LOG = LoggerFactory.getLogger(ClientDetailsEntityCacheManagerImpl.class);
@Resource
private ClientDetailsManager clientDetailsManager;
@Resource(name = "clientDetailsEntityCache")
private Cache clientDetailsCache;
private String releaseName = ReleaseNameUtils.getReleaseName();
LockerObjectsManager lockers = new LockerObjectsManager();
@Override
public ClientDetailsEntity retrieve(String clientId) throws IllegalArgumentException {
Object key = new ClientIdCacheKey(clientId, releaseName);
Date dbDate = retrieveLastModifiedDate(clientId);
ClientDetailsEntity clientDetails = toClientDetailsEntity(clientDetailsCache.get(key));
if (needsFresh(dbDate, clientDetails)) {
try {
synchronized (lockers.obtainLock(clientId)) {
clientDetails = toClientDetailsEntity(clientDetailsCache.get(key));
if (needsFresh(dbDate, clientDetails)) {
clientDetails = clientDetailsManager.findByClientId(clientId);
if(clientDetails == null)
throw new IllegalArgumentException("Invalid client id " + clientId);
clientDetailsCache.put(new Element(key, clientDetails));
}
}
} finally {
lockers.releaseLock(clientId);
}
}
return clientDetails;
}
@Override
public ClientDetailsEntity retrieveByIdP(String idp) throws IllegalArgumentException {
Object key = new ClientIdCacheKey("IdP+" + idp, releaseName);
Date dbDate = retrieveLastModifiedDateByIdP(idp);
ClientDetailsEntity clientDetails = toClientDetailsEntity(clientDetailsCache.get(key));
if (needsFresh(dbDate, clientDetails)) {
try {
synchronized (lockers.obtainLock(idp)) {
clientDetails = toClientDetailsEntity(clientDetailsCache.get(key));
if (needsFresh(dbDate, clientDetails)) {
clientDetails = clientDetailsManager.findByIdP(idp);
if(clientDetails == null)
throw new IllegalArgumentException("Invalid idp " + idp);
clientDetailsCache.put(new Element(key, clientDetails));
}
}
} finally {
lockers.releaseLock(idp);
}
}
return clientDetails;
}
@Override
public void put(ClientDetailsEntity clientDetailsEntity) {
put(clientDetailsEntity.getId(), clientDetailsEntity);
}
public void put(String clientId, ClientDetailsEntity client) {
try {
synchronized (lockers.obtainLock(clientId)) {
clientDetailsCache.put(new Element(new ClientIdCacheKey(clientId, releaseName), client));
}
} finally {
lockers.releaseLock(clientId);
}
}
@Override
public void removeAll() {
clientDetailsCache.removeAll();
}
@Override
public void remove(String clientId) {
clientDetailsCache.remove(new ClientIdCacheKey(clientId, releaseName));
}
private Date retrieveLastModifiedDate(String clientId) {
Date date = null;
try {
date = clientDetailsManager.getLastModified(clientId);
} catch (javax.persistence.NoResultException e) {
LOG.debug("Missing lastModifiedDate clientId:" + clientId);
}
return date;
}
private Date retrieveLastModifiedDateByIdP(String idp) {
Date date = null;
try {
date = clientDetailsManager.getLastModifiedByIdp(idp);
} catch (javax.persistence.NoResultException e) {
LOG.debug("Missing lastModifiedDate idp:" + idp);
}
return date;
}
static public ClientDetailsEntity toClientDetailsEntity(Element element) {
return (ClientDetailsEntity) (element != null ? element.getObjectValue() : null);
}
static public boolean needsFresh(Date dbDate, ClientDetailsEntity clientDetailsEntity) {
if (clientDetailsEntity == null)
return true;
if (dbDate == null) // not sure when this happens?
return true;
if (clientDetailsEntity.getLastModified().getTime() != dbDate.getTime())
return true;
return false;
}
}