ru.codeinside.adm.ui.TreeTableOrganization.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.adm.ui.TreeTableOrganization.java

Source

/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 * Copyright (c) 2013, MPL CodeInside http://codeinside.ru
 */

package ru.codeinside.adm.ui;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSet;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.validator.StringLengthValidator;
import com.vaadin.event.FieldEvents;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutAction.ModifierKey;
import com.vaadin.terminal.ExternalResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.Panel;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Tree.CollapseEvent;
import com.vaadin.ui.Tree.CollapseListener;
import com.vaadin.ui.Tree.ExpandEvent;
import com.vaadin.ui.Tree.ExpandListener;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.TwinColSelect;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;
import com.vaadin.ui.themes.Reindeer;
import org.apache.commons.lang.StringUtils;
import org.tepi.filtertable.FilterTable;
import ru.codeinside.adm.AdminServiceProvider;
import ru.codeinside.adm.UserItem;
import ru.codeinside.adm.database.Group;
import ru.codeinside.adm.database.Organization;
import ru.codeinside.adm.database.Role;
import ru.codeinside.adm.ui.employee.CertificateBlock;
import ru.codeinside.adm.ui.employee.ExecutorGroupsBlock;
import ru.codeinside.adm.ui.employee.TableEmployee;
import ru.codeinside.adm.ui.employee.TableOrganizationEmployee;
import ru.codeinside.gses.vaadin.MaskedTextField;

import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TreeTableOrganization extends HorizontalLayout implements Property.ValueChangeListener {

    protected static final String ID_PROPERTY = "id";
    protected static final String NAME_PROPERTY = "";
    private static final long serialVersionUID = -8903404478050765452L;
    private static final String NAME_ORG = "? ";
    public static Pattern GROUP = Pattern.compile("[a-zA-Z-??-][a-zA-Z-??-0-9_]*");
    final TreeTable treetable;
    private Panel panel = new Panel();
    private boolean lockExpandListener;

    public TreeTableOrganization() {
        setSizeFull();
        treetable = new TreeTable();
        treetable.setSizeFull();
        treetable.setSelectable(true);
        treetable.setMultiSelect(false);
        treetable.addListener(this);
        treetable.setImmediate(true);
        treetable.setValue(null);
        setMargin(true);
        // Add Table columns
        treetable.addContainerProperty(NAME_PROPERTY, String.class, "");

        fillTable(treetable);

        treetable.addListener(new ExpandListener() {

            private static final long serialVersionUID = 1L;

            public void nodeExpand(ExpandEvent event) {
                if (lockExpandListener) {
                    return;
                }
                Object valuePropertyEvent = event.getItemId();
                Organization org = AdminServiceProvider.get().findOrganizationById((Long) valuePropertyEvent);
                Set<Organization> childs = org.getOrganizations();
                if (!(childs.isEmpty())) {
                    treetable.setChildrenAllowed((Long) valuePropertyEvent, true);

                    for (Organization o : childs) {
                        treetable.addItem(new Object[] { o.getName() }, o.getId());
                        treetable.setCollapsed(o.getId(), true);
                    }

                    for (Organization o : childs) {
                        treetable.setParent(o.getId(), (Long) valuePropertyEvent);
                    }

                    for (Organization o : childs) {
                        treetable.setChildrenAllowed(o.getId(), !(o.getOrganizations().isEmpty()));
                    }
                }

            }
        });

        treetable.addListener(new CollapseListener() {

            private static final long serialVersionUID = 1L;

            public void nodeCollapse(CollapseEvent event) {
                if (lockExpandListener) {
                    return;
                }
                Set<Object> delete = new HashSet<Object>();
                Collection<?> children = treetable.getChildren(event.getItemId());
                if (children != null) {
                    for (Object child : children) {
                        removeRecursively(child, delete);
                    }
                }
                for (Object o : delete) {
                    treetable.setCollapsed(o, true);
                    treetable.removeItem(o);
                }
            }

            private void removeRecursively(Object object, Set<Object> delete) {
                Collection<?> children = treetable.getChildren(object);
                if (children != null) {
                    for (Object child : children) {
                        removeRecursively(child, delete);
                    }
                }
                delete.add(object);
            }
        });

        panel.setStyleName(Reindeer.PANEL_LIGHT);
        panel.setSizeFull();
        panel.addComponent(new ButtonCreateOrganization(treetable));

        final HorizontalSplitPanel horiz = new HorizontalSplitPanel();
        horiz.setSplitPosition(25); // percent
        horiz.setSizeFull();
        addComponent(horiz);
        TextField orgFilter = new TextField();
        orgFilter.setImmediate(true);
        orgFilter.setWidth(100, UNITS_PERCENTAGE);
        orgFilter.setInputPrompt("  ");
        orgFilter.addListener(new FieldEvents.TextChangeListener() {

            List<Organization> organizations;
            List<Long> organizationIds;

            @Override
            public void textChange(FieldEvents.TextChangeEvent event) {
                String name = StringUtils.trimToNull(event.getText());
                if (name != null) {
                    lockExpandListener = true;
                    organizations = AdminServiceProvider.get().findOrganizationIdsByName(name);
                    treetable.removeAllItems();
                    organizationIds = new ArrayList<Long>();
                    for (Organization org : organizations) {
                        for (Organization o1 : getPath(org)) {
                            if (!treetable.containsId(o1.getId())) {
                                treetable.addItem(new Object[] { o1.getName() }, o1.getId());
                                if (o1.getParent() != null) {
                                    treetable.setParent(o1.getId(), o1.getParent().getId());
                                }
                                treetable.setChildrenAllowed(o1.getId(), !(o1.getOrganizations().isEmpty()));
                                treetable.setCollapsed(o1.getId(), false);
                            }
                        }
                        organizationIds.add(org.getId());
                    }

                    treetable.setCellStyleGenerator(new Table.CellStyleGenerator() {
                        @Override
                        public String getStyle(Object itemId, Object propertyId) {
                            if (propertyId == null) {
                                if (!organizationIds.contains(itemId)) {
                                    return "gray";
                                }
                            }
                            return null;
                        }
                    });

                } else {
                    lockExpandListener = false;
                    treetable.removeAllItems();
                    fillTable(treetable);
                    treetable.setCellStyleGenerator(new Table.CellStyleGenerator() {
                        @Override
                        public String getStyle(Object itemId, Object propertyId) {
                            return null;
                        }
                    });
                }
            }

            private List<Organization> getPath(Organization org) {
                List<Organization> list = new LinkedList<Organization>();
                while (org != null) {
                    list.add(0, org);
                    org = org.getParent();
                }
                return list;
            }
        });
        VerticalLayout vl = new VerticalLayout();
        vl.setSpacing(true);
        vl.setSizeFull();
        vl.addComponent(orgFilter);
        vl.addComponent(treetable);
        vl.setExpandRatio(treetable, 0.9f);
        horiz.addComponent(vl);
        horiz.addComponent(panel);
    }

    @Override
    public void valueChange(ValueChangeEvent event) {
        Object valuePropertyEvent = event.getProperty().getValue();
        if (valuePropertyEvent != null) {
            showOrganization((Long) valuePropertyEvent);
        } else {
            panel.removeAllComponents();
            panel.addComponent(new ButtonCreateOrganization(treetable));
        }
    }

    void showOrganization(Long id) {
        TableEmployee tableEmployee = showOrganizationLabelsAndButtons(id);
        panel.addComponent(tableEmployee);
    }

    private TableEmployee showOrganizationLabelsAndButtons(Long id) {
        panel.removeAllComponents();
        panel.addComponent(new ButtonCreateOrganization(treetable));
        treetable.setCollapsed(id, false);
        Organization org = AdminServiceProvider.get().findOrganizationById(id);
        Label nameLabel = new Label("?: " + org.getName());
        nameLabel.setStyleName("h2");
        panel.addComponent(nameLabel);
        if (org.getCreator() != null) {
            Label creatorLabel = new Label(": " + org.getCreator().getLogin());
            panel.addComponent(creatorLabel);
        }

        Format formatter = new SimpleDateFormat("dd.MM.yyyy HH:mm");
        Label dateLabel = new Label(" ??: " + formatter.format(org.getDate()));
        panel.addComponent(dateLabel);
        panel.addComponent(groupLabel(id));
        HorizontalLayout layoutButton = new HorizontalLayout();
        layoutButton.addComponent(buttonEditOrganization(org, nameLabel));
        layoutButton.addComponent(buttonCreateOrganization(org));
        TableEmployee tableEmployee = new TableOrganizationEmployee(id);
        tableEmployee.setMargin(true, false, false, false);
        layoutButton.addComponent(buttonCreateEmployee(id));
        layoutButton.setMargin(true, false, false, false);
        layoutButton.addComponent(createGroupLabel(id));
        panel.addComponent(layoutButton);
        return tableEmployee;
    }

    private Component buttonCreateOrganization(final Organization orgHigh) {

        HorizontalLayout buttons = new HorizontalLayout();
        buttons.setSpacing(true);
        buttons.setMargin(false, true, false, false);

        final Button createOrg = new Button(" . ", new Button.ClickListener() {

            private static final long serialVersionUID = 1L;

            public void buttonClick(ClickEvent event) {
                showOrganizationLabelsAndButtons(orgHigh.getId());
                final VerticalLayout layout = new VerticalLayout();
                layout.setMargin(true);
                layout.setSpacing(true);
                panel.addComponent(layout);
                final Form form = new Form();
                form.addField(NAME_ORG, new TextField(NAME_ORG));
                form.getField(NAME_ORG).setRequired(true);
                form.getField(NAME_ORG).setRequiredError("  ");
                form.getField(NAME_ORG).addValidator(new StringLengthValidator(
                        "?      255 ?",
                        1, 255, false));
                form.getField(NAME_ORG).setWidth("500px");
                layout.addComponent(form);
                HorizontalLayout buttons = new HorizontalLayout();
                buttons.setSpacing(true);
                Button create = new Button("", new Button.ClickListener() {
                    private static final long serialVersionUID = 1L;

                    public void buttonClick(ClickEvent event) {
                        try {
                            form.commit();
                        } catch (Exception e) {
                            return;
                        }
                        String nameOrg = form.getField(NAME_ORG).getValue().toString();

                        Set<Organization> orgs = orgHigh.getOrganizations();
                        Boolean bool = true;
                        for (Organization org : orgs) {
                            if (org.getName().equals(nameOrg)) {
                                bool = false;
                                break;
                            }
                        }
                        if (bool) {
                            Organization org = AdminServiceProvider.get().createOrganization(nameOrg,
                                    getApplication().getUser().toString(), orgHigh);
                            treetable.addItem(new Object[] { org.getName() }, org.getId());
                            treetable.setCollapsed(org.getId(), true);
                            treetable.setChildrenAllowed(orgHigh.getId(), true);
                            treetable.setChildrenAllowed(org.getId(), false);
                            treetable.setParent(org.getId(), orgHigh.getId());
                            treetable.setValue(org.getId());
                            treetable.requestRepaint();
                            showOrganization(orgHigh.getId());
                            getWindow().showNotification("? " + nameOrg + " ?");
                        } else {
                            getWindow().showNotification("? c  " + nameOrg
                                    + "  ??");
                        }
                    }
                });
                buttons.addComponent(create);
                addButtonCancel(orgHigh, buttons);
                form.getFooter().addComponent(buttons);
            }
        });
        buttons.addComponent(createOrg);
        return buttons;
    }

    private Component buttonEditOrganization(final Organization org, final Label nameLabel) {

        setSpacing(true);

        HorizontalLayout buttons = new HorizontalLayout();
        buttons.setSpacing(true);
        buttons.setMargin(false, true, false, false);
        addComponent(buttons);

        final Button createOrg = new Button(" ",
                new Button.ClickListener() {

                    private static final long serialVersionUID = 1L;

                    public void buttonClick(ClickEvent event) {
                        showOrganizationLabelsAndButtons(org.getId());
                        final String oldNameOrg = org.getName();
                        final VerticalLayout layout = new VerticalLayout();
                        layout.setMargin(true);
                        layout.setSpacing(true);
                        panel.addComponent(layout);
                        final Form form = new Form();
                        form.addField(NAME_ORG, new TextField(NAME_ORG));
                        form.getField(NAME_ORG).addValidator(new StringLengthValidator(
                                "?      255 ?",
                                0, 255, true));
                        form.getField(NAME_ORG).setWidth("500px");
                        form.getField(NAME_ORG).setValue(oldNameOrg);
                        layout.addComponent(form);
                        HorizontalLayout buttons = new HorizontalLayout();
                        buttons.setSpacing(true);
                        Button save = new Button("", new Button.ClickListener() {
                            private static final long serialVersionUID = 1L;

                            public void buttonClick(ClickEvent event) {
                                try {
                                    form.commit();
                                } catch (Exception e) {
                                    return;
                                }
                                String newNameOrg = form.getField(NAME_ORG).getValue().toString();
                                if (!(newNameOrg.equals(oldNameOrg) || newNameOrg.equals(""))) {
                                    org.setName(newNameOrg);
                                    AdminServiceProvider.get().updateOrganization(org);
                                    treetable.getItem(org.getId())
                                            .getItemProperty(TreeTableOrganization.NAME_PROPERTY)
                                            .setValue(newNameOrg);
                                    treetable.requestRepaint();
                                    nameLabel.setValue("?: " + newNameOrg);
                                    nameLabel.requestRepaint();
                                    // TODO :  userInfoPanel
                                    //if (AdminServiceProvider.get()
                                    //      .findEmployeeByLogin(getApplication().getUser().toString()).getOrganization()
                                    //      .getId() == org.getId()) {
                                    //   ((AdminApp) getApplication()).getUserInfoPanel().setOrganization(newNameOrg);
                                    //}
                                    showOrganization(org.getId());
                                    getWindow().showNotification(
                                            "? " + oldNameOrg + " ");
                                } else {
                                    showOrganization(org.getId());
                                    getWindow().showNotification(" ");
                                }
                            }
                        });
                        buttons.addComponent(save);
                        addButtonCancel(org, buttons);
                        form.getFooter().addComponent(buttons);

                    }

                });
        buttons.addComponent(createOrg);
        return buttons;
    }

    private void addButtonCancel(final Organization org, HorizontalLayout buttons) {
        Button cancel = new Button("", new Button.ClickListener() {

            private static final long serialVersionUID = 1L;

            public void buttonClick(ClickEvent event) {
                showOrganization(org.getId());
            }
        });
        buttons.addComponent(cancel);
    }

    private Component buttonCreateEmployee(final Long id) {
        HorizontalLayout buttons = new HorizontalLayout();
        buttons.setSpacing(true);
        buttons.setMargin(false, true, false, false);
        addComponent(buttons);
        Button createUser = new Button(" ?", new Button.ClickListener() {

            private static final long serialVersionUID = 1L;

            public void buttonClick(ClickEvent event) {
                showOrganizationLabelsAndButtons(id);
                final VerticalLayout layout = new VerticalLayout();
                layout.setMargin(true);
                layout.setSpacing(true);
                layout.setSizeFull();
                panel.addComponent(layout);

                String widthColumn = "100px";
                final TextField fieldLogin = TableEmployee.addTextField(layout, widthColumn, "");
                final PasswordField fieldPass = TableEmployee.addPasswordField(layout, widthColumn, "");
                final PasswordField fieldPassRepeat = TableEmployee.addPasswordField(layout, widthColumn,
                        " ");
                final MaskedTextField fieldSnils = TableEmployee.addMaskedTextField(layout, widthColumn,
                        "?");
                fieldSnils.setMask("###-###-### ##");
                fieldPassRepeat.addValidator(new RepeatPasswordValidator(fieldPass));
                final TextField fieldFIO = TableEmployee.addTextField(layout, widthColumn, "");
                HorizontalLayout l1 = new HorizontalLayout();
                Label labelRole = new Label("");
                labelRole.setWidth(widthColumn);
                l1.addComponent(labelRole);
                l1.setComponentAlignment(labelRole, Alignment.MIDDLE_LEFT);
                final OptionGroup roleOptionGroup = TableEmployee.createRoleOptionGroup(null);
                l1.addComponent(roleOptionGroup);
                layout.addComponent(l1);

                UserItem emptyItem = new UserItem();
                emptyItem.setGroups(ImmutableSet.<String>of());

                final CertificateBlock certificateBlock = new CertificateBlock(emptyItem);
                layout.addComponent(certificateBlock);

                final ExecutorGroupsBlock executorGroupsBlock = new ExecutorGroupsBlock(emptyItem);
                layout.addComponent(executorGroupsBlock);

                final HorizontalLayout supervisorGroupsEmp = new HorizontalLayout();
                supervisorGroupsEmp.setMargin(true, true, true, false);
                supervisorGroupsEmp.setSpacing(true);
                supervisorGroupsEmp.setCaption(
                        "?  ? ? ?");
                final FilterTable allSupervisorGroupsEmp = new FilterTable();
                allSupervisorGroupsEmp.setCaption("?");
                TableEmployee.table(supervisorGroupsEmp, allSupervisorGroupsEmp);
                final FilterTable currentSupervisorGroupsEmp = new FilterTable();
                currentSupervisorGroupsEmp.setCaption("");
                TableEmployee.table(supervisorGroupsEmp, currentSupervisorGroupsEmp);
                for (String groupName : AdminServiceProvider.get().getEmpGroupNames()) {
                    for (Group group : AdminServiceProvider.get().findGroupByName(groupName)) {
                        allSupervisorGroupsEmp.addItem(new Object[] { groupName, group.getTitle() }, groupName);
                    }
                }
                TableEmployee.addListener(allSupervisorGroupsEmp, currentSupervisorGroupsEmp);
                TableEmployee.addListener(currentSupervisorGroupsEmp, allSupervisorGroupsEmp);
                layout.addComponent(supervisorGroupsEmp);

                final HorizontalLayout supervisorGroupsOrg = new HorizontalLayout();
                supervisorGroupsOrg.setMargin(true, true, true, false);
                supervisorGroupsOrg.setSpacing(true);
                supervisorGroupsOrg.setCaption(
                        "?   ? ?");
                final FilterTable allSupervisorGroupsOrg = new FilterTable();
                allSupervisorGroupsOrg.setCaption("?");
                TableEmployee.table(supervisorGroupsOrg, allSupervisorGroupsOrg);
                final FilterTable currentSupervisorGroupsOrg = new FilterTable();
                currentSupervisorGroupsOrg.setCaption("");
                TableEmployee.table(supervisorGroupsOrg, currentSupervisorGroupsOrg);
                for (String groupName : AdminServiceProvider.get().getOrgGroupNames()) {
                    for (Group group : AdminServiceProvider.get().findGroupByName(groupName)) {
                        allSupervisorGroupsOrg.addItem(new Object[] { groupName, group.getTitle() }, groupName);
                    }
                }
                TableEmployee.addListener(allSupervisorGroupsOrg, currentSupervisorGroupsOrg);
                TableEmployee.addListener(currentSupervisorGroupsOrg, allSupervisorGroupsOrg);
                layout.addComponent(supervisorGroupsOrg);

                TableEmployee.setRolesEnabled(roleOptionGroup, certificateBlock, executorGroupsBlock,
                        supervisorGroupsEmp, supervisorGroupsOrg);
                roleOptionGroup.addListener(new Listener() {
                    private static final long serialVersionUID = 1L;

                    public void componentEvent(Event event) {
                        TableEmployee.setRolesEnabled(roleOptionGroup, certificateBlock, executorGroupsBlock,
                                supervisorGroupsEmp, supervisorGroupsOrg);
                    }
                });

                HorizontalLayout l2 = new HorizontalLayout();
                Label labelPrint = new Label("?  ?");
                labelPrint.setWidth(widthColumn);
                l2.addComponent(labelPrint);
                l2.setComponentAlignment(labelPrint, Alignment.MIDDLE_LEFT);
                final CheckBox checkBoxPrint = new CheckBox();
                checkBoxPrint.setDescription("?  ?");
                l2.addComponent(checkBoxPrint);
                layout.addComponent(l2);

                HorizontalLayout layoutButton = new HorizontalLayout();
                layoutButton.setSpacing(true);

                Button buttonUserForm = new Button("", new Button.ClickListener() {

                    private static final long serialVersionUID = -7193894183022375021L;

                    public void buttonClick(ClickEvent event) {
                        if (!fieldPassRepeat.isValid()) {
                            return;
                        }

                        String snilsFieldValue = fieldSnils.getValue() == null ? ""
                                : (String) fieldSnils.getValue();
                        String snilsValue = snilsFieldValue.replaceAll("\\D+", "");
                        Pattern snilsPattern = Pattern.compile("\\d{11}");
                        Matcher snilsMatcher = snilsPattern.matcher(snilsValue);

                        if (!snilsFieldValue.isEmpty() && !snilsMatcher.matches()) {
                            getWindow().showNotification("?  ",
                                    Window.Notification.TYPE_ERROR_MESSAGE);
                            return;
                        }

                        String loginUser = (String) fieldLogin.getValue();

                        if (!AdminServiceProvider.get().isUniqueSnils(loginUser, snilsValue)) {
                            getWindow().showNotification(" ?  ",
                                    Window.Notification.TYPE_ERROR_MESSAGE);
                            return;
                        }

                        String password = (String) fieldPass.getValue();
                        String passwordRepeat = (String) fieldPassRepeat.getValue();
                        String fio = (String) fieldFIO.getValue();
                        Set<Role> roles = (Set) roleOptionGroup.getValue();
                        TreeSet<String> groupExecutor = executorGroupsBlock.getGroups();
                        TreeSet<String> groupSupervisorEmp = new TreeSet<String>(
                                (Collection<String>) currentSupervisorGroupsEmp.getItemIds());
                        TreeSet<String> groupSupervisorOrg = new TreeSet<String>(
                                (Collection<String>) currentSupervisorGroupsOrg.getItemIds());

                        if (loginUser.equals("") || password.equals("") || passwordRepeat.equals("")
                                || fio.equals("")) {
                            getWindow().showNotification(" ? ?!",
                                    Notification.TYPE_WARNING_MESSAGE);
                        } else if (!(password.equals(passwordRepeat))) {
                            getWindow().showNotification("  ?!",
                                    Notification.TYPE_WARNING_MESSAGE);
                        } else if (AdminServiceProvider.get().findEmployeeByLogin(loginUser) == null) {
                            if (roles.contains(Role.SuperSupervisor)) {
                                groupSupervisorEmp = new TreeSet<String>(
                                        AdminServiceProvider.get().selectGroupNamesBySocial(true));
                                groupSupervisorOrg = new TreeSet<String>(
                                        AdminServiceProvider.get().selectGroupNamesBySocial(false));
                            }
                            String creator = getApplication().getUser().toString();
                            AdminServiceProvider.get().createEmployee(loginUser, password, fio, snilsValue, roles,
                                    creator, id, groupExecutor, groupSupervisorEmp, groupSupervisorOrg);
                            showOrganization(id);
                            getWindow().showNotification(" " + loginUser + " ?");
                            if (checkBoxPrint.booleanValue()) {
                                // Create a window that contains what you want to print
                                Window window = new Window();
                                window.addComponent(new Label("<h1>: " + loginUser + "</h1>\n"
                                        + "<h1>: " + password + "</h1>\n", Label.CONTENT_XHTML));
                                getApplication().addWindow(window);
                                getWindow().open(new ExternalResource(window.getURL()), "_blank", 500, 200, // Width and
                                        // height
                                        Window.BORDER_NONE);
                                window.executeJavaScript("print();");
                                window.executeJavaScript("self.close();");
                            }
                        } else {
                            getWindow().showNotification(" ?!",
                                    Notification.TYPE_WARNING_MESSAGE);
                        }

                    }
                });
                layoutButton.addComponent(buttonUserForm);
                Button buttonCancel = new Button("", new Button.ClickListener() {

                    private static final long serialVersionUID = 1L;

                    public void buttonClick(ClickEvent event) {
                        showOrganization(id);
                    }
                });
                layoutButton.addComponent(buttonCancel);
                layout.addComponent(layoutButton);

            }

        });
        createUser.addListener(this);
        buttons.addComponent(createUser);
        return buttons;
    }

    private Component groupLabel(Long id) {
        final Set<String> names = AdminServiceProvider.get().getOrgGroupNames(id);
        final HorizontalLayout layout = new HorizontalLayout();
        String s = ": ";
        if (!names.isEmpty()) {
            s += Joiner.on(", ").join(names);
        } else {
            s += " ??   ";
        }
        layout.addComponent(new Label(s));
        return layout;
    }

    Component createGroupLabel(final long id) {
        final Set<String> names = AdminServiceProvider.get().getOrgGroupNames(id);
        final Button button = new Button(
                names.isEmpty() ? " " : " ",
                new Button.ClickListener() {
                    private static final long serialVersionUID = 6657371896778851327L;

                    @Override
                    public void buttonClick(Button.ClickEvent event) {
                        createGroupEditor(id, names);
                    }
                });
        final HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        layout.setMargin(false, true, false, false);
        layout.addComponent(button);
        return layout;
    }

    // TODO:  ??!
    void createGroupEditor(final long id, final Set<String> names) {
        final Organization org = AdminServiceProvider.get().findOrganizationById(id);
        final Set<String> all = AdminServiceProvider.get().getOrgGroupNames();

        final VerticalLayout layout = new VerticalLayout();
        layout.setSpacing(true);

        final TwinColSelect twin = new TwinColSelect();
        twin.setSizeFull();
        twin.setNullSelectionAllowed(true);
        twin.setLeftColumnCaption("?");
        twin.setRightColumnCaption(" ? " + org.getName());
        twin.setImmediate(true);
        for (final String name : all) {
            twin.addItem(name);
            if (names.contains(name)) {
                twin.select(name);
            }
        }
        layout.addComponent(twin);

        final HorizontalLayout h = new HorizontalLayout();
        h.setSpacing(true);
        Button cancel = new Button("", new Button.ClickListener() {

            private static final long serialVersionUID = -2885182304929510066L;

            @Override
            public void buttonClick(Button.ClickEvent event) {
                showOrganization(id);
            }
        });
        cancel.setClickShortcut(KeyCode.ESCAPE, 0);

        Button ok = new Button("", new Button.ClickListener() {

            private static final long serialVersionUID = -3182280627040233669L;

            @Override
            public void buttonClick(Button.ClickEvent event) {
                AdminServiceProvider.get().setOrgGroupNames(id,
                        new TreeSet<String>((Collection<String>) twin.getValue()));
                showOrganization(id);
            }
        });
        ok.setClickShortcut(KeyCode.O, ModifierKey.CTRL);

        h.addComponent(ok);
        h.addComponent(cancel);

        layout.addComponent(h);
        layout.setSizeFull();
        panel.removeAllComponents();
        panel.addComponent(layout);
        twin.focus();
    }

    boolean isGoodGroup(final Set<String> names, final String group0) {
        final String group = StringUtils.trimToNull(group0);
        return group != null && !names.contains(group) && GROUP.matcher(group).matches();
    }

    public TreeTable getTreeTable() {
        return treetable;
    }

    public static void fillTable(TreeTable treetable) {
        List<Organization> rootOrganizations = AdminServiceProvider.get().getRootOrganizations();
        for (Organization org : rootOrganizations) {
            treetable.addItem(new Object[] { org.getName() }, org.getId());
            treetable.setCollapsed(org.getId(), true);
        }

        for (Organization org : rootOrganizations) {
            treetable.setChildrenAllowed(org.getId(), !(org.getOrganizations().isEmpty()));
        }
    }

}