@Override
  public boolean close() {
    //  로그인이 안되었을 경우 로그인 창이 남아 있도록...(https://github.com/hangum/TadpoleForDBTools/issues/31)
    if (!SessionManager.isLogin()) return false;

    return super.close();
  }
  /**
   * mongodb update
   *
   * @param txtLimitCount
   * @param txtMacCount
   * @param txtFindPage
   * @param txtResultPage
   * @throws Exception
   */
  public static void updateMongoDBUserInfoData(
      String txtLimitCount, String txtMacCount, String txtFindPage, String txtResultPage)
      throws Exception {
    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    UserInfoDataDAO userInfoData = new UserInfoDataDAO();
    userInfoData.setUser_seq(SessionManager.getSeq());

    // 	MONGO_DEFAULT_LIMIT
    userInfoData.setName(PreferenceDefine.MONGO_DEFAULT_LIMIT);
    userInfoData.setValue0(txtLimitCount);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    // MONGO_DEFAULT_MAX_COUNT
    userInfoData.setName(PreferenceDefine.MONGO_DEFAULT_MAX_COUNT);
    userInfoData.setValue0(txtMacCount);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    // MONGO_DEFAULT_FIND
    userInfoData.setName(PreferenceDefine.MONGO_DEFAULT_FIND);
    userInfoData.setValue0(txtFindPage);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    // MONGO_DEFAULT_RESULT
    userInfoData.setName(PreferenceDefine.MONGO_DEFAULT_RESULT);
    userInfoData.setValue0(txtResultPage);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$
  }
  /**
   * general 정보의 export delimit을 저장합니다.
   *
   * @param sessionTimeOut
   * @throws Exception
   */
  public static void updateGeneralExportDelimitData(String delimit) throws Exception {
    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    UserInfoDataDAO userInfoData = new UserInfoDataDAO();
    userInfoData.setUser_seq(SessionManager.getSeq());

    // 	select 제한  갯수
    userInfoData.setName(PreferenceDefine.EXPORT_DILIMITER);
    userInfoData.setValue0(delimit);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$
  }
  /**
   * general 정보의 session time을 저장합니다.
   *
   * @param sessionTimeOut
   * @throws Exception
   */
  public static void updateGeneralUserInfoData(String sessionTimeOut) throws Exception {
    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    UserInfoDataDAO userInfoData = new UserInfoDataDAO();
    userInfoData.setUser_seq(SessionManager.getSeq());

    // 	select 제한  갯수
    userInfoData.setName(PreferenceDefine.SESSION_DFEAULT_PREFERENCE);
    userInfoData.setValue0(sessionTimeOut);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$
  }
  /**
   * default home page
   *
   * @param use
   * @throws Exception
   */
  public static void updateDefaultHomePageUse(String use) throws Exception {
    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    UserInfoDataDAO userInfoData = new UserInfoDataDAO();
    userInfoData.setUser_seq(SessionManager.getSeq());

    // 	select 제한  갯수
    userInfoData.setName(PreferenceDefine.DEFAULT_HOME_PAGE_USE);
    userInfoData.setValue0(use);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$
  }
  /**
   * @param userDB
   * @param title
   * @param desc
   * @param cronExp
   * @param listSchedule
   */
  public static ScheduleMainDAO addSchedule(
      final UserDBDAO userDB,
      String title,
      String desc,
      String cronExp,
      List<ScheduleDAO> listSchedule)
      throws Exception {
    int userSeq = SessionManager.getUserSeq();

    ScheduleMainDAO dao = new ScheduleMainDAO();
    dao.setSeq(userSeq);
    dao.setUser_seq(SessionManager.getUserSeq());
    dao.setDb_seq(userDB.getSeq());
    dao.setTitle(title);
    dao.setDescription(desc);
    dao.setCron_exp(cronExp);

    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    dao = (ScheduleMainDAO) sqlClient.insert("scheduleMainInsert", dao);

    // save schedule
    for (ScheduleDAO scheduleDAO : listSchedule) {
      scheduleDAO.setSchedule_main_seq(dao.getSeq());
      ScheduleDAO retScheduleDAO = (ScheduleDAO) sqlClient.insert("scheduleInsert", scheduleDAO);

      // sql
      String[] sqls = SQLUtil.makeResourceDataArays(scheduleDAO.getSql());
      ScheduleDetailDAO detailDao = null;
      for (String sql : sqls) {
        detailDao = new ScheduleDetailDAO();
        detailDao.setSchedule_seq(retScheduleDAO.getSeq());
        detailDao.setDatas(sql);

        sqlClient.insert("scheduleDetailInsert", detailDao);
      }
    }

    return dao;
  }
  /**
   * update SQLFormatter
   *
   * @param userdb
   * @param tabSize
   * @param resultSelect
   * @param sqlFormatIn
   */
  public static void updateSQLFormatterInfoData(
      String tabSize, String sqlFormatDecode, String sqlFormatIn) throws Exception {
    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    UserInfoDataDAO userInfoData = new UserInfoDataDAO();
    userInfoData.setUser_seq(SessionManager.getSeq());

    userInfoData.setName(PreferenceDefine.DEFAULT_TAB_SIZE_PREFERENCE);
    userInfoData.setValue0(tabSize);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    userInfoData.setName(PreferenceDefine.SQL_FORMATTER_DECODE_PREFERENCE);
    userInfoData.setValue0(sqlFormatDecode);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    userInfoData.setName(PreferenceDefine.SQL_FORMATTER_IN_PREFERENCE);
    userInfoData.setValue0(sqlFormatIn);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$
  }
  /**
   * 신규 사용자의 기본 유저 데이터 정보를 저장합니다.
   *
   * @param userdb
   * @param limitSelect
   * @param resultSelect
   * @param oraclePlan
   */
  public static void updateRDBUserInfoData(
      String limitSelect, String resultSelect, String oraclePlan) throws Exception {
    SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
    UserInfoDataDAO userInfoData = new UserInfoDataDAO();
    userInfoData.setUser_seq(SessionManager.getSeq());

    // 	select 제한  갯수
    userInfoData.setName(PreferenceDefine.SELECT_LIMIT_COUNT);
    userInfoData.setValue0(limitSelect);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    // 검색 결과 페이지 당 보여주는 갯수
    userInfoData.setName(PreferenceDefine.SELECT_RESULT_PAGE_PREFERENCE);
    userInfoData.setValue0(resultSelect);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$

    // ORACLE PLAN TABLE
    userInfoData.setName(PreferenceDefine.ORACLE_PLAN_TABLE);
    userInfoData.setValue0(oraclePlan);
    sqlClient.update("userInfoDataUpdate", userInfoData); // $NON-NLS-1$
  }
 /**
  * 사용자 정보 데이터.
  *
  * @param key
  * @return
  * @throws Exception
  */
 public static Object getUserInfoData(String key) throws Exception {
   SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
   return sqlClient.queryForObject("getUserInfoData", SessionManager.getSeq()); // $NON-NLS-1$
 }
  @Override
  public boolean performOk() {
    String txtResultType = comboRDBResultType.getText();
    String txtSelectLimit = textSelectLimit.getText();
    String txtResultPage = textResultPage.getText();
    String txtQueryTimtout = textQueryTimeout.getText();
    String txtOraclePlan = textOraclePlan.getText();
    String txtRDBNumberColumnIsComman = comboRDBNumberComma.getText();
    String txtFontInfo = lblUserFont.getText();
    String txtCommitCount = textCommitCount.getText();
    String txtShownInTheColumn = textShowInTheColumn.getText();

    if (!NumberUtils.isNumber(txtSelectLimit)) {
      MessageDialog.openError(
          getShell(),
          "Confirm",
          Messages.get().DefaultPreferencePage_0
              + Messages.get().RDBPreferencePage_0); // $NON-NLS-1$
      textSelectLimit.setFocus();
      return false;
    }

    if (!NumberUtils.isNumber(txtResultPage)) {
      MessageDialog.openError(
          getShell(),
          "Confirm",
          Messages.get().DefaultPreferencePage_other_labelText_1
              + Messages.get().RDBPreferencePage_0); // $NON-NLS-1$
      textResultPage.setFocus();
      return false;
    }

    if (!NumberUtils.isNumber(txtQueryTimtout)) {
      MessageDialog.openError(
          getShell(), "Confirm", "Query timeout is " + Messages.get().RDBPreferencePage_0);
      textQueryTimeout.setFocus();
      return false;
    }

    if (!NumberUtils.isNumber(txtCommitCount)) {
      MessageDialog.openError(
          getShell(), "Confirm", "Commit count is " + Messages.get().RDBPreferencePage_0);
      textCommitCount.setFocus();
      return false;
    }

    if ("".equals(txtOraclePlan)) { // $NON-NLS-1$
      MessageDialog.openError(
          getShell(), "Confirm", Messages.get().RDBPreferencePage_3); // $NON-NLS-1$
      return false;
    }

    if (!NumberUtils.isNumber(txtShownInTheColumn)) {
      MessageDialog.openError(getShell(), "Confirm", Messages.get().RDBPreferencePage_0);
      textShowInTheColumn.setFocus();
      return false;
    }

    // 테이블에 저장
    try {
      TadpoleSystem_UserInfoData.updateRDBUserInfoData(
          txtSelectLimit,
          txtResultPage,
          txtQueryTimtout,
          txtOraclePlan,
          txtRDBNumberColumnIsComman,
          txtFontInfo,
          txtCommitCount,
          txtShownInTheColumn,
          txtResultType);

      // session 데이터를 수정한다.
      SessionManager.setUserInfo(PreferenceDefine.RDB_RESULT_TYPE, txtResultType);
      SessionManager.setUserInfo(PreferenceDefine.SELECT_LIMIT_COUNT, txtSelectLimit);
      SessionManager.setUserInfo(PreferenceDefine.SELECT_RESULT_PAGE_PREFERENCE, txtResultPage);
      SessionManager.setUserInfo(PreferenceDefine.SELECT_QUERY_TIMEOUT, txtQueryTimtout);

      SessionManager.setUserInfo(PreferenceDefine.ORACLE_PLAN_TABLE, txtOraclePlan);
      SessionManager.setUserInfo(
          PreferenceDefine.RDB_RESULT_NUMBER_IS_COMMA, txtRDBNumberColumnIsComman);
      SessionManager.setUserInfo(PreferenceDefine.RDB_RESULT_FONT, txtFontInfo);
      SessionManager.setUserInfo(PreferenceDefine.RDB_COMMIT_COUNT, txtCommitCount);
      SessionManager.setUserInfo(
          PreferenceDefine.RDB_CHARACTER_SHOW_IN_THE_COLUMN, txtShownInTheColumn);

    } catch (Exception e) {
      logger.error("RDBPreference saveing", e);

      MessageDialog.openError(
          getShell(),
          "Confirm",
          Messages.get().RDBPreferencePage_5 + e.getMessage()); // $NON-NLS-1$
      return false;
    }

    return super.performOk();
  }
 /**
  * find user schedule
  *
  * @return
  * @throws Exception
  */
 public static List<ScheduleMainDAO> findUserScheduleMain() throws Exception {
   SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
   return sqlClient.queryForList("getUserScheduleMain", SessionManager.getUserSeq());
 }
  @Override
  protected void okPressed() {
    String strEmail = StringUtils.trimToEmpty(textEMail.getText());
    String strPass = StringUtils.trimToEmpty(textPasswd.getText());

    if (!validation(strEmail, strPass)) return;

    try {
      UserDAO userDao = TadpoleSystem_UserQuery.login(strEmail, strPass);

      // firsttime email confirm
      if (PublicTadpoleDefine.YES_NO.NO.name().equals(userDao.getIs_email_certification())) {
        InputDialog inputDialog =
            new InputDialog(
                getShell(),
                Messages.get().LoginDialog_10,
                Messages.get().LoginDialog_17,
                "",
                null); //$NON-NLS-3$ //$NON-NLS-1$
        if (inputDialog.open() == Window.OK) {
          if (!userDao.getEmail_key().equals(inputDialog.getValue())) {
            throw new Exception(Messages.get().LoginDialog_19);
          } else {
            TadpoleSystem_UserQuery.updateEmailConfirm(strEmail);
          }
        } else {
          throw new Exception(Messages.get().LoginDialog_20);
        }
      }

      if (PublicTadpoleDefine.YES_NO.NO.name().equals(userDao.getApproval_yn())) {
        MessageDialog.openError(
            getParentShell(), Messages.get().LoginDialog_7, Messages.get().LoginDialog_27);

        return;
      }

      // Check the allow ip
      String strAllowIP = userDao.getAllow_ip();
      boolean isAllow = IPFilterUtil.ifFilterString(strAllowIP, RequestInfoUtils.getRequestIP());
      if (logger.isDebugEnabled())
        logger.debug(
            Messages.get().LoginDialog_21
                + userDao.getEmail()
                + Messages.get().LoginDialog_22
                + strAllowIP
                + Messages.get().LoginDialog_23
                + RequestInfoUtils.getRequestIP());
      if (!isAllow) {
        logger.error(
            Messages.get().LoginDialog_21
                + userDao.getEmail()
                + Messages.get().LoginDialog_22
                + strAllowIP
                + Messages.get().LoginDialog_26
                + RequestInfoUtils.getRequestIP());
        MessageDialog.openError(
            getParentShell(), Messages.get().LoginDialog_7, Messages.get().LoginDialog_28);
        return;
      }

      if (PublicTadpoleDefine.YES_NO.YES.name().equals(userDao.getUse_otp())) {
        OTPLoginDialog otpDialog = new OTPLoginDialog(getShell());
        otpDialog.open();

        if (!GoogleAuthManager.getInstance()
            .isValidate(userDao.getOtp_secret(), otpDialog.getIntOTPCode())) {
          throw new Exception(Messages.get().LoginDialog_2);
        }
      }

      // 로그인 유지.
      registLoginID(userDao.getEmail());

      SessionManager.addSession(userDao);

      // save login_history
      TadpoleSystem_UserQuery.saveLoginHistory(userDao.getSeq());
    } catch (Exception e) {
      logger.error(
          String.format(
              "Login exception. request email is %s, reason %s",
              strEmail, e.getMessage())); // $NON-NLS-1$
      MessageDialog.openError(getParentShell(), Messages.get().LoginDialog_29, e.getMessage());

      textPasswd.setFocus();
      return;
    }

    super.okPressed();
  }
  @Override
  public boolean connection() {
    if (!isValidate()) return false;

    String dbUrl = "";
    if (comboConnType.getText().equals("SID")) {
      dbUrl =
          String.format(
              DBDefine.ORACLE_DEFAULT.getDB_URL_INFO(),
              textHost.getText(),
              textPort.getText(),
              textDatabase.getText());
    } else if (comboConnType.getText().equals("Service Name")) {
      dbUrl =
          String.format(
              "jdbc:oracle:thin:@%s:%s/%s",
              textHost.getText(), textPort.getText(), textDatabase.getText());
    }

    userDB = new UserDBDAO();
    userDB.setTypes(DBDefine.ORACLE_DEFAULT.getDBToString());
    userDB.setUrl(dbUrl);
    userDB.setDb(textDatabase.getText());
    userDB.setGroup_name(comboGroup.getText().trim());
    userDB.setDisplay_name(textDisplayName.getText());
    userDB.setOperation_type(
        DBOperationType.getNameToType(comboOperationType.getText()).toString());
    userDB.setHost(textHost.getText());
    userDB.setPasswd(textPassword.getText());
    userDB.setPort(textPort.getText());
    //		userDB.setLocale(comboLocale.getText().trim());
    userDB.setUsers(textUser.getText());

    // 기존 데이터 업데이트
    if (oldUserDB != null) {
      if (!MessageDialog.openConfirm(null, "Confirm", Messages.SQLiteLoginComposite_13))
        return false; //$NON-NLS-1$

      if (!checkDatabase(userDB)) return false;

      try {
        TadpoleSystem_UserDBQuery.updateUserDB(userDB, oldUserDB, SessionManager.getSeq());
      } catch (Exception e) {
        logger.error(Messages.SQLiteLoginComposite_8, e);
        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            getShell(), "Error", Messages.SQLiteLoginComposite_5, errStatus); // $NON-NLS-1$

        return false;
      }

      // 신규 데이터 저장.
    } else {
      // db가 정상적인지 채크해본다
      try {
        SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
        List showTables = sqlClient.queryForList("tableList", textDatabase.getText());

      } catch (Exception e) {
        logger.error(Messages.OracleLoginComposite_7, e);
        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            getShell(), "Error", Messages.OracleLoginComposite_10, errStatus); // $NON-NLS-1$

        return false;
      }

      try {
        TadpoleSystem_UserDBQuery.newUserDB(userDB, SessionManager.getSeq());
      } catch (Exception e) {
        logger.error("Oracle db info save", e);
        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            getShell(), "Error", Messages.OracleLoginComposite_11, errStatus); // $NON-NLS-1$
      }
    }

    return true;
  }
/**
 * Tadpole DB Hub ERD editor
 *
 * @author hangum
 */
public class TadpoleRDBEditor extends GraphicalEditor { // WithFlyoutPalette {
  public static final String ID = "com.hangum.tadpole.rdb.erd.core.editor"; // $NON-NLS-1$
  /** Logger for this class */
  private static final Logger logger = Logger.getLogger(TadpoleRDBEditor.class);

  /** 사용자 seq */
  private final int user_seq = SessionManager.getUserSeq();

  /** first init data */
  private DB db;

  private UserDBDAO userDB;
  private UserDBResourceDAO userDBErd;
  /** 처음로드될때부터 모든 테이블 로드 인지 */
  private boolean isAllTable = false;

  /** short key handler */
  private KeyHandler keyHandler;

  /** dnd */
  TableTransferFactory tableTransFactory = new TableTransferFactory();

  public TadpoleRDBEditor() {
    setEditDomain(new DefaultEditDomain(this));
  }

  @Override
  protected void initializeGraphicalViewer() {
    //		super.initializeGraphicalViewer();

    Job job =
        new Job("ERD Initialize") {
          @Override
          public IStatus run(IProgressMonitor monitor) {
            monitor.beginTask("Painting table object", IProgressMonitor.UNKNOWN);

            try {
              RdbFactory factory = RdbFactory.eINSTANCE;

              if (db == null) {

                // 모든 table 정보를 가져온다.
                if (isAllTable) {
                  db = TadpoleModelUtils.INSTANCE.getDBAllTable(monitor, userDB);
                  // 부분 테이블 정보를 처리한다.
                } else {
                  db = factory.createDB();
                }

                db.setDbType(userDB.getDbms_type() + " (" + userDB.getDisplay_name() + ")");
              }

              // 하위 호환을 위한 코드 .
              if (db.getStyle() == null) {
                Style style = RdbFactory.eINSTANCE.createStyle();
                style.setDb(db);
                db.setStyle(style);
              }

            } catch (Exception e) {
              logger.error("ERD Initialize excepiton", e);

              return new Status(Status.WARNING, Activator.PLUGIN_ID, e.getMessage());
            } finally {
              monitor.done();
            }

            /////////////////////////////////////////////////////////////////////////////////////////
            return Status.OK_STATUS;
          }
        };

    // job의 event를 처리해 줍니다.
    final TadpoleRDBEditor rdbEditor = this;
    job.addJobChangeListener(
        new JobChangeAdapter() {

          public void done(IJobChangeEvent event) {
            final IJobChangeEvent jobEvent = event;
            getSite()
                .getShell()
                .getDisplay()
                .asyncExec(
                    new Runnable() {
                      public void run() {
                        if (!jobEvent.getResult().isOK()) {

                          // 아래의 try문은 이슈 169의 오류를 검증하기 위한 코드입니다.
                          // https://github.com/hangum/TadpoleForDBTools/issues/169
                          //  근본적인 에러는 해결안됨.  그러나 프로그램에서 에러나고 죽는 그런 경우는 해결.
                          //
                          try {
                            Exception e = new Exception(jobEvent.getResult().getException());
                            Status errStatus =
                                new Status(
                                    IStatus.ERROR,
                                    Activator.PLUGIN_ID,
                                    e.getMessage(),
                                    e); //$NON-NLS-1$
                            ExceptionDetailsErrorDialog.openError(
                                PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
                                "Error",
                                Messages.get().TadpoleModelUtils_2,
                                errStatus); //$NON-NLS-1$
                          } catch (Exception e) {
                            logger.error(
                                "https://github.com/hangum/TadpoleForDBTools/issues/169 검증오류...",
                                e);
                          }

                          // 오류가 발생했을때는 기본 정보로
                          RdbFactory factory = RdbFactory.eINSTANCE;
                          db = factory.createDB();
                          db.setDbType(userDB.getDbms_type());
                          db.setId(userDB.getUsers());
                          db.setUrl(userDB.getHost());
                        }
                        getGraphicalViewer().setContents(db);

                        // dnd
                        getGraphicalViewer()
                            .addDropTargetListener(
                                new TableTransferDropTargetListener(
                                    rdbEditor, getGraphicalViewer(), userDB, db));
                      }
                    }); // end display.asyncExec
          } // end done
        }); // end job

    job.setName(userDB.getDisplay_name());
    job.setUser(true);
    job.schedule();
  }

  @Override
  public void dispose() {
    super.dispose();
  }

  @Override
  protected void configureGraphicalViewer() {
    super.configureGraphicalViewer();

    GraphicalViewer viewer = getGraphicalViewer();
    viewer.setEditPartFactory(new TadpoleEditPartFactory());

    // zoom menu
    zoomContribution(viewer);

    // layout action
    createDiagramAction(viewer);

    // context menu
    ContextMenuProvider provider = new TadpoleERDContextMenuProvider(viewer, getActionRegistry());
    viewer.setContextMenu(provider);

    // key handler
    configureKeyHandler();

    // grid and geometry
    configureGeometry();
    configureGrid();
  }

  /** configure key handler */
  private void configureKeyHandler() {
    GraphicalViewer viewer = getGraphicalViewer();

    keyHandler = new KeyHandler();
    //		keyHandler.put(KeyStroke.getPressed('a', 0x61, SWT.COMMAND),
    //	getActionRegistry().getAction(ActionFactory.SELECT_ALL.getId()));
    keyHandler.put(
        KeyStroke.getPressed('s', 0x61, SWT.CTRL),
        getActionRegistry().getAction(ActionFactory.SAVE.getId()));

    keyHandler.put(
        KeyStroke.getPressed('z', 0x7a, SWT.CTRL),
        getActionRegistry().getAction(ActionFactory.UNDO.getId()));
    keyHandler.put(
        KeyStroke.getPressed('z', 0x7a, SWT.CTRL | SWT.SHIFT),
        getActionRegistry().getAction(ActionFactory.REDO.getId()));
    keyHandler.put(
        KeyStroke.getPressed('a', 0x61, SWT.CTRL),
        getActionRegistry().getAction(ActionFactory.SELECT_ALL.getId()));

    keyHandler.put(
        KeyStroke.getPressed(SWT.DEL, 127, 0),
        getActionRegistry().getAction(ActionFactory.DELETE.getId()));
    keyHandler.put(
        KeyStroke.getPressed('+', SWT.KEYPAD_ADD, 0),
        getActionRegistry().getAction(GEFActionConstants.ZOOM_IN));
    keyHandler.put(
        KeyStroke.getPressed('-', SWT.KEYPAD_SUBTRACT, 0),
        getActionRegistry().getAction(GEFActionConstants.ZOOM_IN));

    viewer.setProperty(
        MouseWheelHandler.KeyGenerator.getKey(SWT.NONE), MouseWheelZoomHandler.SINGLETON);
    viewer.setKeyHandler(keyHandler);
  }

  /** configure grid */
  private void configureGrid() {
    GraphicalViewer viewer = getGraphicalViewer();
    viewer.setProperty(SnapToGrid.PROPERTY_GRID_ENABLED, true);
    viewer.setProperty(SnapToGrid.PROPERTY_GRID_VISIBLE, true);

    IAction action = new ToggleGridAction(viewer);
    getActionRegistry().registerAction(action);
  }

  /** configure geometry */
  private void configureGeometry() {
    GraphicalViewer viewer = getGraphicalViewer();
    viewer.setProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED, true);

    IAction action = new ToggleSnapToGeometryAction(viewer);
    getActionRegistry().registerAction(action);
  }

  private void zoomContribution(GraphicalViewer viewer) {
    double[] zoomLevels;
    List<String> zoomContributions;

    ScalableRootEditPart rootEditPart = new ScalableRootEditPart();
    viewer.setRootEditPart(rootEditPart);

    ZoomManager manager = rootEditPart.getZoomManager();
    getActionRegistry().registerAction(new ZoomInAction(manager));
    getActionRegistry().registerAction(new ZoomOutAction(manager));

    zoomLevels = new double[] {0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 5.0, 10.0, 20.0};
    manager.setZoomLevels(zoomLevels);

    zoomContributions = new ArrayList<String>();
    //		zoomContributions.add(ZoomManager.FIT_ALL);
    //		zoomContributions.add(ZoomManager.FIT_HEIGHT);
    //		zoomContributions.add(ZoomManager.FIT_WIDTH);
    manager.setZoomLevelContributions(zoomContributions);
  }

  private void createDiagramAction(GraphicalViewer viewer) {
    ActionRegistry registry = getActionRegistry();
    AutoLayoutAction autoLayoutAction = new AutoLayoutAction(this, getGraphicalViewer());
    registry.registerAction(autoLayoutAction);
    getSelectionActions().add(autoLayoutAction.getId());

    IAction action = new TableSelectionAction(this, getGraphicalViewer());
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    ERDViewStyleAction erdStyledAction = new ERDViewStyleAction(this, getGraphicalViewer());
    registry.registerAction(erdStyledAction);
    getSelectionActions().add(ERDViewStyleAction.ID);

    ERDRefreshAction refreshAction = new ERDRefreshAction(this, getGraphicalViewer());
    registry.registerAction(refreshAction);
    getSelectionActions().add(refreshAction.getId());
  }

  @Override
  protected void createActions() {
    super.createActions();
    ActionRegistry registry = getActionRegistry();

    IAction action = new MatchWidthAction(this);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new MatchHeightAction(this);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new AlignmentAction((IWorkbenchPart) this, PositionConstants.LEFT);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new AlignmentAction((IWorkbenchPart) this, PositionConstants.RIGHT);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new AlignmentAction((IWorkbenchPart) this, PositionConstants.TOP);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new AlignmentAction((IWorkbenchPart) this, PositionConstants.BOTTOM);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new AlignmentAction((IWorkbenchPart) this, PositionConstants.CENTER);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());

    action = new AlignmentAction((IWorkbenchPart) this, PositionConstants.MIDDLE);
    registry.registerAction(action);
    getSelectionActions().add(action.getId());
  }

  @Override
  public void init(IEditorSite site, IEditorInput input) throws PartInitException {
    super.init(site, input);
    loadDBRsource(input);
  }

  private void configureKeyboardShortcu() {
    //		getGraphicalViewer().getKeyHandler();
    //		GraphicalViewerKeyHandler keyHandler = new GraphicalViewerKeyHandler(getGraphicalViewer());
    //		keyHandler.put(KeyStroke.getPressed(SWT.F2, 0),
    // getActionRegistry().getAction(GEFActionConstants.DIRECT_EDIT));
    //		keyHandler.put(KeyStroke.getPressed(SWT.F3, 0),
    // getActionRegistry().getAction(ResizeToContentsAction.RESIZE_TO_CONTENTS_ID));
    //		getGraphicalViewer().setKeyHandler(keyHandler);
    //
    //		getGraphicalViewer().getKeyHandler();
    //		GraphicalViewerKeyHandler keyHandler = new GraphicalViewerKeyHandler(getGraphicalViewer());
    //		keyHandler.put(KeyStroke.getPressed(SWT.F3, 0),
    // getActionRegistry().getAction(GEFActionConstants.SAVE));
    ////		keyHandler.put(KeyStroke.getPressed(SWT.F3, 0),
    // getActionRegistry().getAction(ResizeToContentsAction.RESIZE_TO_CONTENTS_ID));
    //		getGraphicalViewer().setKeyHandler(keyHandler);
  }

  /**
   * resource load
   *
   * @param input
   */
  private void loadDBRsource(IEditorInput input) {
    TadpoleRDBEditorInput erdInput = (TadpoleRDBEditorInput) input;
    userDB = erdInput.getUserDBDAO();
    isAllTable = erdInput.isAllTable();

    // 신규로드 인지 기존 파일 로드 인지 검사합니다.
    if (null != erdInput.getUserDBERD()) {
      userDBErd = erdInput.getUserDBERD();

      // load resouce
      try {
        String xmlString = TadpoleSystem_UserDBResource.getResourceData(userDBErd);

        // 처음 로드 할때 ResourceSet에 instance가 등록 되어 있어야 합니다.
        /** <code>TadpolePackage.eNS_URI</code> */
        ResourceSet resourceSet = new ResourceSetImpl();
        if (resourceSet.getPackageRegistry().get("http://com.hangum.tadpole.rdb.model.ERDInfo")
            == null) {
          resourceSet
              .getPackageRegistry()
              .put("http://com.hangum.tadpole.rdb.model.ERDInfo", RdbPackage.eINSTANCE.getClass());
        }

        //
        XMLResourceImpl resource = new XMLResourceImpl();
        resource.setEncoding("UTF-8");
        resource.load(new InputSource(new StringReader(xmlString)), null);
        db = (DB) resource.getContents().get(0);

      } catch (Exception e) {
        logger.error("Load ERD Resource", e); // $NON-NLS-1$

        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            getSite().getShell(),
            "Error",
            Messages.get().TadpoleEditor_0,
            errStatus); //$NON-NLS-1$
      }

      setPartName(isAllTable ? "All " + userDBErd.getName() : userDBErd.getName());
      setTitleToolTip(userDB.getDisplay_name());
    } else {
      setPartName(isAllTable ? "All " + userDB.getDisplay_name() : userDB.getDisplay_name());
      setTitleToolTip(userDB.getDisplay_name());
    }

    // google analytic
    AnalyticCaller.track(TadpoleRDBEditor.ID, userDB.getDbms_type());
  }

  //	@Override
  //	protected PaletteRoot getPaletteRoot() {
  //		return null;
  //	}
  //
  //	@Override
  //	public void doSaveAs() {
  //		super.doSaveAs();
  //	}

  //	/**
  //	 * export images
  //	 *
  //	 * RAP currently, GC drawing is only supported on Canvas, but not on image.
  //	 */
  //	public void exportImage() {
  //		try {
  //           IFigure figure =
  // ((AbstractGraphicalEditPart)getGraphicalViewer().getRootEditPart()).getFigure();
  //           File file = new File ("/Users/hangum/Downloads/gefout.png");
  //           if (file.exists ()) {
  //               if (!MessageDialog.openQuestion(null, "prompted", "The file already exists. Want
  // to re-cover it?")) {
  //                   return;
  //               }
  //           } else {
  //        	   file.createNewFile ();
  //           }
  //
  //           if (figure instanceof Viewport) {
  //	           ((Viewport)figure).setViewLocation(0, 0);
  //           }
  //
  //           Dimension size = figure.getPreferredSize ();
  //           Image image = new Image (Display.getDefault (), size.width, size.height);
  ////           Drawable drawable = (Drawable)image;
  //
  //           GC gc = new GC(getSite().getShell().getDisplay());
  //           gc.drawImage(image, size.width, size.height);
  //           SWTGraphics graphics = new SWTGraphics(gc);
  //           figure.paint (graphics);
  //
  //           ImageLoader loader = new ImageLoader ();
  //           loader.data = new ImageData []{image.getImageData ()};
  //           loader.save("/Users/hangum/Downloads/gefout.png",
  // SWT.IMAGE_PNG);//FileFormat.FORMATS);
  //
  //           graphics.dispose();
  //           gc.dispose();
  //           image.dispose();
  //
  //        } catch (Exception e) {
  //        	e.printStackTrace();
  //	     } finally {
  //        }
  //	}
  @Override
  public void doSave(IProgressMonitor monitor) {
    //		exportImage();

    // 신규 저장이면
    if (userDBErd == null) {

      // file 이름 dialog
      ResourceSaveDialog rsDialog =
          new ResourceSaveDialog(null, null, userDB, PublicTadpoleDefine.RESOURCE_TYPE.ERD, "");
      if (rsDialog.open() == Window.OK) {

        try {
          // erd 정보 디비저장
          userDBErd =
              TadpoleSystem_UserDBResource.saveResource(
                  userDB, rsDialog.getRetResourceDao(), createResourceToString());
          userDBErd.setParent(userDB);

          // command stack 초기화
          getCommandStack().markSaveLocation();

          // title 수정
          setPartName(userDBErd.getName());

          // managerView tree refresh
          // 뒤에 시간을붙인것은 한번 저장한 db_seq는 업데이지 않는 오류를 방지하기위해...
          //
          PlatformUI.getPreferenceStore()
              .setValue(
                  PublicTadpoleDefine.SAVE_FILE,
                  ""
                      + userDBErd.getDb_seq()
                      + ":"
                      + System.currentTimeMillis()); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        } catch (Exception e) {
          logger.error(Messages.get().TadpoleEditor_9, e);

          Status errStatus =
              new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
          ExceptionDetailsErrorDialog.openError(
              getSite().getShell(),
              "Error",
              Messages.get().TadpoleEditor_3,
              errStatus); //$NON-NLS-1$
        }
      }

      // 기존 리소스를 가지고 있었으면
    } else {

      try {
        TadpoleSystem_UserDBResource.updateResource(userDBErd, createResourceToString());
        getCommandStack().markSaveLocation();
      } catch (Exception e) {
        logger.error(Messages.get().TadpoleEditor_12, e);

        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            getSite().getShell(),
            "Error",
            Messages.get().TadpoleEditor_1,
            errStatus); //$NON-NLS-1$
      }
    }
  }

  /**
   * model to string
   *
   * @return
   * @throws Exception
   */
  private String createResourceToString() throws Exception {
    XMLResourceImpl resource = new XMLResourceImpl();
    resource.setEncoding("UTF-8");
    resource.getContents().add(db);

    XMLProcessor processor = new XMLProcessor();
    return processor.saveToString(resource, null);
  }

  @Override
  public void commandStackChanged(EventObject event) {
    firePropertyChange(PROP_DIRTY);
    super.commandStackChanged(event);
  }

  @Override
  public Object getAdapter(Class type) {
    if (type == ZoomManager.class) {
      return ((ScalableRootEditPart) getGraphicalViewer().getRootEditPart()).getZoomManager();
    }

    //		if(type == IContentOutlinePage.class) {
    //			return new OutlinePage();
    //		}

    return super.getAdapter(type);
  }

  public UserDBResourceDAO getUserDBErd() {
    return userDBErd;
  }

  /**
   * outline page
   *
   * @author hangum
   */
  protected class OutlinePage extends ContentOutlinePage {
    private SashForm sash;
    //		private ScrollableThumbnail thumbnail;
    //		private DisposeListener disposeListener;

    public OutlinePage() {
      super(new TreeViewer());
    }

    @Override
    public void createControl(Composite parent) {
      sash = new SashForm(parent, SWT.VERTICAL);

      getViewer().createControl(sash);
      getViewer().setEditDomain(getEditDomain());
      getViewer().setEditPartFactory(new TadpoleTreeEditPartFactory());
      getViewer().setContents(db);
      getSelectionSynchronizer().addViewer(getViewer());

      //			Canvas canvas = new Canvas(sash, SWT.BORDER);
      //			LightweightSystem lws = new LightweightSystem(canvas);
      //			RootEditPart rep = getGraphicalViewer().getRootEditPart();
      //			if (rep instanceof ScalableFreeformRootEditPart) {
      //				ScalableFreeformRootEditPart root = (ScalableFreeformRootEditPart) rep;
      //				thumbnail = new ScrollableThumbnail((Viewport) root.getFigure());
      //				thumbnail.setBorder(new MarginBorder(3));
      //				thumbnail.setSource(root.getLayer(LayerConstants.PRINTABLE_LAYERS));
      //				lws.setContents(thumbnail);
      //				disposeListener = new DisposeListener() {
      //					public void widgetDisposed(DisposeEvent e) {
      //						if (thumbnail != null) {
      //							thumbnail.deactivate();
      //							thumbnail = null;
      //						}
      //					}
      //				};
      //				getGraphicalViewer().getControl().addDisposeListener(disposeListener);
      //			}

    }

    @Override
    public void init(IPageSite pageSite) {
      super.init(pageSite);

      IActionBars bars = getSite().getActionBars();
      bars.setGlobalActionHandler(
          ActionFactory.UNDO.getId(), getActionRegistry().getAction(ActionFactory.UNDO.getId()));
      bars.setGlobalActionHandler(
          ActionFactory.REDO.getId(), getActionRegistry().getAction(ActionFactory.REDO.getId()));
      bars.setGlobalActionHandler(
          ActionFactory.DELETE.getId(),
          getActionRegistry().getAction(ActionFactory.DELETE.getId()));
      bars.updateActionBars();

      getViewer().setKeyHandler(keyHandler);
    }

    @Override
    public Control getControl() {
      return sash;
    }

    @Override
    public void dispose() {
      getSelectionSynchronizer().removeViewer(getViewer());
      //			if(getGraphicalViewer().getControl() != null &&
      // !getGraphicalViewer().getControl().isDisposed())
      //				getGraphicalViewer().getControl().removeDisposeListener(disposeListener);

      super.dispose();
    }
  }

  public DB getDb() {
    return db;
  }

  /** @return the userDB */
  public UserDBDAO getUserDB() {
    return userDB;
  }
}