package org.openlca.app.editors;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Objects;
import java.util.function.Supplier;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.DateTime;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.openlca.app.components.TextDropComponent;
import org.openlca.app.db.Database;
import org.openlca.app.util.Bean;
import org.openlca.app.util.Colors;
import org.openlca.app.util.Controls;
import org.openlca.app.util.Labels;
import org.openlca.app.viewers.combo.AbstractComboViewer;
import org.openlca.core.database.BaseDao;
import org.openlca.core.model.RootEntity;
import org.openlca.core.model.descriptors.BaseDescriptor;
import org.openlca.core.model.descriptors.Descriptors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DataBinding {
private Logger log = LoggerFactory.getLogger(this.getClass());
private IEditor editor;
public DataBinding() {
}
public DataBinding(IEditor editor) {
this.editor = editor;
}
public <T> void onModel(final Supplier<?> supplier, final String property,
final AbstractComboViewer<T> viewer) {
log.trace("Register data binding - base descriptor - {}", property);
if (supplier == null || property == null || viewer == null)
return;
initValue(supplier.get(), property, viewer);
viewer.addSelectionChangedListener((selection) -> {
setModel(supplier.get(), property, viewer);
});
}
private void setModel(Object bean, String property,
AbstractComboViewer<?> viewer) {
log.trace("Change value {} @ {}", property, bean);
try {
Object newValue = viewer.getSelected();
if (newValue instanceof BaseDescriptor) {
BaseDescriptor descriptor = (BaseDescriptor) newValue;
Class<?> modelClass = descriptor.getModelType().getModelClass();
newValue = new BaseDao<>(modelClass, Database.get())
.getForId(descriptor.getId());
}
Object oldValue = Bean.getValue(bean, property);
if (Objects.equals(newValue, oldValue))
return;
Bean.setValue(bean, property, newValue);
editorChange();
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
public void onModel(final Supplier<?> supplier, final String property,
final TextDropComponent text) {
log.trace("Register data binding - base descriptor - {} ", property);
if (supplier == null || property == null || text == null)
return;
initValue(supplier.get(), property, text);
text.setHandler((descriptor) -> {
setModel(supplier.get(), property, text);
});
}
private void setModel(Object bean, String property, TextDropComponent text) {
log.trace("Change value {} @ {}", property, bean);
try {
BaseDescriptor descriptor = text.getContent();
Object newValue = null;
if (descriptor != null) {
BaseDao<?> dao = new BaseDao<>(descriptor.getModelType()
.getModelClass(), Database.get());
newValue = dao.getForId(descriptor.getId());
}
Object oldValue = Bean.getValue(bean, property);
if (Objects.equals(newValue, oldValue))
return;
Bean.setValue(bean, property, newValue);
editorChange();
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
public void onBoolean(final Supplier<?> supplier, final String property,
final Button button) {
log.trace("Register data binding - boolean - {}", property);
if (supplier == null || property == null || button == null)
return;
initValue(supplier.get(), property, button);
Controls.onSelect(button, (e) -> {
setBooleanValue(supplier.get(), property, button);
editorChange();
});
}
public void onDate(final Supplier<?> supplier, final String property,
final DateTime dateTime) {
log.trace("Register data binding - date - {}", property);
if (supplier == null || property == null || dateTime == null)
return;
initValue(supplier.get(), property, dateTime);
dateTime.addSelectionListener(new SelectionListener() {
@Override
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
@Override
public void widgetSelected(SelectionEvent e) {
setDateValue(supplier.get(), property, dateTime);
editorChange();
}
});
}
public void readOnly(final Object bean, final String property,
final Label label) {
log.trace("Register data binding - string - {} - {}", bean, property);
if (bean == null || property == null || label == null)
return;
initValue(bean, property, label);
}
public void readOnly(final Object bean, final String property,
final CLabel label) {
log.trace("Register data binding - string - {} - {}", bean, property);
if (bean == null || property == null || label == null)
return;
initValue(bean, property, label);
}
public void onString(final Supplier<?> supplier, final String property,
final Text text) {
log.trace("Register data binding - string - {}", property);
if (supplier == null || property == null || text == null)
return;
initValue(supplier.get(), property, text);
text.addModifyListener((e) -> {
setStringValue(supplier.get(), property, text);
editorChange();
});
}
public void onShort(final Supplier<?> supplier, final String property,
final Text text) {
log.trace("Register data binding - short - {}", property);
if (supplier == null || property == null || text == null)
return;
initValue(supplier.get(), property, text);
text.addModifyListener((e) -> {
setShortValue(supplier.get(), property, text);
editorChange();
});
}
public void onInt(final Supplier<?> supplier, final String property,
final Text text) {
log.trace("Register data binding - int - {}", property);
if (supplier == null || property == null || text == null)
return;
initValue(supplier.get(), property, text);
text.addModifyListener((e) -> {
setIntValue(supplier.get(), property, text);
editorChange();
});
}
public void onDouble(final Supplier<?> supplier, final String property,
final Text text) {
log.trace("Register data binding - double - {}", property);
if (supplier == null || property == null || text == null)
return;
initValue(supplier.get(), property, text);
text.addModifyListener((e) -> {
setDoubleValue(supplier.get(), property, text);
editorChange();
});
}
private void initValue(Object bean, String property, DateTime dateTime) {
try {
Object val = Bean.getValue(bean, property);
if (val == null)
return;
GregorianCalendar calendar = null;
if (val instanceof Date) {
calendar = new GregorianCalendar();
calendar.setTime((Date) val);
} else if (val instanceof GregorianCalendar)
calendar = (GregorianCalendar) val;
if (calendar != null) {
dateTime.setDay(calendar.get(Calendar.DAY_OF_MONTH));
dateTime.setMonth(calendar.get(Calendar.MONTH));
dateTime.setYear(calendar.get(Calendar.YEAR));
}
} catch (Exception e) {
error("Cannot set text value", e);
}
}
private void initValue(Object bean, String property, Text text) {
if (bean == null)
return;
try {
Object val = Bean.getValue(bean, property);
String value = getValueAsString(val);
text.setText(value);
} catch (Exception e) {
error("Cannot set text value", e);
}
}
private void initValue(Object bean, String property, Label label) {
try {
Object val = Bean.getValue(bean, property);
String value = getValueAsString(val);
label.setText(value);
} catch (Exception e) {
error("Cannot set label value", e);
}
}
private void initValue(Object bean, String property, CLabel label) {
try {
Object val = Bean.getValue(bean, property);
String value = getValueAsString(val);
label.setText(value);
} catch (Exception e) {
error("Cannot set label value", e);
}
}
private String getValueAsString(Object val) {
if (val == null)
return "";
if (val.getClass().isEnum())
return Labels.getEnumText(val);
else if (val instanceof RootEntity)
return ((RootEntity) val).getName();
else if (val instanceof BaseDescriptor)
return ((BaseDescriptor) val).getName();
else if (val instanceof Date)
return DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT).format((Date) val);
else if (val instanceof GregorianCalendar)
return DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT).format(
((GregorianCalendar) val).getTime());
else
return val.toString();
}
private void initValue(Object bean, String property, Button button) {
try {
Object val = Bean.getValue(bean, property);
if (val != null)
if (val instanceof Boolean)
button.setSelection((Boolean) val);
} catch (Exception e) {
error("Cannot set check state", e);
}
}
@SuppressWarnings("unchecked")
private <T> void initValue(Object bean, String property,
AbstractComboViewer<T> viewer) {
try {
Object val = Bean.getValue(bean, property);
if (val == null)
return;
if (BaseDescriptor.class.isAssignableFrom(viewer.getType())
&& !BaseDescriptor.class.isAssignableFrom(val.getClass())) {
val = Descriptors.toDescriptor((RootEntity) val);
}
viewer.select((T) val);
} catch (Exception e) {
error("Cannot set text value", e);
}
}
private void initValue(Object bean, String property, TextDropComponent text) {
try {
Object val = Bean.getValue(bean, property);
if (val instanceof RootEntity) {
BaseDescriptor descriptor = Descriptors
.toDescriptor((RootEntity) val);
text.setContent(descriptor);
}
} catch (Exception e) {
error("Cannot set text value", e);
}
}
private void setDateValue(Object bean, String property, DateTime dateTime) {
log.trace("Change value {} @ {}", property, bean);
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(Calendar.DAY_OF_MONTH, dateTime.getDay());
calendar.set(Calendar.YEAR, dateTime.getYear());
calendar.set(Calendar.MONTH, dateTime.getMonth());
try {
if (Bean.getType(bean, property) == Date.class)
Bean.setValue(bean, property, calendar.getTime());
else if (Bean.getType(bean, property) == GregorianCalendar.class)
Bean.setValue(bean, property, calendar);
else
log.error("Cannot set bean value");
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
private void setStringValue(Object bean, String property, Text text) {
log.trace("Change value {} @ {}", property, bean);
String val = text.getText();
try {
Bean.setValue(bean, property, val);
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
private void setBooleanValue(Object bean, String property, Button button) {
log.trace("Change value {} @ {}", property, bean);
boolean val = button.getSelection();
try {
Bean.setValue(bean, property, val);
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
private void setShortValue(Object bean, String property, Text text) {
log.trace("Change value {} @ {}", property, bean);
String stringVal = text.getText();
try {
Short s = Short.parseShort(stringVal);
Bean.setValue(bean, property, s);
text.setToolTipText(null);
text.setBackground(Colors.white());
} catch (NumberFormatException e) {
text.setToolTipText("" + stringVal + " is not a valid number");
text.setBackground(Colors.errorColor());
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
private void setIntValue(Object bean, String property, Text text) {
log.trace("Change value {} @ {}", property, bean);
String stringVal = text.getText();
try {
Integer s = Integer.parseInt(stringVal);
Bean.setValue(bean, property, s);
text.setToolTipText(null);
text.setBackground(Colors.white());
} catch (NumberFormatException e) {
text.setToolTipText("" + stringVal + " is not a valid number");
text.setBackground(Colors.errorColor());
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
private void setDoubleValue(Object bean, String property, Text text) {
log.trace("Change value {} @ {}", property, bean);
String stringVal = text.getText();
try {
Double d = Double.parseDouble(stringVal);
Bean.setValue(bean, property, d);
text.setToolTipText(null);
text.setBackground(Colors.white());
} catch (NumberFormatException e) {
text.setToolTipText("" + stringVal + " is not a valid number");
text.setBackground(Colors.errorColor());
} catch (Exception e) {
error("Cannot set bean value", e);
}
}
private void error(String message, Exception e) {
Logger log = LoggerFactory.getLogger(DataBinding.class);
log.error(message, e);
}
private void editorChange() {
if (editor != null)
editor.setDirty(true);
}
}