/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.gui.utils.common.configuration;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertySource2;
/**
* A class adapting a usual Java Bean to the {@link IPropertySource2} interface to be included e.g.
* in the property view of eclipse.
*
* @author Christian Weiss
*/
public abstract class BeanPropertySourceAdapter implements IPropertySource2 {
private final Object bean;
private final BeanInfo beanInfo;
private final Map<String, java.beans.PropertyDescriptor> beanDescriptors = new HashMap<String, java.beans.PropertyDescriptor>();
private final Map<String, IPropertyDescriptor> propertyDescriptors = new HashMap<String, IPropertyDescriptor>();
private final Map<Object, Object> defaultValues = new HashMap<Object, Object>();
private final Map<Object, Boolean> sets = new HashMap<Object, Boolean>();
private IPropertyDescriptor[] propertyDescriptorsArray;
public BeanPropertySourceAdapter(final Object source) {
this.bean = source;
try {
beanInfo = Introspector.getBeanInfo(source.getClass());
} catch (IntrospectionException e) {
throw new RuntimeException(e);
}
parse();
}
protected BeanInfo getBeanInfo() {
return beanInfo;
}
private void parse() {
for (final java.beans.PropertyDescriptor descriptor : beanInfo
.getPropertyDescriptors()) {
final String name = descriptor.getName();
if (!isProperty(descriptor)) {
continue;
}
final Class<?> propertyType = descriptor.getPropertyType();
final IPropertyDescriptor propertyDescriptor;
propertyDescriptor = createPropertyDescriptor(propertyType, name,
descriptor.getDisplayName());
if (propertyDescriptor == null) {
continue;
}
addProperty(descriptor, propertyDescriptor);
}
updatePropertyDescriptors();
}
protected IPropertyDescriptor createPropertyDescriptor(
final Class<?> propertyType, final String name,
final String displayName) {
return PropertyDescriptorFactory.createPropertyDescriptor(propertyType,
name, displayName);
}
protected boolean isProperty(final PropertyDescriptor descriptor) {
if ("class".equals(descriptor.getName()) || descriptor.getPropertyType() == null) {
return false;
}
return true;
}
private void addProperty(final PropertyDescriptor descriptor,
final IPropertyDescriptor propertyDescriptor) {
final String name = descriptor.getName();
addDescriptor(descriptor);
propertyDescriptors.put(name, propertyDescriptor);
updatePropertyDescriptors();
}
protected void removeProperty(final PropertyDescriptor descriptor) {
final String name = descriptor.getName();
removeDescriptor(descriptor);
propertyDescriptors.remove(name);
updatePropertyDescriptors();
}
private void updatePropertyDescriptors() {
this.propertyDescriptorsArray = propertyDescriptors.values().toArray(
new IPropertyDescriptor[0]);
}
protected Object getBean() {
return bean;
}
@Override
public Object getEditableValue() {
return bean.toString();
}
protected boolean isManaged(final Object id) {
final String key = id.toString();
return hasDescriptor(key);
}
private boolean hasDescriptor(final Object id) {
final String key = id.toString();
return beanDescriptors.containsKey(key);
}
private java.beans.PropertyDescriptor getDescriptor(final Object id) {
final String key = id.toString();
return beanDescriptors.get(key);
}
private void addDescriptor(final java.beans.PropertyDescriptor descriptor) {
final String name = descriptor.getName();
beanDescriptors.put(name, descriptor);
}
private void removeDescriptor(final java.beans.PropertyDescriptor descriptor) {
final String name = descriptor.getName();
beanDescriptors.remove(name);
}
@Override
public IPropertyDescriptor[] getPropertyDescriptors() {
return propertyDescriptorsArray;
}
protected IPropertyDescriptor getPropertyDescriptor(
final String propertyName) {
return propertyDescriptors.get(propertyName);
}
@Override
public Object getPropertyValue(Object id) {
final String key = id.toString();
final java.beans.PropertyDescriptor descriptor = getDescriptor(key);
Object result = null;
if (descriptor != null) {
final Object value = getValue(descriptor);
result = value;
}
return result;
}
private Object getValue(final java.beans.PropertyDescriptor descriptor) {
try {
return descriptor.getReadMethod().invoke(bean);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean isPropertyResettable(Object id) {
return true;
}
@Override
public void resetPropertyValue(Object id) {
if (isPropertySet(id)) {
setPropertyValue(id, defaultValues.get(id));
defaultValues.remove(id);
sets.put(id, false);
}
}
@Override
public void setPropertyValue(Object id, Object value) {
final String key = id.toString();
final java.beans.PropertyDescriptor descriptor = getDescriptor(key);
if (descriptor != null) {
final Class<?> propertyType = descriptor.getPropertyType();
Object newValue = value;
if (value != null) {
if (String.class.equals(propertyType)) {
newValue = value.toString();
} else if (Number.class.isAssignableFrom(propertyType)) {
newValue = createValue(propertyType, value.toString());
} else if (Boolean.class.equals(propertyType)
|| boolean.class.equals(propertyType)) {
if (value instanceof Boolean) {
newValue = (Boolean) value;
}
} else if (propertyType.isPrimitive()) {
newValue = createValue(propertyType, value.toString());
}
}
setValue(descriptor, newValue);
if (!isPropertySet(id)) {
defaultValues.put(id, getPropertyValue(id));
sets.put(id, true);
}
}
}
private Object createValue(Class<?> type, Object... args) {
Class<?>[] argsTypes = new Class[args.length];
for (int index = 0; index < args.length; ++index) {
argsTypes[index] = args[index].getClass();
}
Object value;
try {
value = type.getConstructor(argsTypes).newInstance(args);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
return value;
}
private void setValue(final java.beans.PropertyDescriptor descriptor,
final Object value) {
final Method setter = descriptor.getWriteMethod();
try {
setter.invoke(bean, value);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean isPropertySet(final Object id) {
return sets.get(id) != null && sets.get(id);
}
}