Package open.dolphin.impl.login

Source Code of open.dolphin.impl.login.LoginDialog$Blocker

package open.dolphin.impl.login;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Date;
import java.util.Properties;
import javax.swing.JOptionPane;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import open.dolphin.client.BlockGlass;
import open.dolphin.client.ClientContext;
import open.dolphin.delegater.UserDelegater;
import open.dolphin.helper.ProxyActionListener;
import open.dolphin.helper.ProxyDocumentListener;
import open.dolphin.helper.ProxyPropertyChangeListener;
import open.dolphin.helper.Task;
import open.dolphin.infomodel.ModelUtils;
import open.dolphin.infomodel.UserModel;
import open.dolphin.project.DolphinPrincipal;
import open.dolphin.project.Project;
import open.dolphin.setting.ProjectSettingDialog;
import open.dolphin.ui.IMEControl;
import open.dolphin.ui.MyJSheet;
import org.apache.log4j.Logger;
import org.jboss.ejb.client.ContextSelector;
import org.jboss.ejb.client.EJBClientConfiguration;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;

/**
* ログインダイアログ クラス。
*
* @author  Kazushi Minagawa, Digital Globe, Inc.
*/
public class LoginDialog {
   
    /** Login Status */
    public enum LoginStatus {AUTHENTICATED, NOT_AUTHENTICATED, CANCELD};
   
    private LoginView view;
    private BlockGlass blockGlass;
   
    // 認証制御用
    private UserDelegater userDlg;
    private Logger part11Logger;
    private int tryCount;
    private int maxTryCount;
   
    // 認証結果のプロパティ
    private LoginStatus result;
    private PropertyChangeSupport boundSupport;
   
    // モデル
    private DolphinPrincipal principal;
   
    // StateMgr
    private StateMgr stateMgr;
   
   
    /**
     * Creates new LoginService
     */
    public LoginDialog() {
    }
   
    /**
     * 認証結果プロパティリスナを登録する。
     * @param listener 登録する認証結果リスナ
     */
    public void addPropertyChangeListener(String prop, PropertyChangeListener listener) {
        if (boundSupport == null) {
            boundSupport = new PropertyChangeSupport(this);
        }
        boundSupport.addPropertyChangeListener(prop, listener);
    }
   
    /**
     * 認証結果プロパティリスナを登録する。
     * @param listener 削除する認証結果リスナ
     */
    public void removePropertyChangeListener(String prop, PropertyChangeListener listener) {
        if (boundSupport == null) {
            boundSupport = new PropertyChangeSupport(this);
        }
        boundSupport.addPropertyChangeListener(prop, listener);
    }
   
    /**
     * ログイン画面を開始する。
     */
    public void start() {
       
        //
        // ダイアログモデルを生成し値を初期化する
        //
        principal = new DolphinPrincipal();
        if (Project.isValid()) {
            principal.setFacilityId(Project.getFacilityId());
            principal.setUserId(Project.getUserId());
        }
       
        //
        // GUI を構築しモデルを表示する
        //
        initComponents();
        bindModelToView();
       
        //
        // EDT からコールされている
        //
        int width = view.getWidth();
        int height = view.getHeight();
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int n = ClientContext.isMac() ? 3 : 2;
        int left = (screen.width - width) / 2;
        int top = (screen.height - height) / n;
        view.setLocation(left, top);
        view.setVisible(true);
    }
   
    /**
     * 認証が成功したかどうかを返す。
     * @return true 認証が成功した場合
     */
    public LoginStatus getResult() {
        return result;
    }
   
    /**
     * PropertyChange で結果を受け取るアプリに通知する。
     * @param result true 認証が成功した場合
     */
    private void notifyResult(final LoginStatus ret) {
         SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
               boundSupport.firePropertyChange("LOGIN_PROP", -100, ret);
            }
        });
    }
   
    /**
     * 認証を試みる。
     * DatabaseLoginModule を使用、UserValueが取得できた場合に認証が成功したとみなす。
     * 詳細はBusiness Delegater へ委譲。
     */
    public void tryLogin() {
       
        // User 情報を取得するためのデリゲータを得る
        if (userDlg == null) {
            userDlg = new UserDelegater();
        }
       
        // Part11 ロガーを取得する
        if (part11Logger == null) {
            part11Logger = ClientContext.getPart11Logger();
        }
       
        // トライ出来る最大回数を得る
        if (maxTryCount == 0) {
            maxTryCount = ClientContext.getInt("loginDialog.maxTryCount");
        }
       
        part11Logger.info("認証を開始します");
       
        // 試行回数 += 1
        tryCount++;
       
        // userIdとpasswordを取得する
        bindViewToModel();
        final String password = new String(view.getPasswordField().getPassword());
       
        // LoginTask を生成する
        int maxEstimation = ClientContext.getInt("task.default.maxEstimation");
        int delay = ClientContext.getInt("task.default.delay");
        int lengthOfTask = maxEstimation / delay;  // タスクの長さ = 最大予想時間 / 割り込み間隔

        String message = "ログイン";
        String note = "認証中...";
       
        Task task = new Task<UserModel>(view, message, note, maxEstimation) {

            @Override
            protected UserModel doInBackground() throws Exception {
               
                // ログイン手順開始
                String pk = principal.getFacilityId() + ":" + principal.getUserId();

                // LoginContext, SecurityAssociation は廃止されて,EJBClientContext を使うようになった
                Properties props = new Properties();
                props.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
                props.put("remote.connections", "default");
                props.put("remote.connection.default.host", Project.getHostAddress());
                props.put("remote.connection.default.port", String.valueOf(Project.getHostPort()));
                props.put("remote.connection.default.username", pk);
                props.put("remote.connection.default.password", password.toString());
                //props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
                props.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");

                // create client configuration
                final EJBClientConfiguration clientConfiguration = new PropertiesBasedEJBClientConfiguration(props);
                // create a context selector
                final ContextSelector<EJBClientContext> contextSelector = new ConfigBasedEJBClientContextSelector(clientConfiguration);
                // set the selector for use
                EJBClientContext.setSelector(contextSelector);       
                               
                return userDlg.getUser(pk);
            }
           
            @Override
            protected void succeeded(UserModel userModel) {
                part11Logger.debug("Task succeeded");
                if (userModel != null) {

                    Project.UserType userType = Project.UserType.valueOf(userModel.getMemberType());
                    part11Logger.info("User Type = " + userType.toString());

                    // 認証成功
                    String time = ModelUtils.getDateTimeAsString(new Date());
                    part11Logger.info(time + ": " + userModel.getUserId() + " がログインしました");

                    // ユーザID、施設ID、ユーザモデルを rojectStub へ保存する
                    Project.getProjectStub().setUserId(principal.getUserId());
                    Project.getProjectStub().setUserModel(userModel);
                    Project.getProjectStub().setDolphinPrincipal(principal);
                    Project.getProjectStub().setUserPassword(password);

                    result = LoginStatus.AUTHENTICATED;
                    notifyClose(result);
                    
                } else {
                    part11Logger.warn("User == null, this never ocuured");
                }
            }
           
            @Override
            protected void failed(java.lang.Throwable cause) {
                part11Logger.warn("Task failed");
                part11Logger.warn(cause.getCause());
                part11Logger.warn(cause.getMessage());
                if (tryCount <= maxTryCount && cause instanceof Exception) {
                    userDlg.processError((Exception) cause);
                    String errMsg = userDlg.getErrorMessage();
                    showMessageDialog(errMsg);
                } else {
                    StringBuilder sb = new StringBuilder();
                    userDlg.processError((Exception) cause);
                    sb.append(userDlg.getErrorMessage());
                    sb.append("\n");
                    sb.append(ClientContext.getString("loginDialog.forceClose"));
                    String msg = sb.toString();
                    showMessageDialog(msg);
                    result = LoginStatus.NOT_AUTHENTICATED;
                    notifyClose(result);
                }
            }           
        };
        task.setInputBlocker(new Blocker());
        task.setMillisToDecidePopup(3000);
        task.execute();
    }

    private class Blocker implements Task.InputBlocker {

        @Override
        public void block() {
            blockGlass.block();
            view.getUserIdField().setEnabled(false);
            view.getPasswordField().setEnabled(false);
            view.getSettingBtn().setEnabled(false);
            view.getLoginBtn().setEnabled(false);
            view.getCancelBtn().setEnabled(false);
            view.getProgressBar().setIndeterminate(true);
        }

        @Override
        public void unblock() {
            blockGlass.unblock();
            view.getUserIdField().setEnabled(true);
            view.getPasswordField().setEnabled(true);
            view.getSettingBtn().setEnabled(true);
            view.getLoginBtn().setEnabled(true);
            view.getCancelBtn().setEnabled(true);
            view.getProgressBar().setIndeterminate(false);
            view.getProgressBar().setValue(0);
        }
    }
   
    /**
     * 警告メッセージを表示する。
     * @param msg 表示するメッセージ
     */
    private void showMessageDialog(String msg) {
        String title = view.getTitle();

        MyJSheet.showMessageDialog(view, msg, title, JOptionPane.WARNING_MESSAGE);
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                view.getPasswordField().requestFocusInWindow();
                view.getPasswordField().selectAll();
            }
        });
    }
   
    /**
     * ログインダイアログを終了する。
     * @param result
     */
    private void notifyClose(LoginStatus result) {
        view.setVisible(false);
        view.dispose();
        notifyResult(result);
    }
   
    /**
     * GUI を構築する。
     */
    private void initComponents() {
       
        view = new LoginView((Frame) null, false);
        view.getRootPane().setDefaultButton(view.getLoginBtn());
        blockGlass = new BlockGlass();
        view.setGlassPane(blockGlass);
       
        setWindowTitle();
       
        //
        // イベント接続を行う
        //
        connect();
    }
   
    /**
     * window title を表示する HostAddress-OpenDolphin-Version という表示
     */
    private void setWindowTitle() {
        String title = ClientContext.getFrameTitle(Project.getProjectStub().getHostAddress());
        view.setTitle(title);
    }
   
    /**
     * イベント接続を行う。
     */
    private void connect() {
       
        //
        // Mediator ライクな StateMgr
        //
        stateMgr = new StateMgr();
       
        //
        // フィールドにリスナを登録する
        //
        JTextField userIdField = view.getUserIdField();
        userIdField.getDocument().addDocumentListener(ProxyDocumentListener.create(stateMgr, "checkButtons"));
        IMEControl.setImeOffIfFocused(userIdField);       
        userIdField.addActionListener(ProxyActionListener.create(stateMgr, "onUserIdAction"));
       
        JPasswordField passwdField = view.getPasswordField();
        passwdField.getDocument().addDocumentListener(ProxyDocumentListener.create(stateMgr, "checkButtons"));
        IMEControl.setImeOffIfFocused(passwdField);
        passwdField.addActionListener(ProxyActionListener.create(stateMgr, "onPasswordAction"));
       
        //
        // ボタンに ActionListener を登録する
        //
        view.getSettingBtn().addActionListener(ProxyActionListener.create(this, "doSettingDialog"));
        view.getCancelBtn().addActionListener(ProxyActionListener.create(this, "doCancel"));
        view.getLoginBtn().addActionListener(ProxyActionListener.create(this, "tryLogin"));
        view.getLoginBtn().setEnabled(false);
               
        //
        // ダイアログに WindowAdapter を設定する
        //
        view.addWindowListener(stateMgr);
    }
   
    /**
     * モデルを表示する。
     */
    private void bindModelToView() {
       
        if (principal.getUserId() != null && (!principal.getUserId().equals(""))) {
            view.getUserIdField().setText(principal.getUserId());
            view.getSavePasswordCbx().setSelected(Project.getProjectStub().isSavePassword());
           
            if (view.getSavePasswordCbx().isSelected()) {
                view.getPasswordField().setText(Project.getUserPassword());
                view.getPasswordField().selectAll();
            }
        }
    }
   
    /**
     * モデル値を取得する。
     */
    private void bindViewToModel() {
       
        String id = view.getUserIdField().getText().trim();
       
        if (!id.equals("")) {
            principal.setUserId(id);
        }
       
        Project.getProjectStub().setSavePassword(view.getSavePasswordCbx().isSelected());
    }
   
   
    /**
     * 設定ボタンがおされた時、設定画面を開始する。
     */
    public void doSettingDialog() {
       
        blockGlass.block();
       
        ProjectSettingDialog sd = new ProjectSettingDialog();
        PropertyChangeListener pl = ProxyPropertyChangeListener.create(this, "setNewParams", new Class[]{Boolean.class});
        sd.addPropertyChangeListener("SETTING_PROP", pl);
        sd.setLoginState(false);
        sd.start();
    }
   
    /**
     * 設定ダイアログから通知を受ける。
     * 有効なプロジェクトでればユーザIDをフィールドに設定しパスワードフィールドにフォーカスする。
     **/
    public void setNewParams(Boolean newValue) {
       
        blockGlass.unblock();
       
        boolean valid = newValue.booleanValue();
        if (valid) {
            principal.setUserId(Project.getUserId());
            principal.setFacilityId(Project.getFacilityId());
            bindModelToView();
            view.getPasswordField().requestFocus();
            setWindowTitle();
        }
    }
   
    /**
     * ログインをキャンセルする。
     */
    public void doCancel() {
        view.setVisible(false);
        view.dispose();
        result = LoginStatus.CANCELD;
        notifyResult(result);
       
        bindViewToModel();
    }
   
    /**
     * ログインボタンを制御する簡易 StateMgr クラス。
     * ProxyDocumentListener から呼ばれるので,public でなければならない
     */
    public class StateMgr extends WindowAdapter {
       
        private boolean okState;
       
        public StateMgr() {
        }
       
        /**
         * ログインボタンの enable/disable を制御する。
         */
        public void checkButtons() {
           
            boolean userEmpty = view.getUserIdField().getText().equals("") ? true : false;
            boolean passwdEmpty = view.getPasswordField().getPassword().length == 0 ? true : false;
           
            boolean newOKState = ( (userEmpty == false) && (passwdEmpty == false) ) ? true : false;
           
            if (newOKState != okState) {
                view.getLoginBtn().setEnabled(newOKState);
                okState = newOKState;
            }
        }
       
        /**
         * UserId フィールドでリターンきーが押された時の処理を行う。
         */
        public void onUserIdAction() {
            view.getPasswordField().requestFocus();
        }
       
        /**
         * Password フィールドでリターンきーが押された時の処理を行う。
         */
        public void onPasswordAction() {
           
            if (view.getUserIdField().getText().equals("")) {
               
                view.getUserIdField().requestFocus();
               
            } else if (view.getPasswordField().getPassword().length != 0 && okState) {
                //
                // ログインボタンをクリックする
                //
                view.getLoginBtn().doClick();
            }
        }
       
        @Override
        public void windowClosing(WindowEvent e) {
            doCancel();
        }
       
        @Override
        public void windowOpened(WindowEvent e) {
           
            if (!view.getUserIdField().getText().trim().equals("")) {
                //
                // UserId に有効な値が設定されていれば
                // パスワードフィールドにフォーカスする
                //
                view.getPasswordField().requestFocus();
            }
        }
    }
}
TOP

Related Classes of open.dolphin.impl.login.LoginDialog$Blocker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.