On 02/28/2012 09:59 PM, Leszek Gawron wrote:
Hello,
I tried to upgrade my cocoon based product to use spring 3.0 new
features. One of those is @Value("${propertyName}") annotation.
This feature works for <context:property-placeholder/> but does not for
cocoon's <configurator:settings/>. This is slightly weird as coocon
configurator theoreticaly bases on PropertyPlaceholderConfigurer.
The issue lies in this code (I used :
cocoon-spring-configurator-1.0.2\src\main\java\org\apache\cocoon\spring\configurator\impl\AbstractSettingsBeanFactoryPostProcessor.java
/**
* @see
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#processProperties(org.springframework.beans.factory.config.ConfigurableListableBeanFactory,
java.util.Properties)
*/
protected void processProperties(ConfigurableListableBeanFactory
beanFactoryToProcess,
Properties props)
throws BeansException {
final BeanDefinitionVisitor visitor = new
CocoonSettingsResolvingBeanDefinitionVisitor(this.settings);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (int i = 0; i < beanNames.length; i++) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(beanNames[i]);
try {
visitor.visitBeanDefinition(bd);
} catch (BeanDefinitionStoreException e) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(),
beanNames[i], e);
}
}
}
protected class CocoonSettingsResolvingBeanDefinitionVisitor extends
BeanDefinitionVisitor {
protected final Properties props;
protected final Set visitedPlaceholders = new HashSet();
public CocoonSettingsResolvingBeanDefinitionVisitor( Settings settings
) {
this.props = new SettingsProperties( settings );
}
protected String resolveStringValue( String strVal ) {
return parseStringValue( strVal,
this.props,
visitedPlaceholders );
}
}
This method completely rewrites the super method (from
PropertyPlaceholderConfigurer) which looks like this:
@Override
protected void processProperties(ConfigurableListableBeanFactory
beanFactoryToProcess, Properties props)
throws BeansException {
StringValueResolver valueResolver = new
PlaceholderResolvingStringValueResolver(props);
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file
locations.
if (!(curName.equals(this.beanName) &&
beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
try {
visitor.visitBeanDefinition(bd);
}
catch (Exception ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(),
curName, ex.getMessage());
}
}
}
// New in Spring 2.5: resolve placeholders in alias target names and
aliases as well.
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as
annotation attributes.
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
As you see new features completely got disabled.
What I actually did was the easiest solution of all:
/**
* @see
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#processProperties(org.springframework.beans.factory.config.ConfigurableListableBeanFactory,
* java.util.Properties)
*/
protected void processProperties( ConfigurableListableBeanFactory
beanFactoryToProcess, Properties props ) throws BeansException {
super.processProperties( beanFactoryToProcess,
new SettingsProperties( this.settings ) );
}
and @Value works as expected. Still I am not aware if the original
solution was a mistake or was thought out for some other use case.
If noone objects I'd like to commit my change.
Go ahead! I will test with our projects in order to give feedback about
unwanted side effects.
--
Reinhard Pötz Founder & Managing Director, Indoqa and Deepsearch
http://www.indoqa.com/people/reinhard-poetz.html
Member of the Apache Software Foundation
Apache Cocoon Committer, PMC member reinh...@apache.org
________________________________________________________________________
Furthermore, I think Oracle has to honor the JSPA agreement.
http://s.apache.org/JCPIsDead http://s.apache.org/tck-trap