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

Java tutorial

Introduction

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

Source

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

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jiangyifen.ec2.bean.DayOfWeek;
import com.jiangyifen.ec2.entity.Domain;
import com.jiangyifen.ec2.entity.Phone2PhoneSetting;
import com.jiangyifen.ec2.entity.Queue;
import com.jiangyifen.ec2.entity.StaticQueueMember;
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.StaticQueueMemberService;
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.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.OptionGroup;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.TextArea;
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 MgrPhone2PhoneSettingView extends VerticalLayout implements ValueChangeListener, ClickListener {
    // 
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    // ?
    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
    // ??
    private final Object[] VISIBLE_PROPERTIES = new String[] { "empNo", "username", "realName", "phoneNumber",
            "department.name" };
    private final String[] COL_HEADERS = new String[] { "?", "??", "??", "?", "" };

    private Notification notification; // ???

    private Panel panel; // 
    private OptionGroup startSettingOption; // ???
    private OptionGroup licensed2CsrOption; // ?CSR ??CSR
    private ComboBox dayOfWeekTypeSelector; // (??)
    private OptionGroup daysOfWeekOption; // (??...)
    private HorizontalLayout dayOfWeekLayout; // dayOfWeekOption
    private ComboBox startRedirectHour; // ??
    private ComboBox startRedirectMinute; // ?
    private ComboBox stopRedirectHour; // ???
    private ComboBox stopRedirectMinute; // ??
    private OptionGroup redirectTypeOption; // (noanswer?unonline?busy)
    private ComboBox noanswerTimeoutSelector; // noanswer ?
    private HorizontalLayout noanswerLayout; //  noanswerTimeoutSelector
    private OptionGroup specifiedOption; // ????
    private TextArea phoneArea; // ???
    private HorizontalLayout phoneAreaLayout; //  phoneArea

    private HorizontalLayout csrSelectHLayout; // CSR ??
    // 
    private TextField leftKeyword; // ?CSR ??
    private Button leftSearch; // ?
    // ?
    private TextField rightKeyword; // CSR ??
    private Button rightSearch; // ?

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

    // 
    private Table leftTable; // ?CSR ?
    private Table rightTable; // CSR ?

    private BeanItemContainer<User> leftTableContainer;
    private BeanItemContainer<User> rightTableContainer;

    // ?
    private Button edit; // ?
    private Button save; // ??
    private Button cancel; // ?

    /**
     * ?
     */
    private Domain domain; // ?
    private User loginUser; // ?
    private Phone2PhoneSetting globalP2PSetting; // ?

    private UserService userService; // ?
    private QueueService queueService; // ?
    private UserQueueService userQueueService; // ???
    private QueueMemberRelationService queueMemberRelationService; // ???
    private Phone2PhoneSettingService phone2PhoneSettingService; // ??
    private StaticQueueMemberService staticQueueMemberService; // ????

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

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

        notification = new Notification("");
        notification.setDelayMsec(1000);
        notification.setHtmlContentAllowed(true);

        VerticalLayout panelContent = new VerticalLayout();
        panelContent.setSpacing(true);
        panelContent.setMargin(true);
        panelContent.setWidth("100%");

        panel = new Panel("?");
        panel.setContent(panelContent);
        panel.setStyleName("light");
        this.addComponent(panel);

        // ?
        createStartSetting(panelContent);

        // ?CSR ?
        createLicensed2Csr(panelContent);

        // 
        createDaysOfWeekType(panelContent);

        // 
        createDayOfWeek(panelContent);

        // 
        createRunRedirectTime(panelContent);

        // 
        createRedirectType(panelContent);

        // ?? 
        createNoanwserTimeout(panelContent);

        // ??
        createSpecifiedPhone(panelContent);

        // ??
        createPhoneArea(panelContent);

        // ????
        createCsrSelectTables(panelContent);

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

        // ?
        HorizontalLayout operators = createOperatorButtons();
        this.addComponent(operators);
    }

    @Override
    public void attach() {
        // ??
        Phone2PhoneSetting globalP2PSetting = phone2PhoneSettingService.getGlobalSettingByDomain(domain.getId());
        // ??
        if (globalP2PSetting == null) {
            globalP2PSetting = new Phone2PhoneSetting();
            globalP2PSetting.setIsGlobalSetting(true);
            globalP2PSetting.setIsStartedRedirect(false);
            globalP2PSetting.setIsLicensed2Csr(false);
            globalP2PSetting.setDayOfWeekType("weekday");

            Set<DayOfWeek> daysOfWeek = new HashSet<DayOfWeek>();
            daysOfWeek.add(DayOfWeek.mon);
            daysOfWeek.add(DayOfWeek.fri);
            globalP2PSetting.setDaysOfWeek(daysOfWeek);

            globalP2PSetting.setStartTime("18:00");
            globalP2PSetting.setStopTime("22:59");

            Set<String> types = new HashSet<String>();
            types.add("unonline");
            globalP2PSetting.setRedirectTypes(types);

            globalP2PSetting.setIsSpecifiedPhones(false);
            globalP2PSetting.setCreator(loginUser);
            globalP2PSetting.setDomain(domain);
        }
        this.globalP2PSetting = globalP2PSetting;

        // ?
        refreshSettingInfos(globalP2PSetting);
    }

    /**
     * ?
     * @param panelContent
     */
    private void createStartSetting(VerticalLayout panelContent) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        panelContent.addComponent(layout);

        Label caption = new Label("?");
        caption.setWidth("-1px");
        caption.setDescription(
                "<B>????</B>");
        layout.addComponent(caption);

        startSettingOption = new OptionGroup();
        startSettingOption.addItem(true);
        startSettingOption.addItem(false);
        startSettingOption.setItemCaption(true, "?");
        startSettingOption.setItemCaption(false, "");
        startSettingOption.setImmediate(true);
        startSettingOption.setReadOnly(true);
        startSettingOption.setDescription(
                "<B>????</B>");
        startSettingOption.setNullSelectionAllowed(false);
        startSettingOption.addStyleName("twocol200");
        startSettingOption.addStyleName("myopacity");
        layout.addComponent(startSettingOption);
    }

    /**
     * ?CSR ?
     * @param panelContent
     */
    private void createLicensed2Csr(VerticalLayout panelContent) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        panelContent.addComponent(layout);

        Label caption = new Label("???");
        caption.setWidth("-1px");
        caption.setDescription("<B>???</B>");
        layout.addComponent(caption);

        licensed2CsrOption = new OptionGroup();
        licensed2CsrOption.addItem(true);
        licensed2CsrOption.addItem(false);
        licensed2CsrOption.setItemCaption(true, "");
        licensed2CsrOption.setItemCaption(false, "?");
        licensed2CsrOption.setImmediate(true);
        licensed2CsrOption.setReadOnly(true);
        licensed2CsrOption
                .setDescription("<B>???</B>");
        licensed2CsrOption.setNullSelectionAllowed(false);
        licensed2CsrOption.addStyleName("twocol200");
        licensed2CsrOption.addStyleName("myopacity");
        layout.addComponent(licensed2CsrOption);
    }

    /**
     *  (????)
     * @param panelContent
     */
    private void createDaysOfWeekType(VerticalLayout panelContent) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        panelContent.addComponent(layout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        caption.setDescription("<B>?</B>");
        layout.addComponent(caption);

        dayOfWeekTypeSelector = new ComboBox();
        dayOfWeekTypeSelector.addItem("weekday");
        dayOfWeekTypeSelector.setItemCaption("weekday", "");
        dayOfWeekTypeSelector.addItem("weekend");
        dayOfWeekTypeSelector.setItemCaption("weekend", "");
        dayOfWeekTypeSelector.addItem("custom");
        dayOfWeekTypeSelector.setItemCaption("custom", "");
        dayOfWeekTypeSelector.setWidth("200px");
        dayOfWeekTypeSelector.setImmediate(true);
        dayOfWeekTypeSelector.setReadOnly(true);
        dayOfWeekTypeSelector.setDescription("<B>?</B>");
        dayOfWeekTypeSelector.setNullSelectionAllowed(false);
        dayOfWeekTypeSelector.addListener(this);
        layout.addComponent(dayOfWeekTypeSelector);
    }

    /**
     * (??...) ???
     * @param panelContent
     */
    private void createDayOfWeek(VerticalLayout panelContent) {
        dayOfWeekLayout = new HorizontalLayout();
        dayOfWeekLayout.setSpacing(true);
        dayOfWeekLayout.setVisible(false);
        panelContent.addComponent(dayOfWeekLayout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        caption.setDescription("<B>?</B>");
        dayOfWeekLayout.addComponent(caption);

        BeanItemContainer<DayOfWeek> container = new BeanItemContainer<DayOfWeek>(DayOfWeek.class);
        container.addBean(DayOfWeek.mon);
        container.addBean(DayOfWeek.tue);
        container.addBean(DayOfWeek.wen);
        container.addBean(DayOfWeek.thu);
        container.addBean(DayOfWeek.fri);
        container.addBean(DayOfWeek.sat);
        container.addBean(DayOfWeek.sun);

        daysOfWeekOption = new OptionGroup();
        daysOfWeekOption.setContainerDataSource(container);
        daysOfWeekOption.setItemCaptionPropertyId("name");
        daysOfWeekOption.setMultiSelect(true);
        daysOfWeekOption.setNullSelectionAllowed(false);
        daysOfWeekOption.setImmediate(true);
        daysOfWeekOption.setReadOnly(true);
        daysOfWeekOption.setDescription("<B>?</B>");
        daysOfWeekOption.addStyleName("threecol");
        daysOfWeekOption.addStyleName("myopacity");
        dayOfWeekLayout.addComponent(daysOfWeekOption);
    }

    /**
     * ? (18:00 - 23:59 )
     * @param panelContent
     */
    private void createRunRedirectTime(VerticalLayout panelContent) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        panelContent.addComponent(layout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        caption.setDescription("<B></B>");
        layout.addComponent(caption);

        startRedirectHour = new ComboBox();
        startRedirectHour.setImmediate(true);
        startRedirectHour.setWidth("50px");
        startRedirectHour.setNullSelectionAllowed(false);
        layout.addComponent(startRedirectHour);

        Label space1 = new Label(" ");
        space1.setWidth("-1px");
        layout.addComponent(space1);

        startRedirectMinute = new ComboBox();
        startRedirectMinute.setImmediate(true);
        startRedirectMinute.setWidth("50px");
        startRedirectMinute.setNullSelectionAllowed(false);
        layout.addComponent(startRedirectMinute);

        Label to = new Label(" - ");
        to.setWidth("-1px");
        layout.addComponent(to);

        stopRedirectHour = new ComboBox();
        stopRedirectHour.setImmediate(true);
        stopRedirectHour.setWidth("50px");
        stopRedirectHour.setNullSelectionAllowed(false);
        layout.addComponent(stopRedirectHour);

        Label space2 = new Label(" ");
        space2.setWidth("-1px");
        layout.addComponent(space2);

        stopRedirectMinute = new ComboBox();
        stopRedirectMinute.setImmediate(true);
        stopRedirectMinute.setWidth("50px");
        stopRedirectMinute.setNullSelectionAllowed(false);
        layout.addComponent(stopRedirectMinute);

        for (int hour = 0; hour < 24; hour++) {
            startRedirectHour.addItem(hour);
            stopRedirectHour.addItem(hour);
        }

        for (int minute = 0; minute < 60; minute++) {
            startRedirectMinute.addItem(minute);
            stopRedirectMinute.addItem(minute);
        }

        startRedirectHour.setValue(18);
        stopRedirectHour.setValue(23);
        startRedirectMinute.setValue(0);
        stopRedirectMinute.setValue(59);

        startRedirectHour.setReadOnly(true);
        startRedirectMinute.setReadOnly(true);
        stopRedirectHour.setReadOnly(true);
        stopRedirectMinute.setReadOnly(true);
    }

    /**
     *  (noanswer?unonline?busy?force)
     * @param panelContent
     */
    private void createRedirectType(VerticalLayout panelContent) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        panelContent.addComponent(layout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        caption.setDescription("<B>????</B>");
        layout.addComponent(caption);

        redirectTypeOption = new OptionGroup();
        redirectTypeOption.addItem("noanswer");
        redirectTypeOption.setItemCaption("noanswer", "?");
        redirectTypeOption.addItem("busy");
        redirectTypeOption.setItemCaption("busy", "");
        redirectTypeOption.addItem("unonline");
        redirectTypeOption.setItemCaption("unonline", "");
        redirectTypeOption.setNullSelectionAllowed(false);
        redirectTypeOption.addListener(this);
        redirectTypeOption.setImmediate(true);
        redirectTypeOption.setMultiSelect(true);
        redirectTypeOption.addStyleName("threecol");
        redirectTypeOption.addStyleName("myopacity");
        redirectTypeOption.setReadOnly(true);
        redirectTypeOption
                .setDescription("<B>????</B>");
        layout.addComponent(redirectTypeOption);
    }

    /**
     * ?? 
     * @param panelContent
     */
    private void createNoanwserTimeout(VerticalLayout panelContent) {
        noanswerLayout = new HorizontalLayout();
        noanswerLayout.setSpacing(true);
        noanswerLayout.setVisible(false);
        panelContent.addComponent(noanswerLayout);

        Label freCaption = new Label("?");
        freCaption.setWidth("-1px");
        freCaption.setDescription(
                "<B>'?'??</B>");
        noanswerLayout.addComponent(freCaption);

        noanswerTimeoutSelector = new ComboBox();
        noanswerTimeoutSelector.setImmediate(true);
        noanswerTimeoutSelector.setWidth("50px");
        noanswerTimeoutSelector.setNullSelectionAllowed(false);
        noanswerTimeoutSelector.setDescription(
                "<B>'?'??</B>");
        noanswerLayout.addComponent(noanswerTimeoutSelector);

        for (int seconds = 3; seconds < 61; seconds++) {
            noanswerTimeoutSelector.addItem(seconds);
        }
        noanswerTimeoutSelector.setValue(10);
        noanswerTimeoutSelector.setReadOnly(true);

        Label postCaption = new Label(" ");
        postCaption.setWidth("-1px");
        postCaption.setDescription(
                "<B>'?'??</B>");
        noanswerLayout.addComponent(postCaption);
    }

    /**
     * ???
     * @param panelContent
     */
    private void createSpecifiedPhone(VerticalLayout panelContent) {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);
        panelContent.addComponent(layout);

        Label caption = new Label("??");
        caption.setWidth("-1px");
        caption.setDescription(
                "<B>'?'??'??'</B>");
        layout.addComponent(caption);

        specifiedOption = new OptionGroup();
        specifiedOption.addItem(false);
        specifiedOption.addItem(true);
        specifiedOption.setItemCaption(false, "?");
        specifiedOption.setItemCaption(true, "??");
        specifiedOption.addListener(this);
        specifiedOption.setImmediate(true);
        specifiedOption.setReadOnly(true);
        specifiedOption.setNullSelectionAllowed(false);
        specifiedOption.addStyleName("twocol200");
        specifiedOption.addStyleName("myopacity");
        specifiedOption.setDescription(
                "<B>'?'??'??'</B>");
        layout.addComponent(specifiedOption);
    }

    /**
     * ??
     * @param panelContent
     */
    private void createPhoneArea(VerticalLayout panelContent) {
        phoneAreaLayout = new HorizontalLayout();
        phoneAreaLayout.setWidth("100%");
        phoneAreaLayout.setVisible(false);
        phoneAreaLayout.setSpacing(true);
        panelContent.addComponent(phoneAreaLayout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        caption.setDescription(
                "<B>'??'???</B>");
        phoneAreaLayout.addComponent(caption);

        phoneArea = new TextArea();
        phoneArea.setRows(6);
        phoneArea.setWidth("100%");
        phoneArea.setImmediate(true);
        phoneArea.setReadOnly(true);
        phoneArea.setInputPrompt(
                "???, ???(,)?");
        phoneArea.setDescription(
                "<B>'??'???</B>");
        phoneAreaLayout.addComponent(phoneArea);
        phoneAreaLayout.setExpandRatio(phoneArea, 1.0f);
    }

    /**
     *  ????
     * @param panelContent
     */
    private void createCsrSelectTables(VerticalLayout panelContent) {
        csrSelectHLayout = new HorizontalLayout();
        csrSelectHLayout.setSpacing(true);
        csrSelectHLayout.setVisible(false);
        csrSelectHLayout.setWidth("100%");
        panelContent.addComponent(csrSelectHLayout);

        Label caption = new Label("");
        caption.setWidth("-1px");
        caption.setDescription("<B>??</B>");
        csrSelectHLayout.addComponent(caption);

        // ???
        HorizontalLayout panelLayout = new HorizontalLayout();
        panelLayout.setSpacing(true);
        panelLayout.setMargin(false, true, false, true);
        panelLayout.setWidth("100%");

        Panel tablePanel = new Panel();
        tablePanel.setContent(panelLayout);
        csrSelectHLayout.addComponent(tablePanel);
        csrSelectHLayout.setExpandRatio(tablePanel, 1.0f);

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

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

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

    /**
     *  ?(??)
     * @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);
        leftKeyword.setEnabled(false);
        searchHLayout.addComponent(leftKeyword);
        searchHLayout.setComponentAlignment(leftKeyword, Alignment.MIDDLE_CENTER);

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

        // 
        leftTable = new Table("?");
        leftTable.addStyleName("striped");
        leftTable.addStyleName("mydisabled");
        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(10);
        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);
        addAll.setEnabled(false);
        operatorVLayout.addComponent(addAll);
        operatorVLayout.setComponentAlignment(addAll, Alignment.MIDDLE_CENTER);

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

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

        removeAll = new Button("<<<", this);
        removeAll.setEnabled(false);
        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);
        rightKeyword.setEnabled(false);
        searchHLayout.addComponent(rightKeyword);
        searchHLayout.setComponentAlignment(rightKeyword, Alignment.MIDDLE_CENTER);

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

        // 
        rightTable = new Table("");
        rightTable.addStyleName("striped");
        rightTable.addStyleName("mydisabled");
        rightTable.setSelectable(true);
        rightTable.setMultiSelect(true);
        rightTable.setWidth("100%");
        rightTable.setPageLength(10);
        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);

        return rightVLayout;
    }

    /**
     * 
     * @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 });

                // ????
                initializeTablesCaption();
            }

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

    /**
     * ?
     * @return
     */
    private HorizontalLayout createOperatorButtons() {
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSpacing(true);

        // 
        edit = new Button(" ", this);
        edit.setStyleName("default");
        edit.setVisible(true);
        edit.setImmediate(true);
        layout.addComponent(edit);

        // ?
        save = new Button("? ", this);
        save.setStyleName("default");
        save.setVisible(false);
        save.setImmediate(true);
        layout.addComponent(save);

        // ?
        cancel = new Button("? ", this);
        layout.addComponent(cancel);
        cancel.setVisible(false);
        cancel.setImmediate(true);

        return layout;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void valueChange(ValueChangeEvent event) {
        Property source = event.getProperty();
        if (source == dayOfWeekTypeSelector) {
            String type = (String) dayOfWeekTypeSelector.getValue();
            dayOfWeekLayout.setVisible("custom".equals(type));
        } else if (source == specifiedOption) {
            Boolean isSpecified = (Boolean) specifiedOption.getValue();
            phoneAreaLayout.setVisible(isSpecified);
            csrSelectHLayout.setVisible(!isSpecified);
        } else if (source == redirectTypeOption) {
            Set<String> redirectTypes = (Set<String>) redirectTypeOption.getValue();
            boolean iscontain = redirectTypes.contains("noanswer");
            if (noanswerLayout != null) {
                noanswerLayout.setVisible(iscontain);
            }
        }
    }

    @Override
    public void buttonClick(ClickEvent event) {
        Button source = event.getButton();
        if (source == edit) {
            changeComponentsStatus(false);
        } else if (source == save) {
            try {
                Set<String> usefullPhones = excuteConfirmPhoneNum();
                String[] runTimeScope = executeConfirmRunTime();
                if (runTimeScope != null) {
                    executeSave(runTimeScope, usefullPhones);
                    notification.setCaption("<B>??!</B>");
                    this.getApplication().getMainWindow().showNotification(notification);
                    // ?
                    refreshSettingInfos(this.globalP2PSetting);
                }
            } catch (Exception e) {
                logger.error("Manager ??? --> " + e.getMessage(), e);
                notification.setCaption("<font color='red'>?????</font>");
                this.getApplication().getMainWindow().showNotification(notification);
            }
        } else if (source == cancel) {
            refreshSettingInfos(this.globalP2PSetting);
        } else if (source == leftSearch) {
            executeLeftSearch();
        } else if (source == rightSearch) {
            executeRightSearch();
        } 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);
            rightTable.setValue(null);
        }
    }

    /**
     * ????
     * @param readOnly
     */
    private void changeComponentsStatus(boolean readOnly) {
        // ??
        startSettingOption.setReadOnly(readOnly);
        licensed2CsrOption.setReadOnly(readOnly);
        dayOfWeekTypeSelector.setReadOnly(readOnly);
        daysOfWeekOption.setReadOnly(readOnly);
        startRedirectHour.setReadOnly(readOnly);
        startRedirectMinute.setReadOnly(readOnly);
        stopRedirectHour.setReadOnly(readOnly);
        stopRedirectMinute.setReadOnly(readOnly);
        redirectTypeOption.setReadOnly(readOnly);
        noanswerTimeoutSelector.setReadOnly(readOnly);
        specifiedOption.setReadOnly(readOnly);
        phoneArea.setReadOnly(readOnly);

        // ??
        leftKeyword.setEnabled(!readOnly);
        leftSearch.setEnabled(!readOnly);
        rightKeyword.setEnabled(!readOnly);
        rightSearch.setEnabled(!readOnly);
        rightTable.setEnabled(!readOnly);
        leftTable.setEnabled(!readOnly);
        addAll.setEnabled(!readOnly);
        add.setEnabled(!readOnly);
        remove.setEnabled(!readOnly);
        removeAll.setEnabled(!readOnly);

        // ??
        edit.setVisible(readOnly);
        save.setVisible(!readOnly);
        cancel.setVisible(!readOnly);
    }

    /**
     * ??
     */
    private void refreshSettingInfos(Phone2PhoneSetting globalP2PSetting) {
        // ?
        if (globalP2PSetting != null) { // ??
            // ?
            changeComponentsStatus(false);

            // ?
            startSettingOption.setValue(globalP2PSetting.getIsStartedRedirect());
            // ???
            licensed2CsrOption.setValue(globalP2PSetting.getIsLicensed2Csr());
            // 
            dayOfWeekTypeSelector.setValue(globalP2PSetting.getDayOfWeekType());

            // ?
            Set<DayOfWeek> dayOfWeeks = globalP2PSetting.getDaysOfWeek();
            daysOfWeekOption.setValue(dayOfWeeks);

            // 
            String[] startTimeStrs = globalP2PSetting.getStartTime().split(":");
            startRedirectHour.setValue(Integer.parseInt(startTimeStrs[0]));
            startRedirectMinute.setValue(Integer.parseInt(startTimeStrs[1]));

            String[] stopTimeStrs = globalP2PSetting.getStopTime().split(":");
            stopRedirectHour.setValue(Integer.parseInt(stopTimeStrs[0]));
            stopRedirectMinute.setValue(Integer.parseInt(stopTimeStrs[1]));

            // 
            Set<String> redirectTypes = globalP2PSetting.getRedirectTypes();
            redirectTypeOption.setValue(redirectTypes);
            // 
            noanswerLayout.setVisible(redirectTypes.contains("noanswer"));
            noanswerTimeoutSelector.setValue(globalP2PSetting.getNoanswerTimeout());

            leftTableContainer.removeAllItems();
            leftTableContainer.addAll(userService.getCsrsByDomain(domain));

            // ?
            specifiedOption.setValue(globalP2PSetting.getIsSpecifiedPhones());

            // ??
            StringBuffer phoneNumstrs = new StringBuffer();
            for (String phoneNum : globalP2PSetting.getSpecifiedPhones()) {
                phoneNumstrs.append(phoneNum);
                phoneNumstrs.append(",");
            }
            String phoneNums = phoneNumstrs.toString();
            if (phoneNums.endsWith(",")) {
                phoneNums = phoneNums.substring(0, phoneNums.length() - 1);
            }
            phoneArea.setValue(phoneNums);

            // ??
            List<User> allCsrs = userService.getCsrsByDomain(domain);
            Set<User> oldSelectedCsrs = globalP2PSetting.getSpecifiedCsrs();
            leftTableContainer.removeAllItems();
            rightTableContainer.removeAllItems();
            for (User user : allCsrs) {
                if (oldSelectedCsrs.size() == 0) {
                    leftTableContainer.addAll(allCsrs);
                    break;
                }
                // ?user ??? true ,?
                boolean needAddToRightTable = false;
                for (User csr : oldSelectedCsrs) {
                    if (user.getId().equals(csr.getId())) {
                        rightTableContainer.addBean(user);
                        needAddToRightTable = true;
                        break;
                    }
                }

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

        // ??
        changeComponentsStatus(true);
    }

    /**
     * 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 });
    }

    /**
     * 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);
        }

        // ?
        initializeTablesCaption();
    }

    /**
     * ??
     */
    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);
    }

    /**
     * ?????
     * @param usefullPhones   ????
     */
    private Set<String> excuteConfirmPhoneNum() {
        Set<String> usefullPhones = new HashSet<String>();
        Boolean specified = (Boolean) specifiedOption.getValue();
        if (specified) {
            // ???? 0 ??? 0 ???
            String phoneStr = (String) phoneArea.getValue();
            if (phoneStr != null && !"".equals(phoneStr.trim())) {
                String[] phoneNums = phoneStr.split(",");
                for (String phoneNum : phoneNums) {
                    if (!phoneNum.trim().matches("\\d+")) {
                        continue;
                    }
                    String remoteNum = ""; //  0 ??
                    String localNum = ""; // ? 0 ??
                    if (phoneNum.startsWith("0")) {
                        remoteNum = phoneNum;
                        localNum = phoneNum.substring(1);
                    } else {
                        remoteNum = "0" + phoneNum;
                        localNum = phoneNum;
                    }
                    if (!usefullPhones.contains(localNum) && !usefullPhones.contains(remoteNum)) {
                        usefullPhones.add(phoneNum.trim());
                    }
                }
            }
        }
        return usefullPhones;
    }

    /**
     * ?????
     * @return boolean 
     * @throws ParseException
     */
    private String[] executeConfirmRunTime() {
        String[] runTimeScope = new String[2];
        try {
            // ??? < ?
            StringBuffer startTimeStr = new StringBuffer();
            startTimeStr.append(((Integer) startRedirectHour.getValue()).toString());
            startTimeStr.append(":");
            startTimeStr.append(((Integer) startRedirectMinute.getValue()).toString());
            Date startDate = simpleDateFormat.parse(startTimeStr.toString());

            StringBuffer stopTimeStr = new StringBuffer();
            stopTimeStr.append(((Integer) stopRedirectHour.getValue()).toString());
            stopTimeStr.append(":");
            stopTimeStr.append(((Integer) stopRedirectMinute.getValue()).toString());
            Date stopDate = simpleDateFormat.parse(stopTimeStr.toString());
            if (startDate.after(stopDate)) {
                notification.setCaption(
                        "<font color='red'>???18:00-22:00!</font>");
                save.getApplication().getMainWindow().showNotification(notification);
                return null;
            }

            runTimeScope[0] = startTimeStr.toString();
            runTimeScope[1] = stopTimeStr.toString();
        } catch (Exception e) {
            logger.error("Manager ? ?? ---> " + e.getMessage(), e);
            notification.setCaption("<font color='red'>??!</font>");
            this.getApplication().getMainWindow().showNotification(notification);
            return null;
        }
        return runTimeScope;
    }

    /**
     * ??
     * @param runTimeScope   
     * @param usefullPhones   ?
     * @return
     */
    @SuppressWarnings({ "unchecked" })
    private void executeSave(String[] runTimeScope, Set<String> usefullPhones) {
        // ?
        Phone2PhoneSetting oldP2PSetting = cloneP2PSetting();
        //      TODO ?
        System.out.println("oldP2PSetting.getIsStartedRedirect()--------> " + oldP2PSetting.getIsStartedRedirect());
        Boolean oldLicensed2Csr = oldP2PSetting.getIsLicensed2Csr();
        Boolean oldSpecified = oldP2PSetting.getIsSpecifiedPhones();
        Set<User> oldCsrs = oldP2PSetting.getSpecifiedCsrs();
        Set<String> oldPhones = oldP2PSetting.getSpecifiedPhones();
        System.out.println(oldPhones.size());

        // ??
        Boolean currentStartSetting = (Boolean) startSettingOption.getValue();
        Boolean currentLicensed2Csr = (Boolean) licensed2CsrOption.getValue();
        String currentDayOfWeekType = (String) dayOfWeekTypeSelector.getValue();
        Set<DayOfWeek> currentDaysOfWeek = (Set<DayOfWeek>) daysOfWeekOption.getValue();
        Set<String> redirectTypes = (Set<String>) redirectTypeOption.getValue();
        Integer noanswerTimeout = (Integer) noanswerTimeoutSelector.getValue();
        Boolean currentSpecified = (Boolean) specifiedOption.getValue();
        Set<User> currentCsrs = new HashSet<User>(rightTableContainer.getItemIds());

        // ?
        globalP2PSetting.setIsStartedRedirect(currentStartSetting);
        globalP2PSetting.setIsLicensed2Csr(currentLicensed2Csr);
        globalP2PSetting.setDayOfWeekType(currentDayOfWeekType);
        if ("custom".equals(currentDayOfWeekType)) {
            globalP2PSetting.setDaysOfWeek(currentDaysOfWeek);
        }
        globalP2PSetting.setStartTime(runTimeScope[0]);
        globalP2PSetting.setStopTime(runTimeScope[1]);
        globalP2PSetting.setRedirectTypes(redirectTypes);
        globalP2PSetting.setNoanswerTimeout(noanswerTimeout);
        globalP2PSetting.setIsSpecifiedPhones(currentSpecified);
        if (currentSpecified) {
            globalP2PSetting.setSpecifiedPhones(usefullPhones);
        }
        globalP2PSetting.setSpecifiedCsrs(currentCsrs);

        // ??
        globalP2PSetting = phone2PhoneSettingService.update(globalP2PSetting);

        //----------------------  ????   ------------------// 
        String defaultOutline = ShareData.domainToDefaultOutline.get(domain.getId());
        if (defaultOutline == null) {
            return;
        }

        // ??
        List<Queue> allCommonQueues = queueService.getAllByDomain(domain, true);
        List<String> allCommonQueueNames = new ArrayList<String>();
        for (Queue autoQueue : allCommonQueues) {
            allCommonQueueNames.add(autoQueue.getName());
        }
        List<Phone2PhoneSetting> customSettings = phone2PhoneSettingService.getAllCsrCustomSettings(domain.getId());

        // ?????????????
        boolean isOldGlobalRunning = phone2PhoneSettingService.confirmSettingIsRunning(oldP2PSetting);
        System.out.println("isOldGlobalRunning------->" + isOldGlobalRunning);
        if (isOldGlobalRunning) {
            // ????
            System.out.println("oldSpecified---------->" + oldSpecified);
            if (oldSpecified) {
                for (String oldPhone : oldPhones) {
                    System.out.println(oldPhone);
                    for (String queueName : allCommonQueueNames) {
                        queueMemberRelationService.removeQueueMemberRelation(queueName,
                                oldPhone + "@" + defaultOutline);
                    }
                }
            } else { // ?????
                for (User oldCsr : oldCsrs) {
                    System.out.println("oldCsr.getid() ----> " + oldCsr.getId());
                    removePhone2QueueMember(oldCsr, defaultOutline, allCommonQueueNames);
                }
            }
        }

        // ???????????????
        if (oldLicensed2Csr) {
            for (Phone2PhoneSetting customSetting : customSettings) {
                boolean isOldCustomRunning = phone2PhoneSettingService.confirmSettingIsRunning(customSetting);
                if (isOldCustomRunning) {
                    User csr = customSetting.getCreator();
                    removePhone2QueueMember(csr, defaultOutline, allCommonQueueNames);
                }
            }
        }

        // ???,?
        // ??1????2????? <= ?    >= ?
        boolean isGlobalRunning = phone2PhoneSettingService.confirmSettingIsRunning(globalP2PSetting);
        if (isGlobalRunning) {
            // ??????
            if (currentSpecified) {
                //  ???
                for (String phoneNumber : usefullPhones) {
                    for (String queueName : allCommonQueueNames) {
                        queueMemberRelationService.addQueueMemberRelation(queueName,
                                phoneNumber + "@" + defaultOutline, 5);
                    }
                }
                // ????????????
                for (String exten : ShareData.userToExten.values()) {
                    for (String queueName : allCommonQueueNames) { // ????
                        queueMemberRelationService.removeQueueMemberRelation(queueName, exten);
                    }
                }
            } else { // ?????
                for (User currentCsr : currentCsrs) {
                    addPhone2QueueMember(currentCsr, defaultOutline, allCommonQueueNames);
                }
                // ??????????
                if (oldSpecified) {
                    for (Long csrId : ShareData.userToExten.keySet()) {
                        addExten2QueueMember(csrId, allCommonQueueNames);
                    }
                }
            }
        } else if (isOldGlobalRunning) { // ??????
            for (Long csrId : ShareData.userToExten.keySet()) {
                addExten2QueueMember(csrId, allCommonQueueNames);
            }
        }

        // ?
        if (globalP2PSetting.getIsStartedRedirect()) {
            phone2PhoneSettingService.createP2PScheduler(globalP2PSetting);
        } else {
            phone2PhoneSettingService.stopP2PScheduler(globalP2PSetting);
        }

        // ??????????????
        if (currentLicensed2Csr) {
            // ???id ?
            List<Long> currentCsrIds = new ArrayList<Long>();
            for (User currentCsr : currentCsrs) {
                currentCsrIds.add(currentCsr.getId());
            }

            for (Phone2PhoneSetting customSetting : customSettings) {
                User csr = customSetting.getCreator();
                // ???????????
                if (!currentSpecified && currentCsrIds.contains(csr.getId())) {
                    continue;
                }
                // ???
                boolean isCustomRunning = phone2PhoneSettingService.confirmSettingIsRunning(customSetting);
                if (isCustomRunning) {
                    addPhone2QueueMember(csr, defaultOutline, allCommonQueueNames);
                }
            }
        }
    }

    /**
     * ??
     * @return
     */
    private Phone2PhoneSetting cloneP2PSetting() {
        Phone2PhoneSetting oldP2PSetting = new Phone2PhoneSetting();
        oldP2PSetting.setCreator(globalP2PSetting.getCreator());
        oldP2PSetting.setDayOfWeekType(globalP2PSetting.getDayOfWeekType());
        oldP2PSetting.setDaysOfWeek(globalP2PSetting.getDaysOfWeek());
        oldP2PSetting.setDomain(globalP2PSetting.getDomain());
        oldP2PSetting.setId(globalP2PSetting.getId());
        oldP2PSetting.setIsGlobalSetting(globalP2PSetting.getIsGlobalSetting());
        oldP2PSetting.setIsLicensed2Csr(globalP2PSetting.getIsLicensed2Csr());
        oldP2PSetting.setIsSpecifiedPhones(globalP2PSetting.getIsSpecifiedPhones());
        oldP2PSetting.setSpecifiedPhones(globalP2PSetting.getSpecifiedPhones());
        oldP2PSetting.setIsStartedRedirect(globalP2PSetting.getIsStartedRedirect());
        oldP2PSetting.setRedirectTypes(globalP2PSetting.getRedirectTypes());
        oldP2PSetting.setSpecifiedCsrs(globalP2PSetting.getSpecifiedCsrs());
        oldP2PSetting.setStartTime(globalP2PSetting.getStartTime());
        oldP2PSetting.setStopTime(globalP2PSetting.getStopTime());
        return oldP2PSetting;
    }

    /**
     * ??????
     * @param csr               ?
     * @param defaultOutline      
     * @param allCommonQueueNames   ?
     */
    private void removePhone2QueueMember(User csr, String defaultOutline, List<String> allCommonQueueNames) {
        // ???? 
        if (ShareData.userToExten.keySet().contains(csr.getId())) {
            return;
        }
        String phoneNum = csr.getPhoneNumber();
        if (phoneNum == null || "".equals(phoneNum)) { // ???
            return;
        }
        // ???????
        List<UserQueue> userQueues = userQueueService.getAllByUsername(csr.getUsername());
        for (UserQueue userQueue : userQueues) {
            String queueName = userQueue.getQueueName();
            if (allCommonQueueNames.contains(queueName)) { // ?????
                queueMemberRelationService.removeQueueMemberRelation(queueName, phoneNum + "@" + defaultOutline);
            }
        }
    }

    /**
     * ??????
     * @param csr               ?
     * @param defaultOutline      
     * @param allCommonQueueNames   ?
     */
    private void addPhone2QueueMember(User csr, String defaultOutline, List<String> allCommonQueueNames) {
        // ???? 
        if (ShareData.userToExten.keySet().contains(csr.getId())) {
            return;
        }
        String phoneNum = csr.getPhoneNumber();
        if (phoneNum == null || "".equals(phoneNum)) { // ???
            return;
        }
        // ???????
        List<UserQueue> userQueues = userQueueService.getAllByUsername(csr.getUsername());
        for (UserQueue userQueue : userQueues) {
            String queueName = userQueue.getQueueName();
            if (allCommonQueueNames.contains(queueName)) { // ?????
                queueMemberRelationService.addQueueMemberRelation(queueName, phoneNum + "@" + defaultOutline, 5);
            }
        }
    }

    /**
     * ?
     *    ?
     *       ????? <= ?
     *       1???????????
     *       2???????
     * @param csrId               ?id
     * @param allCommonQueueNames   ?
     */
    private void addExten2QueueMember(Long csrId, List<String> allCommonQueueNames) {
        User csr = userService.get(csrId);
        String exten = ShareData.userToExten.get(csrId);
        // ??
        List<UserQueue> userQueueList = userQueueService.getAllByUsername(csr.getUsername());
        // ???
        List<StaticQueueMember> staticQMs = staticQueueMemberService.getAllBySipname(domain, exten);
        for (UserQueue userQueue : userQueueList) {
            String queueName = userQueue.getQueueName();
            if (allCommonQueueNames.contains(queueName)) { // ?????
                queueMemberRelationService.addQueueMemberRelation(queueName, exten, userQueue.getPriority());
            }
        }

        for (StaticQueueMember sqm : staticQMs) {
            queueMemberRelationService.addQueueMemberRelation(sqm.getQueueName(), exten, sqm.getPriority());
        }
    }

    /**
     *  ?
     */
    public void update() {
        attach();
    }

}