package com.pgf.mqspring.component.impl; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.pgf.mqspring.component.MqSpringMessageSourceComponent; import com.pgf.mqspring.component.TelegramInfoComponent; import com.pgf.mqspring.constant.CharDiv; import com.pgf.mqspring.constant.MqSpringConst; import com.pgf.mqspring.constant.MqSpringMessageId; import com.pgf.mqspring.model.TelegramInfoModel; /** * 電文情報クラス *

* アプリ起動時にS3よりファイルをダウンロードして初期化する。 * */ @Component public class TelegramInfoComponentImpl implements TelegramInfoComponent { /** ロガー */ private static final Logger logger = LogManager.getLogger(); /** ヘッダ行識別子 */ private static final String HEADER_IDENTIFIER = "DISP_CODE"; /** 電文情報マップ */ private Map> telegramInfoMap = new HashMap<>(); /** 電文情報読込エラー判定 */ private boolean isTelegramInfoError; /** MessageSource実装クラス */ private MqSpringMessageSourceComponent messageSource; public TelegramInfoComponentImpl(MqSpringMessageSourceComponent messageSource, @Value("${aws.bucketname}") String s3BucketName, @Value("${aws.telegramInfo.key}") String telegramInfoKey) { this.messageSource = messageSource; initTelegramInfo(s3BucketName, telegramInfoKey); } /** * 電文情報初期化処理 *

* S3クライアント.getObjectを実行し、電文定義マスタファイルを取得する。以下引数
*  ・引数のS3バケット名
*  ・引数の電文定義マスタキー
* 電文定義マスタファイルを1行ずつ読込し、以下の処理を繰り返し、増幅前電文情報モデルリストを生成する。
*  行データをカンマで分割し、行データ配列とする
*  行データ配列の先頭が"DISP_CODE"の場合
*   ヘッダ行と見なし、次の行を読込する
*  行データ配列を電文情報モデルに変換する
* 増幅前電文情報モデルリストの要素分、以下の処理を繰り返す
*  checkTelegramInfoModelを実行する。以下引数
*   ・電文情報モデル
*  checkTelegramInfoModelの戻り値がfalseの場合
*   電文情報読込エラー判定をtrueに変更する
*   処理を終了する
* 増幅前電文情報モデルリストの要素分、以下の処理を繰り返し、電文情報リストを生成する。
*  電文情報モデル.groupNumが0の場合
*   電文情報リストに要素を追加する
*   次の要素へ
*  グループリストに要素が含まれている場合
*   次の要素へ
*  増幅前電文情報モデルリストから要素~要素+電文情報モデル.groupNumまでのリストを抽出し、グループリストとする
*  グループリストを電文情報モデル.repeatNumの数値分増幅し、電文情報リストに追加する
* 電文情報リストを電文情報モデル.dispCodeでグルーピングし、電文情報マップを生成する。
*
* 処理中に例外が発生した場合
*  電文情報読込エラー判定をtrueに変更する
*  エラーログを出力する
*   ログメッセージID:SYS7081E
*  処理を終了する
* * @param s3BucketName S3バケット名 * @param telegramInfoKey 電文定義マスタキー */ private void initTelegramInfo(String s3BucketName, String telegramInfoKey) { String telegramFile = Paths.get("/ibm_telegram_info.csv").toString(); try ( BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream(telegramFile), StandardCharsets.UTF_8))) { // 電文定義マスタを電文情報モデルリストに変換 List rawTelegramInfoModelList = br.lines() .map(line -> line.split(MqSpringConst.COMMA, 0)) .filter(array -> !HEADER_IDENTIFIER.equals(array[0])) .map(array -> { TelegramInfoModel model = new TelegramInfoModel(); model.setDispCode(array[0]); model.setFieldNo(array[1]); model.setItemName(array[2]); model.setItemLength(array[3]); model.setCharDiv(array[4]); model.setRepeatNum(array[5]); model.setGroupNum(array[6]); model.setInsDate(array[7]); return model; }) .collect(Collectors.toList()); // 電文情報チェック if (!rawTelegramInfoModelList.stream().allMatch(this::checkTelegramInfoModel)) { // 電文情報チェックでエラーが発生した場合 isTelegramInfoError = true; return; } // 繰り返し項目を増幅したリストを作成する List telegramInfoModelList = new ArrayList<>(); List groupList = new ArrayList<>(); for (TelegramInfoModel model : rawTelegramInfoModelList) { int groupNum = Integer.parseInt(model.getGroupNum()); if (groupNum == 0) { telegramInfoModelList.add(model); continue; } if (groupList.contains(model)) { continue; } int currentIndex = rawTelegramInfoModelList.indexOf(model); groupList = rawTelegramInfoModelList.subList(currentIndex, currentIndex + groupNum); for (int i = 0; i < Integer.parseInt(model.getRepeatNum()); i++) { telegramInfoModelList.addAll(groupList); } } // 電文情報マップ作成 telegramInfoMap = telegramInfoModelList.stream() .collect(Collectors.groupingBy(TelegramInfoModel::getDispCode)); } catch (Exception e) { isTelegramInfoError = true; logger.error(messageSource.getMessage(MqSpringMessageId.SYS7081E), e); } } /** * 電文情報マップ取得 *

* 電文情報マップを返却する * * @return 電文情報マップ */ @Override public Map> getTelegramInfoMap() { return telegramInfoMap; } /** * 電文情報チェック処理 *

* 電文情報モデル.dispCodeが""の場合
*  エラーログを出力する
*   ログメッセージID:SYS7062E
*  falseを返却する
* 電文情報モデル.itemNameが""の場合
*  エラーログを出力する
*   ログメッセージID:SYS7064E
*  falseを返却する
* 電文情報モデル.charDivが""の場合
*  エラーログを出力する
*   ログメッセージID:SYS7065E
*  falseを返却する
* 電文情報モデル.charDivが"0"、"1"、"2"のいずれでもない場合
*  エラーログを出力する
*   ログメッセージID:SYS7066E
*  falseを返却する
* 電文情報モデル.RepeatNumが""の場合
*  エラーログを出力する
*   ログメッセージID:SYS7067E
*  falseを返却する
* 数値変換した電文情報モデル.RepeatNumが0より大きい場合
* 且つ電文情報モデル.GroupNumが""の場合
*  エラーログを出力する
*   ログメッセージID:SYS7068E
*  falseを返却する
* 電文情報モデル.itemLengthが""の場合
*  エラーログを出力する
*   ログメッセージID:SYS7069E
*  falseを返却する
* trueを返却する * * @param model * @return */ private boolean checkTelegramInfoModel(TelegramInfoModel model) { if (model.getDispCode().isEmpty()) { // 画面コードが存在しない場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7062E)); return false; } if (model.getItemName().isEmpty()) { // 項目名が存在しない場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7064E)); return false; } if (model.getCharDiv().isEmpty()) { // 文字編集区分が存在しない場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7065E)); return false; } if (!CharDiv.HANKAKU.getKbn().equals(model.getCharDiv()) && !CharDiv.ZENKAKU_SISO_NONE.getKbn().equals(model.getCharDiv()) && !CharDiv.ZENKAKU_SISO.getKbn().equals(model.getCharDiv())) { // 文字編集区分が0~2の範囲以外の場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7066E)); return false; } if (model.getRepeatNum().isEmpty()) { // グループ繰り返し数が存在しない場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7067E)); return false; } if (Integer.parseInt(model.getRepeatNum()) > 0 && model.getGroupNum().isEmpty()) { // グループ繰り返し数が指定されているのに、グループ項目数が存在しない場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7068E)); return false; } if (model.getItemLength().isEmpty()) { // 電文項目長が存在しない場合 logger.error(messageSource.getMessage(MqSpringMessageId.SYS7069E)); return false; } return true; } /** * 電文情報読込エラー判定取得 *

* 電文情報読込エラー判定を返却する * * @return 電文情報読込エラー判定 */ @Override public boolean isTelegramInfoError() { return isTelegramInfoError; } }