package com.link_intersystems.beans;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
/**
*
* @author rene.link
*
* @param <T>
*/
public class BeanPropertySync<T> implements PropertyChangeListener {
private T targetBean;
private boolean skipMissingPropertiesEnabled;
private ReflectivePropertyChangeListenerBinding sourceBeanPropertyChangeListenerBinding;
public BeanPropertySync(T targetBean) {
this.targetBean = targetBean;
}
protected T getBeanSync() {
return targetBean;
}
public void setSkipMissingPropertiesEnabled(
boolean skipMissingPropertiesEnabled) {
this.skipMissingPropertiesEnabled = skipMissingPropertiesEnabled;
}
public boolean isSkipMissingPropertiesEnabled() {
return skipMissingPropertiesEnabled;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
try {
trySetProperty(evt);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
catchSetPropertyException(e);
}
}
private void trySetProperty(PropertyChangeEvent evt)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
String propertyName = evt.getPropertyName();
PropertyDescriptor propertyDescriptor = PropertyUtils
.getPropertyDescriptor(targetBean, propertyName);
if (propertyDescriptor == null) {
if (!skipMissingPropertiesEnabled) {
String msg = MessageFormat
.format("Can't find write method for property '{0}' of bean '{1}'",
propertyName, targetBean.getClass());
throw new RuntimeException(msg);
}
} else {
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(targetBean, evt.getNewValue());
}
}
private void catchSetPropertyException(Exception e) {
throw new RuntimeException("Unable to sync bean", e);
}
public void setSynchronization(T sourceBean) {
if (this.sourceBeanPropertyChangeListenerBinding != null) {
sourceBeanPropertyChangeListenerBinding
.removePropertyChangeListener(this);
}
if (sourceBean == null) {
sourceBeanPropertyChangeListenerBinding = null;
} else {
sourceBeanPropertyChangeListenerBinding = new ReflectivePropertyChangeListenerBinding(
sourceBean);
applyBeanProperties(sourceBean);
sourceBeanPropertyChangeListenerBinding
.addPropertyChangeListener(this);
}
}
protected void applyBeanProperties(T baseBean) {
try {
BeanUtils.copyProperties(this, baseBean);
} catch (Exception e) {
catchSetPropertyException(e);
}
}
}