From: <sha...@us...> - 2011-08-20 13:42:49
|
Revision: 3076 http://dl-learner.svn.sourceforge.net/dl-learner/?rev=3076&view=rev Author: shadowtm Date: 2011-08-20 13:42:42 +0000 (Sat, 20 Aug 2011) Log Message: ----------- Added the ConfigurationBasedPropertyOverrideConfigurer so that we could connect our conf files into the spring initialization process. Modified Paths: -------------- trunk/interfaces/pom.xml Added Paths: ----------- trunk/interfaces/src/main/java/org/dllearner/configuration/ trunk/interfaces/src/main/java/org/dllearner/configuration/spring/ trunk/interfaces/src/main/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurer.java trunk/interfaces/src/test/java/org/dllearner/configuration/ trunk/interfaces/src/test/java/org/dllearner/configuration/spring/ trunk/interfaces/src/test/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurerTest.java trunk/interfaces/src/test/java/org/dllearner/configuration/spring/TestBean.java trunk/interfaces/src/test/resources/org/dllearner/configuration/ trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/ trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configuration-based-property-override-configurer-configuration.xml trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configurationBasedPropertyOverrideConfigurer.conf Modified: trunk/interfaces/pom.xml =================================================================== --- trunk/interfaces/pom.xml 2011-08-20 13:41:54 UTC (rev 3075) +++ trunk/interfaces/pom.xml 2011-08-20 13:42:42 UTC (rev 3076) @@ -21,6 +21,10 @@ <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + </plugin> <plugin> <groupId>org.mortbay.jetty</groupId> @@ -192,10 +196,14 @@ <artifactId>json-simple</artifactId> </dependency> - <dependency> - <groupId>org.springframework</groupId> - <artifactId>spring-context</artifactId> - </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-beans</artifactId> + </dependency> </dependencies> Added: trunk/interfaces/src/main/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurer.java =================================================================== --- trunk/interfaces/src/main/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurer.java (rev 0) +++ trunk/interfaces/src/main/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurer.java 2011-08-20 13:42:42 UTC (rev 3076) @@ -0,0 +1,184 @@ +package org.dllearner.configuration.spring; + +import org.dllearner.configuration.IConfiguration; +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.PropertyOverrideConfigurer; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * User: Chris + * Date: 8/18/11 + * Time: 9:12 PM + * <p/> + * Extending the Custom Property Override Configurer so that we can use our IConfiguration objects + * in conjunction with a Spring Based Configuration. + */ +public class ConfigurationBasedPropertyOverrideConfigurer extends PropertyOverrideConfigurer { + + + private final IConfiguration configuration; + private boolean ignoreInvalidKeys = false; + private List<String> componentKeyPrefixes = new ArrayList<String>(); + + /** + * Primary Constructor. + * + * @param configuration The DL-Learner Configuration object. + * @param ignoreInvalidKeys Consult the PropertyOverrideConfigurer documentation for the usage of this variable. + */ + public ConfigurationBasedPropertyOverrideConfigurer(IConfiguration configuration, boolean ignoreInvalidKeys) { + super(); + this.configuration = configuration; + this.ignoreInvalidKeys = ignoreInvalidKeys; + setIgnoreInvalidKeys(false); + } + + @Override + protected void applyPropertyValue(ConfigurableListableBeanFactory factory, String beanName, String property, String value) { + + BeanDefinition bd = getBeanDefinition(factory, beanName); + + Object obj = buildObject(beanName, property); + + applyPropertyValue(factory, beanName, property, bd, obj); + + + } + + /** + * Build the object represented by beanName.property as it is represented in the configuration. + * + * @param beanName The bean name of the object to build + * @param property The property name of the object to build + * @return The object represented by beanName.property + */ + protected Object buildObject(String beanName, String property) { + StringBuilder objKey = buildObjectKey(beanName, property); + return configuration.getObjectValue(objKey.toString()); + } + + /** + * Get the Bean Definition for a particular bean. + * + * @param factory The factory to get the bean from. + * @param beanName The bean to get. + * @return The bean definition of beanName + */ + protected BeanDefinition getBeanDefinition(ConfigurableListableBeanFactory factory, String beanName) { + BeanDefinition bd = factory.getBeanDefinition(beanName); + while (bd.getOriginatingBeanDefinition() != null) { + bd = bd.getOriginatingBeanDefinition(); + } + return bd; + } + + /** + * Apply obj to a property value. + * @param factory + * @param beanName + * @param property + * @param bd + * @param obj + */ + private void applyPropertyValue(ConfigurableListableBeanFactory factory, String beanName, String property, BeanDefinition bd, Object obj) { + /** Check if Object represents a ReferencedBean */ + String referencedBeanName = getReferencedBeanName(obj); + if (referencedBeanName != null && !referencedBeanName.isEmpty()) { + applyBeanReferencePropertyValue(factory, beanName, property, referencedBeanName); + } else { + /** We have a regular property value */ + applyRegularPropertyValue(property, bd, obj); + } + } + + private void applyRegularPropertyValue(String property, BeanDefinition bd, Object obj) { + PropertyValue pv = new PropertyValue(property, obj); + pv.setOptional(ignoreInvalidKeys); + bd.getPropertyValues().addPropertyValue(pv); + } + + /** + * Apply a bean reference to beanName.property in the given factory. + * + * @param factory The factory to use. + * @param beanName The bean name + * @param property The property name. + * @param referencedBean The referenced bean to set as bean.property in factory. + */ + private void applyBeanReferencePropertyValue(ConfigurableListableBeanFactory factory, String beanName, String property, String referencedBean) { + BeanDefinition bd = getBeanDefinition(factory, beanName); + /** You have to get the bean definition of the referenced bean here - don't try to get the bean itself or you'll get a objects which aren't completely initialized yet */ + Object obj = factory.getBeanDefinition(referencedBean); + bd.getPropertyValues().addPropertyValue(property, obj); + } + + /** + * Build the object key which is just name beanName.property or beanName if property is null. + * @param beanName First part of the key. + * @param property Second part of the key (after the period). + * @return The object key. + */ + private StringBuilder buildObjectKey(String beanName, String property) { + StringBuilder objName = new StringBuilder(); + objName.append(beanName); + if (property != null && !property.isEmpty()) { + objName.append("."); + objName.append(property); + } + return objName; + } + + /** + * Determine if value is a name of a referenced bean. + * <p/> + * This will return the name of the referenced bean if it does. If not, it will return null. + * + * @param object The object to check. + * @return True if we need to do custom loading of this value, false if we can use the parent. + */ + protected String getReferencedBeanName(Object object) { + + String result = null; + + boolean found = false; + + Iterator<String> itr = getComponentKeyPrefixes().iterator(); + + if (object instanceof String) { + String value = (String) object; + while (!found && itr.hasNext()) { + String prefix = itr.next(); + if (value.startsWith(prefix)) { + found = true; + result = value.substring(prefix.length()); + } + } + } + return result; + + } + + /** + * Get the list of prefixes that cause us to do custom loading. + * + * @return The list of prefixes that cause us to do custom loading. + */ + public List<String> getComponentKeyPrefixes() { + return componentKeyPrefixes; + } + + /** + * Set the list of prefixes that cause us to do custom loading. + * + * @param componentKeyPrefixes the list of prefixes that cause us to do custom loading. + */ + public void setComponentKeyPrefixes(List<String> componentKeyPrefixes) { + this.componentKeyPrefixes = componentKeyPrefixes; + } +} Added: trunk/interfaces/src/test/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurerTest.java =================================================================== --- trunk/interfaces/src/test/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurerTest.java (rev 0) +++ trunk/interfaces/src/test/java/org/dllearner/configuration/spring/ConfigurationBasedPropertyOverrideConfigurerTest.java 2011-08-20 13:42:42 UTC (rev 3076) @@ -0,0 +1,87 @@ +package org.dllearner.configuration.spring; + +import junit.framework.Assert; +import org.dllearner.confparser2.ConfParserConfiguration; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +/** + * Created by IntelliJ IDEA. + * User: Chris + * Date: 8/19/11 + * Time: 5:52 PM + * <p/> + * Test For our ConfigurationBasedPropertyOverrideConfigurere. It works as part of a ConfigurableApplicationContext + * so we test it via a context. + */ +public class ConfigurationBasedPropertyOverrideConfigurerTest { + + + private ConfigurableApplicationContext context; + + @Before + public void setUp() throws Exception { + + Resource confFile = new ClassPathResource("/org/dllearner/configuration/spring/configurationBasedPropertyOverrideConfigurer.conf"); + ConfParserConfiguration configuration = new ConfParserConfiguration(confFile); + + ConfigurationBasedPropertyOverrideConfigurer configurer = new ConfigurationBasedPropertyOverrideConfigurer(configuration, false); + configurer.setProperties(configuration.getProperties()); + configurer.getComponentKeyPrefixes().add("component:"); + configurer.getComponentKeyPrefixes().add(":"); + + + String springConfigurationLocation = "/org/dllearner/configuration/spring/configuration-based-property-override-configurer-configuration.xml"; + String[] springConfigurationFiles = new String[1]; + springConfigurationFiles[0] = springConfigurationLocation; + context = new ClassPathXmlApplicationContext(springConfigurationFiles, false); + + context.addBeanFactoryPostProcessor(configurer); + context.refresh(); + + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void testMethods() { + TestBean testBean = context.getBean("testBean", TestBean.class); + + validateFirstBean(testBean); + TestBean secondBean = testBean.getComponent(); + validateSecondBean(secondBean); + validateThirdBean(secondBean.getComponent()); + } + + private void validateThirdBean(TestBean thirdBean) { + Assert.assertEquals(thirdBean.getIntValue(), (Integer) 3); + } + + private void validateFirstBean(TestBean testBean) { + Assert.assertEquals(testBean.getSimpleValue(), "simple value example"); + Assert.assertEquals(testBean.getIntValue(), (Integer) 23); + Assert.assertEquals(testBean.getDoubleValue(), (Double) 78.5); + Assert.assertTrue(testBean.getSetValue().contains("a")); + Assert.assertTrue(testBean.getMapValue().get("a").equals("b")); + Assert.assertTrue(testBean.getComponent() != null); + } + + private void validateSecondBean(TestBean secondBean) { + Assert.assertEquals(secondBean.getSimpleValue(), "second bean example"); + Assert.assertEquals(secondBean.getIntValue(), (Integer) 85); + Assert.assertEquals(secondBean.getDoubleValue(), (Double) 178.5); + Assert.assertTrue(secondBean.getSetValue().contains("e")); + Assert.assertTrue(secondBean.getMapValue().get("f").equals("g")); + Assert.assertTrue(secondBean.getComponent() != null); + } + + +} Added: trunk/interfaces/src/test/java/org/dllearner/configuration/spring/TestBean.java =================================================================== --- trunk/interfaces/src/test/java/org/dllearner/configuration/spring/TestBean.java (rev 0) +++ trunk/interfaces/src/test/java/org/dllearner/configuration/spring/TestBean.java 2011-08-20 13:42:42 UTC (rev 3076) @@ -0,0 +1,88 @@ +package org.dllearner.configuration.spring; + +import java.util.Map; +import java.util.Set; + +/** + * Created by IntelliJ IDEA. + * User: Chris + * Date: 8/19/11 + * Time: 2:55 PM + * + * Test Bean for testing that we can store all the types we need. + */ +public class TestBean { + + private String simpleValue; + private TestBean component; + private Integer intValue; + private Double doubleValue; + private Set setValue; + private Map mapValue; + private Set positiveValues; + private Set negativeValues; + + public String getSimpleValue() { + return simpleValue; + } + + public void setSimpleValue(String simpleValue) { + this.simpleValue = simpleValue; + } + + public TestBean getComponent() { + return component; + } + + public void setComponent(TestBean component) { + this.component = component; + } + + public Integer getIntValue() { + return intValue; + } + + public void setIntValue(Integer intValue) { + this.intValue = intValue; + } + + public Double getDoubleValue() { + return doubleValue; + } + + public void setDoubleValue(Double doubleValue) { + this.doubleValue = doubleValue; + } + + public Set getSetValue() { + return setValue; + } + + public void setSetValue(Set setValue) { + this.setValue = setValue; + } + + public Map getMapValue() { + return mapValue; + } + + public void setMapValue(Map mapValue) { + this.mapValue = mapValue; + } + + public Set getPositiveValues() { + return positiveValues; + } + + public void setPositiveValues(Set positiveValues) { + this.positiveValues = positiveValues; + } + + public Set getNegativeValues() { + return negativeValues; + } + + public void setNegativeValues(Set negativeValues) { + this.negativeValues = negativeValues; + } +} Added: trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configuration-based-property-override-configurer-configuration.xml =================================================================== --- trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configuration-based-property-override-configurer-configuration.xml (rev 0) +++ trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configuration-based-property-override-configurer-configuration.xml 2011-08-20 13:42:42 UTC (rev 3076) @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> + + + <bean name="testBean" class="org.dllearner.configuration.spring.TestBean"/> + + <bean name="secondBean" class="org.dllearner.configuration.spring.TestBean"/> + + <bean name="thirdBean" class="org.dllearner.configuration.spring.TestBean" /> +</beans> \ No newline at end of file Copied: trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configurationBasedPropertyOverrideConfigurer.conf (from rev 3074, trunk/interfaces/src/test/resources/org/dllearner/confparser2/confParserConfigurationTest.conf) =================================================================== --- trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configurationBasedPropertyOverrideConfigurer.conf (rev 0) +++ trunk/interfaces/src/test/resources/org/dllearner/configuration/spring/configurationBasedPropertyOverrideConfigurer.conf 2011-08-20 13:42:42 UTC (rev 3076) @@ -0,0 +1,31 @@ +/** + * A multi-line comment, which is ignored. + */ + +// a single line comment, which is ignored +testBean.simpleValue="simple value example"; // simple value + +testBean.component=component:secondBean; // I wonder whether we even need the component keyword or could just write beanName.property=:test; + +testBean.intValue = 23; // an integer value + +testBean.doubleValue = 78.5; // a double value + +testBean.setValue={"a"}; // a set (list is not implemented, but can be done analogously) + +testBean.mapValue=[("a","b"),("c","d")]; // a map (we can use whatever syntax we like, this is the existing one) + +// Second Bean Definition - to show loading of a referenced bean +secondBean.simpleValue="second bean example"; // simple value +secondBean.component=component:thirdBean; //Another Bean +secondBean.intValue = 85; // an integer value +secondBean.doubleValue = 178.5; // a double value +secondBean.setValue={"e"}; // a set (list is not implemented, but can be done analogously) +secondBean.mapValue=[("f","g"),("c","d")]; // a map (we can use whatever syntax we like, this is the existing one) + +thirdBean.intValue=3; + +// you can also specify positive and negative examples +// (not sure if we really need that) ++"http://example.org/pos1/" +-"http://example.org/neg1/" \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |