package ghast; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.commons.text.StringSubstitutor; import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class Messages { private static final Map MESSAGES_MAP = new HashMap<>(); //region Load messages /** * Загрузка сообщений из {@link Properties} * * @param properties список сообщений и шаблонов */ public static void load(Properties properties) { load(properties.entrySet().stream().collect(Collectors.toMap( entry -> (String) entry.getKey(), entry -> (String) entry.getValue() ))); } /** * Загрузка сообщений из {@link Reader}. *

* Формат строк: {@code key=value} *

* * @param reader {@link Reader} со списоком сообщений и шаблонов */ public static void load(Reader reader) { try(BufferedReader bufferedReader = new BufferedReader(reader)) { Map map = bufferedReader.lines() .map(line -> line.split("=", 2)) .collect(Collectors.toMap( pair -> pair[0].trim().toLowerCase(), pair -> pair[1].trim() )); load(map); } catch (IOException e) { //TODO заменить на специализированный Exception throw new RuntimeException("Error load messages: " + e.getMessage(), e); } } /** * Загрузка сообщений из {@link Map}<{@link String}, {@link String}>. * * @param messages список сообщений и шаблонов */ public static void load(Map messages) { MESSAGES_MAP.clear(); MESSAGES_MAP.putAll(messages); } //endregion //region Get messages /** * Получить обычное сообщение по ключу/коду. * * @param key ключ/код * @return Сообщение, если таковое задано. Иначе - ключ */ public static String get(String key) { String keyLc = key.toLowerCase(); return MESSAGES_MAP.getOrDefault(keyLc, keyLc); } /** * Получить параметизированное сообщение по ключу/коду. * * @param key ключ/код * @param params список параметров * @return Сообщение, если таковое задано. Иначе - ключ */ public static String get(String key, Map params) { String keyLc = key.toLowerCase(); if (MESSAGES_MAP.containsKey(keyLc)) { return format(MESSAGES_MAP.get(keyLc), params); } else { return keyLc; } } /** * Получить параметизированное сообщение по ключу/коду. * * @param key ключ/код * @param params чередующийся по парный список параметров: {@link String (str)param_name}, {@link Object (obj)param_value} и т.д. * @return Сообщение, если таковое задано. Иначе - ключ */ @SuppressWarnings("unchecked") public static String get(String key, Object... params) { if (params.length == 1 && params[0] instanceof Map) { return get(key, (Map) params[0]); } String keyLc = key.toLowerCase(); if (MESSAGES_MAP.containsKey(keyLc)) { return format(MESSAGES_MAP.get(keyLc), params); } else { return keyLc; } } //endregion //region Format message /** * Получить сообщение по формату. * * @param format параметизированное сообщение * @param params параметры * @return сообщение */ public static String format(String format, Map params) { return StringSubstitutor.replace(format, params, "{", "}"); } /** * Получить сообщение по формату. * * @param format параметизированное сообщение * @param params параметры * @return сообщение */ @SuppressWarnings("unchecked") public static String format(String format, Object... params) { if (params.length == 1 && params[0] instanceof Map) { return format(format, (Map) params[0]); } return format(format, arrayParamsToMap(params)); } //endregion private static Map arrayParamsToMap(Object... params) { int len; if ((params.length % 2) == 1) { len = params.length - 1; } else { len = params.length; } Map map = new HashMap<>(len / 2); for (int i = 0; i < len; i = i + 2) { map.put((String) params[i], params[i + 1]); } return map; } }