JSON処理
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws Exception {
// JSON文字列の定義
String jsonString = "{\n" +
"\"apiVer1\":\"$$(TEST_NO1)\",\n" +
"\"apiver2\":\"$$(TEST_NO2 HEAD:11)\",\n" +
"\"norma\":\"testValue\",\n" +
"\"apiver\":\"14\",\n" +
"\"normal2\":\"testValue2\",\n" +
"\"apiPerson\":{\n" +
"\"apiVer3\":\"$$(TEST_NO3 HEAD:13)\",\n" +
"\"kokyaku\":\"$$(kokyakuNo)\",\n" +
"\"apiVer4\":\"$$(TEST_NO4 HEAD:24)\"\n" +
"},\n" +
"\"apiFunds\":{\n" +
"\"apiVer5\":\"$$(TEST_NO5 HEAD:26)\",\n" +
"\"apiVer6\":\"$$(TEST_NO6 ERA:yymmdd)\",\n" +
"\"apiVer7\":\"$$(TEST_NO7 ERA:yymm)\",\n" +
"\"apiVer8\":\"$$(TEST_NO8 IFNA:3/*)\",\n" +
"\"apiVer9\":\"$$(TEST_NO9 IFNA:4/*)\",\n" +
"\"apiVer10\":\"$$(TEST_NO10 IFNA:5/6)\",\n" +
"\"apiVer11\":\"$$(TEST_NO11 IFNA:7/8)\"\n" +
"}\n" +
"}";
// テストデータのマップを定義
Map<String, String> bindDateMap = new HashMap<>();
bindDateMap.put("TEST_NO1", "test1Value");
bindDateMap.put("TEST_NO2", "123456789012345");
bindDateMap.put("TEST_NO3", "123456789012345");
bindDateMap.put("TEST_NO4", "123456789012345678901234567");
bindDateMap.put("TEST_NO5", "123456789012345678901234567");
bindDateMap.put("TEST_NO6", "19261224");
bindDateMap.put("TEST_NO7", "192701");
bindDateMap.put("TEST_NO8", ""); // 空文字を設定
bindDateMap.put("TEST_NO9", "");
bindDateMap.put("TEST_NO10", null);
bindDateMap.put("TEST_NO11", "200");
bindDateMap.put("kokyakuNo", "kokyakuNoValue");
// JSON文字列からキーと対応する値のパターンを抽出
Map<String, String> extractedKeyPatternMap = extractKeyPatterns(jsonString);
// 最終的な結果を格納するマップの定義
Map<String, Object> req = new HashMap<>();
// 抽出したキーを使って値を加工し、結果マップに格納
for (Map.Entry<String, String> entry : extractedKeyPatternMap.entrySet()) {
String jsonKey = entry.getKey(); // JSONのキー
String patternOrValue = entry.getValue(); // $$()内のパターンまたはそのままの値
if (patternOrValue.startsWith("$$(")) {
String pattern = patternOrValue.substring(3, patternOrValue.length() - 1); // $$()を取り除く
String bindKey = pattern.split(" ")[0]; // パターンからテスト番号を取得
String value = bindDateMap.get(bindKey); // テストデータマップから値を取得
if (value == null || value.isEmpty() || "0".equals(value)) { // 空文字チェックの追加
value = ""; // 値がnullまたは"0"の場合には空文字を格納
}
String processedValue = processValue(pattern, value); // 値を加工
req.put(jsonKey, processedValue); // 結果をreqマップに追加
} else {
req.put(jsonKey, patternOrValue); // 値をそのままreqマップに追加
}
}
// 結果マップを出力
for (Map.Entry<String, Object> entry : req.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
// JSON文字列からキーとパターンを抽出するメソッド
public static Map<String, String> extractKeyPatterns(String jsonString) throws Exception {
Map<String, String> keyPatternMap = new HashMap<>();
// JSON文字列をパース
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonString);
// 再帰的にJSONノードを処理してキーとパターンを抽出
extractPatternsRecursive(rootNode, "", keyPatternMap);
return keyPatternMap;
}
// 再帰的にJSONノードを処理してキーとパターンを抽出するメソッド
private static void extractPatternsRecursive(JsonNode node, String parentKey, Map<String, String> keyPatternMap) {
if (node.isObject()) {
// JSONオブジェクトの場合、各フィールドを処理
Iterator<Map.Entry<String, JsonNode>> fields = node.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> field = fields.next();
String currentKey = parentKey.isEmpty() ? field.getKey() : parentKey + "." + field.getKey();
extractPatternsRecursive(field.getValue(), currentKey, keyPatternMap);
}
} else if (node.isTextual()) {
// テキストノードの場合、パターンを抽出
String text = node.asText();
Pattern pattern = Pattern.compile("\\$\\$\\((.*?)\\)");
Matcher matcher = pattern.matcher(text);
if (matcher.find()) {
keyPatternMap.put(parentKey, matcher.group(0)); // $$()のパターンを含めて取得
} else {
keyPatternMap.put(parentKey, text); // パターンが見つからない場合はそのまま取得
}
}
}
// キーに基づいて値を加工するメソッド
public static String processValue(String key, String value) throws ParseException {
if (key.contains("HEAD:")) {
// HEAD:の場合、指定された文字数だけ切り出す
int headLength = Integer.parseInt(key.split("HEAD:")[1]);
if (value.length() <= headLength) {
return value; // valueがheadLength以下の場合はそのまま返す
}
return value.substring(0, headLength);
} else if (key.contains("ERA:yymmdd")) {
// ERA:yymmddの場合、和暦に変換
return convertToJapaneseEra(value, "yyyyMMdd");
} else if (key.contains("ERA:yymm")) {
// ERA:yymmの場合、和暦に変換
return convertToJapaneseEra(value, "yyyyMM");
} else if (key.contains("IFNA:") && key.contains("/*")) {
// IFNA:x/*の場合、値が空またはnullならxに置き換え
int replacementValue = Integer.parseInt(key.split("IFNA:")[1].split("/")[0]);
return (value == null || value.isEmpty()) ? String.valueOf(replacementValue) : value;
} else if (key.contains("IFNA:") && key.split("IFNA:")[1].contains("/")) {
// IFNA:x/yの場合、値が空またはnullならxに置き換え、値が空でない場合にはyに置き換え
String[] parts = key.split("IFNA:")[1].split("/");
int nullValueReplacement = Integer.parseInt(parts[0]);
int nonNullValueReplacement = Integer.parseInt(parts[1]);
return (value == null || value.isEmpty()) ? String.valueOf(nullValueReplacement) : String.valueOf(nonNullValueReplacement);
}
return value;
}
// 西暦を和暦に変換するメソッド
public static String convertToJapaneseEra(String date, String format) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date westernDate = sdf.parse(date);
Calendar calendar = Calendar.getInstance();
calendar.setTime(westernDate);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // Calendarの月は0から始まるため+1
int day = calendar.get(Calendar.DAY_OF_MONTH);
String eraYear;
if (format.equals("yyyyMMdd")) {
if (year > 2019 || (year == 2019 && (month > 5 || (month == 5 && day >= 1)))) {
// 令和 (2019年5月1日から)
eraYear = String.format("%02d", year - 2018); // 年が1桁の場合に先頭に0を付ける
return "5" + eraYear + String.format("%02d%02d", month, day);
} else if (year > 1989 || (year == 1989 && (month > 1 || (month == 1 && day >= 8)))) {
// 平成 (1989年1月8日から)
eraYear = String.format("%02d", year - 1988); // 年が1桁の場合に先頭に0を付ける
return "4" + eraYear + String.format("%02d%02d", month, day);
} else if (year > 1926 || (year == 1926 && (month > 12 || (month == 12 && day >= 25)))) {
// 昭和 (1926年12月25日から)
eraYear = String.format("%02d", year - 1925); // 年が1桁の場合に先頭に0を付ける
return "3" + eraYear + String.format("%02d%02d", month, day);
} else if (year > 1912 || (year == 1912 && (month > 7 || (month == 7 && day >= 30)))) {
// 大正 (1912年7月30日から)
eraYear = String.format("%02d", year - 1911); // 年が1桁の場合に先頭に0を付ける
return "2" + eraYear + String.format("%02d%02d", month, day);
} else if (year > 1868 || (year == 1868 && (month > 1 || (month == 1 && day >= 25)))) {
// 明治 (1868年1月25日から)
eraYear = String.format("%02d", year - 1867); // 年が1桁の場合に先頭に0を付ける
return "1" + eraYear + String.format("%02d%02d", month, day);
} else {
// 上記以外の場合、未("0")
eraYear = "00"; // 年が1桁の場合に先頭に0を付ける
return "0" + eraYear + String.format("%02d%02d", month, day);
}
} else if (format.equals("yyyyMM")) {
if (year > 2019 || (year == 2019 && month >= 5)) {
// 令和 (2019年5月から)
eraYear = String.format("%02d", year - 2018); // 年が1桁の場合に先頭に0を付ける
return "5" + eraYear + String.format("%02d", month);
} else if ((year > 1989) || (year == 1989 && month >= 2) || (year == 2019 && month < 5)) {
// 平成 (1989年2月から2019年4月まで)
eraYear = String.format("%02d", year - 1988); // 年が1桁の場合に先頭に0を付ける
return "4" + eraYear + String.format("%02d", month);
} else if ((year > 1926) || (year == 1927 && month >= 1) || (year == 1989 && month < 2)) {
// 昭和 (1927年1月から1989年1月まで)
if (year == 1927 && month == 1) {
eraYear = String.format("%02d", year - 1926); // 年が1桁の場合に先頭に0を付ける
} else {
eraYear = String.format("%02d", year - 1926 + 1); // 1927年1月は昭和1年1月とする
}
return "3" + eraYear + String.format("%02d", month);
} else if ((year > 1912) || (year == 1912 && month >= 8) || (year == 1926 && month < 12)) {
// 大正 (1912年8月から1926年12月まで)
eraYear = String.format("%02d", year - 1911); // 年が1桁の場合に先頭に0を付ける
return "2" + eraYear + String.format("%02d", month);
} else if ((year > 1868) || (year == 1868 && month >= 2) || (year == 1912 && month < 8)) {
// 明治 (1868年2月から1912年7月まで)
eraYear = String.format("%02d", year - 1867); // 年が1桁の場合に先頭に0を付ける
return "1" + eraYear + String.format("%02d", month);
} else {
// 上記以外の場合、未("0")
eraYear = "00"; // 年が1桁の場合に先頭に0を付ける
return "0" + eraYear + String.format("%02d", month);
}
}
return date;
}
}