com.haulmont.cuba.web.gui.components.mainwindow.WebAppMenu.java Source code

Java tutorial

Introduction

Here is the source code for com.haulmont.cuba.web.gui.components.mainwindow.WebAppMenu.java

Source

/*
 * Copyright (c) 2008-2016 Haulmont.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.haulmont.cuba.web.gui.components.mainwindow;

import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.gui.TestIdManager;
import com.haulmont.cuba.gui.components.mainwindow.AppMenu;
import com.haulmont.cuba.web.AppUI;
import com.haulmont.cuba.web.gui.components.WebAbstractComponent;
import com.haulmont.cuba.web.gui.components.WebComponentsHelper;
import com.haulmont.cuba.web.gui.icons.IconResolver;
import com.haulmont.cuba.web.sys.MenuBuilder;
import com.haulmont.cuba.web.toolkit.ui.CubaMenuBar;
import com.vaadin.server.ClientConnector;
import com.vaadin.server.Resource;
import com.vaadin.ui.MenuBar;
import org.apache.commons.lang.StringUtils;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import static com.haulmont.bali.util.Preconditions.checkNotNullArgument;

public class WebAppMenu extends WebAbstractComponent<CubaMenuBar> implements AppMenu {

    protected Map<String, MenuItem> allItemsIds = new HashMap<>();
    protected Map<MenuBar.MenuItem, MenuItem> viewModelMap = new HashMap<>();

    public static final String MENU_STYLENAME = "c-main-menu";

    public WebAppMenu() {
        component = new CubaMenuBar();
        component.addStyleName(MENU_STYLENAME);

        component.addAttachListener(this::handleAttach);
    }

    protected void handleAttach(ClientConnector.AttachEvent event) {
        AppUI appUi = (AppUI) component.getUI();
        if (appUi == null || !appUi.isTestMode()) {
            return;
        }

        for (Map.Entry<String, MenuItem> entry : allItemsIds.entrySet()) {
            assignTestIds(entry.getValue(), entry.getKey());
        }
    }

    @Override
    public void setStyleName(String name) {
        super.setStyleName(name);

        component.addStyleName(MENU_STYLENAME);
    }

    @Override
    public String getStyleName() {
        return StringUtils.normalizeSpace(super.getStyleName().replace(MENU_STYLENAME, ""));
    }

    @Override
    public void loadMenu() {
        MenuBuilder menuBuilder = AppBeans.getPrototype(MenuBuilder.NAME);
        menuBuilder.build(this);
    }

    @Override
    public MenuItem createMenuItem(String id) {
        return createMenuItem(id, null, null, null);
    }

    @Override
    public MenuItem createMenuItem(String id, String caption) {
        return createMenuItem(id, caption, null, null);
    }

    @Override
    public MenuItem createMenuItem(String id, String caption, @Nullable String icon,
            @Nullable Consumer<MenuItem> command) {
        checkNotNullArgument(id);
        checkItemIdDuplicate(id);

        MenuItem menuItem = new MenuItemImpl(this, id);
        MenuBar.MenuItem delegateItem = component.createMenuItem(caption, WebComponentsHelper.getIcon(icon), null);
        if (command != null) {
            delegateItem.setCommand(selectedItem -> command.accept(menuItem));
        }
        ((MenuItemImpl) menuItem).setDelegateItem(delegateItem);

        menuItem.setCaption(caption);
        menuItem.setIcon(icon);
        menuItem.setCommand(command);

        return menuItem;
    }

    protected void assignTestIds(MenuItem menuItem, String id) {
        AppUI ui = (AppUI) component.getUI();
        if (ui == null || !ui.isTestMode())
            return;

        MenuBar.MenuItem delegateItem = ((MenuItemImpl) menuItem).getDelegateItem();
        component.setCubaId(delegateItem, id);

        TestIdManager testIdManager = ui.getTestIdManager();
        String testId = component.getId() + "_" + id;

        component.setTestId(delegateItem, testIdManager.reserveId(testId));
    }

    @Override
    public void addMenuItem(MenuItem menuItem) {
        checkNotNullArgument(menuItem);
        checkItemIdDuplicate(menuItem.getId());
        checkItemOwner(menuItem);

        component.addMenuItem(((MenuItemImpl) menuItem).getDelegateItem());
        registerMenuItem(menuItem);

        assignTestIds(menuItem, menuItem.getId());
    }

    @Override
    public void addMenuItem(MenuItem menuItem, int index) {
        checkNotNullArgument(menuItem);
        checkItemIdDuplicate(menuItem.getId());
        checkItemOwner(menuItem);

        component.addMenuItem(((MenuItemImpl) menuItem).getDelegateItem(), index);
        registerMenuItem(menuItem);

        assignTestIds(menuItem, menuItem.getId());
    }

    protected void registerMenuItem(MenuItem menuItem) {
        allItemsIds.put(menuItem.getId(), menuItem);
        viewModelMap.put(((MenuItemImpl) menuItem).getDelegateItem(), menuItem);
    }

    @Override
    public void removeMenuItem(MenuItem menuItem) {
        checkNotNullArgument(menuItem);
        checkItemOwner(menuItem);

        component.removeMenuItem(((MenuItemImpl) menuItem).getDelegateItem());
        unregisterItem(menuItem);
    }

    @Override
    public void removeMenuItem(int index) {
        MenuBar.MenuItem delegateItem = component.getMenuItems().get(index);
        component.removeMenuItem(delegateItem);
        unregisterItem(viewModelMap.get(delegateItem));
    }

    protected void unregisterItem(MenuItem menuItem) {
        allItemsIds.remove(menuItem.getId());
        viewModelMap.remove(((MenuItemImpl) menuItem).getDelegateItem());
    }

    @Nullable
    @Override
    public MenuItem getMenuItem(String id) {
        return allItemsIds.get(id);
    }

    @Override
    public MenuItem getMenuItemNN(String id) {
        MenuItem menuItem = allItemsIds.get(id);
        if (menuItem == null) {
            throw new IllegalArgumentException("Unable to find menu item with id: " + id);
        }
        return menuItem;
    }

    @Override
    public List<MenuItem> getMenuItems() {
        return component.getMenuItems().stream().map(viewItem -> viewModelMap.get(viewItem))
                .collect(Collectors.toList());
    }

    @Override
    public boolean hasMenuItems() {
        return component.hasMenuItems();
    }

    protected void checkItemIdDuplicate(String id) {
        if (allItemsIds.containsKey(id)) {
            throw new IllegalArgumentException(String.format("MenuItem with id \"%s\" already exists", id));
        }
    }

    protected void checkItemOwner(MenuItem item) {
        if (item.getMenu() != this) {
            throw new IllegalArgumentException("MenuItem is not created by this menu");
        }
    }

    @Override
    public MenuItem createSeparator() {
        MenuItemImpl menuItem = new MenuItemImpl(this, null);
        menuItem.setSeparator(true);

        MenuBar.MenuItem separator = component.createSeparator();
        menuItem.setDelegateItem(separator);

        return menuItem;
    }

    @Override
    public void setMenuItemShortcutCaption(MenuItem menuItem, String shortcut) {
        component.setShortcut(((MenuItemImpl) menuItem).getDelegateItem(), shortcut);
    }

    @Override
    public int getTabIndex() {
        return component.getTabIndex();
    }

    @Override
    public void setTabIndex(int tabIndex) {
        component.setTabIndex(tabIndex);
    }

    protected static class MenuItemImpl implements MenuItem {
        protected WebAppMenu menu;
        protected String id;
        protected MenuBar.MenuItem delegateItem;
        protected Consumer<MenuItem> command;

        protected String icon;
        protected boolean separator;

        public MenuItemImpl(WebAppMenu menu, String id) {
            this.menu = menu;
            this.id = id;
        }

        @Override
        public String getId() {
            return id;
        }

        @Override
        public AppMenu getMenu() {
            return menu;
        }

        public MenuBar.MenuItem getDelegateItem() {
            return delegateItem;
        }

        public void setDelegateItem(MenuBar.MenuItem delegateItem) {
            this.delegateItem = delegateItem;
        }

        @Override
        public String getCaption() {
            return delegateItem.getText();
        }

        @Override
        public void setCaption(String caption) {
            delegateItem.setText(caption);
        }

        @Override
        public String getDescription() {
            return delegateItem.getDescription();
        }

        @Override
        public void setDescription(String description) {
            delegateItem.setDescription(description);
        }

        @Override
        public String getIcon() {
            return icon;
        }

        @Override
        public void setIcon(String icon) {
            this.icon = icon;

            if (icon != null) {
                Resource iconResource = AppBeans.get(IconResolver.class).getIconResource(this.icon);
                delegateItem.setIcon(iconResource);
            } else {
                delegateItem.setIcon(null);
            }
        }

        @Override
        public boolean isVisible() {
            return delegateItem.isVisible();
        }

        @Override
        public void setVisible(boolean visible) {
            delegateItem.setVisible(visible);
        }

        @Override
        public String getStyleName() {
            return delegateItem.getStyleName();
        }

        @Override
        public void setStyleName(String styleName) {
            delegateItem.setStyleName(styleName);
        }

        @Override
        public Consumer<MenuItem> getCommand() {
            return command;
        }

        @Override
        public void setCommand(Consumer<MenuItem> command) {
            this.command = command;

            if (command != null) {
                delegateItem.setCommand(event -> this.command.accept(this));
            } else {
                delegateItem.setCommand(null);
            }
        }

        @Override
        public void addChildItem(MenuItem menuItem) {
            MenuBar.MenuItem childItem = ((MenuItemImpl) menuItem).getDelegateItem();
            if (childItem.getText() == null) {
                throw new IllegalArgumentException("Caption cannot be null");
            }

            MenuBar.MenuItem delegateItem = this.getDelegateItem();

            // The only place where the parent is set
            childItem.setParent(delegateItem);
            delegateItem.getChildren().add(childItem);
            menu.registerMenuItem(menuItem);

            menu.getComponent().markAsDirty();
        }

        @Override
        public void addChildItem(MenuItem menuItem, int index) {
            MenuBar.MenuItem childItem = ((MenuItemImpl) menuItem).getDelegateItem();
            if (childItem.getText() == null) {
                throw new IllegalArgumentException("Caption cannot be null");
            }

            MenuBar.MenuItem delegateItem = this.getDelegateItem();

            // The only place where the parent is set
            childItem.setParent(delegateItem);
            delegateItem.getChildren().add(index, childItem);
            menu.registerMenuItem(menuItem);

            menu.getComponent().markAsDirty();
        }

        @Override
        public void removeChildItem(MenuItem menuItem) {
            MenuBar.MenuItem childItem = ((MenuItemImpl) menuItem).getDelegateItem();

            getDelegateItem().getChildren().remove(childItem);
            menu.unregisterItem(menuItem);
        }

        @Override
        public void removeChildItem(int index) {
            MenuItem menuItem = getChildren().get(index);
            removeChildItem(menuItem);
            menu.unregisterItem(menuItem);
        }

        @Override
        public List<MenuItem> getChildren() {
            return delegateItem.getChildren().stream().map(menuItem -> menu.viewModelMap.get(menuItem))
                    .collect(Collectors.toList());
        }

        @Override
        public boolean hasChildren() {
            return delegateItem.hasChildren();
        }

        @Override
        public boolean isSeparator() {
            return separator;
        }

        protected void setSeparator(boolean separator) {
            this.separator = separator;
        }
    }
}