From a871175d380e0d955c014a01aac76b5789522418 Mon Sep 17 00:00:00 2001 From: DmitriyMX Date: Thu, 7 Oct 2021 01:03:50 +0300 Subject: [PATCH] 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(']'); + } +}