/**
*
* Copyright 2014 The Darks ORM Project (Liu lihua)
*
* 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 darks.orm.core.cache;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import darks.orm.app.Page;
import darks.orm.core.cache.scope.ApplicationCacheFactory;
import darks.orm.core.cache.scope.CacheFactory;
import darks.orm.core.cache.scope.CacheProvider;
import darks.orm.core.cache.scope.EhCacheProvider;
import darks.orm.core.cache.scope.ThreadCacheFactory;
import darks.orm.core.cache.thread.CacheAsynchronousThread;
import darks.orm.core.data.EntityData;
import darks.orm.core.factory.ClassFactory;
import darks.orm.core.session.SessionContext;
import darks.orm.log.Logger;
import darks.orm.log.LoggerFactory;
import darks.orm.util.ThreadHelper;
@SuppressWarnings("unchecked")
public class CacheContext
{
private static Logger log = LoggerFactory.getLogger(CacheContext.class);
public static final String SCOPE_APPLICATION = "application";
public static final String SCOPE_THREAD = "thread";
public enum CacheKeyType
{
SingleKey, ListKey, PageKey
}
private List<CacheProvider> cacheProviderList = new ArrayList<CacheProvider>();
private ConcurrentMap<String, CacheFactory> cacheFactorys = null;
private boolean synchronous = true;
public CacheContext()
{
cacheFactorys = new ConcurrentHashMap<String, CacheFactory>(3);
addCacheFactory(SCOPE_APPLICATION, ApplicationCacheFactory.getInstance());
addCacheFactory(SCOPE_THREAD, ThreadCacheFactory.getInstance());
EhCacheProvider ehCacheProvider = new EhCacheProvider();
if (ehCacheProvider.isClassLoaded())
{
addCacheProvider(ehCacheProvider);
}
synchronous = SessionContext.getConfigure().getCacheConfig().isSynchronous();
}
/**
* ��ʼ������������
*/
public void initialize()
{
for (CacheProvider cacheProvider : cacheProviderList)
{
if (cacheProvider.isClassLoaded() && !cacheProvider.isInit())
{
cacheProvider.initialize(this);
}
}
}
public void shutdown()
{
for (CacheProvider cacheProvider : cacheProviderList)
{
if (cacheProvider.isClassLoaded() && cacheProvider.isInit())
{
cacheProvider.shutdown();
}
}
}
/**
* ��ӻ��湤��
*
* @param key ������ֵ
* @param cacheFactory ����ʵ��
*/
public void addCacheFactory(String key, CacheFactory cacheFactory)
{
cacheFactorys.put(key, cacheFactory);
}
/**
* �Ƴ����湤��
*
* @param key ������ֵ
*/
public void removeCacheFactory(String key)
{
cacheFactorys.remove(key);
}
/**
* ��ӻ��湩Ӧ��
*
* @param cacheProvider
*/
public void addCacheProvider(CacheProvider cacheProvider)
{
cacheProviderList.add(cacheProvider);
}
/**
* ���浥������
*
* @param cls ʵ����
* @param cacheId ��������
* @param id ʵ������ֵ
* @param value ʵ��ʵ��
*/
public <T> void cacheSingle(Class<T> cls, String cacheId, int id, Object value, boolean cascade)
{
try
{
EntityData data = ClassFactory.getEntity(cls.getName());
CacheKey key = new CacheKey(data, id, CacheKeyType.SingleKey);
key.setCascade(cascade);
cacheObject(key, cacheId, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* ���浥������
*
* @param cls ʵ����
* @param cacheId ��������
* @param sql SQL���
* @param params ע���������
* @param value ʵ��ʵ��
*/
public <T> void cacheSingle(Class<T> cls, String cacheId, String sql, Object[] params, Object value, boolean cascade)
{
try
{
EntityData data = ClassFactory.getEntity(cls.getName());
CacheKey key = new CacheKey(data, sql, params, CacheKeyType.SingleKey);
key.setCascade(cascade);
cacheObject(key, cacheId, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* ����ʵ���б�
*
* @param cls ʵ����
* @param cacheId ��������
* @param sql SQL���
* @param params ע���������
* @param value ʵ��ʵ��
*/
public <T> void cacheList(Class<T> cls, String cacheId, String sql, Object[] params, Object value, boolean cascade)
{
try
{
EntityData data = ClassFactory.getEntity(cls.getName());
CacheKey key = new CacheKey(data, sql, params, CacheKeyType.ListKey);
key.setCascade(cascade);
cacheObject(key, cacheId, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* �����ҳ����
*
* @param cls ʵ����
* @param cacheId ��������
* @param sql SQL���
* @param params ע���������
* @param page ��ǰҳ��
* @param pageSize ��ҳ��
* @param count ��¼����
* @param value ʵ��ʵ��
*/
public <T> void cachePage(Class<T> cls, String cacheId, String sql, Object[] params, int page, int pageSize,
int count, Object value, boolean cascade)
{
try
{
EntityData data = ClassFactory.getEntity(cls.getName());
CacheKey key = new CacheKey(sql, params, page, pageSize, data, CacheKeyType.PageKey, count);
key.setCascade(cascade);
cacheObject(key, cacheId, value);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* �������
*
* @param key ����KEY
* @param cacheId ��������
* @param value ����ʵ��
* @throws Exception
*/
private void cacheObject(CacheKey key, String cacheId, Object value)
throws Exception
{
CacheFactory factory = cacheFactorys.get(cacheId);
if (factory != null)
{
if (synchronous)
{
factory.cacheObject(key, value);
}
else
{
ThreadHelper.addThread(new CacheAsynchronousThread(factory, key, cacheId, value));
}
}
}
/**
* ��û������
*
* @param key ����KEY
* @param cacheId ��������
* @return �������
* @throws Exception
*/
public Object getObject(CacheKey key, String cacheId)
throws Exception
{
CacheFactory factory = cacheFactorys.get(cacheId);
if (factory != null)
{
return factory.getObject(key);
}
return null;
}
/**
* ��õ�������
*
* @param cls ʵ����
* @param cacheId ��������
* @param id ����ֵ
* @return ��������
*/
public <T> T getSingle(Class<T> cls, String cacheId, int id, boolean cascade)
{
try
{
EntityData data = ClassFactory.parseClass(cls);
CacheKey key = new CacheKey(data, id, CacheKeyType.SingleKey);
key.setCascade(cascade);
return (T)getObject(key, cacheId);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public <T> T getSingle(Class<T> cls, String cacheId, String sql, Object[] params, boolean cascade)
{
try
{
EntityData data = ClassFactory.parseClass(cls);
CacheKey key = new CacheKey(data, sql, params, CacheKeyType.SingleKey);
key.setCascade(cascade);
return (T)getObject(key, cacheId);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public <T> List<T> getList(Class<T> cls, String cacheId, String sql, Object[] params, boolean cascade)
{
try
{
EntityData data = ClassFactory.parseClass(cls);
CacheKey key = new CacheKey(data, sql, params, CacheKeyType.ListKey);
key.setCascade(cascade);
return (List<T>)getObject(key, cacheId);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public <T> Page<T> getPage(Class<T> cls, String cacheId, String sql, Object[] params, int page, int pageSize,
boolean cascade)
{
try
{
EntityData data = ClassFactory.parseClass(cls);
CacheKey key = new CacheKey(sql, params, page, pageSize, data, CacheKeyType.PageKey, 0);
key.setCascade(cascade);
List<T> list = (List<T>)getObject(key, cacheId);
if (list == null)
return null;
Page<T> ret = new Page<T>(list, key.getCount());
return ret;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public void flushAll()
{
for (CacheFactory cacheFactory : cacheFactorys.values())
{
cacheFactory.flush();
}
log.debug("Cache Flush");
}
public boolean isSynchronous()
{
return synchronous;
}
}