From c963c4bd6053b23e63cd7dbc4326a0cdc8fed7d1 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 3 Jan 2021 16:00:34 +0300 Subject: [PATCH 01/13] JdbcTemplate: refactoring --- .../java/ghast/database/JdbcOperations.java | 8 +- .../java/ghast/database/JdbcTemplate.java | 122 +++++++++--------- .../java/ghast/database/JdbcTemplateTest.java | 90 ++++++++----- 3 files changed, 122 insertions(+), 98 deletions(-) diff --git a/src/main/java/ghast/database/JdbcOperations.java b/src/main/java/ghast/database/JdbcOperations.java index 89d12ca..9d70f56 100644 --- a/src/main/java/ghast/database/JdbcOperations.java +++ b/src/main/java/ghast/database/JdbcOperations.java @@ -9,15 +9,11 @@ public interface JdbcOperations { T query(String sql, ResultSetExtractor rse) throws DataAccessException; - List query(String sql, RowMapper rowMapper) throws DataAccessException; - - T queryForObject(String sql, RowMapper rowMapper) throws DataAccessException; + List queryList(String sql, RowMapper rowMapper) throws DataAccessException; Map queryForMap(String sql) throws DataAccessException; - List> queryForList(String sql) throws DataAccessException; + List> queryForMapList(String sql) throws DataAccessException; int update(String sql) throws DataAccessException; - - int delete(String sql) throws DataAccessException; } diff --git a/src/main/java/ghast/database/JdbcTemplate.java b/src/main/java/ghast/database/JdbcTemplate.java index c9e629a..52ed3a4 100644 --- a/src/main/java/ghast/database/JdbcTemplate.java +++ b/src/main/java/ghast/database/JdbcTemplate.java @@ -6,17 +6,16 @@ import lombok.NoArgsConstructor; import lombok.Setter; import javax.sql.DataSource; +import java.sql.Date; import java.sql.*; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @NoArgsConstructor @Getter @Setter public class JdbcTemplate implements JdbcOperations { + private static final String DBG_SQL_INFO = "Execute SQL: {0}"; private DataSource dataSource; public JdbcTemplate(DataSource dataSource) { @@ -25,7 +24,7 @@ public class JdbcTemplate implements JdbcOperations { @Override public void execute(String sql) throws DataAccessException { - XLog.debug("Execute SQL: {0}", sql); + XLog.debug(DBG_SQL_INFO, sql); Connection connection = openConnection(); Statement statement = null; @@ -42,7 +41,7 @@ public class JdbcTemplate implements JdbcOperations { @Override public T query(String sql, ResultSetExtractor rse) throws DataAccessException { - XLog.debug("Execute SQL: {0}", sql); + XLog.debug(DBG_SQL_INFO, sql); Connection connection = openConnection(); Statement statement = null; @@ -61,71 +60,63 @@ public class JdbcTemplate implements JdbcOperations { } @Override - public List query(String sql, final RowMapper rowMapper) throws DataAccessException { + public List queryList(String sql, final RowMapper rowMapper) throws DataAccessException { return query(sql, rs -> { - List resultList = new ArrayList<>(); + List resultList; int rowNum = 0; - while (rs.next()) { - resultList.add(rowMapper.mapRow(rs, rowNum++)); + if (rs.next()) { + resultList = new ArrayList<>(); + + do { + resultList.add(rowMapper.mapRow(rs, rowNum++)); + } while (rs.next()); + } else { + resultList = Collections.emptyList(); } + return resultList; }); } @Override - public T queryForObject(String sql, RowMapper rowMapper) throws DataAccessException { + public Map queryForMap(String sql) throws DataAccessException { return query(sql, rs -> { if (rs.next()) { - T resultObj = rowMapper.mapRow(rs, 0); + ResultSetMetaData metaData = rs.getMetaData(); + int columnCount = metaData.getColumnCount(); - if (rs.next()) { - throw new IncorrectResultSizeDataAccessException(1); - } - - return resultObj; + return rowToMap(columnCount, metaData, rs); } else { - throw new EmptyResultDataAccessException(1); + return Collections.emptyMap(); } }); } @Override - public Map queryForMap(String sql) throws DataAccessException { - return queryForObject(sql, (rs, rowNum) -> { - ResultSetMetaData metaData = rs.getMetaData(); - int columnCount = metaData.getColumnCount(); - Map resultMap = new LinkedHashMap<>(columnCount); + public List> queryForMapList(String sql) throws DataAccessException { + return query(sql, rs -> { + List> resultList; - for (int i = 1; i <= columnCount; i++) { - String key = lookupColumnName(metaData, i); - Object value = getResultSetRawValue(rs, i); - resultMap.put(key, value); + if (rs.next()) { + resultList = new ArrayList<>(); + + ResultSetMetaData metaData = rs.getMetaData(); + int columnCount = metaData.getColumnCount(); + + do { + resultList.add(rowToMap(columnCount, metaData, rs)); + } while (rs.next()); + } else { + resultList = Collections.emptyList(); } - return resultMap; - }); - } - - @Override - public List> queryForList(String sql) throws DataAccessException { - return query(sql, (rs, rowNum) -> { - ResultSetMetaData metaData = rs.getMetaData(); - int columnCount = metaData.getColumnCount(); - Map resultMap = new LinkedHashMap<>(columnCount); - - for (int i = 1; i <= columnCount; i++) { - String key = lookupColumnName(metaData, i); - Object value = getResultSetRawValue(rs, i); - resultMap.put(key, value); - } - - return resultMap; + return resultList; }); } @Override public int update(String sql) throws DataAccessException { - XLog.debug("Execute SQL: {0}", sql); + XLog.debug(DBG_SQL_INFO, sql); Connection connection = openConnection(); Statement statement = null; @@ -143,16 +134,10 @@ public class JdbcTemplate implements JdbcOperations { } } - @Override - public int delete(String sql) throws DataAccessException { - return update(sql); - } - private Connection openConnection() { try { return getDataSource().getConnection(); - } - catch (SQLException ex) { + } catch (SQLException ex) { throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); } } @@ -165,13 +150,26 @@ public class JdbcTemplate implements JdbcOperations { return name; } + private Map rowToMap(int columnCount, ResultSetMetaData metaData, ResultSet rs) throws SQLException { + Map rowMap = new LinkedHashMap<>(columnCount); + + for (int i = 1; i <= columnCount; i++) { + String key = lookupColumnName(metaData, i); + Object value = getResultSetRawValue(rs, i); + rowMap.put(key, value); + } + + return rowMap; + } + private Object getResultSetRawValue(ResultSet resultSet, int index) throws SQLException { Object obj = resultSet.getObject(index); - String className = null; - if (obj != null) { - className = obj.getClass().getName(); + if (obj == null) { + return null; } + String className = obj.getClass().getName(); + if (obj instanceof Blob) { Blob blob = (Blob) obj; obj = blob.getBytes(1, (int) blob.length()); @@ -180,18 +178,16 @@ public class JdbcTemplate implements JdbcOperations { obj = clob.getSubString(1, (int) clob.length()); } else if ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className)) { obj = resultSet.getTimestamp(index); - } else if (className != null && className.startsWith("oracle.sql.DATE")) { + } else if (className.startsWith("oracle.sql.DATE")) { String metaDataClassName = resultSet.getMetaData().getColumnClassName(index); if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { obj = resultSet.getTimestamp(index); - } - else { + } else { obj = resultSet.getDate(index); } - } else if (obj instanceof Date) { - if ("java.sql.Timestamp".equals(resultSet.getMetaData().getColumnClassName(index))) { - obj = resultSet.getTimestamp(index); - } + } else if (obj instanceof Date + && "java.sql.Timestamp".equals(resultSet.getMetaData().getColumnClassName(index))) { + obj = resultSet.getTimestamp(index); } return obj; diff --git a/src/test/java/ghast/database/JdbcTemplateTest.java b/src/test/java/ghast/database/JdbcTemplateTest.java index c5ff0d2..bbdc8bc 100644 --- a/src/test/java/ghast/database/JdbcTemplateTest.java +++ b/src/test/java/ghast/database/JdbcTemplateTest.java @@ -84,7 +84,7 @@ class JdbcTemplateTest { } @Test - void testQuery_Single() { + void testQuery_Simple_Single() { String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''", TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); @@ -100,44 +100,30 @@ class JdbcTemplateTest { } @Test - void testQuery_List() { + void testQuery_Simple_List() { String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}'' OR {1} LIKE ''{4}''", TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0], DATA[1][0]); - List listValues = jdbcTemplate.query(sql, (rs, rowNum) -> rs.getInt(1)); + List listValues = jdbcTemplate.queryList(sql, (rs, rowNum) -> rs.getInt(1)); assertIterableEquals(Lists.newArrayList(DATA[0][1], DATA[1][1]), listValues); } @Test - void testQueryForObject() { - class Player { - String name; - int value; - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Player)) return false; - Player player = (Player) o; - return new EqualsBuilder().append(value, player.value).append(name, player.name).isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37).append(name).append(value).toHashCode(); - } - } - + void testQuery_Object_Single() { String sql = MessageFormat.format("SELECT {1}, {2} FROM {0} WHERE {1} LIKE ''{3}''", TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); - Player actualPlayer = jdbcTemplate.queryForObject(sql, (rs, rowNum) -> { - Player player0 = new Player(); - player0.name = rs.getString(COLUMN_NAME); - player0.value = rs.getInt(COLUMN_VALUE); + Player actualPlayer = jdbcTemplate.query(sql, rs -> { + if (rs.next()) { + Player player0 = new Player(); + player0.name = rs.getString(COLUMN_NAME); + player0.value = rs.getInt(COLUMN_VALUE); - return player0; + return player0; + } else { + return null; + } }); Player expectedPlayer = new Player(); @@ -147,6 +133,34 @@ class JdbcTemplateTest { assertEquals(expectedPlayer, actualPlayer); } + @Test + void testQuery_Object_List() { + String sql = MessageFormat.format("SELECT {1}, {2} FROM {0}", + TABLE_NAME, COLUMN_NAME, COLUMN_VALUE); + + List actualPlayers = jdbcTemplate.queryList(sql, (rs, num) -> { + Player player0 = new Player(); + player0.name = rs.getString(COLUMN_NAME); + player0.value = rs.getInt(COLUMN_VALUE); + + return player0; + }); + + + List expectedPlayers = Stream.of(DATA) + .map(datum -> { + Player player1 = new Player(); + player1.name = (String) datum[0]; + player1.value = (int) datum[1]; + + return player1; + }) + .collect(Collectors.toList()); + + + assertIterableEquals(expectedPlayers, actualPlayers); + } + @Test void testQueryForMap() { String sql = MessageFormat.format("SELECT {1}, {2} FROM {0} WHERE {1} LIKE ''{3}''", @@ -162,11 +176,11 @@ class JdbcTemplateTest { } @Test - void testQueryForList() { + void testQueryForMapList() { String sql = MessageFormat.format("SELECT {1}, {2} FROM {0}", TABLE_NAME, COLUMN_NAME, COLUMN_VALUE); - List> actualMapList = jdbcTemplate.queryForList(sql); + List> actualMapList = jdbcTemplate.queryForMapList(sql); List> expectedMapList = Stream.of(DATA) .map(datum -> ImmutableMap.of(COLUMN_NAME, datum[0], COLUMN_VALUE, datum[1])) @@ -211,6 +225,24 @@ class JdbcTemplateTest { jdbcTemplate.execute("DROP TABLE IF EXISTS " + TABLE_NAME); } + class Player { + String name; + int value; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Player)) return false; + Player player = (Player) o; + return new EqualsBuilder().append(value, player.value).append(name, player.name).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37).append(name).append(value).toHashCode(); + } + } + @Nested class JdbcTemplateTest_ExecuteTestCase { From f82169130826c0b12981eeb352d6a24074cb2a46 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 3 Jan 2021 16:07:40 +0300 Subject: [PATCH 02/13] JdbcTemplate: add queryOne method --- src/main/java/ghast/database/JdbcOperations.java | 3 +++ src/main/java/ghast/database/JdbcTemplate.java | 11 +++++++++++ src/test/java/ghast/database/JdbcTemplateTest.java | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/src/main/java/ghast/database/JdbcOperations.java b/src/main/java/ghast/database/JdbcOperations.java index 9d70f56..6a4aa50 100644 --- a/src/main/java/ghast/database/JdbcOperations.java +++ b/src/main/java/ghast/database/JdbcOperations.java @@ -2,6 +2,7 @@ package ghast.database; import java.util.List; import java.util.Map; +import java.util.Optional; public interface JdbcOperations { @@ -9,6 +10,8 @@ public interface JdbcOperations { T query(String sql, ResultSetExtractor rse) throws DataAccessException; + Optional queryOne(String sql, ResultSetExtractor rse) throws DataAccessException; + List queryList(String sql, RowMapper rowMapper) throws DataAccessException; Map queryForMap(String sql) throws DataAccessException; diff --git a/src/main/java/ghast/database/JdbcTemplate.java b/src/main/java/ghast/database/JdbcTemplate.java index 52ed3a4..3b91032 100644 --- a/src/main/java/ghast/database/JdbcTemplate.java +++ b/src/main/java/ghast/database/JdbcTemplate.java @@ -59,6 +59,17 @@ public class JdbcTemplate implements JdbcOperations { } } + @Override + public Optional queryOne(String sql, ResultSetExtractor rse) throws DataAccessException { + return query(sql, rs -> { + if (rs.next()) { + return Optional.ofNullable(rse.extractData(rs)); + } else { + return Optional.empty(); + } + }); + } + @Override public List queryList(String sql, final RowMapper rowMapper) throws DataAccessException { return query(sql, rs -> { diff --git a/src/test/java/ghast/database/JdbcTemplateTest.java b/src/test/java/ghast/database/JdbcTemplateTest.java index bbdc8bc..97a3f97 100644 --- a/src/test/java/ghast/database/JdbcTemplateTest.java +++ b/src/test/java/ghast/database/JdbcTemplateTest.java @@ -17,6 +17,7 @@ import java.sql.SQLException; import java.text.MessageFormat; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.StringJoiner; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -99,6 +100,17 @@ class JdbcTemplateTest { assertEquals(DATA[0][1], value); } + @Test + void testQuery_Simple_Optional() { + String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}''", + TABLE_NAME, COLUMN_NAME, COLUMN_VALUE, DATA[0][0]); + + Optional optValue = jdbcTemplate.queryOne(sql, rs -> rs.getInt(1)); + + assertTrue(optValue.isPresent()); + assertEquals(DATA[0][1], optValue.get()); + } + @Test void testQuery_Simple_List() { String sql = MessageFormat.format("SELECT {2} FROM {0} WHERE {1} LIKE ''{3}'' OR {1} LIKE ''{4}''", From 3037aed8ef070ae58f73b2a4dcf84c8cb27ed0a2 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 3 Jan 2021 16:09:24 +0300 Subject: [PATCH 03/13] =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D0=BD=20=D0=BB?= =?UTF-8?q?=D0=B8=D1=88=D0=BD=D0=B8=D0=B9=20=D0=BA=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ghast/database/DataAccessException.java | 9 --------- .../ghast/database/EmptyResultDataAccessException.java | 8 -------- .../database/IncorrectResultSizeDataAccessException.java | 8 -------- 3 files changed, 25 deletions(-) delete mode 100644 src/main/java/ghast/database/EmptyResultDataAccessException.java delete mode 100644 src/main/java/ghast/database/IncorrectResultSizeDataAccessException.java diff --git a/src/main/java/ghast/database/DataAccessException.java b/src/main/java/ghast/database/DataAccessException.java index 5c686b5..445a104 100644 --- a/src/main/java/ghast/database/DataAccessException.java +++ b/src/main/java/ghast/database/DataAccessException.java @@ -8,15 +8,6 @@ public class DataAccessException extends RuntimeException { private String sql; - public DataAccessException(String msg) { - super(msg); - } - - public DataAccessException(String msg, String sql) { - this(msg); - this.sql = sql; - } - public DataAccessException(String msg, Throwable cause) { super(msg, cause); } diff --git a/src/main/java/ghast/database/EmptyResultDataAccessException.java b/src/main/java/ghast/database/EmptyResultDataAccessException.java deleted file mode 100644 index 0d42ee1..0000000 --- a/src/main/java/ghast/database/EmptyResultDataAccessException.java +++ /dev/null @@ -1,8 +0,0 @@ -package ghast.database; - -public class EmptyResultDataAccessException extends IncorrectResultSizeDataAccessException { - - public EmptyResultDataAccessException(int expectedSize) { - super(expectedSize); - } -} diff --git a/src/main/java/ghast/database/IncorrectResultSizeDataAccessException.java b/src/main/java/ghast/database/IncorrectResultSizeDataAccessException.java deleted file mode 100644 index 5acd10d..0000000 --- a/src/main/java/ghast/database/IncorrectResultSizeDataAccessException.java +++ /dev/null @@ -1,8 +0,0 @@ -package ghast.database; - -public class IncorrectResultSizeDataAccessException extends DataAccessException { - - public IncorrectResultSizeDataAccessException(int expectedSize) { - super("Incorrect result size: expected " + expectedSize); - } -} From 1c1075e2dcfeea5e13bfe43a6e9e1aac19aa32b1 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Mon, 4 Jan 2021 02:17:44 +0300 Subject: [PATCH 04/13] add README.MD --- README.MD | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 README.MD diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..4f8b65a --- /dev/null +++ b/README.MD @@ -0,0 +1,156 @@ +# GHAST TOOLS + +Набор вспомогательных инструментов для Bukkit API. +_Основан на версии Bukkit API 1.12._ + +## Использование + +Перед началом использования, необходимо в вашем Bukkit-плагине прописать подобный код: + +```java +void onLoad() { + GhastTools.setPlugin(this); +} +``` + +Это необходимо сделать, т.к. весь инструментарий основан на статических (static) методах. + +Все методы данного набора инструментов объеденены в классы, выполняющие роль группировщиков. + +### GhastTools + +Методы общего назначения или без определённой группировки. + +#### loadConfig + +Загрузка файла настроек плагина - `config.yml`. + +```java +YamlConfiguration config = GhastTools.loadConfig(); +``` + +По-умолчанию "гаст" пытается файл найти в папке плагина - `getDataFolder()`. +Если файла там нет, то выгружает встроенный (имеющийся в `.jar` файле плагина) в эту папку и загружает его. + +```java +YamlConfiguration config = GhastTools.loadConfig(false); +``` + +Если передать параметр `false`, то при отсутствии файла `config.yml` в папке плагина, +будет загруден исключительно встроенный файл настроек. + +### AssetsManager + +Методы по работе с файлами плагина (_"ассетами"_). + +У каждой группы методов один и тот же набор входных параметров: + +- `resourceName` - наименование и путь к файлу в папке плагина +- `defaultResourceName` - наименование и путь к файлу в плагине. + _Опционально. По-умолчанию равнен `resourceName`_ +- `saveDefault` - необходимость скопировать содержимое файла из `defaultResourceName` в файл `resourceName`. + _Опционально. По-умолчанию равен `true`_ + +Правила поиска файлов так же одинаков для каждой группы: + +- В начале файл ищется в папке плагина +- Если файл отсутствует в папке плагина, то... + - если `defaultResourceName` не равен `null`... + - если `saveDefault` равен `true`, то файл из плагина будет выгружен в папку плагина и от туда загружен в память. + - если `saveDefault` равен `false`, то данные будут взяты из файлв в плагине. + - если `defaultResourceName` равен `null`, то будет брошено исключение `AssetsException` с описанием ошибки вида "Файл X не найден". + +#### getAsInputStream + +```java +InputStream inputStream = AssetsManager.getAsInputStream("translate.ru.yml", "translate.yml", false); +``` + +#### getAsReader + +```java +Reader reader = AssetsManager.getAsReader("translate.ru.yml", "translate.yml", false); +``` + +#### getAsString + +```java +String string = AssetsManager.getAsString("readme.txt", "readme.txt", StandardCharsets.UTF_8, false); +``` + +У этой группы есть дополнительный _опциональный_ параметр - `charset` - в котором указывается кодиривка получаемой строки. +_По-умолчанию равен `StandardCharsets.UTF_8`_ + +### BuildHelper + +Набор методов облегчающих размецение объектов на карте. + +#### placeSkull + +```java +Location location = ...; +Skull skull = BuildHelper.placeSkull(location, BlockFace.NORTH) +``` + +#### placeSignWall + +```java +Location location = ...; +Sign signWall = BuildHelper.placeSignWall(location, BlockFace.NORTH) +``` + +### CommandManager + +Регистрация комманд. + +Имеется два варианта использования: упрощённый + +```java +CommandManager.register("start", (sender, args) -> sender.sendMessage("hello!")); +``` + +и подробный: + +```java +CommandManager.create("start") + .useOnlyPlayer() + .executer((sender, args) -> sender.sendMessage("hello!")) + .register(); +``` + +_TODO добавить описание подробного режима_ + +## Подключение + +### Gradle + +```groovy +repositories { + maven { url 'https://dmx-mc-project.gitlab.io/maven-repository/' } +} +``` + +```groovy +implementation group: 'ghast', name: 'ghast-tools', version: '1.9' +``` + +### Maven + +```xml + + + dmx-mc-project + https://dmx-mc-project.gitlab.io/maven-repository/ + + +``` + +```xml + + + ghast + ghast-tools + 1.9 + + +``` \ No newline at end of file From 8e20d3122749869bee2a7343aae0fff00b417bc9 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 17:13:15 +0300 Subject: [PATCH 05/13] update README.MD --- README.MD | 372 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 370 insertions(+), 2 deletions(-) diff --git a/README.MD b/README.MD index 4f8b65a..13233ca 100644 --- a/README.MD +++ b/README.MD @@ -101,7 +101,7 @@ Sign signWall = BuildHelper.placeSignWall(location, BlockFace.NORTH) ### CommandManager -Регистрация комманд. +Регистрация команд. Имеется два варианта использования: упрощённый @@ -118,7 +118,375 @@ CommandManager.create("start") .register(); ``` -_TODO добавить описание подробного режима_ +#### register + +Упрощенная регистрация команды. Указывается лишь название команды и исполнитель. + +```java +CommandManager.register("start", (sender, args) -> sender.sendMessage("hello!")); +``` + +#### create + +Конструктор для подробного варианта регистрации команды. + +```java +CommandManager.Builder builder = CommandManager.create("start"); +``` + +#### executer + +Указание исполнителя для команды + +```java +CommandManager.Builder builder = CommandManager.create("start") + .executer((sender, args) -> sender.sendMessage("hello!")); +``` + +#### onError + +Обработчик исключений + +```java +CommandManager.Builder builder = CommandManager.create("start") + .onError((sender, commandName, args, exception) -> { + sender.sendMessage(ChatColor.RED + "Произошла ошибка при выполнении команды '" + commandName + "'."); + exception.printStackTrace(); + }); +``` + +#### useOnlyPlayer + +Указание, что данную команду могут использовать только Игроки. +Опционально можно указать сообщение, которое будет выводиться в консоль. +_Отменяет действие указателя `useOnlyConsole`_ + +```java +CommandManager.Builder builder = CommandManager.create("start") + .useOnlyPlayer("Команду могут использовать только игроки"); +``` + +#### useOnlyConsole + +Указание, что данную команду можно использовать только в консоле. +Опционально можно указать сообщение, которое будет выводиться Игроку. +_Отменяет действие указателя `useOnlyPlayer`_ + +```java +CommandManager.Builder builder = CommandManager.create("start") + .useOnlyConsole(ChatColor.RED + "Команду можно использовать только в консоли"); +``` + +#### register + +Регистрация описанной в Конструкторе команды. + +```java +CommandManager.create("start") + .useOnlyPlayer() + .executer((sender, args) -> sender.sendMessage("hello!")) + .register(); +``` + +### EffectsHelper + +Набор методов для работы с эффектами. + +#### playSound + +Воспроизвести звук. + +```java +Location location = ...; +EffectsHelper.playSound(location, Sound.AMBIENT_CAVE, 1.0f); +``` + +#### particle + +Создание частиц. + +```java +Location location = ...; +EffectsHelper.particle(location, Particle.REDSTONE, 1.0d, 1.0d, 1.0d, 1.0d, 5); +``` + +### EventContext + +Регистрация группы обработчиков событий, объединённых общим условием выполнения. + +```java +EventContext.create() + .filter(() -> Bukkit.getOnlinePlayers().size() > 10) + .onEvent(PlayerJoinEvent.class, event -> { event.getPlayer().kickPlayer("Max players"); }); +``` + +#### create + +Создание контекста событий. + +```java +EventContext eventContext = EventContext.create(); +``` + +#### filter + +Условие, при котором будут срабатывать обработчики событий в данном контексте. + +```java +EventContext.create() + .filter(() -> Bukkit.getOnlinePlayers().size() > 10) +``` + +#### onEvent + +Указание события и его обработчика. +_Обработчик события регистрируется сразу же._ + +```java +EventContext.create() + .filter(() -> Bukkit.getOnlinePlayers().size() > 10) + .onEvent(PlayerJoinEvent.class, event -> event.getPlayer().kickPlayer("Max players")); +``` + +#### cancelEvent + +Отменить событие. +_Обработчик события регистрируется сразу же._ + +```java +EventContext.create() + .cancelEvent(BlockPlaceEvent.class); +``` + +эквивалентен коду: + +```java +EventContext.create() + .onEvent(BlockPlaceEvent.class, event -> event.setCancelled(true)) +``` + +### JdbcTemplate + +Инструмент для упрощения работы с SQL базами данных, работающими через JDBC. + +Для начала потребуется создать объект `DataSource` + +```java +// На примере MySQL +MysqlDataSource dataSource = new MysqlDataSource(); +dataSource.setServerName("localhost"); +dataSource.setPort(3306); +dataSource.setCharacterEncoding(StandardCharsets.UTF_8.name()); +dataSource.setDatabaseName("MyDataBase"); +dataSource.setUser("root"); +dataSource.setPassword("secret"); +``` + +После чего создать `JdbcTemplate` + +```java +JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); +``` + +#### execute + +Выполнение SQL запроса без последующей обработки результатов выполнения. + +```java +jdbcTemplate.execute("CREATE TABLE my_table (id int, name varchar(16));"); +``` + +#### query + +Выполнение SQL запроса и обработка его результатов. +Может возвращать любой тип объектов. + +```java +String name = jdbcTemplate.query("SELECT name FROM my_table LIMIT 0,1", resultSet -> { + if (resultSet.next()) { + return resultSet.getString("name"); + } else { + return null; + } +}); +``` + +```java +List names = jdbcTemplate.query("SELECT name FROM my_table", resultSet -> { + if (resultSet.next()) { + List list = new ArrayList<>(); + do { + list.add(resultSet.getString("name")); + } while (resultSet.next()); + return list; + } else { + return Collections.emptyList(); + } +}); +``` + +#### queryOne + +Выполнение SQL запроса с расчетом, что результат будет единичным либо не будет вовсе. +Возвращает `Optional`. + +```java +Optional optName = jdbcTemplate.queryOne("SELECT name FROM my_table WHERE name LIKE 'dmitriymx'", rs -> rs.getString("name")); +``` + +#### queryList + +Выполнение SQL запроса и обработка результата как списка данных. +Возвращает `List`. + +```java +List names = jdbcTemplate.queryList("SELECT name FROM my_table", (resultSet, rowNum) -> resultSet.getString("name")); +``` + +#### queryForMap + +Выполнение SQL запроса с расчетом, что результат будет единичным либо не будет вовсе. +Возвращает `Map`, где ключ — это наименование колонок таблицы, а значения — это значения в ячейках таблицы. + +```java +Map map = jdbcTemplate.queryForMap("SELECT * FROM my_table LIMIT 0,1;"); +``` + +#### queryForMapList + +Выполнение SQL запроса и обработка результата как списка данных. +Возвращает `List>`, где ключ — это наименование колонок таблицы, а значения — это значения в ячейках таблицы. + +```java +List> mapList = jdbcTemplate.queryForMapList("SELECT * FROM my_table"); +``` + +#### update + +Выполнение SQL запроса где будет происходить обновление данных в таблице. +Под "обновлением" подразумеваются любые изменения в таблице: `UPDATE`, `DELETE`, `INSERT`. +Возвращает число строк, которые были _по факту обновлены_ в таблице. + +```java +int rows = jdbcTemplate.update("DELETE FROM my_table WHERE name LIKE 'dmitriymx';"); +``` + +### ScheduleManager + +Набор методов для создания параллельных задач, выполняющихся один раз или по рассписанию. + +#### createTask + +Создание конструктора задачи. + +```java +ScheduleManager.Builder builder = ScheduleManager.createTask(); +``` + +#### useBukkitScheduler + +Если задача будет взаимодействоватьс **Bukkit API** или необходима привязка задачи к _тикам_, +то необходимо использовать данный указатель. + +В ином случае, указатель не нужен. + +```java +ScheduleManager.Builder builder = ScheduleManager.createTask() + .useBukkitScheduler(); +``` + +#### after + +Указание, что задачу нужно выполнить не сразу, а с некоторой задержкой перед запуском. + +```java +ScheduleManager.Builder builder = ScheduleManager.createTask() + .after(5, TimeUnit.MINUTES); +``` + +#### every + +Указание, что задачу нужно повторять через указанное время. + +```java +ScheduleManager.Builder builder = ScheduleManager.createTask() + .every(5, TimeUnit.MINUTES); +``` + +#### create + +Создание описанной задачи. + +```java +ScheduleTask scheduleTask = ScheduleManager.createTask() + .every(1, TimeUnit.SECONDS) + .create(() -> Bukkit.getServer().getLogger().info("TimeMS: " + System.currentTimeMillis())); +``` + +_Задача будет только создана. Для её выполнения нужно вызвать `scheduleTask.start()`._ + +#### execute + +Создание и выполнение описанной задачи. + +```java +ScheduleTask scheduleTask = ScheduleManager.createTask() + .every(1, TimeUnit.SECONDS) + .execute(() -> Bukkit.getServer().getLogger().info("TimeMS: " + System.currentTimeMillis())); +``` + +### ScheduleTask + +Вспомогательный объект, созданный через `ScheduleManager`. Позволяет управлять созданной задачей. + +#### start + +Запускает задачу, если она еще не запущена. + +```java +ScheduleTask scheduleTask = ...; +scheduleTask.start(); +``` + +#### isCanceled + +Возвращает состояние задачи. Если `true`, значит задача была или _отменена/остоновлена_ или была завершена. + +```java +ScheduleTask scheduleTask = ...; +boolean status = scheduleTask.isCanceled(); +``` + +#### cancel + +Отменяет/Остонавливает выполнение задачи. + +```java +ScheduleTask scheduleTask = ...; +scheduleTask.cancel(); +``` + +### I18n + +TODO + +#### loadMessages + +TODO + +#### get + +TODO + +#### paramBuilder + +TODO + +### XLog + +TODO + +--- ## Подключение From d63b9a085c7617700d7ef202e61b1583631afdff Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 17:28:51 +0300 Subject: [PATCH 06/13] update README.MD --- README.MD | 119 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/README.MD b/README.MD index 13233ca..ff178fe 100644 --- a/README.MD +++ b/README.MD @@ -1,9 +1,28 @@ # GHAST TOOLS +![version: 1.9](https://img.shields.io/badge/version-1.9-0a0.svg?style=flat) +![bukkit-api: 1.12](https://img.shields.io/badge/bukkit--api-1.12-d50.svg?style=flat) + Набор вспомогательных инструментов для Bukkit API. _Основан на версии Bukkit API 1.12._ -## Использование +--- + +1. [Перед использованием](#перед_использованием) +2. [GhastTools](#ghasttools) +3. [AssetsManager](#assetsmanager) +4. [BuildHelper](#buildhelper) +5. [CommandManager](#commandmanager) +6. [EffectsHelper](#effectshelper) +7. [EventContext](#eventcontext) +8. [JdbcTemplate](#jdbctemplate) +9. [ScheduleManager](#schedulemanager) +10. [ScheduleTask](#scheduletask) +11. [I18n](#i18n) +12. [XLog](#xlog) +--- + +## Перед использованием Перед началом использования, необходимо в вашем Bukkit-плагине прописать подобный код: @@ -17,11 +36,11 @@ void onLoad() { Все методы данного набора инструментов объеденены в классы, выполняющие роль группировщиков. -### GhastTools +## GhastTools Методы общего назначения или без определённой группировки. -#### loadConfig +### loadConfig Загрузка файла настроек плагина - `config.yml`. @@ -39,7 +58,7 @@ YamlConfiguration config = GhastTools.loadConfig(false); Если передать параметр `false`, то при отсутствии файла `config.yml` в папке плагина, будет загруден исключительно встроенный файл настроек. -### AssetsManager +## AssetsManager Методы по работе с файлами плагина (_"ассетами"_). @@ -60,19 +79,19 @@ YamlConfiguration config = GhastTools.loadConfig(false); - если `saveDefault` равен `false`, то данные будут взяты из файлв в плагине. - если `defaultResourceName` равен `null`, то будет брошено исключение `AssetsException` с описанием ошибки вида "Файл X не найден". -#### getAsInputStream +### getAsInputStream ```java InputStream inputStream = AssetsManager.getAsInputStream("translate.ru.yml", "translate.yml", false); ``` -#### getAsReader +### getAsReader ```java Reader reader = AssetsManager.getAsReader("translate.ru.yml", "translate.yml", false); ``` -#### getAsString +### getAsString ```java String string = AssetsManager.getAsString("readme.txt", "readme.txt", StandardCharsets.UTF_8, false); @@ -81,25 +100,25 @@ String string = AssetsManager.getAsString("readme.txt", "readme.txt", StandardCh У этой группы есть дополнительный _опциональный_ параметр - `charset` - в котором указывается кодиривка получаемой строки. _По-умолчанию равен `StandardCharsets.UTF_8`_ -### BuildHelper +## BuildHelper Набор методов облегчающих размецение объектов на карте. -#### placeSkull +### placeSkull ```java Location location = ...; Skull skull = BuildHelper.placeSkull(location, BlockFace.NORTH) ``` -#### placeSignWall +### placeSignWall ```java Location location = ...; Sign signWall = BuildHelper.placeSignWall(location, BlockFace.NORTH) ``` -### CommandManager +## CommandManager Регистрация команд. @@ -118,7 +137,7 @@ CommandManager.create("start") .register(); ``` -#### register +### register Упрощенная регистрация команды. Указывается лишь название команды и исполнитель. @@ -126,7 +145,7 @@ CommandManager.create("start") CommandManager.register("start", (sender, args) -> sender.sendMessage("hello!")); ``` -#### create +### create Конструктор для подробного варианта регистрации команды. @@ -134,7 +153,7 @@ CommandManager.register("start", (sender, args) -> sender.sendMessage("hello!")) CommandManager.Builder builder = CommandManager.create("start"); ``` -#### executer +### executer Указание исполнителя для команды @@ -143,7 +162,7 @@ CommandManager.Builder builder = CommandManager.create("start") .executer((sender, args) -> sender.sendMessage("hello!")); ``` -#### onError +### onError Обработчик исключений @@ -155,7 +174,7 @@ CommandManager.Builder builder = CommandManager.create("start") }); ``` -#### useOnlyPlayer +### useOnlyPlayer Указание, что данную команду могут использовать только Игроки. Опционально можно указать сообщение, которое будет выводиться в консоль. @@ -166,7 +185,7 @@ CommandManager.Builder builder = CommandManager.create("start") .useOnlyPlayer("Команду могут использовать только игроки"); ``` -#### useOnlyConsole +### useOnlyConsole Указание, что данную команду можно использовать только в консоле. Опционально можно указать сообщение, которое будет выводиться Игроку. @@ -177,7 +196,7 @@ CommandManager.Builder builder = CommandManager.create("start") .useOnlyConsole(ChatColor.RED + "Команду можно использовать только в консоли"); ``` -#### register +### register Регистрация описанной в Конструкторе команды. @@ -188,11 +207,11 @@ CommandManager.create("start") .register(); ``` -### EffectsHelper +## EffectsHelper Набор методов для работы с эффектами. -#### playSound +### playSound Воспроизвести звук. @@ -201,7 +220,7 @@ Location location = ...; EffectsHelper.playSound(location, Sound.AMBIENT_CAVE, 1.0f); ``` -#### particle +### particle Создание частиц. @@ -210,7 +229,7 @@ Location location = ...; EffectsHelper.particle(location, Particle.REDSTONE, 1.0d, 1.0d, 1.0d, 1.0d, 5); ``` -### EventContext +## EventContext Регистрация группы обработчиков событий, объединённых общим условием выполнения. @@ -220,7 +239,7 @@ EventContext.create() .onEvent(PlayerJoinEvent.class, event -> { event.getPlayer().kickPlayer("Max players"); }); ``` -#### create +### create Создание контекста событий. @@ -228,7 +247,7 @@ EventContext.create() EventContext eventContext = EventContext.create(); ``` -#### filter +### filter Условие, при котором будут срабатывать обработчики событий в данном контексте. @@ -237,7 +256,7 @@ EventContext.create() .filter(() -> Bukkit.getOnlinePlayers().size() > 10) ``` -#### onEvent +### onEvent Указание события и его обработчика. _Обработчик события регистрируется сразу же._ @@ -248,7 +267,7 @@ EventContext.create() .onEvent(PlayerJoinEvent.class, event -> event.getPlayer().kickPlayer("Max players")); ``` -#### cancelEvent +### cancelEvent Отменить событие. _Обработчик события регистрируется сразу же._ @@ -265,7 +284,7 @@ EventContext.create() .onEvent(BlockPlaceEvent.class, event -> event.setCancelled(true)) ``` -### JdbcTemplate +## JdbcTemplate Инструмент для упрощения работы с SQL базами данных, работающими через JDBC. @@ -288,7 +307,7 @@ dataSource.setPassword("secret"); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); ``` -#### execute +### execute Выполнение SQL запроса без последующей обработки результатов выполнения. @@ -296,7 +315,7 @@ JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); jdbcTemplate.execute("CREATE TABLE my_table (id int, name varchar(16));"); ``` -#### query +### query Выполнение SQL запроса и обработка его результатов. Может возвращать любой тип объектов. @@ -325,7 +344,7 @@ List names = jdbcTemplate.query("SELECT name FROM my_table", resultSet - }); ``` -#### queryOne +### queryOne Выполнение SQL запроса с расчетом, что результат будет единичным либо не будет вовсе. Возвращает `Optional`. @@ -334,7 +353,7 @@ List names = jdbcTemplate.query("SELECT name FROM my_table", resultSet - Optional optName = jdbcTemplate.queryOne("SELECT name FROM my_table WHERE name LIKE 'dmitriymx'", rs -> rs.getString("name")); ``` -#### queryList +### queryList Выполнение SQL запроса и обработка результата как списка данных. Возвращает `List`. @@ -343,7 +362,7 @@ Optional optName = jdbcTemplate.queryOne("SELECT name FROM my_table WHER List names = jdbcTemplate.queryList("SELECT name FROM my_table", (resultSet, rowNum) -> resultSet.getString("name")); ``` -#### queryForMap +### queryForMap Выполнение SQL запроса с расчетом, что результат будет единичным либо не будет вовсе. Возвращает `Map`, где ключ — это наименование колонок таблицы, а значения — это значения в ячейках таблицы. @@ -352,7 +371,7 @@ List names = jdbcTemplate.queryList("SELECT name FROM my_table", (result Map map = jdbcTemplate.queryForMap("SELECT * FROM my_table LIMIT 0,1;"); ``` -#### queryForMapList +### queryForMapList Выполнение SQL запроса и обработка результата как списка данных. Возвращает `List>`, где ключ — это наименование колонок таблицы, а значения — это значения в ячейках таблицы. @@ -361,7 +380,7 @@ Map map = jdbcTemplate.queryForMap("SELECT * FROM my_table LIMIT List> mapList = jdbcTemplate.queryForMapList("SELECT * FROM my_table"); ``` -#### update +### update Выполнение SQL запроса где будет происходить обновление данных в таблице. Под "обновлением" подразумеваются любые изменения в таблице: `UPDATE`, `DELETE`, `INSERT`. @@ -371,11 +390,11 @@ List> mapList = jdbcTemplate.queryForMapList("SELECT * FROM int rows = jdbcTemplate.update("DELETE FROM my_table WHERE name LIKE 'dmitriymx';"); ``` -### ScheduleManager +## ScheduleManager Набор методов для создания параллельных задач, выполняющихся один раз или по рассписанию. -#### createTask +### createTask Создание конструктора задачи. @@ -383,7 +402,7 @@ int rows = jdbcTemplate.update("DELETE FROM my_table WHERE name LIKE 'dmitriymx' ScheduleManager.Builder builder = ScheduleManager.createTask(); ``` -#### useBukkitScheduler +### useBukkitScheduler Если задача будет взаимодействоватьс **Bukkit API** или необходима привязка задачи к _тикам_, то необходимо использовать данный указатель. @@ -395,7 +414,7 @@ ScheduleManager.Builder builder = ScheduleManager.createTask() .useBukkitScheduler(); ``` -#### after +### after Указание, что задачу нужно выполнить не сразу, а с некоторой задержкой перед запуском. @@ -404,7 +423,7 @@ ScheduleManager.Builder builder = ScheduleManager.createTask() .after(5, TimeUnit.MINUTES); ``` -#### every +### every Указание, что задачу нужно повторять через указанное время. @@ -413,7 +432,7 @@ ScheduleManager.Builder builder = ScheduleManager.createTask() .every(5, TimeUnit.MINUTES); ``` -#### create +### create Создание описанной задачи. @@ -425,7 +444,7 @@ ScheduleTask scheduleTask = ScheduleManager.createTask() _Задача будет только создана. Для её выполнения нужно вызвать `scheduleTask.start()`._ -#### execute +### execute Создание и выполнение описанной задачи. @@ -435,11 +454,11 @@ ScheduleTask scheduleTask = ScheduleManager.createTask() .execute(() -> Bukkit.getServer().getLogger().info("TimeMS: " + System.currentTimeMillis())); ``` -### ScheduleTask +## ScheduleTask Вспомогательный объект, созданный через `ScheduleManager`. Позволяет управлять созданной задачей. -#### start +### start Запускает задачу, если она еще не запущена. @@ -448,7 +467,7 @@ ScheduleTask scheduleTask = ...; scheduleTask.start(); ``` -#### isCanceled +### isCanceled Возвращает состояние задачи. Если `true`, значит задача была или _отменена/остоновлена_ или была завершена. @@ -457,7 +476,7 @@ ScheduleTask scheduleTask = ...; boolean status = scheduleTask.isCanceled(); ``` -#### cancel +### cancel Отменяет/Остонавливает выполнение задачи. @@ -466,23 +485,23 @@ ScheduleTask scheduleTask = ...; scheduleTask.cancel(); ``` -### I18n +## I18n TODO -#### loadMessages +### loadMessages TODO -#### get +### get TODO -#### paramBuilder +### paramBuilder TODO -### XLog +## XLog TODO From 9929b0af189913e08711b1e3781a2f62f2b36972 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 17:29:36 +0300 Subject: [PATCH 07/13] fix README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index ff178fe..097649d 100644 --- a/README.MD +++ b/README.MD @@ -8,7 +8,7 @@ _Основан на версии Bukkit API 1.12._ --- -1. [Перед использованием](#перед_использованием) +1. [Перед использованием](#перед-использованием) 2. [GhastTools](#ghasttools) 3. [AssetsManager](#assetsmanager) 4. [BuildHelper](#buildhelper) From 1e529d9d55c0942ae76b8aaa7f7dc8728417cf37 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 17:40:43 +0300 Subject: [PATCH 08/13] update README.MD --- README.MD | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/README.MD b/README.MD index 097649d..19d681b 100644 --- a/README.MD +++ b/README.MD @@ -6,20 +6,24 @@ Набор вспомогательных инструментов для Bukkit API. _Основан на версии Bukkit API 1.12._ ---- +## Содержание 1. [Перед использованием](#перед-использованием) -2. [GhastTools](#ghasttools) -3. [AssetsManager](#assetsmanager) -4. [BuildHelper](#buildhelper) -5. [CommandManager](#commandmanager) -6. [EffectsHelper](#effectshelper) -7. [EventContext](#eventcontext) -8. [JdbcTemplate](#jdbctemplate) -9. [ScheduleManager](#schedulemanager) -10. [ScheduleTask](#scheduletask) -11. [I18n](#i18n) -12. [XLog](#xlog) +2. [GhastTools](#ghasttools) +3. [AssetsManager](#assetsmanager) +4. [BuildHelper](#buildhelper) +5. [CommandManager](#commandmanager) +6. [EffectsHelper](#effectshelper) +7. [EventContext](#eventcontext) +8. [JdbcTemplate](#jdbctemplate) +9. [ScheduleManager](#schedulemanager) +10. [ScheduleTask](#scheduletask) +11. [I18n](#i18n) +12. [XLog](#xlog) +13. [Подключение](#подключение) + 1. [Gradle](#gradle) + 2. [Maven](#maven) + --- ## Перед использованием From b1615e258e13412497ee5dc80f0c8d33e9db9902 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 18:17:27 +0300 Subject: [PATCH 09/13] update README.MD --- README.MD | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/README.MD b/README.MD index 19d681b..dc9456c 100644 --- a/README.MD +++ b/README.MD @@ -491,23 +491,110 @@ scheduleTask.cancel(); ## I18n -TODO +Инструмент для работы с мультиязыковыми сообщениями или просто сообщениями, которые храняться в отдельном файле. + +Позволяет использовать шаблонизированные сообщения вида `Привет, {player}!`. ### loadMessages -TODO +Загрузка сообщений в инструмент. + +Передать можно как "мапу" с перечислением ключ-сообщение, так и `Reader` на файл в формате `key=message` (как у `Properties`). + +```java +Map messagesMap = ...; +I18n.loadMessages(messagesMap); +``` + +```java +Reader reader = AssetsManager.getAsReader("messages.properties"); +I18n.loadMessages(reader); +``` + +В первом параметре можно указать код языка, для которого загружаются сообщения. По-умолчанию будет "en". + +```java +Map enMessagesMap = ...; +Map ruMessagesMap = ...; + +I18n.loadMessages("en", enMessagesMap); +I18n.loadMessages("ru", ruMessagesMap); +``` + +```java +Reader readerEn = AssetsManager.getAsReader("messages.properties"); +Reader readerRu = AssetsManager.getAsReader("messages.ru.properties"); + +I18n.loadMessages("en", readerEn); +I18n.loadMessages("ru", readerRu); +``` ### get -TODO +Получение сообщения по его ключу. + +```java +String msg = I18n.get("player.join.msg"); +``` + +Если следующим сообщением указать `Map`, то можно будет воспользоваться шаблонизатором. + +```java +Map messagesMap = new HashMap<>(); +messagesMap.put("player.join.msg", "Привет, {player}!"); + +I18n.loadMessages(messagesMap); + +Map params = new HashMap<>(); +params.put("player", event.getPlayer().getName()); + +String msg = I18n.get("player.join.msg", params); +``` + +Однако можно создавать `Map params` явно, а воспользоваться [paramBuilder()](#paramBuilder) + +```java +String msg = I18n.get("player.join.msg", I18n.paramBuilder() + .add("player", event.getPlayer().getName()) + .build()); +``` + +Можно первым параметром указать код языка. + +```java +String msg = I18n.get("ru", "player.join.msg"); +``` ### paramBuilder -TODO +Инструмент для параметизирования шаблонов сообщений. + +```java +Map params = I18n.paramBuilder() + .add("player", event.getPlayer().getName()) + .build(); +String msg = I18n.get("player.join.msg", params); +``` ## XLog -TODO +Замена станрадтному `getLogger()`, который использует `java.utils.Logger` и не всегда удобен для логирования. + +Имеет 4 уровня логирования: `debug`, `info`, `warning`, `error`. + +Сообщения могут быть шаблонизированными. Синтаксис шаблонов — `java.text.MessageFormat`. + +Примеры: + +```java +XLog.info("Hello"); +XLog.info("Player {0} join game", event.getPlayer().getName()); + +XLog.error("ERROR!", exception); +XLog.error("ERROR: {0}", exception.getMessage()); +XLog.error("ERROR {0} in Event {1}: {2}", exception.getClass(), event.getClass(), exception.getMessage()); +XLog.error("ERROR: {0}", exception.getMessage(), exception); +``` --- From 0a648b7a5da734786b86fbd6aab9b0080b66a73c Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 18:18:29 +0300 Subject: [PATCH 10/13] fix README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index dc9456c..284d59c 100644 --- a/README.MD +++ b/README.MD @@ -551,7 +551,7 @@ params.put("player", event.getPlayer().getName()); String msg = I18n.get("player.join.msg", params); ``` -Однако можно создавать `Map params` явно, а воспользоваться [paramBuilder()](#paramBuilder) +Однако можно создавать `Map params` явно, а воспользоваться [paramBuilder()](#parambuilder) ```java String msg = I18n.get("player.join.msg", I18n.paramBuilder() From 897045b8d26e13de2c01b97ad301ca5114487928 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 18:20:09 +0300 Subject: [PATCH 11/13] fix README.MD --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 284d59c..08c317f 100644 --- a/README.MD +++ b/README.MD @@ -578,7 +578,7 @@ String msg = I18n.get("player.join.msg", params); ## XLog -Замена станрадтному `getLogger()`, который использует `java.utils.Logger` и не всегда удобен для логирования. +Замена стандартному `getLogger()`, который использует `java.utils.Logger` и не всегда удобен для логирования. Имеет 4 уровня логирования: `debug`, `info`, `warning`, `error`. From 89bca95d9f50281ee69b03788cba542b6e8c5160 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 18:22:31 +0300 Subject: [PATCH 12/13] update README.MD --- README.MD | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.MD b/README.MD index 08c317f..4972c77 100644 --- a/README.MD +++ b/README.MD @@ -592,7 +592,9 @@ XLog.info("Player {0} join game", event.getPlayer().getName()); XLog.error("ERROR!", exception); XLog.error("ERROR: {0}", exception.getMessage()); -XLog.error("ERROR {0} in Event {1}: {2}", exception.getClass(), event.getClass(), exception.getMessage()); +// Для экранирования "{" нужно перед ней поставить "'". +// А для использования "'" нужно их дублировать. +XLog.error("ERROR ''{0}'' in Event '{{1}'}: {2}", exception.getClass(), event.getClass(), exception.getMessage()); XLog.error("ERROR: {0}", exception.getMessage(), exception); ``` From c47bb2093e43dfafaaf1d18330a875de2a600377 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Tue, 5 Jan 2021 19:03:21 +0300 Subject: [PATCH 13/13] =?UTF-8?q?=D1=83=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B5=D0=BD=D1=83=D0=B6=D0=BD=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.gradle b/build.gradle index 9eb2d6b..0804fb1 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,6 @@ ext { commons_text: 'org.apache.commons:commons-text:1.9', lombok: 'org.projectlombok:lombok:1.18.12', reflection_object: 'ru.dmitriymx:reflection-object:1.0-BETA', - mysql: 'mysql:mysql-connector-java:8.0.22', test: [ junit5: [ "org.junit.jupiter:junit-jupiter-api:$junitVersion", @@ -66,7 +65,6 @@ dependencies { annotationProcessor libs.lombok compileOnly2 libs.bukkit - compileOnly libs.mysql implementation libs.commons_text implementation libs.reflection_object