
org.tinygroup.tinydb.ConfigurationBuilder Maven / Gradle / Ivy
The newest version!
/**
* Copyright (c) 1997-2013, www.tinygroup.org ([email protected]).
*
* Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html
*
* 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 org.tinygroup.tinydb;
import com.thoughtworks.xstream.XStream;
import org.springframework.jdbc.core.JdbcTemplate;
import org.tinygroup.commons.io.StreamUtil;
import org.tinygroup.commons.tools.CollectionUtil;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.database.config.dialectfunction.DialectFunctions;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;
import org.tinygroup.tinydb.config.BeanQueryConfigs;
import org.tinygroup.tinydb.convert.TableConfigLoad;
import org.tinygroup.tinydb.dialect.Dialect;
import org.tinygroup.tinydb.dialect.impl.AbstractDialect;
import org.tinygroup.tinydb.exception.TinyDbRuntimeException;
import org.tinygroup.tinydb.relation.Relations;
import org.tinygroup.tinydb.util.TinyDBUtil;
import org.tinygroup.vfs.FileObject;
import org.tinygroup.vfs.VFS;
import org.tinygroup.xmlparser.node.XmlNode;
import org.tinygroup.xmlparser.parser.XmlStringParser;
import org.tinygroup.xstream.XStreamFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ConfigurationBuilder {
private static final String DIALECT_FUNCTION = "dialect-function";
private static final String DIALECT_FUNCTIONS = "dialect-functions";
private static final String CONVERT_TYPE = "convert-type";
private static final String RELATION = "relation";
private static final String RELATIONS = "relations";
private static final String DIALECT = "dialect";
private static final String TABLE_LOADS = "table-loads";
private static final String DATA_SOURCE_ID = "id";
private static final String PROPERTY = "property";
private static final String TYPE = "type";
private static final String DEFAULT = "default";
private static final String DATASOURCES = "dataSources";
private static final String QUERY_CONFIGS = "bean-query-configs";
private static final String QUERY_CONFIG = "bean-query-config";
private boolean parsed;
private XmlNode xmlNode;
private String dataSource;
private final Configuration configuration;
private Logger logger = LoggerFactory.getLogger(ConfigurationBuilder.class);
public ConfigurationBuilder(InputStream inputStream) {
this(inputStream, null);
}
public ConfigurationBuilder(InputStream inputStream, String dataSource) {
try {
XmlStringParser parser = new XmlStringParser();
String configXml = StreamUtil.readText(inputStream, "UTF-8", true);
xmlNode = parser.parse(configXml).getRoot();
} catch (IOException e) {
logger.errorMessage("载入数据库配置信息时出现异常,错误原因:{}!", e, e.getMessage());
}
this.parsed = false;
this.dataSource = dataSource;
this.configuration = new Configuration();
}
public ConfigurationBuilder(Reader reader) {
this(reader, null);
}
public ConfigurationBuilder(Reader reader, String dataSource) {
try {
XmlStringParser parser = new XmlStringParser();
String configXml = StreamUtil.readText(reader, true);
xmlNode = parser.parse(configXml).getRoot();
} catch (IOException e) {
logger.errorMessage("载入数据库配置信息时出现异常,错误原因:{}!", e, e.getMessage());
}
this.parsed = false;
this.dataSource = dataSource;
this.configuration = new Configuration();
}
public ConfigurationBuilder(XmlNode xmlNode, String dataSource) {
this.xmlNode = xmlNode;
this.parsed = false;
this.dataSource = dataSource;
this.configuration = new Configuration();
}
public Configuration parser() {
if (parsed) {
throw new TinyDbRuntimeException(
"Each ConfigurationBuilder can only be used once.");
}
parsed = true;
parserOperator();
parserDataSources();
parserTableLoad();
parserDialect();
parserRelations();
parserDialectFunctions();
parserBeanQueryConfig();
return configuration;
}
private void parserBeanQueryConfig() {
XmlNode queryConfigsNode = xmlNode.getSubNode(QUERY_CONFIGS);
if (queryConfigsNode == null) {
return;
}
List queryConfigNodes = queryConfigsNode
.getSubNodes(QUERY_CONFIG);
if (!CollectionUtil.isEmpty(queryConfigNodes)) {
for (XmlNode queryConfigNode : queryConfigNodes) {
String url = queryConfigNode.getAttribute("url");
String resource = queryConfigNode.getAttribute("resource");
XStream stream = XStreamFactory.getXStream();
stream.processAnnotations(BeanQueryConfigs.class);
if (url != null && resource == null) {
FileObject fileObject = VFS.resolveFile(url);
BeanQueryConfigs queryConfigs = (BeanQueryConfigs) stream
.fromXML(fileObject.getInputStream());
configuration.addBeanQueryConfigs(queryConfigs);
} else if (url == null && resource != null) {
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream(resource);
BeanQueryConfigs queryConfigs = (BeanQueryConfigs) stream
.fromXML(inputStream);
configuration.addBeanQueryConfigs(queryConfigs);
} else {
throw new TinyDbRuntimeException(
"bean-query-config元素的属性只能是url或者是resource");
}
}
}
}
private void parserDialectFunctions() {
XmlNode functionsNode = xmlNode.getSubNode(DIALECT_FUNCTIONS);
if (functionsNode == null) {
return;
}
List functionNodes = functionsNode
.getSubNodes(DIALECT_FUNCTION);
if (!CollectionUtil.isEmpty(functionNodes)) {
for (XmlNode node : functionNodes) {
String url = node.getAttribute("url");
String resource = node.getAttribute("resource");
XStream stream = XStreamFactory.getXStream();
stream.processAnnotations(DialectFunctions.class);
if (url != null && resource == null) {
FileObject fileObject = VFS.resolveFile(url);
DialectFunctions functions = (DialectFunctions) stream
.fromXML(fileObject.getInputStream());
configuration.addDialectFunctions(functions);
} else if (url == null && resource != null) {
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream(resource);
DialectFunctions functions = (DialectFunctions) stream
.fromXML(inputStream);
configuration.addDialectFunctions(functions);
} else {
throw new TinyDbRuntimeException(
"relation元素的属性只能是url或者是resource");
}
}
}
}
private void parserRelations() {
XmlNode relationsNode = xmlNode.getSubNode(RELATIONS);
if (relationsNode == null) {
return;
}
List relationNodes = relationsNode.getSubNodes(RELATION);
if (!CollectionUtil.isEmpty(relationNodes)) {
for (XmlNode relationNode : relationNodes) {
String url = relationNode.getAttribute("url");
String resource = relationNode.getAttribute("resource");
XStream stream = XStreamFactory.getXStream();
stream.processAnnotations(Relations.class);
if (url != null && resource == null) {
FileObject fileObject = VFS.resolveFile(url);
Relations relations = (Relations) stream.fromXML(fileObject
.getInputStream());
configuration.addRelationConfigs(relations);
} else if (url == null && resource != null) {
InputStream inputStream = getClass().getClassLoader()
.getResourceAsStream(resource);
Relations relations = (Relations) stream
.fromXML(inputStream);
configuration.addRelationConfigs(relations);
} else {
throw new TinyDbRuntimeException(
"relation元素的属性只能是url或者是resource");
}
}
}
}
private void parserDialect() {
XmlNode dialectNode = xmlNode.getSubNode(DIALECT);
if (dialectNode == null) {
return;
}
String dialectType = dialectNode.getAttribute(TYPE);
Dialect dialect = (Dialect) newInstance(dialectType);
setProperties(dialectNode, dialect);
AbstractDialect abstractDialect = (AbstractDialect) dialect;
abstractDialect.setFunctionProcessor(configuration
.getFunctionProcessor());
abstractDialect.setDataSource(configuration.getUseDataSource());
configuration.setDialect(abstractDialect);
}
private Object newInstance(String type) {
try {
Class clazz = Class.forName(type);
return clazz.newInstance();
} catch (Exception e) {
throw new TinyDbRuntimeException("对象实例化出现异常", e);
}
}
private void parserTableLoad() {
XmlNode loadsNode = xmlNode.getSubNode(TABLE_LOADS);
if (loadsNode == null) {
return;
}
setDefaultSchema(loadsNode);
List loadNodes = loadsNode.getSubNodes("table-load");
if (!CollectionUtil.isEmpty(loadNodes)) {
for (XmlNode node : loadNodes) {
try {
TableConfigLoad load = newTableConfigLoad(node);
setProperties(node, load);
load.loadTable(configuration);
} catch (Exception e) {
logger.errorMessage("解析表配置出现异常", e);
throw new TinyDbRuntimeException("解析表配置出现异常", e);
}
}
}
}
private TableConfigLoad newTableConfigLoad(XmlNode node) throws Exception {
String type = node.getAttribute(TYPE);
TableConfigLoad load = (TableConfigLoad) newInstance(type);
return load;
}
private void setDefaultSchema(XmlNode loadsNode) {
String defaultSchema = loadsNode.getAttribute(DEFAULT);
if (StringUtil.isBlank(defaultSchema)) {
throw new TinyDbRuntimeException("未设置默认的schema");
}
configuration.setDefaultSchema(defaultSchema);
}
private void parserOperator() {
String operatorType = xmlNode.getAttribute(TYPE);
configuration.setOperatorType(operatorType);
String convertType = xmlNode.getAttribute(CONVERT_TYPE);
if (!StringUtil.isBlank(convertType)) {
BeanDbNameConverter converter = (BeanDbNameConverter) newInstance(convertType);
configuration.setConverter(converter);
}
String increase = xmlNode.getAttribute("is-increase");
if (!StringUtil.isBlank(increase)) {
configuration.setIncrease(Boolean.parseBoolean(increase));
}
}
private void parserDataSources() {
XmlNode dataSources = xmlNode.getSubNode(DATASOURCES);
if (dataSources == null) {
return;
}
String defaultDataSource = dataSources.getAttribute(DEFAULT);
if (dataSource == null) {
dataSource = defaultDataSource;
}
if (dataSource == null) {
throw new TinyDbRuntimeException("默认数据源不能为空");
}
configuration.setDefaultDataSource(defaultDataSource);
List nodes = dataSources.getSubNodes("dataSource");
if (!CollectionUtil.isEmpty(nodes)) {
boolean existDefault = false;
for (XmlNode node : nodes) {
if (parserDataSource(node)) {
existDefault = true;
}
}
if (!existDefault) {
throw new TinyDbRuntimeException("默认数据源:" + dataSource + "没有设置");
}
JdbcTemplate template = new JdbcTemplate(
configuration.getUseDataSource());
configuration.setJdbcTemplate(template);
}
}
private boolean parserDataSource(XmlNode node) {
if (node == null) {
return false;
}
boolean isDefault = false;
String type = node.getAttribute(TYPE);
try {
DataSource newDataSource = newDataSourceInstance(type);
String dataSourceId = node.getAttribute(DATA_SOURCE_ID);
setProperties(node, newDataSource);
// DynamicDataSource dynamic=new DynamicDataSource();
// dynamic.setDataSource(newDataSource);
// if(dataSourceId.equals(dataSource)){
// configuration.setUseDataSource(dynamic);
// isDefault=true;
// }
// configuration.putDataSource(type, dynamic);
if (dataSourceId.equals(dataSource)) {
configuration.setUseDataSource(newDataSource);
isDefault = true;
}
configuration.putDataSource(dataSourceId, newDataSource);
} catch (Exception e) {
throw new TinyDbRuntimeException("解析数据源配置出现异常", e);
}
return isDefault;
}
private void setProperties(XmlNode node, Object object) {
Map properties = new HashMap();
List subNodes = node.getSubNodes(PROPERTY);
if (!CollectionUtil.isEmpty(subNodes)) {
for (XmlNode subNode : subNodes) {
properties.put(subNode.getAttribute("name"),
subNode.getAttribute("value"));
}
}
TinyDBUtil.setProperties(object, properties);
}
private DataSource newDataSourceInstance(String type)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
Class dataSourceType = Class.forName(type);
DataSource dataSource = (DataSource) dataSourceType.newInstance();
return dataSource;
}
public Configuration getConfiguration() {
return configuration;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy