/**
   * DB환경 정보 파일을 올바른 정보로 바꾸어준다.
   *
   * @param dbInfo
   * @return
   * @throws Exception
   */
  private static String getConfig(UserDBDAO dbInfo) throws Exception {
    String config = getFileToString(dbInfo.getDBDefine().getLocation());

    config = config.replace(URL, StringEscapeUtils.escapeXml(dbInfo.getUrl()));
    config = config.replace(USERNAME, StringEscapeUtils.escapeXml(dbInfo.getUsers()));
    config = config.replace(PASSWORD, StringEscapeUtils.escapeXml(dbInfo.getPasswd()));

    return config;
  }
  /**
   * table의 컬럼 정보를 가져옵니다.
   *
   * @param strTBName
   * @return
   * @throws Exception
   */
  public List<TableColumnDAO> getColumns(String strTBName) throws Exception {
    Map<String, String> param = new HashMap<String, String>();
    param.put("db", userDB.getDb()); // $NON-NLS-1$
    param.put("table", strTBName); // $NON-NLS-1$

    if (userDB.getDBDefine() == DBDefine.TAJO_DEFAULT) {
      return new TajoConnectionManager().tableColumnList(userDB, param);
    } else {
      SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
      return sqlClient.queryForList("tableColumnList", param); // $NON-NLS-1$
    }
  }
  /**
   * 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());
  }
  /**
   * 디비의 화면을 오픈합니다.
   *
   * @param userDB
   */
  public void run(UserDBDAO userDB) {

    // mongodb인지 검사하여..
    if (userDB.getDBDefine() != DBDefine.MONGODB_DEFAULT) {
      MainEditorInput mei = new MainEditorInput(userDB);

      try {
        PlatformUI.getWorkbench()
            .getActiveWorkbenchWindow()
            .getActivePage()
            .openEditor(mei, MainEditor.ID);
      } catch (PartInitException e) {
        logger.error("open editor", e); // $NON-NLS-1$

        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            null, "Error", Messages.AbstractQueryAction_1, errStatus); // $NON-NLS-1$
      }
    } else if (userDB.getDBDefine() == DBDefine.MONGODB_DEFAULT) {
      MongoDBInfosInput mongoInput =
          new MongoDBInfosInput(userDB, MongoDBInfosEditor.PAGES.COLLECTION_SUMMERY);
      try {
        PlatformUI.getWorkbench()
            .getActiveWorkbenchWindow()
            .getActivePage()
            .openEditor(mongoInput, MongoDBInfosEditor.ID);
      } catch (PartInitException e) {
        logger.error("open editor", e); // $NON-NLS-1$

        Status errStatus =
            new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
        ExceptionDetailsErrorDialog.openError(
            null, "Error", Messages.AbstractQueryAction_1, errStatus); // $NON-NLS-1$
      }
    }
  }
  /**
   * user label text
   *
   * @param userDB
   * @return
   */
  public static String getDBText(UserDBDAO userDB) {
    String retText = "";
    if (PublicTadpoleDefine.DBOperationType.PRODUCTION
        .toString()
        .equals(userDB.getOperation_type())) {
      retText =
          String.format(
              "%s [%s] %s",
              PRODUCTION_SERVER_START_TAG,
              StringUtils.substring(userDB.getOperation_type(), 0, 1),
              END_TAG);
      //		} else {
      //			retText = String.format("%s [%s] %s", DEVELOPMENT_SERVER_START_TAG,
      // StringUtils.substring(userDB.getOperation_type(), 0, 1), END_TAG);
    }

    if (PermissionChecker.isDBAdminRole(userDB)) {
      retText +=
          String.format(
              "%s (%s@%s)",
              userDB.getDisplay_name(),
              userDB.getUsers(),
              userDB.getDb()); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    } else {

      // 프러덕이나 백업디비이면디비 이름만보이면 됨.
      if (PermissionChecker.isProductBackup(userDB)) {
        retText += userDB.getDisplay_name();
        // 기타 디비 이면 다 보이면 됨.
      } else {
        retText +=
            String.format(
                "%s (%s@%s)",
                userDB.getDisplay_name(),
                userDB.getUsers(),
                userDB.getDb()); // $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$		
      }
    }

    return retText;
  }
  /**
   * save sqlhistory
   *
   * @param user_seq
   * @param userDB
   * @param sqlType
   * @param sqlHistoryDAO
   */
  public static void saveExecuteSQUeryResource(
      int user_seq,
      UserDBDAO userDB,
      PublicTadpoleDefine.EXECUTE_SQL_TYPE sqlType,
      SQLHistoryDAO sqlHistoryDAO)
      throws Exception {
    if (PublicTadpoleDefine.YES_NO.YES.name().equals(userDB.getIs_profile())) {
      ExecutedSqlResourceDAO executeSQLResourceDao = new ExecutedSqlResourceDAO();
      executeSQLResourceDao.setDb_seq(userDB.getSeq());
      executeSQLResourceDao.setUser_seq(user_seq);
      executeSQLResourceDao.setTypes(sqlType.toString());

      executeSQLResourceDao.setStartDateExecute(sqlHistoryDAO.getStartDateExecute());
      executeSQLResourceDao.setEndDateExecute(sqlHistoryDAO.getEndDateExecute());
      long duration =
          sqlHistoryDAO.getEndDateExecute().getTime()
              - sqlHistoryDAO.getStartDateExecute().getTime();
      executeSQLResourceDao.setDuration(Integer.parseInt("" + duration));

      executeSQLResourceDao.setRow(sqlHistoryDAO.getRows());
      executeSQLResourceDao.setResult(sqlHistoryDAO.getResult());
      executeSQLResourceDao.setMessage(
          sqlHistoryDAO
              .getMesssage()); // ""+(sqlHistoryDAO.getEndDateExecute().getTime() -
                               // sqlHistoryDAO.getStartDateExecute().getTime()));
      executeSQLResourceDao.setIpAddress(sqlHistoryDAO.getIpAddress());
      // 기존에 등록 되어 있는지 검사한다
      SqlMapClient sqlClient = TadpoleSQLManager.getInstance(TadpoleSystemInitializer.getUserDB());
      ExecutedSqlResourceDAO executeSQL =
          (ExecutedSqlResourceDAO)
              sqlClient.insert(
                  "userExecuteSQLResourceInsert", executeSQLResourceDao); // $NON-NLS-1$

      insertResourceData(executeSQL, sqlHistoryDAO.getStrSQLText());
    }
  }
  private void initUI() {
    try {
      SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
      List listTableInform =
          sqlClient.queryForList("tableInformation", userDB.getDb()); // $NON-NLS-1$

      tvTableInform.setInput(listTableInform);
      tvTableInform.refresh();
    } catch (Exception e) {
      logger.error("initialize session list", e); // $NON-NLS-1$

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

    // google analytic
    AnalyticCaller.track(RDBDBInfosEditor.ID, "TablesComposite"); // $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;
  }
 /**
  * 보여 주어야할 목록을 정의합니다.
  *
  * @param userDB
  * @return
  * @throws Exception
  */
 public static List<OracleSynonymDAO> getSynonymList(final UserDBDAO userDB) throws Exception {
   SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
   return sqlClient.queryForList("synonymList", userDB.getDb()); // $NON-NLS-1$
 }
  @Override
  public void run(IStructuredSelection selection, UserDBDAO userDB, OBJECT_TYPE actionType) {
    try {
      PublicTadpoleDefine.QUERY_DML_TYPE queryType = QUERY_DML_TYPE.INSERT;
      if (queryType == QUERY_DML_TYPE.INSERT) {
        if (PublicTadpoleDefine.YES_NO
            .YES
            .name()
            .equals(userDB.getDbAccessCtl().getInsert_lock())) {
          throw new Exception(Messages.get().MainEditor_21);
        }
      }
      queryType = QUERY_DML_TYPE.UPDATE;
      if (queryType == QUERY_DML_TYPE.UPDATE) {
        if (PublicTadpoleDefine.YES_NO
            .YES
            .name()
            .equals(userDB.getDbAccessCtl().getUpdate_lock())) {
          throw new Exception(Messages.get().MainEditor_21);
        }
      }
      queryType = QUERY_DML_TYPE.DELETE;
      if (queryType == QUERY_DML_TYPE.DELETE) {
        if (PublicTadpoleDefine.YES_NO
            .YES
            .name()
            .equals(userDB.getDbAccessCtl().getDelete_locl())) {
          throw new Exception(Messages.get().MainEditor_21);
        }
      }
    } catch (Exception e) {
      MessageDialog.openError(
          getWindow().getShell(), Messages.get().ObjectDeleteAction_2, e.getMessage());
      return;
    }

    try {
      if (!GrantCheckerUtils.ifExecuteQuery(userDB)) return;
    } catch (Exception e) {
      MessageDialog.openError(
          getWindow().getShell(), Messages.get().ObjectDeleteAction_2, e.getMessage());
      return;
    }

    TableDAO tableDAO = (TableDAO) selection.getFirstElement();
    try {
      // get the table columns
      SqlMapClient sqlClient = TadpoleSQLManager.getInstance(userDB);
      Map<String, String> mapParam = new HashMap<String, String>();
      mapParam.put("db", userDB.getDb()); // $NON-NLS-1$
      mapParam.put("table", tableDAO.getName()); // $NON-NLS-1$
      List showTableColumns = sqlClient.queryForList("tableColumnList", mapParam); // $NON-NLS-1$

      // Open the table director editor
      IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();

      DBTableEditorInput dbEditorInput = new DBTableEditorInput(tableDAO, userDB, showTableColumns);
      page.openEditor(dbEditorInput, TableInformationEditor.ID, false);
    } catch (Exception e) {
      logger.error("Load the table data", e); // $NON-NLS-1$

      Status errStatus =
          new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e); // $NON-NLS-1$
      ExceptionDetailsErrorDialog.openError(
          null, "Error", Messages.get().ExplorerViewer_39, errStatus); // $NON-NLS-1$
    }
  }
  @Override
  protected void handleDrop() {
    String[] arrayDragSourceData = null;
    try {
      arrayDragSourceData =
          StringUtils.splitByWholeSeparator(
              ((String) getCurrentEvent().data), PublicTadpoleDefine.DELIMITER);

      int sourceDBSeq = Integer.parseInt(arrayDragSourceData[0]);
      if (userDB.getSeq() != sourceDBSeq) {
        MessageDialog.openError(
            null, "Error", Messages.TableTransferDropTargetListener_1); // $NON-NLS-1$
        return;
      }
    } catch (Exception e) {
      logger.error("dragger error", e); // $NON-NLS-1$
      MessageDialog.openError(
          null, "Error", "Draging exception : " + e.getMessage()); // $NON-NLS-1$
      return;
    }

    String tableName = arrayDragSourceData[1];
    String refTableNames = "'" + tableName + "',"; // $NON-NLS-1$ //$NON-NLS-2$

    // 이미 editor 상에 테이블 정보를 가져온다.
    Map<String, Table> mapDBTables = new HashMap<String, Table>();
    for (Table table : db.getTables()) {
      mapDBTables.put(table.getName(), table);
      refTableNames += "'" + table.getName() + "',"; // $NON-NLS-1$ //$NON-NLS-2$
    }
    refTableNames = StringUtils.chompLast(refTableNames, ","); // $NON-NLS-1$

    // 이미 등록되어 있는 것이 아니라면
    if (mapDBTables.get(tableName) == null) {
      // 테이블 모델 생성
      Table tableModel = tadpoleFactory.createTable();
      tableModel.setName(tableName);
      tableModel.setDb(db);

      if (userDB.getDBDefine() == DBDefine.SQLite_DEFAULT) {
        tableModel.setComment("");
      } else {
        String tableComment = arrayDragSourceData[2];
        tableComment = StringUtils.substring("" + tableComment, 0, 10);
        tableModel.setComment(tableComment);
      }

      tableModel.setConstraints(new Rectangle(getDropLocation().x, getDropLocation().y, -1, -1));

      try {
        // 컬럼 모델 생성
        for (TableColumnDAO columnDAO : getColumns(tableName)) {
          Column column = tadpoleFactory.createColumn();

          column.setDefault(columnDAO.getDefault());
          column.setExtra(columnDAO.getExtra());
          column.setField(columnDAO.getField());
          column.setNull(columnDAO.getNull());
          column.setKey(columnDAO.getKey());
          column.setType(columnDAO.getType());

          String strComment = columnDAO.getComment();
          if (strComment == null) strComment = "";
          else strComment = StringUtils.substring("" + strComment, 0, 10);
          column.setComment(strComment);

          column.setTable(tableModel);
          tableModel.getColumns().add(column);
        }
        mapDBTables.put(tableName, tableModel);
        RelationUtil.calRelation(
            userDB,
            mapDBTables,
            db,
            refTableNames); // RelationUtil.getReferenceTable(userDB, refTableNames));

      } catch (Exception e) {
        logger.error("GEF Table Drag and Drop Exception", e); // $NON-NLS-1$

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

      transferFactory.setTable(tableModel);
    } else {
      transferFactory.setTable(mapDBTables.get(tableName));
    }

    super.handleDrop();
  }
  @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();
  }
  //	MapReduceOutput mrOutput = null;
  private void goMapReduce(
      final DBCollection dbCol,
      final BasicDBObject basicObj,
      final MapReduceCommand.OutputType mrOType) {
    Job job = new Job("MapReduce search job") { // $NON-NLS-1$
          @Override
          public IStatus run(IProgressMonitor monitor) {
            monitor.beginTask("Starting JSON query...", IProgressMonitor.UNKNOWN); // $NON-NLS-1$
            try {

              //					if(mrOType == MapReduceCommand.OutputType.INLINE) {
              //						cmdResult = dbCol.getDB().command(basicObj, dbCol.getOptions());
              //						cmdResult.throwOnError();
              //						mrOutput = new MapReduceOutput(dbCol, basicObj, cmdResult);
              //					} else {
              cmdResult = dbCol.getDB().command(basicObj);
              //						cmdResult.throwOnError();
              //						mrOutput = new MapReduceOutput(dbCol, basicObj, cmdResult);
              //					}
              if (!cmdResult.ok()) {
                throw cmdResult.getException();
              }

            } catch (Exception e) {
              logger.error("mapreduce exception", e); // $NON-NLS-1$
              return new Status(
                  Status.WARNING,
                  Activator.PLUGIN_ID,
                  "mapreduce " + e.getMessage()); // $NON-NLS-1$
            } finally {
              monitor.done();
            }

            return Status.OK_STATUS;
          }
        };

    // job의 event를 처리해 줍니다.
    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 {
                            Iterable<DBObject> iteResult =
                                (Iterable<DBObject>) cmdResult.get("results");
                            compositeResult.refreshDBView(iteResult, 0);
                            compositeResult.setResult();
                          } catch (Exception e) {
                            logger.error("MapReduce Error", e); // $NON-NLS-1$
                            Status errStatus =
                                new Status(
                                    IStatus.ERROR,
                                    Activator.PLUGIN_ID,
                                    e.getMessage(),
                                    e); //$NON-NLS-1$
                            ExceptionDetailsErrorDialog.openError(
                                null,
                                "Error",
                                "MapReduce execute exception",
                                errStatus); //$NON-NLS-1$ //$NON-NLS-2$
                          }
                        } else {
                          //							compositeResult.errorView(jobEvent.getResult().getMessage());
                        }
                      }
                    }); // end display.asyncExec
          } // end done
        }); // end job

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