From a871175d380e0d955c014a01aac76b5789522418 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 01:03:50 +0300 Subject: [PATCH 01/20] XLog -> BukkitLogger --- src/main/java/ghast/XLog.java | 4 + src/main/java/ghast/logger/BukkitLogger.java | 42 +++ .../java/ghast/logger/FormattingPair.java | 19 ++ src/main/java/ghast/logger/LoggerAdapter.java | 37 +++ .../java/ghast/logger/LoggerFormatter.java | 59 +++++ .../java/ghast/logger/StringFormatter.java | 240 ++++++++++++++++++ 6 files changed, 401 insertions(+) create mode 100644 src/main/java/ghast/logger/BukkitLogger.java create mode 100644 src/main/java/ghast/logger/FormattingPair.java create mode 100644 src/main/java/ghast/logger/LoggerAdapter.java create mode 100644 src/main/java/ghast/logger/LoggerFormatter.java create mode 100644 src/main/java/ghast/logger/StringFormatter.java diff --git a/src/main/java/ghast/XLog.java b/src/main/java/ghast/XLog.java index b0f83fb..07b08cb 100644 --- a/src/main/java/ghast/XLog.java +++ b/src/main/java/ghast/XLog.java @@ -6,8 +6,12 @@ import java.util.logging.Level; import static java.text.MessageFormat.format; +/** + * @deprecated use {@link ghast.logger.BukkitLogger} + */ @UtilityClass @SuppressWarnings("unused") +@Deprecated public class XLog { //region Debug diff --git a/src/main/java/ghast/logger/BukkitLogger.java b/src/main/java/ghast/logger/BukkitLogger.java new file mode 100644 index 0000000..e75728f --- /dev/null +++ b/src/main/java/ghast/logger/BukkitLogger.java @@ -0,0 +1,42 @@ +package ghast.logger; + +import lombok.RequiredArgsConstructor; + +import java.util.logging.Level; +import java.util.logging.Logger; + +@RequiredArgsConstructor +public class BukkitLogger extends LoggerAdapter { + + private final Logger originallLogger; + + @Override + public void debug(String message) { + originallLogger.log(Level.CONFIG, message); + } + + @Override + public void debug(String message, Throwable throwable) { + originallLogger.log(Level.CONFIG, message, throwable); + } + + @Override + public void info(String message) { + originallLogger.log(Level.INFO, message); + } + + @Override + public void warn(String message) { + originallLogger.log(Level.WARNING, message); + } + + @Override + public void error(String message) { + originallLogger.log(Level.SEVERE, message); + } + + @Override + public void error(String message, Throwable throwable) { + originallLogger.log(Level.SEVERE, message, throwable); + } +} diff --git a/src/main/java/ghast/logger/FormattingPair.java b/src/main/java/ghast/logger/FormattingPair.java new file mode 100644 index 0000000..c8e67e3 --- /dev/null +++ b/src/main/java/ghast/logger/FormattingPair.java @@ -0,0 +1,19 @@ +package ghast.logger; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@RequiredArgsConstructor +@Getter +@ToString +public class FormattingPair { + + private final String message; + private final Throwable throwable; + + public FormattingPair(String message) { + this.message = message; + this.throwable = null; + } +} diff --git a/src/main/java/ghast/logger/LoggerAdapter.java b/src/main/java/ghast/logger/LoggerAdapter.java new file mode 100644 index 0000000..03c4685 --- /dev/null +++ b/src/main/java/ghast/logger/LoggerAdapter.java @@ -0,0 +1,37 @@ +package ghast.logger; + +public abstract class LoggerAdapter { + + public abstract void debug(String message); + public abstract void debug(String message, Throwable throwable); + public abstract void info(String message); + public abstract void warn(String message); + public abstract void error(String message); + public abstract void error(String message, Throwable throwable); + + public void debug(String pattern, Object... objects) { + FormattingPair formattingPair = LoggerFormatter.arrayFormat(pattern, objects); + if (formattingPair.getThrowable() != null) { + debug(formattingPair.getMessage(), formattingPair.getThrowable()); + } else { + debug(formattingPair.getMessage()); + } + } + + public void info(String pattern, Object... objects) { + info(StringFormatter.arrayFormat(pattern, objects)); + } + + public void warn(String pattern, Object... objects) { + warn(StringFormatter.arrayFormat(pattern, objects)); + } + + public void error(String pattern, Object... objects) { + FormattingPair formattingPair = LoggerFormatter.arrayFormat(pattern, objects); + if (formattingPair.getThrowable() != null) { + error(formattingPair.getMessage(), formattingPair.getThrowable()); + } else { + error(formattingPair.getMessage()); + } + } +} diff --git a/src/main/java/ghast/logger/LoggerFormatter.java b/src/main/java/ghast/logger/LoggerFormatter.java new file mode 100644 index 0000000..759498f --- /dev/null +++ b/src/main/java/ghast/logger/LoggerFormatter.java @@ -0,0 +1,59 @@ +package ghast.logger; + +/** + * Copy-Paste from org.slf4j.helpers.MessageFormatter + */ +public final class LoggerFormatter { + + public static FormattingPair arrayFormat(String messagePattern, Object[] argArray) { + Object[] args; + Throwable throwableCandidate = getThrowableCandidate(argArray); + if (throwableCandidate != null) { + args = trimmedCopy(argArray); + } else { + args = argArray; + } + + return arrayFormat(messagePattern, args, throwableCandidate); + } + + public static FormattingPair arrayFormat(String messagePattern, Object[] argArray, Throwable throwable) { + if (messagePattern == null) { + return new FormattingPair(null, throwable); + } + + if (argArray == null) { + return new FormattingPair(messagePattern); + } + + return new FormattingPair(StringFormatter.arrayFormat(messagePattern, argArray), throwable); + } + + private static Throwable getThrowableCandidate(Object[] argArray) { + if (argArray == null || argArray.length == 0) { + return null; + } + + Object lastEntry = argArray[argArray.length - 1]; + if (lastEntry instanceof Throwable) { + return (Throwable) lastEntry; + } + + return null; + } + + private static Object[] trimmedCopy(final Object[] argArray) { + if (argArray == null || argArray.length == 0) { + throw new IllegalStateException("non-sensical empty or null argument array"); + } + + int trimmedLen = argArray.length - 1; + Object[] trimmed = new Object[trimmedLen]; + + if (trimmedLen > 0) { + System.arraycopy(argArray, 0, trimmed, 0, trimmedLen); + } + + return trimmed; + } +} diff --git a/src/main/java/ghast/logger/StringFormatter.java b/src/main/java/ghast/logger/StringFormatter.java new file mode 100644 index 0000000..bde0513 --- /dev/null +++ b/src/main/java/ghast/logger/StringFormatter.java @@ -0,0 +1,240 @@ +package ghast.logger; + +import java.util.HashMap; +import java.util.Map; + +/** + * Copy-Paste from org.slf4j.helpers.MessageFormatter + */ +public final class StringFormatter { + private static final String EMPTY = ""; + private static final char DELIM_START = '{'; + private static final String DELIM_STR = "{}"; + private static final char ESCAPE_CHAR = '\\'; + + public static String arrayFormat(String messagePattern, Object[] argArray) { + if (messagePattern == null) { + return EMPTY; + } else if (argArray == null) { + return messagePattern; + } + + StringBuilder sb = new StringBuilder(messagePattern.length() + 50); + + int k = 0; + for (int i = 0; i < argArray.length; i++) { + int idx = messagePattern.indexOf(DELIM_STR, k); + + if (idx == -1) { + // no more variables + if (k == 0) { // this is a simple string + return messagePattern; + } else { // add the tail string which contains no variables and return + // the result. + sb.append(messagePattern, k, messagePattern.length()); + return sb.toString(); + } + } else { + if (isEscapedDelimeter(messagePattern, idx)) { + if (!isDoubleEscaped(messagePattern, idx)) { + i--; // DELIM_START was escaped, thus should not be incremented + sb.append(messagePattern, k, idx - 1); + sb.append(DELIM_START); + k = idx + 1; + } else { + // The escape character preceding the delimiter start is + // itself escaped: "abc x:\\{}" + // we have to consume one backward slash + sb.append(messagePattern, k, idx - 1); + deeplyAppendParameter(sb, argArray[i], new HashMap<>()); + k = idx + 2; + } + } else { + sb.append(messagePattern, k, idx); + deeplyAppendParameter(sb, argArray[i], new HashMap<>()); + k = idx + 2; + } + } + } + // append the characters following the last {} pair. + sb.append(messagePattern, k, messagePattern.length()); + return sb.toString(); + } + + private static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) { + if (delimeterStartIndex == 0) { + return false; + } + char potentialEscape = messagePattern.charAt(delimeterStartIndex - 1); + return potentialEscape == ESCAPE_CHAR; + } + + private static boolean isDoubleEscaped(String messagePattern, int delimeterStartIndex) { + return delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR; + } + + // special treatment of array values was suggested by 'lizongbo' + private static void deeplyAppendParameter(StringBuilder sbuf, Object o, Map seenMap) { + if (o == null) { + sbuf.append("null"); + return; + } + if (!o.getClass().isArray()) { + safeObjectAppend(sbuf, o); + } else { + // check for primitive array types because they + // unfortunately cannot be cast to Object[] + if (o instanceof boolean[]) { + booleanArrayAppend(sbuf, (boolean[]) o); + } else if (o instanceof byte[]) { + byteArrayAppend(sbuf, (byte[]) o); + } else if (o instanceof char[]) { + charArrayAppend(sbuf, (char[]) o); + } else if (o instanceof short[]) { + shortArrayAppend(sbuf, (short[]) o); + } else if (o instanceof int[]) { + intArrayAppend(sbuf, (int[]) o); + } else if (o instanceof long[]) { + longArrayAppend(sbuf, (long[]) o); + } else if (o instanceof float[]) { + floatArrayAppend(sbuf, (float[]) o); + } else if (o instanceof double[]) { + doubleArrayAppend(sbuf, (double[]) o); + } else { + objectArrayAppend(sbuf, (Object[]) o, seenMap); + } + } + } + + private static void safeObjectAppend(StringBuilder sbuf, Object o) { + try { + String oAsString = o.toString(); + sbuf.append(oAsString); + } catch (Throwable t) { + throw new RuntimeException("Failed toString() invocation on an object of type [" + o.getClass().getName() + "]", t); + } + } + + @SuppressWarnings("DuplicatedCode") + private static void booleanArrayAppend(StringBuilder sbuf, boolean[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void byteArrayAppend(StringBuilder sbuf, byte[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void charArrayAppend(StringBuilder sbuf, char[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void shortArrayAppend(StringBuilder sbuf, short[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void intArrayAppend(StringBuilder sbuf, int[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void longArrayAppend(StringBuilder sbuf, long[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void floatArrayAppend(StringBuilder sbuf, float[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + @SuppressWarnings("DuplicatedCode") + private static void doubleArrayAppend(StringBuilder sbuf, double[] a) { + sbuf.append('['); + int len = a.length; + for (int i = 0; i < len; i++) { + sbuf.append(a[i]); + if (i != len - 1) { + sbuf.append(", "); + } + } + sbuf.append(']'); + } + + private static void objectArrayAppend(StringBuilder sbuf, Object[] a, Map seenMap) { + sbuf.append('['); + if (!seenMap.containsKey(a)) { + seenMap.put(a, null); + int len = a.length; + for (int i = 0; i < len; i++) { + deeplyAppendParameter(sbuf, a[i], seenMap); + if (i != len - 1) { + sbuf.append(", "); + } + } + // allow repeats in siblings + seenMap.remove(a); + } else { + sbuf.append("..."); + } + sbuf.append(']'); + } +} From ba58bc463d1c1da20e719cd4af7a76c5db7d6dfb Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 01:45:02 +0300 Subject: [PATCH 02/20] add JaCoCo --- build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bc0e549..b6f9925 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'jacoco' } def publishScript = file(rootProject.getProjectDir().getPath() + '/publish.gradle') @@ -76,4 +77,12 @@ dependencies { test { useJUnitPlatform() -} \ No newline at end of file +} + +jacoco { + toolVersion = '0.8.5' +} + +jacocoTestReport { + dependsOn test +} From 41fe79875705c8938ee5675f294ddbffd6d45c15 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 01:45:30 +0300 Subject: [PATCH 03/20] test: StringFormatter --- .../java/ghast/logger/StringFormatter.java | 4 +- .../ghast/logger/StringFormatterTest.java | 95 +++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/test/java/ghast/logger/StringFormatterTest.java diff --git a/src/main/java/ghast/logger/StringFormatter.java b/src/main/java/ghast/logger/StringFormatter.java index bde0513..1e1f530 100644 --- a/src/main/java/ghast/logger/StringFormatter.java +++ b/src/main/java/ghast/logger/StringFormatter.java @@ -13,7 +13,7 @@ public final class StringFormatter { private static final char ESCAPE_CHAR = '\\'; public static String arrayFormat(String messagePattern, Object[] argArray) { - if (messagePattern == null) { + if (messagePattern == null || messagePattern.equals(EMPTY)) { return EMPTY; } else if (argArray == null) { return messagePattern; @@ -30,7 +30,7 @@ public final class StringFormatter { if (k == 0) { // this is a simple string return messagePattern; } else { // add the tail string which contains no variables and return - // the result. + // the result. sb.append(messagePattern, k, messagePattern.length()); return sb.toString(); } diff --git a/src/test/java/ghast/logger/StringFormatterTest.java b/src/test/java/ghast/logger/StringFormatterTest.java new file mode 100644 index 0000000..33ed046 --- /dev/null +++ b/src/test/java/ghast/logger/StringFormatterTest.java @@ -0,0 +1,95 @@ +package ghast.logger; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class StringFormatterTest { + + @Test + void emptyPattern() { + String actual = StringFormatter.arrayFormat(null, null); + assertEquals("", actual); + + actual = StringFormatter.arrayFormat("", null); + assertEquals("", actual); + } + + @Test + void nullArgArray() { + String pattern = "some pattern"; + String actual = StringFormatter.arrayFormat(pattern, null); + assertEquals(pattern, actual); + + pattern = "some pattern {}"; + actual = StringFormatter.arrayFormat(pattern, null); + assertEquals(pattern, actual); + } + + @Test + void dummyPattern() { + String actual = StringFormatter.arrayFormat("dummy pattern", new Object[]{"argument"}); + assertEquals("dummy pattern", actual); + } + + @Test + void escapePattern() { + String actual = StringFormatter.arrayFormat("Arg1: \\{}", new Object[]{"item1"}); + assertEquals("Arg1: {}", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}, \\{}", new Object[]{"item1"}); + assertEquals("Arg1: item1, \\{}", actual); + } + + @Test + void simpleArg() { + String actual; + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{"item1"}); + assertEquals("Arg1: item1", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{11}); + assertEquals("Arg1: 11", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{11.5f}); + assertEquals("Arg1: 11.5", actual); + } + + @Test + void nullArg() { + String actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{null}); + assertEquals("Arg1: null", actual); + } + + @Test + void arrayArg() { + String actual; + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new boolean[]{false, true}}); + assertEquals("Arg1: [false, true]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new byte[]{0b00, 0b01}}); + assertEquals("Arg1: [0, 1]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new char[]{'c', 'h'}}); + assertEquals("Arg1: [c, h]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new short[]{11, 12}}); + assertEquals("Arg1: [11, 12]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new int[]{11, 12}}); + assertEquals("Arg1: [11, 12]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new long[]{11L, 12L}}); + assertEquals("Arg1: [11, 12]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new float[]{11.2f, 12.3f}}); + assertEquals("Arg1: [11.2, 12.3]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new double[]{11.2d, 12.3d}}); + assertEquals("Arg1: [11.2, 12.3]", actual); + + actual = StringFormatter.arrayFormat("Arg1: {}", new Object[]{new String[]{"str-arr-1", "str-arr-2"}}); + assertEquals("Arg1: [str-arr-1, str-arr-2]", actual); + } +} \ No newline at end of file From 47de776e36ed5357be038adddceeb7606ea1c2dd Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 10:36:38 +0300 Subject: [PATCH 04/20] gradle: upgrade --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 14e30f7..a0f7639 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 6e8a16e36fd21daf4548f9fd7aa42cae23773b52 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 11:35:49 +0300 Subject: [PATCH 05/20] gradle: script update --- .gitattributes | 2 +- .gitignore | 1 - build.gradle | 88 ++++++++++++++++------------------------------- gradle.properties | 3 -- settings.gradle | 2 +- 5 files changed, 32 insertions(+), 64 deletions(-) delete mode 100644 gradle.properties diff --git a/.gitattributes b/.gitattributes index 72216f8..0f3666f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,4 +4,4 @@ gradlew.bat text eol=crlf gradle/wrapper/gradle-wrapper.properties text eol=lf # Other -.gitattributes text eol=lf \ No newline at end of file +.gitattributes text eol=lf diff --git a/.gitignore b/.gitignore index 90ae4d1..6132566 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ out/ # GRADLE # .gradle/ build/ -publish.gradle diff --git a/build.gradle b/build.gradle index bc0e549..bcc696b 100644 --- a/build.gradle +++ b/build.gradle @@ -2,13 +2,14 @@ plugins { id 'java' } -def publishScript = file(rootProject.getProjectDir().getPath() + '/publish.gradle') -if (publishScript.exists()) { - apply from: publishScript.path -} +project.group = 'ghast' +project.version = '1.12.2-SNAPSHOT' +jar.archiveBaseName.set(project.name) -project.group = projectGroup -project.version = projectVersion +compileJava { + sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8 + options.encoding = 'UTF-8' +} repositories { mavenLocal() @@ -17,63 +18,34 @@ repositories { maven { url 'https://dmx-mc-project.gitlab.io/maven-repository/' } } -ext { - junitVersion = '5.5.2' - - libs = [ - bukkit: [lib: 'org.bukkit:bukkit:1.12.2-R0.1-SNAPSHOT', exclude: [ - 'com.google.code.gson:gson', - 'com.googlecode.json-simple:json-simple', - 'commons-lang:commons-lang', - 'org.yaml:snakeyaml' - ]], - commons_text: 'org.apache.commons:commons-text:1.9', - lombok: 'org.projectlombok:lombok:1.18.12', - reflection_object: 'ru.dmitriymx:reflection-object:1.2', - test: [ - junit5: [ - "org.junit.jupiter:junit-jupiter-api:$junitVersion", - "org.junit.jupiter:junit-jupiter-engine:$junitVersion" - ], - mock: ['org.mockito:mockito-core:1.10.19'], - h2db: 'com.h2database:h2:1.4.200' - ] - - ] -} - -def compileOnly2(library) { - dependencies.compileOnly library.lib, { - library.exclude.each { String excludeLibStr -> - String[] excludeLib = excludeLibStr.split(':') - exclude group: excludeLib[0], module: excludeLib[1] - } - } -} - -def testImplementation2(library) { - dependencies.testImplementation library.lib, { - library.exclude.each { String excludeLibStr -> - String[] excludeLib = excludeLibStr.split(':') - exclude group: excludeLib[0], module: excludeLib[1] - } - } -} +def lombokVersion = '1.18.12' +def junitVersion = '5.5.2' dependencies { - compileOnly libs.lombok - annotationProcessor libs.lombok + annotationProcessor("org.projectlombok:lombok:$lombokVersion") + compileOnly("org.projectlombok:lombok:$lombokVersion") - compileOnly2 libs.bukkit - implementation libs.commons_text - implementation libs.reflection_object + compileOnly('org.bukkit:bukkit:1.12.2-R0.1-SNAPSHOT') { + exclude(module: 'gson') + exclude(module: 'json-simple') + exclude(module: 'commons-lang') + exclude(module: 'snakeyaml') + } + implementation('org.apache.commons:commons-text:1.9') + implementation('ru.dmitriymx:reflection-object:1.2') - testImplementation libs.test.junit5 - testImplementation libs.test.mock - testImplementation2 libs.bukkit - testImplementation libs.test.h2db + testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") + testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion") + testImplementation('org.mockito:mockito-core:1.10.19') + testImplementation('org.bukkit:bukkit:1.12.2-R0.1-SNAPSHOT') { + exclude(module: 'gson') + exclude(module: 'json-simple') + exclude(module: 'commons-lang') + exclude(module: 'snakeyaml') + } + testImplementation('com.h2database:h2:1.4.200') } test { useJUnitPlatform() -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index 645012a..0000000 --- a/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -projectGroup=ghast -projectName=ghast-tools -projectVersion=1.12.1 \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index de4b82c..8159b24 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -rootProject.name=projectName \ No newline at end of file +rootProject.name = 'ghast-tools' From d3bae13c351aabb2a106d4ee3be1e824851da33e Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 11:37:52 +0300 Subject: [PATCH 06/20] gradle: upgrade dependencies --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index bcc696b..f0a23cb 100644 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,8 @@ repositories { maven { url 'https://dmx-mc-project.gitlab.io/maven-repository/' } } -def lombokVersion = '1.18.12' -def junitVersion = '5.5.2' +def lombokVersion = '1.18.20' +def junitVersion = '5.8.1' dependencies { annotationProcessor("org.projectlombok:lombok:$lombokVersion") @@ -36,7 +36,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion") - testImplementation('org.mockito:mockito-core:1.10.19') + testImplementation('org.mockito:mockito-core:3.12.4') testImplementation('org.bukkit:bukkit:1.12.2-R0.1-SNAPSHOT') { exclude(module: 'gson') exclude(module: 'json-simple') From ccc4dd56c1352c442a7f6a90cfc5b731b2b6f4cc Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 13:07:25 +0300 Subject: [PATCH 07/20] ReflectionObject -> JOOR --- build.gradle | 2 +- src/main/java/ghast/BuildHelper.java | 43 ++++++++----------- .../java/ghast/command/CommandManager.java | 14 +++--- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/build.gradle b/build.gradle index f0a23cb..6802336 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ dependencies { exclude(module: 'snakeyaml') } implementation('org.apache.commons:commons-text:1.9') - implementation('ru.dmitriymx:reflection-object:1.2') + implementation('org.jooq:joor-java-8:0.9.13') testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion") diff --git a/src/main/java/ghast/BuildHelper.java b/src/main/java/ghast/BuildHelper.java index 6e5d9fe..224dc15 100644 --- a/src/main/java/ghast/BuildHelper.java +++ b/src/main/java/ghast/BuildHelper.java @@ -8,13 +8,15 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.Sign; import org.bukkit.block.Skull; -import ru.dmitriymx.reflection.ReflectionClass; -import ru.dmitriymx.reflection.ReflectionObject; +import org.joor.Reflect; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.UUID; +import static org.joor.Reflect.on; +import static org.joor.Reflect.onClass; + @UtilityClass @SuppressWarnings("unused") public class BuildHelper { @@ -96,16 +98,13 @@ public class BuildHelper { */ public static void setPlayerHeadSkin(Skull skull, String skinUrl) { //TODO заменить рефлексию на "фантомные" классы - ReflectionObject refobjBlockPosition = new ReflectionClass(CLASS_BLOCKPOSITION) - .constructor(double.class, double.class, double.class) - .newInstance(skull.getX(), skull.getY(), skull.getZ()); + Reflect reflectBlockPosition = onClass(CLASS_BLOCKPOSITION) + .create(skull.getX(), skull.getY(), skull.getZ()); - new ReflectionObject(skull.getWorld()) - .method("getHandle").invoke() - .method("getTileEntity", CLASS_BLOCKPOSITION) - .invoke(refobjBlockPosition.getOriginalObject()) - .method("setGameProfile", CLASS_GAMEPROFILE) - .invoke(getRefObjPlayerProfile(skinUrl).getOriginalObject()); + on(skull.getWorld()) + .call("getHandle") + .call("getTileEntity", reflectBlockPosition.get()) + .call("setGameProfile", getReflectPlayerProfile(skinUrl).get()); } public Sign placeSignWall(Location location, BlockFace face) { @@ -119,22 +118,18 @@ public class BuildHelper { return sign; } - private ReflectionObject getRefObjPlayerProfile(String url){ - ReflectionObject refobjProperty = new ReflectionClass( - getClassForName("com.mojang.authlib.properties.Property")) - .constructor(String.class, String.class) - .newInstance("textures", Base64.getEncoder() + private Reflect getReflectPlayerProfile(String url) { + Reflect reflectProperty = onClass("com.mojang.authlib.properties.Property") + .create("textures", Base64.getEncoder() .encodeToString(("{textures:{SKIN:{url:\"" + url + "\"}}}").getBytes(StandardCharsets.UTF_8))); - ReflectionObject refobjGameProfile = new ReflectionClass(CLASS_GAMEPROFILE) - .constructor(UUID.class, String.class) - .newInstance(UUID.randomUUID(), null); - refobjGameProfile - .method("getProperties").invoke() - .method("put", Object.class, Object.class) - .invoke("textures", refobjProperty.getOriginalObject()); + Reflect reflectGameProfile = onClass(CLASS_GAMEPROFILE) + .create(UUID.randomUUID(), null); - return refobjGameProfile; + reflectGameProfile.call("getProperties") + .call("put", "textures", reflectProperty.get()); + + return reflectGameProfile; } private Class getClassForName(String className) { diff --git a/src/main/java/ghast/command/CommandManager.java b/src/main/java/ghast/command/CommandManager.java index b4c1c3a..2dc3656 100644 --- a/src/main/java/ghast/command/CommandManager.java +++ b/src/main/java/ghast/command/CommandManager.java @@ -4,8 +4,8 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import ru.dmitriymx.reflection.ReflectionObject; + +import static org.joor.Reflect.on; @UtilityClass @SuppressWarnings("unused") @@ -60,12 +60,10 @@ public class CommandManager { public void register() { //TODO для Paper такие "извращения" не требуются. Нужно продумать. - new ReflectionObject(Bukkit.getServer()) - .method("getCommandMap").invoke() - .method("register", String.class, Command.class).invoke( - name, new CommandWrapper(name, this.onlyPlayer, this.deniedMessage, - this.executer, this.errorConsumer) - ); + on(Bukkit.getServer()) + .call("getCommandMap") + .call("register", name, new CommandWrapper(name, this.onlyPlayer, this.deniedMessage, + this.executer, this.errorConsumer)); } } } From 2e7f95b3234e16db1915ed9678456494659fd86e Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 14:52:29 +0300 Subject: [PATCH 08/20] test: LoggerFormatter --- .../java/ghast/logger/LoggerFormatter.java | 4 - .../ghast/logger/LoggerFormatterTest.java | 84 +++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 src/test/java/ghast/logger/LoggerFormatterTest.java diff --git a/src/main/java/ghast/logger/LoggerFormatter.java b/src/main/java/ghast/logger/LoggerFormatter.java index 759498f..08ad31f 100644 --- a/src/main/java/ghast/logger/LoggerFormatter.java +++ b/src/main/java/ghast/logger/LoggerFormatter.java @@ -43,10 +43,6 @@ public final class LoggerFormatter { } private static Object[] trimmedCopy(final Object[] argArray) { - if (argArray == null || argArray.length == 0) { - throw new IllegalStateException("non-sensical empty or null argument array"); - } - int trimmedLen = argArray.length - 1; Object[] trimmed = new Object[trimmedLen]; diff --git a/src/test/java/ghast/logger/LoggerFormatterTest.java b/src/test/java/ghast/logger/LoggerFormatterTest.java new file mode 100644 index 0000000..60fe5c7 --- /dev/null +++ b/src/test/java/ghast/logger/LoggerFormatterTest.java @@ -0,0 +1,84 @@ +package ghast.logger; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class LoggerFormatterTest { + + @Test + void arrayFormatNullPattern() { + Exception exception = new Exception("oops!"); + FormattingPair formattingPair = LoggerFormatter.arrayFormat(null, null, exception); + + assertNotNull(formattingPair); + assertNull(formattingPair.getMessage()); + assertNotNull(formattingPair.getThrowable()); + assertEquals(exception, formattingPair.getThrowable()); + + formattingPair = LoggerFormatter.arrayFormat(null, null, null); + assertNotNull(formattingPair); + assertNull(formattingPair.getMessage()); + assertNull(formattingPair.getThrowable()); + } + + @Test + void arrayFormatNullArgs() { + FormattingPair formattingPair = LoggerFormatter.arrayFormat("some pattern", null, null); + + assertNotNull(formattingPair); + assertNotNull(formattingPair.getMessage()); + assertEquals("some pattern", formattingPair.getMessage()); + assertNull(formattingPair.getThrowable()); + + formattingPair = LoggerFormatter.arrayFormat("some pattern {}", null, null); + assertNotNull(formattingPair); + assertNotNull(formattingPair.getMessage()); + assertEquals("some pattern {}", formattingPair.getMessage()); + assertNull(formattingPair.getThrowable()); + } + + @Test + void arrayFormat() { + Exception exception = new Exception("oops!"); + FormattingPair formattingPair = LoggerFormatter.arrayFormat("some pattern {}", new Object[]{"item-1"}, exception); + + assertNotNull(formattingPair); + assertNotNull(formattingPair.getMessage()); + assertEquals("some pattern item-1", formattingPair.getMessage()); + assertNotNull(formattingPair.getThrowable()); + assertEquals(exception, formattingPair.getThrowable()); + } + + @Test + void arrayFormatWithoutThrowable() { + FormattingPair formattingPair = LoggerFormatter.arrayFormat("Arg1: {}", new Object[]{ "item-1" }); + + assertNotNull(formattingPair); + assertNotNull(formattingPair.getMessage()); + assertEquals("Arg1: item-1", formattingPair.getMessage()); + assertNull(formattingPair.getThrowable()); + } + + @Test + void arrayFormatWithoutThrowableNullArgs() { + FormattingPair formattingPair = LoggerFormatter.arrayFormat("Arg1: {}", null); + + assertNotNull(formattingPair); + assertNotNull(formattingPair.getMessage()); + assertEquals("Arg1: {}", formattingPair.getMessage()); + assertNull(formattingPair.getThrowable()); + } + + @Test + void arrayFormatThrowableInArgs() { + Exception exception = new Exception("oops!"); + FormattingPair formattingPair = LoggerFormatter.arrayFormat("Arg1: {}", new Object[]{ "item-1", exception }); + + assertNotNull(formattingPair); + assertNotNull(formattingPair.getMessage()); + assertEquals("Arg1: item-1", formattingPair.getMessage()); + assertNotNull(formattingPair.getThrowable()); + assertEquals(exception, formattingPair.getThrowable()); + } +} \ No newline at end of file From 8cf2cbf951f38a354530d4ce8e6328b07bfc7932 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 16:16:25 +0300 Subject: [PATCH 09/20] test: LoggerAdapter --- .../java/ghast/logger/FormattingPair.java | 2 - .../java/ghast/logger/LoggerAdapterTest.java | 50 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/test/java/ghast/logger/LoggerAdapterTest.java diff --git a/src/main/java/ghast/logger/FormattingPair.java b/src/main/java/ghast/logger/FormattingPair.java index c8e67e3..26283e2 100644 --- a/src/main/java/ghast/logger/FormattingPair.java +++ b/src/main/java/ghast/logger/FormattingPair.java @@ -2,11 +2,9 @@ package ghast.logger; import lombok.Getter; import lombok.RequiredArgsConstructor; -import lombok.ToString; @RequiredArgsConstructor @Getter -@ToString public class FormattingPair { private final String message; diff --git a/src/test/java/ghast/logger/LoggerAdapterTest.java b/src/test/java/ghast/logger/LoggerAdapterTest.java new file mode 100644 index 0000000..00eccd2 --- /dev/null +++ b/src/test/java/ghast/logger/LoggerAdapterTest.java @@ -0,0 +1,50 @@ +package ghast.logger; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class LoggerAdapterTest { + + LoggerAdapter loggerAdapter; + + @BeforeEach + void before() { + loggerAdapter = mock(LoggerAdapter.class, CALLS_REAL_METHODS); + } + + @Test + void debug() { + loggerAdapter.debug("some pattern {}", "item-1"); + verify(loggerAdapter).debug("some pattern item-1"); + + Exception exception = new Exception("oops!"); + loggerAdapter.debug("some pattern {}", "item-1", exception); + verify(loggerAdapter).debug("some pattern item-1", exception); + } + + @Test + void info() { + loggerAdapter.info("some pattern {}", "item-1"); + verify(loggerAdapter).info("some pattern item-1"); + } + + @Test + void warn() { + loggerAdapter.warn("some pattern {}", "item-1"); + verify(loggerAdapter).warn("some pattern item-1"); + } + + @Test + void error() { + loggerAdapter.error("some pattern {}", "item-1"); + verify(loggerAdapter).error("some pattern item-1"); + + Exception exception = new Exception("oops!"); + loggerAdapter.error("some pattern {}", "item-1", exception); + verify(loggerAdapter).error("some pattern item-1", exception); + } +} \ No newline at end of file From df15d23988de9d50574eb60ed07c1e610fe8d858 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 16:26:27 +0300 Subject: [PATCH 10/20] test: BukkitLogger --- .../java/ghast/logger/BukkitLoggerTest.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/test/java/ghast/logger/BukkitLoggerTest.java diff --git a/src/test/java/ghast/logger/BukkitLoggerTest.java b/src/test/java/ghast/logger/BukkitLoggerTest.java new file mode 100644 index 0000000..8e599e8 --- /dev/null +++ b/src/test/java/ghast/logger/BukkitLoggerTest.java @@ -0,0 +1,54 @@ +package ghast.logger; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +class BukkitLoggerTest { + + Logger logger; + BukkitLogger bukkitLogger; + + @BeforeEach + void before() { + logger = mock(Logger.class); + bukkitLogger = new BukkitLogger(logger); + } + + @Test + void debug() { + bukkitLogger.debug("Some String"); + verify(logger).log(Level.CONFIG, "Some String"); + + Exception exception = new Exception("oops!"); + bukkitLogger.debug("Some String", exception); + verify(logger).log(Level.CONFIG, "Some String", exception); + } + + @Test + void info() { + bukkitLogger.info("some message"); + verify(logger).log(Level.INFO, "some message"); + } + + @Test + void warn() { + bukkitLogger.warn("some message"); + verify(logger).log(Level.WARNING, "some message"); + } + + @Test + void error() { + bukkitLogger.error("some message"); + verify(logger).log(Level.SEVERE, "some message"); + + Exception exception = new Exception("oops!"); + bukkitLogger.error("Some String", exception); + verify(logger).log(Level.SEVERE, "Some String", exception); + } +} \ No newline at end of file From a0b81ab0a195573fac6c76e890d3398bffed6cc2 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 01:45:02 +0300 Subject: [PATCH 11/20] add JaCoCo --- build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bc0e549..b6f9925 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'jacoco' } def publishScript = file(rootProject.getProjectDir().getPath() + '/publish.gradle') @@ -76,4 +77,12 @@ dependencies { test { useJUnitPlatform() -} \ No newline at end of file +} + +jacoco { + toolVersion = '0.8.5' +} + +jacocoTestReport { + dependsOn test +} From a7a1ca0efa46f71ecc144f5877af75dc6c8e5246 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Fri, 8 Oct 2021 10:13:20 +0300 Subject: [PATCH 12/20] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20Messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ghast/Messages.java | 111 +++++++++++++++--------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/src/main/java/ghast/Messages.java b/src/main/java/ghast/Messages.java index 9856f31..1f6e299 100644 --- a/src/main/java/ghast/Messages.java +++ b/src/main/java/ghast/Messages.java @@ -1,6 +1,7 @@ package ghast; -import lombok.experimental.UtilityClass; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; import org.apache.commons.text.StringSubstitutor; import java.io.BufferedReader; @@ -9,57 +10,12 @@ import java.io.Reader; import java.util.HashMap; import java.util.Map; import java.util.Properties; +import java.util.stream.Collectors; -@UtilityClass +@RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class Messages { - private final Map MESSAGES_MAP = new HashMap<>(); - - //region Load messages - - /** - * Загрузка сообщений из {@link Properties} - * - * @param properties список сообщений и шаблонов - */ - public void load(Properties properties) { - MESSAGES_MAP.clear(); - properties.forEach((key, value) -> MESSAGES_MAP.put(key.toString().trim().toLowerCase(), value.toString().trim())); - } - - /** - * Загрузка сообщений из {@link Reader}. - *

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

- * - * @param reader {@link Reader} со списоком сообщений и шаблонов - */ - public void load(Reader reader) { - MESSAGES_MAP.clear(); - try { - BufferedReader bufferedReader = new BufferedReader(reader); - String line; - while ((line = bufferedReader.readLine()) != null) { - String[] split = line.split("=", 2); - MESSAGES_MAP.put(split[0].trim().toLowerCase(), split[1].trim()); - } - } catch (IOException e) { - //TODO заменить на специализированный Exception - throw new RuntimeException("Error load messages: " + e.getMessage(), e); - } - } - - /** - * Загрузка сообщений из {@link Map}<{@link String}, {@link String}>. - * - * @param messages список сообщений и шаблонов - */ - public void load(Map messages) { - MESSAGES_MAP.clear(); - MESSAGES_MAP.putAll(messages); - } - //endregion + private final Map messagesMap; //region Get messages /** @@ -70,7 +26,7 @@ public class Messages { */ public String get(String key) { String keyLc = key.toLowerCase(); - return MESSAGES_MAP.getOrDefault(keyLc, keyLc); + return messagesMap.getOrDefault(keyLc, keyLc); } /** @@ -83,8 +39,8 @@ public class Messages { public String get(String key, Map params) { String keyLc = key.toLowerCase(); - if (MESSAGES_MAP.containsKey(keyLc)) { - return format(MESSAGES_MAP.get(keyLc), params); + if (messagesMap.containsKey(keyLc)) { + return format(messagesMap.get(keyLc), params); } else { return keyLc; } @@ -100,8 +56,8 @@ public class Messages { public String get(String key, Object... params) { String keyLc = key.toLowerCase(); - if (MESSAGES_MAP.containsKey(keyLc)) { - return format(MESSAGES_MAP.get(keyLc), params); + if (messagesMap.containsKey(keyLc)) { + return format(messagesMap.get(keyLc), params); } else { return keyLc; } @@ -147,4 +103,51 @@ public class Messages { return map; } + + /** + * Загрузка сообщений из {@link Properties} + * + * @param properties список сообщений и шаблонов + * @return экземпляр {@link Messages} + */ + public static Messages load(Properties properties) { + Map map = properties.entrySet().stream().collect(Collectors.toMap( + entry -> (String) entry.getKey(), + entry -> (String) entry.getValue() + )); + + return new Messages(map); + } + + /** + * Загрузка сообщений из {@link Reader}. + *

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

+ * + * @param reader {@link Reader} со списоком сообщений и шаблонов + */ + public static Messages 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() + )); + return new Messages(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 Messages load(Map messages) { + return new Messages(new HashMap<>(messages)); + } } From a2ff9725d57e17771b1e17e20f6b9b9fc58a1040 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Fri, 8 Oct 2021 10:14:04 +0300 Subject: [PATCH 13/20] =?UTF-8?q?=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BD=D0=B8=D1=86=D0=B8=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20Messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/ghast/Messages.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/ghast/Messages.java b/src/main/java/ghast/Messages.java index 1f6e299..716badc 100644 --- a/src/main/java/ghast/Messages.java +++ b/src/main/java/ghast/Messages.java @@ -126,6 +126,7 @@ public class Messages { *

* * @param reader {@link Reader} со списоком сообщений и шаблонов + * @return экземпляр {@link Messages} */ public static Messages load(Reader reader) { try(BufferedReader bufferedReader = new BufferedReader(reader)) { @@ -146,6 +147,7 @@ public class Messages { * Загрузка сообщений из {@link Map}<{@link String}, {@link String}>. * * @param messages список сообщений и шаблонов + * @return экземпляр {@link Messages} */ public static Messages load(Map messages) { return new Messages(new HashMap<>(messages)); From 262d4ee9841925b9e388ad40a26a2a384150117d Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Fri, 8 Oct 2021 13:22:35 +0300 Subject: [PATCH 14/20] HashMaps --- src/main/java/ghast/HashMaps.java | 156 ++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 src/main/java/ghast/HashMaps.java diff --git a/src/main/java/ghast/HashMaps.java b/src/main/java/ghast/HashMaps.java new file mode 100644 index 0000000..ae63bcf --- /dev/null +++ b/src/main/java/ghast/HashMaps.java @@ -0,0 +1,156 @@ +package ghast; + +import lombok.*; + +import java.util.HashMap; +import java.util.Map; + +/** + * Создание Map как в Java 9+. + */ +@SuppressWarnings("DuplicatedCode") +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class HashMaps { + + public static Map of() { + return new HashMap<>(0); + } + + public static Map of(K k1, V v1) { + return new HashMap() {{ + put(k1, v1); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + put(k5, v5); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + K k6, V v6) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + put(k5, v5); + put(k6, v6); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + K k6, V v6, K k7, V v7) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + put(k5, v5); + put(k6, v6); + put(k7, v7); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + K k6, V v6, K k7, V v7, K k8, V v8) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + put(k5, v5); + put(k6, v6); + put(k7, v7); + put(k8, v8); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + put(k5, v5); + put(k6, v6); + put(k7, v7); + put(k8, v8); + put(k9, v9); + }}; + } + + public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, + K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) { + return new HashMap() {{ + put(k1, v1); + put(k2, v2); + put(k3, v3); + put(k4, v4); + put(k5, v5); + put(k6, v6); + put(k7, v7); + put(k8, v8); + put(k9, v9); + put(k10, v10); + }}; + } + + @SafeVarargs + public static Map ofEntries(Map.Entry... entries) { + if (entries == null || entries.length == 0) { + return of(); + } + + Map map = new HashMap<>(entries.length); + for (Map.Entry entry : entries) { + map.put(entry.getKey(), entry.getValue()); + } + + return map; + } + + public static Map.Entry entry(K k, V v) { + return new SimpleEntry<>(k, v); + } + + @AllArgsConstructor + @Getter + @Setter + @EqualsAndHashCode + private static class SimpleEntry implements Map.Entry { + + private final K key; + private V value; + } +} From ce2f302d2e62d55222dd329cea2b9c4771b0eb35 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Fri, 8 Oct 2021 14:31:29 +0300 Subject: [PATCH 15/20] test: Messages --- build.gradle | 1 + src/main/java/ghast/Messages.java | 142 ++++++++++++---------- src/test/java/ghast/MessagesLoadTest.java | 59 +++++++++ src/test/java/ghast/MessagesTest.java | 91 ++++++++++++++ 4 files changed, 226 insertions(+), 67 deletions(-) create mode 100644 src/test/java/ghast/MessagesLoadTest.java create mode 100644 src/test/java/ghast/MessagesTest.java diff --git a/build.gradle b/build.gradle index 32ef767..cfd2d8a 100644 --- a/build.gradle +++ b/build.gradle @@ -38,6 +38,7 @@ dependencies { testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion") testImplementation('org.mockito:mockito-core:3.12.4') + testImplementation('org.jooq:joor-java-8:0.9.13') testImplementation('org.bukkit:bukkit:1.12.2-R0.1-SNAPSHOT') { exclude(module: 'gson') exclude(module: 'json-simple') diff --git a/src/main/java/ghast/Messages.java b/src/main/java/ghast/Messages.java index 716badc..6869b9b 100644 --- a/src/main/java/ghast/Messages.java +++ b/src/main/java/ghast/Messages.java @@ -1,7 +1,7 @@ package ghast; import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; +import lombok.NoArgsConstructor; import org.apache.commons.text.StringSubstitutor; import java.io.BufferedReader; @@ -12,21 +12,68 @@ import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; -@RequiredArgsConstructor(access = AccessLevel.PRIVATE) -public class Messages { +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class Messages { - private final Map messagesMap; + 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 сообщение, если таковое задано. Иначе - ключ + * @return Сообщение, если таковое задано. Иначе - ключ */ - public String get(String key) { + public static String get(String key) { String keyLc = key.toLowerCase(); - return messagesMap.getOrDefault(keyLc, keyLc); + return MESSAGES_MAP.getOrDefault(keyLc, keyLc); } /** @@ -34,13 +81,13 @@ public class Messages { * * @param key ключ/код * @param params список параметров - * @return сообщение, если таковое задано. Иначе - ключ + * @return Сообщение, если таковое задано. Иначе - ключ */ - public String get(String key, Map params) { + public static String get(String key, Map params) { String keyLc = key.toLowerCase(); - if (messagesMap.containsKey(keyLc)) { - return format(messagesMap.get(keyLc), params); + if (MESSAGES_MAP.containsKey(keyLc)) { + return format(MESSAGES_MAP.get(keyLc), params); } else { return keyLc; } @@ -51,13 +98,18 @@ public class Messages { * * @param key ключ/код * @param params чередующийся по парный список параметров: {@link String (str)param_name}, {@link Object (obj)param_value} и т.д. - * @return сообщение, если таковое задано. Иначе - ключ + * @return Сообщение, если таковое задано. Иначе - ключ */ - public String get(String key, Object... params) { + @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 (messagesMap.containsKey(keyLc)) { - return format(messagesMap.get(keyLc), params); + if (MESSAGES_MAP.containsKey(keyLc)) { + return format(MESSAGES_MAP.get(keyLc), params); } else { return keyLc; } @@ -72,7 +124,7 @@ public class Messages { * @param params параметры * @return сообщение */ - public String format(String format, Map params) { + public static String format(String format, Map params) { return StringSubstitutor.replace(format, params, "{", "}"); } @@ -83,12 +135,17 @@ public class Messages { * @param params параметры * @return сообщение */ - public String format(String format, Object... params) { + @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 Map arrayParamsToMap(Object... params) { + private static Map arrayParamsToMap(Object... params) { int len; if ((params.length % 2) == 1) { len = params.length - 1; @@ -103,53 +160,4 @@ public class Messages { return map; } - - /** - * Загрузка сообщений из {@link Properties} - * - * @param properties список сообщений и шаблонов - * @return экземпляр {@link Messages} - */ - public static Messages load(Properties properties) { - Map map = properties.entrySet().stream().collect(Collectors.toMap( - entry -> (String) entry.getKey(), - entry -> (String) entry.getValue() - )); - - return new Messages(map); - } - - /** - * Загрузка сообщений из {@link Reader}. - *

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

- * - * @param reader {@link Reader} со списоком сообщений и шаблонов - * @return экземпляр {@link Messages} - */ - public static Messages 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() - )); - return new Messages(map); - } catch (IOException e) { - //TODO заменить на специализированный Exception - throw new RuntimeException("Error load messages: " + e.getMessage(), e); - } - } - - /** - * Загрузка сообщений из {@link Map}<{@link String}, {@link String}>. - * - * @param messages список сообщений и шаблонов - * @return экземпляр {@link Messages} - */ - public static Messages load(Map messages) { - return new Messages(new HashMap<>(messages)); - } } diff --git a/src/test/java/ghast/MessagesLoadTest.java b/src/test/java/ghast/MessagesLoadTest.java new file mode 100644 index 0000000..5f6cec1 --- /dev/null +++ b/src/test/java/ghast/MessagesLoadTest.java @@ -0,0 +1,59 @@ +package ghast; + +import org.joor.Reflect; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.stream.Collectors; + +import static org.joor.Reflect.onClass; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +class MessagesLoadTest { + + Map map; + + @BeforeEach + void before() { + map = new HashMap() {{ + put("key1", "value1"); + put("key2", "value2"); + }}; + } + + @Test + void loadMap() { + Messages.load(map); + + Reflect reflectMessagesMap = onClass(Messages.class).field("MESSAGES_MAP"); + assertIterableEquals(map.entrySet(), reflectMessagesMap.as(Map.class).entrySet()); + } + + @Test + void loadReader() { + String lines = map.entrySet().stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining("\n")); + StringReader reader = new StringReader(lines); + + Messages.load(reader); + + Reflect reflectMessagesMap = onClass(Messages.class).field("MESSAGES_MAP"); + assertIterableEquals(map.entrySet(), reflectMessagesMap.as(Map.class).entrySet()); + } + + @Test + void loadProperties() { + Properties properties = new Properties(); + properties.putAll(map); + + Messages.load(properties); + + Reflect reflectMessagesMap = onClass(Messages.class).field("MESSAGES_MAP"); + assertIterableEquals(map.entrySet(), reflectMessagesMap.as(Map.class).entrySet()); + } +} \ No newline at end of file diff --git a/src/test/java/ghast/MessagesTest.java b/src/test/java/ghast/MessagesTest.java new file mode 100644 index 0000000..7b8a43a --- /dev/null +++ b/src/test/java/ghast/MessagesTest.java @@ -0,0 +1,91 @@ +package ghast; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MessagesTest { + + @BeforeEach + void before() { + Map map1 = new HashMap() {{ + put("simple-message", "some message"); + put("parametrized-message", "Arg1: {key1}"); + }}; + Messages.load(map1); + } + + @Test + void getSimpleMessage() { + String string = Messages.get("simple-message"); + assertEquals("some message", string); + } + + @Test + void getSimpleMessageNotFound() { + String string = Messages.get("non-exists-key"); + assertEquals("non-exists-key", string); + } + + @Test + void formatMap() { + Map map1 = new HashMap() {{ + put("key1", "some message"); + }}; + String string = Messages.format("Arg1: {key1}", map1); + assertEquals("Arg1: some message", string); + + Map map2 = new HashMap() {{ + put("key1", "some message"); + }}; + string = Messages.format("Arg1: {key1}", map2); + assertEquals("Arg1: some message", string); + } + + @Test + void formatArray() { + String string = Messages.format("Arg1: {key1}", "key1", "some message"); + assertEquals("Arg1: some message", string); + } + + @Test + void getParametrizedMessageMap() { + Map map2 = new HashMap() {{ + put("key1", "some message"); + }}; + String string = Messages.get("parametrized-message", map2); + assertEquals("Arg1: some message", string); + + Map map3 = new HashMap() {{ + put("key1", "some message"); + }}; + string = Messages.get("parametrized-message", map3); + assertEquals("Arg1: some message", string); + } + + @Test + void getParametrizedMessageMapNotFound() { + Map map2 = new HashMap() {{ + put("key1", "some message"); + }}; + + String string = Messages.get("non-exists-key", map2); + assertEquals("non-exists-key", string); + } + + @Test + void getParametrizedMessageArray() { + String string = Messages.get("parametrized-message", "key1", "some message"); + assertEquals("Arg1: some message", string); + } + + @Test + void getParametrizedMessageArrayNotFound() { + String string = Messages.get("non-exists-key", "key1", "some message"); + assertEquals("non-exists-key", string); + } +} \ No newline at end of file From 26d6fee242366d6d6b9044efcb74b7b33db15bc9 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Fri, 8 Oct 2021 15:17:54 +0300 Subject: [PATCH 16/20] test: HashMaps --- build.gradle | 9 ++ src/main/java/ghast/HashMaps.java | 39 ++++-- src/test/java/ghast/HashMapsTest.java | 182 ++++++++++++++++++++++++++ 3 files changed, 218 insertions(+), 12 deletions(-) create mode 100644 src/test/java/ghast/HashMapsTest.java diff --git a/build.gradle b/build.gradle index f0a23cb..32ef767 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java' + id 'jacoco' } project.group = 'ghast' @@ -49,3 +50,11 @@ dependencies { test { useJUnitPlatform() } + +jacoco { + toolVersion = '0.8.5' +} + +jacocoTestReport { + dependsOn test +} diff --git a/src/main/java/ghast/HashMaps.java b/src/main/java/ghast/HashMaps.java index ae63bcf..1da8d7d 100644 --- a/src/main/java/ghast/HashMaps.java +++ b/src/main/java/ghast/HashMaps.java @@ -17,20 +17,20 @@ public final class HashMaps { } public static Map of(K k1, V v1) { - return new HashMap() {{ + return new HashMap(1) {{ put(k1, v1); }}; } public static Map of(K k1, V v1, K k2, V v2) { - return new HashMap() {{ + return new HashMap(2) {{ put(k1, v1); put(k2, v2); }}; } public static Map of(K k1, V v1, K k2, V v2, K k3, V v3) { - return new HashMap() {{ + return new HashMap(3) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -38,7 +38,7 @@ public final class HashMaps { } public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) { - return new HashMap() {{ + return new HashMap(4) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -47,7 +47,7 @@ public final class HashMaps { } public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) { - return new HashMap() {{ + return new HashMap(5) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -58,7 +58,7 @@ public final class HashMaps { public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6) { - return new HashMap() {{ + return new HashMap(6) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -70,7 +70,7 @@ public final class HashMaps { public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7) { - return new HashMap() {{ + return new HashMap(7) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -83,7 +83,7 @@ public final class HashMaps { public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8) { - return new HashMap() {{ + return new HashMap(8) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -97,7 +97,7 @@ public final class HashMaps { public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) { - return new HashMap() {{ + return new HashMap(9) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -112,7 +112,7 @@ public final class HashMaps { public static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) { - return new HashMap() {{ + return new HashMap(10) {{ put(k1, v1); put(k2, v2); put(k3, v3); @@ -145,12 +145,27 @@ public final class HashMaps { } @AllArgsConstructor - @Getter - @Setter @EqualsAndHashCode private static class SimpleEntry implements Map.Entry { private final K key; private V value; + + @Override + public K getKey() { + return key; + } + + @Override + public V getValue() { + return value; + } + + @Override + public V setValue(V value) { + V prev = this.value; + this.value = value; + return prev; + } } } diff --git a/src/test/java/ghast/HashMapsTest.java b/src/test/java/ghast/HashMapsTest.java new file mode 100644 index 0000000..92d5e3e --- /dev/null +++ b/src/test/java/ghast/HashMapsTest.java @@ -0,0 +1,182 @@ +package ghast; + +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.*; + +class HashMapsTest { + + @Test + void of0() { + Map map = HashMaps.of(); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertTrue(map.isEmpty()); + } + + @Test + void of1() { + Map map = HashMaps.of("key1", "val1"); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(1, map.size()); + } + + @Test + void of2() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(2, map.size()); + } + + @Test + void of3() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(3, map.size()); + } + + @Test + void of4() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(4, map.size()); + } + + @Test + void of5() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4", + "key5", "val5" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(5, map.size()); + } + + @Test + void of6() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4", + "key5", "val5", + "key6", "val6" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(6, map.size()); + } + + @Test + void of7() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4", + "key5", "val5", + "key6", "val6", + "key7", "val7" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(7, map.size()); + } + + @Test + void of8() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4", + "key5", "val5", + "key6", "val6", + "key7", "val7", + "key8", "val8" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(8, map.size()); + } + + @Test + void of9() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4", + "key5", "val5", + "key6", "val6", + "key7", "val7", + "key8", "val8", + "key9", "val9" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(9, map.size()); + } + + @Test + void of10() { + Map map = HashMaps.of( + "key1", "val1", + "key2", "val2", + "key3", "val3", + "key4", "val4", + "key5", "val5", + "key6", "val6", + "key7", "val7", + "key8", "val8", + "key9", "val9", + "key10", "val10" + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(10, map.size()); + } + + @Test + void ofEntries() { + Map map = HashMaps.ofEntries( + HashMaps.entry("key1", "val1"), + HashMaps.entry("key2", "val2"), + HashMaps.entry("key3", "val3"), + HashMaps.entry("key4", "val4"), + HashMaps.entry("key5", "val5"), + HashMaps.entry("key6", "val6"), + HashMaps.entry("key7", "val7"), + HashMaps.entry("key8", "val8"), + HashMaps.entry("key9", "val9"), + HashMaps.entry("key10", "val10"), + HashMaps.entry("key11", "val11") + ); + assertNotNull(map); + assertTrue(map instanceof HashMap); + assertEquals(11, map.size()); + } +} \ No newline at end of file From 86a1c3ab9c36f9067b55cdbc43e570b82bda35d2 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Sun, 10 Oct 2021 14:26:44 +0300 Subject: [PATCH 17/20] GitLab CI --- .gitlab-ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..3378d7d --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,11 @@ +image: gradle:6.7.0-jdk8 +variables: + GRADLE_OPTS: "-Dorg.gradle.daemon=false" +before_script: + - export GRADLE_USER_HOME=`pwd`/.gradle + +build: + stage: build + only: + - dev/ci + script: gradle --console=plain compileJava From f923f477655865c94633351946c6c9dac2ddab57 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 21 Oct 2021 18:33:16 +0300 Subject: [PATCH 18/20] GitLab CI: manual publish --- .gitignore | 3 +++ build.gradle | 36 +++++++++++++++++++++++++++++++----- gradle.properties | 4 +++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 90ae4d1..cbb7093 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ out/ .gradle/ build/ publish.gradle + +# OTHER # +secrets.properties diff --git a/build.gradle b/build.gradle index bc0e549..d7eb09c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,11 @@ +//file:noinspection GroovyAssignabilityCheck plugins { id 'java' + id 'maven-publish' } -def publishScript = file(rootProject.getProjectDir().getPath() + '/publish.gradle') -if (publishScript.exists()) { - apply from: publishScript.path -} +def secrets = new Properties() +file("secrets.properties").withInputStream { secrets.load(it) } project.group = projectGroup project.version = projectVersion @@ -15,6 +15,7 @@ repositories { mavenCentral() maven { url 'https://hub.spigotmc.org/nexus/content/groups/public' } maven { url 'https://dmx-mc-project.gitlab.io/maven-repository/' } + maven { url "https://gitlab.com/api/v4/projects/${project.property('gitlab.projectid')}/packages/maven" } } ext { @@ -76,4 +77,29 @@ dependencies { test { useJUnitPlatform() -} \ No newline at end of file +} + +publishing { + publications { + mavenBinary(MavenPublication) { + groupId = project.property('projectGroup') + artifactId = project.property('projectName') + version = project.property('projectVersion') + + from components.java + } + } + + repositories { + maven { + url "https://gitlab.com/api/v4/projects/${project.property('gitlab.projectid')}/packages/maven" + credentials(HttpHeaderCredentials) { + name = 'Private-Token' + value = secrets.getProperty('gitlab.privateToken') + } + authentication { + header(HttpHeaderAuthentication) + } + } + } +} diff --git a/gradle.properties b/gradle.properties index 645012a..94ef319 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,5 @@ projectGroup=ghast projectName=ghast-tools -projectVersion=1.12.1 \ No newline at end of file +projectVersion=1.12.1 + +gitlab.projectid=23328133 \ No newline at end of file From 2b055062a34567336f99bf12a9a189e2032b1490 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 21 Oct 2021 22:24:23 +0300 Subject: [PATCH 19/20] GitLab CI: publish by job --- .gitignore | 3 --- .gitlab-ci.yml | 2 +- build.gradle | 7 ++----- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index cbb7093..90ae4d1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,3 @@ out/ .gradle/ build/ publish.gradle - -# OTHER # -secrets.properties diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3378d7d..ea343c2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,4 +8,4 @@ build: stage: build only: - dev/ci - script: gradle --console=plain compileJava + script: gradle --console=plain publish diff --git a/build.gradle b/build.gradle index d7eb09c..375738a 100644 --- a/build.gradle +++ b/build.gradle @@ -4,9 +4,6 @@ plugins { id 'maven-publish' } -def secrets = new Properties() -file("secrets.properties").withInputStream { secrets.load(it) } - project.group = projectGroup project.version = projectVersion @@ -94,8 +91,8 @@ publishing { maven { url "https://gitlab.com/api/v4/projects/${project.property('gitlab.projectid')}/packages/maven" credentials(HttpHeaderCredentials) { - name = 'Private-Token' - value = secrets.getProperty('gitlab.privateToken') + name = 'Job-Token' + value = System.getenv('CI_JOB_TOKEN') } authentication { header(HttpHeaderAuthentication) From 914dbc169212220d9de995e3696f523886fa7982 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Fri, 22 Oct 2021 12:23:42 +0300 Subject: [PATCH 20/20] gradle: update dependencies --- build.gradle | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 920dcb7..663157d 100644 --- a/build.gradle +++ b/build.gradle @@ -16,14 +16,11 @@ compileJava { } repositories { - mavenLocal() mavenCentral() maven { url 'https://hub.spigotmc.org/nexus/content/groups/public' } - maven { url 'https://dmx-mc-project.gitlab.io/maven-repository/' } - maven { url "https://gitlab.com/api/v4/projects/${gitlab_projectid}/packages/maven" } } -def lombokVersion = '1.18.20' +def lombokVersion = '1.18.22' def junitVersion = '5.8.1' def bukkitVersion = '1.12.2-R0.1-SNAPSHOT' @@ -38,12 +35,12 @@ dependencies { exclude(module: 'snakeyaml') } implementation('org.apache.commons:commons-text:1.9') - implementation('org.jooq:joor-java-8:0.9.13') + implementation('org.jooq:joor-java-8:0.9.14') testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion") - testImplementation('org.mockito:mockito-core:3.12.4') - testImplementation('org.jooq:joor-java-8:0.9.13') + testImplementation('org.mockito:mockito-core:4.0.0') + testImplementation('org.jooq:joor-java-8:0.9.14') testImplementation("org.bukkit:bukkit:$bukkitVersion") { exclude(module: 'gson') exclude(module: 'json-simple')