io.mateu.mdd.vaadin.components.views.ListViewComponent Maven / Gradle / Ivy
The newest version!
package io.mateu.mdd.vaadin.components.views;
import com.byteowls.vaadin.chartjs.ChartJs;
import com.byteowls.vaadin.chartjs.config.DonutChartConfig;
import com.byteowls.vaadin.chartjs.data.Dataset;
import com.byteowls.vaadin.chartjs.data.PieDataset;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.vaadin.data.HasDataProvider;
import com.vaadin.data.ValueProvider;
import com.vaadin.data.provider.ListDataProvider;
import com.vaadin.data.provider.QuerySortOrder;
import com.vaadin.event.ShortcutAction;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.server.Setter;
import com.vaadin.server.UserError;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.shared.ui.BorderStyle;
import com.vaadin.shared.ui.ContentMode;
import com.vaadin.shared.ui.ValueChangeMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.*;
import com.vaadin.ui.Link;
import com.vaadin.ui.components.grid.EditorOpenEvent;
import com.vaadin.ui.components.grid.EditorOpenListener;
import com.vaadin.ui.components.grid.SortOrderProvider;
import com.vaadin.ui.renderers.ButtonRenderer;
import com.vaadin.ui.renderers.ComponentRenderer;
import com.vaadin.ui.renderers.HtmlRenderer;
import com.vaadin.ui.renderers.TextRenderer;
import com.vaadin.ui.themes.ValoTheme;
import elemental.json.JsonValue;
import io.mateu.i18n.Translator;
import io.mateu.mdd.core.app.AbstractAction;
import io.mateu.mdd.core.dataProviders.JPQLListDataProvider;
import io.mateu.mdd.core.interfaces.*;
import io.mateu.mdd.core.ui.MDDUIAccessor;
import io.mateu.mdd.shared.CSS;
import io.mateu.mdd.shared.annotations.*;
import io.mateu.mdd.shared.data.*;
import io.mateu.mdd.shared.interfaces.IResource;
import io.mateu.mdd.shared.interfaces.RpcView;
import io.mateu.mdd.shared.reflection.FieldInterfaced;
import io.mateu.mdd.vaadin.components.fieldBuilders.components.WeekDaysComponent;
import io.mateu.mdd.vaadin.data.MDDBinder;
import io.mateu.mdd.vaadin.util.VaadinHelper;
import io.mateu.reflection.FieldInterfacedForCheckboxColumn;
import io.mateu.reflection.ReflectionHelper;
import io.mateu.util.Helper;
import io.mateu.util.interfaces.IIcon;
import io.mateu.util.notification.Notifier;
import io.mateu.util.persistence.JPAHelper;
import lombok.extern.slf4j.Slf4j;
import org.javamoney.moneta.FastMoney;
import org.vaadin.grid.cellrenderers.editable.DateFieldRenderer;
import org.vaadin.grid.cellrenderers.editable.SimpleSelectRenderer;
import org.vaadin.grid.cellrenderers.editable.TextFieldRenderer;
import org.vaadin.grid.cellrenderers.editoraware.CheckboxRenderer;
import javax.money.MonetaryAmount;
import javax.persistence.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
public abstract class ListViewComponent extends AbstractViewComponent {
public ResultsComponent resultsComponent;
private List listeners = new ArrayList<>();
private int count;
private Label countLabel;
public FiltersComponent filtersComponent;
private Button excelButton;
private Button pdfButton;
private HorizontalLayout matchesComponent;
private String baseUrl;
protected FieldInterfaced field;
private VerticalLayout fieldGroup;
private HorizontalLayout fieldGroupHeader;
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public VerticalLayout getFieldGroup() {
return fieldGroup;
}
public HorizontalLayout getFieldGroupHeader() {
return fieldGroupHeader;
}
@Override
public VaadinIcons getIcon() {
return VaadinIcons.LINES;
}
public String getFieldsFilter() {
return null;
}
public String getEditableFieldsFilter() {
return null;
}
public ListViewComponent() {
if (!MDDUIAccessor.isMobile()) setSizeFull();
}
@Override
public boolean mustCreateHeader() {
return field == null;
}
@Override
public Layout getActionsContainer() {
if (fieldGroupHeader != null) {
HorizontalLayout l;
fieldGroupHeader.addComponent(l = new HorizontalLayout());
l.addStyleName(CSS.NOPADDING);
fieldGroupHeader.setExpandRatio(l, 1);
fieldGroupHeader.setComponentAlignment(l, Alignment.MIDDLE_RIGHT);
return l;
}
return bar;
}
@Override
public ListViewComponent build() throws Exception {
return build(null, null);
}
public ListViewComponent build(VerticalLayout _fieldGroup, HorizontalLayout _fieldGroupHeader) throws Exception {
fieldGroup = _fieldGroup;
fieldGroupHeader = _fieldGroupHeader;
addStyleName("listviewcomponent");
super.build();
if (fieldGroup == null) {
VerticalLayout section = new VerticalLayout();
section.addStyleName("section");
section.addStyleName(CSS.NOPADDING);
fieldGroup = new VerticalLayout();
fieldGroup.addStyleName("fieldgroup");
fieldGroup.addStyleName(CSS.NOPADDING);
fieldGroup.addComponent(fieldGroupHeader = new HorizontalLayout());
fieldGroup.setWidthFull();
fieldGroupHeader.setWidthFull();
fieldGroupHeader.addStyleName("fieldgroupheader");
section.addComponents(fieldGroup);
addComponents(section);
}
fieldGroupHeader.addComponent(countLabel = new Label("No search done"), fieldGroupHeader.getComponentCount() > 0? 1 : 0);
countLabel.addStyleName(ValoTheme.LABEL_H4);
countLabel.addStyleName("countlabel");
countLabel.addStyleName("test-countlabel");
countLabel.setWidthUndefined();
if (!(this instanceof JPACollectionFieldListViewComponent)) fieldGroup.addComponent(filtersComponent = new FiltersComponent(this));
fieldGroup.addComponents(resultsComponent = buildResultsComponent(fieldGroupHeader));
return this;
}
private ResultsComponent buildResultsComponent() {
return buildResultsComponent(null);
}
private ResultsComponent buildResultsComponent(HorizontalLayout countLabel) {
if (countLabel != null) matchesComponent = countLabel;
return new ResultsComponent(this, matchesComponent);
}
public List getColumnFields() {
return getColumnFields(getColumnType(), false, getFieldsFilter(), new ArrayList<>(), new HashMap<>());
}
public void buildColumns(Grid grid) {
buildColumns(null, grid);
}
public void buildColumns(ResultsComponent resultsComponent, Grid grid) {
List colFields = getColumnFields();
buildColumns(resultsComponent, grid, colFields, this instanceof JPAListViewComponent, false, null, null, getFieldsFilter());
}
public static void buildColumns(Grid grid, List colFields, boolean isJPAListViewComponent, boolean editable) {
buildColumns(grid, colFields, isJPAListViewComponent, editable, null);
}
public static void buildColumns(Grid grid, List colFields, boolean isJPAListViewComponent, boolean editable, MDDBinder binder) {
buildColumns(grid, colFields, isJPAListViewComponent, editable, binder, null);
}
public static void buildColumns(Grid grid, List colFields, boolean isJPAListViewComponent, boolean editable, MDDBinder binder, FieldInterfaced collectionField) {
buildColumns(null, grid, colFields, isJPAListViewComponent, editable, binder, null, null);
}
public static void buildColumns(ResultsComponent resultsComponent, Grid grid, List colFields, boolean isJPAListViewComponent, boolean editable, MDDBinder binder, FieldInterfaced collectionField, String fieldsFilter) {
List columnIds = new ArrayList<>();
Map fieldByColumnId = new HashMap<>();
if (!Strings.isNullOrEmpty(fieldsFilter)) {
List fns = new ArrayList<>();
for (String s : fieldsFilter.split(",")) {
String n = s.trim();
if (n.contains("(")) n = n.substring(0, n.indexOf("("));
if (n.contains(" ")) n = n.substring(n.lastIndexOf(" ") + 1);
fns.add(n);
}
for (int i = 0; i < colFields.size(); i++) {
fieldByColumnId.put(fns.get(i), colFields.get(i));
columnIds.add(fns.get(i));
}
} else {
colFields.forEach(f -> {
fieldByColumnId.put(f.getId(), f);
columnIds.add(f.getId());
});
}
buildColumns(resultsComponent, grid, columnIds, fieldByColumnId, isJPAListViewComponent, editable, binder, collectionField, fieldsFilter);
}
private static String getCircleSvg() {
return "";
}
public static void buildColumns(ResultsComponent resultsComponent, Grid grid, List columnIds, Map fieldByColumnId, boolean isJPAListViewComponent, boolean editable, MDDBinder binder, FieldInterfaced collectionField, String fieldsFilter) {
Object bean = binder != null?binder.getBean():null;
// ancho columnas en la definición del filtro. ej: nombre(200),apellidos(300), ...
Map nombresColumnas = new HashMap<>();
Map extras = new HashMap<>();
if (!Strings.isNullOrEmpty(fieldsFilter)) {
Pattern patternNombre = Pattern.compile("'(.*?)'");
Pattern patternParentesis = Pattern.compile("\\((.*?)\\)");
for (String t : fieldsFilter.split(",")) {
String n = t;
if (n.contains("(")) n = n.substring(0, n.indexOf("("));
if (n.contains(" ")) n = n.substring(0, n.indexOf(" "));
if (t.contains("'")) {
String v = "";
Matcher matcher = patternNombre.matcher(t);
if (matcher.find())
{
v = matcher.group(1);
}
nombresColumnas.putIfAbsent(n, v);
}
if (t.contains("(")) {
String v = "";
Matcher matcher = patternParentesis.matcher(t);
if (matcher.find())
{
v = matcher.group(1);
}
extras.putIfAbsent(n, v);
}
}
}
List colBindings = new ArrayList<>();
Map fieldByCol = new HashMap<>();
// descomponemos los campos que tienen usecheckbox
for (String columnId : columnIds) {
FieldInterfaced f = fieldByColumnId.get(columnId);
if (f != null) {
if (f.isAnnotationPresent(UseCheckboxes.class) && f.getAnnotation(UseCheckboxes.class).editableInline()) {
Collection possibleValues = null;
String vmn = ReflectionHelper.getGetter(collectionField.getName() + ReflectionHelper.getFirstUpper(f.getName())) + "Values";
Method mdp = ReflectionHelper.getMethod(collectionField.getDeclaringClass(), vmn);
if (mdp != null) {
try {
possibleValues = (Collection) mdp.invoke(bean);
} catch (Exception e) {
Notifier.alert(e);
}
} else {
Notifier.alert("Missing " + vmn + " method at " + collectionField.getDeclaringClass().getName());
}
int pos = 0;
if (possibleValues != null) for (Object v : possibleValues) if (v != null) {
fieldByColumnId.put(columnId + "_" + pos, new FieldInterfacedForCheckboxColumn(f.getName() + "" + pos, f, v));
pos++;
}
} else fieldByColumnId.put(columnId, f);
}
}
int pos = 0;
for (String columnId : columnIds) {
FieldInterfaced f = fieldByColumnId.get(columnId);
if (f != null) {
final int finalPos = (isJPAListViewComponent?1:0) + pos++;
Grid.Column col;
ICellStyleGenerator csg = null;
if (f.isAnnotationPresent(CellStyleGenerator.class)) {
try {
csg = (ICellStyleGenerator) f.getAnnotation(CellStyleGenerator.class).value().newInstance();
} catch (Exception e) {
Notifier.alert(e);
}
}
if (boolean.class.equals(f.getType()) || Boolean.class.equals(f.getType())) {
csg = new ICellStyleGenerator() {
@Override
public String getStyles(Object row, Object value) {
return ""; //(value != null && ((Boolean)value))?"rowyes":"rowno";
}
@Override
public boolean isContentShown() {
return true;
}
};
}
DecimalFormat df = new DecimalFormat("##,###,###,###,##0.00");
ICellStyleGenerator finalCsg = csg;
col = grid.addColumn(new ValueProvider() {
@Override
public Object apply(Object o) {
//if (finalCsg != null && !finalCsg.isContentShown()) return null;
Object v = null;
if (o instanceof Object[]) {
v = ((Object[]) o)[finalPos];
} else {
try {
v = ReflectionHelper.getValue(f, o);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
if (double.class.equals(f.getType()) && f.isAnnotationPresent(Money.class)) {
return (v != null)?df.format(v):df.format(0);
} else if (boolean[].class.equals(f.getType()) && f.isAnnotationPresent(WeekDays.class)) {
if (o == null) return null;
boolean[] wds = (boolean[]) v;
String s = "";
if (wds != null) for (int i = 0; i < wds.length; i++) {
if (!"".equals(s)) s += ",";
s += wds[i]? WeekDaysComponent.days.get(i):"-";
}
return s;
} else if (LocalDate.class.equals(f.getType())) {
return v != null?((LocalDate)v).format(DateTimeFormatter.ISO_LOCAL_DATE):null;
} else if (LocalDateTime.class.equals(f.getType())) {
return v != null?((LocalDateTime)v).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")):null;
} else if (LocalTime.class.equals(f.getType())) {
return v != null?((LocalTime)v).format(DateTimeFormatter.ofPattern("HH:mm")):null;
} else if (Boolean.class.equals(f.getType()) || boolean.class.equals(f.getType())) {
return (v != null && (Boolean)v)?VaadinIcons.CHECK.getHtml():VaadinIcons.CLOSE.getHtml();
//return "";
} else if (Status.class.equals(f.getType())) {
return v != null?getCircleSvg() + " " + ((Status)v).getMessage():null;
} else if (IIcon.class.isAssignableFrom(f.getType())) {
return (v != null)?"" + v:null;
} else if (IResource.class.equals(f.getType())) {
IResource r = (IResource) v;
if (r != null) {
try {
return new Link(r.getName(), new ExternalResource(r.toFileLocator().getUrl()), "_blank", 400, 400, BorderStyle.MINIMAL);
} catch (Exception e) {
return null;
}
} else {
return null;
}
} else {
return (v != null)?"" + v:null;
}
}
});
if (IResource.class.equals(f.getType())) col.setRenderer(new ComponentRenderer());
if (Status.class.equals(f.getType())) col.setRenderer(new HtmlRenderer(""));
if (IIcon.class.isAssignableFrom(f.getType())) col.setRenderer(new HtmlRenderer(""));
if (Boolean.class.equals(f.getType()) || boolean.class.equals(f.getType())) col.setRenderer(new HtmlRenderer(""));
if (Runnable.class.isAssignableFrom(f.getType())) {
ButtonRenderer r;
col.setRenderer(r = new ButtonRenderer(e -> {
try {
((Runnable)ReflectionHelper.getValue(f, e.getItem())).run();
if (resultsComponent != null) {
try {
resultsComponent.refresh();
} catch (Throwable ex) {
ex.printStackTrace();
}
}
} catch (NoSuchMethodException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InvocationTargetException ex) {
ex.printStackTrace();
}
}, "es null"));
r.setHtmlContentAllowed(true);
col.setSortable(false);
col.setStyleGenerator(c -> "v-align-center");
col.setWidth(100);
}
if (csg != null) col.setStyleGenerator(new StyleGenerator() {
@Override
public String apply(Object o) {
try {
Object v = null;
if (o instanceof Object[]) {
v = ((Object[]) o)[finalPos];
} else {
try {
v = ReflectionHelper.getValue(f, o);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
String s = finalCsg.getStyles(o, v);
if (o instanceof Activable) {
if (!((Activable) o).isActive()) s = (Strings.isNullOrEmpty(s)?"":s + " ") + "cancelled";
} else if (o instanceof Cancellable) {
if (((Cancellable)o).isCancelled()) s = (Strings.isNullOrEmpty(s)?"":s + " ") + "cancelled";
}
return s;
} catch (Exception e) {
Notifier.alert(e);
}
return null;
}
});
else if (collectionField != null && collectionField.getGenericClass() != null && (Activable.class.isAssignableFrom(collectionField.getGenericClass()) || Cancellable.class.isAssignableFrom(collectionField.getGenericClass()))) {
col.setStyleGenerator(new StyleGenerator() {
@Override
public String apply(Object o) {
try {
if (o instanceof Activable) {
if (!((Activable) o).isActive()) return "cancelled";
} else if (o instanceof Cancellable) {
if (((Cancellable)o).isCancelled()) return "cancelled";
}
} catch (Exception e) {
Notifier.alert(e);
}
return null;
}
});
}
if (Status.class.equals(f.getType())) {
col.setStyleGenerator(new StyleGenerator() {
@Override
public String apply(Object o) {
try {
Status v = (Status) ReflectionHelper.getValue(f, o);
if (v == null) return null;
String s = "statusLabel " + ((Status) v).getType();
return s;
} catch (Exception e) {
Notifier.alert(e);
}
return null;
}
});
}
if (finalCsg != null && !finalCsg.isContentShown()) col.setRenderer(new TextRenderer() {
@Override
public JsonValue encode(Object value) {
return super.encode(null);
}
});
if (f.isAnnotationPresent(HtmlCol.class)) col.setRenderer(new HtmlRenderer(""));
if (Integer.class.equals(f.getType()) || int.class.equals(f.getType())
|| Long.class.equals(f.getType()) || long.class.equals(f.getType())
|| Double.class.equals(f.getType()) || double.class.equals(f.getType())
|| BigInteger.class.equals(f.getType()) || BigDecimal.class.equals(f.getType()) || Number.class.equals(f.getType())
|| FastMoney.class.equals(f.getType()) || MonetaryAmount.class.equals(f.getType())
|| f.isAnnotationPresent(RightAlignedCol.class)
) {
if (f.isAnnotationPresent(Balance.class)) {
col.setStyleGenerator(new StyleGenerator() {
@Override
public String apply(Object o) {
try {
Object v = null;
if (o instanceof Object[]) {
v = ((Object[]) o)[finalPos];
} else {
try {
v = ReflectionHelper.getValue(f, o);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
String s = "v-align-right";
if (v != null && ((double)v) < 0) {
s += " negativo";
} else {
s += " positivo";
}
return s;
} catch (Exception e) {
Notifier.alert(e);
}
return null;
}
});
} else col.setStyleGenerator(c -> "v-align-right");
}
if (editable) {
boolean eager = false;
if (f.isAnnotationPresent(Output.class)) {
} else {
if (collectionField != null && collectionField.isAnnotationPresent(UseComponentsToEditValues.class)) {
setEditorAsRenderer(col, f, eager, grid, binder, collectionField);
} else {
Method mdp = ReflectionHelper.getMethod(f.getDeclaringClass(), ReflectionHelper.getGetter(f.getName()) + "DataProvider");
if (f.getType().isAnnotationPresent(UseIdToSelect.class)) {
TextField nf = new TextField();
if (eager) nf.setValueChangeMode(ValueChangeMode.EAGER);
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> {
Object id = null;
if (o != null) {
id = ReflectionHelper.getId(o);
} // else stf.setValue("");
return (id != null)?"" + id:"";
}, (o, v) -> {
Object[] w = {null};
try {
JPAHelper.notransact(em -> {
FieldInterfaced fid = ReflectionHelper.getIdField(f.getType());
String sql = "select x from " + f.getType().getName() + " x where x." + fid.getName() + " = :i";
Object id = null;
if (int.class.equals(fid.getType()) || Integer.class.equals(fid.getType())) {
id = Integer.parseInt((String) v);
} else if (long.class.equals(fid.getType()) || Long.class.equals(fid.getType())) {
id = Long.parseLong((String) v);
} else if (String.class.equals(fid.getType())) {
id = v;
} else id = v;
Query q = em.createQuery(sql).setParameter("i", id);
List r = q.getResultList();
if (r.size() == 1) {
w[0] = r.get(0);
nf.setComponentError(null);
} else {
nf.setComponentError(new UserError("Not found"));
}
});
} catch (Throwable throwable) {
if (throwable instanceof InvocationTargetException) {
throwable = throwable.getCause();
}
String msg = (throwable.getMessage() != null)?throwable.getMessage():throwable.getClass().getName();
nf.setComponentError(new UserError(msg));
Notifier.alert(throwable);
}
try {
ReflectionHelper.setValue(f, o, w[0]);
//refrescar(col, binder, f, o, w[0], colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (f.isAnnotationPresent(ValueClass.class) || f.isAnnotationPresent(DataProvider.class) || mdp != null || f.isAnnotationPresent(ManyToOne.class)) {
ComboBox cb = new ComboBox();
//AbstractBackendDataProvider
//FetchItemsCallback
//newItemProvider
boolean necesitaCaptionGenerator = false;
if (mdp != null) {
// en este punto no hacemos nada
} else if (f.isAnnotationPresent(ValueClass.class)) {
ValueClass a = f.getAnnotation(ValueClass.class);
cb.setDataProvider(new JPQLListDataProvider(a.value()));
} else if (f.isAnnotationPresent(DataProvider.class)) {
necesitaCaptionGenerator = true;
try {
DataProvider a = f.getAnnotation(DataProvider.class);
((HasDataProvider)cb).setDataProvider(a.dataProvider().newInstance());
cb.setItemCaptionGenerator(a.itemCaptionGenerator().newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
necesitaCaptionGenerator = true;
try {
JPAHelper.notransact((em) -> cb.setDataProvider(new JPQLListDataProvider(em, f)));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
if (necesitaCaptionGenerator) {
FieldInterfaced fName = ReflectionHelper.getNameField(f.getType());
if (fName != null) cb.setItemCaptionGenerator((i) -> {
try {
return "" + ReflectionHelper.getValue(fName, i);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return "Error";
});
}
if (mdp != null) {
grid.getEditor().addOpenListener(new EditorOpenListener() {
@Override
public void onEditorOpen(EditorOpenEvent editorOpenEvent) {
try {
Object object = editorOpenEvent.getBean();
cb.setDataProvider((com.vaadin.data.provider.DataProvider) mdp.invoke(object), fx -> new SerializablePredicate() {
@Override
public boolean test(Object o) {
String s = (String) fx;
return o != null && (Strings.isNullOrEmpty(s) || cb.getItemCaptionGenerator().apply(o).toLowerCase().contains(((String) s).toLowerCase()));
}
});
} catch (Exception e) {
Notifier.alert(e);
}
}
});
}
col.setEditorComponent(cb, (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
});
col.setEditable(true);
} else if (FareValue.class.equals(f.getType())) {
TextField nf = new TextField();
nf.setValueChangeMode(ValueChangeMode.EAGER);
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> ReflectionHelper.getValue(f, o, ""), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, (v != null)?new FareValue((String) v):null);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (f.isAnnotationPresent(WeekDays.class)) {
List days = Lists.newArrayList("Mo", "Tu", "We", "Th", "Fr", "Sa", "Su");
col.setEditorComponent(new WeekDaysGridEditor(), (o, v) -> {
try {
boolean[] array = {false, false, false, false, false, false, false};
if (v != null) {
for (int i = 0; i < days.size(); i++) if (i < array.length) array[i] = ((String)v).contains(days.get(i));
}
ReflectionHelper.setValue(f, o, v != null?array:null);
if (binder != null) binder.refresh();
} catch (Exception e) {
Notifier.alert(e);
}
});
col.setEditable(true);
} else if (Boolean.class.equals(f.getType()) || boolean.class.equals(f.getType())) {
col.setEditorComponent(new CheckBox(), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
if (binder != null) binder.refresh();
} catch (Exception e) {
Notifier.alert(e);
}
});
col.setEditable(true);
} else if (String.class.equals(f.getType())) {
TextField nf = new TextField();
if (eager) nf.setValueChangeMode(ValueChangeMode.EAGER);
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> ReflectionHelper.getValue(f, o, ""), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (Integer.class.equals(f.getType()) || int.class.equals(f.getType())
|| Long.class.equals(f.getType()) || long.class.equals(f.getType())) {
TextField nf = new TextField();
if (eager) nf.setValueChangeMode(ValueChangeMode.EAGER);
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> "" + ReflectionHelper.getValue(f, o, ""), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (Double.class.equals(f.getType()) || double.class.equals(f.getType())) {
TextField nf = new TextField();
if (eager) nf.setValueChangeMode(ValueChangeMode.EAGER);
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> "" + ReflectionHelper.getValue(f, o, ""), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (LocalDate.class.equals(f.getType())) {
DateField nf = new DateField();
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> ReflectionHelper.getValue(f, o, null), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (LocalDateTime.class.equals(f.getType())) {
DateTimeField nf = new DateTimeField();
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> ReflectionHelper.getValue(f, o, null), (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (LocalTime.class.equals(f.getType())) {
TextField nf = new TextField();
col.setEditorBinding(grid.getEditor().getBinder().forField(nf).bind(o -> "" + ReflectionHelper.getValue(f, o, ""), (o, v) -> {
try {
LocalTime t = null;
if (v != null && v instanceof String) {
String s = (String) v;
if (!"".equals(s)) {
try {
t = LocalTime.parse(s, DateTimeFormatter.ofPattern("HHmm"));
} catch (Exception e1) {
try {
t = LocalTime.parse(s, DateTimeFormatter.ofPattern("HH:mm"));
} catch (Exception e2) {
try {
t = LocalTime.parse(s, DateTimeFormatter.ofPattern("HH.mm"));
} catch (Exception e3) {
}
}
}
}
}
ReflectionHelper.setValue(f, o, t);
//refrescar(col, binder, f, o, t, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
col.setEditable(true);
} else if (f.getType().isEnum()) {
ComboBox tf = new ComboBox();
tf.setDataProvider(new ListDataProvider(Arrays.asList(f.getType().getEnumConstants())));
col.setEditorComponent(tf, (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
});
col.setEditable(true);
}
}
//todo: acabar
}
}
colBindings.add(col);
fieldByCol.put(col, f);
String caption = nombresColumnas.getOrDefault(columnId, Helper.capitalize(f.getName()));
if (f instanceof FieldInterfacedForCheckboxColumn) caption = ((FieldInterfacedForCheckboxColumn)f).getCaption();
if (f.isAnnotationPresent(Caption.class)) caption = f.getAnnotation(Caption.class).value();
col.setCaption(Translator.translate(caption));
if (columnIds.size() == 1) col.setExpandRatio(1);
else col.setWidth(getColumnWidth(f, extras.get(columnId)));
col.setSortOrderProvider(new SortOrderProvider() {
@Override
public Stream apply(SortDirection sortDirection) {
return Stream.of(new QuerySortOrder(columnId, sortDirection));
}
}).setId(columnId);
}
}
}
private static void setEditorAsRenderer(Grid.Column col, FieldInterfaced f, boolean eager, Grid grid, MDDBinder binder, FieldInterfaced collectionField) {
Method mdp = ReflectionHelper.getMethod(f.getDeclaringClass(), ReflectionHelper.getGetter(f.getName()) + "DataProvider");
Setter setter = (o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
ReflectionHelper.setValue(collectionField, binder.getBean(), ReflectionHelper.getValue(collectionField, binder.getBean()));
binder.refresh();
} catch (Exception e) {
Notifier.alert(e);
}
};
if (f.getType().isAnnotationPresent(UseIdToSelect.class)) {
col.setRenderer(o -> {
Object id = null;
if (o != null) {
id = ReflectionHelper.getId(o);
} // else stf.setValue("");
return (id != null)?"" + id:"";
}, new TextFieldRenderer((o, v) -> {
Object[] w = {null};
try {
JPAHelper.notransact(em -> {
FieldInterfaced fid = ReflectionHelper.getIdField(f.getType());
String sql = "select x from " + f.getType().getName() + " x where x." + fid.getName() + " = :i";
Object id = null;
if (int.class.equals(fid.getType()) || Integer.class.equals(fid.getType())) {
id = Integer.parseInt((String) v);
} else if (long.class.equals(fid.getType()) || Long.class.equals(fid.getType())) {
id = Long.parseLong((String) v);
} else if (String.class.equals(fid.getType())) {
id = v;
} else id = v;
Query q = em.createQuery(sql).setParameter("i", id);
List r = q.getResultList();
if (r.size() == 1) {
w[0] = r.get(0);
//setComponentError(null);
} else {
//setComponentError(new UserError("Not found"));
Notifier.alert("Not found");
}
});
} catch (Throwable throwable) {
if (throwable instanceof InvocationTargetException) {
throwable = throwable.getCause();
}
String msg = (throwable.getMessage() != null)?throwable.getMessage():throwable.getClass().getName();
//nf.setComponentError(new UserError(msg));
Notifier.alert(throwable);
}
try {
ReflectionHelper.setValue(f, o, w[0]);
//refrescar(col, binder, f, o, w[0], colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
} else if (f.isAnnotationPresent(ValueClass.class) || f.isAnnotationPresent(DataProvider.class) || mdp != null || f.isAnnotationPresent(ManyToOne.class)) {
/*
ComboBox cb = new ComboBox();
//AbstractBackendDataProvider
//FetchItemsCallback
//newItemProvider
boolean necesitaCaptionGenerator = false;
if (mdp != null) {
// en este punto no hacemos nada
} else if (f.isAnnotationPresent(ValueClass.class)) {
ValueClass a = f.getAnnotation(ValueClass.class);
cb.setDataProvider(new JPQLListDataProvider(a.value()));
} else if (f.isAnnotationPresent(DataProvider.class)) {
necesitaCaptionGenerator = true;
try {
DataProvider a = f.getAnnotation(DataProvider.class);
((HasDataProvider)cb).setDataProvider(a.dataProvider().newInstance());
cb.setItemCaptionGenerator(a.itemCaptionGenerator().newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
necesitaCaptionGenerator = true;
try {
JPAHelper.notransact((em) -> cb.setDataProvider(new JPQLListDataProvider(em, f)));
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
if (necesitaCaptionGenerator) {
FieldInterfaced fName = ReflectionHelper.getNameField(f.getType());
if (fName != null) cb.setItemCaptionGenerator((i) -> {
try {
return "" + ReflectionHelper.getValue(fName, i);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return "Error";
});
}
if (mdp != null) {
grid.getEditor().addOpenListener(new EditorOpenListener() {
@Override
public void onEditorOpen(EditorOpenEvent editorOpenEvent) {
try {
Object object = editorOpenEvent.getBean();
cb.setDataProvider((com.vaadin.data.provider.DataProvider) mdp.invoke(object), fx -> new SerializablePredicate() {
@Override
public boolean test(Object o) {
String s = (String) fx;
return o != null && (Strings.isNullOrEmpty(s) || cb.getItemCaptionGenerator().apply(o).toLowerCase().contains(((String) s).toLowerCase()));
}
});
} catch (Exception e) {
Notifier.alert(e);
}
}
});
}
*/
col.setRenderer(new SimpleSelectRenderer((o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}, new ArrayList()));
} else if (FareValue.class.equals(f.getType())) {
col.setRenderer(o -> ReflectionHelper.getValue(f, o, ""), new TextFieldRenderer((o, v) -> {
try {
ReflectionHelper.setValue(f, o, (v != null)?new FareValue((String) v):null);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
} else if (f.isAnnotationPresent(WeekDays.class)) {
List days = Lists.newArrayList("Mo", "Tu", "We", "Th", "Fr", "Sa", "Su");
/*
col.setEditorComponent(new WeekDaysGridEditor(), (o, v) -> {
try {
boolean array[] = {false, false, false, false, false, false, false};
if (v != null) {
for (int i = 0; i < days.size(); i++) if (i < array.length) array[i] = ((String)v).contains(days.get(i));
}
ReflectionHelper.setValue(f, o, v != null?array:null);
if (binder != null) binder.refresh();
} catch (Exception e) {
Notifier.alert(e);
}
});
col.setEditable(true);
*/
} else if (Boolean.class.equals(f.getType()) || boolean.class.equals(f.getType())) {
col.setRenderer(new CheckboxRenderer(setter));
} else if (String.class.equals(f.getType())) {
TextFieldRenderer r;
col.setRenderer(r = new TextFieldRenderer(setter));
r.setConverter(new DummyConverter());
} else if (Integer.class.equals(f.getType()) || int.class.equals(f.getType())
|| Long.class.equals(f.getType()) || long.class.equals(f.getType())) {
TextFieldRenderer r;
col.setRenderer(r = new TextFieldRenderer(setter));
r.setConverter(new DummyConverter());
} else if (Double.class.equals(f.getType()) || double.class.equals(f.getType())) {
TextFieldRenderer r;
col.setRenderer(r = new TextFieldRenderer(setter));
r.setConverter(new DummyConverter());
} else if (LocalDate.class.equals(f.getType())) {
TextFieldRenderer r;
col.setRenderer(r = new TextFieldRenderer(setter));
r.setConverter(new DummyConverter(null));
} else if (LocalDateTime.class.equals(f.getType())) {
TextFieldRenderer r;
col.setRenderer(r = new TextFieldRenderer(setter));
r.setConverter(new DummyConverter(null));
} else if (LocalTime.class.equals(f.getType())) {
col.setRenderer(o -> "" + ReflectionHelper.getValue(f, o, ""), new DateFieldRenderer((o, v) -> {
try {
LocalTime t = null;
if (v != null && v instanceof String) {
String s = (String) v;
if (!"".equals(s)) {
try {
t = LocalTime.parse(s, DateTimeFormatter.ofPattern("HHmm"));
} catch (Exception e1) {
try {
t = LocalTime.parse(s, DateTimeFormatter.ofPattern("HH:mm"));
} catch (Exception e2) {
try {
t = LocalTime.parse(s, DateTimeFormatter.ofPattern("HH.mm"));
} catch (Exception e3) {
}
}
}
}
}
ReflectionHelper.setValue(f, o, t);
//refrescar(col, binder, f, o, t, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}));
} else if (f.getType().isEnum()) {
col.setRenderer(new SimpleSelectRenderer((o, v) -> {
try {
ReflectionHelper.setValue(f, o, v);
//refrescar(col, binder, f, o, v, colBindings, fieldByCol);
} catch (Exception e) {
Notifier.alert(e);
}
}, Arrays.asList(f.getType().getEnumConstants())));
}
}
private static void refrescar(Grid.Column col, MDDBinder binder, FieldInterfaced f, Object o, Object v, List colBindings, Map fieldByCol) {
if (binder != null) binder.refresh();
if (false) colBindings.stream().filter(e -> !e.equals(col)).forEach(b -> {
try {
Object w = ReflectionHelper.getValue(fieldByCol.get(b), o);
if (b.getEditorBinding() != null && b.getEditorBinding().getField() != null) {
if (b.getEditorBinding().getField() instanceof TextField) b.getEditorBinding().getField().setValue(w != null?"" + w:"");
else b.getEditorBinding().getField().setValue(w);
} else {
log.debug("columna " + b.getId() + " no es editable");
b.getValueProvider().apply(o);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
});
}
public static double getColumnWidth(FieldInterfaced f) {
return getColumnWidth(f, null);
}
public static double getColumnWidth(FieldInterfaced f, String overriden) {
if (!Strings.isNullOrEmpty(overriden)) return Double.parseDouble(overriden);
else if (f.isAnnotationPresent(ColumnWidth.class)) return f.getAnnotation(ColumnWidth.class).value();
else {
Class t = f.getType();
if (
int.class.equals(t)
|| Integer.class.equals(t)
|| long.class.equals(t)
|| Long.class.equals(t)
|| float.class.equals(t)
|| Float.class.equals(t)
|| double.class.equals(t)
|| Double.class.equals(t)
|| boolean.class.equals(t)
|| Boolean.class.equals(t)
|| BigInteger.class.equals(t)
|| BigDecimal.class.equals(t)
|| Number.class.equals(t)
) return 120;
else if (LocalDate.class.equals(t)) return 125;
else if (LocalDateTime.class.equals(t)) return 225;
else if (LocalTime.class.equals(t)) return 225;
else if (FareValue.class.equals(t)) return 125;
else if (f.isAnnotationPresent(WeekDays.class)) return 200;
else return 250;
}
}
public void search(Object filters) throws Throwable {
setModelForSearchFilters(filters);
resultsComponent.search(filters);
}
public ListViewComponent addListener(ListViewComponentListener listener) {
listeners.add(listener);
return this;
}
public void edit(Object id) {
for (ListViewComponentListener l : listeners) l.onEdit(id);
};
public void select(Object id) {
for (ListViewComponentListener l : listeners) l.onSelect(id);
};
public Object getPrevious(Object current) {
if (resultsComponent == null) {
try {
build();
} catch (Exception e) {
Notifier.alert(e);
}
}
Object x = resultsComponent.getPrevious();
if (x == null) return null;
if (getView().getViewComponent() instanceof RpcListViewComponent) {
try {
return ReflectionHelper.getId(((RpcListViewComponent) getView().getViewComponent()).getRpcListView().onEdit(x));
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
}
return toId(x);
}
public Object getNext(Object current) {
if (resultsComponent == null) {
try {
build();
} catch (Exception e) {
Notifier.alert(e);
}
}
Object x = resultsComponent.getNext();
if (x == null) return null;
if (getView().getViewComponent() instanceof RpcListViewComponent) {
try {
return ReflectionHelper.getId(((RpcListViewComponent) getView().getViewComponent()).getRpcListView().onEdit(x));
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
}
return toId(x);
}
public abstract Collection findAll(Object filters, List sortOrders, int offset, int limit);
public int count(Object filters) throws Throwable {
count = gatherCount(filters);
String s = (count == 1)?"" + count + " match.":"" + count + " matches";
s += toCountLabel(filters);
s += ".";
countLabel.setValue(s);
List sums = getSums(filters);
getKpisContainer().removeAllComponents();
if (sums != null && sums.size() > 0) {
for (SumData d : sums) {
getKpisContainer().addComponent(buildSum(d));
}
}
if (MDDUIAccessor.getApp().isChartsEnabled()) {
List charts = getCharts(filters);
if (charts != null && charts.size() > 0) {
for (ChartData d : charts) {
getKpisContainer().addComponent(buildChart(d));
}
}
}
return count;
}
private String toCountLabel(Object filters) {
String s = "";
if (filters != null) for (FieldInterfaced f : getFilterFields()) if (!f.isAnnotationPresent(Version.class) && !f.isAnnotationPresent(Ignored.class)) {
try {
Object v = f.getValue(filters);
if (v != null) {
if (!(v instanceof String) || !Strings.isNullOrEmpty((String) v)) {
if (!"".equals(s)) s += ", ";
s += ReflectionHelper.getCaption(f) + " = " + v;
s += "";
}
}
} catch (Exception e) {
Notifier.alert(e);
}
}
if (!"".equals(s)) s = " where " + s;
return s;
}
@Override
public String getPageTitle() {
if (getModelType().isAnnotationPresent(Caption.class)) {
return ((Caption)getModelType().getAnnotation(Caption.class)).value();
}
try {
return super.getPageTitle() + toCountLabel(getModelForSearchFilters());
} catch (Exception e) {
}
return super.getTitle();
}
private Component buildChart(ChartData d) {
DonutChartConfig config = new DonutChartConfig();
config
.data()
.labelsAsList(d.getValues().stream().map(v -> v.getTitle()).collect(Collectors.toList()))
.addDataset(new PieDataset().label(d.getTitle()))
.and();
config.
options()
.rotation(Math.PI)
.circumference(Math.PI)
.responsive(true)
.title()
.display(true)
.text(d.getTitle())
.and()
.animation()
.animateScale(false)
.animateRotate(true)
.and()
.done();
double total = 0;
for (ChartValue v : d.getValues()) {
total += v.getValue();
}
List labels = config.data().getLabels();
for (Dataset, ?> ds : config.data().getDatasets()) {
PieDataset lds = (PieDataset) ds;
String[] colors = d.getValues().stream().map(v -> v.getStyle().toLowerCase().replaceAll("mdd-", "").replaceAll("-bgd", "")).collect(Collectors.toList()).toArray(new String[0]);
if (colors.length > 0 && !Strings.isNullOrEmpty(colors[0])) lds.backgroundColor(colors);
else lds.randomBackgroundColors(true);
List data = new ArrayList<>();
for (int i = 0; i < d.getValues().size(); i++) {
//data.add(100d * d.getValues().get(i).getValue() / total);
data.add(d.getValues().get(i).getValue());
}
lds.dataAsList(data);
}
ChartJs chart = new ChartJs(config);
chart.setJsLoggingEnabled(true);
if (d.getField() != null) {
chart.addClickListener((a,b) -> {
Object bean = filtersComponent.getBinder().getBean();
try {
ReflectionHelper.setValue(d.getField(), bean, d.getValues().get(b).getKey());
filtersComponent.getBinder().setBean(bean);
search(bean);
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
//DemoUtils.notification(a, b, config.data().getDatasets().get(a));
});
}
return chart;
}
private Component buildSum(SumData d) {
VerticalLayout vl = new VerticalLayout();
vl.addStyleName("kpi");
vl.setWidthUndefined();
vl.addComponent(new Label(d.getTitle()));
Object v = d.getValue();
Label l;
vl.addComponent(l = new Label());
l.addStyleName("valor");
l.setContentMode(ContentMode.HTML);
String s = "";
if (double.class.equals(v.getClass())) {
DecimalFormat df = new DecimalFormat("##,###,###,###,##0.00");
s = df.format(v != null?v:0);
if (v != null && ((double)v) < 0) {
l.addStyleName("negativo");
l.removeStyleName("positivo");
} else {
l.addStyleName("positivo");
l.removeStyleName("negativo");
}
} else {
if (v == null) s = "";
else {
if (v instanceof Boolean) {
if ((Boolean) v) {
s = VaadinIcons.CHECK.getHtml();
l.addStyleName(ValoTheme.BUTTON_FRIENDLY);
} else {
s = VaadinIcons.CLOSE.getHtml();
l.addStyleName(ValoTheme.BUTTON_DANGER);
}
l.addStyleName("centered");
} else {
s = "" + v;
}
}
}
l.setValue(s);
return vl;
/*
Label l = new Label(d.getTitle() + ": " + d.getValue());
l.addStyleName("sum");
if (!Strings.isNullOrEmpty(d.getStyle())) l.addStyleName(d.getStyle());
return l;
*/
}
protected abstract int gatherCount(Object filters) throws Throwable;
protected abstract List getSums(Object filters);
protected abstract List getCharts(Object filters);
public abstract Object deserializeId(String id);
public String getPathForEditor(Object id) {
return "" + id;
}
public String getPathForFilters() {
return "filters";
}
public abstract Object getModelForSearchFilters() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException;
public abstract void setModelForSearchFilters(Object filters);
public Component getFiltersViewComponent() {
return filtersComponent.getFiltersViewComponent();
}
public Class getModelType() {
return getClass();
}
public Method getMethod(String methodName) {
Method a = null;
for (Method m : ReflectionHelper.getAllMethods(getFiltersType())) {
if (RpcView.class.isAssignableFrom(getFiltersType())&& m.getName().equals(methodName)) {
a = m;
break;
}
}
for (Method m : ReflectionHelper.getAllMethods(getModelType())) {
if (Modifier.isStatic(m.getModifiers()) && m.getName().equals(methodName)) {
a = m;
break;
}
}
return a;
}
public Set getSelection() {
return resultsComponent.getSelection();
}
public static List getColumnFields(Class objectType) {
return getColumnFields(objectType, false);
}
public static List getColumnFields(Class objectType, boolean forGrid) {
return getColumnFields(objectType, forGrid, null, null, null);
}
public static List getColumnFields(Class objectType, boolean forGrid, String fieldsFilter, List columNames, Map fieldsByColumnName) {
List explicitColumns = null;
if (Strings.isNullOrEmpty(fieldsFilter)) {
explicitColumns = ReflectionHelper.getAllFields(objectType).stream().filter(
f -> f.isAnnotationPresent(ListColumn.class)
).peek(f -> {
if (columNames != null && fieldsByColumnName != null) {
String n = f.getName();
columNames.add(n);
fieldsByColumnName.put(n, f);
}
}).filter(f -> f != null).collect(Collectors.toList());
} else {
List fns = Lists.newArrayList(fieldsFilter.split(","));
fns = fns.stream().map(n -> {
n = n.trim();
n = n.replaceAll("\\(.*\\)", "");
if (n.contains(" ")) n = n.substring(0, n.indexOf(" "));
n = n.replaceAll(" ", "");
return n;
}).collect(Collectors.toList());
explicitColumns = fns.stream().map(n -> {
FieldInterfaced f = ReflectionHelper.getFieldByName(objectType, n);
if (columNames != null && fieldsByColumnName != null) {
columNames.add(n);
fieldsByColumnName.put(n, f);
}
return f;
}).filter(f -> f != null).collect(Collectors.toList());
}
if (explicitColumns.size() > 0) {
return explicitColumns;
} else {
List cols = ReflectionHelper.getAllFields(objectType).stream().filter(
(f) -> !"_proxied".equalsIgnoreCase(f.getName()) && !"_possibleValues".equalsIgnoreCase(f.getName()) && !"_binder".equalsIgnoreCase(f.getName()) && !"_field".equalsIgnoreCase(f.getName())
&& !Modifier.isTransient(f.getModifiers())
&& !f.isAnnotationPresent(Transient.class)
&& !f.isAnnotationPresent(NotInList.class)
&& !f.isAnnotationPresent(Version.class)
&& !f.isAnnotationPresent(Ignored.class)
&& !f.isAnnotationPresent(Password.class)
//&& !Modifier.isTransient(f.getModifiers())
&& (!Collection.class.isAssignableFrom(f.getType()) || (forGrid && f.isAnnotationPresent(UseCheckboxes.class) && f.getAnnotation(UseCheckboxes.class).editableInline()))
&& !Map.class.isAssignableFrom(f.getType())
&& !f.isAnnotationPresent(GeneratedValue.class)
&& (ReflectionHelper.isBasico(f.getType())
|| BigDecimal.class.equals(f.getType())
|| f.getType().isEnum()
|| f.getType().isAnnotationPresent(Entity.class)
|| java.sql.Date.class.equals(f.getType())
|| FareValue.class.equals(f.getType())
|| Status.class.equals(f.getType())
|| f.isAnnotationPresent(WeekDays.class)
|| (forGrid && f.isAnnotationPresent(UseCheckboxes.class) && f.getAnnotation(UseCheckboxes.class).editableInline())
|| Runnable.class.isAssignableFrom(f.getType())
)
).filter(f -> f != null).collect(Collectors.toList());
if (columNames != null && fieldsByColumnName != null) cols.forEach(f -> {
columNames.add(f.getName());
fieldsByColumnName.put(f.getName(), f);
});
return cols;
}
}
public abstract Class getColumnType();
public List getFilterFields() {
return getFilterFields(getFiltersType());
}
public List getFilterFields(Class filtersType) {
List explicitFilters = ReflectionHelper.getAllFields(filtersType).stream().filter(
(f) -> !f.isAnnotationPresent(Password.class) && !f.isAnnotationPresent(Version.class) && !f.isAnnotationPresent(Ignored.class) && f.isAnnotationPresent(SearchFilter.class) || f.isAnnotationPresent(MainSearchFilter.class)
).collect(Collectors.toList());
if (explicitFilters.size() > 0) {
return explicitFilters;
} else {
return ReflectionHelper.getAllFields(filtersType).stream().filter(
(f) -> !f.isAnnotationPresent(Password.class) && !f.isAnnotationPresent(Version.class) && !f.isAnnotationPresent(Ignored.class) && !f.isAnnotationPresent(Output.class) && !IResource.class.equals(f.getType()) && (String.class.equals(f.getType()) || LocalDate.class.equals(f.getType()) || LocalDateTime.class.equals(f.getType()) || LocalTime.class.equals(f.getType()) || Date.class.equals(f.getType()) || boolean.class.equals(f.getType()) || Boolean.class.equals(f.getType()) || f.getType().isEnum() || f.isAnnotationPresent(ManyToOne.class) || f.getType().isAnnotationPresent(Entity.class))
).collect(Collectors.toList());
}
}
public abstract Class getFiltersType();
public boolean isAddEnabled() {
return false;
}
public boolean isDeleteEnabled() {
return false;
}
public boolean isReadOnlyListView() {
return false;
}
@Override
public void addViewActionsMenuItems(Layout bar, List actions) {
if (!isReadOnlyListView() && isAddEnabled()) {
Button i;
bar.addComponent(i = new Button("New", VaadinIcons.PLUS));
if (!bar.getStyleName().contains("actionsbar")) i.addStyleName(ValoTheme.BUTTON_QUIET);
i.addClickListener(e -> {
try {
MDDUIAccessor.go(getFieldPrefix() + "new");
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
});
i.setClickShortcut(ShortcutAction.KeyCode.N, ShortcutAction.ModifierKey.CTRL, ShortcutAction.ModifierKey.ALT);
}
if (!isReadOnlyListView() && isDeleteEnabled()) {
Button i;
bar.addComponent(i = new Button("Delete", VaadinIcons.MINUS));
if (!bar.getStyleName().contains("actionsbar")) i.addStyleName(ValoTheme.BUTTON_QUIET);
i.addClickListener(e -> {
VaadinHelper.confirm("Are you sure you want to delete the selected items?", new Runnable() {
@Override
public void run() {
try {
delete(getSelection());
resultsComponent.refresh();
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
}
});
});
i.setClickShortcut(ShortcutAction.KeyCode.DELETE, ShortcutAction.ModifierKey.CTRL);
}
super.addViewActionsMenuItems(bar, actions);
}
public String getFieldPrefix() {
if (field != null) return field.getName() + "/";
return "";
}
protected void delete(Set selection) throws Throwable {
throw new Exception("You must override the delete method for " + getClass().getSimpleName());
}
public Object toId(Object row) {
if (row != null && row.getClass().isAnnotationPresent(NativeJPQLResult.class)) return row;
else return ReflectionHelper.getId(row);
}
public Grid getGrid() {
return resultsComponent.getGrid();
}
public void decorateGridMain(Grid grid) {
int pos = 2;
for (FieldInterfaced f : getColumnFields(getColumnType())) {
if (StyledEnum.class.isAssignableFrom(f.getType())) {
Grid.Column col = grid.getColumn(f.getName());
int finalPos = pos;
col.setStyleGenerator(o -> {
if (o instanceof Object[]) {
return ((StyledEnum)((Object[])o)[finalPos]).getStyle();
} else {
try {
return ((StyledEnum)ReflectionHelper.getValue(f, o)).getStyle();
} catch (Exception e) {
Notifier.alert(e);
}
return null;
}
});
}
pos++;
}
decorateGrid(grid);
}
public abstract void decorateGrid(Grid grid);
public int getFrozenColumnCount() {
return 0;
}
public void searched() {
MDDUIAccessor.goTo(getUrl());
}
public String getUrl() {
String u = baseUrl;
if (u == null) u = MDDUIAccessor.getCurrentState();
if (u.contains("/")) {
String s = u.substring(u.lastIndexOf("/"));
if (s.contains("&")) u = u.substring(0, u.length() - (s.length() - s.indexOf("&") - 1));
}
u += getModelForSearchFiltersSerialized();
return u;
}
private String getModelForSearchFiltersSerialized() {
Base64.Encoder b64 = Base64.getUrlEncoder();
String s = "";
try {
Object m = getModelForSearchFilters();
for (FieldInterfaced f : ReflectionHelper.getAllFields(m.getClass())) {
Object v = ReflectionHelper.getValue(f, m);
if (v != null) {
if (v.getClass().isAnnotationPresent(Entity.class)) {
v = ReflectionHelper.getValue(ReflectionHelper.getIdField(v.getClass()), v);
} else if (v.getClass().isEnum()) {
v = ((Enum)v).name();
}
s += "&";
s += "" + f.getName() + "_" + b64.encodeToString(("" + v).getBytes("utf-8"));
}
}
} catch (Exception e) {
Notifier.alert(e);
}
return s;
}
}