001package org.dllearner.configuration.spring; 002 003import java.util.Collection; 004 005import org.dllearner.configuration.IConfiguration; 006import org.dllearner.configuration.IConfigurationProperty; 007import org.springframework.beans.BeansException; 008import org.springframework.beans.factory.config.BeanDefinition; 009import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 010import org.springframework.beans.factory.config.RuntimeBeanReference; 011import org.springframework.beans.factory.support.BeanDefinitionBuilder; 012import org.springframework.beans.factory.support.BeanDefinitionRegistry; 013import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; 014import org.springframework.beans.factory.support.ManagedSet; 015 016/** 017 * Created by IntelliJ IDEA. 018 * User: Chris 019 * Date: 8/22/11 020 * Time: 6:38 AM 021 * <p/> 022 * This class is used to insert BeanDefinitions that are declared in the configuration file that 023 * do not exist in the existing registry (ie. they aren't declared in the spring XML file). 024 */ 025public class ConfigurationBasedBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { 026 027 private final IConfiguration configuration; 028 029 public ConfigurationBasedBeanDefinitionRegistryPostProcessor(IConfiguration configuration) { 030 this.configuration = configuration; 031 } 032 033 /** 034 * Ensure that BeanDefinitions exist for all referenced beans in the configuration. 035 * 036 * @param registry The Bean registry to use. 037 * @throws BeansException 038 */ 039 @Override 040 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 041 final Collection<String> beanNames = configuration.getBeanNames(); 042 043 for (String beanName : beanNames) { 044 if (!registry.containsBeanDefinition(beanName)) { 045 Class beanClass = configuration.getClass(beanName); 046 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass); 047 048 BeanDefinition definition = builder.getBeanDefinition(); 049 050 registry.registerBeanDefinition(beanName, definition); 051 } 052 } 053 054 } 055 056 @Override 057 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 058 059 final Collection<String> beanNames = configuration.getBeanNames(); 060 061 062 for (String beanName : beanNames) { 063 064 BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); 065 066 Collection<IConfigurationProperty> properties = configuration.getConfigurationProperties(beanName); 067 068 for (IConfigurationProperty property : properties) { 069 070 Object value = property.getValue(); 071 //Process Single Bean References 072 if (property.isBeanReference()) { 073 value = new RuntimeBeanReference((String)property.getValue()); 074 } 075 076 //Process collections of bean references 077 if(property.isBeanReferenceCollection()){ 078 Collection<RuntimeBeanReference> beanReferences = new ManagedSet<>(); 079 Collection<String> referencedBeanNames = (Collection<String>)property.getValue(); 080 for (String referencedBeanName : referencedBeanNames) { 081 beanReferences.add(new RuntimeBeanReference(referencedBeanName)); 082 } 083 value = beanReferences; 084 } 085 086 addBaseDirectoryIfNeeded(beanDefinition); 087 088 beanDefinition.getPropertyValues().add(property.getName(), value); 089 } 090 } 091 } 092 093 /** 094 * Add Base Directory Value to Beans which need it. 095 * 096 * @param beanDefinition The current Bean Definition 097 */ 098 private void addBaseDirectoryIfNeeded(BeanDefinition beanDefinition) { 099 Class beanClass = null; 100 try { 101 beanClass = Class.forName(beanDefinition.getBeanClassName()); 102 } catch (ClassNotFoundException e) { 103 throw new RuntimeException("Can't find class " + beanDefinition.getBeanClassName()); 104 } 105 /** Add Base Directory */ 106 try { 107 beanClass.getMethod("setBaseDir", String.class); 108 beanDefinition.getPropertyValues().add("baseDir", configuration.getBaseDir()); 109 } catch (NoSuchMethodException e) { 110 // ignore 111 } catch (SecurityException e) { 112 // TODO Auto-generated catch block 113 e.printStackTrace(); 114 } 115 } 116 117}