mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-02 19:27:57 +08:00
MenuBuilder eagerly creates MenuCommand and loads execution params for all menu items #984
This commit is contained in:
parent
134d0903b1
commit
6a8a3dd541
@ -17,7 +17,6 @@
|
||||
|
||||
package com.haulmont.cuba.gui.config;
|
||||
|
||||
import com.haulmont.bali.util.Dom4j;
|
||||
import com.haulmont.cuba.core.app.DataService;
|
||||
import com.haulmont.cuba.core.entity.Entity;
|
||||
import com.haulmont.cuba.core.global.*;
|
||||
@ -43,31 +42,29 @@ import java.util.function.Consumer;
|
||||
public class MenuCommand {
|
||||
|
||||
protected MenuItem item;
|
||||
|
||||
protected MenuItemCommand command;
|
||||
|
||||
public MenuCommand(MenuItem item) {
|
||||
this.item = item;
|
||||
|
||||
createCommand();
|
||||
this.command = createCommand(item);
|
||||
}
|
||||
|
||||
protected void createCommand() {
|
||||
protected MenuItemCommand createCommand(MenuItem item) {
|
||||
Map<String, Object> params = loadParams(item.getDescriptor(), item.getScreen());
|
||||
|
||||
if (StringUtils.isNotEmpty(item.getScreen())) {
|
||||
command = new ScreenCommand(item.getScreen(), item.getDescriptor(), params);
|
||||
return;
|
||||
return new ScreenCommand(item.getScreen(), item.getDescriptor(), params);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(item.getRunnableClass())) {
|
||||
command = new RunnableClassCommand(item.getRunnableClass(), params);
|
||||
return;
|
||||
return new RunnableClassCommand(item.getRunnableClass(), params);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(item.getBean())) {
|
||||
command = new BeanCommand(item.getBean(), item.getBeanMethod(), params);
|
||||
return new BeanCommand(item.getBean(), item.getBeanMethod(), params);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
@ -84,7 +81,8 @@ public class MenuCommand {
|
||||
|
||||
protected Map<String, Object> loadParams(Element descriptor, String screen) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
for (Element element : Dom4j.elements(descriptor, "param")) {
|
||||
|
||||
for (Element element : descriptor.elements("param")) {
|
||||
String value = element.attributeValue("value");
|
||||
EntityLoadInfo info = EntityLoadInfo.parse(value);
|
||||
if (info == null) {
|
||||
@ -94,8 +92,9 @@ public class MenuCommand {
|
||||
} else {
|
||||
if (value.startsWith("${") && value.endsWith("}")) {
|
||||
String property = AppContext.getProperty(value.substring(2, value.length() - 1));
|
||||
if (!StringUtils.isEmpty(property))
|
||||
if (!StringUtils.isEmpty(property)) {
|
||||
value = property;
|
||||
}
|
||||
}
|
||||
params.put(element.attributeValue("name"), value);
|
||||
}
|
||||
@ -127,7 +126,7 @@ public class MenuCommand {
|
||||
String getDescription();
|
||||
}
|
||||
|
||||
protected class ScreenCommand implements MenuItemCommand {
|
||||
protected static class ScreenCommand implements MenuItemCommand {
|
||||
|
||||
protected String screen;
|
||||
protected Element descriptor;
|
||||
@ -147,8 +146,6 @@ public class MenuCommand {
|
||||
openType = OpenType.valueOf(openTypeStr);
|
||||
}
|
||||
|
||||
WindowManager wm = AppBeans.get(WindowManagerProvider.class).get();
|
||||
|
||||
if (openType.getOpenMode() == OpenMode.DIALOG) {
|
||||
String resizable = descriptor.attributeValue("resizable");
|
||||
if (StringUtils.isNotEmpty(resizable)) {
|
||||
@ -159,7 +156,10 @@ public class MenuCommand {
|
||||
WindowInfo windowInfo = AppBeans.get(WindowConfig.class).getWindowInfo(screen);
|
||||
|
||||
final String id = windowInfo.getId();
|
||||
if (id.endsWith(Window.CREATE_WINDOW_SUFFIX) || id.endsWith(Window.EDITOR_WINDOW_SUFFIX)) {
|
||||
|
||||
WindowManager wm = AppBeans.get(WindowManagerProvider.class).get();
|
||||
if (id.endsWith(Window.CREATE_WINDOW_SUFFIX)
|
||||
|| id.endsWith(Window.EDITOR_WINDOW_SUFFIX)) {
|
||||
Entity entityItem;
|
||||
if (params.containsKey("item")) {
|
||||
entityItem = (Entity) params.get("item");
|
||||
@ -188,7 +188,7 @@ public class MenuCommand {
|
||||
}
|
||||
}
|
||||
|
||||
protected class BeanCommand implements MenuItemCommand {
|
||||
protected static class BeanCommand implements MenuItemCommand {
|
||||
|
||||
protected String bean;
|
||||
protected String beanMethod;
|
||||
@ -210,9 +210,9 @@ public class MenuCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
MethodUtils.invokeMethod(beanInstance, beanMethod, null);
|
||||
MethodUtils.invokeMethod(beanInstance, beanMethod, (Object[]) null);
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
throw new RuntimeException("Unable to execute bean method", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,7 +222,7 @@ public class MenuCommand {
|
||||
}
|
||||
}
|
||||
|
||||
protected class RunnableClassCommand implements MenuItemCommand {
|
||||
protected static class RunnableClassCommand implements MenuItemCommand {
|
||||
|
||||
protected String runnableClass;
|
||||
protected Map<String, Object> params;
|
||||
@ -232,6 +232,7 @@ public class MenuCommand {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run() {
|
||||
Class<?> clazz = AppBeans.get(Scripting.class).loadClass(runnableClass);
|
||||
@ -239,22 +240,23 @@ public class MenuCommand {
|
||||
throw new IllegalStateException(String.format("Can't load class: %s", runnableClass));
|
||||
}
|
||||
|
||||
if (!Runnable.class.isAssignableFrom(clazz) && !Consumer.class.isAssignableFrom(clazz)) {
|
||||
throw new IllegalStateException(String.format("Class \"%s\" should implement Runnable or Consumer<Map<String, Object>>", runnableClass));
|
||||
if (!Runnable.class.isAssignableFrom(clazz)
|
||||
&& !Consumer.class.isAssignableFrom(clazz)) {
|
||||
throw new IllegalStateException(String.format("Class \"%s\" must implement Runnable or Consumer<Map<String, Object>>", runnableClass));
|
||||
}
|
||||
|
||||
Object classInstance;
|
||||
try {
|
||||
Object classInstance = clazz.newInstance();
|
||||
|
||||
if (classInstance instanceof Consumer) {
|
||||
((Consumer) classInstance).accept(params);
|
||||
return;
|
||||
}
|
||||
|
||||
((Runnable) classInstance).run();
|
||||
classInstance = clazz.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new DevelopmentException(String.format("Failed to get a new instance of %s", runnableClass));
|
||||
}
|
||||
|
||||
if (classInstance instanceof Consumer) {
|
||||
((Consumer) classInstance).accept(params);
|
||||
} else {
|
||||
((Runnable) classInstance).run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -353,7 +353,7 @@ public class WebAppMenu extends WebAbstractComponent<CubaMenuBar> implements App
|
||||
this.command = command;
|
||||
|
||||
if (command != null) {
|
||||
delegateItem.setCommand(event -> this.command.accept(this));
|
||||
delegateItem.setCommand(this::menuSelected);
|
||||
} else {
|
||||
delegateItem.setCommand(null);
|
||||
}
|
||||
@ -428,5 +428,9 @@ public class WebAppMenu extends WebAbstractComponent<CubaMenuBar> implements App
|
||||
protected void setSeparator(boolean separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
protected void menuSelected(@SuppressWarnings("unused") MenuBar.MenuItem event) {
|
||||
this.command.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -483,7 +483,7 @@ public class WebSideMenu extends WebAbstractComponent<CubaSideMenu> implements S
|
||||
this.command = command;
|
||||
|
||||
if (command != null) {
|
||||
delegateItem.setCommand(event -> this.command.accept(this));
|
||||
delegateItem.setCommand(this::menuSelected);
|
||||
} else {
|
||||
delegateItem.setCommand(null);
|
||||
}
|
||||
@ -564,5 +564,10 @@ public class WebSideMenu extends WebAbstractComponent<CubaSideMenu> implements S
|
||||
}
|
||||
return ((MenuItemWrapper) delegateItem.getParent()).getMenuItem();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void menuSelected(CubaSideMenu.MenuItemTriggeredEvent event) {
|
||||
this.command.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -103,7 +103,7 @@ public class MenuBuilder {
|
||||
done = true;
|
||||
if (item.hasChildren()) {
|
||||
AppMenu.MenuItem[] children =
|
||||
item.getChildren().toArray(new AppMenu.MenuItem[item.getChildren().size()]);
|
||||
item.getChildren().toArray(new AppMenu.MenuItem[0]);
|
||||
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
AppMenu.MenuItem child = children[i];
|
||||
@ -191,10 +191,7 @@ public class MenuBuilder {
|
||||
}
|
||||
|
||||
protected Consumer<AppMenu.MenuItem> createMenuCommandExecutor(MenuItem item) {
|
||||
MenuCommand menuCommand = new MenuCommand(item);
|
||||
|
||||
return menuItem ->
|
||||
menuCommand.execute();
|
||||
return new MenuCommandExecutor(item);
|
||||
}
|
||||
|
||||
protected boolean isMenuItemEmpty(AppMenu.MenuItem menuItem) {
|
||||
@ -233,4 +230,18 @@ public class MenuBuilder {
|
||||
menuItem.setIcon(conf.getIcon());
|
||||
}
|
||||
}
|
||||
|
||||
public static class MenuCommandExecutor implements Consumer<AppMenu.MenuItem> {
|
||||
private final MenuItem item;
|
||||
|
||||
public MenuCommandExecutor(MenuItem item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(AppMenu.MenuItem menuItem) {
|
||||
MenuCommand command = new MenuCommand(item);
|
||||
command.execute();
|
||||
}
|
||||
}
|
||||
}
|
@ -82,7 +82,7 @@ public class SideMenuBuilder {
|
||||
|
||||
protected void removeExtraSeparators(SideMenu menuBar) {
|
||||
List<SideMenu.MenuItem> menuItems = menuBar.getMenuItems();
|
||||
for (SideMenu.MenuItem item : menuItems.toArray(new SideMenu.MenuItem[menuItems.size()])) {
|
||||
for (SideMenu.MenuItem item : menuItems.toArray(new SideMenu.MenuItem[0])) {
|
||||
removeExtraSeparators(item);
|
||||
if (isMenuItemEmpty(item)) {
|
||||
menuBar.removeMenuItem(item);
|
||||
@ -97,7 +97,7 @@ public class SideMenuBuilder {
|
||||
// SideMenu does not support separator elements
|
||||
if (item.hasChildren()) {
|
||||
SideMenu.MenuItem[] menuItems =
|
||||
item.getChildren().toArray(new SideMenu.MenuItem[item.getChildren().size()]);
|
||||
item.getChildren().toArray(new SideMenu.MenuItem[0]);
|
||||
|
||||
for (SideMenu.MenuItem child : menuItems) {
|
||||
removeExtraSeparators(child);
|
||||
@ -174,10 +174,7 @@ public class SideMenuBuilder {
|
||||
}
|
||||
|
||||
protected Consumer<SideMenu.MenuItem> createMenuCommandExecutor(MenuItem item) {
|
||||
MenuCommand command = new MenuCommand(item);
|
||||
|
||||
return event ->
|
||||
command.execute();
|
||||
return new MenuCommandExecutor(item);
|
||||
}
|
||||
|
||||
protected boolean isMenuItemEmpty(SideMenu.MenuItem menuItem) {
|
||||
@ -235,4 +232,18 @@ public class SideMenuBuilder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MenuCommandExecutor implements Consumer<SideMenu.MenuItem> {
|
||||
private final MenuItem item;
|
||||
|
||||
public MenuCommandExecutor(MenuItem item) {
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SideMenu.MenuItem menuItem) {
|
||||
MenuCommand command = new MenuCommand(item);
|
||||
command.execute();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user