# class Veritrans::Tercerog::Mdk::MdkContentHandler

MdkContentHandler クラス

    戻り電文（JSON）からレスポンスDTOへプロパティをマッピングするクラス

### Constants

DFAULT_ENCODE

  デフォルトエンコード

ELEM_OPTION_RESULTS_PATH

  決済オプションリザルトエレメントパス

ELEM_RESULT_ROOT

  決済コマンド共通部ルートエレメント

SLASH

  区切り文字

### Public Class Methods

new() click to toggle source

### コンストラクタ¶ ↑

    # File tgMdk/lib/tg_mdk/mdk_content_handler.rb, line 36
    def initialize()
      config = Veritrans::Tercerog::Mdk::MdkConfig.instance
      # DTOの文字エンコードを取得
      @encode = config[:DTO_ENCODE]
    end

### Public Instance Methods

parse(result_json_string, response_dto) click to toggle source

### GW処理結果JSONを解析し、指定した応答Dtoの各プロパティに設定する¶ ↑

@param

  result_json_string JSON文字列

@param

  response_dto 応答Dto

@return

  JSONを設定した応答Dto

    # File tgMdk/lib/tg_mdk/mdk_content_handler.rb, line 48
    def parse(result_json_string, response_dto)

      hash_data = JSON.parse(result_json_string)

      parse_hash("", hash_data, response_dto, ["#{SLASH}#{ELEM_RESULT_ROOT}"])
      parse_hash("#{SLASH}#{ELEM_RESULT_ROOT}", hash_data[ELEM_RESULT_ROOT], response_dto, ["#{SLASH}#{ELEM_OPTION_RESULTS_PATH}"])
      return response_dto
    end

### Private Instance Methods

get_attr_accessor_class(obj, attr_accessor_name) click to toggle source

### 指定したオブジェクトのアクセサメソッドの型を取得する。¶ ↑

@param

  obj オブジェクト

@param

  attr_accessor_name アクセサメソッド名

@return

  アクセサメソッドの型

    # File tgMdk/lib/tg_mdk/mdk_content_handler.rb, line 172
    def get_attr_accessor_class(obj, attr_accessor_name)

      return nil if obj.nil? || attr_accessor_name.empty?

      if obj.respond_to?(:get_property_class_name_hash) && obj.get_property_class_name_hash["#{attr_accessor_name}"] != nil
        class_name =  obj.get_property_class_name_hash["#{attr_accessor_name}"]
      else
        class_name = attr_accessor_name.gsub(/\b\w/){|word| word.capitalize}
      end
      return nil unless Veritrans::Tercerog::Mdk.const_defined?(class_name)

      class_name = "Veritrans::Tercerog::Mdk::#{class_name}"
      target_class = class_name.split("::").inject(Object){ |c, name| c.const_get(name) }
      if target_class.is_a?(Class)
        return target_class
      end
      return nil
    end

parse_hash(parent_path, hash_data, response_dto, ignore_list) click to toggle source

### ハッシュデータを指定した応答Dtoの各プロパティに設定する¶ ↑

@param

  parent_path 親要素のパス

@param

  hash_data ハッシュデータ

@param

  response_dto 応答Dto

@param

  ignore_list 無視する項目（パス）の配列

@return

  JSONを設定した応答Dto

    # File tgMdk/lib/tg_mdk/mdk_content_handler.rb, line 65
    def parse_hash(parent_path, hash_data, response_dto, ignore_list)

      if hash_data.nil? || !hash_data.is_a?(Hash)
        return response_dto
      end

      if ignore_list.nil? || !ignore_list.is_a?(Array)
        ignore_paths = []
      else
        ignore_paths = ignore_list
      end

      hash_data.each_pair do |key, value|
        current_path = "#{parent_path}#{SLASH}#{key}"
        if ignore_paths.include?(current_path)
          next
        end

        # Element名よりsetter名生成
        setter_name = key.gsub(/\b\w/){|word| word.downcase}.gsub(/[A-Z]/){|word|
          "_".concat word.downcase}
        setter_name = setter_name.concat "="

        # インスタンス変数の存在確認
        if response_dto.respond_to?(setter_name)
          # valueのクラスによって処理を変更
          if value.nil?
            response_dto.send(setter_name, nil)

          elsif value.is_a?(String)
            # valueが文字列の場合
            response_dto.send(setter_name, Veritrans::Tercerog::Mdk::MdkUtils::mdk_encode_to(@encode, value.to_s))

          elsif value.is_a?(Numeric)
            # valueが数値型の場合
            response_dto.send(setter_name, Veritrans::Tercerog::Mdk::MdkUtils::mdk_encode_to(@encode, value.to_s))

          elsif !!value == value
            # valueがBoolean型の場合
            response_dto.send(setter_name, Veritrans::Tercerog::Mdk::MdkUtils::mdk_encode_to(@encode, value.to_s))

          elsif value.is_a?(Hash)
            # valueがハッシュの場合
            attr_class =  get_attr_accessor_class(response_dto, key)
            unless attr_class.nil?
              instance = attr_class.new
              # 処理中ノードとDtoクラスを基に再帰処理を実行
              parse_hash(current_path, value, instance, ignore_list)
              # オブジェクトをDTOプロパティに設定
              response_dto.send(setter_name, instance)
            end
          elsif value.is_a?(Array)
            # valueが配列の場合
            if value.empty?
              # 要素が存在しない場合
              response_dto.send(setter_name, [])
              next
            end

            # keyから型を特定
            attr_class = get_attr_accessor_class(response_dto, key)
            if attr_class.nil?
              # 型が特定できない場合
              array_instance = []

              value.each do |element|
                if !element.nil?
                  array_instance << Veritrans::Tercerog::Mdk::MdkUtils::mdk_encode_to(@encode, element.to_s)
                end
              end
              # オブジェクト配列をDTOプロパティに設定
              response_dto.send(setter_name, array_instance)

            else
              # 配列の要素が上記以外の配列の場合
              instance_list = []

              value.each do |element|
                if !element.nil?
                  instance = attr_class.new
                  # 処理中ノードとDtoクラスを基に再帰処理を実行
                  parse_hash(current_path, element, instance, ignore_list)
                instance_list << instance
                end
              end
            # オブジェクト配列をDTOプロパティに設定
            response_dto.send(setter_name, instance_list)
            end
          end
        else
          # パースするプロパティが無かったエレメント要素の存在をログ出力
          getter_name = key.gsub(/\b\w/){|word| word.downcase}.gsub(/[A-Z]/){|word|
            "_".concat word.downcase}
          Veritrans::Tercerog::Mdk::logger.info("attr_accessor: '#{getter_name}' not exists.")
        end
      end

      return response_dto
    end