eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/cdm/api/cache/CdmServiceCacher.java -text
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/CdmEagerLoadingException.java -text
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/CdmRemotingException.java -text
+eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CacheLoader.java -text
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CachedCommonServiceImpl.java -text
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmClientCacheException.java -text
eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CdmEntityCacheKey.java -text
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/SelectFeatureTreeWizard.java -text
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/featuretree/SelectFeatureTreeWizardPage.java -text
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/OpenDistributionEditorWizardHandler.java -text
+eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/OpenInspectSessionsHandler.java -text
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/OpenPasswordWizzardHandler.java -text
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/ShowLoginWindowHandler.java -text
eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/handler/ShowRemotingLoginWindowHandler.java -text
import eu.etaxonomy.cdm.api.service.ITermService;
import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.DefinedTermBase;
+import eu.etaxonomy.taxeditor.remoting.cache.CacheLoader;
import eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher;
/**
* @param <T>
*/
@Component
-public class CdmServiceCacher extends CdmCacher {
+public class CdmServiceCacher extends CdmCacher{
@Autowired
ITermService termService;
+ private CacheLoader cacheLoader;
+
@Override
protected void setup() {
+ DefinedTermBase.setCacher(this);
CdmTransientEntityCacher.setDefaultCacher(this);
+ cacheLoader = new CacheLoader(this);
}
@Override
protected CdmBase findByUuid(UUID uuid) {
CdmBase term = termService.findWithoutFlush(uuid);
- return term;
+ return cacheLoader.load(term, true);
+
}
+
}
--- /dev/null
+// $Id$
+/**
+ * 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.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javassist.util.proxy.ProxyFactory;
+import net.sf.ehcache.Cache;
+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.model.ICdmCacher;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+
+/**
+ * @author cmathew
+ * @date 19 Feb 2015
+ *
+ */
+public class CacheLoader {
+ private static final Logger logger = Logger.getLogger(CacheLoader.class);
+
+ private static boolean isRecursiveEnabled = true;
+
+ private 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 extends Object> T load(T obj, boolean recursive) {
+ if(obj == null) {
+ return null;
+ }
+ if(obj instanceof CdmBase) {
+ return (T) load((CdmBase)obj, recursive);
+ } else if (obj instanceof Map) {
+ return (T) load((Map<T,T>)obj, recursive);
+ } else if (obj instanceof Collection) {
+ return (T) load((Collection<T>)obj, recursive);
+ }
+
+ return obj;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Object> T loadRecursive(T obj, Set<CdmBase> alreadyVisitedEntities) {
+ if(obj == null) {
+ return null;
+ }
+ if(obj instanceof CdmBase) {
+ return (T) loadRecursive((CdmBase)obj, alreadyVisitedEntities);
+ } else if (obj instanceof Map) {
+ return (T) load((Map<T,T>)obj, alreadyVisitedEntities);
+ } else if (obj instanceof Collection) {
+ return (T) load((Collection<T>)obj, alreadyVisitedEntities);
+ }
+
+
+ logger.info("No caching yet for type " + obj.getClass().getName());
+
+ return obj;
+ }
+
+ public <T extends Object> Map<T,T> load(Map<T,T> map, boolean recursive){
+ if(map == null) {
+ return null;
+ }
+
+ if(isRecursiveEnabled && recursive) {
+ logger.info("---- starting recursive load for cdm entity map");
+ Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
+ Map<T,T> cachedMap = load(map, alreadyVisitedEntities);
+ alreadyVisitedEntities.clear();
+ logger.info("---- ending recursive load for cdm entity map \n");
+ return cachedMap;
+ } else {
+ return load(map, null);
+ }
+ }
+
+
+ private <T extends Object> Map<T,T> load(Map<T,T> map, Set<CdmBase> alreadyVisitedEntities){
+ if(map == null || map.isEmpty()) {
+ return map;
+ }
+
+ int originalMapSize = map.size();
+ Object[] result = new Object[ map.size() * 2 ];
+ Iterator<Map.Entry<T,T>> iter = map.entrySet().iterator();
+ int i=0;
+ while ( iter.hasNext() ) {
+ Map.Entry<T,T> e = iter.next();
+ result[i++] = e.getKey();
+ result[i++] = e.getValue();
+ }
+
+ for(i=0; i<result.length;i++) {
+ if(alreadyVisitedEntities == null) {
+ result[i] = load(result[i], false);
+ } else {
+ result[i] = loadRecursive(result[i], alreadyVisitedEntities);
+ }
+ }
+ map.clear();
+ for(i = 0; i < originalMapSize; i+=2 ) {
+ map.put(
+ (T)result[i],
+ (T)result[i+1]
+ );
+ }
+ return map;
+ }
+
+ public <T extends Object> Collection<T> load(Collection<T> collection, boolean recursive){
+ if(collection == null) {
+ return null;
+ }
+
+ Collection<T> loadedCollection;
+ if(isRecursiveEnabled && recursive) {
+ logger.info("---- starting recursive load for cdm entity collection");
+ Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
+ Collection<T> cachedCollection = load(collection, alreadyVisitedEntities);
+ alreadyVisitedEntities.clear();
+ logger.info("---- ending recursive load for cdm entity collection \n");
+ loadedCollection = cachedCollection;
+ } else {
+ loadedCollection = load(collection, null);
+ }
+ return loadedCollection;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Object> Collection<T> load(Collection<T> collection, Set<CdmBase> alreadyVisitedEntities){
+ int length = collection.size();
+ Object[] result = new Object[length];
+ Iterator<T> collectionItr = collection.iterator();
+ int count = 0;
+ while(collectionItr.hasNext()) {
+ Object obj = collectionItr.next();
+ if(alreadyVisitedEntities == null) {
+ result[count] = load(obj, false);
+ } else {
+ result[count] = loadRecursive(obj, alreadyVisitedEntities);
+ }
+
+ count++;
+ }
+
+ collection.clear();
+
+ for ( int i = 0; i < length; i++ ) {
+ collection.add((T)result[i]);
+ }
+
+ return collection;
+ }
+
+
+ /**
+ * 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) {
+ 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;
+ }
+ return cachedCdmEntity;
+ }
+
+ CdmBase loadedCdmBase;
+ if(isRecursiveEnabled && recursive) {
+ logger.info("---- starting recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
+ Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
+ CdmBase cb = loadRecursive(cdmEntity, alreadyVisitedEntities);
+ 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;
+
+ }
+
+
+ private CdmBase load(CdmBase cdmEntity) {
+ logger.info("loading object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
+
+ // 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 return ...
+ logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " already exists");
+ return cachedCdmEntity;
+ } else {
+ // ... else save the entity in the cache
+ cdmCacher.put(cdmEntity);
+ logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " put in cache");
+ return cdmEntity;
+ }
+ }
+
+ private CdmBase loadRecursive(CdmBase cdmEntity, Set<CdmBase> alreadyVisitedEntities) {
+
+ 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<String> 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);
+ if(cdmEntityInSubGraph != null) {
+ //checkForIdenticalCdmEntity(alreadyVisitedEntities, cdmEntityInSubGraph);
+ if(!alreadyVisitedEntities.contains(cdmEntityInSubGraph)) {
+ logger.info("recursive loading object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId());
+ loadRecursive(cdmEntityInSubGraph, alreadyVisitedEntities);
+ } 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,
+ Set<CdmBase> alreadyVisitedEntities) {
+
+ // 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 supercalsses");
+ }
+ field.setAccessible(true);
+ Object o = field.get(cdmEntity);
+
+ if(o != null && o instanceof HibernateProxy) {
+ LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
+ if(!hli.isUninitialized()) {
+ o = ((HibernateProxy) o).getHibernateLazyInitializer().getImplementation();
+ field.set(cdmEntity, o);
+ }
+ }
+
+ if(o != null && o instanceof PersistentCollection) {
+ PersistentCollection pc = ((PersistentCollection)o);
+ if(pc.wasInitialized()) {
+ o = ProxyUtils.getObject(pc);
+ field.set(cdmEntity, o);
+ }
+ }
+
+
+ CdmBase cdmEntityInSubGraph = null;
+ if(o != null
+ && !ProxyFactory.isProxyClass(o.getClass())
+ && !(o instanceof PersistentCollection) ) {
+
+ 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);
+ // making sure that the field in cached cdm entity is always
+ // up-to-date by setting to the value of the cdm entity being loaded
+ // the only execption to this is found below
+ field.set(cachedCdmEntity, o);
+
+
+ // the only exception to updating the field to the latest value
+ // 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
+ if(cachedCdmEntityInSubGraph != null) {
+ if(cachedCdmEntityInSubGraph != cdmEntityInSubGraph) {
+ 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);
+ }
+ cdmEntityInSubGraph = null;
+ }
+
+ } else if(o instanceof Map) {
+ loadRecursive((Map)o, alreadyVisitedEntities);
+ } else if(o instanceof Collection) {
+ loadRecursive((Collection)o, alreadyVisitedEntities);
+ }
+ }
+ // 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(Set<CdmBase> cbSet, CdmBase cbToCompare) {
+ if(cbToCompare != null) {
+ for(CdmBase cb : cbSet) {
+
+ if(cb == cbToCompare) {
+ return true;
+ } else {
+ if(cb.equals(cbToCompare)) {
+ logger.info("equal but non identical object found of type " + cbToCompare.getUserFriendlyTypeName() + " with id " + cbToCompare.getId());
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean isRecursiveEnabled() {
+ return isRecursiveEnabled;
+ }
+
+ public static void setRecursiveEnabled(boolean ire) {
+ isRecursiveEnabled = ire;
+ }
+}
*/
package eu.etaxonomy.taxeditor.remoting.cache;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import javassist.util.proxy.ProxyFactory;
import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
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.CdmServiceCacher;
+import eu.etaxonomy.cdm.model.ICdmCacher;
import eu.etaxonomy.cdm.model.common.CdmBase;
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
*
*/
-public class CdmTransientEntityCacher {
+public class CdmTransientEntityCacher implements ICdmCacher {
private static final Logger logger = Logger.getLogger(CdmTransientEntityCacher.class);
- private ICdmEntitySessionManager cdmEntitySessionManager;
+ private final ICdmEntitySessionManager cdmEntitySessionManager;
private static CdmServiceCacher cdmServiceCacher;
- private String cacheId;
+ private final String cacheId;
- private Cache cache;
+ private final Cache cache;
+
+ private final CacheLoader cacheLoader;
- private Cache cdmlibModelCache;
- private static boolean isRecursiveEnabled = true;
public static enum CollectionType {
SET,
}
}
- private CdmTransientEntityCacher() {
-
- }
public CdmTransientEntityCacher(String cacheId, ICdmEntitySessionManager cdmEntitySessionManager) {
this.cacheId = cacheId;
cache = new Cache(getEntityCacheConfiguration(cacheId));
- cdmServiceCacher.getDefaultCacheManager().addCache(cache);
+ CdmRemoteCacheManager.getInstance().getDefaultCacheManager().addCache(cache);
- cdmlibModelCache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
+ cacheLoader = new CacheLoader(this);
this.cdmEntitySessionManager = cdmEntitySessionManager;
* @return
*/
private Cache getCache() {
- return cdmServiceCacher.getDefaultCacheManager().getCache(cacheId);
+ return CdmRemoteCacheManager.getInstance().getDefaultCacheManager().getCache(cacheId);
}
- @SuppressWarnings("unchecked")
public <T extends Object> T load(T obj, boolean recursive) {
- if(obj == null) {
- return null;
- }
- if(obj instanceof CdmBase) {
- return (T) load((CdmBase)obj, recursive);
- } else if (obj instanceof Map) {
- return (T) load((Map<T,T>)obj, recursive);
- } else if (obj instanceof Collection) {
- return (T) load((Collection<T>)obj, recursive);
- }
-
- return obj;
- }
-
- @SuppressWarnings("unchecked")
- private <T extends Object> T loadRecursive(T obj, Set<CdmBase> alreadyVisitedEntities) {
- if(obj == null) {
- return null;
- }
- if(obj instanceof CdmBase) {
- return (T) loadRecursive((CdmBase)obj, alreadyVisitedEntities);
- } else if (obj instanceof Map) {
- return (T) load((Map<T,T>)obj, alreadyVisitedEntities);
- } else if (obj instanceof Collection) {
- return (T) load((Collection<T>)obj, alreadyVisitedEntities);
- }
-
-
- logger.info("No caching yet for type " + obj.getClass().getName());
-
- return obj;
+ return cacheLoader.load(obj, recursive);
}
public <T extends Object> Map<T,T> load(Map<T,T> map, boolean recursive){
- if(map == null) {
- return null;
- }
-
- if(isRecursiveEnabled && recursive) {
- logger.info("---- starting recursive load for cdm entity map");
- Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
- Map<T,T> cachedMap = load(map, alreadyVisitedEntities);
- alreadyVisitedEntities.clear();
- logger.info("---- ending recursive load for cdm entity map \n");
- return cachedMap;
- } else {
- return load(map, null);
- }
- }
-
-
- private <T extends Object> Map<T,T> load(Map<T,T> map, Set<CdmBase> alreadyVisitedEntities){
- if(map == null || map.isEmpty()) {
- return map;
- }
-
- int originalMapSize = map.size();
- Object[] result = new Object[ map.size() * 2 ];
- Iterator<Map.Entry<T,T>> iter = map.entrySet().iterator();
- int i=0;
- while ( iter.hasNext() ) {
- Map.Entry<T,T> e = iter.next();
- result[i++] = e.getKey();
- result[i++] = e.getValue();
- }
-
- for(i=0; i<result.length;i++) {
- if(alreadyVisitedEntities == null) {
- result[i] = load(result[i], false);
- } else {
- result[i] = loadRecursive(result[i], alreadyVisitedEntities);
- }
- }
- map.clear();
- for(i = 0; i < originalMapSize; i+=2 ) {
- map.put(
- (T)result[i],
- (T)result[i+1]
- );
- }
- return map;
+ return cacheLoader.load(map, recursive);
}
public <T extends Object> Collection<T> load(Collection<T> collection, boolean recursive){
- if(collection == null) {
- return null;
- }
-
- Collection<T> loadedCollection;
- if(isRecursiveEnabled && recursive) {
- logger.info("---- starting recursive load for cdm entity collection");
- Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
- Collection<T> cachedCollection = load(collection, alreadyVisitedEntities);
- alreadyVisitedEntities.clear();
- logger.info("---- ending recursive load for cdm entity collection \n");
- loadedCollection = cachedCollection;
- } else {
- loadedCollection = load(collection, null);
- }
- return loadedCollection;
- }
-
- @SuppressWarnings("unchecked")
- private <T extends Object> Collection<T> load(Collection<T> collection, Set<CdmBase> alreadyVisitedEntities){
- int length = collection.size();
- Object[] result = new Object[length];
- Iterator<T> collectionItr = collection.iterator();
- int count = 0;
- while(collectionItr.hasNext()) {
- Object obj = collectionItr.next();
- if(alreadyVisitedEntities == null) {
- result[count] = load(obj, false);
- } else {
- result[count] = loadRecursive(obj, alreadyVisitedEntities);
- }
-
- count++;
- }
-
- collection.clear();
-
- for ( int i = 0; i < length; i++ ) {
- collection.add((T)result[i]);
- }
-
- return collection;
+ return cacheLoader.load(collection, recursive);
}
-
- /**
- * 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) {
- if(cdmEntity == null) {
- return null;
- }
-
-
- // start by looking up the cdm entity in the cache
- CdmBase cachedCdmEntity = 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());
- Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
- CdmBase cb = loadRecursive(cdmEntity, alreadyVisitedEntities);
- 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;
-
- }
-
-
- private CdmBase load(CdmBase cdmEntity) {
- logger.info("loading object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
-
- // start by looking up the cdm entity in the cache
- CdmBase cachedCdmEntity = getFromCache(cdmEntity);
-
- if(cachedCdmEntity != null) {
- // if cdm entity was found in cache then return ...
- logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " already exists");
- return cachedCdmEntity;
- } else {
- // ... else save the entity in the cache
- getCache().put(new Element(generateKey(cdmEntity), cdmEntity));
- logger.info(" - object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + " put in cache");
- return cdmEntity;
- }
+ return cacheLoader.load(cdmEntity, recursive);
}
- private CdmBase loadRecursive(CdmBase cdmEntity, Set<CdmBase> alreadyVisitedEntities) {
-
- 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<String> 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);
- if(cdmEntityInSubGraph != null) {
- if(!alreadyVisitedEntities.contains(cdmEntityInSubGraph)) {
- logger.info("recursive loading object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId());
- loadRecursive(cdmEntityInSubGraph, alreadyVisitedEntities);
- } 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;
+ public CdmModelFieldPropertyFromClass getFromCdmlibModelCache(String className) {
+ return cacheLoader.getFromCdmlibModelCache(className);
}
- private CdmBase getCdmBaseTypeFieldValue(CdmBase cdmEntity,
- CdmBase cachedCdmEntity,
- String fieldName,
- Set<CdmBase> alreadyVisitedEntities) {
-
- // 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 supercalsses");
- }
- field.setAccessible(true);
- Object o = field.get(cdmEntity);
-
- if(o != null && o instanceof HibernateProxy) {
- LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
- if(!hli.isUninitialized()) {
- o = ((HibernateProxy) o).getHibernateLazyInitializer().getImplementation();
- field.set(cdmEntity, o);
- }
- }
-
- if(o != null && o instanceof PersistentCollection) {
- PersistentCollection pc = ((PersistentCollection)o);
- if(pc.wasInitialized()) {
- o = ProxyUtils.getObject(pc);
- field.set(cdmEntity, o);
- }
- }
-
- //field.set(cdmEntity, o);
- CdmBase cdmEntityInSubGraph = null;
- if(o != null
- && !ProxyFactory.isProxyClass(o.getClass())
- && !(o instanceof PersistentCollection) ) {
-
- 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 = getFromCache(cdmEntityInSubGraph);
- // making sure that the field in cached cdm entity is always
- // up-to-date by setting to the value of the cdm entity being loaded
- // the only execption to this is found below
- field.set(cachedCdmEntity, o);
-
- // the only exception to updating the field to the latest value
- // 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
- if(cachedCdmEntityInSubGraph != null) {
- if(cachedCdmEntityInSubGraph != cdmEntityInSubGraph) {
- logger.info("setting cached + real value to '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId());
- field.set(cachedCdmEntity, cachedCdmEntityInSubGraph);
- }
- }
- } else if(o instanceof Map) {
- loadRecursive((Map)o, alreadyVisitedEntities);
- } else if(o instanceof Collection) {
- loadRecursive((Collection)o, alreadyVisitedEntities);
- }
- }
- // 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);
- }
- }
+ @Override
public void put(CdmBase cdmEntity) {
CdmEntityCacheKey id = new CdmEntityCacheKey(cdmEntity);
- Element cachedCdmEntityElement = getCacheElement(id);
-
- if(cachedCdmEntityElement == null) {
- cachedCdmEntityElement = cdmServiceCacher.getCacheElement(cdmEntity.getUuid());
- if(cachedCdmEntityElement != null) {
- logger.info("Cdm Entity with id : " + cdmEntity.getId() + " already exists in permanent cache. Ignoring put.");
- return;
- }
+ Element cachedCdmEntityElement = cdmServiceCacher.getCacheElement(cdmEntity.getUuid());
+ if(cachedCdmEntityElement != null) {
+ logger.info("Cdm Entity with id : " + cdmEntity.getId() + " already exists in permanent cache. Ignoring put.");
+ return;
}
-
getCache().put(new Element(id, cdmEntity));
}
return getCache().get(key);
}
- public CdmModelFieldPropertyFromClass getFromCdmlibModelCache(String className) {
- Element e = cdmlibModelCache.get(className);
- if (e == null) {
- return null;
- } else {
- return (CdmModelFieldPropertyFromClass) e.getObjectValue();
- }
- }
public CdmBase getFromCache(CdmEntityCacheKey id) {
Element e = getCacheElement(id);
return getFromCache(cacheId);
}
+ @Override
public CdmBase getFromCache(CdmBase cdmBase) {
CdmEntityCacheKey cacheId = generateKey(cdmBase);
public void dispose() {
cache.removeAll();
cache.flush();
- cdmServiceCacher.getDefaultCacheManager().removeCache(cacheId);
+ CdmRemoteCacheManager.getInstance().getDefaultCacheManager().removeCache(cacheId);
}
return new CdmEntityCacheKey(entityClass, id);
}
- public static boolean isRecursiveEnabled() {
- return isRecursiveEnabled;
- }
-
- public static void setRecursiveEnabled(boolean ire) {
- isRecursiveEnabled = ire;
- }
-
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.IdentityHashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-
-import javassist.util.proxy.ProxyFactory;
+import java.util.Set;
import org.apache.log4j.Logger;
import org.hibernate.collection.spi.PersistentCollection;
private List<CdmEntityInfo> rootElements;
+ StringBuilder debugOutput = new StringBuilder();
+
public EntityCacherDebugResult() {
}
public <T extends CdmBase> EntityCacherDebugResult(CdmTransientEntityCacher cacher, List<T> rootEntities) {
this.cacher = cacher;
init();
+
if(rootEntities != null && !rootEntities.isEmpty()) {
for(CdmBase rootEntity : rootEntities) {
debug(rootEntity, true);
- print();
+ String out = toString(duplicateCdmEntityMap, notInCacheList, rootEntity);
+ System.out.println(out);
+ debugOutput.append(out);
clear();
}
return rootElements;
}
- private void print() {
- System.out.println(toString());
+ private void print(Map<CdmEntityInfo, CdmEntityInfo> duplicateCdmEntityMap,
+ List<CdmEntityInfo> notInCacheList,
+ CdmBase rootEntity) {
+ System.out.println(toString(duplicateCdmEntityMap, notInCacheList, rootEntity));
}
@Override
public String toString() {
+ return debugOutput.toString();
+ }
+
+ private String toString(Map<CdmEntityInfo, CdmEntityInfo> duplicateCdmEntityMap,
+ List<CdmEntityInfo> 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(System.getProperty("line.separator"));
CdmEntityInfo cei = entry.getKey();
CdmBase cb = (CdmBase) cei.getObject();
- CdmBase cbParent = (CdmBase) cei.getParent().getObject();
+ Object cbParent = cei.getParent().getObject();
CdmEntityInfo dupCei = entry.getValue();
CdmBase dupCb = (CdmBase) dupCei.getObject();
- CdmBase dupCbParent = (CdmBase) dupCei.getParent().getObject();
+ Object dupCbParent = dupCei.getParent().getObject();
sb.append(" - entity : " + cb.getUserFriendlyTypeName() + "/" + cb.getId() +
- " as field " + cei.getField().getName() +
- " of entity " + cbParent.getUserFriendlyTypeName() + "/" + cbParent.getId());
+ " as member " + cei.getField().getName() +
+ " of entity " + cbParent.getClass().getCanonicalName());
sb.append(System.getProperty("line.separator"));
sb.append(" - duplicate entity : " + dupCb.getUserFriendlyTypeName() + "/" + dupCb.getId() +
" as field " + dupCei.getField().getName() +
- " of entity " + dupCbParent.getUserFriendlyTypeName() + "/" + dupCbParent.getId());
+ " of entity " + dupCbParent.getClass().getCanonicalName());
sb.append(System.getProperty("line.separator"));
sb.append("-----------");
}
for(CdmEntityInfo cei : notInCacheList) {
CdmBase cb = (CdmBase) cei.getObject();
- CdmBase cbParent = (CdmBase) cei.getParent().getObject();
+ Object cbParent = cei.getParent().getObject();
sb.append(System.getProperty("line.separator"));
sb.append(" - entity : " + cb.getUserFriendlyTypeName() + "/" + cb.getId() +
" as field " + cei.getField().getName() +
- " of entity" + cbParent.getUserFriendlyTypeName() + "/" + cbParent.getId());
+ " of entity" + cbParent.getClass().getCanonicalName());
}
}
-
+ sb.append(System.getProperty("line.separator"));
return sb.toString();
}
return;
}
logger.info("---- starting recursive debug for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
- IdentityHashMap<Object, CdmEntityInfo> alreadyVisitedEntities = new IdentityHashMap<Object, CdmEntityInfo>();
+ Set<CdmEntityInfo> alreadyVisitedEntities = new HashSet<CdmEntityInfo>();
CdmEntityInfo cei = new CdmEntityInfo(cdmEntity);
debugRecursive(cdmEntity, alreadyVisitedEntities, cei);
rootElements.add(cei);
}
private <T extends Object> void debugRecursive(T obj,
- IdentityHashMap<Object, CdmEntityInfo> alreadyVisitedEntities,
+ Set<CdmEntityInfo> alreadyVisitedEntities,
CdmEntityInfo cei) {
if(obj == null) {
return;
if(obj instanceof CdmBase) {
debugRecursive((CdmBase)obj, alreadyVisitedEntities, cei);
} else if (obj instanceof Map) {
- debug((Map<T,T>)obj, alreadyVisitedEntities, cei);
+ debug((Map<T,T>)obj, alreadyVisitedEntities, cei);
} else if (obj instanceof Collection) {
debug((Collection<T>)obj, alreadyVisitedEntities, cei);
}
}
private <T extends Object> void debug(Map<T,T> map,
- IdentityHashMap<Object, CdmEntityInfo> alreadyVisitedEntities,
+ Set<CdmEntityInfo> alreadyVisitedEntities,
CdmEntityInfo cei) {
if(map == null || map.isEmpty()) {
return;
}
private <T extends Object> void debug(Collection<T> collection,
- IdentityHashMap<Object, CdmEntityInfo> alreadyVisitedEntities,
+ Set<CdmEntityInfo> alreadyVisitedEntities,
CdmEntityInfo cei) {
int length = collection.size();
Object[] result = new Object[length];
}
private void debugRecursive(CdmBase cdmEntity,
- IdentityHashMap<Object, CdmEntityInfo> alreadyVisitedEntities,
+ Set<CdmEntityInfo> alreadyVisitedEntities,
CdmEntityInfo 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
String className = cdmEntity.getClass().getName();
CdmModelFieldPropertyFromClass cmgmfc = cacher.getFromCdmlibModelCache(className);
if(cmgmfc != null) {
- alreadyVisitedEntities.put(cdmEntity, cei);
+ alreadyVisitedEntities.add(cei);
List<String> fields = cmgmfc.getFields();
for(String field : fields) {
// retrieve the actual object corresponding to the field.
// with CdmBase as the generic type
CdmEntityInfo childCei = getDebugCdmBaseTypeFieldValue(cdmEntity, field, alreadyVisitedEntities, cei);
- CdmBase cdmEntityInSubGraph = (CdmBase)childCei.getObject();
- if(cdmEntityInSubGraph != null) {
- if(!alreadyVisitedEntities.keySet().contains(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");
+ 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");
+ }
}
}
}
private CdmEntityInfo getDebugCdmBaseTypeFieldValue(CdmBase cdmEntity,
String fieldName,
- IdentityHashMap<Object, CdmEntityInfo> alreadyVisitedEntities,
+ Set<CdmEntityInfo> alreadyVisitedEntities,
CdmEntityInfo cei) {
CdmEntityInfo childCei = null;
}
field.setAccessible(true);
Object o = field.get(cdmEntity);
+
+ CdmBase cdmEntityInSubGraph = null;
+
+ boolean isHibernateProxy = false;
+ boolean isPersistentCollection = false;
+
+ childCei = new CdmEntityInfo(o);
+ cei.addChild(childCei);
+ childCei.setField(field);
+
if(o != null) {
+
if(o instanceof HibernateProxy) {
LazyInitializer hli = ((HibernateProxy)o).getHibernateLazyInitializer();
if(!hli.isUninitialized()) {
o = hli.getImplementation();
+ } else {
+ isHibernateProxy = true;
}
}
PersistentCollection pc = ((PersistentCollection)o);
if(pc.wasInitialized()) {
o = ProxyUtils.getObject(pc);
+ } else {
+ isPersistentCollection = true;
}
}
- }
- childCei = new CdmEntityInfo(o);
- cei.addChild(childCei);
- childCei.setField(field);
- CdmBase cdmEntityInSubGraph = null;
- if(o != null
- && !ProxyFactory.isProxyClass(o.getClass())
- && !(o instanceof PersistentCollection) ) {
+ childCei.setObject(o);
+ childCei.setProxy(isHibernateProxy || isPersistentCollection);
+ if(!isHibernateProxy && !isPersistentCollection) {
- 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;
+ 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;
- if(alreadyVisitedEntities.keySet().contains(cdmEntityInSubGraph)) {
//logger.info(" - found duplicate entity at " + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId());
- CdmEntityInfo dupCei = alreadyVisitedEntities.get(cdmEntityInSubGraph);
- addDuplicateEntity(childCei, dupCei);
+ CdmEntityInfo dupCei = getDuplicate(alreadyVisitedEntities, cdmEntityInSubGraph);
+ if(dupCei != null) {
+ addDuplicateEntity(childCei, dupCei);
+ }
+
+ CdmBase cachedCdmEntityInSubGraph = cacher.getFromCache(cdmEntityInSubGraph);
+ // the only exception to updating the field to the latest value
+ // 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
+ if(cachedCdmEntityInSubGraph == null) {
+ // 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(childCei);
+ }
+
+ } else if(o instanceof Map) {
+ debugRecursive((Map)o, alreadyVisitedEntities, childCei);
+ } else if(o instanceof Collection) {
+ debugRecursive((Collection)o, alreadyVisitedEntities, childCei);
}
-
- CdmBase cachedCdmEntityInSubGraph = cacher.getFromCache(cdmEntityInSubGraph);
- // the only exception to updating the field to the latest value
- // 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
- if(cachedCdmEntityInSubGraph == null) {
- // 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(childCei);
- }
- } 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);
}
+ private CdmEntityInfo getDuplicate(Set<CdmEntityInfo> 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(Set<CdmEntityInfo> ceiSet, Object objectToCompare) {
+ if(objectToCompare != null) {
+ for(CdmEntityInfo cei : ceiSet) {
+ if(cei.getObject() == objectToCompare) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
public class CdmEntityInfo {
- private final Object object;
+ private Object object;
private CdmEntityInfo parent;
private List<CdmEntityInfo> children;
private Field field;
private String label;
+ private boolean isProxy;
public CdmEntityInfo(Object object) {
this.object = object;
+ isProxy = false;
children = new ArrayList<CdmEntityInfo>();
}
}
} else if(object instanceof Collection) {
String className = object.getClass().getName();
- label = "[" + className + "] " + fieldName + String.valueOf(((Collection)object).size());
+ label = "[" + className + "] " + fieldName + " : " + String.valueOf(((Collection)object).size());
} else if(object instanceof Map) {
String className = object.getClass().getName();
- label = "[" + className + "] " + fieldName + String.valueOf(((Map)object).size());
+ label = "[" + className + "] " + fieldName + " : " + String.valueOf(((Map)object).size());
} else {
String className = object.getClass().getName();
- label = "[" + className + "] " + fieldName;
+ label = "[" + className + "] " + fieldName + " : " + object.toString();
}
} else {
label = "[NULL] " + fieldName;
return object;
}
+ public void setObject(Object object) {
+ this.object = object;
+ }
+
+ public boolean isProxy() {
+ return isProxy;
+ }
+
+ public void setProxy(boolean isProxy) {
+ this.isProxy = isProxy;
+ }
+
}
*/
@Override
public <T extends CdmBase> T remoteUpdate(IService<T> service, T cdmBase) {
- debug(cdmBase);
+ //debug(cdmBase);
T mergedCdmBase = service.merge(cdmBase);
//cdmTransientEntityCacher.clear();
// FIXME:Remoting not really sure if we need to reload the new
logger.info("No Session connected to owner, nothing to dispose");
return;
}
+ if(session == activeSession) {
+ activeSession = null;
+ }
ownerSessionMap.remove(owner);
notifyObservers();
}
<context:component-scan base-package="eu.etaxonomy.cdm.api.cache">\r
<!-- FIXME:Remoting Temp workaround to make remoting work -->\r
<context:exclude-filter type="regex"\r
- expression="eu\.etaxonomy\.cdm\.api\.cache\.CdmDaoCacher" />\r
+ expression="eu\.etaxonomy\.cdm\.api\.cache\.CdmTermCacher" />\r
</context:component-scan>\r
\r
<context:component-scan base-package="eu.etaxonomy.taxeditor.remoting.cache"/>\r
id="eu.etaxonomy.taxeditor.datasource.connect"
name="Connect">
</command>
+ <command
+ defaultHandler="eu.etaxonomy.taxeditor.handler.OpenInspectSessionsHandler"
+ id="eu.etaxonomy.taxeditor.store.open.InspectSessionsDialog"
+ name="Inspect Active Session">
+ </command>
</extension>
<extension
point="org.eclipse.ui.importWizards">
--- /dev/null
+// $Id$
+/**
+* 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.handler;
+
+import java.util.List;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.IHandler;
+import org.eclipse.swt.SWT;
+
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
+import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
+import eu.etaxonomy.taxeditor.store.CdmStore;
+import eu.etaxonomy.taxeditor.view.sessions.InspectSessionsDialog;
+
+/**
+ * @author cmathew
+ * @date 18 Feb 2015
+ *
+ */
+public class OpenInspectSessionsHandler extends AbstractHandler implements IHandler {
+
+
+ /* (non-Javadoc)
+ * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+ */
+ /** {@inheritDoc} */
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ Object principal = CdmStore.getCurrentAuthentiation().getPrincipal();
+
+ ICdmEntitySession activeSession = CdmStore.getCurrentSessionManager().getActiveSession();
+
+ if(activeSession == null) {
+ MessagingUtils.warningDialog("No Active Session", this, "Active Session is null");
+ } else {
+ List<CdmBase> rootEntities = activeSession.getRootEntities();
+ if(rootEntities == null || rootEntities.isEmpty()) {
+ MessagingUtils.warningDialog("No Root Entities", this, "No root entities to inspect");
+ } else {
+ InspectSessionsDialog dialog = new InspectSessionsDialog(AbstractUtility.getShell(), SWT.NONE);
+ dialog.open();
+ }
+
+ }
+
+ return null;
+
+ }
+}
import java.util.TreeSet;
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.NotEnabledException;
+import org.eclipse.core.commands.NotHandledException;
+import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
import org.eclipse.ui.part.EditorPart;
import org.eclipse.ui.progress.IProgressService;
}
+ public static void executeCommand(String commandId, Object source, String pluginId) {
+ IHandlerService handlerService = (IHandlerService) AbstractUtility.getService(IHandlerService.class);
+ Exception exception = null;
+ try {
+ handlerService.executeCommand(commandId, null);
+ } catch (ExecutionException e) {
+ exception = e;
+ } catch (NotDefinedException e) {
+ exception = e;
+ } catch (NotEnabledException e) {
+ exception = e;
+ } catch (NotHandledException e) {
+ exception = e;
+ } finally {
+ if(exception != null) {
+ MessagingUtils.errorDialog("Error executing command",
+ source,
+ "Could not execute command with id " + commandId ,
+ pluginId,
+ exception,
+ true);
+ }
+ }
+ }
}
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
protected Object result;
protected Shell shlInspectSessions;
- private Text text;
+ private Text txtDebugInfo;
private Label lblDebugInformation;
private final Cache cdmlibModelCache;
private final ICdmEntitySession activeSession;
private TreeViewer treeViewer;
+ private Button btnClose;
+ EntityCacherDebugResult ecdr;
+ private SashForm sashForm;
+ private Composite compositeDebug;
/**
* Create the dialog.
* @param parent
*/
public InspectSessionsDialog(Shell parent, int style) {
super(parent, style);
- setText("SWT Dialog");
+ setText("Inspect Active Session");
cdmlibModelCache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
activeSession = CdmStore.getCurrentSessionManager().getActiveSession();
+ ecdr = activeSession.debug();
}
/**
* @return the result
*/
public Object open() {
+
createContents();
+ setDebugInfoText();
treeViewer.setContentProvider(new SessionsTreeContentProvider());
treeViewer.setLabelProvider(new SessionsTreeLabelProvider());
treeViewer.setInput(getRootElements());
* Create contents of the dialog.
*/
private void createContents() {
- shlInspectSessions = new Shell(getParent(), getStyle());
- shlInspectSessions.setSize(641, 529);
+ shlInspectSessions = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE);
+ shlInspectSessions.setSize(641, 631);
shlInspectSessions.setText("Inspect Sessions");
shlInspectSessions.setLayout(new GridLayout(1, false));
- TreeViewer treeViewer = new TreeViewer(shlInspectSessions, SWT.BORDER);
- Tree tree = treeViewer.getTree();
- tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ sashForm = new SashForm(shlInspectSessions, SWT.VERTICAL);
+ sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+
+ treeViewer = new TreeViewer(sashForm, SWT.BORDER);
+ Tree tree = treeViewer.getTree();
- lblDebugInformation = new Label(shlInspectSessions, SWT.NONE);
- lblDebugInformation.setFont(SWTResourceManager.getFont("Ubuntu", 10, SWT.NORMAL));
- lblDebugInformation.setText("Debug Information :");
+ compositeDebug = new Composite(sashForm, SWT.NONE);
+ compositeDebug.setLayout(new GridLayout(1, false));
- text = new Text(shlInspectSessions, SWT.BORDER);
- text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ lblDebugInformation = new Label(compositeDebug, SWT.NONE);
+ lblDebugInformation.setAlignment(SWT.CENTER);
+ lblDebugInformation.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false, 1, 1));
+ lblDebugInformation.setFont(SWTResourceManager.getFont("Ubuntu", 10, SWT.NORMAL));
+ lblDebugInformation.setText("Debug Information");
+
+ txtDebugInfo = new Text(compositeDebug, SWT.BORDER | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL | SWT.MULTI);
+ txtDebugInfo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
+ sashForm.setWeights(new int[] {338, 184});
+
+ btnClose = new Button(shlInspectSessions, SWT.NONE);
+ btnClose.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ shlInspectSessions.dispose();
+ }
+ });
+ GridData gd_btnClose = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
+ gd_btnClose.widthHint = 70;
+ btnClose.setLayoutData(gd_btnClose);
+ btnClose.setText("Close");
}
+ private void setDebugInfoText() {
+ txtDebugInfo.setText(ecdr.toString());
+ }
private CdmEntityInfo[] getRootElements() {
- EntityCacherDebugResult ecdr = activeSession.debug();
- return (CdmEntityInfo[]) ecdr.getRootElements().toArray();
+
+ List<CdmEntityInfo> rootElemnts = ecdr.getRootElements();
+ return rootElemnts.toArray(new CdmEntityInfo[rootElemnts.size()]);
}
class SessionsTreeContentProvider implements ITreeContentProvider {
// $Id$
/**
-* 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.
-*/
+ * 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.view.sessions;
import java.text.DecimalFormat;
import org.eclipse.wb.swt.SWTResourceManager;
import eu.etaxonomy.cdm.api.cache.CdmCacher;
+import eu.etaxonomy.taxeditor.model.AbstractUtility;
import eu.etaxonomy.taxeditor.remoting.cache.CdmRemoteCacheManager;
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
public class SessionsViewPart extends ViewPart implements ICdmEntitySessionManagerObserver {
public static final String ID = "eu.etaxonomy.taxeditor.view.sessions.SessionsViewPart"; //$NON-NLS-1$
+ public static final String OPEN_INSPECT_SESSIONS_DIALOG_ID = "eu.etaxonomy.taxeditor.store.open.InspectSessionsDialog";
private Table tableSessions;
private final String[] titles = { "Owner", "In Memory", "On Disk"};
private Text txtCdmModelInMemory;
private Text txtCdmModelOnDisk;
private Text txtDefaultOnDisk;
+
public SessionsViewPart() {
this.cdmEntitySessionManager = CdmStore.getCurrentSessionManager();
if(cdmEntitySessionManager != null) {
@Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
- container.setLayout(new GridLayout(6, false));
+ container.setLayout(new GridLayout(5, false));
{
Label lblNoOfSessions = new Label(container, SWT.NONE);
lblNoOfSessions.setFont(SWTResourceManager.getFont("Ubuntu", 10, SWT.NORMAL));
new Label(container, SWT.NONE);
new Label(container, SWT.NONE);
new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
{
Label lblNoOfCaches = new Label(container, SWT.CENTER);
lblNoOfCaches.setAlignment(SWT.RIGHT);
}
new Label(container, SWT.NONE);
new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
new Label(container, SWT.NONE);
- {
- Label lblDefaultCache = new Label(container, SWT.CENTER);
- lblDefaultCache.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
- lblDefaultCache.setText("Default Cache, ");
- lblDefaultCache.setFont(SWTResourceManager.getFont("Ubuntu", 10, SWT.NORMAL));
- lblDefaultCache.setAlignment(SWT.RIGHT);
- }
+ {
+ Label lblDefaultCache = new Label(container, SWT.CENTER);
+ lblDefaultCache.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+ lblDefaultCache.setText("Default Cache, ");
+ lblDefaultCache.setFont(SWTResourceManager.getFont("Ubuntu", 10, SWT.NORMAL));
+ lblDefaultCache.setAlignment(SWT.RIGHT);
+ }
{
Label lblDefaultInMemory = new Label(container, SWT.CENTER);
lblDefaultInMemory.setText("in Memory : ");
gd_txtDefaultOnDisk.widthHint = 130;
txtDefaultOnDisk.setLayoutData(gd_txtDefaultOnDisk);
}
- new Label(container, SWT.NONE);
{
Label lblCdmModelCache = new Label(container, SWT.CENTER);
lblCdmModelCache.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
gd_txtCdmModelOnDisk.widthHint = 130;
txtCdmModelOnDisk.setLayoutData(gd_txtCdmModelOnDisk);
}
- new Label(container, SWT.NONE);
{
Button btnRefresh = new Button(container, SWT.NONE);
btnRefresh.addSelectionListener(new SelectionAdapter() {
btnRefresh.setLayoutData(gd_btnRefresh);
btnRefresh.setText("Refresh");
}
- new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
- new Label(container, SWT.NONE);
-
- {
- tableSessions = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
- tableSessions.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1));
- tableSessions.setHeaderVisible(true);
- tableSessions.setLinesVisible(true);
+ {
+ Button btnInspectActiveSession = new Button(container, SWT.NONE);
+ btnInspectActiveSession.addSelectionListener(new SelectionAdapter() {
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ AbstractUtility.executeCommand(OPEN_INSPECT_SESSIONS_DIALOG_ID, this, null);
}
- new Label(container, SWT.NONE);
+ });
+ btnInspectActiveSession.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1));
+ btnInspectActiveSession.setText("Inspect Active Session");
+ }
+ new Label(container, SWT.NONE);
+ new Label(container, SWT.NONE);
+
+ {
+ tableSessions = new Table(container, SWT.BORDER | SWT.FULL_SELECTION);
+ GridData gd_tableSessions = new GridData(SWT.FILL, SWT.FILL, true, true, 5, 1);
+ gd_tableSessions.widthHint = 769;
+ tableSessions.setLayoutData(gd_tableSessions);
+ tableSessions.setHeaderVisible(true);
+ tableSessions.setLinesVisible(true);
+ }
createActions();
initializeToolBar();
for (String title : titles) {
- TableColumn column = new TableColumn(tableSessions, SWT.NULL);
- column.setWidth(200);
- column.setText(title);
+ TableColumn column = new TableColumn(tableSessions, SWT.NULL);
+ column.setWidth(200);
+ column.setText(title);
}
changed();
@Override
public void changed() {
+ if(tableSessions.isDisposed()) {
+ return;
+ }
tableSessions.removeAll();
if(cdmEntitySessionManager != null) {
Collection<ICdmEntitySession> sessions = cdmEntitySessionManager.getSessions();