Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.mateu.mdd.vaadin.components.fieldBuilders.JPAManyToOneFieldBuilder Maven / Gradle / Ivy
package io.mateu.mdd.vaadin.components.fieldBuilders;
import com.google.common.base.Strings;
import com.vaadin.data.*;
import com.vaadin.data.validator.BeanValidator;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.server.SerializablePredicate;
import com.vaadin.ui.*;
import com.vaadin.ui.themes.ValoTheme;
import io.mateu.mdd.core.MDD;
import io.mateu.mdd.core.app.AbstractAction;
import io.mateu.mdd.core.dataProviders.JPQLListDataProvider;
import io.mateu.mdd.core.interfaces.AbstractStylist;
import io.mateu.mdd.core.ui.MDDUIAccessor;
import io.mateu.mdd.shared.CSS;
import io.mateu.mdd.shared.annotations.*;
import io.mateu.mdd.shared.reflection.FieldInterfaced;
import io.mateu.mdd.vaadin.data.MDDBinder;
import io.mateu.reflection.ReflectionHelper;
import io.mateu.util.notification.Notifier;
import io.mateu.util.persistence.JPAHelper;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.Query;
import javax.validation.constraints.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JPAManyToOneFieldBuilder extends AbstractFieldBuilder {
public boolean isSupported(FieldInterfaced field) {
return field.isAnnotationPresent(ManyToOne.class) || field.getType().isAnnotationPresent(Entity.class);
}
@Override
public Component build(VerticalLayout fieldGroup, HorizontalLayout fieldGroupHeader, FieldInterfaced field, Object object, Layout container, MDDBinder binder, Map> validators, AbstractStylist stylist, Map allFieldContainers, boolean forSearchFilter, Map> attachedActions) {
Component r = null;
Component tf = null;
HasValue hv = null;
com.vaadin.data.provider.DataProvider dp = null;
AbstractComponent captionOwner = null;
Converter converter = null;
Button botonLink = null;
if (field.isAnnotationPresent(UseLinkToListView.class)) {
HorizontalLayout wrap = new HorizontalLayout();
wrap.setSpacing(true);
wrap.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT);
TextField l = new TextField();
l.setEnabled(false);
l.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS);
wrap.addComponent(l);
captionOwner = l;
hv = new AbstractField() {
Object v = null;
@Override
protected void doSetValue(Object o) {
v = o;
if (o != null) l.setValue(o.toString());
else l.setValue("");
}
@Override
public Object getValue() {
return v;
}
};
if (MDD.isReadWrite(field.getType())) {
Button b = new Button("Select");
b.addStyleName(ValoTheme.BUTTON_LINK);
b.addClickListener(e -> MDDUIAccessor.go(field.getName()));
wrap.addComponent(b);
}
container.addComponent(wrap);
addErrorHandler(field, (AbstractField) tf);
r = tf;
tf = wrap;
if (!forSearchFilter) l.setRequiredIndicatorVisible(field.isAnnotationPresent(NotNull.class));
} else {
HorizontalLayout hl;
if (field.getType().isAnnotationPresent(UseIdToSelect.class)) {
VerticalLayout fl;
tf = fl = new VerticalLayout();
hl = new HorizontalLayout();
fl.addComponent(hl);
hl.setDefaultComponentAlignment(Alignment.BOTTOM_LEFT);
container.addComponent(fl);
fl.addStyleName(CSS.NOPADDING);
TextField stf;
hl.addComponent(stf = new TextField());
Label l;
fl.addComponent(l = new Label());
addErrorHandler(field, stf);
r = stf;
captionOwner = stf;
hv = stf;
converter = new Converter() {
@Override
public Result convertToModel(String s, ValueContext valueContext) {
stf.setComponentError(null);
Result[] r = new Result[1];
if (Strings.isNullOrEmpty(s)) {
r[0] = Result.ok(null);
l.setValue("No value");
}
else try {
JPAHelper.notransact(em -> {
FieldInterfaced fid = ReflectionHelper.getIdField(field.getType());
String sql = "select x from " + field.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(s);
} else if (long.class.equals(fid.getType()) || Long.class.equals(fid.getType())) {
id = Long.parseLong(s);
} else if (String.class.equals(fid.getType())) {
id = s;
} else id = s;
Query q = em.createQuery(sql).setParameter("i", id);
List list = q.getResultList();
if (list.size() == 1) {
Object v;
r[0] = Result.ok(v = list.get(0));
l.setValue((v != null)?"" + v:"No value");
} else {
r[0] = Result.error("Not found");
l.setValue("Not found");
}
});
} catch (Throwable throwable) {
if (throwable instanceof InvocationTargetException) {
throwable = throwable.getCause();
}
String msg = (throwable.getMessage() != null) ? throwable.getMessage() : throwable.getClass().getName();
r[0] = Result.error(msg);
l.setValue(msg);
}
return r[0];
}
@Override
public String convertToPresentation(Object o, ValueContext valueContext) {
String s = null;
l.setValue((o != null)?"" + o:"No value");
if (o != null) {
Object id = ReflectionHelper.getId(o);
s = (id != null)?"" + id:"";
}
return s != null?s:"";
}
};
} else {
tf = hl = new HorizontalLayout();
hl.setDefaultComponentAlignment(Alignment.BOTTOM_LEFT);
container.addComponent(hl);
if (!forSearchFilter && field.isAnnotationPresent(UseRadioButtons.class)) {
RadioButtonGroup rbg;
hl.addComponent(rbg = new RadioButtonGroup());
hv = rbg;
addErrorHandler(field, rbg);
r = rbg;
captionOwner = rbg;
//AbstractBackendDataProvider
//FetchItemsCallback
//newItemProvider
setDataProvider(rbg, field, binder);
if (!forSearchFilter) rbg.setRequiredIndicatorVisible(field.isAnnotationPresent(NotNull.class));
} else {
ComboBox cb;
hl.addComponent(cb = new ComboBox());
cb.setId(field.getId());
captionOwner = cb;
addErrorHandler(field, cb);
r = cb;
cb.addStyleName("combo");
if (field.isAnnotationPresent(Width.class)) cb.setWidth(field.getAnnotation(Width.class).value());
if (field.isAnnotationPresent(RequestFocus.class)) cb.focus();
hv = cb;
setDataProvider(cb, field, binder);
}
}
if (!forSearchFilter && !field.isAnnotationPresent(UseRadioButtons.class)) {
hv.setRequiredIndicatorVisible(field.isAnnotationPresent(NotNull.class));
if (field.getType().isAnnotationPresent(Entity.class)) {
Button b = null;
com.vaadin.data.provider.DataProvider dpx = (hv instanceof ComboBox)?((ComboBox)hv).getDataProvider():((hv instanceof RadioButtonGroup)?((RadioButtonGroup)hv).getDataProvider():null);
if (dpx != null && dpx instanceof JPQLListDataProvider) {
b = new Button(null, VaadinIcons.REFRESH);
b.addStyleName(ValoTheme.BUTTON_QUIET);
b.addStyleName(CSS.NOPADDING);
b.addClickListener(e -> ((JPQLListDataProvider)dpx).refreshAll());
hl.addComponent(b);
}
b = new Button(null, VaadinIcons.SEARCH);
b.addStyleName(ValoTheme.BUTTON_QUIET);
b.addStyleName(CSS.NOPADDING);
b.addClickListener(e -> {
MDDUIAccessor.go(field.getName() + "_search");
});
hl.addComponent(b);
if (MDD.isReadWrite(field.getType())) {
botonLink = new Button(null, VaadinIcons.EXTERNAL_LINK);
botonLink.addStyleName(ValoTheme.BUTTON_QUIET);
botonLink.addStyleName(CSS.NOPADDING);
botonLink.addClickListener(e -> MDDUIAccessor.go(field.getName()));
//botonLink.setVisible(false);
hl.addComponent(botonLink);
}
}
}
}
if (allFieldContainers != null) allFieldContainers.put(field, tf);
captionOwner.setCaption(ReflectionHelper.getCaption(field));
Binder.Binding binding = bind(binder, hv, field, forSearchFilter, dp, captionOwner, converter, botonLink);
return r;
}
public static void setDataProvider(HasItems hdp, FieldInterfaced field, MDDBinder binder) {
try {
JPAHelper.notransact((em) -> {
com.vaadin.data.provider.DataProvider dp = null;
ItemCaptionGenerator icg = null;
DataProvider dpa = (field.isAnnotationPresent(DataProvider.class))?field.getAnnotation(DataProvider.class):null;
Method mdp = ReflectionHelper.getMethod(field.getDeclaringClass(), ReflectionHelper.getGetter(field.getName()) + "DataProvider");
if (mdp != null) {
dp = (com.vaadin.data.provider.DataProvider) ((mdp.getParameterCount() == 0)?mdp.invoke(binder.getBean()):mdp.invoke(binder.getBean(), binder));
if (mdp.isAnnotationPresent(DependsOn.class)) {
for (String fn : mdp.getAnnotation(DependsOn.class).value().split(",")) {
fn = fn.trim();
binder.addValueChangeListener((e) -> {
if (e.isUserOriginated()) {
if (binder.getBean() != null) { // puede pasar que llamemos a este método cuando todavía no hayamos bindeado nada
com.vaadin.data.provider.DataProvider dpx = null;
try {
dpx = (com.vaadin.data.provider.DataProvider) ((mdp.getParameterCount() == 0) ? mdp.invoke(binder.getBean()) : mdp.invoke(binder.getBean(), binder));
if (hdp instanceof RadioButtonGroup) {
((RadioButtonGroup)hdp).setDataProvider(dpx);
} else if (hdp instanceof CheckBoxGroup) {
((CheckBoxGroup)hdp).setDataProvider(dpx);
Object bean = binder.getBean();
if (bean != null && ReflectionHelper.getValue(field, bean) != null) {
Object v = ReflectionHelper.getValue(field, bean);
if (v != null && v instanceof Set) {
((CheckBoxGroup)hdp).setValue((Set) v);
}
}
} else if (hdp instanceof ComboBox) {
((ComboBox)hdp).setDataProvider(dpx, f -> new SerializablePredicate() {
@Override
public boolean test(Object o) {
String s = (String) f;
return o != null && (Strings.isNullOrEmpty(s) || ((ComboBox)hdp).getItemCaptionGenerator().apply(o).toLowerCase().contains(((String) s).toLowerCase()));
}
});
} else if (hdp instanceof TwinColSelect) {
((TwinColSelect)hdp).setDataProvider(dpx);
} else if (hdp instanceof Grid) {
((Grid)hdp).setDataProvider(dpx);
}
Object v = null;
if (hdp instanceof ComboBox && field.isAnnotationPresent(NotNull.class)) {
if (((ComboBox)hdp).getDataProvider().size(new com.vaadin.data.provider.Query()) == 1) {
v = ((ComboBox)hdp).getDataProvider().fetch(new com.vaadin.data.provider.Query()).findFirst().get();
}
}
Object bean = binder.getBean();
if (bean != null && ReflectionHelper.getValue(field, bean) == null) {
ReflectionHelper.setValue(field, bean, v);
binder.update(bean);
}
} catch (Exception e1) {
Notifier.alert(e1);
}
}
}
});
}
}
} else if (dpa != null) {
try {
dp = dpa.dataProvider().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
dp = new JPQLListDataProvider(em, field);
}
Method micg = ReflectionHelper.getMethod(field.getDeclaringClass(), ReflectionHelper.getGetter(field.getName()) + "ItemCaptionGenerator");
if (micg != null) {
icg = (ItemCaptionGenerator) micg.invoke(binder.getBean());
} else if (dpa != null) {
try {
icg = dpa.itemCaptionGenerator().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
FieldInterfaced fName = ReflectionHelper.getNameField(field.getType());
if (fName != null) icg = (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 (hdp instanceof RadioButtonGroup) {
if (dp != null) ((RadioButtonGroup)hdp).setDataProvider(dp);
if (icg != null) ((RadioButtonGroup)hdp).setItemCaptionGenerator(icg);
} else if (hdp instanceof CheckBoxGroup) {
if (dp != null) ((CheckBoxGroup)hdp).setDataProvider(dp);
if (icg != null) ((CheckBoxGroup)hdp).setItemCaptionGenerator(icg);
} else if (hdp instanceof ComboBox) {
if (dp != null) ((ComboBox)hdp).setDataProvider(dp, f -> new SerializablePredicate() {
@Override
public boolean test(Object o) {
String s = (String) f;
return o != null && (Strings.isNullOrEmpty(s) || ((ComboBox)hdp).getItemCaptionGenerator().apply(o).toLowerCase().contains(((String) s).toLowerCase()));
}
});
if (icg != null) ((ComboBox)hdp).setItemCaptionGenerator(icg);
} else if (hdp instanceof TwinColSelect) {
if (dp != null) ((TwinColSelect)hdp).setDataProvider(dp);
if (icg != null) ((TwinColSelect)hdp).setItemCaptionGenerator(icg);
} else if (hdp instanceof Grid) {
if (dp != null) ((Grid)hdp).setDataProvider(dp);
}
if (hdp instanceof ComboBox && field.isAnnotationPresent(NotNull.class)) {
com.vaadin.data.provider.Query q = new com.vaadin.data.provider.Query();
if (((ComboBox)hdp).getDataProvider().size(q) == 1) {
Object v = null;
v = ((ComboBox)hdp).getDataProvider().fetch(q).findFirst().get();
Object bean = binder.getBean();
if (bean != null && ReflectionHelper.getValue(field, bean) == null) {
ReflectionHelper.setValue(field, bean, v);
binder.setBean(bean, false);
}
}
}
});
} catch (Throwable t) {
Notifier.alert(t);
}
}
public Object convert(String s) {
return s;
}
public void addValidators(List validators) {
}
protected Binder.Binding bind(MDDBinder binder, HasValue tf, FieldInterfaced field, boolean forSearchFilter, com.vaadin.data.provider.DataProvider dp, AbstractComponent captionOwner, Converter converter, Button botonLink) {
Binder.BindingBuilder aux = binder.forField(tf);
if (!forSearchFilter && field.getDeclaringClass() != null) aux.withValidator(new BeanValidator(field.getDeclaringClass(), field.getName()));
if (converter != null) aux.withConverter(converter);
Binder.Binding binding = completeBinding(aux, binder, field, captionOwner);
if (dp != null && dp instanceof JPQLListDataProvider) {
JPQLListDataProvider ldp = (JPQLListDataProvider) dp;
binding.getField().addValueChangeListener(e -> {
ldp.refresh();
});
}
if (!forSearchFilter && field.getDeclaringClass() != null && field.getType().isAnnotationPresent(Entity.class)) {
binding.getField().addValueChangeListener(e -> {
if (botonLink != null) botonLink.setVisible(e.getValue() != null);
});
}
if (botonLink != null) botonLink.setVisible(tf.getValue() != null);
return binding;
}
private Object getInstance(FieldInterfaced field, Object rawValue) {
if (rawValue == null || "".equals(rawValue)) return null;
if (field.getType().isAssignableFrom(rawValue.getClass())) return rawValue;
try {
Object id = rawValue;
if (rawValue instanceof String) {
FieldInterfaced idField = ReflectionHelper.getIdField(field.getType());
if (Long.class.equals(idField.getType()) || long.class.equals(idField.getType())) id = Long.parseLong((String) rawValue);
if (Integer.class.equals(idField.getType()) || int.class.equals(idField.getType())) id = Integer.parseInt((String) rawValue);
}
return JPAHelper.find(field.getType(), id);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return null;
}
}