package com.dianping.pigeon.remoting.provider.config.spring;
import com.dianping.pigeon.config.ConfigManager;
import com.dianping.pigeon.config.ConfigManagerLoader;
import com.dianping.pigeon.remoting.provider.config.PoolConfigFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* Created by chenchongze on 16/10/15.
*/
public class PoolBeanDefinitionParser implements BeanDefinitionParser {
/** Default placeholder prefix: "${" */
public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
/** Default placeholder suffix: "}" */
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
private final Class<?> beanClass;
private final boolean required;
private static ConfigManager configManager = ConfigManagerLoader.getConfigManager();
public PoolBeanDefinitionParser(Class<?> beanClass, boolean required) {
this.beanClass = beanClass;
this.required = required;
}
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
return parse(element, parserContext, beanClass, required);
}
private BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {
RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setLazyInit(false);
beanDefinition.setBeanClass(PoolBean.class);
MutablePropertyValues properties = beanDefinition.getPropertyValues();
String id = element.getAttribute("id");
properties.addPropertyValue("poolName", id);
Integer corePoolSize = Integer.parseInt(resolveReference(element, "corePoolSize"));
properties.addPropertyValue("corePoolSize", corePoolSize);
String value = element.getAttribute("corePoolSize");
if (value.startsWith(DEFAULT_PLACEHOLDER_PREFIX) && value.endsWith(DEFAULT_PLACEHOLDER_SUFFIX)) {
PoolConfigFactory.getCoreSizeKeys().put(id, value.substring(2, value.length() - 1));
}
Integer maxPoolSize = Integer.parseInt(resolveReference(element, "maxPoolSize"));
properties.addPropertyValue("maxPoolSize", maxPoolSize);
value = element.getAttribute("maxPoolSize");
if (value.startsWith(DEFAULT_PLACEHOLDER_PREFIX) && value.endsWith(DEFAULT_PLACEHOLDER_SUFFIX)) {
PoolConfigFactory.getMaxSizeKeys().put(id, value.substring(2, value.length() - 1));
}
Integer workQueueSize = Integer.parseInt(resolveReference(element, "workQueueSize"));
properties.addPropertyValue("workQueueSize", workQueueSize);
value = element.getAttribute("workQueueSize");
if (value.startsWith(DEFAULT_PLACEHOLDER_PREFIX) && value.endsWith(DEFAULT_PLACEHOLDER_SUFFIX)) {
PoolConfigFactory.getQueueSizeKeys().put(id, value.substring(2, value.length() - 1));
}
if (corePoolSize < 0 ||
maxPoolSize <= 0 ||
maxPoolSize < corePoolSize ||
workQueueSize <= 0)
throw new IllegalArgumentException("please check pool config: " + id);
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
return beanDefinition;
}
private static String resolveReference(Element element, String attribute) {
String value = element.getAttribute(attribute);
if (value.startsWith(DEFAULT_PLACEHOLDER_PREFIX) && value.endsWith(DEFAULT_PLACEHOLDER_SUFFIX)) {
String valueInCache = configManager.getStringValue(value.substring(2, value.length() - 1));
if (valueInCache == null) {
throw new IllegalStateException("undefined config property:" + element.getAttribute(attribute));
} else {
value = valueInCache;
}
}
return value;
}
}