/**
   * PreparedStatement用にパターン別のコードを埋め込む
   *
   * @param ctClass クラス
   * @param method メソッド
   * @param bindValCode バインド変数取得用コード
   * @param explainCodeTemplate 実行計画取得用コード
   * @throws CannotCompileException コード埋め込みに失敗した場合
   */
  public static void convertPreparedMethod(
      final CtClass ctClass,
      final CtBehavior method,
      final String bindValCode,
      final String explainCodeTemplate)
      throws CannotCompileException {
    String className = ctClass.getName();
    String methodName = method.getName();
    className = className.substring(className.lastIndexOf('.') + 1);

    // setメソッドの引数の1番目がintのときのみ、実行計画取得用処理、バインド引数取得処理を追加する
    try {
      CtClass[] paramTypes;
      paramTypes = method.getParameterTypes();
      if (paramTypes.length >= 1 && "int".equals(paramTypes[0].getName())) {
        // 実行計画取得用PreparedStatementのsetXXXを適したメソッド名に変更する
        String explainCode =
            explainCodeTemplate.replaceAll(REPLACETARGET_OF_PLANPREPARED, methodName);

        // 前処理を埋め込む
        String key = "javelin.jdbc.instrument.JdbcJavelinConverter.ModifiedMethodLabel";
        String message = JdbcJavelinMessages.getMessage(key, className, methodName);
        SystemLogger.getInstance().info(message);

        method.insertBefore(bindValCode + explainCode);
      }
    } catch (NotFoundException e) {
      SystemLogger.getInstance().warn(e);
    }
  }
  /**
   * PreparedStatement#close用にコードを埋め込む
   *
   * @param ctClass PreparedStatementを実装するクラス
   * @param method closeメソッド
   * @throws CannotCompileException コード埋め込みに失敗した場合
   */
  public static void convertPreparedMethodClose(final CtClass ctClass, final CtBehavior method)
      throws CannotCompileException {
    String className = ctClass.getName();
    className = className.substring(className.lastIndexOf('.') + 1);

    // 前処理を埋め込む
    String key = "javelin.jdbc.instrument.JdbcJavelinConverter.ModifiedMethodLabel";
    String message = JdbcJavelinMessages.getMessage(key, className, method.getName());
    SystemLogger.getInstance().info(message);
    method.insertAfter(BCI_METHOD_PLANFORPREPARED_CLOSE);
  }
  /**
   * PreparedStatementのexecuteメソッドに、 バインド引数保存用ArrayList初期化処理を追加する。
   *
   * @param ctClass 変換対象のクラス。
   * @param method メソッド。
   * @throws CannotCompileException javassistがコンパイルに失敗した場合。
   */
  private static void convertExecuteMethod(final CtClass ctClass, final CtBehavior method)
      throws CannotCompileException {
    String className = ctClass.getName();
    className = className.substring(className.lastIndexOf('.') + 1);

    // 前処理を埋め込む
    String key = "javelin.jdbc.instrument.JdbcJavelinConverter.ModifiedMethodLabel";
    String message = JdbcJavelinMessages.getMessage(key, className, method.getName());
    SystemLogger.getInstance().info(message);
    method.insertAfter(
        "this.jdbcJavelinBindValIndex_ = 0;" + "this.flagForPlanStmt_ = false;", true);
  }
 private static void addSqlToFieldCon(final CtClass ctClass, final CtBehavior method)
     throws CannotCompileException {
   String addSqlCode =
       JdbcJavelinRecorder.class.getName()
           + ".postPrepareStatement($0, $1, $_, \""
           + method.getName()
           + "\");";
   method.insertAfter(addSqlCode);
   String key = "javelin.jdbc.instrument.JdbcJavelinConverter.ModifiedMethodLabel";
   String message = JdbcJavelinMessages.getMessage(key, ctClass.getName(), method.getName());
   SystemLogger.getInstance().info(message);
   if (SystemLogger.getInstance().isDebugEnabled()) {
     String tegKey = "javelin.jdbc.instrument.JdbcJavelinConverter.JDBCJavelinTag";
     String jdbcJavelinTag = JdbcJavelinMessages.getMessage(tegKey);
     String messageKey = "javelin.jdbc.instrument.JdbcJavelinConverter.SQLAddedLabel1";
     String logMessage = JdbcJavelinMessages.getMessage(messageKey, method.getName());
     SystemLogger.getInstance().debug(jdbcJavelinTag + logMessage);
   }
 }