/* * Copyright (c) 2012-2015 Savoir Technologies, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.savoirtech.hecate.cql3.persistence.def; import com.datastax.driver.core.Session; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.savoirtech.hecate.cql3.mapping.PojoMapping; import com.savoirtech.hecate.cql3.mapping.PojoMappingFactory; import com.savoirtech.hecate.cql3.mapping.def.DefaultPojoMappingFactory; import com.savoirtech.hecate.cql3.persistence.Dehydrator; import com.savoirtech.hecate.cql3.persistence.Evaporator; import com.savoirtech.hecate.cql3.persistence.Hydrator; import com.savoirtech.hecate.cql3.persistence.PersistenceContext; import com.savoirtech.hecate.cql3.util.PojoCacheKey; public class DefaultPersistenceContext implements PersistenceContext { //---------------------------------------------------------------------------------------------------------------------- // Fields //---------------------------------------------------------------------------------------------------------------------- private final Session session; private final PojoMappingFactory pojoMappingFactory; private final LoadingCache<PojoCacheKey, DefaultPojoQuery<?>> findByKeyCache; private final LoadingCache<PojoCacheKey, DefaultPojoQuery<?>> findByKeysCache; private final LoadingCache<PojoCacheKey, DefaultPojoSave> saveCache; private final LoadingCache<PojoCacheKey, DefaultPojoFindForDelete> findForDeleteCache; private final LoadingCache<PojoCacheKey, DefaultPojoDelete> deleteCache; //---------------------------------------------------------------------------------------------------------------------- // Constructors //---------------------------------------------------------------------------------------------------------------------- public DefaultPersistenceContext(Session session) { this(session, new DefaultPojoMappingFactory(session)); } public DefaultPersistenceContext(Session session, PojoMappingFactory pojoMappingFactory) { this.session = session; this.pojoMappingFactory = pojoMappingFactory; this.findByKeysCache = CacheBuilder.newBuilder().build(new FindByKeysLoader()); this.findByKeyCache = CacheBuilder.newBuilder().build(new FindByKeyLoader()); this.saveCache = CacheBuilder.newBuilder().build(new SaveLoader()); this.findForDeleteCache = CacheBuilder.newBuilder().build(new FindForDeleteLoader()); this.deleteCache = CacheBuilder.newBuilder().build(new DeleteLoader()); } //---------------------------------------------------------------------------------------------------------------------- // PersistenceContext Implementation //---------------------------------------------------------------------------------------------------------------------- @Override public DefaultPojoDelete delete(Class<?> pojoType, String tableName) { return deleteCache.getUnchecked(key(pojoType, tableName)); } @Override public <P> DefaultPojoQueryBuilder<P> find(Class<P> pojoType) { return find(pojoType, null); } @Override public <P> DefaultPojoQueryBuilder<P> find(Class<P> pojoType, String tableName) { return new DefaultPojoQueryBuilder<>(this, pojoMappingFactory.getPojoMapping(key(pojoType, tableName))); } @Override @SuppressWarnings("unchecked") public <P> DefaultPojoQuery<P> findByKey(Class<P> pojoType, String tableName) { return (DefaultPojoQuery<P>) findByKeyCache.getUnchecked(key(pojoType, tableName)); } @Override @SuppressWarnings("unchecked") public <P> DefaultPojoQuery<P> findByKeys(Class<P> pojoType, String tableName) { return (DefaultPojoQuery<P>) findByKeysCache.getUnchecked(key(pojoType, tableName)); } @Override public DefaultPojoSave save(Class<?> pojoType, String tableName) { return saveCache.getUnchecked(key(pojoType, tableName)); } //---------------------------------------------------------------------------------------------------------------------- // Getter/Setter Methods //---------------------------------------------------------------------------------------------------------------------- public Session getSession() { return session; } //---------------------------------------------------------------------------------------------------------------------- // Other Methods //---------------------------------------------------------------------------------------------------------------------- private DefaultPojoQueryBuilder<?> find(PojoMapping mapping) { return new DefaultPojoQueryBuilder<>(this, mapping); } public DefaultPojoFindForDelete findForDelete(Class<?> pojoType, String tableName) { return findForDeleteCache.getUnchecked(key(pojoType, tableName)); } private PojoCacheKey key(Class<?> pojoType, String tableName) { return new PojoCacheKey(pojoType, tableName); } public Dehydrator newDehydrator(Integer ttl) { return new DefaultDehydrator(this, ttl); } public Evaporator newEvaporator() { return new DefaultEvaporator(this); } public Hydrator newHydrator() { return new DefaultHydrator(this); } private PojoMapping pojoMapping(PojoCacheKey key) { return pojoMappingFactory.getPojoMapping(key); } //---------------------------------------------------------------------------------------------------------------------- // Inner Classes //---------------------------------------------------------------------------------------------------------------------- private final class DeleteLoader extends PojoMappingCacheLoader<DefaultPojoDelete> { @Override protected DefaultPojoDelete load(PojoMapping pojoMapping) { return new DefaultPojoDelete(DefaultPersistenceContext.this, pojoMapping); } } private class FindByKeyLoader extends PojoMappingCacheLoader<DefaultPojoQuery<?>> { @Override protected DefaultPojoQuery<?> load(PojoMapping pojoMapping) { return find(pojoMapping).identifierEquals().build(); } } private class FindByKeysLoader extends PojoMappingCacheLoader<DefaultPojoQuery<?>> { @Override protected DefaultPojoQuery<?> load(PojoMapping pojoMapping) { return find(pojoMapping).identifierIn().build(); } } private final class FindForDeleteLoader extends PojoMappingCacheLoader<DefaultPojoFindForDelete> { @Override protected DefaultPojoFindForDelete load(PojoMapping pojoMapping) { return new DefaultPojoFindForDelete(DefaultPersistenceContext.this, pojoMapping); } } private abstract class PojoMappingCacheLoader<T> extends CacheLoader<PojoCacheKey, T> { @Override public final T load(PojoCacheKey key) throws Exception { return load(pojoMapping(key)); } protected abstract T load(PojoMapping pojoMapping); } private final class SaveLoader extends PojoMappingCacheLoader<DefaultPojoSave> { @Override protected DefaultPojoSave load(PojoMapping pojoMapping) { return new DefaultPojoSave(DefaultPersistenceContext.this, pojoMapping); } } }