/******************************************************************************* * Copyright (c) 2014 BestSolution.at and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation *******************************************************************************/ package at.bestsolution.persistence.java.internal; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import at.bestsolution.persistence.java.SessionCache; import at.bestsolution.persistence.java.SessionCacheFactory; public class DefaultSessionCacheFactory implements SessionCacheFactory { @Override public SessionCache createCache() { return new SessionCacheImpl(); } static class VersionedEObject { final EObject object; long version; public VersionedEObject(EObject object, long version) { this.object = object; this.version = version; } } static class ParameterObject<D> { final String name; final D data; final Object[] parameters; public ParameterObject(String name, D data, Object[] parameter) { this.name = name; this.data = data; this.parameters = parameter; } } static class SessionCacheImpl implements SessionCache { private Map<EClass, Map<Object,VersionedEObject>> cacheMap = new HashMap<EClass, Map<Object,VersionedEObject>>(); private Map<String, ParameterObject<List<EObject>>> queryResultCache = new HashMap<String, ParameterObject<List<EObject>>>(); private Map<String, ParameterObject<Map<Object,EObject>>> queryMapResultCache = new HashMap<String, ParameterObject<Map<Object,EObject>>>(); @SuppressWarnings("unchecked") @Override public <O extends EObject> O getObject(EClass eClass, Object id) { Map<Object, VersionedEObject> map = cacheMap.get(eClass); if( map != null ) { VersionedEObject vo = map.get(id); if( vo != null ) { return (O) vo.object; } } return null; } @Override public void evitObject(EObject object) { Map<Object, VersionedEObject> map = cacheMap.get(object.eClass()); if( map != null ) { Iterator<VersionedEObject> it = map.values().iterator(); while( it.hasNext() ) { if( it.next().object == object ) { it.remove(); break; } } } } @Override public void evictObject(EClass eClass, Object id) { Map<Object, VersionedEObject> map = cacheMap.get(eClass); if( map != null ) { map.remove(id); } } @Override public void evictObjects(EClass eClass) { cacheMap.remove(eClass); } @Override public void putObject(EObject object, Object id, long version) { Map<Object, VersionedEObject> map = cacheMap.get(object.eClass()); if( map == null ) { map = new HashMap<Object, VersionedEObject>(); cacheMap.put(object.eClass(), map); } map.put(id, new VersionedEObject(object, version)); } @Override public boolean isCached(EObject object) { Map<Object, VersionedEObject> map = cacheMap.get(object.eClass()); if( map != null ) { Iterator<VersionedEObject> it = map.values().iterator(); while( it.hasNext() ) { if( it.next().object == object ) { return true; } } } return false; } @Override public long getVersion(EObject object, Object id) { Map<Object, VersionedEObject> map = cacheMap.get(object.eClass()); if( map != null ) { VersionedEObject o = map.get(id); if( o != null ) { return o.version; } } return -1; } @Override public boolean updateVersion(EObject object, Object id, long version) { Map<Object, VersionedEObject> map = cacheMap.get(object.eClass()); if( map != null ) { VersionedEObject o = map.get(id); if( o != null ) { o.version = version; return true; } } return false; } @Override public void release() { cacheMap.clear(); queryResultCache.clear(); queryMapResultCache.clear(); } @Override public void clear() { cacheMap.clear(); queryResultCache.clear(); queryMapResultCache.clear(); } @SuppressWarnings("unchecked") @Override public <O extends EObject> List<O> getQueryResult(String query, Object... parameters) { ParameterObject<List<EObject>> parameterObject = queryResultCache.get(createQueryKey(query, parameters)); return parameterObject == null ? null : (List<O>) parameterObject.data; } @Override public void putQueryResult(List<EObject> list, String query, Object... parameters) { queryResultCache.put(createQueryKey(query, parameters), new ParameterObject<List<EObject>>(query,list,parameters)); } @Override public void evitQueryResult(Selector<List<EObject>> selector) { Iterator<ParameterObject<List<EObject>>> it = queryResultCache.values().iterator(); while( it.hasNext() ) { ParameterObject<List<EObject>> next = it.next(); selector.select(next.name, Arrays.asList(next.parameters), Collections.unmodifiableList(next.data)); } } private static String createQueryKey(String query, Object... parameters) { StringBuilder b = new StringBuilder(query); for( Object o : parameters ) { if( o == null ) { b.append("#null"); } else { b.append("#"+o); } } return b.toString(); } @SuppressWarnings("unchecked") @Override public <O extends EObject> Map<Object, O> getQueryMapResult( String query, Object... parameters) { ParameterObject<Map<Object, EObject>> parameterObject = queryMapResultCache.get(createQueryKey(query, parameters)); return parameterObject == null ? null : (Map<Object, O>) parameterObject.data; } @Override public void putQueryMapResult(Map<Object, EObject> map, String query, Object... parameters) { queryMapResultCache.put(createQueryKey(query, parameters), new ParameterObject<Map<Object,EObject>>(query, map, parameters)); } @Override public void evitQueryMapResult(Selector<Map<Object, EObject>> selector) { Iterator<ParameterObject<Map<Object,EObject>>> it = queryMapResultCache.values().iterator(); while( it.hasNext() ) { ParameterObject<Map<Object,EObject>> next = it.next(); selector.select(next.name, Arrays.asList(next.parameters), Collections.unmodifiableMap(next.data)); } } } }