package com.revolsys.spring.config; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.MapFactoryBean; import org.springframework.context.ApplicationContext; import com.revolsys.collection.map.AttributeMap; import com.revolsys.collection.map.ThreadSharedProperties; import com.revolsys.spring.TargetBeanFactoryBean; public class AttributesBeanConfigurer extends BeanConfigurrer { public AttributesBeanConfigurer() { this(null, null); } public AttributesBeanConfigurer(final ApplicationContext applicationContext) { super(applicationContext, null); } public AttributesBeanConfigurer(final ApplicationContext applicationContext, final Map<String, Object> attributes) { super(applicationContext, attributes); setOrder(LOWEST_PRECEDENCE - 1000); } @SuppressWarnings("unchecked") protected void addFields(final Map<String, Object> attributes, final ConfigurableListableBeanFactory beanFactory, final BeanDefinition beanDefinition, final String beanName, final String beanClassName) { if (beanClassName != null) { if (beanClassName.equals(AttributeMap.class.getName()) || beanName.endsWith("-AttributeMap")) { processPlaceholderAttributes(beanFactory, beanName, attributes); final Map<String, Object> otherAttributes = (Map<String, Object>)beanFactory .getBean(beanName); processPlaceholderAttributes(beanFactory, otherAttributes); attributes.putAll(otherAttributes); } else if (beanClassName.equals(MapFactoryBean.class.getName())) { final MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); final PropertyValue targetMapClass = propertyValues.getPropertyValue("targetMapClass"); if (targetMapClass != null) { final Object mapClass = targetMapClass.getValue(); if (AttributeMap.class.getName().equals(mapClass)) { processPlaceholderAttributes(beanFactory, beanName, attributes); final Map<String, Object> otherAttributes = (Map<String, Object>)beanFactory .getBean(beanName); processPlaceholderAttributes(beanFactory, otherAttributes); attributes.putAll(otherAttributes); } } } } } @Override public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException { final Map<String, Object> allAttributes = new LinkedHashMap<>(); final Map<String, Object> threadAttributes = ThreadSharedProperties.getProperties(); allAttributes.putAll(threadAttributes); processPlaceholderAttributes(beanFactory, threadAttributes); final Map<String, Object> attributes = getFields(); processPlaceholderAttributes(beanFactory, attributes); for (final Entry<String, Object> entry : attributes.entrySet()) { final String key = entry.getKey(); if (!allAttributes.containsKey(key)) { final Object value = entry.getValue(); allAttributes.put(key, value); } } final String configBeanName = getBeanName(); for (final String beanName : beanFactory.getBeanDefinitionNames()) { // Check that we're not parsing our own bean definition, // to avoid failing on non-resolvable place-holders in properties file // locations. if (!beanName.equals(configBeanName)) { final BeanDefinition bd = beanFactory.getBeanDefinition(beanName); final String beanClassName = bd.getBeanClassName(); if (beanClassName != null) { addFields(allAttributes, beanFactory, bd, beanName, beanClassName); if (beanClassName.equals(TargetBeanFactoryBean.class.getName())) { final MutablePropertyValues propertyValues = bd.getPropertyValues(); final BeanDefinition targetBeanDefinition = (BeanDefinition)propertyValues .getPropertyValue("targetBeanDefinition").getValue(); final String targetBeanClassName = targetBeanDefinition.getBeanClassName(); addFields(allAttributes, beanFactory, targetBeanDefinition, beanName, targetBeanClassName); } } } } processOverrideAttributes(beanFactory, allAttributes); } }