/**********************************************************************************
*
* $Id: ReversiblePropertyOverrideConfigurer.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $
*
***********************************************************************************
*
* Copyright (c) 2007, 2008 Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaiproject.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyOverrideConfigurer;
/**
* This is just a version of Spring's PropertyOverrideConfigurer that lets the
* bean name be specified Sakai-style before the property name instead of after.
* (For example "myBean@the.property" instead of "the.property@myBean".)
*/
public class ReversiblePropertyOverrideConfigurer extends PropertyOverrideConfigurer {
//private static Log log = LogFactory.getLog(ReversiblePropertyOverrideConfigurer.class);
private boolean beanNameAtEnd = true;
private String beanNameSeparator; // Private in the superclass, so we need to stash our own copy.
protected void processKey(ConfigurableListableBeanFactory factory, String key, String value)
throws BeansException {
if (this.beanNameAtEnd) {
int separatorIndex = key.indexOf(this.beanNameSeparator);
if (separatorIndex >= 0) {
String beanProperty = key.substring(0, separatorIndex);
String beanName = key.substring(separatorIndex+1);
key = beanName + this.beanNameSeparator + beanProperty;
}
super.processKey(factory, key, value);
}
}
public void setBeanNameSeparator(String beanNameSeparator) {
this.beanNameSeparator = beanNameSeparator;
super.setBeanNameSeparator(beanNameSeparator);
}
/* NOTE: this was meant to fix https://jira.sakaiproject.org/browse/KNL-791
* but it fails because factory.getType will return interfaces sometimes instead of the underlying
* bean class type and this causes the method to fail to identify that the setter exists (since it
* often does not on the interface). Notably, this fails for ehcache Cache beans since spring reports
* the class type as EhCache and not Cache.
*
@Override
protected void applyPropertyValue(ConfigurableListableBeanFactory factory, String beanName, String property, String value) {
// check if the bean has this property which can be set
Class<?> beanClass = factory.getType(beanName);
boolean exists = ReflectionUtils.findField(beanClass, property) != null;
if (!exists) {
String setProperty = "set"+Character.toUpperCase(property.charAt(0))+(property.length() > 1 ? property.substring(1) : "");
Method[] methods = ReflectionUtils.getAllDeclaredMethods(beanClass);
ArrayList<String> l = new ArrayList<String>();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
l.add(method.getName());
if (method.getName().equals(setProperty) && method.getParameterTypes().length == 1) {
exists = true;
break;
}
}
log.warn("KNL-791 ("+property+") to bean ("+beanName+") class ("+beanClass.getCanonicalName()+"): "+l);
}
if (exists) {
log.info("Applying property ("+property+"="+value+") to bean ("+beanName+")");
super.applyPropertyValue(factory, beanName, property, value);
} else {
log.warn("Skipping configured bean property ("+property+"="+value+") for bean ("+beanName+"), no property with name ("+property+") could be found");
}
}
*/
public boolean isBeanNameAtEnd() {
return beanNameAtEnd;
}
public void setBeanNameAtEnd(boolean beanNameAtEnd) {
this.beanNameAtEnd = beanNameAtEnd;
}
}