com.jiangyifen.ec2.ui.mgr.system.tabsheet.DynQueueMemberManagement.java Source code

Java tutorial

Introduction

Here is the source code for com.jiangyifen.ec2.ui.mgr.system.tabsheet.DynQueueMemberManagement.java

Source

package com.jiangyifen.ec2.ui.mgr.system.tabsheet;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;

import com.jiangyifen.ec2.entity.Domain;
import com.jiangyifen.ec2.entity.Phone2PhoneSetting;
import com.jiangyifen.ec2.entity.Queue;
import com.jiangyifen.ec2.entity.User;
import com.jiangyifen.ec2.entity.UserQueue;
import com.jiangyifen.ec2.globaldata.ShareData;
import com.jiangyifen.ec2.service.csr.ami.QueueMemberRelationService;
import com.jiangyifen.ec2.service.eaoservice.Phone2PhoneSettingService;
import com.jiangyifen.ec2.service.eaoservice.QueueService;
import com.jiangyifen.ec2.service.eaoservice.UserQueueService;
import com.jiangyifen.ec2.service.eaoservice.UserService;
import com.jiangyifen.ec2.utils.SpringContextHolder;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.filter.Like;
import com.vaadin.data.util.filter.Or;
import com.vaadin.data.validator.RegexpValidator;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.event.dd.acceptcriteria.ClientSideCriterion;
import com.vaadin.event.dd.acceptcriteria.SourceIs;
import com.vaadin.ui.AbstractSelect.AcceptItem;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Window.Notification;

/**
 * ??? 
 * @author jrh
 */
@SuppressWarnings("serial")
public class DynQueueMemberManagement extends VerticalLayout implements ClickListener, ValueChangeListener {

    private final Object[] VISIBLE_PROPERTIES = new String[] { "empNo", "username", "department.name" };
    private final String[] COL_HEADERS = new String[] { "?", "??", "" };

    /**
     * ?
     */
    // 
    private ComboBox queueSelector;
    private Queue nearestSelectedQueue; // ?
    private List<UserQueue> oldUserQueuesToQueueName; // ? -?
    private BeanItemContainer<Queue> queueContainer;

    // ?
    // 
    private TextField leftKeyword;
    private Button leftSearch;
    // ?
    private TextField rightKeyword;
    private Button rightSearch;

    // 
    private Button addAll;
    private Button add;
    private Button remove;
    private Button removeAll;

    // 
    private Table leftTable;
    private Table rightTable;
    private BeanItemContainer<User> leftTableContainer;
    private BeanItemContainer<User> rightTableContainer;

    // ???
    private Button save;
    private Button cancel;
    private TextField priorityField; // 
    private Notification priorityError; // ???

    // ?????
    private Window globalPriorityConfirmWindow;
    private Label noticeInPriorityWindow;
    private Button submit;
    private Button abolish;

    /**
     * 
     */
    private Domain domain; // ?
    private TreeMap<String, Integer> usernameToPriority; // ?    
    private UserService userService; // ?
    private QueueService queueService; // ?
    private UserQueueService userQueueService; // ???
    private QueueMemberRelationService queueMemberRelationService; // ???
    private Phone2PhoneSettingService phone2PhoneSettingService; // ??

    public DynQueueMemberManagement() {
        this.setWidth("100%");
        this.setMargin(true);
        this.setSpacing(true);

        domain = SpringContextHolder.getDomain();
        userService = SpringContextHolder.getBean("userService");
        queueService = SpringContextHolder.getBean("queueService");
        userQueueService = SpringContextHolder.getBean("userQueueService");
        queueMemberRelationService = SpringContextHolder.getBean("queueMemberRelationService");
        phone2PhoneSettingService = SpringContextHolder.getBean("phone2PhoneSettingService");

        queueContainer = new BeanItemContainer<Queue>(Queue.class);
        List<Queue> allQueues = queueService.getAllByDomain(domain, true);
        for (Queue queue : allQueues) {
            if (queue.getDynamicmember() && queue.getIsModifyable()) {
                queueContainer.addBean(queue);
            }
        }

        priorityError = new Notification(" <B>?</B>?<B> >0 </B>",
                Notification.TYPE_ERROR_MESSAGE);
        priorityError.setDelayMsec(1000);
        priorityError.setHtmlContentAllowed(true);
        priorityError.setPosition(Notification.POSITION_CENTERED);

        usernameToPriority = new TreeMap<String, Integer>();

        // ?  
        createQueueSelectComponents();

        // ?(?????) 
        HorizontalLayout centerHLayout = createCenterHLayout();
        this.addComponent(centerHLayout);

        // ?(???)
        createBottomComponents();

        // ?
        makeTableDragAble(new SourceIs(rightTable), leftTable, true);
        makeTableDragAble(new SourceIs(leftTable), rightTable, false);

        //  ??
        createPriorityConfirmWindow();

        // ?
        for (Queue queue : allQueues) {
            if (queue.getDynamicmember()) {
                queueSelector.select(queue);
                break;
            }
        }
    }

    /**
     * ?  
     */
    private void createQueueSelectComponents() {
        HorizontalLayout maintopLayout = new HorizontalLayout();
        maintopLayout.setSpacing(true);
        this.addComponent(maintopLayout);
        this.setComponentAlignment(maintopLayout, Alignment.MIDDLE_CENTER);

        Label caption = new Label("<B></B>", Label.CONTENT_XHTML);
        caption.setWidth("-1px");
        maintopLayout.addComponent(caption);

        queueSelector = new ComboBox();
        queueSelector.setNullSelectionAllowed(false);
        queueSelector.setImmediate(true);
        queueSelector.setContainerDataSource(queueContainer);
        queueSelector.setItemCaptionPropertyId("descriptionAndName");
        queueSelector.addListener(this);
        maintopLayout.addComponent(queueSelector);
    }

    /** 
     * ?(?????)
     * @return HorizontalLayout
     */
    private HorizontalLayout createCenterHLayout() {
        HorizontalLayout centerHLayout = new HorizontalLayout();
        centerHLayout.setSpacing(true);
        centerHLayout.setWidth("100%");

        // ?(??)
        VerticalLayout leftComponents = createLeftComponents();
        centerHLayout.addComponent(leftComponents);
        centerHLayout.setExpandRatio(leftComponents, 0.4f);

        // ??("?")
        VerticalLayout middleComponents = createMiddleComponents();
        centerHLayout.addComponent(middleComponents);
        centerHLayout.setComponentAlignment(middleComponents, Alignment.MIDDLE_CENTER);
        centerHLayout.setExpandRatio(middleComponents, 0.2f);

        // ??(????)
        VerticalLayout rightComponents = createRightComponents();
        centerHLayout.addComponent(rightComponents);
        centerHLayout.setExpandRatio(rightComponents, 0.4f);

        return centerHLayout;
    }

    /**
     *  ?(??)
     * @return
     */

    private VerticalLayout createLeftComponents() {
        VerticalLayout leftVLayout = new VerticalLayout();
        leftVLayout.setSpacing(true);
        leftVLayout.setWidth("100%");

        // ?
        HorizontalLayout searchHLayout = new HorizontalLayout();
        searchHLayout.setSpacing(true);
        leftVLayout.addComponent(searchHLayout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        searchHLayout.addComponent(caption);
        searchHLayout.setComponentAlignment(caption, Alignment.MIDDLE_CENTER);

        leftKeyword = new TextField();
        leftKeyword.setImmediate(true);
        leftKeyword.setInputPrompt("?");
        leftKeyword.setDescription("??????????");
        leftKeyword.setStyleName("search");
        leftKeyword.addListener(this);
        searchHLayout.addComponent(leftKeyword);
        searchHLayout.setComponentAlignment(leftKeyword, Alignment.MIDDLE_CENTER);

        leftSearch = new Button("?", this);
        leftSearch.setImmediate(true);
        searchHLayout.addComponent(leftSearch);
        searchHLayout.setComponentAlignment(leftSearch, Alignment.MIDDLE_CENTER);

        // 
        // 
        leftTable = new Table("??");
        leftTable.setStyleName("striped");
        leftTable.setSelectable(true);
        leftTable.setMultiSelect(true);
        leftTable.setWidth("100%");
        leftTable.setRowHeaderMode(Table.ROW_HEADER_MODE_INDEX);
        leftVLayout.addComponent(leftTable);

        leftTableContainer = new BeanItemContainer<User>(User.class);
        leftTableContainer.addNestedContainerProperty("department.name");
        leftTable.setContainerDataSource(leftTableContainer);
        leftTable.setPageLength(20);
        leftTable.setVisibleColumns(VISIBLE_PROPERTIES);
        leftTable.setColumnHeaders(COL_HEADERS);

        return leftVLayout;
    }

    /**
     * ??("?")
     * return 
     */
    private VerticalLayout createMiddleComponents() {
        VerticalLayout operatorVLayout = new VerticalLayout();
        operatorVLayout.setSpacing(true);
        operatorVLayout.setSizeFull();

        // ??
        operatorVLayout.addComponent(new Label("&nbsp&nbsp", Label.CONTENT_XHTML));
        operatorVLayout.addComponent(new Label("&nbsp&nbsp", Label.CONTENT_XHTML));
        operatorVLayout.addComponent(new Label("&nbsp&nbsp", Label.CONTENT_XHTML));

        // 
        addAll = new Button(">>>", this);
        operatorVLayout.addComponent(addAll);
        operatorVLayout.setComponentAlignment(addAll, Alignment.MIDDLE_CENTER);

        add = new Button(">>", this);
        operatorVLayout.addComponent(add);
        operatorVLayout.setComponentAlignment(add, Alignment.MIDDLE_CENTER);

        remove = new Button("<<", this);
        operatorVLayout.addComponent(remove);
        operatorVLayout.setComponentAlignment(remove, Alignment.MIDDLE_CENTER);

        removeAll = new Button("<<<", this);
        operatorVLayout.addComponent(removeAll);
        operatorVLayout.setComponentAlignment(removeAll, Alignment.MIDDLE_CENTER);

        // ??
        operatorVLayout.addComponent(new Label("&nbsp&nbsp", Label.CONTENT_XHTML));
        operatorVLayout.addComponent(new Label("&nbsp&nbsp", Label.CONTENT_XHTML));

        return operatorVLayout;
    }

    /**
     * ??(????)
     * return 
     */
    private VerticalLayout createRightComponents() {
        VerticalLayout rightVLayout = new VerticalLayout();
        rightVLayout.setSpacing(true);
        rightVLayout.setWidth("100%");

        // ?
        HorizontalLayout searchHLayout = new HorizontalLayout();
        searchHLayout.setSpacing(true);
        rightVLayout.addComponent(searchHLayout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        searchHLayout.addComponent(caption);
        searchHLayout.setComponentAlignment(caption, Alignment.MIDDLE_CENTER);

        rightKeyword = new TextField();
        rightKeyword.setImmediate(true);
        rightKeyword.setInputPrompt("?");
        rightKeyword.setDescription("??????????");
        rightKeyword.setStyleName("search");
        rightKeyword.addListener(this);
        searchHLayout.addComponent(rightKeyword);
        searchHLayout.setComponentAlignment(rightKeyword, Alignment.MIDDLE_CENTER);

        rightSearch = new Button("?", this);
        rightSearch.setImmediate(true);
        searchHLayout.addComponent(rightSearch);
        searchHLayout.setComponentAlignment(rightSearch, Alignment.MIDDLE_CENTER);

        // 
        // 
        rightTable = new Table("?");
        rightTable.setStyleName("striped");
        rightTable.setSelectable(true);
        rightTable.setMultiSelect(true);
        rightTable.setWidth("100%");
        rightTable.setPageLength(16);
        rightTable.setRowHeaderMode(Table.ROW_HEADER_MODE_INDEX);
        rightVLayout.addComponent(rightTable);

        rightTableContainer = new BeanItemContainer<User>(User.class);
        rightTableContainer.addNestedContainerProperty("department.name");
        rightTable.setContainerDataSource(rightTableContainer);
        rightTable.setVisibleColumns(VISIBLE_PROPERTIES);
        rightTable.setColumnHeaders(COL_HEADERS);
        rightTable.addGeneratedColumn("priority", new PriorityColumnGenerate());
        rightTable.setColumnHeader("priority", "");

        return rightVLayout;
    }

    /**
     * ?(???)
     */
    private void createBottomComponents() {
        HorizontalLayout bottomHLayout = new HorizontalLayout();
        bottomHLayout.setSpacing(true);
        bottomHLayout.setWidth("100%");
        this.addComponent(bottomHLayout);

        // 
        HorizontalLayout bottomLeft = new HorizontalLayout();
        bottomLeft.setSpacing(true);
        bottomLeft.setWidth("-1px");
        bottomHLayout.addComponent(bottomLeft);
        bottomHLayout.setComponentAlignment(bottomLeft, Alignment.MIDDLE_LEFT);

        // ?
        save = new Button("? ", this);
        save.setStyleName("default");
        bottomLeft.addComponent(save);
        bottomLeft.setComponentAlignment(save, Alignment.MIDDLE_LEFT);

        // ?
        cancel = new Button("? ", this);
        bottomLeft.addComponent(cancel);
        bottomLeft.setComponentAlignment(cancel, Alignment.MIDDLE_LEFT);

        // ?
        HorizontalLayout bottomRight = new HorizontalLayout();
        bottomRight.setSpacing(true);
        bottomRight.setWidth("-1px");
        bottomHLayout.addComponent(bottomRight);
        bottomHLayout.setComponentAlignment(bottomRight, Alignment.MIDDLE_RIGHT);

        Label priorityCaption = new Label("<B>?</B>", Label.CONTENT_XHTML);
        priorityCaption.setWidth("-1px");
        bottomRight.addComponent(priorityCaption);
        bottomRight.setComponentAlignment(priorityCaption, Alignment.MIDDLE_RIGHT);

        priorityField = new TextField();
        priorityField.addListener(this);
        priorityField.setWidth("100px");
        priorityField.setImmediate(true);
        priorityField.setWriteThrough(false);
        bottomRight.addComponent(priorityField);
        bottomRight.setComponentAlignment(priorityField, Alignment.MIDDLE_RIGHT);

        // ?????
        setButtonsEnable(false);
    }

    /**
     * 
     * @param acceptCriterion
     * @param table
     * @param isDragout ? UserQueues ??
     */
    private void makeTableDragAble(final ClientSideCriterion acceptCriterion, final Table table,
            final boolean isDragout) {
        table.setDragMode(TableDragMode.ROW);
        table.setDropHandler(new DropHandler() {
            public void drop(DragAndDropEvent dropEvent) {
                // ????
                DataBoundTransferable transferable = (DataBoundTransferable) dropEvent.getTransferable();

                // ?BeanItemContainer??
                if (!(transferable.getSourceContainer() instanceof BeanItemContainer)) {
                    return;
                }

                // ??sourceItemId
                User sourceItem = (User) transferable.getItemId();

                // ?DroptargetItemId
                table.getContainerDataSource().addItem(sourceItem);
                transferable.getSourceContainer().removeItem(sourceItem);

                // ???
                leftTableContainer.sort(new Object[] { "empNo" }, new boolean[] { true });
                rightTableContainer.sort(new Object[] { "empNo" }, new boolean[] { true });

                // ?? -- 
                if (isDragout == true) {
                    usernameToPriority.remove(sourceItem.getUsername());
                }

                // ????
                initializeTablesCaption();

                // ???????
                setButtonsEnable(true);
            }

            public AcceptCriterion getAcceptCriterion() {
                return new com.vaadin.event.dd.acceptcriteria.And(acceptCriterion, AcceptItem.ALL);
            }
        });
    }

    /**
     *  ??
     */
    private void createPriorityConfirmWindow() {
        globalPriorityConfirmWindow = new Window("?");
        globalPriorityConfirmWindow.center();
        globalPriorityConfirmWindow.setWidth("300px");
        globalPriorityConfirmWindow.setModal(true);
        globalPriorityConfirmWindow.setResizable(false);

        VerticalLayout windowContent = new VerticalLayout();
        windowContent.setSizeFull();
        windowContent.setMargin(true);
        windowContent.setSpacing(true);
        globalPriorityConfirmWindow.setContent(windowContent);

        noticeInPriorityWindow = new Label("", Label.CONTENT_XHTML);
        windowContent.addComponent(noticeInPriorityWindow);

        HorizontalLayout buttonsHLayout = new HorizontalLayout();
        buttonsHLayout.setSpacing(true);
        windowContent.addComponent(buttonsHLayout);

        submit = new Button(" ", this);
        abolish = new Button("? ", this);
        abolish.setStyleName("default");
        buttonsHLayout.addComponent(submit);
        buttonsHLayout.addComponent(abolish);
    }

    /**
     * buttonClick,tableFromtableTo
     * @param tableFrom ??
     * @param tableTo   
     * @param isAll ?
     */
    @SuppressWarnings("unchecked")
    private void addToOpposite(Table tableFrom, Table tableTo, Boolean isAll) {
        if (tableFrom == null || tableTo == null)
            return;

        //?tableFrom?,??Null
        if (!isAll && ((Collection<User>) tableFrom.getValue()).size() == 0) {
            this.getApplication().getMainWindow().showNotification("?CSR!",
                    Window.Notification.TYPE_HUMANIZED_MESSAGE);
            return;
        }

        //tableFrom?Csr
        Collection<User> csrs = null;
        if (isAll) {
            // java.util.ConcurrentModificationException
            csrs = new ArrayList<User>((Collection<User>) tableFrom.getItemIds());
        } else {
            csrs = (Collection<User>) tableFrom.getValue();
        }

        //??TableFromTableToItem   
        for (User user : csrs) {
            tableFrom.getContainerDataSource().removeItem(user);
            tableTo.getContainerDataSource().addItem(user);

            // ?? ????
            if (tableFrom == rightTable) {
                usernameToPriority.remove(user.getUsername());
            }
        }

        // ?? ??
        setButtonsEnable(true);

        // ?
        initializeTablesCaption();
    }

    /**
     * buttonClick?Table,TableContainer
     */
    private void executeLeftSearch() {
        if (leftTableContainer == null)
            return;

        // ?
        leftTableContainer.removeAllContainerFilters();

        // ??? 
        String leftKeywordStr = ((String) leftKeyword.getValue()).trim();

        Or compareAll = new Or(new Like("empNo", "%" + leftKeywordStr + "%", false),
                new Like("username", "%" + leftKeywordStr + "%", false),
                new Like("department.name", "%" + leftKeywordStr + "%", false));
        leftTableContainer.addContainerFilter(compareAll);
        // ???
        leftTableContainer.sort(new Object[] { "empNo" }, new boolean[] { true });

        // ???
        String leftCaption = "?? ( " + leftTableContainer.size() + " )";
        leftTable.setCaption(leftCaption);
    }

    /**
     * buttonClick,??
     */
    private void executeRightSearch() {
        if (rightTableContainer == null)
            return;

        // ?
        rightTableContainer.removeAllContainerFilters();

        // ??? 
        String rightKeywordStr = ((String) rightKeyword.getValue()).trim();

        Or compareAll = new Or(new Like("empNo", "%" + rightKeywordStr + "%", false),
                new Like("username", "%" + rightKeywordStr + "%", false),
                new Like("department.name", "%" + rightKeywordStr + "%", false));
        rightTableContainer.addContainerFilter(compareAll);
        // ???
        rightTableContainer.sort(new Object[] { "empNo" }, new boolean[] { true });
    }

    /**
     * ?????
     *  addaddAllremoveremoveAll
     */
    @Override
    public void buttonClick(ClickEvent event) {
        Button source = event.getButton();
        if (source == leftSearch) {
            executeLeftSearch();
        } else if (source == add) {
            addToOpposite(leftTable, rightTable, false);
            leftTable.setValue(null);
        } else if (source == addAll) {
            addToOpposite(leftTable, rightTable, true);
        } else if (source == remove) {
            addToOpposite(rightTable, leftTable, false);
        } else if (source == removeAll) {
            addToOpposite(rightTable, leftTable, true);
        } else if (source == rightSearch) {
            executeRightSearch();
        } else if (source == save) {
            String globalPriorityStr = ((String) priorityField.getValue()).trim();
            if (!"".equals(globalPriorityStr) && !globalPriorityStr.matches("[1-9]\\d*")) {
                this.getApplication().getMainWindow().showNotification(priorityError);
                return;
            }

            // ???????
            String rightKeywordStr = ((String) rightKeyword.getValue()).trim();
            if (!"".equals(rightKeywordStr)) {
                rightKeyword.setValue("");
            }

            executeConfirm(globalPriorityStr);
        } else if (source == cancel) {
            // ????
            if (nearestSelectedQueue != null) {
                updateTableSource(nearestSelectedQueue.getName());
            } else {
                updateTableSource("");
            }
            // 
            initializeTablesCaption();
            // ?????
            setButtonsEnable(false);
            priorityField.setValue(""); // 
        } else if (source == submit) {
            String globalPriority = ((String) priorityField.getValue()).trim();
            Integer globalPriorityInteger = Integer.valueOf(globalPriority);
            excuteSave(globalPriorityInteger);
            // 
            updateTable();
            this.getApplication().getMainWindow().removeWindow(globalPriorityConfirmWindow);
        } else if (source == abolish) {
            this.getApplication().getMainWindow().removeWindow(globalPriorityConfirmWindow);
        }
    }

    @Override
    public void valueChange(ValueChangeEvent event) {
        Property source = event.getProperty();
        if (source == queueSelector) {
            usernameToPriority.clear();
            Queue queue = (Queue) source.getValue();
            nearestSelectedQueue = queue;

            if (queue != null) {
                // ? 
                List<UserQueue> userQueues = userQueueService.getAllByQueueName(queue.getName(), domain);
                if (userQueues != null) {
                    for (UserQueue userQueue : userQueues) {
                        usernameToPriority.put(userQueue.getUsername(), userQueue.getPriority());
                    }
                }
                updateTableSource(queue.getName());
            } else {
                updateTableSource("");
            }
            leftKeyword.setValue("");
            rightKeyword.setValue("");
            initializeTablesCaption();
        } else if (source == leftKeyword) {
            leftSearch.click();
        } else if (source == rightKeyword) {
            rightSearch.click();
        } else if (source == priorityField) {
            setButtonsEnable(true);
        }
    }

    /**
     * ?  ? ? ??
     * @param enabled
     */
    public void setButtonsEnable(boolean enabled) {
        save.setEnabled(enabled);
        cancel.setEnabled(enabled);
    }

    /**
     * ??
     */
    private void executeConfirm(String globalPriority) {
        if (!"".equals(globalPriority)) {
            noticeInPriorityWindow
                    .setValue("<font color='red'>?<B></B>?: <B>"
                            + globalPriority + "</B>?");
            this.getApplication().getMainWindow().addWindow(globalPriorityConfirmWindow);
        } else {
            excuteSave(null);
            updateTable(); // 
        }
    }

    /**
     * ??
     * @param globalPriorityInteger 
     */
    private void excuteSave(Integer globalPriorityInteger) {
        //CSR
        Set<User> selectedCsrs = new HashSet<User>((Collection<User>) rightTableContainer.getItemIds());
        Phone2PhoneSetting globalSetting = phone2PhoneSettingService.getGlobalSettingByDomain(domain.getId());
        String defaultOutline = ShareData.domainToDefaultOutline.get(domain.getId());

        //  UserQueue
        for (User user : selectedCsrs) {
            // ??
            UserQueue userQueue = null;
            Phone2PhoneSetting customSetting = phone2PhoneSettingService.getByUser(user.getId());
            String exten = ShareData.userToExten.get(user.getId());
            Integer currentPriority = usernameToPriority.get(user.getUsername());

            // ?? user oldPriority  ?
            for (UserQueue uq : oldUserQueuesToQueueName) {
                if (user.getUsername().equals(uq.getUsername())) {
                    userQueue = uq;
                    break;
                }
            }

            // ??
            if (userQueue == null) {
                UserQueue newUserQueue = new UserQueue();
                newUserQueue.setDomain(domain);
                newUserQueue.setUsername(user.getUsername());
                newUserQueue.setQueueName(nearestSelectedQueue.getName());
                Integer priority = (globalPriorityInteger == null) ? currentPriority : globalPriorityInteger;
                newUserQueue.setPriority(priority);
                newUserQueue = userQueueService.update(newUserQueue);
                // ??? ??Asterisk ???
                if (newUserQueue.getId() != null) {
                    // ??
                    updateQueueMembers(true, priority, exten, defaultOutline, user, globalSetting, customSetting);
                }
            } else { // ??UserQueue ?
                // ?UserQueue ???
                if (globalPriorityInteger != null && userQueue.getPriority() != globalPriorityInteger) {
                    userQueue.setPriority(globalPriorityInteger);
                    userQueueService.update(userQueue);
                    // ??
                    updateQueueMembers(true, globalPriorityInteger, exten, defaultOutline, user, globalSetting,
                            customSetting);
                    // UserQueue ????
                } else if (globalPriorityInteger == null && userQueue.getPriority() != currentPriority) {
                    userQueue.setPriority(currentPriority);
                    userQueueService.update(userQueue);
                    // ??
                    updateQueueMembers(true, currentPriority, exten, defaultOutline, user, globalSetting,
                            customSetting);
                }
            }
        }

        // UserQueue
        for (UserQueue userQueue : oldUserQueuesToQueueName) {
            // ?
            boolean hasRemoved = true;
            String username = userQueue.getUsername();

            // ???? username   user  hasRemoved  false
            for (User user : selectedCsrs) {
                if (username.equals(user.getUsername())) {
                    hasRemoved = false;
                    break;
                }
            }

            // ?? userQueue ?
            if (hasRemoved == true) {
                // ?
                userQueueService.deleteById(userQueue.getId());

                // ???? ??Asterisk ?? Action
                List<User> users = userService.getUsersByUsername(userQueue.getUsername());
                User user = null;
                if (users.size() > 0) {
                    user = users.get(0);
                    Phone2PhoneSetting customSetting = phone2PhoneSettingService.getByUser(user.getId());
                    String exten = ShareData.userToExten.get(user.getId());
                    // ??
                    updateQueueMembers(false, 5, exten, defaultOutline, user, globalSetting, customSetting);
                }
            }
        }

        priorityField.setValue(""); // 

        // ?????
        setButtonsEnable(false);
    }

    /**
     * ????????
     * @param isAddMember      ???
     * @param priority         ?
     * @param exten            ??
     * @param defaultOutline   ?
     * @param csr            ??
     * @param globalSetting      ?
     * @param customSetting      ?
     */
    private void updateQueueMembers(boolean isAddMember, Integer priority, String exten, String defaultOutline,
            User csr, Phone2PhoneSetting globalSetting, Phone2PhoneSetting customSetting) {
        if (exten != null) { // ?
            queueMemberRelationService.removeQueueMemberRelation(nearestSelectedQueue.getName(), exten);
            if (isAddMember) {
                queueMemberRelationService.addQueueMemberRelation(nearestSelectedQueue.getName(), exten, priority);
            }
        } else if (defaultOutline != null && globalSetting != null) { // ??, 
            // ???????
            String phoneNum = csr.getPhoneNumber();
            if (phoneNum == null || "".equals(phoneNum)) {
                return;
            }

            // ?
            // ??? 1????2?? <= ?,  >= ?
            boolean isGlobalRunning = phone2PhoneSettingService.confirmSettingIsRunning(globalSetting);
            if (isGlobalRunning) {
                // ?????
                if (globalSetting.getIsSpecifiedPhones()) {
                    return;
                }
                // ????,???CSR????
                for (User specifiedCsr : globalSetting.getSpecifiedCsrs()) {
                    if (specifiedCsr.getId() == csr.getId()) {
                        if (isAddMember) {
                            queueMemberRelationService.addQueueMemberRelation(nearestSelectedQueue.getName(),
                                    csr.getPhoneNumber() + "@" + defaultOutline, priority);
                        } else {
                            queueMemberRelationService.removeQueueMemberRelation(nearestSelectedQueue.getName(),
                                    csr.getPhoneNumber() + "@" + defaultOutline);
                        }
                        return;
                    }
                }
            }

            // ??(??????)
            // ??
            if (customSetting == null) {
                return;
            }
            // ?? 1??????2???????
            if (!globalSetting.getIsSpecifiedPhones()) {
                for (User specifiedCsr : globalSetting.getSpecifiedCsrs()) {
                    // ????[???]
                    if (specifiedCsr.getId() == csr.getId()) {
                        return;
                    }
                }

            }
            // 3????4???2?? <= ?,  >= ?
            if (globalSetting.getIsLicensed2Csr()) {
                boolean isCustomRunning = phone2PhoneSettingService.confirmSettingIsRunning(customSetting);
                if (isCustomRunning) {
                    if (isAddMember) {
                        queueMemberRelationService.addQueueMemberRelation(nearestSelectedQueue.getName(),
                                csr.getPhoneNumber() + "@" + defaultOutline, priority);
                    } else {
                        queueMemberRelationService.removeQueueMemberRelation(nearestSelectedQueue.getName(),
                                csr.getPhoneNumber() + "@" + defaultOutline);
                    }
                }
            }
        }
    }

    /**
     * ????
     * @param queueName 
     */
    private void updateTableSource(String queueName) {
        List<User> users = userService.getCsrsByDomain(domain);
        oldUserQueuesToQueueName = userQueueService.getAllByQueueName(queueName, domain);

        leftTableContainer.removeAllItems();
        rightTableContainer.removeAllItems();

        for (User user : users) {
            if (oldUserQueuesToQueueName.size() == 0) {
                leftTableContainer.addAll(users);
                return;
            }

            // ?user ??? true ,?
            boolean needAddToRightTable = false;
            for (UserQueue userQueue : oldUserQueuesToQueueName) {
                if (user.getUsername().equals(userQueue.getUsername())) {
                    rightTableContainer.addBean(user);
                    needAddToRightTable = true;
                    break;
                }
            }

            // ?user ??
            if (needAddToRightTable == false) {
                leftTableContainer.addBean(user);
            }
        }
    }

    /**
     * ??
     */
    public void initializeTablesCaption() {
        // ?????,??
        String rightKeywordStr = ((String) rightKeyword.getValue()).trim();
        if (!"".equals(rightKeywordStr)) {
            rightKeyword.setValue("");
        }

        String leftCaption = "?? ( " + leftTable.getContainerDataSource().size() + " )";
        String rightCaption = "? ( " + rightTable.getContainerDataSource().size() + " )";

        leftTable.setCaption(leftCaption);
        rightTable.setCaption(rightCaption);
    }

    /**
     * 
     */
    public void updateTable() {
        List<Queue> allQueues = queueService.getAllByDomain(domain, true);
        List<Queue> dynQueues = new ArrayList<Queue>();
        for (Queue queue : allQueues) { // ?
            if (queue.getDynamicmember()) {
                dynQueues.add(queue);
            }
        }
        queueContainer.removeAllItems();
        queueContainer.addAll(dynQueues);

        // ?
        if (nearestSelectedQueue != null) { // ???
            boolean isExisted = false;
            for (Queue queue : dynQueues) {
                if (queue.getId() == nearestSelectedQueue.getId()) {
                    queueSelector.select(queue);
                    isExisted = true;
                    break;
                }
            }
            if (isExisted == false && dynQueues.size() > 0) {
                queueSelector.select(dynQueues.get(0));
            } else if (isExisted == false && dynQueues.size() == 0) {
                queueSelector.select(null);
            }
        } else if (dynQueues.size() > 0) { // ??????
            queueSelector.select(dynQueues.get(0));
        } else { // ????
            queueSelector.select(null);
        }
    }

    /**
     * ? 
     */
    private class PriorityColumnGenerate implements Table.ColumnGenerator {

        @Override
        public Object generateCell(Table source, Object itemId, Object columnId) {
            final String username = (String) source.getItem(itemId).getItemProperty("username").getValue();
            final Integer priorityValue = usernameToPriority.get(username);
            final TextField priorityField = new TextField();
            priorityField.setWidth("60px");
            priorityField.setImmediate(true);
            priorityField.setWriteThrough(false);
            priorityField.addValidator(new RegexpValidator("[1-9]\\d*", "? >0 ?"));

            if (priorityValue == null) {
                priorityField.setValue("5");
                usernameToPriority.put(username, 5);
            } else { // ??
                priorityField.setValue(priorityValue.toString());
            }

            // UserQueue ??? Map ?
            priorityField.addListener(new ValueChangeListener() {
                @Override
                public void valueChange(ValueChangeEvent event) {
                    String valueStr = (String) priorityField.getValue();
                    if (priorityField.isValid()) {
                        Integer value = Integer.valueOf(valueStr);
                        usernameToPriority.put(username, value);

                        // ???????
                        setButtonsEnable(true);
                    } else {
                        Notification formatError = new Notification(
                                " <B>" + valueStr + "</B> ?, ",
                                Notification.TYPE_ERROR_MESSAGE);
                        formatError.setDelayMsec(1000);
                        priorityField.getApplication().getMainWindow().showNotification(formatError);
                        priorityField.setValue(usernameToPriority.get(username).toString());
                    }
                }
            });
            return priorityField;
        }
    }

}