From: Katja Luther Date: Fri, 16 Mar 2018 13:40:05 +0000 (+0100) Subject: adapt taxeditor cache to cdmlib-cache X-Git-Tag: 5.0.0^2~263 X-Git-Url: https://dev.e-taxonomy.eu/gitweb/taxeditor.git/commitdiff_plain/f4cc04f2b9598a3fb594c14edf7b9b0159ed0a55 adapt taxeditor cache to cdmlib-cache --- diff --git a/eu.etaxonomy.taxeditor.cdmlib/.classpath b/eu.etaxonomy.taxeditor.cdmlib/.classpath index baf1c113a..42ddf885a 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/.classpath +++ b/eu.etaxonomy.taxeditor.cdmlib/.classpath @@ -1,227 +1,229 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eu.etaxonomy.taxeditor.cdmlib/META-INF/MANIFEST.MF b/eu.etaxonomy.taxeditor.cdmlib/META-INF/MANIFEST.MF index a1f60491a..e38ed9c5e 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/META-INF/MANIFEST.MF +++ b/eu.etaxonomy.taxeditor.cdmlib/META-INF/MANIFEST.MF @@ -34,6 +34,7 @@ Export-Package: com.google.api, eu.etaxonomy.cdm.api.utility, eu.etaxonomy.cdm.api.validation, eu.etaxonomy.cdm.api.validation.batch, + eu.etaxonomy.cdm.cache, eu.etaxonomy.cdm.common, eu.etaxonomy.cdm.common.media, eu.etaxonomy.cdm.common.monitor, @@ -653,6 +654,7 @@ Bundle-ClassPath: ., lib/cdmlib-persistence-4.15.0-SNAPSHOT.jar, lib/cdmlib-print-4.15.0-SNAPSHOT.jar, lib/cdmlib-remote-4.15.0-SNAPSHOT.jar, + lib/cdmlib-cache-4.15.0-SNAPSHOT.jar, lib/cdmlib-services-4.15.0-SNAPSHOT.jar, lib/cdmlib-test-4.15.0-SNAPSHOT.jar, lib/com.springsource.org.aopalliance-1.0.0.jar, diff --git a/eu.etaxonomy.taxeditor.cdmlib/build.properties b/eu.etaxonomy.taxeditor.cdmlib/build.properties index a80a00a80..7ebfc414c 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/build.properties +++ b/eu.etaxonomy.taxeditor.cdmlib/build.properties @@ -220,7 +220,8 @@ bin.includes = META-INF/,\ lib/lucene-analyzers-3.6.2.jar,\ lib/lucene-analyzers-common-5.4.1.jar,\ lib/lucene-sandbox-5.4.1.jar,\ - lib/lucene-suggest-5.4.1.jar + lib/lucene-suggest-5.4.1.jar,\ + lib/cdmlib-cache-4.15.0-SNAPSHOT.jar jars.compile.order = . output.. = bin/ diff --git a/eu.etaxonomy.taxeditor.cdmlib/pom.xml b/eu.etaxonomy.taxeditor.cdmlib/pom.xml index d79ec0c7c..d727157d0 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/pom.xml +++ b/eu.etaxonomy.taxeditor.cdmlib/pom.xml @@ -39,7 +39,7 @@ cdmlib-remote-webapp - cdmlib-services,cdmlib-commons,cdmlib-persistence,cdmlib-ext,cdmlib-model,cdmlib-io,cdmlib-print,cdmlib-remote,cdmlib-test + cdmlib-services,cdmlib-commons,cdmlib-cache,cdmlib-persistence,cdmlib-ext,cdmlib-model,cdmlib-io,cdmlib-print,cdmlib-remote,cdmlib-test ${basedir}/lib true @@ -236,7 +236,11 @@ cdmlib-test ${cdmlib.version} - + + eu.etaxonomy + cdmlib-cache + ${cdmlib.version} + net.sf.ehcache ehcache-core @@ -478,6 +482,7 @@ 1.1.0.Final + diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java index 97dd56e02..9d6bd88ef 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/application/CdmApplicationRemoteController.java @@ -20,11 +20,11 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import eu.etaxonomy.cdm.api.service.ITestService; +import eu.etaxonomy.cdm.cache.CdmRemoteCacheManager; import eu.etaxonomy.cdm.common.monitor.IProgressMonitor; import eu.etaxonomy.cdm.common.monitor.NullProgressMonitor; import eu.etaxonomy.cdm.ext.geo.IEditGeoService; import eu.etaxonomy.cdm.io.service.IIOService; -import eu.etaxonomy.taxeditor.remoting.cache.CdmRemoteCacheManager; import eu.etaxonomy.taxeditor.remoting.source.ICdmRemoteSource; import eu.etaxonomy.taxeditor.service.ICachedCommonService; import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager; diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java index c8fd418cf..788d4e932 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java @@ -7,13 +7,13 @@ import org.springframework.stereotype.Component; import eu.etaxonomy.cdm.api.application.CdmApplicationState; import eu.etaxonomy.cdm.api.config.EhCacheConfiguration; +import eu.etaxonomy.cdm.cache.CacheLoader; +import eu.etaxonomy.cdm.cache.CdmEntityCacheKey; +import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher; import eu.etaxonomy.cdm.common.CdmUtils; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.model.common.DefinedTermBase; import eu.etaxonomy.cdm.model.common.TermBase; -import eu.etaxonomy.taxeditor.remoting.cache.CacheLoader; -import eu.etaxonomy.taxeditor.remoting.cache.CdmEntityCacheKey; -import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher; import eu.etaxonomy.taxeditor.service.TermServiceRequestExecutor; import eu.etaxonomy.taxeditor.session.CdmEntitySession; import eu.etaxonomy.taxeditor.session.ICdmEntitySession; @@ -58,6 +58,9 @@ public class CdmServiceCacher extends CdmCacher implements ICdmEntitySessionMana } + + + /** * */ diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CacheLoader.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CacheLoader.java deleted file mode 100644 index ac773837d..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CacheLoader.java +++ /dev/null @@ -1,409 +0,0 @@ -/** - * Copyright (C) 2015 EDIT - * European Distributed Institute of Taxonomy - * http://www.e-taxonomy.eu - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * See LICENSE.TXT at the top of this package for the full license terms. - */ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.apache.log4j.Logger; -import org.springframework.util.ReflectionUtils; - -import eu.etaxonomy.cdm.api.service.pager.Pager; -import eu.etaxonomy.cdm.model.ICdmCacher; -import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.cdm.persistence.dto.MergeResult; -import net.sf.ehcache.Cache; -import net.sf.ehcache.Element; - -/** - * @author cmathew - * @date 19 Feb 2015 - * - */ -public class CacheLoader { - private static final Logger logger = Logger.getLogger(CacheLoader.class); - - private static boolean isRecursiveEnabled = true; - - protected final ICdmCacher cdmCacher; - - private final Cache cdmlibModelCache; - - - - public CacheLoader(ICdmCacher cdmCacher) { - this.cdmCacher = cdmCacher; - this.cdmlibModelCache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache(); - - } - - - public CdmModelFieldPropertyFromClass getFromCdmlibModelCache(String className) { - Element e = cdmlibModelCache.get(className); - if (e == null) { - return null; - } else { - return (CdmModelFieldPropertyFromClass) e.getObjectValue(); - } - } - - @SuppressWarnings("unchecked") - public T load(T obj, boolean recursive, boolean update) { - if(obj == null) { - return null; - } - if(obj instanceof CdmBase) { - return (T) load((CdmBase)obj, recursive, update); - } else if (obj instanceof Map) { - return (T) load((Map)obj, recursive, update); - } else if (obj instanceof Collection) { - return (T) load((Collection)obj, recursive, update); - } else if(obj instanceof Pager) { - load(((Pager)obj).getRecords(), recursive, update); - return obj; - } else if(obj instanceof MergeResult) { - return (T) load((MergeResult)obj, recursive, update); - } - - return obj; - } - - @SuppressWarnings("unchecked") - private T loadRecursive(T obj, List alreadyVisitedEntities, boolean update) { - if(obj == null) { - return null; - } - if(obj instanceof CdmBase) { - return (T) loadRecursive((CdmBase)obj, alreadyVisitedEntities, update); - } else if (obj instanceof Map) { - return (T) load((Map)obj, alreadyVisitedEntities, update); - } else if (obj instanceof Collection) { - return (T) load((Collection)obj, alreadyVisitedEntities, update); - } else if (obj instanceof MergeResult) { - return (T) loadRecursive((MergeResult)obj, alreadyVisitedEntities, update); - } - - - logger.info("No caching yet for type " + obj.getClass().getName()); - - return obj; - } - - public Map load(Map map, boolean recursive, boolean update){ - - - if(isRecursiveEnabled && recursive) { - logger.info("---- starting recursive load for cdm entity map"); - List alreadyVisitedEntities = new ArrayList(); - Map cachedMap = load(map, alreadyVisitedEntities, update); - alreadyVisitedEntities.clear(); - logger.info("---- ending recursive load for cdm entity map \n"); - return cachedMap; - } else { - return load(map, null, update); - } - } - - - private Map load(Map map, List alreadyVisitedEntities, boolean update){ - //map = (Map)deproxy(map); - - if(map == null || map.isEmpty()) { - return map; - } - - Object[] result = new Object[ map.size() * 2 ]; - Iterator> iter = map.entrySet().iterator(); - int i=0; - // to avoid ConcurrentModificationException - alreadyVisitedEntities.add(map); - while ( iter.hasNext() ) { - Map.Entry e = iter.next(); - result[i++] = e.getKey(); - result[i++] = e.getValue(); - } - - for(i=0; i Collection load(Collection collection, boolean recursive, boolean update){ - - Collection loadedCollection; - if(isRecursiveEnabled && recursive) { - logger.info("---- starting recursive load for cdm entity collection"); - List alreadyVisitedEntities = new ArrayList(); - Collection cachedCollection = load(collection, alreadyVisitedEntities, update); - alreadyVisitedEntities.clear(); - logger.info("---- ending recursive load for cdm entity collection \n"); - loadedCollection = cachedCollection; - } else { - loadedCollection = load(collection, null, update); - } - return loadedCollection; - } - - @SuppressWarnings("unchecked") - private Collection load(Collection collection, List alreadyVisitedEntities, boolean update) { - - - - if(collection == null || collection.isEmpty()) { - return collection; - } - int length = collection.size(); - Object[] result = new Object[length]; - Iterator collectionItr = collection.iterator(); - int count = 0; - // to avoid ConcurrentModificationException - alreadyVisitedEntities.add(collection); - while(collectionItr.hasNext()) { - Object obj = collectionItr.next(); - if(alreadyVisitedEntities == null) { - result[count] = load(obj, false, update); - } else { - result[count] = loadRecursive(obj, alreadyVisitedEntities, update); - } - - count++; - } - - collection.clear(); - - for ( int i = 0; i < length; i++ ) { - collection.add((T)result[i]); - } - - return collection; - } - - - public MergeResult load(MergeResult mergeResult, boolean recursive, boolean update) { - CdmBase cdmBase = load(mergeResult.getMergedEntity(), recursive, update); - load(mergeResult.getNewEntities(), recursive, update); - return new MergeResult(cdmBase, mergeResult.getNewEntities()); - } - - public MergeResult loadRecursive(MergeResult mergeResult,List alreadyVisitedEntities, boolean update) { - CdmBase cdmBase = loadRecursive(mergeResult.getMergedEntity(), alreadyVisitedEntities, update); - loadRecursive(mergeResult.getNewEntities(), alreadyVisitedEntities, update); - return new MergeResult(cdmBase, mergeResult.getNewEntities()); - } - - /** - * Puts the (Key,Value) pair of ({@link java.util.UUID}, {@link eu.etaxonomy.cdm.model.common.CdmBase}), - * in the cache corresponding to the given cache id - * - * @param cacheId - * @param uuid - * @param cdmEntity - */ - public CdmBase load(CdmBase cdmEntity, boolean recursive, boolean update) { - if(cdmEntity == null) { - return null; - } - - // start by looking up the cdm entity in the cache - CdmBase cachedCdmEntity = cdmCacher.getFromCache(cdmEntity); - - if(cachedCdmEntity != null) { - // if cdm entity was found in cache then - logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " already exists"); - // .. return if the cached and input objects are identical, else (this is a newly loaded object so) continue - if(cachedCdmEntity == cdmEntity) { - return cachedCdmEntity; - } - } - - CdmBase loadedCdmBase; - if(isRecursiveEnabled && recursive) { - logger.info("---- starting recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId()); - List alreadyVisitedEntities = new ArrayList(); - CdmBase cb = loadRecursive(cdmEntity, alreadyVisitedEntities, update); - alreadyVisitedEntities.clear(); - logger.info("---- ending recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + "\n"); - loadedCdmBase = cb; - } else { - loadedCdmBase = load(cdmEntity); - } - return loadedCdmBase; - - } - - - protected CdmBase load(CdmBase cdmEntity) { - logger.info("loading object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId()); - cdmCacher.put((CdmBase)ProxyUtils.deproxy(cdmEntity)); - return cdmCacher.getFromCache(cdmEntity); - } - - - private CdmBase loadRecursive(CdmBase cdmEntity, List alreadyVisitedEntities, boolean update) { - - CdmBase cachedCdmEntity = load(cdmEntity); - - - // we want to recursive through the cdmEntity (and not the cachedCdmEntity) - // since there could be new or deleted objects in the cdmEntity sub-graph - - // start by getting the fields from the cdm entity - String className = cdmEntity.getClass().getName(); - CdmModelFieldPropertyFromClass cmgmfc = getFromCdmlibModelCache(className); - if(cmgmfc != null) { - alreadyVisitedEntities.add(cdmEntity); - List fields = cmgmfc.getFields(); - for(String field : fields) { - // retrieve the actual object corresponding to the field. - // this object will be either a CdmBase or a Collection / Map - // with CdmBase as the generic type - - CdmBase cdmEntityInSubGraph = getCdmBaseTypeFieldValue(cdmEntity, cachedCdmEntity, field, alreadyVisitedEntities, update); - if(cdmEntityInSubGraph != null) { - //checkForIdenticalCdmEntity(alreadyVisitedEntities, cdmEntityInSubGraph); - if(!checkForIdenticalCdmEntity(alreadyVisitedEntities, cdmEntityInSubGraph)) { - logger.info("recursive loading object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId()); - loadRecursive(cdmEntityInSubGraph, alreadyVisitedEntities, update); - } else { - logger.info("object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId() + " already visited"); - } - } - } - } else { - throw new CdmClientCacheException("CdmEntity with class " + cdmEntity.getClass().getName() + " is not found in the cdmlib model cache. " + - "The cache may be corrupted or not in sync with the latest model version" ); - } - - return cachedCdmEntity; - } - - - private CdmBase getCdmBaseTypeFieldValue(CdmBase cdmEntity, - CdmBase cachedCdmEntity, - String fieldName, - List alreadyVisitedEntities, - boolean update) { - - // this method attempts to make sure that for any two objects found in - // the object graph, if they are equal then they should also be the same, - // which is crucial for the merge to work - if(cachedCdmEntity == null) { - throw new CdmClientCacheException("When trying to set field value, the cached cdm entity cannot be null"); - } - - Class clazz = cdmEntity.getClass(); - try { - // this call will search in the provided class as well as - // the super classes until it finds the field - Field field = ReflectionUtils.findField(clazz, fieldName); - - if(field == null) { - throw new CdmClientCacheException("Field '" + fieldName - + "' not found when searching in class '" + clazz.getName() + "' and its superclasses"); - } - field.setAccessible(true); - Object o = field.get(cdmEntity); - // resetting the value in cdm entity to the deproxied object - o = ProxyUtils.deproxy(o); - field.set(cdmEntity, o); - Object cachedo = field.get(cachedCdmEntity); - CdmBase cdmEntityInSubGraph = null; - - if(!ProxyUtils.isProxy(o) && (update || ProxyUtils.isProxy(cachedo))) { - // if we are in update mode we have to make the field of the cached entity - // up-to-date by setting it to the value of the cdm entity being loaded - // - // if the cdm entity is a proxy then we always update to make sure that - // newly created entities are always up-to-date - // - // NOTE : the field is overridden in the case of the exception - // found below - field.set(cachedCdmEntity, o); - - } - - if(o != null && !ProxyUtils.isProxy(o)) { - if(CdmBase.class.isAssignableFrom(o.getClass())) { - logger.info("found initialised cdm entity '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId()); - - cdmEntityInSubGraph = (CdmBase)o; - CdmBase cachedCdmEntityInSubGraph = cdmCacher.getFromCache(cdmEntityInSubGraph); - - if(cachedCdmEntityInSubGraph != null) { - if(cachedCdmEntityInSubGraph != cdmEntityInSubGraph) { - // exception : is the case where - // the field has been already initialised, cached and - // is not the same as the one in the cache, in which case we set the value - // of the field to the one found in the cache - logger.info("setting cached + real value to '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId()); - field.set(cachedCdmEntity, cachedCdmEntityInSubGraph); - field.set(cdmEntity, cachedCdmEntityInSubGraph); - } else { - // since the field value object in cdmEntity - // is the same as the field value object in cachedCdmEntity - // we are sure that the its subgraph is also correctly loaded, - // so we can exit the recursion - return null; - } - } - } else if(o instanceof Map && !checkForIdenticalCdmEntity(alreadyVisitedEntities, o)) { - loadRecursive((Map)o, alreadyVisitedEntities, update); - } else if(o instanceof Collection && !checkForIdenticalCdmEntity(alreadyVisitedEntities, o)) { - loadRecursive((Collection)o, alreadyVisitedEntities, update); - } - } - // we return the original cdm entity in the sub graph because we - // want to continue to recurse on the input cdm entity graph - // and not the one in the cache - return cdmEntityInSubGraph; - } catch (SecurityException e) { - throw new CdmClientCacheException(e); - } catch (IllegalArgumentException e) { - throw new CdmClientCacheException(e); - } catch (IllegalAccessException e) { - throw new CdmClientCacheException(e); - } - } - - private boolean checkForIdenticalCdmEntity(List objList, Object objToCompare) { - if(objToCompare != null) { - for(Object obj : objList) { - if(obj == objToCompare) { - return true; - } - } - } - return false; - } - - - public static boolean isRecursiveEnabled() { - return isRecursiveEnabled; - } - - public static void setRecursiveEnabled(boolean ire) { - isRecursiveEnabled = ire; - } -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmClientCacheException.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmClientCacheException.java deleted file mode 100644 index e00649f76..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmClientCacheException.java +++ /dev/null @@ -1,12 +0,0 @@ -package eu.etaxonomy.taxeditor.remoting.cache; - -public class CdmClientCacheException extends RuntimeException { - - public CdmClientCacheException(String message) { - super(message); - } - - public CdmClientCacheException(Exception e) { - super(e); - } -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmEntityCacheKey.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmEntityCacheKey.java deleted file mode 100644 index 74e543cef..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmEntityCacheKey.java +++ /dev/null @@ -1,56 +0,0 @@ -package eu.etaxonomy.taxeditor.remoting.cache; - -import eu.etaxonomy.cdm.model.common.CdmBase; - -public class CdmEntityCacheKey { - - private Class persistenceClass; - private int persistenceId; - - public CdmEntityCacheKey(CdmBase cdmBase) { - this.persistenceClass = cdmBase.getClass(); - this.persistenceId = cdmBase.getId(); - } - - public CdmEntityCacheKey(Class clazz, int id) { - this.persistenceClass = clazz; - this.persistenceId = id; - } - - - - public Class getPersistenceClass() { - return persistenceClass; - } - - public int getPersistenceId() { - return persistenceId; - } - @Override - public boolean equals(Object obj) { - if(obj == null || !(obj instanceof CdmEntityCacheKey)) { - return false; - } - - if(this == obj) { - return true; - } - CdmEntityCacheKey that = (CdmEntityCacheKey) obj; - if(this.persistenceClass.equals(that.persistenceClass) && this.persistenceId == that.persistenceId) { - return true; - } - - return false; - } - - @Override - public int hashCode() { - return (this.persistenceClass.getName() + String.valueOf(this.persistenceId)).hashCode(); - } - - @Override - public String toString() { - return this.persistenceClass.getName() + String.valueOf(this.persistenceId); - } - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelCacher.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelCacher.java deleted file mode 100644 index 640056619..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelCacher.java +++ /dev/null @@ -1,179 +0,0 @@ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.reflect.Field; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.Element; - -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.Platform; -import org.hibernate.SessionFactory; -import org.hibernate.boot.Metadata; -import org.hibernate.boot.MetadataSources; -import org.hibernate.boot.registry.StandardServiceRegistry; -import org.hibernate.boot.registry.StandardServiceRegistryBuilder; -import org.hibernate.cfg.Configuration; -import org.hibernate.mapping.PersistentClass; -import org.hibernate.mapping.Property; -import org.hibernate.metadata.ClassMetadata; -import org.hibernate.property.access.spi.Getter; -import org.osgi.framework.Bundle; - - -/** - * This class serializing and deserializing the CDM model for performance purposes. - * To serialize it see the comments on {@link #main(String[])} and on - * https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/TaxonomicEditorDevelopersGuide#Model-Change-Actions - * - * @author c.mathew - * @date 2015 - * - */ -public class CdmModelCacher { - - - public static String HB_CONFIG_FILE_PATH= "/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml"; - - public static final String CDM_MAP_SER_FILE_PATH = "resources/cdm.map.ser"; - - - - - public void cacheGetterFields(Cache cache) throws IOException, ClassNotFoundException, URISyntaxException { - Map modelClassMap = loadModelClassMap(); - - cache.removeAll(); - - for(Map.Entry entry : modelClassMap.entrySet()) { - cache.put(new Element(entry.getKey(), entry.getValue())); - } - } - - public Map loadModelClassMap() throws URISyntaxException, IOException, ClassNotFoundException { - - Bundle bundle = Platform.getBundle("eu.etaxonomy.taxeditor.cdmlib"); - - URL modelMapFileBundleURL = bundle.getEntry(CDM_MAP_SER_FILE_PATH); - URL modelMapFileURL = FileLocator.resolve(modelMapFileBundleURL); - String modelMapFilePath = modelMapFileURL.getFile(); - - FileInputStream fin = new FileInputStream(modelMapFilePath); - ObjectInputStream ois = new ObjectInputStream(fin); - @SuppressWarnings("unchecked") - Map modelClassMap = (Map) ois.readObject(); - ois.close(); - return modelClassMap; - } - - - public Map generateModelClassMap() { - - // A SessionFactory is set up once for an application! - final StandardServiceRegistry registry = new StandardServiceRegistryBuilder() - .configure(HB_CONFIG_FILE_PATH) // configures settings from hibernate.cfg.xml - .build(); - SessionFactory sessionFactory = null; - Map modelClassMap = new HashMap<>(); - try { -// ConnectionProvider connectionProvider = registry.getService(ConnectionProvider.class); -// DatasourceConnectionProviderImpl providerImpl = registry.getService(DatasourceConnectionProviderImpl.class); - - Metadata metadata = new MetadataSources( registry ).buildMetadata(); - sessionFactory = metadata.buildSessionFactory(); -// Configuration configuration = buildConfiguration(HB_CONFIG_FILE_PATH); - Map classMetaDataMap = sessionFactory.getAllClassMetadata(); -// Metadata metadata = new MetadataSources( registry ).getMetadataBuilder().applyImplicitNamingStrategy( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE ).build(); - - - for(ClassMetadata classMetaData :classMetaDataMap.values()) { - Class mappedClass = classMetaData.getMappedClass(); - - String mappedClassName = mappedClass.getName(); - - PersistentClass persistentClass =metadata.getEntityBinding(mappedClassName); - CdmModelFieldPropertyFromClass cmgmfc = new CdmModelFieldPropertyFromClass(mappedClassName); - System.out.println("Adding class : " + mappedClassName + " to cache"); - addGetters(persistentClass, cmgmfc); - modelClassMap.put(mappedClassName, cmgmfc); - } - } - catch (Exception e) { - // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory - // so destroy it manually. - StandardServiceRegistryBuilder.destroy( registry ); - e.printStackTrace(); - } - - - return modelClassMap; - } - - - public static Configuration buildConfiguration(String hibernateConfigFilePath) { - Configuration configuration = new Configuration().configure(hibernateConfigFilePath); - configuration.buildMappings(); - return configuration; - } - - private void addGetters(PersistentClass persistentClass, CdmModelFieldPropertyFromClass cmgmfc) { - if (persistentClass != null) { - Iterator propertyIt = persistentClass.getPropertyIterator(); - - while(propertyIt.hasNext()) - { - Property property = (Property)propertyIt.next(); - Getter getter = property.getGetter(persistentClass.getMappedClass()); - if(getter != null && getter.getMember() != null) { - Field field = (Field)getter.getMember(); - - //logger.info(" - contains field '" + field.getName() + "' of type '" + field.getType().getName() + "'"); - cmgmfc.addGetMethods(field.getName()); - } - } - addGetters(persistentClass.getSuperclass(), cmgmfc); - } - } - - - - public static void main(String argv[]) { - - // To re-create the serialised cdm map run, - // mvn exec:java -Dexec.mainClass="eu.etaxonomy.taxeditor.remoting.cache.CdmModelCacher" - // in the eu.etaxonomy.taxeditor.cdmlib project root dir - // See also https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/TaxonomicEditorDevelopersGuide#Model-Change-Actions - //Note AM: does not fully work for me, but running the main from the IDE works. - String CDM_MAP_SER_DIR = "resources/"; - - CdmModelCacher cdmModelCacher = new CdmModelCacher(); - Map modelClassMap = cdmModelCacher.generateModelClassMap(); - try{ - if (!modelClassMap.isEmpty()){ - FileOutputStream fout = new FileOutputStream(CDM_MAP_SER_DIR + "cdm.map.ser"); - ObjectOutputStream oos = new ObjectOutputStream(fout); - oos.writeObject(modelClassMap); - oos.close(); - System.out.println("CDM Map serialized"); - }else{ - String message = "CDM Map was empty. Model cache update NOT successful"; - System.out.println(message); - } - - }catch(Exception ex){ - ex.printStackTrace(); - } - - } - - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelCacherConnectionProvider.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelCacherConnectionProvider.java deleted file mode 100644 index 20aee0c4d..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelCacherConnectionProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -package eu.etaxonomy.taxeditor.remoting.cache; - -import javax.sql.DataSource; - -import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl; - -import eu.etaxonomy.cdm.database.CdmDataSource; - -/** - * This is a very preliminary class to get the model cache running. Need to better understand how - * the datasource works with hibernate service registry before implementing the correct way. - - * Or use a running source. - * - * When changing this class please also adapt https://dev.e-taxonomy.eu/redmine/projects/edit/wiki/TaxonomicEditorDevelopersGuide#Model-Change-Actions - * - * @author a.mueller - * - */ -public class CdmModelCacherConnectionProvider extends DatasourceConnectionProviderImpl{ - private static final long serialVersionUID = 454393966637126346L; - - public CdmModelCacherConnectionProvider() { - super(); - setDataSource(getDataSourcePreliminary()); - } - - private DataSource getDataSourcePreliminary() { - String database = "xyz"; - String path = "C:\\Users\\a.mueller\\.cdmLibrary\\writableResources\\h2\\LocalH2_" + database; - String username = "sa"; - CdmDataSource dataSource = CdmDataSource.NewH2EmbeddedInstance("cdmTest", username, "", path); - return dataSource; - } - - - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelFieldPropertyFromClass.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelFieldPropertyFromClass.java deleted file mode 100644 index e90ec6d3c..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmModelFieldPropertyFromClass.java +++ /dev/null @@ -1,51 +0,0 @@ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -public class CdmModelFieldPropertyFromClass implements Serializable { - - private static final long serialVersionUID = 5726395976531887526L; - private String className; - private String parentClassName; - - private List fields = new ArrayList(); - - - public CdmModelFieldPropertyFromClass(String className) { - this.setClassName(className); - } - - public String getParentClassName() { - return parentClassName; - } - - public void setParentClassName(String parentClassName) { - this.parentClassName = parentClassName; - } - - public List getFields() { - return fields; - } - - public void setFields(List fields) { - this.fields = fields; - } - - public void addGetMethods(String getMethod) { - this.fields.add(getMethod); - } - - public String getClassName() { - return className; - } - - public void setClassName(String className) { - this.className = className; - } - - - - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmRemoteCacheManager.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmRemoteCacheManager.java deleted file mode 100644 index a2c4d1c66..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmRemoteCacheManager.java +++ /dev/null @@ -1,94 +0,0 @@ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.io.IOException; -import java.net.URISyntaxException; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheException; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.config.SizeOfPolicyConfiguration; - -import org.apache.log4j.Logger; - - -public class CdmRemoteCacheManager { - - private static final Logger logger = Logger.getLogger(CdmRemoteCacheManager.class); - - - private Cache cdmlibModelCache; - - private static CdmRemoteCacheManager cdmRemoteCacheManager = null; - - public static final String CDM_MODEL_CACHE_NAME = "cdmModelGetMethodsCache"; - - private static Thread initThread; - - private static boolean cacheInitialised = false; - - public enum CdmCacheManagerType { - CDMLIB_MODEL, - DEFAULT - } - - public static CdmRemoteCacheManager getInstance(){ - - if(cdmRemoteCacheManager == null) { - cdmRemoteCacheManager = new CdmRemoteCacheManager(); - } - return cdmRemoteCacheManager; - } - private CdmRemoteCacheManager() { - - - try { - // NOTE:Programmatically creating the cache manager may solve the problem of - // recreating data written to disk on startup - // see https://stackoverflow.com/questions/1729605/ehcache-persist-to-disk-issues - //String cacheFilePath = CDMLIB_CACHE_MANAGER_CONFIG_RESOURCE.getFile().getAbsolutePath(); - //InputStream in = this.getClass().getClassLoader().getResourceAsStream("cdmlib-ehcache.xml"); - - SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration(); - sizeOfConfig.setMaxDepth(1000); - sizeOfConfig.setMaxDepthExceededBehavior("abort"); - - CacheConfiguration modelcc = new CacheConfiguration(CDM_MODEL_CACHE_NAME, 0) - .eternal(true) - .statistics(true) - .sizeOfPolicy(sizeOfConfig) - .overflowToOffHeap(false); - - cdmlibModelCache = new Cache(modelcc); - - CacheManager.create().addCache(cdmlibModelCache); - CdmModelCacher cmdmc = new CdmModelCacher(); - cmdmc.cacheGetterFields(cdmlibModelCache); - - } catch (CacheException e) { - throw new CdmClientCacheException(e); - } catch (ClassNotFoundException e) { - throw new CdmClientCacheException(e); - } catch (IOException e) { - throw new CdmClientCacheException(e); - } catch (URISyntaxException e) { - throw new CdmClientCacheException(e); - } - - } - - - public Cache getCdmModelGetMethodsCache(){ - return cdmlibModelCache; - } - - public static void removeEntityCaches() { - CacheManager cm = CacheManager.create(); - String[] cacheNames = CacheManager.create().getCacheNames(); - for(String cacheName : cacheNames) { - if(!cacheName.equals(CDM_MODEL_CACHE_NAME)) { - cm.removeCache(cacheName); - } - } - } -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmTransientEntityCacher.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmTransientEntityCacher.java deleted file mode 100644 index 21c04da42..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmTransientEntityCacher.java +++ /dev/null @@ -1,328 +0,0 @@ -/** - * Copyright (C) 2014 EDIT - * European Distributed Institute of Taxonomy - * http://www.e-taxonomy.eu - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * See LICENSE.TXT at the top of this package for the full license terms. - */ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.apache.log4j.Logger; - -import eu.etaxonomy.cdm.api.application.CdmApplicationState; -import eu.etaxonomy.cdm.api.cache.CdmServiceCacher; -import eu.etaxonomy.cdm.api.service.UpdateResult; -import eu.etaxonomy.cdm.api.service.dto.CdmEntityIdentifier; -import eu.etaxonomy.cdm.model.ICdmCacher; -import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.cdm.persistence.dto.MergeResult; -import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager; -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Element; -import net.sf.ehcache.Status; -import net.sf.ehcache.config.CacheConfiguration; -import net.sf.ehcache.config.SizeOfPolicyConfiguration; -import net.sf.ehcache.statistics.LiveCacheStatistics; - -/** - * - * This cache guarantees that - * - all objects put will be ancestors of CdmBase - * - all CdmBase objects in the cache will be already de-proxied - * - after any CdmBase object is put in the cache, - * all non-null / non-proxy CdmBase objects in the sub-graph - * will also be present in the cache. - * - * @author cmathew - * @date 14 Oct 2014 - * - */ - -public class CdmTransientEntityCacher implements ICdmCacher { - - private static final Logger logger = Logger.getLogger(CdmTransientEntityCacher.class); - - - private final ICdmEntitySessionManager cdmEntitySessionManager; - - private static CdmServiceCacher cdmServiceCacher; - - private final String cacheId; - - private final Cache cache; - - private final CacheLoader cacheLoader; - - private final Map newEntitiesMap = new HashMap(); - - public CdmTransientEntityCacher(String cacheId, ICdmEntitySessionManager cdmEntitySessionManager) { - this.cacheId = cacheId; - - cache = new Cache(getEntityCacheConfiguration(cacheId)); - - CacheManager.create().removeCache(cache.getName()); - CacheManager.create().addCache(cache); - - this.cdmEntitySessionManager = cdmEntitySessionManager; - - cacheLoader = new CacheLoader(this); - - } - - public CdmTransientEntityCacher(Object sessionOwner, ICdmEntitySessionManager cdmEntitySessionManager) { - this(generateCacheId(sessionOwner), cdmEntitySessionManager); - } - - public static String generateCacheId(Object sessionOwner) { - return sessionOwner.getClass().getName() + String.valueOf(sessionOwner.hashCode()); - } - - /** - * Returns the default cache configuration. - * - * @return - */ - private CacheConfiguration getEntityCacheConfiguration(String cacheId) { - SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration(); - sizeOfConfig.setMaxDepth(100); - sizeOfConfig.setMaxDepthExceededBehavior("abort"); - - return new CacheConfiguration(cacheId, 0) - .eternal(true) - .statistics(true) - .sizeOfPolicy(sizeOfConfig) - .overflowToOffHeap(false); - - } - - public static void setDefaultCacher(CdmServiceCacher css) { - cdmServiceCacher = css; - } - - public LiveCacheStatistics getCacheStatistics() { - if(cache.getStatus() == Status.STATUS_ALIVE) { - return cache.getLiveCacheStatistics(); - } - return null; - - } - - /** - * Returns the cache corresponding to the cache id - * - * @param cacheId - * @return - */ - private Cache getCache() { - return CacheManager.create().getCache(cacheId); - } - - public T load(T obj, boolean update) { - return cacheLoader.load(obj, true, update); - } - - public Map load(Map map, boolean update){ - return cacheLoader.load(map, true, update); - } - - public Collection load(Collection collection, boolean update){ - return cacheLoader.load(collection, true, update); - } - - public CdmBase load(CdmBase cdmEntity, boolean update) { - return cacheLoader.load(cdmEntity, true, update); - } - - - private CdmBase load(CdmEntityIdentifier cei, boolean update) { - return CdmApplicationState.getCommonService().findWithUpdate(cei.getCdmClass(), cei.getId()); - } - - - public UpdateResult load(UpdateResult result, boolean update) { - // probably a good time to broadcast to other sessions - - Set updatedObjects = result.getUpdatedObjects(); - Set reloadedObjects = new HashSet(); - Set updatedCdmIds = result.getUpdatedCdmIds(); - boolean updatedCdmIdsIsEmpty = updatedCdmIds.isEmpty(); - - // if the cdm identifier set contains identifiers of objects already - // present in the updated objects set reomve them - for(CdmBase updatedObject : updatedObjects) { - if(updatedObject != null && exists(new CdmEntityCacheKey(updatedObject.getClass(), updatedObject.getId()))) { - CdmEntityIdentifier cdmEntityIdentifier = new CdmEntityIdentifier(updatedObject.getId(), updatedObject.getClass()); - if(!updatedCdmIdsIsEmpty && updatedCdmIds.contains(cdmEntityIdentifier)) { - updatedCdmIds.remove(cdmEntityIdentifier); - } - reloadedObjects.add(cacheLoader.load(updatedObject, true, update)); - } - } - - // remote load cdm identifiers of objects which already exist - // in the cache - - for(CdmEntityIdentifier cei : updatedCdmIds) { - if(exists(new CdmEntityCacheKey(cei.getCdmClass(), cei.getId()))) { - reloadedObjects.add(load(cei, update)); - } - - } - updatedObjects.clear(); - result.addUpdatedObjects(reloadedObjects); - return result; - } - - public MergeResult load(MergeResult mergeResult, boolean update) { - return cacheLoader.load(mergeResult, true, update); - } - - public CdmModelFieldPropertyFromClass getFromCdmlibModelCache(String className) { - return cacheLoader.getFromCdmlibModelCache(className); - } - - - public void addNewEntity(CdmBase newEntity) { - if(newEntity != null && newEntity.getId() == 0 && newEntity.getUuid() != null) { - newEntitiesMap.put(newEntity.getUuid(), newEntity); - } - } - - @Override - public void put(CdmBase cdmEntity) { - - CdmBase cachedCdmEntity = cdmServiceCacher.load(cdmEntity); - if(cachedCdmEntity != null) { - logger.info("Cdm Entity with id : " + cdmEntity.getId() + " already exists in permanent cache. Ignoring put."); - return; - } - CdmEntityCacheKey id = new CdmEntityCacheKey(cdmEntity); - - cachedCdmEntity = getFromCache(id); - if(cachedCdmEntity == null) { - CdmBase cdmEntityToCache = cdmEntity; - CdmBase newEntity = newEntitiesMap.get(cdmEntity.getUuid()); - if(newEntity != null) { - newEntity.setId(cdmEntity.getId()); - cdmEntityToCache = newEntity; - } - getCache().put(new Element(id, cdmEntityToCache)); - cdmEntityToCache.initListener(); - newEntitiesMap.remove(cdmEntity.getUuid()); - logger.info(" - object of type " + cdmEntityToCache.getClass().getName() + " with id " + cdmEntityToCache.getId() + " put in cache"); - return; - } - logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " already exists"); - } - - - private Element getCacheElement(CdmEntityCacheKey key) { - return getCache().get(key); - } - - - public CdmBase getFromCache(CdmEntityCacheKey id) { - Element e = getCacheElement(id); - - if (e == null) { - return null; - } else { - return (CdmBase) e.getObjectValue(); - } - } - - public CdmBase getFromCache(Class clazz, int id) { - CdmEntityCacheKey cacheId = generateKey(clazz,id); - return getFromCache(cacheId); - } - - @Override - public CdmBase getFromCache(CdmBase cdmBase) { - - CdmEntityCacheKey cacheId = generateKey((CdmBase)ProxyUtils.deproxy(cdmBase)); - // first try this cache - CdmBase cachedCdmEntity = getFromCache(cacheId); - - if(cachedCdmEntity == null) { - // ... then try the permanent cache - cachedCdmEntity = cdmServiceCacher.getFromCache(cdmBase.getUuid()); - } - - return cachedCdmEntity; - } - - public CdmBase getFromCache(CdmBase cdmBase, Class clazz) { - - cdmBase = CdmBase.deproxy(cdmBase, clazz); - return getFromCache(cdmBase); - } - - public List getAllEntities() { - List entities = new ArrayList(); - Map elementsMap = getCache().getAllWithLoader(getCache().getKeys(), null); - for (Map.Entry entry : elementsMap.entrySet()) { - entities.add(entry.getValue()); - } - return entities; - } - - public boolean exists(CdmEntityCacheKey key) { - return (getCacheElement(key) != null); - } - - public boolean existsAndIsNotNull(CdmEntityCacheKey id) { - return getFromCache(id) != null; - } - - public void clear() { - cache.removeAll(); - } - - public void dispose() { - CacheManager.create().removeCache(cache.getName()); - cache.dispose(); - newEntitiesMap.clear(); - - } - - - public static CdmEntityCacheKey generateKey(Class clazz, int id) { - return new CdmEntityCacheKey(clazz, id); - } - - - public static CdmEntityCacheKey generateKey(CdmBase cdmBase) { - Class entityClass = cdmBase.getClass(); - int id = cdmBase.getId(); - return new CdmEntityCacheKey(entityClass, id); - } - - @Override - public CdmBase load(CdmBase cdmEntity) { - return load(cdmEntity, true); - } - - @Override - public boolean isCachable(CdmBase cdmEntity) { - return true; - } - - @Override - public boolean exists(CdmBase cdmBase) { - return exists(generateKey(cdmBase)); - } - - - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/ConversationalTransientEntityCacher.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/ConversationalTransientEntityCacher.java new file mode 100755 index 000000000..af8e9c21c --- /dev/null +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/ConversationalTransientEntityCacher.java @@ -0,0 +1,75 @@ +// $Id$ +/** +* Copyright (C) 2018 EDIT +* European Distributed Institute of Taxonomy +* http://www.e-taxonomy.eu +* +* The contents of this file are subject to the Mozilla Public License Version 1.1 +* See LICENSE.TXT at the top of this package for the full license terms. +*/ +package eu.etaxonomy.taxeditor.remoting.cache; + +import java.util.HashSet; +import java.util.Set; + +import eu.etaxonomy.cdm.api.application.CdmApplicationState; +import eu.etaxonomy.cdm.api.service.UpdateResult; +import eu.etaxonomy.cdm.api.service.dto.CdmEntityIdentifier; +import eu.etaxonomy.cdm.cache.CdmEntityCacheKey; +import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher; +import eu.etaxonomy.cdm.model.common.CdmBase; + +/** + * @author k.luther + * @date 15.03.2018 + * + */ +public class ConversationalTransientEntityCacher extends CdmTransientEntityCacher { + + /** + * @param sessionOwner + */ + public ConversationalTransientEntityCacher(Object sessionOwner) { + super(sessionOwner); + + } + private CdmBase load(CdmEntityIdentifier cei, boolean update) { + return CdmApplicationState.getCommonService().findWithUpdate(cei.getCdmClass(), cei.getId()); + } + + + public UpdateResult load(UpdateResult result, boolean update) { + // probably a good time to broadcast to other sessions + + Set updatedObjects = result.getUpdatedObjects(); + Set reloadedObjects = new HashSet(); + Set updatedCdmIds = result.getUpdatedCdmIds(); + boolean updatedCdmIdsIsEmpty = updatedCdmIds.isEmpty(); + + // if the cdm identifier set contains identifiers of objects already + // present in the updated objects set reomve them + for(CdmBase updatedObject : updatedObjects) { + if(updatedObject != null && super.exists(new CdmEntityCacheKey(updatedObject.getClass(), updatedObject.getId()))) { + CdmEntityIdentifier cdmEntityIdentifier = new CdmEntityIdentifier(updatedObject.getId(), updatedObject.getClass()); + if(!updatedCdmIdsIsEmpty && updatedCdmIds.contains(cdmEntityIdentifier)) { + updatedCdmIds.remove(cdmEntityIdentifier); + } + reloadedObjects.add(load(updatedObject, update)); + } + } + + // remote load cdm identifiers of objects which already exist + // in the cache + + for(CdmEntityIdentifier cei : updatedCdmIds) { + if(exists(new CdmEntityCacheKey(cei.getCdmClass(), cei.getId()))) { + reloadedObjects.add(load(cei, update)); + } + + } + updatedObjects.clear(); + result.addUpdatedObjects(reloadedObjects); + return result; + } + +} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/EntityCacherDebugResult.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/EntityCacherDebugResult.java deleted file mode 100644 index ede3d16ca..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/EntityCacherDebugResult.java +++ /dev/null @@ -1,539 +0,0 @@ -/** - * Copyright (C) 2015 EDIT - * European Distributed Institute of Taxonomy - * http://www.e-taxonomy.eu - * - * The contents of this file are subject to the Mozilla Public License Version 1.1 - * See LICENSE.TXT at the top of this package for the full license terms. - */ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import net.sf.ehcache.Cache; -import net.sf.ehcache.CacheManager; -import net.sf.ehcache.Element; - -import org.apache.log4j.Logger; -import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.LazyInitializer; -import org.springframework.util.ReflectionUtils; - -import eu.etaxonomy.cdm.api.cache.CdmCacher; -import eu.etaxonomy.cdm.model.common.CdmBase; - -/** - * @author cmathew - * @date 9 Feb 2015 - * - */ -public class EntityCacherDebugResult { - - private static final Logger logger = Logger.getLogger(EntityCacherDebugResult.class); - - private Map duplicateCdmEntityMap; - - private List notInCacheList; - - private CdmTransientEntityCacher cacher; - - private List rootElements; - - StringBuilder debugOutput = new StringBuilder(); - - public EntityCacherDebugResult() { - } - - - public EntityCacherDebugResult(CdmTransientEntityCacher cacher, Collection rootEntities) { - this.cacher = cacher; - init(); - - if(rootEntities != null && !rootEntities.isEmpty()) { - for(CdmBase rootEntity : rootEntities) { - debug(rootEntity, true); - String out = toString(duplicateCdmEntityMap, notInCacheList, rootEntity); - System.out.println(out); - debugOutput.append(out); - clear(); - } - - } - } - - private void init() { - duplicateCdmEntityMap = new HashMap(); - notInCacheList = new ArrayList(); - rootElements = new ArrayList(); - } - - private void clear() { - duplicateCdmEntityMap.clear(); - notInCacheList.clear(); - } - - public void addDuplicateEntity(CdmEntityInfo cei, CdmEntityInfo cachedCei) { - duplicateCdmEntityMap.put(cei, cachedCei); - } - - public void addEntityNotInCache(CdmEntityInfo cei) { - notInCacheList.add(cei); - } - - public List getRootElements() { - return rootElements; - } - - private void print(Map duplicateCdmEntityMap, - List notInCacheList, - CdmBase rootEntity) { - System.out.println(toString(duplicateCdmEntityMap, notInCacheList, rootEntity)); - } - - - @Override - public String toString() { - return debugOutput.toString(); - } - - private String toString(Map duplicateCdmEntityMap, - List notInCacheList, - CdmBase rootEntity) { - - - StringBuilder sb = new StringBuilder(); - sb.append(System.getProperty("line.separator")); - sb.append("<<< Root Entity " + rootEntity.getUserFriendlyTypeName() + " with id " + rootEntity.getId() + " >>>"); - sb.append(System.getProperty("line.separator")); - if(duplicateCdmEntityMap.isEmpty()) { - sb.append("No Duplicate CDM Entities."); - } else { - sb.append("Duplicate CDM Entities,"); - - for (Map.Entry entry : duplicateCdmEntityMap.entrySet()) - { - sb.append(System.getProperty("line.separator")); - CdmEntityInfo cei = entry.getKey(); - CdmBase cb = (CdmBase) cei.getObject(); - - sb.append(" - " + cei.getField().getName() + ":" + cb.getUserFriendlyTypeName() + "/" + cb.getId()); - if(cei.getParent() != null) { - Object cbParent = cei.getParent().getObject(); - sb.append(" in entity " + cbParent.getClass().getCanonicalName()); - if(cbParent instanceof CdmBase) { - - sb.append(" with id : " + ((CdmBase)cbParent).getId()); - } - } - sb.append(System.getProperty("line.separator")); - sb.append(" -- entity belongs to cache(s) : " + getCachesContainingEntity(cb)); - sb.append(System.getProperty("line.separator")); - - - CdmEntityInfo dupCei = entry.getValue(); - CdmBase dupCb = (CdmBase) dupCei.getObject(); - - String dupCeiFieldName = ""; - if(dupCei.getField() != null) { - dupCeiFieldName = dupCei.getField().getName(); - } - sb.append(" - " + dupCeiFieldName + ":" + dupCb.getUserFriendlyTypeName() + "/" + dupCb.getId()); - if(dupCei.getParent() != null) { - Object dupCbParent = dupCei.getParent().getObject(); - sb.append(" in entity " + dupCbParent.getClass().getCanonicalName()); - if(dupCbParent instanceof CdmBase) { - sb.append(" with id : " + ((CdmBase)dupCbParent).getId()); - } - } - sb.append(System.getProperty("line.separator")); - sb.append(" -- entity belongs to cache(s) : " + getCachesContainingEntity(dupCb)); - sb.append(System.getProperty("line.separator")); - sb.append("-----------"); - } - } - - sb.append(System.getProperty("line.separator")); - sb.append(System.getProperty("line.separator")); - - if(notInCacheList.isEmpty()) { - sb.append("No Entities found which are not in Cache."); - } else { - sb.append("Not In Cache Entities,"); - - for(CdmEntityInfo cei : notInCacheList) { - CdmBase cb = (CdmBase) cei.getObject(); - Object cbParent = cei.getParent().getObject(); - - sb.append(System.getProperty("line.separator")); - - String fieldName = ""; - if(cei.getField() != null) { - fieldName = cei.getField().getName(); - } - sb.append(" - " + fieldName + ":" + cb.getUserFriendlyTypeName() + "/" + cb.getId()); - - if(cbParent instanceof CdmBase) { - sb.append(" of entity " + ((CdmBase)cbParent).getUserFriendlyTypeName()); - } else { - sb.append(" of entity " + cbParent.getClass().getName()); - } - } - } - sb.append(System.getProperty("line.separator")); - return sb.toString(); - } - - private String getCachesContainingEntity(CdmBase cdmEntity) { - Cache defaultCache = CacheManager.create().getCache(CdmCacher.DEFAULT_CACHE_NAME); - String caches = ""; - Element dce = defaultCache.get(cdmEntity.getUuid()); - if(dce != null && dce.getObjectValue() == cdmEntity) { - caches = "{DC}"; - } - - Object cte = cacher.getFromCache(CdmTransientEntityCacher.generateKey(cdmEntity)); - if(cte != null && cte == cdmEntity) { - caches += "{TC}"; - } - return caches; - } - - - private void debug(CdmBase cdmEntity, boolean recursive) { - if(cdmEntity == null) { - return; - } - logger.info("---- starting recursive debug for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId()); - List alreadyVisitedEntities = new ArrayList(); - CdmEntityInfo cei = new CdmEntityInfo(ProxyUtils.deproxy(cdmEntity)); - debugRecursive(cdmEntity, alreadyVisitedEntities, cei); - rootElements.add(cei); - alreadyVisitedEntities.clear(); - logger.info("---- ending recursive debug for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + "\n"); - } - - private void debugRecursive(T obj, - List alreadyVisitedEntities, - CdmEntityInfo cei) { - if(obj == null) { - return; - } - if(obj instanceof CdmBase) { - debugRecursive((CdmBase)obj, alreadyVisitedEntities, cei); - } else if (obj instanceof Map) { - debug((Map)obj, alreadyVisitedEntities, cei); - } else if (obj instanceof Collection) { - debug((Collection)obj, alreadyVisitedEntities, cei); - } - - logger.info("No caching yet for type " + obj.getClass().getName()); - - - } - - private void debug(Map map, - List alreadyVisitedEntities, - CdmEntityInfo cei) { - if(map == null || map.isEmpty()) { - return; - } - - Iterator> iter = map.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry e = iter.next(); - CdmEntityInfo childCei = new CdmEntityInfo(e); - cei.addChild(childCei); - - CdmEntityInfo keyCei = new CdmEntityInfo(ProxyUtils.deproxy(e.getKey())); - childCei.addChild(keyCei); - CdmEntityInfo valueCei = new CdmEntityInfo(ProxyUtils.deproxy(e.getValue())); - childCei.addChild(valueCei); - - debugRecursive(e.getKey(), alreadyVisitedEntities, keyCei); - debugRecursive(e.getValue(), alreadyVisitedEntities, valueCei); - } - } - - private void debug(Collection collection, - List alreadyVisitedEntities, - CdmEntityInfo cei) { - Iterator collectionItr = collection.iterator(); - - while(collectionItr.hasNext()) { - Object obj = collectionItr.next(); - boolean alreadyVisited = false; - for (CdmEntityInfo entityInfo: alreadyVisitedEntities) { - if(obj.equals(entityInfo.getObject())){ - alreadyVisited = true; - break; - } - } - if(!alreadyVisited){ - CdmEntityInfo childCei = new CdmEntityInfo(ProxyUtils.deproxy(obj)); - cei.addChild(childCei); - debugRecursive(obj, alreadyVisitedEntities, childCei); - } - - } - - } - - private void debugRecursive(CdmBase cdmEntity, - List alreadyVisitedEntities, - CdmEntityInfo cei) { - - CdmBase cachedCdmEntityInSubGraph = null; - - if(cei.getObject() instanceof CdmBase) { - CdmBase cb = (CdmBase)cei.getObject(); - cachedCdmEntityInSubGraph = cacher.getFromCache(cb); - if(cachedCdmEntityInSubGraph != cb) { - // found a cdm entity which is not in cache - need to record this - //logger.info(" - found entity not in cache " + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId()); - addEntityNotInCache(cei); - } - } - - - // we want to recursive through the cdmEntity (and not the cachedCdmEntity) - // since there could be new or deleted objects in the cdmEntity sub-graph - - // start by getting the fields from the cdm entity - String className = cdmEntity.getClass().getName(); - CdmModelFieldPropertyFromClass cmgmfc = cacher.getFromCdmlibModelCache(className); - if(cmgmfc != null) { - alreadyVisitedEntities.add(cei); - List fields = cmgmfc.getFields(); - for(String field : fields) { - // retrieve the actual object corresponding to the field. - // this object will be either a CdmBase or a Collection / Map - // with CdmBase as the generic type - CdmEntityInfo childCei = getDebugCdmBaseTypeFieldValue(cdmEntity, field, alreadyVisitedEntities, cei); - if(!childCei.isProxy()) { - Object object = childCei.getObject(); - if(object != null && object instanceof CdmBase) { - CdmBase cdmEntityInSubGraph = (CdmBase)object; - if(!containsIdenticalCdmEntity(alreadyVisitedEntities, cdmEntityInSubGraph)) { - logger.info("recursive debugging object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId()); - debugRecursive(cdmEntityInSubGraph, alreadyVisitedEntities, childCei); - } else { - logger.info("object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId() + " already visited"); - } - } - } - } - } else { - throw new CdmClientCacheException("CdmEntity with class " + cdmEntity.getClass().getName() + " is not found in the cdmlib model cache. " + - "The cache may be corrupted or not in sync with the latest model version" ); - } - - } - - - private CdmEntityInfo getDebugCdmBaseTypeFieldValue(CdmBase cdmEntity, - String fieldName, - List alreadyVisitedEntities, - CdmEntityInfo cei) { - - CdmEntityInfo childCei = null; - Class clazz = cdmEntity.getClass(); - try { - // this call will search in the provided class as well as - // the super classes until it finds the field - Field field = ReflectionUtils.findField(clazz, fieldName); - - if(field == null) { - throw new CdmClientCacheException("Field '" + fieldName - + "' not found when searching in class '" + clazz.getName() + "' and its supercalsses"); - } - field.setAccessible(true); - Object o = field.get(cdmEntity); - o = ProxyUtils.deproxy(o); - CdmBase cdmEntityInSubGraph = null; - - childCei = new CdmEntityInfo(o); - cei.addChild(childCei); - childCei.setField(field); - - if(o != null) { - boolean isProxy = ProxyUtils.isProxy(o); - - childCei.setProxy(isProxy); - if(!isProxy) { - childCei.setObject(o); - if(CdmBase.class.isAssignableFrom(o.getClass())) { - logger.info("found initialised cdm entity '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId()); - cdmEntityInSubGraph = (CdmBase)o; - - //logger.info(" - found duplicate entity at " + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId()); - CdmEntityInfo dupCei = getDuplicate(alreadyVisitedEntities, cdmEntityInSubGraph); - if(dupCei != null) { - addDuplicateEntity(childCei, dupCei); - } - - } else if(o instanceof Map) { - debugRecursive((Map)o, alreadyVisitedEntities, childCei); - } else if(o instanceof Collection) { - debugRecursive((Collection)o, alreadyVisitedEntities, childCei); - } - - } - } - // we return the original cdm entity in the sub graph because we - // want to continue to recurse on the input cdm entity graph - // and not the one in the cache - - return childCei; - } catch (SecurityException e) { - throw new CdmClientCacheException(e); - } catch (IllegalArgumentException e) { - throw new CdmClientCacheException(e); - } catch (IllegalAccessException e) { - throw new CdmClientCacheException(e); - } - } - - - private CdmEntityInfo getDuplicate(List alreadyVisitedEntities, Object objectToCompare) { - if(objectToCompare != null ) { - for(CdmEntityInfo cei: alreadyVisitedEntities) { - if(objectToCompare.equals(cei.getObject()) && objectToCompare != cei.getObject()) { - return cei; - } - } - } - return null; - } - - private boolean containsIdenticalCdmEntity(List ceiSet, Object objectToCompare) { - boolean foundIdentical = false; - if(objectToCompare != null) { - for(CdmEntityInfo cei : ceiSet) { - if(cei.getObject() == objectToCompare) { - foundIdentical = true; - } -// } else if(objectToCompare.equals(cei.getObject())) { -// return false; -// } - } - } - return foundIdentical; - } - - public class CdmEntityInfo { - - private Object object; - private CdmEntityInfo parent; - private List children; - private Field field; - private String label; - private boolean isProxy; - - public CdmEntityInfo(Object object) { - this.object = object; - isProxy = false; - children = new ArrayList(); - } - - public CdmEntityInfo getParent() { - return parent; - } - - public void setParent(CdmEntityInfo parent) { - this.parent = parent; - } - - public List getChildren() { - return children; - } - - public void setChildren(List children) { - this.children = children; - } - - public void addChild(CdmEntityInfo cei) { - this.children.add(cei); - cei.setParent(this); - } - - public Field getField() { - return field; - } - - public void setField(Field field) { - this.field = field; - } - - - public String getLabel() { - String label; - String fieldName = ""; - if(field != null) { - fieldName = field.getName(); - } - - if(object != null) { - String className = object.getClass().getName(); - if(object instanceof HibernateProxy) { - LazyInitializer hli = ((HibernateProxy)object).getHibernateLazyInitializer(); - if(hli.isUninitialized()) { - className = "HibernateProxy"; - } else { - className = "InitialisedHibernateProxy"; - } - label = "[" + className + "] " + fieldName; - } else if(object instanceof PersistentCollection) { - PersistentCollection pc = ((PersistentCollection)object); - if(!pc.wasInitialized()) { - className = "PersistentCollection"; - } else { - className = "InitialisedPersistentCollection"; - } - label = "[" + className + "] " + fieldName; - } else if(object instanceof Collection) { - label = "[" + className + "] " + fieldName + " : " + String.valueOf(((Collection)object).size()); - } else if(object instanceof Map) { - label = "[" + className + "] " + fieldName + " : " + String.valueOf(((Map)object).size()); - } else if(object instanceof CdmBase) { - label = getCachesContainingEntity((CdmBase)object) + "[" + className + ",id" + ((CdmBase)object).getId() + "] " + fieldName + " : " + object.toString(); - } else { - label = "[" + className + "] " + fieldName + " : " + object.toString(); - } - } else { - label = "[NULL] " + fieldName; - } - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public Object getObject() { - return object; - } - - public void setObject(Object object) { - this.object = object; - } - - public boolean isProxy() { - return isProxy; - } - - public void setProxy(boolean isProxy) { - this.isProxy = isProxy; - } - - - - } - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/ProxyUtils.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/ProxyUtils.java deleted file mode 100644 index 7b6a5c7a3..000000000 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/ProxyUtils.java +++ /dev/null @@ -1,226 +0,0 @@ -/** -* Copyright (C) 2015 EDIT -* European Distributed Institute of Taxonomy -* http://www.e-taxonomy.eu -* -* The contents of this file are subject to the Mozilla Public License Version 1.1 -* See LICENSE.TXT at the top of this package for the full license terms. -*/ -package eu.etaxonomy.taxeditor.remoting.cache; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.UUID; - -import org.hibernate.collection.internal.PersistentBag; -import org.hibernate.collection.internal.PersistentList; -import org.hibernate.collection.internal.PersistentMap; -import org.hibernate.collection.internal.PersistentSet; -import org.hibernate.collection.internal.PersistentSortedMap; -import org.hibernate.collection.internal.PersistentSortedSet; -import org.hibernate.collection.spi.PersistentCollection; -import org.hibernate.proxy.HibernateProxy; -import org.hibernate.proxy.LazyInitializer; -import org.springframework.util.ReflectionUtils; - -import eu.etaxonomy.cdm.api.application.CdmApplicationState; -import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.cdm.model.common.PersistentMultiLanguageText; -import eu.etaxonomy.taxeditor.remoting.CdmRemotingException; - -/** - * @author cmathew - * @date 17 Feb 2015 - * - */ -public class ProxyUtils { - - - - public static enum CollectionType { - SET, - LIST, - MAP, - BAG; - - @Override - public String toString() { - return this.name().toLowerCase(); - } - } - - public static Object getCollectionType(Object obj, Class clazz) { - if(obj != null) { - if(obj instanceof List) { - //the field in PersistentBag is called "bag" although it is an ArrayList -> # - if(clazz.equals(PersistentBag.class)){ - return CollectionType.BAG; - } - return CollectionType.LIST; - } - if(obj instanceof Set) { - return CollectionType.SET; - } - if(obj instanceof Map) { - return CollectionType.MAP; - } - throw new CdmRemotingException("Cannot get Collection Type for " + obj.getClass().getName()); - } - return null; - } - - public static Object getObject(PersistentCollection pc) { - if(pc != null) { - if(pc instanceof PersistentSet) { - return new HashSet<>((Set)pc); - } - if(pc instanceof PersistentSortedSet) { - return new TreeSet<>((Set)pc); - } - if(pc instanceof PersistentList || pc instanceof PersistentBag) { - return new ArrayList<>((List)pc); - } - if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) { - return new HashMap<>((Map)pc); - } - if(pc instanceof PersistentSortedMap) { - return new TreeMap<>((Map)pc); - } - throw new CdmRemotingException("Cannot get Collection field for type " + pc.getClass().getName()); - } - return null; - } - - public static CollectionField getCollectionField(PersistentCollection pc) { - if(pc != null) { - if(pc instanceof PersistentSet) { - return new CollectionField(new HashSet<>((Set)pc), CollectionType.SET); - } - if(pc instanceof PersistentSortedSet) { - return new CollectionField(new TreeSet<>((Set)pc), CollectionType.SET); - } - if(pc instanceof PersistentList) { - return new CollectionField(new ArrayList<>((List)pc), CollectionType.LIST); - } - if(pc instanceof PersistentMap || pc instanceof PersistentMultiLanguageText) { - return new CollectionField(new HashMap<>((Map)pc), CollectionType.MAP); - } - if(pc instanceof PersistentSortedMap) { - return new CollectionField(new TreeMap<>((Map)pc), CollectionType.MAP); - } - throw new CdmRemotingException("Cannot get Collection field for type " + pc.getClass().getName()); - } - return null; - } - - public static class CollectionField { - private final Object col; - private final CollectionType type; - public CollectionField(Object col, CollectionType type) { - this.col = col; - this.type = type; - } - - public Object getCollection() { - return this.col; - } - - public CollectionType getType() { - return this.type; - } - } - - - public static Object deproxy(Object o) { - if(o != null && o instanceof HibernateProxy) { - LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer(); - if(!hli.isUninitialized()) { - return hli.getImplementation(); - - } - } - - if(o != null && o instanceof PersistentCollection) { - PersistentCollection pc = ((PersistentCollection)o); - if(pc.wasInitialized()) { - return ProxyUtils.getObject(pc); - - } - } - return o; - } - - public static boolean isProxy(Object o) { - if(o != null && o instanceof HibernateProxy) { - LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer(); - if(hli.isUninitialized()) { - return true; - } - } - - if(o != null && o instanceof PersistentCollection) { - PersistentCollection pc = ((PersistentCollection)o); - if(!pc.wasInitialized()) { - return true; - } - } - - return false; - } - - @SuppressWarnings("unchecked") - public static Object remoteLoadPersistentCollectionIfProxy(Object o, UUID ownerUuid, String fieldName) throws ClassNotFoundException { - if(o != null && o instanceof HibernateProxy) { - LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer(); - if(hli.isUninitialized()) { - return CdmApplicationState.getCachedCommonService().find((Class)Class.forName(hli.getEntityName()), - ((Integer)hli.getIdentifier()).intValue()); - } - } - - if(o != null && o instanceof PersistentCollection) { - PersistentCollection pc = ((PersistentCollection)o); - if(!pc.wasInitialized()) { - return CdmApplicationState.getCachedCommonService().initializeCollection(ownerUuid, fieldName); - } - } - - return o; - } - - - - - public static void setRoleValueInOwner(Object owner, String role, Object value) { - if(role == null || role.isEmpty()) { - throw new CdmRemotingException("Role cannot be null or an empty string"); - } - - String fieldName = role.substring(role.lastIndexOf(".") + 1); - - Field field = ReflectionUtils.findField(owner.getClass(), fieldName); - - if(field == null) { - throw new CdmRemotingException("Field '" + fieldName - + "' not found when searching in class '" + owner.getClass() + "' and its supercalsses"); - } - - field.setAccessible(true); - - try { - field.set(owner, value); - } catch (IllegalArgumentException e) { - throw new CdmRemotingException(e); - } catch (IllegalAccessException e) { - throw new CdmRemotingException(e); - } - } - -} diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/CdmEntitySession.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/CdmEntitySession.java index f4cee67e9..cb3effd76 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/CdmEntitySession.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/CdmEntitySession.java @@ -15,16 +15,17 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import net.sf.ehcache.statistics.LiveCacheStatistics; - import org.apache.log4j.Logger; import eu.etaxonomy.cdm.api.service.IService; import eu.etaxonomy.cdm.api.service.UpdateResult; +import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher; +//import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher; +import eu.etaxonomy.cdm.cache.EntityCacherDebugResult; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.persistence.dto.MergeResult; -import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher; -import eu.etaxonomy.taxeditor.remoting.cache.EntityCacherDebugResult; +import eu.etaxonomy.taxeditor.remoting.cache.ConversationalTransientEntityCacher; +import net.sf.ehcache.statistics.LiveCacheStatistics; /** @@ -57,7 +58,9 @@ public class CdmEntitySession implements ICdmEntitySession { } private void init(ICdmEntitySessionEnabled sessionOwner, CdmEntitySessionManager cdmEntitySessionManager) { - this.cdmTransientEntityCacher = new CdmTransientEntityCacher(sessionOwner, cdmEntitySessionManager); + this.cdmTransientEntityCacher = new ConversationalTransientEntityCacher(sessionOwner); + + this.changeObservers = new ArrayList(); cdmEntitySessionManager.addToOwnerSessionMap(sessionOwner, this); } @@ -79,7 +82,7 @@ public class CdmEntitySession implements ICdmEntitySession { */ @Override public T load(T cdmBase, boolean update) { - return (T)cdmTransientEntityCacher.load(cdmBase, update); + return cdmTransientEntityCacher.load(cdmBase, update); } @@ -149,7 +152,7 @@ public class CdmEntitySession implements ICdmEntitySession { * @see eu.etaxonomy.taxeditor.session.ICdmEntitySession#debug(java.util.List) */ @Override - public EntityCacherDebugResult debug(Collection cdmBases) { + public eu.etaxonomy.cdm.cache.EntityCacherDebugResult debug(Collection cdmBases) { EntityCacherDebugResult entityCacherDebugResult = new EntityCacherDebugResult(cdmTransientEntityCacher, cdmBases); return entityCacherDebugResult; diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/ICdmEntitySession.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/ICdmEntitySession.java index dbb1a62fb..92d4d5cd0 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/ICdmEntitySession.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/ICdmEntitySession.java @@ -4,12 +4,12 @@ import java.util.Collection; import java.util.List; import java.util.UUID; -import net.sf.ehcache.statistics.LiveCacheStatistics; import eu.etaxonomy.cdm.api.service.IService; import eu.etaxonomy.cdm.api.service.UpdateResult; +import eu.etaxonomy.cdm.cache.EntityCacherDebugResult; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.persistence.dto.MergeResult; -import eu.etaxonomy.taxeditor.remoting.cache.EntityCacherDebugResult; +import net.sf.ehcache.statistics.LiveCacheStatistics; public interface ICdmEntitySession { diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/NullSession.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/NullSession.java index 76ac45f29..4b12f0c8d 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/NullSession.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/NullSession.java @@ -13,12 +13,12 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import net.sf.ehcache.statistics.LiveCacheStatistics; import eu.etaxonomy.cdm.api.service.IService; import eu.etaxonomy.cdm.api.service.UpdateResult; +import eu.etaxonomy.cdm.cache.EntityCacherDebugResult; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.persistence.dto.MergeResult; -import eu.etaxonomy.taxeditor.remoting.cache.EntityCacherDebugResult; +import net.sf.ehcache.statistics.LiveCacheStatistics; /** * @author cmathew diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/mock/MockCdmEntitySession.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/mock/MockCdmEntitySession.java index 9deb9cc99..49f453bdc 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/mock/MockCdmEntitySession.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/session/mock/MockCdmEntitySession.java @@ -12,14 +12,14 @@ import java.util.Collection; import java.util.List; import java.util.UUID; -import net.sf.ehcache.statistics.LiveCacheStatistics; import eu.etaxonomy.cdm.api.service.IService; import eu.etaxonomy.cdm.api.service.UpdateResult; +import eu.etaxonomy.cdm.cache.EntityCacherDebugResult; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.cdm.persistence.dto.MergeResult; -import eu.etaxonomy.taxeditor.remoting.cache.EntityCacherDebugResult; import eu.etaxonomy.taxeditor.session.ICdmEntitySession; import eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled; +import net.sf.ehcache.statistics.LiveCacheStatistics; /** * @author cmathew diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java index 1b2fc8abc..e9c3f4c57 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java @@ -60,9 +60,9 @@ import org.hibernate.type.Type; import org.jboss.logging.Logger; import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration; +import eu.etaxonomy.cdm.cache.ProxyUtils; import eu.etaxonomy.cdm.model.common.CdmBase; import eu.etaxonomy.taxeditor.remoting.CdmEagerLoadingException; -import eu.etaxonomy.taxeditor.remoting.cache.ProxyUtils; import eu.etaxonomy.taxeditor.service.ICachedCommonService; /** @@ -1338,7 +1338,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers //Object obj = ProxyUtils.deproxy(cachedCommonService.initializeCollection(this)); Object obj = ProxyUtils.deproxy(cachedCommonService.initializeCollection(cdmBase.getUuid(), fieldName)); - if(ProxyUtils.isProxy(obj)) { + if(ProxyUtils.isUninitializedProxy(obj)) { throw new HibernateException("Persistent Collection initialized but is still a proxy"); } afterInitialize(); diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java index f9920b678..de085411f 100644 --- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java +++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java @@ -40,8 +40,8 @@ import org.hibernate.persister.entity.EntityPersister; import org.jboss.logging.Logger; import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration; +import eu.etaxonomy.cdm.cache.ProxyUtils; import eu.etaxonomy.cdm.model.common.CdmBase; -import eu.etaxonomy.taxeditor.remoting.cache.ProxyUtils; import eu.etaxonomy.taxeditor.service.ICachedCommonService; /** @@ -449,7 +449,7 @@ public abstract class AbstractLazyInitializer implements LazyInitializer { } CdmBase cdmBase = cachedCommonService.find(clazz,classid); - if(ProxyUtils.isProxy(cdmBase)) { + if(ProxyUtils.isUninitializedProxy(cdmBase)) { throw new HibernateException("CdmBase Object initialized but is still a proxy"); } setImplementation(cdmBase); diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/InspectSessionsDialog.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/InspectSessionsDialog.java index 5b79066f2..86dc20682 100644 --- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/InspectSessionsDialog.java +++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/InspectSessionsDialog.java @@ -10,9 +10,6 @@ package eu.etaxonomy.taxeditor.view.sessions; import java.util.List; -import net.sf.ehcache.Cache; -import net.sf.ehcache.Element; - import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.StyledCellLabelProvider; @@ -38,12 +35,14 @@ import org.eclipse.ui.dialogs.FilteredTree; import org.eclipse.ui.dialogs.PatternFilter; import org.eclipse.wb.swt.SWTResourceManager; -import eu.etaxonomy.taxeditor.remoting.cache.CdmModelFieldPropertyFromClass; -import eu.etaxonomy.taxeditor.remoting.cache.CdmRemoteCacheManager; -import eu.etaxonomy.taxeditor.remoting.cache.EntityCacherDebugResult; -import eu.etaxonomy.taxeditor.remoting.cache.EntityCacherDebugResult.CdmEntityInfo; +import eu.etaxonomy.cdm.cache.CdmModelFieldPropertyFromClass; +import eu.etaxonomy.cdm.cache.CdmRemoteCacheManager; +import eu.etaxonomy.cdm.cache.EntityCacherDebugResult; +import eu.etaxonomy.cdm.cache.EntityCacherDebugResult.CdmEntityInfo; import eu.etaxonomy.taxeditor.session.ICdmEntitySession; import eu.etaxonomy.taxeditor.store.CdmStore; +import net.sf.ehcache.Cache; +import net.sf.ehcache.Element; /** * @author cmathew diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/SessionsViewPart.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/SessionsViewPart.java index d696de710..0f0006ab6 100644 --- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/SessionsViewPart.java +++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/view/sessions/SessionsViewPart.java @@ -33,7 +33,7 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.wb.swt.SWTResourceManager; import eu.etaxonomy.cdm.api.cache.CdmCacher; -import eu.etaxonomy.taxeditor.remoting.cache.CdmRemoteCacheManager; +import eu.etaxonomy.cdm.cache.CdmRemoteCacheManager; import eu.etaxonomy.taxeditor.session.ICdmEntitySession; import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager; import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManagerObserver;