package com.salama.android.dataservice;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import MetoXML.XmlDeserializer;
import MetoXML.Base.XmlParseException;
import MetoXML.Util.PropertyDescriptor;
import android.util.Log;
import com.salama.android.datacore.DBDataUtil;
import com.salama.android.datacore.DBManager;
import com.salama.android.datacore.SqliteUtilException;
import com.salama.android.dataservice.param.DataQueryParam;
import com.salama.android.dataservice.param.LocalQueryParam;
import com.salama.android.dataservice.param.LocalStorageParam;
import com.salama.android.dataservice.param.WebServiceParam;
import com.salama.android.support.ServiceSupportApplication;
import com.salama.android.util.ResourceFileManager;
public class SalamaDataService {
public static final String DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT = "result";
private DBManager _dbManager;
private ResourceFileManager _resourceFileManager;
private WebService _webService;
private LocalStorageService _localStorageService;
private ResourceDownloadHandler _resourceDownloadHandler;
private ResourceDownloadTaskService _resourceDownloadTaskService;
private ExecutorService _queueForQueryWebService;
private ExecutorService _queueForQueryLocalDB;
// private int _queueMaxCountForQueryWebService = 5;
// private int _queueMaxCountForQueryLocalDB = 5;
/**
* 取得资源下载处理器
* @return 资源下载处理器
*/
public ResourceDownloadHandler getResourceDownloadHandler() {
return _resourceDownloadHandler;
}
/**
* 设置资源下载处理器
* @param resourceDownloadHandler 资源下载处理器
*/
public void setResourceDownloadHandler(
ResourceDownloadHandler resourceDownloadHandler) {
_resourceDownloadHandler = resourceDownloadHandler;
_resourceDownloadTaskService.setResourceDownloadHandler(_resourceDownloadHandler);
}
/**
* 取得DBManager
* @return DBManager
*/
public DBManager getDbManager() {
return _dbManager;
}
/**
* 取得资源管理器
* @return 资源管理器
*/
public ResourceFileManager getResourceFileManager() {
return _resourceFileManager;
}
/**
* 取得WebService处理器
* @return WebService处理器
*/
public WebService getWebService() {
return _webService;
}
/**
* 取得本地存储处理器
* @return 本地存储处理器
*/
public LocalStorageService getLocalStorageService() {
return _localStorageService;
}
/**
* 取得资源下载任务处理器
* @return 资源下载任务处理器
*/
public ResourceDownloadTaskService getResourceDownloadTaskService() {
return _resourceDownloadTaskService;
}
/**
* 取得WebService任务队列
* @return
*/
public ExecutorService getQueueForQueryWebService() {
return _queueForQueryWebService;
}
/**
* 取得本地数据库查询任务队列
* @return
*/
public ExecutorService getQueueForQueryLocalDB() {
return _queueForQueryLocalDB;
}
/**
* 构造函数
*/
public SalamaDataService() {
initObjs();
}
/**
* 构造函数
* @param config 配置
*/
public SalamaDataService(SalamaDataServiceConfig config) {
initObjs();
loadConfig(config);
}
/*
public SalamaDataService(int queueMaxCountForQueryWebService, int queueMaxCountForQueryLocalDB) {
_queueMaxCountForQueryWebService = queueMaxCountForQueryWebService;
_queueMaxCountForQueryLocalDB = queueMaxCountForQueryLocalDB;
initObjs();
}
public SalamaDataService(SalamaDataServiceConfig config,
int queueMaxCountForQueryWebService, int queueMaxCountForQueryLocalDB) {
_queueMaxCountForQueryWebService = queueMaxCountForQueryWebService;
_queueMaxCountForQueryLocalDB = queueMaxCountForQueryLocalDB;
initObjs();
loadConfig(config);
}
*/
private void initObjs() {
_webService = new WebService();
_resourceDownloadTaskService = new ResourceDownloadTaskService();
_resourceDownloadTaskService.setKeyForNotificationUserObj(
DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT);
_localStorageService = new LocalStorageService();
_queueForQueryLocalDB = ServiceSupportApplication.singleton().createSingleThreadPool();
_queueForQueryWebService = ServiceSupportApplication.singleton().createFixedThreadPool(4);
}
/**
* 装载配置
* @param config 配置
*/
public void loadConfig(SalamaDataServiceConfig config) {
_dbManager = null;
_dbManager = new DBManager(ServiceSupportApplication.singleton(), config.getDbName());
_resourceFileManager = null;
_resourceFileManager = new ResourceFileManager(config.getResourceStorageDirPath());
_webService.setRequestTimeoutSeconds(config.getHttpRequestTimeout());
_webService.setResourceFileManager(_resourceFileManager);
_resourceDownloadTaskService.setResourceFileManager(_resourceFileManager);
}
/**
* 查询数据
* @param queryParam 查询参数
* @return 数据列表
* @throws SqliteUtilException
* @throws IOException
* @throws XmlParseException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws ClassNotFoundException
*/
public List<?> query(DataQueryParam queryParam) throws SqliteUtilException,
IOException, XmlParseException, InvocationTargetException, IllegalAccessException, InstantiationException,
NoSuchMethodException, ClassNotFoundException {
DBDataUtil dbDataUtil = _dbManager.createNewDBDataUtil();
try {
//query
return query(queryParam, dbDataUtil);
} finally {
dbDataUtil.close();
}
}
/**
* 查询数据
* @param queryParam 查询参数
* @param dbDataUtil DBDataUtil
* @return 数据列表
* @throws SqliteUtilException
* @throws IOException
* @throws XmlParseException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws ClassNotFoundException
*/
public List<?> query(DataQueryParam queryParam, DBDataUtil dbDataUtil) throws SqliteUtilException,
IOException, XmlParseException, InvocationTargetException, IllegalAccessException, InstantiationException,
NoSuchMethodException, ClassNotFoundException {
if(queryParam == null) {
return null;
}
//query through web service and sotre the result to localDB
List<?> wsResult = queryWebService(queryParam.getWebService(), queryParam.getLocalStorage(),
dbDataUtil);
if(queryParam.getLocalQuery() == null) {
return wsResult;
}
//query from local db ---
return queryLocalDB(queryParam.getLocalQuery(), dbDataUtil);
}
/**
* 查询WebService
* @param webServiceParam WebService参数
* @param localStorageParam 本地存储参数
* @return 数据列表
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws XmlParseException
* @throws IOException
* @throws SqliteUtilException
*/
public List<?> queryWebService(WebServiceParam webServiceParam, LocalStorageParam localStorageParam) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
InvocationTargetException, XmlParseException, IOException, SqliteUtilException {
DBDataUtil dbDataUtil = _dbManager.createNewDBDataUtil();
try {
return queryWebService(webServiceParam, localStorageParam, dbDataUtil);
} finally {
dbDataUtil.close();
}
}
/**
* 查询WebService
* @param webServiceParam WebService参数
* @param localStorageParam 本地存储参数
* @param dbDataUtil DBDataUtil
* @return 数据列表
* @throws NoSuchMethodException
* @throws InstantiationException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws XmlParseException
* @throws IOException
* @throws SqliteUtilException
*/
public List<?> queryWebService(WebServiceParam webServiceParam, LocalStorageParam localStorageParam,
DBDataUtil dbDataUtil) throws NoSuchMethodException, InstantiationException, IllegalAccessException,
InvocationTargetException, XmlParseException, IOException, SqliteUtilException {
if(webServiceParam == null) {
return null;
}
boolean isPost = true;
if("GET".equalsIgnoreCase(webServiceParam.getMethod())) {
isPost = false;
}
String wsResult = _webService.doBasic(webServiceParam.getUrl(), isPost,
webServiceParam.getParamNames(), webServiceParam.getParamValues());
//parse xml result to object
List<?> wsResultObj = (List<?>) XmlDeserializer.stringToObject(wsResult, List.class,
ServiceSupportApplication.singleton());
//save data to local db ---
if(localStorageParam != null
&& localStorageParam.getTableName() != null
&& localStorageParam.getTableName().length() > 0) {
//store data into local db
saveToLocalDB(localStorageParam, wsResultObj, dbDataUtil);
}
return wsResultObj;
}
/**
* 保存数据至本地数据库
* @param localStorageParam 本地存储参数
* @param datas 数据列表
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws SqliteUtilException
*/
public void saveToLocalDB(LocalStorageParam localStorageParam, List<?> datas)
throws InvocationTargetException, IllegalAccessException, SqliteUtilException {
DBDataUtil dbDataUtil = _dbManager.createNewDBDataUtil();
try {
saveToLocalDB(localStorageParam, datas, dbDataUtil);
} finally {
dbDataUtil.close();
}
}
/**
* 保存数据至本地数据库
* @param localStorageParam 本地存储参数
* @param datas 数据列表
* @param dbDataUtil DBDataUtil
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws SqliteUtilException
*/
public void saveToLocalDB(LocalStorageParam localStorageParam, List<?> datas, DBDataUtil dbDataUtil)
throws InvocationTargetException, IllegalAccessException, SqliteUtilException {
if(datas != null) {
_localStorageService.storeDataToTable(
localStorageParam.getTableName(), datas,
localStorageParam.getExtraIndexNames(),
localStorageParam.getExtraIndexValues(), dbDataUtil);
}
}
/**
* 查询本地数据
* @param localQueryParam 本地查询参数
* @return 数据列表
* @throws SqliteUtilException
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public List<?> queryLocalDB(LocalQueryParam localQueryParam)
throws SqliteUtilException, ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, IllegalAccessException {
DBDataUtil dbDataUtil = _dbManager.createNewDBDataUtil();
try {
return queryLocalDB(localQueryParam, dbDataUtil);
} finally {
dbDataUtil.close();
}
}
/**
* 查询本地数据
* @param localQueryParam 本地查询参数
* @param dbDataUtil DBDataUtil
* @return 数据列表
* @throws SqliteUtilException
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public List<?> queryLocalDB(LocalQueryParam localQueryParam, DBDataUtil dbDataUtil)
throws SqliteUtilException, ClassNotFoundException, NoSuchMethodException,
InvocationTargetException, IllegalAccessException {
if(localQueryParam == null) {
return null;
}
List<?> dataList = null;
if(localQueryParam.getSql() != null && localQueryParam.getSql().length() > 0) {
//get data
Class<?> dataClass = loadClass(localQueryParam.getDataClass());
dataList = dbDataUtil.getSqliteUtil().findDataList(
localQueryParam.getSql(), dataClass);
//download resource file
if(localQueryParam.getResourceNames() != null
&& localQueryParam.getResourceNames().length() > 0
&& _resourceDownloadHandler != null) {
String[] resNameArray = localQueryParam.getResourceNames().split(",");
String resNameTmp = null;
String resIdTmp = null;
Object dataTmp = null;
int i,j;
PropertyDescriptor propertyInfo;
if(resNameArray.length > 0) {
for(j = 0; j < resNameArray.length; j++) {
resNameTmp = resNameArray[j];
propertyInfo = new PropertyDescriptor(resNameTmp, dataClass);
for(i = 0; i < dataList.size(); i++) {
dataTmp = dataList.get(i);
resIdTmp = (String) propertyInfo.getReadMethod().invoke(dataTmp);
if(resIdTmp != null && resIdTmp.length() > 0) {
_resourceDownloadTaskService.addDownloadTaskWithResId(
resIdTmp, localQueryParam.getResourceDownloadNotification());
}
}
}
}
}
}
return dataList;
}
/**
* 查询数据(异步-通知模式)
* @param queryParam 查询参数
* @param notification 通知名
*/
public void queryAsync(DataQueryParam queryParam, String notification) {
final DataQueryParam queryParamTmp = queryParam;
final String queryNotificationTmp = notification;
_queueForQueryWebService.execute(new Runnable() {
@Override
public void run() {
try {
List<?> result = query(queryParamTmp);
ServiceSupportApplication.singleton().sendWrappedLocalBroadcast(
queryNotificationTmp, result,
DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT);
} catch (Exception e) {
Log.e("SalamaDataService", "queryWebServiceAsync()", e);
}
}
});
}
/**
* 查询WebService(异步-通知模式)
* @param webServiceParam WebService参数
* @param localStorageParam 本地存储参数
* @param notification 通知名
*/
public void queryWebServiceAsync(WebServiceParam webServiceParam, LocalStorageParam localStorageParam,
String notification) {
final WebServiceParam webServiceParamTmp = webServiceParam;
final LocalStorageParam localStorageParamTmp = localStorageParam;
final String queryNotificationTmp = notification;
_queueForQueryWebService.execute(new Runnable() {
@Override
public void run() {
try {
List<?> result = queryWebService(webServiceParamTmp, localStorageParamTmp);
ServiceSupportApplication.singleton().sendWrappedLocalBroadcast(
queryNotificationTmp, result,
DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT);
} catch (Exception e) {
Log.e("SalamaDataService", "queryWebServiceAsync()", e);
}
}
});
}
/**
* 保存数据至本地数据库(异步-通知模式)
* @param localStorageParam 本地存储参数
* @param datas 数据列表
* @param notification 通知名
*/
public void saveToLocalDBAsync(LocalStorageParam localStorageParam, final List<?> datas, String notification) {
final LocalStorageParam localStorageParamTmp = localStorageParam;
final String queryNotificationTmp = notification;
_queueForQueryLocalDB.execute(new Runnable() {
@Override
public void run() {
try {
saveToLocalDB(localStorageParamTmp, datas);
ServiceSupportApplication.singleton().sendWrappedLocalBroadcast(
queryNotificationTmp, null,
DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT);
} catch (Exception e) {
Log.e("SalamaDataService", "saveToLocalDBAsync()", e);
}
}
});
}
/**
* 查询本地数据(异步-通知模式)
* @param localQueryParam 本地查询参数
* @param notification 通知名
*/
public void queryLocalDBAsync(LocalQueryParam localQueryParam, String notification) {
final LocalQueryParam localQueryParamTmp = localQueryParam;
final String queryNotificationTmp = notification;
_queueForQueryLocalDB.execute(new Runnable() {
@Override
public void run() {
List<?> result = null;
try {
DBDataUtil dbDataUtil = _dbManager.createNewDBDataUtil();
try {
result = queryLocalDB(localQueryParamTmp, dbDataUtil);
} finally {
dbDataUtil.close();
dbDataUtil = null;
}
ServiceSupportApplication.singleton().sendWrappedLocalBroadcast(
queryNotificationTmp, result,
DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT);
} catch (Exception e) {
Log.e("SalamaDataService", "queryLocalDBAsync()", e);
}
}
});
}
/**
* 发送通知
* @param notification 通知名
* @param result 数据
*/
public void postNotification(String notification, Object result) {
ServiceSupportApplication.singleton().sendWrappedLocalBroadcast(
notification, result,
DATA_SERVICE_NOTIFICATION_USER_INFO_RESULT);
}
private Class<?> loadClass(String className) throws ClassNotFoundException {
return ServiceSupportApplication.singleton().findClass(className);
}
}