io.mateu.mdd.vaadin.MateuUI Maven / Gradle / Ivy
The newest version!
package io.mateu.mdd.vaadin;
import com.google.common.base.Strings;
import com.vaadin.navigator.CustomNavigator;
import com.vaadin.navigator.Navigator;
import com.vaadin.server.Page;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServletRequest;
import com.vaadin.server.WrappedHttpSession;
import com.vaadin.ui.*;
import elemental.json.JsonArray;
import io.mateu.mdd.core.MDD;
import io.mateu.mdd.core.app.AbstractApplication;
import io.mateu.mdd.core.app.AbstractArea;
import io.mateu.mdd.core.app.MateuApp;
import io.mateu.mdd.core.interfaces.PersistentPojo;
import io.mateu.mdd.core.ui.MDDUIAccessor;
import io.mateu.mdd.shared.interfaces.App;
import io.mateu.mdd.shared.interfaces.MenuEntry;
import io.mateu.mdd.shared.interfaces.UserPrincipal;
import io.mateu.mdd.shared.reflection.FieldInterfaced;
import io.mateu.mdd.shared.reflection.IFieldBuilder;
import io.mateu.mdd.shared.ui.IMDDUI;
import io.mateu.mdd.vaadin.components.app.main.MainComponent;
import io.mateu.mdd.vaadin.components.app.views.firstLevel.AreaComponent;
import io.mateu.mdd.vaadin.components.app.views.firstLevel.MenuComponent;
import io.mateu.mdd.vaadin.components.fieldBuilders.AbstractFieldBuilder;
import io.mateu.mdd.vaadin.components.views.*;
import io.mateu.mdd.vaadin.navigation.MateuViewProvider;
import io.mateu.mdd.vaadin.navigation.View;
import io.mateu.mdd.vaadin.navigation.ViewStack;
import io.mateu.mdd.vaadin.util.VaadinHelper;
import io.mateu.mdd.vaadin.views.BrokenLinkView;
import io.mateu.reflection.ReflectionHelper;
import io.mateu.security.MateuSecurityManager;
import io.mateu.util.Helper;
import io.mateu.util.notification.Notifier;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.persistence.Entity;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Slf4j
public class MateuUI extends UI implements IMDDUI {
private Navigator navigator;
private AbstractApplication app;
private MateuViewProvider viewProvider;
private ViewStack stack;
private Set pendingSelection;
private Object pendingResult;
private String pendingFocusedSectionId;
private MainComponent main;
private AbstractArea area;
private MateuSecurityManager securityManager;
List locales = Arrays.asList(new Locale("en"),
new Locale("es"),
new Locale("fr"),
new Locale("ru"),
new Locale("ar"),
new Locale("zh"),
new Locale("de"),
new Locale("it"));
public static MateuUI get() {
return (MateuUI) UI.getCurrent();
}
public MainComponent getMain() {
return main;
}
public void setCurrentEditor(EditorViewComponent editor) {
viewProvider.setCurrentEditor(editor);
}
public EditorViewComponent getCurrentEditor() {
return viewProvider != null?viewProvider.getCurrentEditor():null;
}
public Set getSelectedRows() {
Set selectedRows = viewProvider != null && viewProvider.getCurrentEditor() != null
&& viewProvider.getCurrentEditor().getListViewComponent() != null
? viewProvider.getCurrentEditor().getListViewComponent().getSelection() : null;
if (selectedRows == null) {
if (viewProvider != null && viewProvider.getLastView() != null
&& viewProvider.getLastView() != null
&& viewProvider.getLastView().getViewComponent() instanceof ListViewComponent) {
selectedRows = ((ListViewComponent) viewProvider.getLastView()
.getViewComponent()).getSelection();
}
}
if (selectedRows == null) {
if (viewProvider != null && viewProvider.getLastView() != null
&& viewProvider.getLastView() != null
&& viewProvider.getLastView().getViewComponent() instanceof MethodParametersViewComponent
&& ((MethodParametersViewComponent) viewProvider.getLastView().getViewComponent()).getListViewComponent() != null) {
selectedRows = ((MethodParametersViewComponent) viewProvider.getLastView().getViewComponent()).getListViewComponent().getSelection();
}
}
if (selectedRows == null) {
selectedRows = new HashSet();
}
return selectedRows;
}
public String getPendingFocusedSectionId() {
return pendingFocusedSectionId;
}
public void setPendingFocusedSectionId(String pendingFocusedSectionId) {
this.pendingFocusedSectionId = pendingFocusedSectionId;
}
@Override
protected void init(VaadinRequest vaadinRequest) {
JavaScript.getCurrent().addFunction("pingserver", new JavaScriptFunction() {
@Override
public void call(JsonArray jsonArray) {
// esto lo hace para provocar un cambio, y que viaje de arriba para abajo
// al forzar una actualización de la ui
if (getStyleName().contains("xxxxxx")) removeStyleName("xxxxxx");
else addStyleName("xxxxxx");
}
});
try {
securityManager = Helper.getImpl(MateuSecurityManager.class);
} catch (Exception e) {
log.warn("security manager implementation not found");
}
try {
initApp(vaadinRequest);
String language = resolveLocale(vaadinRequest.getHeader("Accept-Language")).getLanguage();
log.info("accepted language = " + language);
getSession().setAttribute("__language", language);
setContent(main = new MainComponent(this));
stack = new ViewStack();
navigator = new CustomNavigator(this, main.panel, stack);
navigator.setErrorView(new BrokenLinkView(stack));
navigator.addProvider(viewProvider = new MateuViewProvider(stack));
} catch (Exception e) {
e.printStackTrace();
}
}
public Locale resolveLocale(String acceptLanguageHeader) {
if (StringUtils.isBlank(acceptLanguageHeader)) {
return Locale.getDefault();
}
List ranges = Locale.LanguageRange.parse(acceptLanguageHeader);
Locale locale = Locale.lookup(ranges, locales);
return locale ;
}
private void initApp(VaadinRequest vaadinRequest) throws Exception {
if (app == null) {
String k = Strings.isNullOrEmpty(getUiRootPath())?"/": getUiRootPath();
String cp = ((VaadinServletRequest)vaadinRequest).getServletContext().getContextPath();
if (k.startsWith(cp)) k = k.substring(cp.length());
if (!k.startsWith("/")) k = "/" + k;
Class uiClassFromContext = (Class) ((VaadinServletRequest) vaadinRequest).getServletContext()
.getAttribute(k + "_app");
app = new MateuApp(uiClassFromContext != null?uiClassFromContext:Object.class, vaadinRequest);
if (MDD.getClassPool() == null) MDD.setClassPool(ReflectionHelper
.createClassPool(((VaadinServletRequest)vaadinRequest).getHttpServletRequest()
.getServletContext()));
app.buildAreaAndMenuIds();
}
}
public void irA(String donde) {
navigator.navigateTo(donde);
}
@Override
public boolean isEditingNewRecord() {
return getCurrentEditor() != null
&& getCurrentEditor().isNewRecord();
}
@Override
public IFieldBuilder getFieldBuilder(FieldInterfaced field) {
IFieldBuilder r = null;
for (IFieldBuilder b : AbstractFieldBuilder.builders) if (b.isSupported(field)) {
r = b;
break;
}
return r;
}
@Override
public String getBaseUrl() {
return null;
}
@Override
public void clearStack() {
}
public MateuViewProvider getViewProvider() {
return viewProvider;
}
@Override
public String getPath(MenuEntry e) {
return app.getState(e);
}
@Override
public App getApp() {
return app;
}
@Override
public String getCurrentUserLogin() {
UserPrincipal p = securityManager != null?
securityManager.getPrincipal(((WrappedHttpSession) getSession()
.getSession()).getHttpSession()):null;
return p != null?p.getLogin():null;
}
@Override
public UserPrincipal getCurrentUser() {
//todo: completar
return null;
}
@Override
public Collection getColumnFields(Class targetType) {
return ListViewComponent.getColumnFields(targetType);
}
@Override
public void updateTitle(String title) {
//todo: completar
}
@Override
public boolean isMobile() {
return false;
}
@Override
public String getCurrentState() {
return navigator.getCurrentNavigationState();
}
@Override
public void go(String relativePath) {
String path = stack.getState(stack.getLast());
if (!"".equals(path) && !path.endsWith("/")) path += "/";
path += relativePath;
if (path != null) {
com.vaadin.navigator.View v = viewProvider.getView(path);
if (v != null) {
navigator.navigateTo(path);
}
}
}
@Override
public void goTo(String path) {
if (path != null) {
com.vaadin.navigator.View v = viewProvider.getView(path);
if (v != null) {
if (false) { // open in new tab
String rootPath = MDDUIAccessor.getUiRootPath();
//Ui.getcurrent.open(new external resources(https://www.youtube.com/),"_blank",false)
if (!path.startsWith("/")) path = rootPath + "/" + path;
else path = rootPath + path;
Page.getCurrent().open(path, "_blank", false);
} else navigator.navigateTo(path);
}
}
}
@Override
public void goBack() {
if (stack.getLast() != null && !(stack.getLast().getComponent() instanceof OwnedCollectionViewComponent)
&& stack.getLast().getComponent() instanceof EditorViewComponent
&& ((
stack.getLast().getComponent() instanceof OwnedPojoViewComponent
|| stack.getLast().getComponent() instanceof OwnedPojoViewComponent
|| stack.getLast().getComponent() instanceof OwnedCollectionViewComponent
||(PersistentPojo.class.isAssignableFrom(((EditorViewComponent)stack.getLast().getComponent())
.getModelType())
|| ((EditorViewComponent)stack.getLast().getComponent()).getModelType()
.isAnnotationPresent(Entity.class))
)
&& ((EditorViewComponent)stack.getLast().getComponent()).isModificado())
&& ((EditorViewComponent)stack.getLast().getComponent()).isCreateSaveButton()) {
VaadinHelper.saveOrDiscard("There are unsaved changes. What do you want to do?",
(EditorViewComponent) stack.getLast().getComponent(), () -> yesGoBack());
} else {
yesGoBack();
}
}
public void yesGoBack() {
View l = stack.getLast();
if (stack.size() > 1) {
View v = stack.get(stack.size() - 2);
String u = stack.getState(v);
if (v.getViewComponent() instanceof ListViewComponent) u =
((ListViewComponent) v.getViewComponent()).getUrl();
if (l.getWindowContainer() != null && !l.getWindowContainer().equals(v.getWindowContainer())) {
l.getWindowContainer().setData("noback");
l.getWindowContainer().close();
stack.pop();
viewProvider.setLastView(stack.getLast());
} else {
MDDUIAccessor.goTo(u);
}
} else {
String u = stack.getState(l);
if (!Strings.isNullOrEmpty(u) && u.contains("/")) {
u = u.substring(0, u.lastIndexOf("/"));
if (!MDDUIAccessor.isMobile() && esMenu(u))
while (esMenu(u.substring(0, u.lastIndexOf("/")))) {
u = u.substring(0, u.lastIndexOf("/"));
}
if (MDDUIAccessor.isMobile()) {
if (esInutil(u)) while (esInutil(u)) {
u = u.substring(0, u.lastIndexOf("/"));
}
}
MDDUIAccessor.goTo(u);
} else {
}
}
if (l.getComponent() instanceof EditorViewComponent) {
Object result = ((EditorViewComponent)l.getComponent()).getModel();
if (result != null && result instanceof EditorListener) ((EditorListener) result).onGoBack(result);
((EditorViewComponent) l.getComponent()).onGoBack();
}
}
public void goSibling(Object id) {
if (stack.getLast().getComponent() instanceof EditorViewComponent
&& ((PersistentPojo.class.isAssignableFrom(((EditorViewComponent)stack.getLast()
.getComponent()).getModelType())
|| ((EditorViewComponent)stack.getLast().getComponent()).getModelType()
.isAnnotationPresent(Entity.class))
&& ((EditorViewComponent)stack.getLast().getComponent()).isModificado())) {
VaadinHelper.saveOrDiscard("There are unsaved changes. What do you want to do?",
(EditorViewComponent) stack.getLast().getComponent(), () -> {
try {
yesGoSibling(id);
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
});
} else {
yesGoSibling(id);
}
}
@Override
public void open(FieldInterfaced field, Method m, Set selection) {
setPendingSelection(selection);
go(getFieldPrefix(field) + m.getName());
}
public String getFieldPrefix(FieldInterfaced field) {
if (field != null) return field.getName() + "/";
return "";
}
@Override
public void open(Method m, Set selection) {
setPendingSelection(selection);
go(m.getName());
}
@Override
public void open(Method m, Object result) {
pendingResult = result;
go(m.getName());
}
@Override
public Set getPendingSelection() {
return pendingSelection;
}
@Override
public void setPendingSelection(Set selecion) {
this.pendingSelection = selecion;
}
@Override
public Object getPendingResult() {
return pendingResult;
}
@Override
public void setPendingResult(Object result) {
this.pendingResult = result;
}
@Override
public void updateSession() {
main.getHeader().updateSession();
}
private void yesGoSibling(Object id) {
EditorViewComponent ed = null;
if (stack.getLast().getComponent() instanceof EditorViewComponent) {
ed = (EditorViewComponent) stack.getLast().getComponent();
ed.onGoBack();
}
String u = stack.getState(stack.getLast()); //
u = u.substring(0, u.lastIndexOf("/"));
if (!MDDUIAccessor.isMobile() && esMenu(u)) while (esMenu(u.substring(0, u.lastIndexOf("/")))) {
u = u.substring(0, u.lastIndexOf("/"));
}
if (MDDUIAccessor.isMobile()) {
if (esInutil(u)) while (esInutil(u)) {
u = u.substring(0, u.lastIndexOf("/"));
}
}
u += "/" + Base64.getUrlEncoder().encodeToString(id.toString().getBytes(StandardCharsets.UTF_8));
if (ed != null && ed.getView().getWindowContainer() != null) {
try {
ed.load(id);
//viewProvider.setCurrentPath(u); //todo: pendiente ver que pasa con las windows
viewProvider.getStack().getViewByState().remove(viewProvider.getStack().getStateByView()
.get(ed.getView()));
viewProvider.getStack().getStateByView().put(ed.getView(), u);
viewProvider.getStack().getViewByState().put(u, ed.getView());
} catch (Throwable throwable) {
Notifier.alert(throwable);
}
}
else MDDUIAccessor.goTo(u);
}
private boolean esInutil(String u) {
if (!Strings.isNullOrEmpty(u)) {
View v = stack.get(u);
if (v != null) {
Component c = v.getComponent();
if (c instanceof AreaComponent) {
return MDDUIAccessor.getApp().getAreas().length <= 1;
}
}
}
return false;
}
private boolean esMenu(String u) {
if (!Strings.isNullOrEmpty(u)) {
View v = stack.get(u);
if (v != null) {
Component c = v.getComponent();
if (c instanceof MenuComponent) {
return true;
}
}
}
return false;
}
public void openInWindow(View view) {
// lo mismo para buscar y para navegar en profundidad
Window w = new MateuWindow(this, stack, view.getViewComponent().getCaption());
w.addStyleName("maincomponent");
int percent = 100 - (UI.getCurrent().getWindows().size() + 1) * 5;
w.setWidth("" + percent + "%");
w.setHeight("" + percent + "%");
w.setContent(view.getViewComponent());
view.setWindowContainer(w);
w.center();
w.setModal(true);
UI.getCurrent().addWindow(w);
}
public void openInWindow(Component component) {
// lo mismo para buscar y para navegar en profundidad
Window w = new MateuWindow(this, stack, component.getCaption());
w.addStyleName("maincomponent");
int percent = 100 - (UI.getCurrent().getWindows().size() + 1) * 5;
w.setWidth("" + percent + "%");
w.setHeight("" + percent + "%");
w.setContent(component);
w.center();
w.setModal(true);
UI.getCurrent().addWindow(w);
}
public static void closeWindow() {
closeWindow(true);
}
public static void closeWindow(boolean notifyClosingEvent) {
if (UI.getCurrent() != null && UI.getCurrent().getWindows().size() > 0) {
ArrayList l = new ArrayList<>(UI.getCurrent().getWindows());
Window w = l.get(l.size() - 1);
w.setData(notifyClosingEvent);
w.close();
}
}
public ViewStack getStack() {
return viewProvider.getStack();
}
public void setArea(AbstractArea area) {
this.area = area;
main.getHeader().setArea(area);
main.getHeaderForMobile().setArea(area);
}
}