io.shardingjdbc.spring.namespace.parser.ShardingDataSourceBeanDefinitionParser Maven / Gradle / Ivy
/*
* Copyright 1999-2015 dangdang.com.
*
* 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 io.shardingjdbc.spring.namespace.parser;
import io.shardingjdbc.core.api.config.ShardingRuleConfiguration;
import io.shardingjdbc.core.api.config.TableRuleConfiguration;
import io.shardingjdbc.spring.datasource.SpringShardingDataSource;
import io.shardingjdbc.spring.namespace.constants.ShardingDataSourceBeanDefinitionParserTag;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Sharding data source parser for spring namespace.
*
* @author caohao
*/
public class ShardingDataSourceBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override
//CHECKSTYLE:OFF
protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext parserContext) {
//CHECKSTYLE:ON
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(SpringShardingDataSource.class);
factory.addConstructorArgValue(parseDataSources(element, parserContext));
factory.addConstructorArgValue(parseShardingRuleConfig(element));
factory.addConstructorArgValue(parseProperties(element, parserContext));
factory.setDestroyMethodName("close");
return factory.getBeanDefinition();
}
private Map parseDataSources(final Element element, final ParserContext parserContext) {
Element shardingRuleElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.SHARDING_RULE_CONFIG_TAG);
List dataSources = Splitter.on(",").trimResults().splitToList(shardingRuleElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.DATA_SOURCE_NAMES_TAG));
Map result = new ManagedMap<>(dataSources.size());
for (String each : dataSources) {
result.put(each, parserContext.getRegistry().getBeanDefinition(each));
}
return result;
}
private BeanDefinition parseShardingRuleConfig(final Element element) {
Element shardingRuleElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.SHARDING_RULE_CONFIG_TAG);
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ShardingRuleConfiguration.class);
parseDefaultDataSource(factory, shardingRuleElement);
parseDefaultDatabaseShardingStrategy(factory, shardingRuleElement);
parseDefaultTableShardingStrategy(factory, shardingRuleElement);
factory.addPropertyValue("tableRuleConfigs", parseTableRulesConfig(shardingRuleElement));
factory.addPropertyValue("bindingTableGroups", parseBindingTablesConfig(shardingRuleElement));
parseKeyGenerator(factory, shardingRuleElement);
return factory.getBeanDefinition();
}
private void parseKeyGenerator(final BeanDefinitionBuilder factory, final Element element) {
String keyGeneratorClass = element.getAttribute(ShardingDataSourceBeanDefinitionParserTag.KEY_GENERATOR_CLASS);
if (!Strings.isNullOrEmpty(keyGeneratorClass)) {
factory.addPropertyValue("defaultKeyGeneratorClass", keyGeneratorClass);
}
}
private void parseDefaultDataSource(final BeanDefinitionBuilder factory, final Element element) {
String defaultDataSource = element.getAttribute(ShardingDataSourceBeanDefinitionParserTag.DEFAULT_DATA_SOURCE_NAME_TAG);
if (!Strings.isNullOrEmpty(defaultDataSource)) {
factory.addPropertyValue("defaultDataSourceName", defaultDataSource);
}
}
private void parseDefaultDatabaseShardingStrategy(final BeanDefinitionBuilder factory, final Element element) {
String defaultDatabaseShardingStrategy = element.getAttribute(ShardingDataSourceBeanDefinitionParserTag.DEFAULT_DATABASE_STRATEGY_REF_ATTRIBUTE);
if (!Strings.isNullOrEmpty(defaultDatabaseShardingStrategy)) {
factory.addPropertyReference("defaultDatabaseShardingStrategyConfig", defaultDatabaseShardingStrategy);
}
}
private void parseDefaultTableShardingStrategy(final BeanDefinitionBuilder factory, final Element element) {
String defaultTableShardingStrategy = element.getAttribute(ShardingDataSourceBeanDefinitionParserTag.DEFAULT_TABLE_STRATEGY_REF_ATTRIBUTE);
if (!Strings.isNullOrEmpty(defaultTableShardingStrategy)) {
factory.addPropertyReference("defaultTableShardingStrategyConfig", defaultTableShardingStrategy);
}
}
private List parseTableRulesConfig(final Element element) {
Element tableRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.TABLE_RULES_TAG);
List tableRuleElements = DomUtils.getChildElementsByTagName(tableRulesElement, ShardingDataSourceBeanDefinitionParserTag.TABLE_RULE_TAG);
List result = new ManagedList<>(tableRuleElements.size());
for (Element each : tableRuleElements) {
result.add(parseTableRuleConfig(each));
}
return result;
}
private BeanDefinition parseTableRuleConfig(final Element tableElement) {
BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(TableRuleConfiguration.class);
factory.addPropertyValue("logicTable", tableElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.LOGIC_TABLE_ATTRIBUTE));
String actualDataNodes = tableElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.ACTUAL_DATA_NODES_ATTRIBUTE);
if (!Strings.isNullOrEmpty(actualDataNodes)) {
factory.addPropertyValue("actualDataNodes", actualDataNodes);
}
String databaseStrategy = tableElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.DATABASE_STRATEGY_REF_ATTRIBUTE);
if (!Strings.isNullOrEmpty(databaseStrategy)) {
factory.addPropertyReference("databaseShardingStrategyConfig", databaseStrategy);
}
String tableStrategy = tableElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.TABLE_STRATEGY_REF_ATTRIBUTE);
if (!Strings.isNullOrEmpty(tableStrategy)) {
factory.addPropertyReference("tableShardingStrategyConfig", tableStrategy);
}
String keyGeneratorColumnName = tableElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.GENERATE_KEY_COLUMN);
if (!Strings.isNullOrEmpty(keyGeneratorColumnName)) {
factory.addPropertyValue("keyGeneratorColumnName", keyGeneratorColumnName);
}
String keyGeneratorClass = tableElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.COLUMN_KEY_GENERATOR_CLASS);
if (!Strings.isNullOrEmpty(keyGeneratorClass)) {
factory.addPropertyValue("keyGeneratorClass", keyGeneratorClass);
}
return factory.getBeanDefinition();
}
private List parseBindingTablesConfig(final Element element) {
Element bindingTableRulesElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.BINDING_TABLE_RULES_TAG);
if (null == bindingTableRulesElement) {
return Collections.emptyList();
}
List bindingTableRuleElements = DomUtils.getChildElementsByTagName(bindingTableRulesElement, ShardingDataSourceBeanDefinitionParserTag.BINDING_TABLE_RULE_TAG);
List result = new LinkedList<>();
for (Element bindingTableRuleElement : bindingTableRuleElements) {
result.add(bindingTableRuleElement.getAttribute(ShardingDataSourceBeanDefinitionParserTag.LOGIC_TABLES_ATTRIBUTE));
}
return result;
}
private Properties parseProperties(final Element element, final ParserContext parserContext) {
Element propsElement = DomUtils.getChildElementByTagName(element, ShardingDataSourceBeanDefinitionParserTag.PROPS_TAG);
return null == propsElement ? new Properties() : parserContext.getDelegate().parsePropsElement(propsElement);
}
}