All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.web4thejob.web.util.ToolbarRenderer Maven / Gradle / Ivy

/*
 * Copyright (c) 2012-2013 Veniamin Isaias.
 *
 * This file is part of web4thejob.
 *
 * Web4thejob is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or any later version.
 *
 * Web4thejob is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with web4thejob.  If not, see .
 */

package org.web4thejob.web.util;

import org.springframework.context.annotation.Scope;
import org.web4thejob.command.*;
import org.web4thejob.message.Message;
import org.web4thejob.message.MessageAware;
import org.web4thejob.setting.SettingEnum;
import org.web4thejob.web.panel.BorderedLayoutPanel;
import org.web4thejob.web.panel.HtmlViewPanel;
import org.web4thejob.web.panel.PlaceholderPanel;
import org.zkoss.zk.ui.Component;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Separator;
import org.zkoss.zul.Space;
import org.zkoss.zul.Toolbar;

import java.util.*;

/**
 * @author Veniamin Isaias
 * @since 1.0.0
 */

@org.springframework.stereotype.Component
@Scope("prototype")
public class ToolbarRenderer implements CommandRenderer {
    // ------------------------------ FIELDS ------------------------------
    private static final CommandsSorter COMMANDS_SORTER = new CommandsSorter();
    private final Set commandOwners = new LinkedHashSet(0);
    private Component container;
    private Toolbar toolbar;
    private String align;
    private boolean supressed;

// --------------------- GETTER / SETTER METHODS ---------------------

    @Override
    public String getAlign() {
        return align;
    }

    @Override
    public void setAlign(String align) {
        this.align = align;
    }

    @Override
    public boolean isSupressed() {
        return supressed;
    }

// ------------------------ INTERFACE METHODS ------------------------


// --------------------- Interface CommandRenderer ---------------------

    @Override
    public void render() {
        final boolean isEmpty = isEmpty();
        if (toolbar != null && isEmpty) {
            reset();
            return;
        } else if (toolbar != null || isEmpty) {
            return;
        }

        toolbar = new Toolbar();
        toolbar.setAlign(align);
        container.insertBefore(toolbar, container.getFirstChild());

        if (!HtmlViewPanel.class.isInstance(getPrimaryOwner())) {
            toolbar.setStyle("border-width: 0;");
        }

        SortedMap> map = mergeCommands();

        for (final CommandEnum id : map.keySet()) {
            CommandDecorator commandDecorator = null;
            if (map.get(id).size() == 1) {
                commandDecorator = getDecorator(map.get(id).get(0));
            } else {
                for (Command command : map.get(id)) {
                    if (commandDecorator == null) {
                        commandDecorator = new DefaultDropdownCommandDecorator(command);
                    } else {
                        ((DropdownCommandDecorator) commandDecorator).add(command);
                    }
                }
            }

            if (id.isRequiresStartSeparator() && id != map.firstKey() && !isPreviousSeparator()) {
                addSeparator();
            }

            if (commandDecorator != null) {
                commandDecorator.attach(toolbar);
                commandDecorator.addMessageListener(this);
                commandDecorator.render();
            }

            if (id.isRequiresEndSeparator() && id != map.lastKey()) {
                addSeparator();
            }


            Space space = new Space();
            space.setSpacing("8px");
            space.setParent(toolbar);
        }
    }

    private boolean isPreviousSeparator() {
        Component component = toolbar.getLastChild();
        while (component != null) {
            if (Space.class.isInstance(component)) {
                component = component.getPreviousSibling();
            } else {
                break;
            }
        }

        return Separator.class.isInstance(component);
    }

    private void addSeparator() {
        Separator separator = new Separator("vertical");
        separator.setParent(toolbar);
        separator.setSclass("z-toolbarbutton");
        separator.setBar(true);
    }


    @Override
    public void reset() {
        if (toolbar != null) {
            List decorators = new ArrayList();
            for (Object item : toolbar.getChildren()) {
                CommandDecorator decorator = ((CommandDecorator) ((Component) item).getAttribute(CommandDecorator
                        .ATTRIB_DECORATOR));
                if (decorator != null) {
                    decorators.add(decorator);
                }
            }

            for (CommandDecorator decorator : decorators) {
                decorator.dettach();
            }

            toolbar.detach();
            toolbar = null;
        }
    }

    @Override
    public void setContainer(Object container) {
        if (this.container != null) throw new IllegalStateException("container can only be set once");

        if (container instanceof Panel) {
            container = ((Panel) container).getPanelchildren();
        }
        this.container = (Component) container;
    }

    @Override
    public void supress(boolean supress) {
        if (supressed != supress) {
            supressed = supress;
            reset();
        }
    }

    @Override
    public void addCommandOwner(CommandAware commandAware) {
        commandOwners.add(commandAware);
    }

    @Override
    public void removeCommandOwner(CommandAware commandAware) {
        commandOwners.remove(commandAware);
    }

    @Override
    public Set getCommandOwners() {
        return Collections.unmodifiableSet(commandOwners);
    }

// --------------------- Interface MessageAware ---------------------


    @Override
    public boolean addMessageListener(MessageAware messageAware) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void dispatchMessage(Message message) {
        processMessage(message);
    }

    @Override
    public boolean removeMessageListener(MessageAware messageAware) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set getListeners() {
        throw new UnsupportedOperationException();
    }

    // --------------------- Interface MessageListener ---------------------


    @Override
    public void processMessage(Message message) {
        switch (message.getId()) {
            case AFTER_ADD:
                reset();
                render();
                break;
            case AFTER_REMOVE:
                if (toolbar != null && isEmpty()) {
                    reset();
                }
                break;
            default:
                break;
        }
    }

// -------------------------- OTHER METHODS --------------------------

    private CommandDecorator getDecorator(Command command) {
        if (CommandEnum.QUERY_LOOKUP == command.getId()) {
            return new QueryLookupCommandDecorator(command);
        } else if (CommandEnum.RENDER_SCHEME_LOOKUP == command.getId()) {
            return new RenderSchemeLookupCommandDecorator(command);
        } else if (CommandEnum.RELATED_PANELS == command.getId()) {
            return new DefaultArbitraryDropdownCommandDecorator(command);
        } else if (!command.getId().getSubcommands().isEmpty()) {
            return new DefaultSubcommandsCommandDecorator(command);
        } else {
            return new DefaultToolbarbuttonCommandDecorator(command);
        }
    }

    private boolean isEmpty() {
        CommandAware primaryOwner = getPrimaryOwner();
        if (primaryOwner.hasCommand(CommandEnum.DESIGN) || primaryOwner.hasCommand(CommandEnum.LOCALIZE) ||
                (!primaryOwner.isCommandsSupressed() && !primaryOwner.getCommands().isEmpty())) {
            return false;
        } else if (!primaryOwner.isCommandsSupressed()) {
            for (CommandAware owner : commandOwners) {
                if (owner instanceof CommandMerger) {
                    if (!((CommandMerger) owner).getMergedCommands().isEmpty()) {
                        return false;
                    }
                } else {
                    if (!owner.getCommands().isEmpty()) {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    @Override
    public CommandAware getPrimaryOwner() {
        if (!commandOwners.isEmpty()) {
            return commandOwners.iterator().next();
        }
        return null;
    }

    protected boolean isMergable(Command command) {
        boolean isPrimaryOwner = command.getOwner().equals(getPrimaryOwner());

        if (supressed && command.getId() != CommandEnum.DESIGN && command.getId() != CommandEnum.LOCALIZE) {
            // always show settiings and localization commands
            return false;
        } else if ((command.getId() == CommandEnum.DESIGN || command.getId() == CommandEnum.LOCALIZE) &&
                !isPrimaryOwner) {
            // don't integrate settings and localization command for child panels
            return false;
        } else if (command instanceof Subcommand) {
            return false;
        } else if (!isPrimaryOwner && command.getId().isCrud() && command.getOwner() instanceof org.web4thejob.web.panel
                .Panel) {
            // special toolbar rendering hint
            if (getPrimaryOwner() instanceof BorderedLayoutPanel && command.getArg(CommandMerger
                    .ATTRIB_COMMAND_MERGER, CommandMerger.class) != null) {
                CommandMerger commandMerger = command.getArg(CommandMerger.ATTRIB_COMMAND_MERGER, CommandMerger.class);
                if (commandMerger.equals(((BorderedLayoutPanel) getPrimaryOwner()).getNorth())) {
                    return !((BorderedLayoutPanel) getPrimaryOwner()).getSettingValue(SettingEnum
                            .NORTH_EXCLUDE_CRUD_COMMANDS, false);
                } else if (commandMerger.equals(((BorderedLayoutPanel) getPrimaryOwner()).getSouth())) {
                    return !((BorderedLayoutPanel) getPrimaryOwner()).getSettingValue(SettingEnum
                            .SOUTH_EXCLUDE_CRUD_COMMANDS, false);
                } else if (commandMerger.equals(((BorderedLayoutPanel) getPrimaryOwner()).getCenter())) {
                    return !((BorderedLayoutPanel) getPrimaryOwner()).getSettingValue(SettingEnum
                            .CENTER_EXCLUDE_CRUD_COMMANDS, false);
                } else if (commandMerger.equals(((BorderedLayoutPanel) getPrimaryOwner()).getWest())) {
                    return !((BorderedLayoutPanel) getPrimaryOwner()).getSettingValue(SettingEnum
                            .WEST_EXCLUDE_CRUD_COMMANDS, false);
                } else if (commandMerger.equals(((BorderedLayoutPanel) getPrimaryOwner()).getEast())) {
                    return !((BorderedLayoutPanel) getPrimaryOwner()).getSettingValue(SettingEnum
                            .EAST_EXCLUDE_CRUD_COMMANDS, false);
                }
            } else {
                Object val = (((org.web4thejob.web.panel.Panel) command.getOwner()).getAttribute(CommandRenderer
                        .ATTRIB_SUPPRESS_CRUD_COMMANDS));
                if (val instanceof Boolean) {
                    return !((Boolean) val);
                }
            }

        }

        return true;
    }


    private SortedMap> mergeCommands() {
        SortedMap> map = new TreeMap>(COMMANDS_SORTER);

        for (CommandAware owner : commandOwners) {
            if (owner instanceof PlaceholderPanel && !owner.equals(getPrimaryOwner())) {
                continue;
            }

            SortedSet commands;
            if (owner instanceof CommandMerger) {
                commands = ((CommandMerger) owner).getMergedCommands();
            } else {
                commands = owner.getCommands();
            }
            for (final Command command : commands) {
                if (isMergable(command)) {
                    if (map.containsKey(command.getId())) {
                        if (!map.get(command.getId()).contains(command)) {
                            map.get(command.getId()).add(command);
                        }
                    } else {
                        List list = new ArrayList();
                        list.add(command);
                        map.put(command.getId(), list);
                    }
                }
            }

        }

        return map;
    }

    private static class CommandsSorter implements Comparator {

        @Override
        public int compare(CommandEnum o1, CommandEnum o2) {
            Integer i1 = (o1.getSubcommands().isEmpty() ? 10000 : 0) + o1.ordinal();
            Integer i2 = (o2.getSubcommands().isEmpty() ? 10000 : 0) + o2.ordinal();
            return i1.compareTo(i2);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy