package com.horstmann.violet.web.property;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Locale;
import java.util.ResourceBundle;
import com.horstmann.violet.framework.injection.resources.ResourceBundleConstant;
import com.horstmann.violet.product.diagram.property.BentStyleChoiceList;
import com.horstmann.violet.product.diagram.abstracts.edge.IEdge;
import com.horstmann.violet.product.diagram.abstracts.node.INode;
import com.horstmann.violet.product.diagram.property.text.MultiLineText;
import com.horstmann.violet.web.workspace.editorpart.EditorPartWidget;
import com.horstmann.violet.workspace.editorpart.IEditorPart;
import com.horstmann.violet.workspace.editorpart.IEditorPartBehaviorManager;
import eu.webtoolkit.jwt.WCompositeWidget;
import eu.webtoolkit.jwt.WContainerWidget;
import eu.webtoolkit.jwt.WVBoxLayout;
public class PropertyEditorWidget extends WCompositeWidget {
private Object bean;
private EditorPartWidget editorPartWidget;
private IEditorPartBehaviorManager behaviorManager;
private boolean isSomethingToEdit = false;
public PropertyEditorWidget(Object bean, IEditorPart editorPart, EditorPartWidget editorPartWidget) {
super();
this.bean = bean;
this.editorPartWidget = editorPartWidget;
this.behaviorManager = editorPart.getBehaviorManager();
populateWidget();
}
public boolean isEditable() {
return this.isSomethingToEdit;
}
private void populateWidget() {
WContainerWidget container = new WContainerWidget();
WVBoxLayout vbox = new WVBoxLayout();
try {
Introspector.flushFromCaches(bean.getClass());
BeanInfo info = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] descriptors = (PropertyDescriptor[]) info.getPropertyDescriptors().clone();
Arrays.sort(descriptors, new Comparator<PropertyDescriptor>() {
public int compare(PropertyDescriptor d1, PropertyDescriptor d2) {
Integer p1 = (Integer) d1.getValue("priority");
Integer p2 = (Integer) d2.getValue("priority");
if (p1 == null && p2 == null)
return 0;
if (p1 == null)
return 1;
if (p2 == null)
return -1;
return p1.intValue() - p2.intValue();
}
});
ResourceBundle rs = ResourceBundle.getBundle(ResourceBundleConstant.NODE_AND_EDGE_STRINGS, Locale.getDefault());
for (int i = 0; i < descriptors.length; i++) {
AbstractPropertyEditorWidget<?> editor = getEditorWidget(bean, descriptors[i]);
if (editor != null) {
vbox.addWidget(editor);
this.isSomethingToEdit = true;
}
}
} catch (IntrospectionException exception) {
exception.printStackTrace();
}
container.setLayout(vbox);
setImplementation(container);
}
private AbstractPropertyEditorWidget<?> getEditorWidget(final Object bean, final PropertyDescriptor descriptor) {
try {
Method getter = descriptor.getReadMethod();
if (getter == null)
return null;
final Method setter = descriptor.getWriteMethod();
if (setter == null)
return null;
Class<?> type = descriptor.getPropertyType();
Class<?> editorClass = descriptor.getPropertyEditorClass();
final AbstractPropertyEditorWidget editorWidget = getEditorWidget(type, bean, descriptor);
if (editorWidget == null)
return null;
Object value = getter.invoke(bean);
editorWidget.setValue(value);
editorWidget.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
try {
Object newValue = editorWidget.getValue();
setter.invoke(bean, newValue);
if (bean instanceof INode) {
behaviorManager.fireWhileEditingNode((INode) bean, evt);
}
if (bean instanceof IEdge) {
behaviorManager.fireWhileEditingEdge((IEdge) bean, evt);
}
editorPartWidget.update();
} catch (IllegalAccessException exception) {
exception.printStackTrace();
} catch (InvocationTargetException exception) {
exception.printStackTrace();
}
}
});
return editorWidget;
} catch (IllegalAccessException exception) {
exception.printStackTrace();
return null;
} catch (InvocationTargetException exception) {
exception.printStackTrace();
return null;
}
}
private AbstractPropertyEditorWidget<?> getEditorWidget(Class<?> type, Object bean, PropertyDescriptor descriptor) {
AbstractPropertyEditorWidget editorWidget = null;
if (MultiLineText.class.equals(type)) {
editorWidget = new MultilineStringEditorWidget(bean, descriptor);
}
if (BentStyleChoiceList.class.equals(type)) {
editorWidget = new BentStyleEditorWidget(bean, descriptor);
}
return editorWidget;
}
}