From 7f532b126d4b60f35c0cabb6eb6ea2af9370026a Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 24 Sep 2009 14:40:13 +0000 Subject: [PATCH] PropertyOverrideConfigurer's "ignoreInvalidKeys" ignores invalid property names as well (SPR-5792) git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1987 50f2f4bb-b051-0410-bef5-90022cba6387 --- .../springframework/beans/BeanWrapperImpl.java | 15 +++++++++++---- .../org/springframework/beans/PropertyValue.java | 12 ++++++++++++ .../config/PropertyOverrideConfigurer.java | 15 +++++++++------ .../config/PropertyResourceConfigurerTests.java | 7 +++++-- 4 files changed, 37 insertions(+), 12 deletions(-) diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java index c3f287e2dbd..09e1941c93e 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java @@ -867,10 +867,17 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) { pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName); if (pd == null || pd.getWriteMethod() == null) { - PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass()); - throw new NotWritablePropertyException( - getRootClass(), this.nestedPath + propertyName, - matches.buildErrorMessage(), matches.getPossibleMatches()); + if (pv.isOptional()) { + logger.debug("Ignoring optional value for property '" + actualName + + "' - property not found on bean class [" + getRootClass().getName() + "]"); + return; + } + else { + PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass()); + throw new NotWritablePropertyException( + getRootClass(), this.nestedPath + propertyName, + matches.buildErrorMessage(), matches.getPossibleMatches()); + } } pv.getOriginalPropertyValue().resolvedDescriptor = pd; } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java b/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java index 18bc05a2a1b..abc9c666629 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/PropertyValue.java @@ -47,6 +47,8 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri private Object source; + private boolean optional = false; + private boolean converted = false; private Object convertedValue; @@ -80,6 +82,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri this.name = original.getName(); this.value = original.getValue(); this.source = original.getSource(); + this.optional = original.isOptional(); this.converted = original.converted; this.convertedValue = original.convertedValue; this.conversionNecessary = original.conversionNecessary; @@ -99,6 +102,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri this.name = original.getName(); this.value = newValue; this.source = original; + this.optional = original.isOptional(); this.conversionNecessary = original.conversionNecessary; this.resolvedTokens = original.resolvedTokens; this.resolvedDescriptor = original.resolvedDescriptor; @@ -136,6 +140,14 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri return original; } + public void setOptional(boolean optional) { + this.optional = optional; + } + + public boolean isOptional() { + return this.optional; + } + /** * Return whether this holder contains a converted value already (true), * or whether the value still needs to be converted (false). diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java index f937b646d3c..7d2125c66cb 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import java.util.Properties; import java.util.Set; import org.springframework.beans.BeansException; +import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.BeanInitializationException; /** @@ -84,9 +85,9 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { /** * Set whether to ignore invalid keys. Default is "false". - *

If you ignore invalid keys, keys that do not follow the - * 'beanName.property' format will just be logged as warning. - * This allows to have arbitrary other keys in a properties file. + *

If you ignore invalid keys, keys that do not follow the 'beanName.property' format + * (or refer to invalid bean names or properties) will just be logged at debug level. + * This allows one to have arbitrary other keys in a properties file. */ public void setIgnoreInvalidKeys(boolean ignoreInvalidKeys) { this.ignoreInvalidKeys = ignoreInvalidKeys; @@ -138,13 +139,15 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { * Apply the given property value to the corresponding bean. */ protected void applyPropertyValue( - ConfigurableListableBeanFactory factory, String beanName, String property, String value) { + ConfigurableListableBeanFactory factory, String beanName, String property, String value) { BeanDefinition bd = factory.getBeanDefinition(beanName); while (bd.getOriginatingBeanDefinition() != null) { bd = bd.getOriginatingBeanDefinition(); } - bd.getPropertyValues().addPropertyValue(property, value); + PropertyValue pv = new PropertyValue(property, value); + pv.setOptional(this.ignoreInvalidKeys); + bd.getPropertyValues().addPropertyValue(pv); } diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java index a4370ed96d4..77ab1e039a6 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/factory/config/PropertyResourceConfigurerTests.java @@ -25,7 +25,6 @@ import java.util.prefs.Preferences; import static org.junit.Assert.*; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import test.beans.IndexedTestBean; import test.beans.TestBean; @@ -281,8 +280,11 @@ public final class PropertyResourceConfigurerTests { Properties props = new Properties(); props.setProperty("argh", "hgra"); props.setProperty("tb2.name", "test"); + props.setProperty("tb2.nam", "test"); + props.setProperty("tb3.name", "test"); poc.setProperties(props); poc.postProcessBeanFactory(factory); + assertEquals("test", factory.getBean("tb2", TestBean.class).getName()); } { PropertyOverrideConfigurer poc = new PropertyOverrideConfigurer(); @@ -294,7 +296,8 @@ public final class PropertyResourceConfigurerTests { poc.setOrder(0); // won't actually do anything since we're not processing through an app ctx try { poc.postProcessBeanFactory(factory); - } catch (BeanInitializationException ex) { + } + catch (BeanInitializationException ex) { // prove that the processor chokes on the invalid key assertTrue(ex.getMessage().toLowerCase().contains("argh")); }