summaryrefslogtreecommitdiff
path: root/dicore3/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'dicore3/core/src')
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/BitModifier.java364
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/Formatting.java588
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/InterfaceChain.java346
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/InventoryEventUtil.java240
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/Logging.java232
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/Reflection.java1560
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/SetBasedWhitelist.java118
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/SpigotUtil.java816
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/StringUtil.java946
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/Whitelist.java182
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/ChainedListener.java92
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandle.java110
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandles.java126
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/ChainedListeners.java112
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/HandlerList.java182
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/Listener.java34
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/ListenerHandle.java18
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/event/SimpleListener.java14
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/ExceptionHandler.java406
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiConsumer.java138
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiFunction.java152
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedConsumer.java134
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunction.java148
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunctionalObject.java170
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedRunnable.java124
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedSupplier.java140
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/task/BaseTask.java216
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/task/IteratorTask.java240
-rw-r--r--dicore3/core/src/main/java/io/dico/dicore/task/VoidTask.java38
29 files changed, 3993 insertions, 3993 deletions
diff --git a/dicore3/core/src/main/java/io/dico/dicore/BitModifier.java b/dicore3/core/src/main/java/io/dico/dicore/BitModifier.java
index e4facb1..ae25123 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/BitModifier.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/BitModifier.java
@@ -1,182 +1,182 @@
-package io.dico.dicore;
-
-public interface BitModifier {
-
- long mask();
-
- long get(long x);
-
- long set(long x, long value);
-
- default int lowerBound() {
- return Long.numberOfTrailingZeros(mask());
- }
-
- default int upperBound() {
- return 64 - Long.numberOfLeadingZeros(mask());
- }
-
- default int bitCount() {
- return Long.bitCount(mask());
- }
-
- default boolean getBoolean(long x) {
- return get(x) == 1;
- }
-
- default long setBoolean(long x, boolean value) {
- return set(x, value ? 1 : 0);
- }
-
- default int getInt(long x) {
- return (int) (get(x) & 0xFFFFFFFFL);
- }
-
- default long setInt(long x, int value) {
- return set(x, value & 0xFFFFFFFFL);
- }
-
- default short getShort(long x) {
- return (short) (get(x) & 0xFFFFL);
- }
-
- default long setShort(long x, int value) {
- return set(x, value & 0xFFFFL);
- }
-
- default byte getByte(long x) {
- return (byte) (get(x) & 0xFFL);
- }
-
- default long setByte(long x, int value) {
- return set(x, value & 0xFFL);
- }
-
- final class OfSingle implements BitModifier {
- private final long mask;
-
- public OfSingle(int bit) {
- if (bit < 0 || bit >= 64) {
- throw new IndexOutOfBoundsException();
- }
- this.mask = 1L << bit;
- }
-
- @Override
- public int bitCount() {
- return 1;
- }
-
- @Override
- public long mask() {
- return mask;
- }
-
- public boolean getBoolean(long x) {
- return (x & mask) != 0;
- }
-
- public long setBoolean(long x, boolean value) {
- return value ? (x | mask) : (x & ~mask);
- }
-
- @Override
- public long get(long x) {
- return getBoolean(x) ? 1 : 0;
- }
-
- @Override
- public long set(long x, long value) {
- if (value < 0 || value > 1) {
- throw new IllegalArgumentException();
- }
- return setBoolean(x, value == 1);
- }
- }
-
- final class OfMultiple implements BitModifier {
- private final int lowerBound;
- private final int bitCount;
- private final long mask;
-
- public OfMultiple(int lowerBound, int bitCount) {
- int upperBound = lowerBound + bitCount;
- if (lowerBound < 0 || lowerBound >= 64 || upperBound < 1 || upperBound > 64 || upperBound < lowerBound) {
- throw new IndexOutOfBoundsException();
- }
- this.lowerBound = lowerBound;
- this.bitCount = bitCount;
- this.mask = (Long.MIN_VALUE >> (bitCount - 1)) >>> (64 - bitCount - lowerBound);
- }
-
- @Override
- public int lowerBound() {
- return lowerBound;
- }
-
- @Override
- public int bitCount() {
- return bitCount;
- }
-
- @Override
- public int upperBound() {
- return lowerBound + bitCount;
- }
-
- @Override
- public long mask() {
- return mask;
- }
-
- @Override
- public long get(long x) {
- return (x & mask) >>> lowerBound;
- }
-
- @Override
- public long set(long x, long value) {
- return (x & ~mask) | ((value << lowerBound) & mask);
- }
-
- }
-
- class Builder {
- int currentIndex;
-
- public int getCurrentIndex() {
- return currentIndex;
- }
-
- public int getRemaining() {
- return 64 - currentIndex;
- }
-
- public OfSingle single() {
- checkAvailable(1);
- return new OfSingle(currentIndex++);
- }
-
- public BitModifier size(int size) {
- if (size == 1) {
- return single();
- }
- checkAvailable(size);
- BitModifier result = new OfMultiple(currentIndex, size);
- currentIndex += size;
- return result;
- }
-
- public BitModifier remaining() {
- return size(getRemaining());
- }
-
- private void checkAvailable(int size) {
- if (size <= 0 || currentIndex + size > 64) {
- throw new IllegalStateException("Exceeding bit count of a long");
- }
- }
-
- }
-
-}
+package io.dico.dicore;
+
+public interface BitModifier {
+
+ long mask();
+
+ long get(long x);
+
+ long set(long x, long value);
+
+ default int lowerBound() {
+ return Long.numberOfTrailingZeros(mask());
+ }
+
+ default int upperBound() {
+ return 64 - Long.numberOfLeadingZeros(mask());
+ }
+
+ default int bitCount() {
+ return Long.bitCount(mask());
+ }
+
+ default boolean getBoolean(long x) {
+ return get(x) == 1;
+ }
+
+ default long setBoolean(long x, boolean value) {
+ return set(x, value ? 1 : 0);
+ }
+
+ default int getInt(long x) {
+ return (int) (get(x) & 0xFFFFFFFFL);
+ }
+
+ default long setInt(long x, int value) {
+ return set(x, value & 0xFFFFFFFFL);
+ }
+
+ default short getShort(long x) {
+ return (short) (get(x) & 0xFFFFL);
+ }
+
+ default long setShort(long x, int value) {
+ return set(x, value & 0xFFFFL);
+ }
+
+ default byte getByte(long x) {
+ return (byte) (get(x) & 0xFFL);
+ }
+
+ default long setByte(long x, int value) {
+ return set(x, value & 0xFFL);
+ }
+
+ final class OfSingle implements BitModifier {
+ private final long mask;
+
+ public OfSingle(int bit) {
+ if (bit < 0 || bit >= 64) {
+ throw new IndexOutOfBoundsException();
+ }
+ this.mask = 1L << bit;
+ }
+
+ @Override
+ public int bitCount() {
+ return 1;
+ }
+
+ @Override
+ public long mask() {
+ return mask;
+ }
+
+ public boolean getBoolean(long x) {
+ return (x & mask) != 0;
+ }
+
+ public long setBoolean(long x, boolean value) {
+ return value ? (x | mask) : (x & ~mask);
+ }
+
+ @Override
+ public long get(long x) {
+ return getBoolean(x) ? 1 : 0;
+ }
+
+ @Override
+ public long set(long x, long value) {
+ if (value < 0 || value > 1) {
+ throw new IllegalArgumentException();
+ }
+ return setBoolean(x, value == 1);
+ }
+ }
+
+ final class OfMultiple implements BitModifier {
+ private final int lowerBound;
+ private final int bitCount;
+ private final long mask;
+
+ public OfMultiple(int lowerBound, int bitCount) {
+ int upperBound = lowerBound + bitCount;
+ if (lowerBound < 0 || lowerBound >= 64 || upperBound < 1 || upperBound > 64 || upperBound < lowerBound) {
+ throw new IndexOutOfBoundsException();
+ }
+ this.lowerBound = lowerBound;
+ this.bitCount = bitCount;
+ this.mask = (Long.MIN_VALUE >> (bitCount - 1)) >>> (64 - bitCount - lowerBound);
+ }
+
+ @Override
+ public int lowerBound() {
+ return lowerBound;
+ }
+
+ @Override
+ public int bitCount() {
+ return bitCount;
+ }
+
+ @Override
+ public int upperBound() {
+ return lowerBound + bitCount;
+ }
+
+ @Override
+ public long mask() {
+ return mask;
+ }
+
+ @Override
+ public long get(long x) {
+ return (x & mask) >>> lowerBound;
+ }
+
+ @Override
+ public long set(long x, long value) {
+ return (x & ~mask) | ((value << lowerBound) & mask);
+ }
+
+ }
+
+ class Builder {
+ int currentIndex;
+
+ public int getCurrentIndex() {
+ return currentIndex;
+ }
+
+ public int getRemaining() {
+ return 64 - currentIndex;
+ }
+
+ public OfSingle single() {
+ checkAvailable(1);
+ return new OfSingle(currentIndex++);
+ }
+
+ public BitModifier size(int size) {
+ if (size == 1) {
+ return single();
+ }
+ checkAvailable(size);
+ BitModifier result = new OfMultiple(currentIndex, size);
+ currentIndex += size;
+ return result;
+ }
+
+ public BitModifier remaining() {
+ return size(getRemaining());
+ }
+
+ private void checkAvailable(int size) {
+ if (size <= 0 || currentIndex + size > 64) {
+ throw new IllegalStateException("Exceeding bit count of a long");
+ }
+ }
+
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/Formatting.java b/dicore3/core/src/main/java/io/dico/dicore/Formatting.java
index 9fdfe0e..40afb9b 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/Formatting.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/Formatting.java
@@ -1,295 +1,295 @@
-/*
- * Copyright (c) 2017 ProjectOreville
- *
- * All rights reserved.
- *
- * Author(s):
- * Dico Karssiens
- */
-
-package io.dico.dicore;
-
-import org.jetbrains.annotations.NotNull;
-
-public final class Formatting implements CharSequence {
- public static final char FORMAT_CHAR = '\u00a7';
- private static final String CACHED_CHARS = "0123456789abcdefklmnor";
- private static final Formatting[] singleCharInstances = new Formatting[CACHED_CHARS.length()];
-
- @NotNull
- public static final Formatting
- BLACK = from('0'),
- DARK_BLUE = from('1'),
- DARL_GREEN = from('2'),
- CYAN = from('3'),
- DARK_RED = from('4'),
- PURPLE = from('5'),
- ORANGE = from('6'),
- GRAY = from('7'),
- DARK_GRAY = from('8'),
- BLUE = from('9'),
- GREEN = from('a'),
- AQUA = from('b'),
- RED = from('c'),
- PINK = from('d'),
- YELLOW = from('e'),
- WHITE = from('f'),
- BOLD = from('l'),
- STRIKETHROUGH = from('m'),
- UNDERLINE = from('n'),
- ITALIC = from('o'),
- MAGIC = from('k'),
- RESET = from('r'),
- EMPTY = from('\0');
-
- public static String stripAll(String value) {
- return stripAll(FORMAT_CHAR, value);
- }
-
- public static String stripAll(char alternateChar, String value) {
- int index = value.indexOf(alternateChar);
- int max;
- if (index == -1 || index == (max = value.length() - 1)) {
- return value;
- }
-
- StringBuilder result = new StringBuilder();
- int from = 0;
- do {
- if (isRecognizedChar(value.charAt(index + 1))) {
- result.append(value, from, index);
- from = index + 2;
- } else {
- result.append(value, from, from = index + 2);
- }
-
- index = value.indexOf(alternateChar, index + 1);
- } while (index != -1 && index != max && from <= max);
-
- if (from <= max) {
- result.append(value, from, value.length());
- }
- return result.toString();
- }
-
- public static String stripFirst(String value) {
- return stripFirst(FORMAT_CHAR, value);
- }
-
- public static String stripFirst(char alternateChar, String value) {
- int index = value.indexOf(alternateChar);
- int max;
- if (index == -1 || index == (max = value.length() - 1)) {
- return value;
- }
-
- StringBuilder result = new StringBuilder(value.length());
- int from = 0;
- if (isRecognizedChar(value.charAt(index + 1))) {
- result.append(value, from, index);
- from = index + 2;
- } else {
- result.append(value, from, from = index + 2);
- }
-
- if (from < max) {
- result.append(value, from, value.length());
- }
- return result.toString();
- }
-
- public static Formatting from(char c) {
- if (isRecognizedChar(c)) {
- c = Character.toLowerCase(c);
- int index = CACHED_CHARS.indexOf(c);
- if (index == -1) return EMPTY;
-
- Formatting res = singleCharInstances[index];
- if (res == null) {
- singleCharInstances[index] = res = new Formatting(c);
- }
- return res;
- }
- return EMPTY;
- }
-
- public static Formatting from(String chars) {
- return chars.length() == 1 ? from(chars.charAt(0)) : getFormats(chars, '\0');
- }
-
- public static Formatting getFormats(String input) {
- return getFormats(input, FORMAT_CHAR);
- }
-
- public static Formatting getFormats(String input, char formatChar) {
- return getFormats(input, 0, input.length(), formatChar);
- }
-
- public static Formatting getFormats(String input, int start, int end, char formatChar) {
- if ((start < 0) || (start > end) || (end > input.length())) {
- throw new IndexOutOfBoundsException("start " + start + ", end " + end + ", input.length() " + input.length());
- }
-
- boolean needsFormatChar = formatChar != '\0';
- char[] formats = new char[6];
- // just make sure it's not the same as formatChar
- char previous = (char) (formatChar + 1);
-
- for (int i = start; i < end; i++) {
- char c = input.charAt(i);
-
- if (previous == formatChar || !needsFormatChar) {
- if (isColourChar(c) || isResetChar(c)) {
- formats = new char[6];
- formats[0] = Character.toLowerCase(c);
- } else if (isFormatChar(c)) {
- char format = Character.toLowerCase(c);
- for (int j = 0; j < 6; j++) {
- if (formats[j] == '\0') {
- formats[j] = format;
- break;
- } else if (formats[j] == format) {
- break;
- }
- }
- }
- }
-
- previous = c;
- }
-
- return formats[1] == '\0' ? from(formats[0]) : new Formatting(formats);
- }
-
- public static String translate(String input) {
- return translateChars('&', input);
- }
-
- public static String translateChars(char alternateChar, String input) {
- return translateFormat(alternateChar, FORMAT_CHAR, input);
- }
-
- public static String revert(String input) {
- return revertChars('&', input);
- }
-
- public static String revertChars(char alternateChar, String input) {
- return translateFormat(FORMAT_CHAR, alternateChar, input);
- }
-
- public static String translateFormat(char fromChar, char toChar, String input) {
- if (input == null) {
- return null;
- }
- int n = input.length();
- if (n < 2) {
- return input;
- }
- char[] result = null;
- char previous = input.charAt(0);
- for (int i = 1; i < n; i++) {
- char c = input.charAt(i);
- if (previous == fromChar && isRecognizedChar(c)) {
- if (result == null) {
- result = input.toCharArray();
- }
- result[i - 1] = toChar;
- }
- previous = c;
- }
- return result == null ? input : String.valueOf(result);
- }
-
- public static void translate(StringBuilder input) {
- translateChars('&', input);
- }
-
- public static void translateChars(char alternateChar, StringBuilder input) {
- translateFormat(alternateChar, FORMAT_CHAR, input);
- }
-
- public static void revert(StringBuilder input) {
- revertChars('&', input);
- }
-
- public static void revertChars(char alternateChar, StringBuilder input) {
- translateFormat(FORMAT_CHAR, alternateChar, input);
- }
-
- public static void translateFormat(char fromChar, char toChar, StringBuilder input) {
- if (input == null) {
- return;
- }
- int n = input.length();
- if (n < 2) {
- return;
- }
- char previous = input.charAt(0);
- for (int i = 1; i < n; i++) {
- char c = input.charAt(i);
- if (previous == fromChar && isRecognizedChar(c)) {
- input.setCharAt(i -1, toChar);
- }
- previous = c;
- }
- }
-
- private static boolean isRecognizedChar(char c) {
- return isColourChar(c) || isFormatChar(c) || isResetChar(c);
- }
-
- private static boolean isColourChar(char c) {
- return "0123456789abcdefABCDEF".indexOf(c) >= 0;
- }
-
- private static boolean isResetChar(char c) {
- return c == 'r' || c == 'R';
- }
-
- private static boolean isFormatChar(char c) {
- return "klmnoKLMNO".indexOf(c) >= 0;
- }
-
- private final String format;
-
- private Formatting(char[] formats) {
- StringBuilder format = new StringBuilder(12);
- for (char c : formats) {
- if (c != '\0') {
- format.append(FORMAT_CHAR).append(c);
- } else {
- break;
- }
- }
- this.format = format.toString();
- }
-
- private Formatting(char c) {
- this.format = (c != '\0') ? String.valueOf(new char[]{FORMAT_CHAR, c}) : "";
- }
-
- @Override
- public int length() {
- return format.length();
- }
-
- @Override
- public char charAt(int index) {
- return format.charAt(index);
- }
-
- @Override
- public String subSequence(int start, int end) {
- return format.substring(start, end);
- }
-
- @Override
- public String toString() {
- return format;
- }
-
- public String toString(char formatChar) {
- return format.replace(FORMAT_CHAR, formatChar);
- }
-
+/*
+ * Copyright (c) 2017 ProjectOreville
+ *
+ * All rights reserved.
+ *
+ * Author(s):
+ * Dico Karssiens
+ */
+
+package io.dico.dicore;
+
+import org.jetbrains.annotations.NotNull;
+
+public final class Formatting implements CharSequence {
+ public static final char FORMAT_CHAR = '\u00a7';
+ private static final String CACHED_CHARS = "0123456789abcdefklmnor";
+ private static final Formatting[] singleCharInstances = new Formatting[CACHED_CHARS.length()];
+
+ @NotNull
+ public static final Formatting
+ BLACK = from('0'),
+ DARK_BLUE = from('1'),
+ DARL_GREEN = from('2'),
+ CYAN = from('3'),
+ DARK_RED = from('4'),
+ PURPLE = from('5'),
+ ORANGE = from('6'),
+ GRAY = from('7'),
+ DARK_GRAY = from('8'),
+ BLUE = from('9'),
+ GREEN = from('a'),
+ AQUA = from('b'),
+ RED = from('c'),
+ PINK = from('d'),
+ YELLOW = from('e'),
+ WHITE = from('f'),
+ BOLD = from('l'),
+ STRIKETHROUGH = from('m'),
+ UNDERLINE = from('n'),
+ ITALIC = from('o'),
+ MAGIC = from('k'),
+ RESET = from('r'),
+ EMPTY = from('\0');
+
+ public static String stripAll(String value) {
+ return stripAll(FORMAT_CHAR, value);
+ }
+
+ public static String stripAll(char alternateChar, String value) {
+ int index = value.indexOf(alternateChar);
+ int max;
+ if (index == -1 || index == (max = value.length() - 1)) {
+ return value;
+ }
+
+ StringBuilder result = new StringBuilder();
+ int from = 0;
+ do {
+ if (isRecognizedChar(value.charAt(index + 1))) {
+ result.append(value, from, index);
+ from = index + 2;
+ } else {
+ result.append(value, from, from = index + 2);
+ }
+
+ index = value.indexOf(alternateChar, index + 1);
+ } while (index != -1 && index != max && from <= max);
+
+ if (from <= max) {
+ result.append(value, from, value.length());
+ }
+ return result.toString();
+ }
+
+ public static String stripFirst(String value) {
+ return stripFirst(FORMAT_CHAR, value);
+ }
+
+ public static String stripFirst(char alternateChar, String value) {
+ int index = value.indexOf(alternateChar);
+ int max;
+ if (index == -1 || index == (max = value.length() - 1)) {
+ return value;
+ }
+
+ StringBuilder result = new StringBuilder(value.length());
+ int from = 0;
+ if (isRecognizedChar(value.charAt(index + 1))) {
+ result.append(value, from, index);
+ from = index + 2;
+ } else {
+ result.append(value, from, from = index + 2);
+ }
+
+ if (from < max) {
+ result.append(value, from, value.length());
+ }
+ return result.toString();
+ }
+
+ public static Formatting from(char c) {
+ if (isRecognizedChar(c)) {
+ c = Character.toLowerCase(c);
+ int index = CACHED_CHARS.indexOf(c);
+ if (index == -1) return EMPTY;
+
+ Formatting res = singleCharInstances[index];
+ if (res == null) {
+ singleCharInstances[index] = res = new Formatting(c);
+ }
+ return res;
+ }
+ return EMPTY;
+ }
+
+ public static Formatting from(String chars) {
+ return chars.length() == 1 ? from(chars.charAt(0)) : getFormats(chars, '\0');
+ }
+
+ public static Formatting getFormats(String input) {
+ return getFormats(input, FORMAT_CHAR);
+ }
+
+ public static Formatting getFormats(String input, char formatChar) {
+ return getFormats(input, 0, input.length(), formatChar);
+ }
+
+ public static Formatting getFormats(String input, int start, int end, char formatChar) {
+ if ((start < 0) || (start > end) || (end > input.length())) {
+ throw new IndexOutOfBoundsException("start " + start + ", end " + end + ", input.length() " + input.length());
+ }
+
+ boolean needsFormatChar = formatChar != '\0';
+ char[] formats = new char[6];
+ // just make sure it's not the same as formatChar
+ char previous = (char) (formatChar + 1);
+
+ for (int i = start; i < end; i++) {
+ char c = input.charAt(i);
+
+ if (previous == formatChar || !needsFormatChar) {
+ if (isColourChar(c) || isResetChar(c)) {
+ formats = new char[6];
+ formats[0] = Character.toLowerCase(c);
+ } else if (isFormatChar(c)) {
+ char format = Character.toLowerCase(c);
+ for (int j = 0; j < 6; j++) {
+ if (formats[j] == '\0') {
+ formats[j] = format;
+ break;
+ } else if (formats[j] == format) {
+ break;
+ }
+ }
+ }
+ }
+
+ previous = c;
+ }
+
+ return formats[1] == '\0' ? from(formats[0]) : new Formatting(formats);
+ }
+
+ public static String translate(String input) {
+ return translateChars('&', input);
+ }
+
+ public static String translateChars(char alternateChar, String input) {
+ return translateFormat(alternateChar, FORMAT_CHAR, input);
+ }
+
+ public static String revert(String input) {
+ return revertChars('&', input);
+ }
+
+ public static String revertChars(char alternateChar, String input) {
+ return translateFormat(FORMAT_CHAR, alternateChar, input);
+ }
+
+ public static String translateFormat(char fromChar, char toChar, String input) {
+ if (input == null) {
+ return null;
+ }
+ int n = input.length();
+ if (n < 2) {
+ return input;
+ }
+ char[] result = null;
+ char previous = input.charAt(0);
+ for (int i = 1; i < n; i++) {
+ char c = input.charAt(i);
+ if (previous == fromChar && isRecognizedChar(c)) {
+ if (result == null) {
+ result = input.toCharArray();
+ }
+ result[i - 1] = toChar;
+ }
+ previous = c;
+ }
+ return result == null ? input : String.valueOf(result);
+ }
+
+ public static void translate(StringBuilder input) {
+ translateChars('&', input);
+ }
+
+ public static void translateChars(char alternateChar, StringBuilder input) {
+ translateFormat(alternateChar, FORMAT_CHAR, input);
+ }
+
+ public static void revert(StringBuilder input) {
+ revertChars('&', input);
+ }
+
+ public static void revertChars(char alternateChar, StringBuilder input) {
+ translateFormat(FORMAT_CHAR, alternateChar, input);
+ }
+
+ public static void translateFormat(char fromChar, char toChar, StringBuilder input) {
+ if (input == null) {
+ return;
+ }
+ int n = input.length();
+ if (n < 2) {
+ return;
+ }
+ char previous = input.charAt(0);
+ for (int i = 1; i < n; i++) {
+ char c = input.charAt(i);
+ if (previous == fromChar && isRecognizedChar(c)) {
+ input.setCharAt(i -1, toChar);
+ }
+ previous = c;
+ }
+ }
+
+ private static boolean isRecognizedChar(char c) {
+ return isColourChar(c) || isFormatChar(c) || isResetChar(c);
+ }
+
+ private static boolean isColourChar(char c) {
+ return "0123456789abcdefABCDEF".indexOf(c) >= 0;
+ }
+
+ private static boolean isResetChar(char c) {
+ return c == 'r' || c == 'R';
+ }
+
+ private static boolean isFormatChar(char c) {
+ return "klmnoKLMNO".indexOf(c) >= 0;
+ }
+
+ private final String format;
+
+ private Formatting(char[] formats) {
+ StringBuilder format = new StringBuilder(12);
+ for (char c : formats) {
+ if (c != '\0') {
+ format.append(FORMAT_CHAR).append(c);
+ } else {
+ break;
+ }
+ }
+ this.format = format.toString();
+ }
+
+ private Formatting(char c) {
+ this.format = (c != '\0') ? String.valueOf(new char[]{FORMAT_CHAR, c}) : "";
+ }
+
+ @Override
+ public int length() {
+ return format.length();
+ }
+
+ @Override
+ public char charAt(int index) {
+ return format.charAt(index);
+ }
+
+ @Override
+ public String subSequence(int start, int end) {
+ return format.substring(start, end);
+ }
+
+ @Override
+ public String toString() {
+ return format;
+ }
+
+ public String toString(char formatChar) {
+ return format.replace(FORMAT_CHAR, formatChar);
+ }
+
} \ No newline at end of file
diff --git a/dicore3/core/src/main/java/io/dico/dicore/InterfaceChain.java b/dicore3/core/src/main/java/io/dico/dicore/InterfaceChain.java
index b59979a..f92da6b 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/InterfaceChain.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/InterfaceChain.java
@@ -1,173 +1,173 @@
-package io.dico.dicore;
-
-/**
- * A chainable object
- * <p>
- * It is not possible to declare another upper bound for type parameter Subtype.
- * However, it is required that it also extends the type parameter Element.
- *
- * @param <Subtype> the interface that is chainable
- * @param <Element> the element of the chain, this is a supertype of the subtype
- */
-@SuppressWarnings("unchecked")
-public interface InterfaceChain<Element, Subtype extends InterfaceChain<Element, Subtype>> {
-
- /**
- * returns the empty InterfaceChain instance.
- *
- * @return the empty InterfaceChain instance
- */
- Subtype getEmptyInstance();
-
- /**
- * returns a InterfaceChain with the last added element detached.
- * <p>
- * if this InterfaceChain is the empty instance, the empty instance is returned.
- *
- * @return a InterfaceChain with the last added element detached
- * @implNote for the purpose of lambdas, the default implementation also returns the empty instance.
- */
- default Subtype withoutLastNode() {
- return getEmptyInstance();
- }
-
- /**
- * returns the element that was inserted as the last element
- * <p>
- * For instance, calling this method on the result of calling {@link InterfaceChain#withElement(Object)}
- * would return the given element.
- *
- * @return the element that was inserted as the last element
- * @implNote for the purpose of lambdas, the default implementation returns this object,
- * which is required to implement the Element type parameter.
- */
- default Element getDelegateOfLastNode() {
- //noinspection unchecked
- return (Element) this;
- }
-
- /**
- * @return The number of elements chained from this InterfaceChain.
- * @implNote for the purpose of lambdas, the default implementation returns 1.
- */
- default int getElementCount() {
- return 1;
- }
-
- /**
- * Get a new InterfaceChain that includes the given Element.
- * <p>
- * The default implementation of the Subtype should look like this:
- * <pre> {@code
- * if (element == null) {
- * return this;
- * }
- *
- * int count = getElementCount() + 1;
- * return new Subtype() {
- * \@Override
- * public void exampleElementMethod() {
- * try {
- * Subtype.this.exampleElementMethod();
- * } finally {
- * element.exampleElementMethod();
- * }
- * }
- *
- * \@Override
- * public Subtype withoutLastNode() {
- * return Subtype.this;
- * }
- *
- * \@Override
- * public Element getDelegateOfLastNode() {
- * return element;
- * }
- *
- * \@Override
- * public int getElementCount() {
- * return count;
- * }
- * };
- * }
- * </pre>
- *
- * @param element A new element to insert at the end of this InterfaceChain.
- * @return a new InterfaceChain that includes the given Element.
- */
- Subtype withElement(Element element);
-
- /**
- * Append each of the elements to this InterfaceChain
- *
- * @param elements the elements to append
- * @return a new InterfaceChain with the elements appended
- */
- default Subtype withElements(Element... elements) {
- Subtype result = (Subtype) this;
- for (Element element : elements) {
- result = result.withElement(element);
- }
- return result;
- }
-
- /*
- Example Subtypes implementation
-
- public class Subtypes {
-
- private Subtypes() {
-
- }
-
- private static final Subtype empty = new Subtype() {
- @Override
- public void exampleElementMethod() {
-
- }
-
- @Override
- public Subtype withElement(Element other) {
- return Subtypes.singleton(other);
- }
-
- @Override
- public int getElementCount() {
- return 0;
- }
-
- @Override
- public Element getDelegateOfLastNode() {
- return null;
- }
- };
-
- public static Subtype empty() {
- return empty;
- }
-
- public static Subtype singleton(Element element) {
- if (element instanceof Subtype) {
- return (Subtype) element;
- }
- if (element == null) {
- return empty();
- }
- return new Subtype() {
- @Override
- public void exampleElementMethod() {
- element.exampleElementMethod();
- }
-
- @Override
- public Element getDelegateOfLastNode() {
- return element;
- }
- };
- }
-
- }
-
- */
-
-}
+package io.dico.dicore;
+
+/**
+ * A chainable object
+ * <p>
+ * It is not possible to declare another upper bound for type parameter Subtype.
+ * However, it is required that it also extends the type parameter Element.
+ *
+ * @param <Subtype> the interface that is chainable
+ * @param <Element> the element of the chain, this is a supertype of the subtype
+ */
+@SuppressWarnings("unchecked")
+public interface InterfaceChain<Element, Subtype extends InterfaceChain<Element, Subtype>> {
+
+ /**
+ * returns the empty InterfaceChain instance.
+ *
+ * @return the empty InterfaceChain instance
+ */
+ Subtype getEmptyInstance();
+
+ /**
+ * returns a InterfaceChain with the last added element detached.
+ * <p>
+ * if this InterfaceChain is the empty instance, the empty instance is returned.
+ *
+ * @return a InterfaceChain with the last added element detached
+ * @implNote for the purpose of lambdas, the default implementation also returns the empty instance.
+ */
+ default Subtype withoutLastNode() {
+ return getEmptyInstance();
+ }
+
+ /**
+ * returns the element that was inserted as the last element
+ * <p>
+ * For instance, calling this method on the result of calling {@link InterfaceChain#withElement(Object)}
+ * would return the given element.
+ *
+ * @return the element that was inserted as the last element
+ * @implNote for the purpose of lambdas, the default implementation returns this object,
+ * which is required to implement the Element type parameter.
+ */
+ default Element getDelegateOfLastNode() {
+ //noinspection unchecked
+ return (Element) this;
+ }
+
+ /**
+ * @return The number of elements chained from this InterfaceChain.
+ * @implNote for the purpose of lambdas, the default implementation returns 1.
+ */
+ default int getElementCount() {
+ return 1;
+ }
+
+ /**
+ * Get a new InterfaceChain that includes the given Element.
+ * <p>
+ * The default implementation of the Subtype should look like this:
+ * <pre> {@code
+ * if (element == null) {
+ * return this;
+ * }
+ *
+ * int count = getElementCount() + 1;
+ * return new Subtype() {
+ * \@Override
+ * public void exampleElementMethod() {
+ * try {
+ * Subtype.this.exampleElementMethod();
+ * } finally {
+ * element.exampleElementMethod();
+ * }
+ * }
+ *
+ * \@Override
+ * public Subtype withoutLastNode() {
+ * return Subtype.this;
+ * }
+ *
+ * \@Override
+ * public Element getDelegateOfLastNode() {
+ * return element;
+ * }
+ *
+ * \@Override
+ * public int getElementCount() {
+ * return count;
+ * }
+ * };
+ * }
+ * </pre>
+ *
+ * @param element A new element to insert at the end of this InterfaceChain.
+ * @return a new InterfaceChain that includes the given Element.
+ */
+ Subtype withElement(Element element);
+
+ /**
+ * Append each of the elements to this InterfaceChain
+ *
+ * @param elements the elements to append
+ * @return a new InterfaceChain with the elements appended
+ */
+ default Subtype withElements(Element... elements) {
+ Subtype result = (Subtype) this;
+ for (Element element : elements) {
+ result = result.withElement(element);
+ }
+ return result;
+ }
+
+ /*
+ Example Subtypes implementation
+
+ public class Subtypes {
+
+ private Subtypes() {
+
+ }
+
+ private static final Subtype empty = new Subtype() {
+ @Override
+ public void exampleElementMethod() {
+
+ }
+
+ @Override
+ public Subtype withElement(Element other) {
+ return Subtypes.singleton(other);
+ }
+
+ @Override
+ public int getElementCount() {
+ return 0;
+ }
+
+ @Override
+ public Element getDelegateOfLastNode() {
+ return null;
+ }
+ };
+
+ public static Subtype empty() {
+ return empty;
+ }
+
+ public static Subtype singleton(Element element) {
+ if (element instanceof Subtype) {
+ return (Subtype) element;
+ }
+ if (element == null) {
+ return empty();
+ }
+ return new Subtype() {
+ @Override
+ public void exampleElementMethod() {
+ element.exampleElementMethod();
+ }
+
+ @Override
+ public Element getDelegateOfLastNode() {
+ return element;
+ }
+ };
+ }
+
+ }
+
+ */
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/InventoryEventUtil.java b/dicore3/core/src/main/java/io/dico/dicore/InventoryEventUtil.java
index 5c19848..3be2179 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/InventoryEventUtil.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/InventoryEventUtil.java
@@ -1,120 +1,120 @@
-package io.dico.dicore;
-
-import org.bukkit.Material;
-import org.bukkit.event.inventory.InventoryClickEvent;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.PlayerInventory;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-public class InventoryEventUtil {
-
- private InventoryEventUtil() {
-
- }
-
- public static ItemStack getNewItem(InventoryClickEvent event) {
- Inventory clicked = event.getInventory();
- switch (event.getAction()) {
- case SWAP_WITH_CURSOR:
- case PLACE_ALL:
- return event.getCursor();
- case PICKUP_ALL:
- case HOTBAR_MOVE_AND_READD:
- case MOVE_TO_OTHER_INVENTORY:
- case DROP_ALL_SLOT:
- case COLLECT_TO_CURSOR:
- return null;
- case PICKUP_HALF:
- case PICKUP_SOME:
- ItemStack item = clicked.getItem(event.getSlot()).clone();
- item.setAmount(item.getAmount() / 2);
- return item;
- case PICKUP_ONE:
- case DROP_ONE_SLOT:
- item = clicked.getItem(event.getSlot()).clone();
- item.setAmount(Math.max(0, item.getAmount() - 1));
- return item;
- case PLACE_ONE:
- item = event.getView().getCursor().clone();
- item.setAmount(1);
- return item;
- case PLACE_SOME:
- item = event.getView().getCursor().clone();
- item.setAmount(item.getAmount() / 2);
- return item;
- case HOTBAR_SWAP:
- return event.getView().getBottomInventory().getItem(event.getHotbarButton());
- default:
- return clicked.getItem(event.getSlot());
- }
- }
-
-
- public static Map<Integer, ItemStack> deduceChangesIfItemAdded(Inventory inventory, ItemStack added, boolean computeNewItem) {
- int addedAmount = added.getAmount();
- Map<Integer, ItemStack> rv = Collections.emptyMap();
-
- for (int n = inventory.getSize(), i = 0; i < n; i++) {
- if (addedAmount <= 0) break;
-
- ItemStack current = inventory.getItem(i);
- if (current == null || current.getType() == Material.AIR || current.isSimilar(added)) {
- int count = current == null ? 0 : current.getAmount();
- int max = (current == null ? added : current).getType().getMaxStackSize();
- if (count < max) {
- int diff = max - count;
- if (diff > addedAmount) {
- diff = addedAmount;
- }
- addedAmount -= diff;
-
- if (rv.isEmpty()) rv = new LinkedHashMap<>();
-
- if (computeNewItem) {
- current = (current == null ? added : current).clone();
- current.setAmount(count + diff);
- rv.put(i, current);
- } else {
- rv.put(i, null);
- }
- }
- }
- }
-
- return rv;
- }
-
-
- public static ItemStack getNewHeldItemIfPickedUp(PlayerInventory inventory, ItemStack added) {
- int heldItemSlot = inventory.getHeldItemSlot();
- ItemStack heldItem = inventory.getItem(heldItemSlot);
-
- if (SpigotUtil.isItemPresent(heldItem) && !added.isSimilar(heldItem)) {
- return null;
- }
-
- int amt = added.getAmount();
- for (int i = 0; i < heldItemSlot; i++) {
- ItemStack item = inventory.getItem(i);
- if (!SpigotUtil.isItemPresent(item)) {
- return null;
- }
- if (item.isSimilar(item)) {
- amt -= Math.max(0, item.getMaxStackSize() - item.getAmount());
- if (amt <= 0) {
- return null;
- }
- }
- }
-
- added = added.clone();
- added.setAmount(amt + Math.max(0, heldItem == null ? 0 : heldItem.getAmount()));
- return added;
- }
-
-
-}
+package io.dico.dicore;
+
+import org.bukkit.Material;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.PlayerInventory;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class InventoryEventUtil {
+
+ private InventoryEventUtil() {
+
+ }
+
+ public static ItemStack getNewItem(InventoryClickEvent event) {
+ Inventory clicked = event.getInventory();
+ switch (event.getAction()) {
+ case SWAP_WITH_CURSOR:
+ case PLACE_ALL:
+ return event.getCursor();
+ case PICKUP_ALL:
+ case HOTBAR_MOVE_AND_READD:
+ case MOVE_TO_OTHER_INVENTORY:
+ case DROP_ALL_SLOT:
+ case COLLECT_TO_CURSOR:
+ return null;
+ case PICKUP_HALF:
+ case PICKUP_SOME:
+ ItemStack item = clicked.getItem(event.getSlot()).clone();
+ item.setAmount(item.getAmount() / 2);
+ return item;
+ case PICKUP_ONE:
+ case DROP_ONE_SLOT:
+ item = clicked.getItem(event.getSlot()).clone();
+ item.setAmount(Math.max(0, item.getAmount() - 1));
+ return item;
+ case PLACE_ONE:
+ item = event.getView().getCursor().clone();
+ item.setAmount(1);
+ return item;
+ case PLACE_SOME:
+ item = event.getView().getCursor().clone();
+ item.setAmount(item.getAmount() / 2);
+ return item;
+ case HOTBAR_SWAP:
+ return event.getView().getBottomInventory().getItem(event.getHotbarButton());
+ default:
+ return clicked.getItem(event.getSlot());
+ }
+ }
+
+
+ public static Map<Integer, ItemStack> deduceChangesIfItemAdded(Inventory inventory, ItemStack added, boolean computeNewItem) {
+ int addedAmount = added.getAmount();
+ Map<Integer, ItemStack> rv = Collections.emptyMap();
+
+ for (int n = inventory.getSize(), i = 0; i < n; i++) {
+ if (addedAmount <= 0) break;
+
+ ItemStack current = inventory.getItem(i);
+ if (current == null || current.getType() == Material.AIR || current.isSimilar(added)) {
+ int count = current == null ? 0 : current.getAmount();
+ int max = (current == null ? added : current).getType().getMaxStackSize();
+ if (count < max) {
+ int diff = max - count;
+ if (diff > addedAmount) {
+ diff = addedAmount;
+ }
+ addedAmount -= diff;
+
+ if (rv.isEmpty()) rv = new LinkedHashMap<>();
+
+ if (computeNewItem) {
+ current = (current == null ? added : current).clone();
+ current.setAmount(count + diff);
+ rv.put(i, current);
+ } else {
+ rv.put(i, null);
+ }
+ }
+ }
+ }
+
+ return rv;
+ }
+
+
+ public static ItemStack getNewHeldItemIfPickedUp(PlayerInventory inventory, ItemStack added) {
+ int heldItemSlot = inventory.getHeldItemSlot();
+ ItemStack heldItem = inventory.getItem(heldItemSlot);
+
+ if (SpigotUtil.isItemPresent(heldItem) && !added.isSimilar(heldItem)) {
+ return null;
+ }
+
+ int amt = added.getAmount();
+ for (int i = 0; i < heldItemSlot; i++) {
+ ItemStack item = inventory.getItem(i);
+ if (!SpigotUtil.isItemPresent(item)) {
+ return null;
+ }
+ if (item.isSimilar(item)) {
+ amt -= Math.max(0, item.getMaxStackSize() - item.getAmount());
+ if (amt <= 0) {
+ return null;
+ }
+ }
+ }
+
+ added = added.clone();
+ added.setAmount(amt + Math.max(0, heldItem == null ? 0 : heldItem.getAmount()));
+ return added;
+ }
+
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/Logging.java b/dicore3/core/src/main/java/io/dico/dicore/Logging.java
index fa2a676..50c4b52 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/Logging.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/Logging.java
@@ -1,116 +1,116 @@
-package io.dico.dicore;
-
-import java.util.logging.Logger;
-
-public interface Logging {
-
- void info(Object o);
-
- void warn(Object o);
-
- void error(Object o);
-
- void debug(Object o);
-
- void setDebugging(boolean debugging);
-
- boolean isDebugging();
-
- class RootLogging implements Logging {
- private final String prefix;
- private final Logger root;
- private boolean debugging;
-
- public RootLogging(String prefix, Logger root, boolean debugging) {
- this.root = root;
- this.prefix = prefix;
- this.debugging = debugging;
- }
-
- @Override
- public void info(Object o) {
- root.info(prefix(o));
- }
-
- @Override
- public void warn(Object o) {
- root.warning(prefix(o));
- }
-
- @Override
- public void error(Object o) {
- root.severe(prefix(o));
- }
-
- @Override
- public void debug(Object o) {
- if (debugging) {
- root.info(String.format("[DEBUG] %s", prefix(o)));
- }
- }
-
- @Override
- public boolean isDebugging() {
- return debugging;
- }
-
- @Override
- public void setDebugging(boolean debugging) {
- this.debugging = debugging;
- }
-
- private String prefix(Object o) {
- return String.format("[%s] %s", prefix, String.valueOf(o));
- }
- }
-
- class SubLogging implements Logging {
- protected String prefix;
- private final Logging superLogger;
- private boolean debugging;
-
- public SubLogging(String prefix, Logging superLogger, boolean debugging) {
- this.superLogger = superLogger;
- this.prefix = prefix;
- this.debugging = debugging;
- }
-
- @Override
- public void info(Object o) {
- superLogger.info(prefix(o));
- }
-
- @Override
- public void warn(Object o) {
- superLogger.warn(prefix(o));
- }
-
- @Override
- public void error(Object o) {
- superLogger.error(prefix(o));
- }
-
- @Override
- public void debug(Object o) {
- if (debugging) {
- superLogger.info(String.format("[DEBUG] %s", prefix(o)));
- }
- }
-
- @Override
- public boolean isDebugging() {
- return debugging;
- }
-
- @Override
- public void setDebugging(boolean debugging) {
- this.debugging = debugging;
- }
-
- private String prefix(Object o) {
- return String.format("[%s] %s", prefix, String.valueOf(o));
- }
-
- }
-
-}
+package io.dico.dicore;
+
+import java.util.logging.Logger;
+
+public interface Logging {
+
+ void info(Object o);
+
+ void warn(Object o);
+
+ void error(Object o);
+
+ void debug(Object o);
+
+ void setDebugging(boolean debugging);
+
+ boolean isDebugging();
+
+ class RootLogging implements Logging {
+ private final String prefix;
+ private final Logger root;
+ private boolean debugging;
+
+ public RootLogging(String prefix, Logger root, boolean debugging) {
+ this.root = root;
+ this.prefix = prefix;
+ this.debugging = debugging;
+ }
+
+ @Override
+ public void info(Object o) {
+ root.info(prefix(o));
+ }
+
+ @Override
+ public void warn(Object o) {
+ root.warning(prefix(o));
+ }
+
+ @Override
+ public void error(Object o) {
+ root.severe(prefix(o));
+ }
+
+ @Override
+ public void debug(Object o) {
+ if (debugging) {
+ root.info(String.format("[DEBUG] %s", prefix(o)));
+ }
+ }
+
+ @Override
+ public boolean isDebugging() {
+ return debugging;
+ }
+
+ @Override
+ public void setDebugging(boolean debugging) {
+ this.debugging = debugging;
+ }
+
+ private String prefix(Object o) {
+ return String.format("[%s] %s", prefix, String.valueOf(o));
+ }
+ }
+
+ class SubLogging implements Logging {
+ protected String prefix;
+ private final Logging superLogger;
+ private boolean debugging;
+
+ public SubLogging(String prefix, Logging superLogger, boolean debugging) {
+ this.superLogger = superLogger;
+ this.prefix = prefix;
+ this.debugging = debugging;
+ }
+
+ @Override
+ public void info(Object o) {
+ superLogger.info(prefix(o));
+ }
+
+ @Override
+ public void warn(Object o) {
+ superLogger.warn(prefix(o));
+ }
+
+ @Override
+ public void error(Object o) {
+ superLogger.error(prefix(o));
+ }
+
+ @Override
+ public void debug(Object o) {
+ if (debugging) {
+ superLogger.info(String.format("[DEBUG] %s", prefix(o)));
+ }
+ }
+
+ @Override
+ public boolean isDebugging() {
+ return debugging;
+ }
+
+ @Override
+ public void setDebugging(boolean debugging) {
+ this.debugging = debugging;
+ }
+
+ private String prefix(Object o) {
+ return String.format("[%s] %s", prefix, String.valueOf(o));
+ }
+
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/Reflection.java b/dicore3/core/src/main/java/io/dico/dicore/Reflection.java
index b7b1ed4..2452d75 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/Reflection.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/Reflection.java
@@ -1,780 +1,780 @@
-package io.dico.dicore;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-/**
- * Reflective utilities
- */
-@SuppressWarnings("unchecked")
-public class Reflection {
- private static final ExceptionHandler exceptionHandler;
- private static final Field fieldModifiersField = restrictedSearchField(Field.class, "modifiers");
- private static Consumer<String> errorTarget;
-
- private Reflection() {
-
- }
-
- static {
- exceptionHandler = new ExceptionHandler() {
- @Override
- public void handle(Throwable ex) {
- handleGenericException(ex);
- }
-
- @Override
- public Object handleGenericException(Throwable ex, Object... args) {
- String action = args.length == 0 || !(args[0] instanceof String) ? "executing a reflective operation" : (String) args[0];
- ExceptionHandler.log(errorTarget, action, ex);
- return null;
- }
- };
-
- // don't use method reference here: the current reference in System.out would be cached.
- setErrorTarget(msg -> System.out.println(msg));
- }
-
- /**
- * Sets the output where ReflectiveOperationException's and similar are sent.
- * This defaults to {@link System#out}.
- *
- * @param target The new output
- * @throws NullPointerException if target is null
- */
- public static void setErrorTarget(Consumer<String> target) {
- errorTarget = Objects.requireNonNull(target);
- }
-
- /**
- * This search modifier tells the implementation that it should subsequently search superclasses for the field/method.
- * Using this modifier means a call to {@link #deepSearchField(Class, String)} will be used instead of {@link #restrictedSearchField(Class, String)}
- * and a call to {@link #deepSearchMethod(Class, String, Class[])} will be used instead of {@link #restrictedSearchMethod(Class, String, Class[])}
- */
- public static final int DEEP_SEARCH = 0x1;
-
- /**
- * This search modifier applies only to fields, and tells the implementation that a final modifier might be present on a found field, and that it should be removed.
- */
- public static final int REMOVE_FINAL = 0x2;
-
- /**
- * This search modifier applies only to methods, and tells the implementation that it should completely ignore parameter types and return the first method with a matching name
- * The implementation uses {@link Class#getDeclaredMethods()} instead of {@link Class#getDeclaredMethod(String, Class[])} if this modifier is set.
- */
- public static final int IGNORE_PARAMS = 0x2;
-
- /*
- ### FIELD METHODS ###
- */
-
- /**
- * Search a field of any accessibility within the class or any of its superclasses.
- * The first field with the given name that is found will be returned.
- * <p>
- * If a field is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the field will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Field is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the field exists, you'll have to use try/catch for that.
- *
- * @param clazz The lowest class in the ladder to start searching from
- * @param fieldName The name of the field
- * //@param fieldType the type of the field, or null if it can be any.
- * @return The field
- * @throws NullPointerException if clazz is null or fieldName is null
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #restrictedSearchField(Class, String)
- */
- public static Field deepSearchField(Class<?> clazz, String fieldName/*, Class<?> fieldType*/) {
- Class<?> currentClass = clazz;
- Field result;
- do {
- // throws NPE if class or fieldName is null
- result = internalSearchField(clazz, fieldName);
- if (result != null) {
- return result;
- }
- currentClass = currentClass.getSuperclass();
- } while (currentClass != null);
-
- throw new IllegalArgumentException("field not found in " + clazz.getCanonicalName() + " and superclasses: " + fieldName);
- }
-
- /**
- * Search a field of any accessibility within the class, but not its superclasses.
- * <p>
- * If a field is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the field will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Field is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the field exists, you'll have to use try/catch for that.
- *
- * @param clazz The only class to search for the field
- * @param fieldName The name of the field
- * @return The field
- * @throws NullPointerException if clazz or fieldName is null
- * @throws IllegalArgumentException if the field does not exist
- */
- public static Field restrictedSearchField(Class<?> clazz, String fieldName) {
- Field result = internalSearchField(clazz, fieldName);
- if (result == null) {
- throw new IllegalArgumentException("field not found in " + clazz.getCanonicalName() + ": " + fieldName);
- }
- return result;
- }
-
- /**
- * Searches for a field using the given search method.
- *
- * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
- * @param clazz The class to search in/from
- * @param fieldName Name of the field
- * @return The field
- * @throws NullPointerException if clazz or fieldName is null
- * @throws IllegalArgumentException if the field is not found
- */
- public static Field searchField(int modifiers, Class<?> clazz, String fieldName) {
- Field result;
- if ((modifiers & DEEP_SEARCH) != 0) {
- result = deepSearchField(clazz, fieldName);
- } else {
- result = restrictedSearchField(clazz, fieldName);
- }
- if ((modifiers & REMOVE_FINAL) != 0) {
- removeFinalModifier(result);
- }
- return result;
- }
-
- /**
- * @return The same as {@link #restrictedSearchField(Class, String)}, but returns null instead of throwing IllegalArgumentException
- * @see #restrictedSearchField(Class, String)
- */
- private static Field internalSearchField(Class<?> clazz, String fieldName) {
- Field result;
- try {
- // throws NullPointerException if either clazz or fieldName are null.
- result = clazz.getDeclaredField(fieldName);
- } catch (NoSuchFieldException | SecurityException ex) {
- return null;
- }
-
- if (!result.isAccessible()) try {
- result.setAccessible(true);
- } catch (SecurityException ignored) {
-
- }
-
- return result;
- }
-
- /**
- * Attempts to remove existing final modifier of the given field
- * This method should always return true.
- *
- * @param field The field whose final modifier to remove
- * @return true if the field most definitely has no final modifier after this call
- * @throws NullPointerException if field is null
- */
- public static boolean removeFinalModifier(Field field) {
- Objects.requireNonNull(field);
- try {
- int modifiers = (int) fieldModifiersField.get(field);
- if (modifiers != (modifiers &= ~Modifier.FINAL)) {
- fieldModifiersField.set(field, modifiers);
- }
- return true;
- } catch (Exception ex) {
- return false;
- }
- }
-
- /**
- * Gets field value of the field named fieldName and the given instance
- * To find the field, {@link #deepSearchField(Class, String)} is used (DEEP search method).
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param instance The instance whose field value to get
- * @param fieldName the name of the field
- * @param <T> The expected/known field type
- * @return The field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #deepSearchField(Class, String)
- * @see #getFieldValue(Class, String, Object)
- */
- public static <T> T getFieldValue(Object instance, String fieldName) {
- return getFieldValue(deepSearchField(instance.getClass(), fieldName), instance);
- }
-
- /**
- * Gets field value of the field named fieldName and the given instance
- * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param clazz The class to search for the field
- * @param instance The instance whose field value to get
- * @param fieldName the name of the field
- * @param <T> The expected/known field type
- * @return The field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #restrictedSearchField(Class, String)
- * @see #getFieldValue(Field, Object)
- */
- public static <T> T getFieldValue(Class<?> clazz, String fieldName, Object instance) {
- return getFieldValue(restrictedSearchField(clazz, fieldName), instance);
- }
-
- /**
- * Gets field value of the field named fieldName and the given instance
- * To find the field, {@link #searchField(int, Class, String)} is used.
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
- * @param clazz The class to search for the field
- * @param instance The instance whose field value to get
- * @param fieldName the name of the field
- * @param <T> The expected/known field type
- * @return The field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #searchField(int, Class, String)
- * @see #getFieldValue(Field, Object)
- */
- public static <T> T getFieldValue(int modifiers, Class<?> clazz, String fieldName, Object instance) {
- return getFieldValue(searchField(modifiers, clazz, fieldName), instance);
- }
-
- /**
- * Gets field value of the given field and the given instance
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param field the field
- * @param instance The instance whose field value to get
- * @param <T> The expected/known field type
- * @return The field value
- */
- public static <T> T getFieldValue(Field field, Object instance) {
- return exceptionHandler.supplySafe(() -> (T) field.get(instance));
- }
-
- /**
- * Gets static field value of the field named fieldName
- * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param clazz The class to search for the field
- * @param fieldName the name of the field
- * @param <T> The expected/known field type
- * @return The field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #restrictedSearchField(Class, String)
- * @see #getStaticFieldValue(Field)
- */
- public static <T> T getStaticFieldValue(Class<?> clazz, String fieldName) {
- return getStaticFieldValue(restrictedSearchField(clazz, fieldName));
- }
-
- /**
- * Gets static field value of the field named fieldName
- * To find the field, {@link #searchField(int, Class, String)} is used.
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
- * @param clazz The class to search for the field
- * @param fieldName the name of the field
- * @param <T> The expected/known field type
- * @return The field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #deepSearchField(Class, String)
- * @see #getStaticFieldValue(Field)
- */
- public static <T> T getStaticFieldValue(int modifiers, Class<?> clazz, String fieldName) {
- return getStaticFieldValue(searchField(modifiers, clazz, fieldName));
- }
-
- /**
- * Gets static field value
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- * <p>
- * Equivalent to the call {@code getFieldValue(field, (Object) null)}
- *
- * @param field the field
- * @param <T> The expected/known field type
- * @return The field value
- * @see #getFieldValue(Field, Object)
- */
- public static <T> T getStaticFieldValue(Field field) {
- return getFieldValue(field, (Object) null);
- }
-
- /**
- * Sets field value of the field named fieldName and the given instance
- * To find the field, {@link #deepSearchField(Class, String)} is used (DEEP search method).
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param instance The instance whose field value to set
- * @param fieldName the name of the field
- * @param newValue the new field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #deepSearchField(Class, String)
- * @see #setFieldValue(Class, String, Object, Object)
- */
- public static void setFieldValue(Object instance, String fieldName, Object newValue) {
- setFieldValue(deepSearchField(instance.getClass(), fieldName), instance, newValue);
- }
-
- /**
- * Sets field value of the field named fieldName and the given instance
- * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param clazz The class to search for the field
- * @param fieldName the name of the field
- * @param instance The field owner
- * @param newValue The new field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #restrictedSearchField(Class, String)
- * @see #setFieldValue(Field, Object, Object)
- */
- public static void setFieldValue(Class<?> clazz, String fieldName, Object instance, Object newValue) {
- setFieldValue(restrictedSearchField(clazz, fieldName), instance, newValue);
- }
-
- /**
- * Sets field value of the field named fieldName and the given instance
- * To find the field, {@link #searchField(int, Class, String)} is used.
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
- * @param clazz The class to search for the field
- * @param instance The instance whose field value to set
- * @param fieldName the name of the field
- * @param newValue The new field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #searchField(int, Class, String)
- * @see #setFieldValue(Field, Object, Object)
- */
- public static void setFieldValue(int modifiers, Class<?> clazz, String fieldName, Object instance, Object newValue) {
- setFieldValue(searchField(modifiers, clazz, fieldName), instance, newValue);
- }
-
- /**
- * Sets a field value
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param field The field
- * @param instance The field owner
- * @param newValue The new field value
- */
- public static void setFieldValue(Field field, Object instance, Object newValue) {
- exceptionHandler.runSafe(() -> field.set(instance, newValue));
- }
-
- /**
- * Sets static field value of the field name fieldName
- * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param clazz The class to search for the field
- * @param fieldName the name of the field
- * @param newValue The new field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #restrictedSearchField(Class, String)
- * @see #setStaticFieldValue(Field, Object)
- */
- public static void setStaticFieldValue(Class<?> clazz, String fieldName, Object newValue) {
- setStaticFieldValue(restrictedSearchField(clazz, fieldName), newValue);
- }
-
- /**
- * Sets static field value of the field named fieldName
- * To find the field, {@link #searchField(int, Class, String)} is used.
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
- * @param clazz The class to search for the field
- * @param fieldName the name of the field
- * @param newValue The new field value
- * @throws IllegalArgumentException if the field doesn't exist
- * @see #searchField(int, Class, String)
- * @see #setStaticFieldValue(Field, Object)
- */
- public static void setStaticFieldValue(int modifiers, Class<?> clazz, String fieldName, Object newValue) {
- setStaticFieldValue(searchField(modifiers, clazz, fieldName), newValue);
- }
-
- /**
- * Sets a static field value
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param field The field
- * @param newValue The new field value
- */
- public static void setStaticFieldValue(Field field, Object newValue) {
- setFieldValue(field, (Object) null, newValue);
- }
-
- /*
- ### METHOD METHODS ###
- */
-
- /**
- * Search a method of any accessibility within the class or any of its superclasses.
- * The first method with the given name that is found will be returned.
- * <p>
- * If a method is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
- *
- * @param clazz The lowest class in the ladder to start searching from
- * @param methodName The name of the method
- * @param parameterTypes the parameter types of the sought method.
- * @return The method
- * @throws NullPointerException if clazz is null or methodName is null
- * @throws IllegalArgumentException if the method doesn't exist
- * @see #restrictedSearchMethod(Class, String, Class[])
- */
- public static Method deepSearchMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
- return deepSearchMethod(0, clazz, methodName, parameterTypes);
- }
-
- /**
- * Search a method of any accessibility within the class or any of its superclasses.
- * The first method with the given name that is found will be returned.
- * <p>
- * If a method is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
- *
- * @param modifiers The modifiers for method search. Can have {@link #IGNORE_PARAMS}
- * @param clazz The lowest class in the ladder to start searching from
- * @param methodName The name of the method
- * @param parameterTypes the parameter types of the sought method.
- * @return The method
- * @throws NullPointerException if clazz is null or methodName is null
- * @throws IllegalArgumentException if the method doesn't exist
- * @see #restrictedSearchMethod(Class, String, Class[])
- */
- public static Method deepSearchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
- Class<?> currentClass = clazz;
- Method result;
- do {
- // throws NPE if class or methodName is null
- result = internalSearchMethod(modifiers, currentClass, methodName, parameterTypes);
- if (result != null) {
- return result;
- }
- currentClass = currentClass.getSuperclass();
- } while (currentClass != null);
-
- throw new IllegalArgumentException("method not found in " + clazz.getCanonicalName() + " and superclasses: " + methodName);
- }
-
- /**
- * Search a method of any accessibility within the class, but not its superclasses.
- * <p>
- * If a method is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
- *
- * @param clazz The only class to search for the method
- * @param methodName The name of the method
- * @param parameterTypes the parameter types of the sought method.
- * @return The method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method does not exist
- */
- public static Method restrictedSearchMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
- return restrictedSearchMethod(0, clazz, methodName, parameterTypes);
- }
-
- /**
- * Search a method of any accessibility within the class, but not its superclasses.
- * <p>
- * If a method is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
- *
- * @param modifiers The modifiers for method search. Can have {@link #IGNORE_PARAMS}
- * @param clazz The only class to search for the method
- * @param methodName The name of the method
- * @param parameterTypes the parameter types of the sought method.
- * @return The method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method does not exist
- */
- public static Method restrictedSearchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
- Method result = internalSearchMethod(modifiers, clazz, methodName, parameterTypes);
- if (result == null) {
- throw new IllegalArgumentException("method not found in " + clazz.getCanonicalName() + ": " + methodName);
- }
- return result;
- }
-
- /**
- * Searches for a method using the given search method.
- * <p>
- * If a method is found and it is not accessible, this method attempts to make it accessible.
- * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
- * <p>
- * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
- * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
- *
- * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
- * @param clazz The class to search in/from
- * @param methodName Name of the method
- * @param parameterTypes the parameter types of the sought method.
- * @return The method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method is not found
- */
- public static Method searchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
- if ((modifiers & DEEP_SEARCH) != 0) {
- return deepSearchMethod(modifiers, clazz, methodName, parameterTypes);
- } else {
- return restrictedSearchMethod(modifiers, clazz, methodName, parameterTypes);
- }
- }
-
- /**
- * @return The same as {@link #restrictedSearchMethod(Class, String, Class[]) }, but returns null instead of throwing IllegalArgumentException
- * @see #restrictedSearchMethod(Class, String, Class[])
- */
- private static Method internalSearchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
- Method result = null;
-
- if ((modifiers & IGNORE_PARAMS) != 0) {
-
- // throws NullPointerException if either clazz or methodName are null.
- methodName = methodName.intern();
- for (Method method : clazz.getDeclaredMethods()) {
- // all method names are interned. Identity comparison is much faster.
- if (method.getName() == methodName) {
- result = method;
- break;
- }
- }
-
- if (result == null) {
- return null;
- }
-
- } else {
-
- try {
- // throws NullPointerException if either clazz or methodName are null.
- result = clazz.getDeclaredMethod(methodName, parameterTypes);
- } catch (NoSuchMethodException | SecurityException ex) {
- return null;
- }
-
- }
-
- if (!result.isAccessible()) try {
- result.setAccessible(true);
- } catch (SecurityException ignored) {
-
- }
-
- return result;
- }
-
- /**
- * Invokes the method named methodName with the given instance and arguments
- * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters,
- * modifiers {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}, and the class {@link Object#getClass() instance.getClass()}
- * <p>
- * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
- * and call {@link #invokeMethod(Method, Object, Object...)}
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param methodName Name of the method
- * @param instance The instance to invoke the method on
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @throws NullPointerException if instance or methodName is null
- * @throws IllegalArgumentException if the method is not found
- * @see #invokeMethod(Method, Object, Object...)
- */
- public static <T> T invokeMethod(Object instance, String methodName, Object... args) {
- return invokeMethod(searchMethod(DEEP_SEARCH | IGNORE_PARAMS, instance.getClass(), methodName), instance, args);
- }
-
- /**
- * Invokes the method named methodName with the given instance and arguments
- * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters,
- * as well as the modifier {@link #IGNORE_PARAMS}
- * <p>
- * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
- * and call {@link #invokeMethod(Method, Object, Object...)}
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param clazz The class to search in/from
- * @param methodName Name of the method
- * @param instance The instance to invoke the method on
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method is not found
- * @see #invokeMethod(Method, Object, Object...)
- */
- public static <T> T invokeMethod(Class<?> clazz, String methodName, Object instance, Object... args) {
- return invokeMethod(searchMethod(IGNORE_PARAMS, clazz, methodName), instance, args);
- }
-
- /**
- * Invokes the method named methodName with the given instance and arguments
- * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters.
- * For this search, the result of calling {@link Object#getClass() instance.getClass()} is used.
- * <p>
- * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
- * and call {@link #invokeMethod(Method, Object, Object...)}
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
- * @param methodName Name of the method
- * @param instance The instance to invoke the method on
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @throws NullPointerException if instance or methodName is null
- * @throws IllegalArgumentException if the method is not found
- * @see #invokeMethod(Method, Object, Object...)
- */
- public static <T> T invokeMethod(int modifiers, Object instance, String methodName, Object... args) {
- return invokeMethod(searchMethod(modifiers, instance.getClass(), methodName), instance, args);
- }
-
- /**
- * Invokes the method named methodName with the given instance and arguments
- * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters.
- * <p>
- * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
- * and call {@link #invokeMethod(Method, Object, Object...)}
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
- * @param clazz The class to search in/from
- * @param methodName Name of the method
- * @param instance The instance to invoke the method on
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method is not found
- * @see #invokeMethod(Method, Object, Object...)
- */
- public static <T> T invokeMethod(int modifiers, Class<?> clazz, String methodName, Object instance, Object... args) {
- return invokeMethod(searchMethod(modifiers, clazz, methodName), instance, args);
- }
-
- /**
- * Invokes the method with the given instance and arguments
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param method The method to invoke
- * @param instance The instance to invoke the method on
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- */
- public static <T> T invokeMethod(Method method, Object instance, Object... args) {
- return exceptionHandler.supplySafe(() -> (T) method.invoke(instance, args));
- }
-
- /**
- * Invokes the static method named methodName with the given arguments
- * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters,
- * as well as the modifier {@link #IGNORE_PARAMS}
- * <p>
- * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
- * and call {@link #invokeMethod(Method, Object, Object...)}
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param clazz The class to search in/from
- * @param methodName Name of the method
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method is not found
- * @see #invokeStaticMethod(Method, Object...)
- */
- public static <T> T invokeStaticMethod(Class<?> clazz, String methodName, Object... args) {
- return invokeStaticMethod(searchMethod(IGNORE_PARAMS, clazz, methodName), args);
- }
-
- /**
- * Invokes the static method named methodName with the given arguments
- * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters.
- * <p>
- * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
- * and call {@link #invokeMethod(Method, Object, Object...)}
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
- * @param clazz The class to search in/from
- * @param methodName Name of the method
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @throws NullPointerException if clazz or methodName is null
- * @throws IllegalArgumentException if the method is not found
- * @see #invokeStaticMethod(Method, Object...)
- */
- public static <T> T invokeStaticMethod(int modifiers, Class<?> clazz, String methodName, Object... args) {
- return invokeStaticMethod(searchMethod(modifiers, clazz, methodName), args);
- }
-
- /**
- * Invokes the static method with the given arguments
- * <p>
- * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
- *
- * @param method The method to invoke
- * @param args The arguments to use in the method call
- * @param <T> The expected/known method return type
- * @return The result of calling the method
- * @see #invokeMethod(Method, Object, Object...)
- */
- public static <T> T invokeStaticMethod(Method method, Object... args) {
- return invokeMethod(method, (Object) null, args);
- }
-
-}
+package io.dico.dicore;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+/**
+ * Reflective utilities
+ */
+@SuppressWarnings("unchecked")
+public class Reflection {
+ private static final ExceptionHandler exceptionHandler;
+ private static final Field fieldModifiersField = restrictedSearchField(Field.class, "modifiers");
+ private static Consumer<String> errorTarget;
+
+ private Reflection() {
+
+ }
+
+ static {
+ exceptionHandler = new ExceptionHandler() {
+ @Override
+ public void handle(Throwable ex) {
+ handleGenericException(ex);
+ }
+
+ @Override
+ public Object handleGenericException(Throwable ex, Object... args) {
+ String action = args.length == 0 || !(args[0] instanceof String) ? "executing a reflective operation" : (String) args[0];
+ ExceptionHandler.log(errorTarget, action, ex);
+ return null;
+ }
+ };
+
+ // don't use method reference here: the current reference in System.out would be cached.
+ setErrorTarget(msg -> System.out.println(msg));
+ }
+
+ /**
+ * Sets the output where ReflectiveOperationException's and similar are sent.
+ * This defaults to {@link System#out}.
+ *
+ * @param target The new output
+ * @throws NullPointerException if target is null
+ */
+ public static void setErrorTarget(Consumer<String> target) {
+ errorTarget = Objects.requireNonNull(target);
+ }
+
+ /**
+ * This search modifier tells the implementation that it should subsequently search superclasses for the field/method.
+ * Using this modifier means a call to {@link #deepSearchField(Class, String)} will be used instead of {@link #restrictedSearchField(Class, String)}
+ * and a call to {@link #deepSearchMethod(Class, String, Class[])} will be used instead of {@link #restrictedSearchMethod(Class, String, Class[])}
+ */
+ public static final int DEEP_SEARCH = 0x1;
+
+ /**
+ * This search modifier applies only to fields, and tells the implementation that a final modifier might be present on a found field, and that it should be removed.
+ */
+ public static final int REMOVE_FINAL = 0x2;
+
+ /**
+ * This search modifier applies only to methods, and tells the implementation that it should completely ignore parameter types and return the first method with a matching name
+ * The implementation uses {@link Class#getDeclaredMethods()} instead of {@link Class#getDeclaredMethod(String, Class[])} if this modifier is set.
+ */
+ public static final int IGNORE_PARAMS = 0x2;
+
+ /*
+ ### FIELD METHODS ###
+ */
+
+ /**
+ * Search a field of any accessibility within the class or any of its superclasses.
+ * The first field with the given name that is found will be returned.
+ * <p>
+ * If a field is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the field will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Field is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the field exists, you'll have to use try/catch for that.
+ *
+ * @param clazz The lowest class in the ladder to start searching from
+ * @param fieldName The name of the field
+ * //@param fieldType the type of the field, or null if it can be any.
+ * @return The field
+ * @throws NullPointerException if clazz is null or fieldName is null
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #restrictedSearchField(Class, String)
+ */
+ public static Field deepSearchField(Class<?> clazz, String fieldName/*, Class<?> fieldType*/) {
+ Class<?> currentClass = clazz;
+ Field result;
+ do {
+ // throws NPE if class or fieldName is null
+ result = internalSearchField(clazz, fieldName);
+ if (result != null) {
+ return result;
+ }
+ currentClass = currentClass.getSuperclass();
+ } while (currentClass != null);
+
+ throw new IllegalArgumentException("field not found in " + clazz.getCanonicalName() + " and superclasses: " + fieldName);
+ }
+
+ /**
+ * Search a field of any accessibility within the class, but not its superclasses.
+ * <p>
+ * If a field is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the field will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Field is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the field exists, you'll have to use try/catch for that.
+ *
+ * @param clazz The only class to search for the field
+ * @param fieldName The name of the field
+ * @return The field
+ * @throws NullPointerException if clazz or fieldName is null
+ * @throws IllegalArgumentException if the field does not exist
+ */
+ public static Field restrictedSearchField(Class<?> clazz, String fieldName) {
+ Field result = internalSearchField(clazz, fieldName);
+ if (result == null) {
+ throw new IllegalArgumentException("field not found in " + clazz.getCanonicalName() + ": " + fieldName);
+ }
+ return result;
+ }
+
+ /**
+ * Searches for a field using the given search method.
+ *
+ * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
+ * @param clazz The class to search in/from
+ * @param fieldName Name of the field
+ * @return The field
+ * @throws NullPointerException if clazz or fieldName is null
+ * @throws IllegalArgumentException if the field is not found
+ */
+ public static Field searchField(int modifiers, Class<?> clazz, String fieldName) {
+ Field result;
+ if ((modifiers & DEEP_SEARCH) != 0) {
+ result = deepSearchField(clazz, fieldName);
+ } else {
+ result = restrictedSearchField(clazz, fieldName);
+ }
+ if ((modifiers & REMOVE_FINAL) != 0) {
+ removeFinalModifier(result);
+ }
+ return result;
+ }
+
+ /**
+ * @return The same as {@link #restrictedSearchField(Class, String)}, but returns null instead of throwing IllegalArgumentException
+ * @see #restrictedSearchField(Class, String)
+ */
+ private static Field internalSearchField(Class<?> clazz, String fieldName) {
+ Field result;
+ try {
+ // throws NullPointerException if either clazz or fieldName are null.
+ result = clazz.getDeclaredField(fieldName);
+ } catch (NoSuchFieldException | SecurityException ex) {
+ return null;
+ }
+
+ if (!result.isAccessible()) try {
+ result.setAccessible(true);
+ } catch (SecurityException ignored) {
+
+ }
+
+ return result;
+ }
+
+ /**
+ * Attempts to remove existing final modifier of the given field
+ * This method should always return true.
+ *
+ * @param field The field whose final modifier to remove
+ * @return true if the field most definitely has no final modifier after this call
+ * @throws NullPointerException if field is null
+ */
+ public static boolean removeFinalModifier(Field field) {
+ Objects.requireNonNull(field);
+ try {
+ int modifiers = (int) fieldModifiersField.get(field);
+ if (modifiers != (modifiers &= ~Modifier.FINAL)) {
+ fieldModifiersField.set(field, modifiers);
+ }
+ return true;
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
+ /**
+ * Gets field value of the field named fieldName and the given instance
+ * To find the field, {@link #deepSearchField(Class, String)} is used (DEEP search method).
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param instance The instance whose field value to get
+ * @param fieldName the name of the field
+ * @param <T> The expected/known field type
+ * @return The field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #deepSearchField(Class, String)
+ * @see #getFieldValue(Class, String, Object)
+ */
+ public static <T> T getFieldValue(Object instance, String fieldName) {
+ return getFieldValue(deepSearchField(instance.getClass(), fieldName), instance);
+ }
+
+ /**
+ * Gets field value of the field named fieldName and the given instance
+ * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param clazz The class to search for the field
+ * @param instance The instance whose field value to get
+ * @param fieldName the name of the field
+ * @param <T> The expected/known field type
+ * @return The field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #restrictedSearchField(Class, String)
+ * @see #getFieldValue(Field, Object)
+ */
+ public static <T> T getFieldValue(Class<?> clazz, String fieldName, Object instance) {
+ return getFieldValue(restrictedSearchField(clazz, fieldName), instance);
+ }
+
+ /**
+ * Gets field value of the field named fieldName and the given instance
+ * To find the field, {@link #searchField(int, Class, String)} is used.
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
+ * @param clazz The class to search for the field
+ * @param instance The instance whose field value to get
+ * @param fieldName the name of the field
+ * @param <T> The expected/known field type
+ * @return The field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #searchField(int, Class, String)
+ * @see #getFieldValue(Field, Object)
+ */
+ public static <T> T getFieldValue(int modifiers, Class<?> clazz, String fieldName, Object instance) {
+ return getFieldValue(searchField(modifiers, clazz, fieldName), instance);
+ }
+
+ /**
+ * Gets field value of the given field and the given instance
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param field the field
+ * @param instance The instance whose field value to get
+ * @param <T> The expected/known field type
+ * @return The field value
+ */
+ public static <T> T getFieldValue(Field field, Object instance) {
+ return exceptionHandler.supplySafe(() -> (T) field.get(instance));
+ }
+
+ /**
+ * Gets static field value of the field named fieldName
+ * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param clazz The class to search for the field
+ * @param fieldName the name of the field
+ * @param <T> The expected/known field type
+ * @return The field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #restrictedSearchField(Class, String)
+ * @see #getStaticFieldValue(Field)
+ */
+ public static <T> T getStaticFieldValue(Class<?> clazz, String fieldName) {
+ return getStaticFieldValue(restrictedSearchField(clazz, fieldName));
+ }
+
+ /**
+ * Gets static field value of the field named fieldName
+ * To find the field, {@link #searchField(int, Class, String)} is used.
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
+ * @param clazz The class to search for the field
+ * @param fieldName the name of the field
+ * @param <T> The expected/known field type
+ * @return The field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #deepSearchField(Class, String)
+ * @see #getStaticFieldValue(Field)
+ */
+ public static <T> T getStaticFieldValue(int modifiers, Class<?> clazz, String fieldName) {
+ return getStaticFieldValue(searchField(modifiers, clazz, fieldName));
+ }
+
+ /**
+ * Gets static field value
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ * <p>
+ * Equivalent to the call {@code getFieldValue(field, (Object) null)}
+ *
+ * @param field the field
+ * @param <T> The expected/known field type
+ * @return The field value
+ * @see #getFieldValue(Field, Object)
+ */
+ public static <T> T getStaticFieldValue(Field field) {
+ return getFieldValue(field, (Object) null);
+ }
+
+ /**
+ * Sets field value of the field named fieldName and the given instance
+ * To find the field, {@link #deepSearchField(Class, String)} is used (DEEP search method).
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param instance The instance whose field value to set
+ * @param fieldName the name of the field
+ * @param newValue the new field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #deepSearchField(Class, String)
+ * @see #setFieldValue(Class, String, Object, Object)
+ */
+ public static void setFieldValue(Object instance, String fieldName, Object newValue) {
+ setFieldValue(deepSearchField(instance.getClass(), fieldName), instance, newValue);
+ }
+
+ /**
+ * Sets field value of the field named fieldName and the given instance
+ * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param clazz The class to search for the field
+ * @param fieldName the name of the field
+ * @param instance The field owner
+ * @param newValue The new field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #restrictedSearchField(Class, String)
+ * @see #setFieldValue(Field, Object, Object)
+ */
+ public static void setFieldValue(Class<?> clazz, String fieldName, Object instance, Object newValue) {
+ setFieldValue(restrictedSearchField(clazz, fieldName), instance, newValue);
+ }
+
+ /**
+ * Sets field value of the field named fieldName and the given instance
+ * To find the field, {@link #searchField(int, Class, String)} is used.
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
+ * @param clazz The class to search for the field
+ * @param instance The instance whose field value to set
+ * @param fieldName the name of the field
+ * @param newValue The new field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #searchField(int, Class, String)
+ * @see #setFieldValue(Field, Object, Object)
+ */
+ public static void setFieldValue(int modifiers, Class<?> clazz, String fieldName, Object instance, Object newValue) {
+ setFieldValue(searchField(modifiers, clazz, fieldName), instance, newValue);
+ }
+
+ /**
+ * Sets a field value
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param field The field
+ * @param instance The field owner
+ * @param newValue The new field value
+ */
+ public static void setFieldValue(Field field, Object instance, Object newValue) {
+ exceptionHandler.runSafe(() -> field.set(instance, newValue));
+ }
+
+ /**
+ * Sets static field value of the field name fieldName
+ * To find the field, {@link #restrictedSearchField(Class, String)} is used (RESTRICTED search method).
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param clazz The class to search for the field
+ * @param fieldName the name of the field
+ * @param newValue The new field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #restrictedSearchField(Class, String)
+ * @see #setStaticFieldValue(Field, Object)
+ */
+ public static void setStaticFieldValue(Class<?> clazz, String fieldName, Object newValue) {
+ setStaticFieldValue(restrictedSearchField(clazz, fieldName), newValue);
+ }
+
+ /**
+ * Sets static field value of the field named fieldName
+ * To find the field, {@link #searchField(int, Class, String)} is used.
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for field search. Can have {@link #DEEP_SEARCH} and {@link #REMOVE_FINAL}
+ * @param clazz The class to search for the field
+ * @param fieldName the name of the field
+ * @param newValue The new field value
+ * @throws IllegalArgumentException if the field doesn't exist
+ * @see #searchField(int, Class, String)
+ * @see #setStaticFieldValue(Field, Object)
+ */
+ public static void setStaticFieldValue(int modifiers, Class<?> clazz, String fieldName, Object newValue) {
+ setStaticFieldValue(searchField(modifiers, clazz, fieldName), newValue);
+ }
+
+ /**
+ * Sets a static field value
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param field The field
+ * @param newValue The new field value
+ */
+ public static void setStaticFieldValue(Field field, Object newValue) {
+ setFieldValue(field, (Object) null, newValue);
+ }
+
+ /*
+ ### METHOD METHODS ###
+ */
+
+ /**
+ * Search a method of any accessibility within the class or any of its superclasses.
+ * The first method with the given name that is found will be returned.
+ * <p>
+ * If a method is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
+ *
+ * @param clazz The lowest class in the ladder to start searching from
+ * @param methodName The name of the method
+ * @param parameterTypes the parameter types of the sought method.
+ * @return The method
+ * @throws NullPointerException if clazz is null or methodName is null
+ * @throws IllegalArgumentException if the method doesn't exist
+ * @see #restrictedSearchMethod(Class, String, Class[])
+ */
+ public static Method deepSearchMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+ return deepSearchMethod(0, clazz, methodName, parameterTypes);
+ }
+
+ /**
+ * Search a method of any accessibility within the class or any of its superclasses.
+ * The first method with the given name that is found will be returned.
+ * <p>
+ * If a method is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
+ *
+ * @param modifiers The modifiers for method search. Can have {@link #IGNORE_PARAMS}
+ * @param clazz The lowest class in the ladder to start searching from
+ * @param methodName The name of the method
+ * @param parameterTypes the parameter types of the sought method.
+ * @return The method
+ * @throws NullPointerException if clazz is null or methodName is null
+ * @throws IllegalArgumentException if the method doesn't exist
+ * @see #restrictedSearchMethod(Class, String, Class[])
+ */
+ public static Method deepSearchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+ Class<?> currentClass = clazz;
+ Method result;
+ do {
+ // throws NPE if class or methodName is null
+ result = internalSearchMethod(modifiers, currentClass, methodName, parameterTypes);
+ if (result != null) {
+ return result;
+ }
+ currentClass = currentClass.getSuperclass();
+ } while (currentClass != null);
+
+ throw new IllegalArgumentException("method not found in " + clazz.getCanonicalName() + " and superclasses: " + methodName);
+ }
+
+ /**
+ * Search a method of any accessibility within the class, but not its superclasses.
+ * <p>
+ * If a method is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
+ *
+ * @param clazz The only class to search for the method
+ * @param methodName The name of the method
+ * @param parameterTypes the parameter types of the sought method.
+ * @return The method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method does not exist
+ */
+ public static Method restrictedSearchMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+ return restrictedSearchMethod(0, clazz, methodName, parameterTypes);
+ }
+
+ /**
+ * Search a method of any accessibility within the class, but not its superclasses.
+ * <p>
+ * If a method is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
+ *
+ * @param modifiers The modifiers for method search. Can have {@link #IGNORE_PARAMS}
+ * @param clazz The only class to search for the method
+ * @param methodName The name of the method
+ * @param parameterTypes the parameter types of the sought method.
+ * @return The method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method does not exist
+ */
+ public static Method restrictedSearchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+ Method result = internalSearchMethod(modifiers, clazz, methodName, parameterTypes);
+ if (result == null) {
+ throw new IllegalArgumentException("method not found in " + clazz.getCanonicalName() + ": " + methodName);
+ }
+ return result;
+ }
+
+ /**
+ * Searches for a method using the given search method.
+ * <p>
+ * If a method is found and it is not accessible, this method attempts to make it accessible.
+ * If a {@link SecurityException} is thrown in the process, that is ignored and the method will be returned nonetheless.
+ * <p>
+ * This method throws IllegalArgumentException if the Method is not found, because, in most cases, that should never happen,
+ * and it should simplify debugging. In some cases, if you want to know if the method exists, you'll have to use try/catch for that.
+ *
+ * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
+ * @param clazz The class to search in/from
+ * @param methodName Name of the method
+ * @param parameterTypes the parameter types of the sought method.
+ * @return The method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ */
+ public static Method searchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+ if ((modifiers & DEEP_SEARCH) != 0) {
+ return deepSearchMethod(modifiers, clazz, methodName, parameterTypes);
+ } else {
+ return restrictedSearchMethod(modifiers, clazz, methodName, parameterTypes);
+ }
+ }
+
+ /**
+ * @return The same as {@link #restrictedSearchMethod(Class, String, Class[]) }, but returns null instead of throwing IllegalArgumentException
+ * @see #restrictedSearchMethod(Class, String, Class[])
+ */
+ private static Method internalSearchMethod(int modifiers, Class<?> clazz, String methodName, Class<?>... parameterTypes) {
+ Method result = null;
+
+ if ((modifiers & IGNORE_PARAMS) != 0) {
+
+ // throws NullPointerException if either clazz or methodName are null.
+ methodName = methodName.intern();
+ for (Method method : clazz.getDeclaredMethods()) {
+ // all method names are interned. Identity comparison is much faster.
+ if (method.getName() == methodName) {
+ result = method;
+ break;
+ }
+ }
+
+ if (result == null) {
+ return null;
+ }
+
+ } else {
+
+ try {
+ // throws NullPointerException if either clazz or methodName are null.
+ result = clazz.getDeclaredMethod(methodName, parameterTypes);
+ } catch (NoSuchMethodException | SecurityException ex) {
+ return null;
+ }
+
+ }
+
+ if (!result.isAccessible()) try {
+ result.setAccessible(true);
+ } catch (SecurityException ignored) {
+
+ }
+
+ return result;
+ }
+
+ /**
+ * Invokes the method named methodName with the given instance and arguments
+ * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters,
+ * modifiers {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}, and the class {@link Object#getClass() instance.getClass()}
+ * <p>
+ * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
+ * and call {@link #invokeMethod(Method, Object, Object...)}
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param methodName Name of the method
+ * @param instance The instance to invoke the method on
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @throws NullPointerException if instance or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ * @see #invokeMethod(Method, Object, Object...)
+ */
+ public static <T> T invokeMethod(Object instance, String methodName, Object... args) {
+ return invokeMethod(searchMethod(DEEP_SEARCH | IGNORE_PARAMS, instance.getClass(), methodName), instance, args);
+ }
+
+ /**
+ * Invokes the method named methodName with the given instance and arguments
+ * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters,
+ * as well as the modifier {@link #IGNORE_PARAMS}
+ * <p>
+ * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
+ * and call {@link #invokeMethod(Method, Object, Object...)}
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param clazz The class to search in/from
+ * @param methodName Name of the method
+ * @param instance The instance to invoke the method on
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ * @see #invokeMethod(Method, Object, Object...)
+ */
+ public static <T> T invokeMethod(Class<?> clazz, String methodName, Object instance, Object... args) {
+ return invokeMethod(searchMethod(IGNORE_PARAMS, clazz, methodName), instance, args);
+ }
+
+ /**
+ * Invokes the method named methodName with the given instance and arguments
+ * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters.
+ * For this search, the result of calling {@link Object#getClass() instance.getClass()} is used.
+ * <p>
+ * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
+ * and call {@link #invokeMethod(Method, Object, Object...)}
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
+ * @param methodName Name of the method
+ * @param instance The instance to invoke the method on
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @throws NullPointerException if instance or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ * @see #invokeMethod(Method, Object, Object...)
+ */
+ public static <T> T invokeMethod(int modifiers, Object instance, String methodName, Object... args) {
+ return invokeMethod(searchMethod(modifiers, instance.getClass(), methodName), instance, args);
+ }
+
+ /**
+ * Invokes the method named methodName with the given instance and arguments
+ * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters.
+ * <p>
+ * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
+ * and call {@link #invokeMethod(Method, Object, Object...)}
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
+ * @param clazz The class to search in/from
+ * @param methodName Name of the method
+ * @param instance The instance to invoke the method on
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ * @see #invokeMethod(Method, Object, Object...)
+ */
+ public static <T> T invokeMethod(int modifiers, Class<?> clazz, String methodName, Object instance, Object... args) {
+ return invokeMethod(searchMethod(modifiers, clazz, methodName), instance, args);
+ }
+
+ /**
+ * Invokes the method with the given instance and arguments
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param method The method to invoke
+ * @param instance The instance to invoke the method on
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ */
+ public static <T> T invokeMethod(Method method, Object instance, Object... args) {
+ return exceptionHandler.supplySafe(() -> (T) method.invoke(instance, args));
+ }
+
+ /**
+ * Invokes the static method named methodName with the given arguments
+ * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters,
+ * as well as the modifier {@link #IGNORE_PARAMS}
+ * <p>
+ * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
+ * and call {@link #invokeMethod(Method, Object, Object...)}
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param clazz The class to search in/from
+ * @param methodName Name of the method
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ * @see #invokeStaticMethod(Method, Object...)
+ */
+ public static <T> T invokeStaticMethod(Class<?> clazz, String methodName, Object... args) {
+ return invokeStaticMethod(searchMethod(IGNORE_PARAMS, clazz, methodName), args);
+ }
+
+ /**
+ * Invokes the static method named methodName with the given arguments
+ * To find the method, {@link #searchMethod(int, Class, String, Class[])} is used with no type parameters.
+ * <p>
+ * To search the method with type parameters, you should search the method using {@link #searchMethod(int, Class, String, Class[])} or similar,
+ * and call {@link #invokeMethod(Method, Object, Object...)}
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param modifiers The modifiers for method search. Can have {@link #DEEP_SEARCH} and {@link #IGNORE_PARAMS}
+ * @param clazz The class to search in/from
+ * @param methodName Name of the method
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @throws NullPointerException if clazz or methodName is null
+ * @throws IllegalArgumentException if the method is not found
+ * @see #invokeStaticMethod(Method, Object...)
+ */
+ public static <T> T invokeStaticMethod(int modifiers, Class<?> clazz, String methodName, Object... args) {
+ return invokeStaticMethod(searchMethod(modifiers, clazz, methodName), args);
+ }
+
+ /**
+ * Invokes the static method with the given arguments
+ * <p>
+ * If a {@link ReflectiveOperationException} occurs, this is printed to {@link System#out}
+ *
+ * @param method The method to invoke
+ * @param args The arguments to use in the method call
+ * @param <T> The expected/known method return type
+ * @return The result of calling the method
+ * @see #invokeMethod(Method, Object, Object...)
+ */
+ public static <T> T invokeStaticMethod(Method method, Object... args) {
+ return invokeMethod(method, (Object) null, args);
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/SetBasedWhitelist.java b/dicore3/core/src/main/java/io/dico/dicore/SetBasedWhitelist.java
index 6596b65..d4486ed 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/SetBasedWhitelist.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/SetBasedWhitelist.java
@@ -1,59 +1,59 @@
-package io.dico.dicore;
-
-import org.bukkit.configuration.ConfigurationSection;
-
-import java.util.*;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-public class SetBasedWhitelist implements Whitelist {
- private final Set set;
- private final boolean blacklist;
-
- public SetBasedWhitelist(Object[] array, boolean blacklist) {
- this(Arrays.asList(array), blacklist);
- }
-
- public SetBasedWhitelist(ConfigurationSection section, Function<String, ?> parser) {
- this(section.getStringList("listed").stream().map(parser).filter(Objects::nonNull).collect(Collectors.toList()),
- section.getBoolean("blacklist", false));
- }
-
- @SuppressWarnings("unchecked")
- public SetBasedWhitelist(Collection collection, boolean blacklist) {
- Set set;
- if (collection.isEmpty()) {
- set = Collections.emptySet();
- } else if (collection.iterator().next() instanceof Enum) {
- set = EnumSet.copyOf(collection);
- } else if (collection instanceof Set) {
- set = (Set) collection;
- } else {
- set = new HashSet<>(collection);
- }
-
- this.set = set;
- this.blacklist = blacklist;
- }
-
- @Override
- public boolean isWhitelisted(Object o) {
- return blacklist != set.contains(o);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public String toString() {
- return (blacklist ? "Blacklist" : "Whitelist") + "{"
- + String.join(", ", (CharSequence[]) set.stream().map(String::valueOf).toArray(String[]::new)) + "}";
- }
-
- public Set getSet() {
- return set;
- }
-
- public boolean isBlacklist() {
- return blacklist;
- }
-
-}
+package io.dico.dicore;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class SetBasedWhitelist implements Whitelist {
+ private final Set set;
+ private final boolean blacklist;
+
+ public SetBasedWhitelist(Object[] array, boolean blacklist) {
+ this(Arrays.asList(array), blacklist);
+ }
+
+ public SetBasedWhitelist(ConfigurationSection section, Function<String, ?> parser) {
+ this(section.getStringList("listed").stream().map(parser).filter(Objects::nonNull).collect(Collectors.toList()),
+ section.getBoolean("blacklist", false));
+ }
+
+ @SuppressWarnings("unchecked")
+ public SetBasedWhitelist(Collection collection, boolean blacklist) {
+ Set set;
+ if (collection.isEmpty()) {
+ set = Collections.emptySet();
+ } else if (collection.iterator().next() instanceof Enum) {
+ set = EnumSet.copyOf(collection);
+ } else if (collection instanceof Set) {
+ set = (Set) collection;
+ } else {
+ set = new HashSet<>(collection);
+ }
+
+ this.set = set;
+ this.blacklist = blacklist;
+ }
+
+ @Override
+ public boolean isWhitelisted(Object o) {
+ return blacklist != set.contains(o);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public String toString() {
+ return (blacklist ? "Blacklist" : "Whitelist") + "{"
+ + String.join(", ", (CharSequence[]) set.stream().map(String::valueOf).toArray(String[]::new)) + "}";
+ }
+
+ public Set getSet() {
+ return set;
+ }
+
+ public boolean isBlacklist() {
+ return blacklist;
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/SpigotUtil.java b/dicore3/core/src/main/java/io/dico/dicore/SpigotUtil.java
index 44659fa..afcae02 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/SpigotUtil.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/SpigotUtil.java
@@ -1,408 +1,408 @@
-package io.dico.dicore;
-
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-import org.bukkit.block.BlockState;
-import org.bukkit.configuration.serialization.ConfigurationSerializable;
-import org.bukkit.entity.*;
-import org.bukkit.inventory.Inventory;
-import org.bukkit.inventory.InventoryHolder;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.material.Attachable;
-import org.bukkit.material.MaterialData;
-import org.bukkit.projectiles.ProjectileSource;
-
-import java.util.*;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Predicate;
-
-public class SpigotUtil {
-
- private SpigotUtil() {
- throw new UnsupportedOperationException();
- }
-
- public static World matchWorld(String input) {
- try {
- UUID uid = UUID.fromString(input);
- World world = Bukkit.getWorld(uid);
- if (world != null) {
- return world;
- }
- } catch (IllegalArgumentException ignored) {
- }
-
- World result = Bukkit.getWorld(input);
- if (result == null) {
- input = input.toLowerCase().replace("_", "").replaceAll("[-_]", "");
- for (World world : Bukkit.getWorlds()) {
- if (world.getName().toLowerCase().equals(input)) {
- result = world;
- break;
- }
- }
- }
-
- return result;
- }
-
- public static Block getSupportingBlock(Block block) {
- MaterialData data = block.getState().getData();
- if (data instanceof Attachable) {
- BlockFace attachedOn = ((Attachable) data).getAttachedFace();
- return block.getRelative(attachedOn);
- }
- return null;
- }
-
- public static boolean isItemPresent(ItemStack stack) {
- return stack != null && stack.getType() != Material.AIR && stack.getAmount() > 0;
- }
-
- public static boolean removeItems(Inventory from, ItemStack item, int amount) {
- for (Map.Entry<Integer, ? extends ItemStack> entry : from.all(item.getType()).entrySet()) {
- ItemStack stack = entry.getValue();
- if (item.isSimilar(stack)) {
- amount -= stack.getAmount();
- int stackAmount = -Math.min(0, amount);
- if (stackAmount == 0) {
- from.setItem(entry.getKey(), null);
- } else {
- stack.setAmount(stackAmount);
- }
- }
- }
- return amount <= 0;
- }
-
- public static BlockFace yawToFace(float yaw) {
- if ((yaw %= 360) < 0)
- yaw += 360;
- if (45 <= yaw && yaw < 135)
- return BlockFace.WEST;
- if (135 <= yaw && yaw < 225)
- return BlockFace.NORTH;
- if (225 <= yaw && yaw < 315)
- return BlockFace.EAST;
- return BlockFace.SOUTH;
- }
-
- public static void addItems(InventoryHolder entity, ItemStack... items) {
- Location dropLocation;
- if (entity instanceof Entity) {
- dropLocation = ((Entity) entity).getLocation();
- } else if (entity instanceof BlockState) {
- dropLocation = ((BlockState) entity).getLocation().add(0.5, 1, 0.5);
- } else {
- throw new IllegalArgumentException("Can't find location of this InventoryHolder: " + entity);
- }
- World world = dropLocation.getWorld();
- for (ItemStack toDrop : entity.getInventory().addItem(items).values()) {
- world.dropItemNaturally(dropLocation, toDrop);
- }
- }
-
- public static String asJsonString(Object object) {
- return asJsonString(null, object, 0);
- }
-
- public static String asJsonString(String key, Object object, int indentation) {
- String indent = new String(new char[indentation * 2]).replace('\0', ' ');
- StringBuilder builder = new StringBuilder(indent);
- if (key != null) {
- builder.append(key).append(": ");
- }
- if (object instanceof ConfigurationSerializable) {
- object = ((ConfigurationSerializable) object).serialize();
- }
- if (object instanceof Map) {
- builder.append("{\n");
- Map<?, ?> map = (Map) object;
- for (Map.Entry entry : map.entrySet()) {
- builder.append(asJsonString(String.valueOf(entry.getKey()), entry.getValue(), indentation + 1));
- }
- builder.append(indent).append("}");
- } else if (object instanceof List) {
- builder.append("[\n");
- List list = (List) object;
- for (Object entry : list) {
- builder.append(asJsonString(null, entry, indentation + 1));
- }
- builder.append(indent).append("]");
- } else {
- builder.append(String.valueOf(object));
- }
- return builder.append(",\n").toString();
- }
-
- public static String asJsonString(String key, Object object, int indentation, BiConsumer<List<?>, StringBuilder> listHeader) {
- String indent = new String(new char[indentation * 2]).replace('\0', ' ');
- StringBuilder builder = new StringBuilder(indent);
- if (key != null) {
- builder.append(key).append(": ");
- }
- if (object instanceof ConfigurationSerializable) {
- object = ((ConfigurationSerializable) object).serialize();
- }
- if (object instanceof Map) {
- builder.append("{\n");
- Map<?, ?> map = (Map) object;
- for (Map.Entry entry : map.entrySet()) {
- builder.append(asJsonString(String.valueOf(entry.getKey()), entry.getValue(), indentation + 1, listHeader));
- }
- builder.append(indent).append("}");
- } else if (object instanceof List) {
- builder.append("[");
- List list = (List) object;
- listHeader.accept(list, builder);
- builder.append("\n");
- for (Object entry : list) {
- builder.append(asJsonString(null, entry, indentation + 1, listHeader));
- }
- builder.append(indent).append("]");
- } else {
- builder.append(String.valueOf(object));
- }
- return builder.append(",\n").toString();
- }
-
- public static BlockFace estimateDirectionTo(Location from, Location to) {
- double dx = from.getX() - to.getX();
- double dz = from.getZ() - to.getZ();
-
- boolean xGreater = Math.abs(dx) - Math.abs(dz) > 0;
- double f = xGreater ? 2 / Math.abs(dx) : 2 / Math.abs(dz);
- dx *= f;
- dz *= f;
-
- double other = Math.abs(xGreater ? dz : dx);
-
- if (other <= .5) {
- return xGreater ? (dx < 0 ? BlockFace.WEST : BlockFace.EAST) : (dz < 0 ? BlockFace.NORTH : BlockFace.SOUTH);
- }
-
- if (other < 1.5) {
- if (xGreater) {
- return dx < 0 ? (dz < 0 ? BlockFace.WEST_NORTH_WEST : BlockFace.WEST_SOUTH_WEST) : (dz < 0 ? BlockFace.EAST_NORTH_EAST : BlockFace.EAST_SOUTH_EAST);
- }
- return dx < 0 ? (dz < 0 ? BlockFace.NORTH_NORTH_WEST : BlockFace.SOUTH_SOUTH_WEST) : (dz < 0 ? BlockFace.NORTH_NORTH_EAST : BlockFace.SOUTH_SOUTH_EAST);
- }
-
- return dx < 0 ? (dz < 0 ? BlockFace.NORTH_WEST : BlockFace.SOUTH_WEST) : (dz < 0 ? BlockFace.NORTH_EAST : BlockFace.SOUTH_EAST);
- }
-
- public static Entity findEntityFromDamager(Entity damager, EntityType searched) {
- if (damager.getType() == searched) {
- return damager;
- }
-
- if (damager instanceof Projectile) {
- ProjectileSource shooter = ((Projectile) damager).getShooter();
- if (shooter instanceof Entity && ((Entity) shooter).getType() == searched) {
- return (Entity) shooter;
- }
- return null;
- }
-
- if (damager.getType() == EntityType.PRIMED_TNT) {
- Entity source = ((TNTPrimed) damager).getSource();
- if (source.getType() == searched) {
- return source;
- }
- }
-
- return null;
- }
-
- public static int xpForNextLevel(int currentLevel) {
- if (currentLevel >= 30) {
- return 112 + (currentLevel - 30) * 9;
- }
-
- if (currentLevel >= 15) {
- return 37 + (currentLevel - 15) * 5;
- }
-
- return 7 + currentLevel * 2;
- }
-
- public static int removeExp(Player entity, int xp) {
- int total = entity.getTotalExperience();
- if (xp > total) {
- xp = total;
- }
-
- int level = entity.getLevel();
- if (level < 0) {
- return 0;
- }
-
- int removed = 0;
- int xpForNextLevel = xpForNextLevel(level);
- int current = (int) entity.getExp() * xpForNextLevel;
-
- if (xp > current) {
- xp -= current;
- total -= current;
- removed += current;
-
- if (level == 0) {
- entity.setExp(0F);
- entity.setTotalExperience(total);
- return removed;
- }
- } else {
- current -= xp;
- total -= xp;
- removed += xp;
-
- entity.setExp((float) current / xpForNextLevel);
- entity.setTotalExperience(total);
- return removed;
- }
-
- do {
- xpForNextLevel = xpForNextLevel(--level);
- if (xpForNextLevel >= xp) {
- total -= xp;
- removed += xp;
-
- entity.setExp(1F / xpForNextLevel * (xpForNextLevel - xp));
- entity.setTotalExperience(total);
- entity.setLevel(level);
- return removed;
- }
-
- xp -= xpForNextLevel;
- total -= xpForNextLevel;
- removed += xpForNextLevel;
- } while (level > 0);
-
- entity.setExp(0F);
- entity.setTotalExperience(0);
- entity.setLevel(0);
- return removed;
- }
-
- public static int getTotalExp(Player entity) {
- int rv = 0;
- int level = Math.min(entity.getLevel(), 20000);
- for (int i = 0; i < level; i++) {
- rv += xpForNextLevel(i);
- }
- rv += Math.min(1F, Math.max(0F, entity.getExp())) * xpForNextLevel(level);
- return rv;
- }
-
- public static double getTotalExpLevels(Player entity) {
- int xp = entity.getTotalExperience();
-
- int level = 0;
- while (xp > 0 && level < 20000) {
- int needed = xpForNextLevel(level);
- if (needed > xp) {
- return level + ((double) xp / needed);
- }
- xp -= needed;
- level++;
- }
-
- return level;
- }
-
- public static int getNearbyPlayerCount(Player origin, double range, Predicate<Player> predicate) {
- List<Entity> entities = origin.getNearbyEntities(range, range, range);
- int result = 0;
- for (Entity entity : entities) {
- if (entity.getType() == EntityType.PLAYER && predicate.test((Player) entity)) {
- result++;
- }
- }
- return result;
- }
-
- public static void getNearbyPlayers(Player origin, double range, Collection<Player> collection, Predicate<Player> predicate) {
- List<Entity> entities = origin.getNearbyEntities(range, range, range);
- for (Entity entity : entities) {
- if (entity.getType() == EntityType.PLAYER && predicate.test((Player) entity)) {
- collection.add((Player) entity);
- }
- }
- }
-
- public static void forEachNearbyPlayer(Player origin, double range, Consumer<Player> action) {
- List<Entity> entities = origin.getNearbyEntities(range, range, range);
- for (Entity entity : entities) {
- if (entity.getType() == EntityType.PLAYER) {
- action.accept((Player) entity);
- }
- }
- }
-
- public static double distanceSquared(Location first, Location second) {
- double dx = first.getX() - second.getX();
- double dy = first.getY() - second.getY();
- double dz = first.getZ() - second.getZ();
-
- return dx * dx + dy * dy + dz * dz;
- }
-
-
- public static <T extends Entity> Iterator<T> findNearbyEntities(Entity origin, boolean includeSelf, Predicate<Entity> predicate, double horizontalRange, double verticalRange) {
- Objects.requireNonNull(origin);
- return new Iterator<T>() {
- Entity next;
- List<Entity> nearby;
- int index = 0;
- int size;
-
- {
- if (includeSelf) {
- next = origin;
- } else {
- next = findNext();
- }
- }
-
- Entity findNext() {
- if (nearby == null) {
- nearby = origin.getNearbyEntities(horizontalRange, verticalRange, horizontalRange);
- size = nearby.size();
- }
-
- while (index < size) {
- Entity e = nearby.get(index++);
- if (predicate.test(e)) {
- return e;
- }
- }
-
- return null;
- }
-
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- @Override
- public T next() {
- if (next == null) {
- throw new NoSuchElementException();
- }
- Entity result = next;
- next = findNext();
- //noinspection unchecked
- return (T) result;
- }
-
- };
- }
-
-
-}
+package io.dico.dicore;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.BlockState;
+import org.bukkit.configuration.serialization.ConfigurationSerializable;
+import org.bukkit.entity.*;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.material.Attachable;
+import org.bukkit.material.MaterialData;
+import org.bukkit.projectiles.ProjectileSource;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public class SpigotUtil {
+
+ private SpigotUtil() {
+ throw new UnsupportedOperationException();
+ }
+
+ public static World matchWorld(String input) {
+ try {
+ UUID uid = UUID.fromString(input);
+ World world = Bukkit.getWorld(uid);
+ if (world != null) {
+ return world;
+ }
+ } catch (IllegalArgumentException ignored) {
+ }
+
+ World result = Bukkit.getWorld(input);
+ if (result == null) {
+ input = input.toLowerCase().replace("_", "").replaceAll("[-_]", "");
+ for (World world : Bukkit.getWorlds()) {
+ if (world.getName().toLowerCase().equals(input)) {
+ result = world;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+ public static Block getSupportingBlock(Block block) {
+ MaterialData data = block.getState().getData();
+ if (data instanceof Attachable) {
+ BlockFace attachedOn = ((Attachable) data).getAttachedFace();
+ return block.getRelative(attachedOn);
+ }
+ return null;
+ }
+
+ public static boolean isItemPresent(ItemStack stack) {
+ return stack != null && stack.getType() != Material.AIR && stack.getAmount() > 0;
+ }
+
+ public static boolean removeItems(Inventory from, ItemStack item, int amount) {
+ for (Map.Entry<Integer, ? extends ItemStack> entry : from.all(item.getType()).entrySet()) {
+ ItemStack stack = entry.getValue();
+ if (item.isSimilar(stack)) {
+ amount -= stack.getAmount();
+ int stackAmount = -Math.min(0, amount);
+ if (stackAmount == 0) {
+ from.setItem(entry.getKey(), null);
+ } else {
+ stack.setAmount(stackAmount);
+ }
+ }
+ }
+ return amount <= 0;
+ }
+
+ public static BlockFace yawToFace(float yaw) {
+ if ((yaw %= 360) < 0)
+ yaw += 360;
+ if (45 <= yaw && yaw < 135)
+ return BlockFace.WEST;
+ if (135 <= yaw && yaw < 225)
+ return BlockFace.NORTH;
+ if (225 <= yaw && yaw < 315)
+ return BlockFace.EAST;
+ return BlockFace.SOUTH;
+ }
+
+ public static void addItems(InventoryHolder entity, ItemStack... items) {
+ Location dropLocation;
+ if (entity instanceof Entity) {
+ dropLocation = ((Entity) entity).getLocation();
+ } else if (entity instanceof BlockState) {
+ dropLocation = ((BlockState) entity).getLocation().add(0.5, 1, 0.5);
+ } else {
+ throw new IllegalArgumentException("Can't find location of this InventoryHolder: " + entity);
+ }
+ World world = dropLocation.getWorld();
+ for (ItemStack toDrop : entity.getInventory().addItem(items).values()) {
+ world.dropItemNaturally(dropLocation, toDrop);
+ }
+ }
+
+ public static String asJsonString(Object object) {
+ return asJsonString(null, object, 0);
+ }
+
+ public static String asJsonString(String key, Object object, int indentation) {
+ String indent = new String(new char[indentation * 2]).replace('\0', ' ');
+ StringBuilder builder = new StringBuilder(indent);
+ if (key != null) {
+ builder.append(key).append(": ");
+ }
+ if (object instanceof ConfigurationSerializable) {
+ object = ((ConfigurationSerializable) object).serialize();
+ }
+ if (object instanceof Map) {
+ builder.append("{\n");
+ Map<?, ?> map = (Map) object;
+ for (Map.Entry entry : map.entrySet()) {
+ builder.append(asJsonString(String.valueOf(entry.getKey()), entry.getValue(), indentation + 1));
+ }
+ builder.append(indent).append("}");
+ } else if (object instanceof List) {
+ builder.append("[\n");
+ List list = (List) object;
+ for (Object entry : list) {
+ builder.append(asJsonString(null, entry, indentation + 1));
+ }
+ builder.append(indent).append("]");
+ } else {
+ builder.append(String.valueOf(object));
+ }
+ return builder.append(",\n").toString();
+ }
+
+ public static String asJsonString(String key, Object object, int indentation, BiConsumer<List<?>, StringBuilder> listHeader) {
+ String indent = new String(new char[indentation * 2]).replace('\0', ' ');
+ StringBuilder builder = new StringBuilder(indent);
+ if (key != null) {
+ builder.append(key).append(": ");
+ }
+ if (object instanceof ConfigurationSerializable) {
+ object = ((ConfigurationSerializable) object).serialize();
+ }
+ if (object instanceof Map) {
+ builder.append("{\n");
+ Map<?, ?> map = (Map) object;
+ for (Map.Entry entry : map.entrySet()) {
+ builder.append(asJsonString(String.valueOf(entry.getKey()), entry.getValue(), indentation + 1, listHeader));
+ }
+ builder.append(indent).append("}");
+ } else if (object instanceof List) {
+ builder.append("[");
+ List list = (List) object;
+ listHeader.accept(list, builder);
+ builder.append("\n");
+ for (Object entry : list) {
+ builder.append(asJsonString(null, entry, indentation + 1, listHeader));
+ }
+ builder.append(indent).append("]");
+ } else {
+ builder.append(String.valueOf(object));
+ }
+ return builder.append(",\n").toString();
+ }
+
+ public static BlockFace estimateDirectionTo(Location from, Location to) {
+ double dx = from.getX() - to.getX();
+ double dz = from.getZ() - to.getZ();
+
+ boolean xGreater = Math.abs(dx) - Math.abs(dz) > 0;
+ double f = xGreater ? 2 / Math.abs(dx) : 2 / Math.abs(dz);
+ dx *= f;
+ dz *= f;
+
+ double other = Math.abs(xGreater ? dz : dx);
+
+ if (other <= .5) {
+ return xGreater ? (dx < 0 ? BlockFace.WEST : BlockFace.EAST) : (dz < 0 ? BlockFace.NORTH : BlockFace.SOUTH);
+ }
+
+ if (other < 1.5) {
+ if (xGreater) {
+ return dx < 0 ? (dz < 0 ? BlockFace.WEST_NORTH_WEST : BlockFace.WEST_SOUTH_WEST) : (dz < 0 ? BlockFace.EAST_NORTH_EAST : BlockFace.EAST_SOUTH_EAST);
+ }
+ return dx < 0 ? (dz < 0 ? BlockFace.NORTH_NORTH_WEST : BlockFace.SOUTH_SOUTH_WEST) : (dz < 0 ? BlockFace.NORTH_NORTH_EAST : BlockFace.SOUTH_SOUTH_EAST);
+ }
+
+ return dx < 0 ? (dz < 0 ? BlockFace.NORTH_WEST : BlockFace.SOUTH_WEST) : (dz < 0 ? BlockFace.NORTH_EAST : BlockFace.SOUTH_EAST);
+ }
+
+ public static Entity findEntityFromDamager(Entity damager, EntityType searched) {
+ if (damager.getType() == searched) {
+ return damager;
+ }
+
+ if (damager instanceof Projectile) {
+ ProjectileSource shooter = ((Projectile) damager).getShooter();
+ if (shooter instanceof Entity && ((Entity) shooter).getType() == searched) {
+ return (Entity) shooter;
+ }
+ return null;
+ }
+
+ if (damager.getType() == EntityType.PRIMED_TNT) {
+ Entity source = ((TNTPrimed) damager).getSource();
+ if (source.getType() == searched) {
+ return source;
+ }
+ }
+
+ return null;
+ }
+
+ public static int xpForNextLevel(int currentLevel) {
+ if (currentLevel >= 30) {
+ return 112 + (currentLevel - 30) * 9;
+ }
+
+ if (currentLevel >= 15) {
+ return 37 + (currentLevel - 15) * 5;
+ }
+
+ return 7 + currentLevel * 2;
+ }
+
+ public static int removeExp(Player entity, int xp) {
+ int total = entity.getTotalExperience();
+ if (xp > total) {
+ xp = total;
+ }
+
+ int level = entity.getLevel();
+ if (level < 0) {
+ return 0;
+ }
+
+ int removed = 0;
+ int xpForNextLevel = xpForNextLevel(level);
+ int current = (int) entity.getExp() * xpForNextLevel;
+
+ if (xp > current) {
+ xp -= current;
+ total -= current;
+ removed += current;
+
+ if (level == 0) {
+ entity.setExp(0F);
+ entity.setTotalExperience(total);
+ return removed;
+ }
+ } else {
+ current -= xp;
+ total -= xp;
+ removed += xp;
+
+ entity.setExp((float) current / xpForNextLevel);
+ entity.setTotalExperience(total);
+ return removed;
+ }
+
+ do {
+ xpForNextLevel = xpForNextLevel(--level);
+ if (xpForNextLevel >= xp) {
+ total -= xp;
+ removed += xp;
+
+ entity.setExp(1F / xpForNextLevel * (xpForNextLevel - xp));
+ entity.setTotalExperience(total);
+ entity.setLevel(level);
+ return removed;
+ }
+
+ xp -= xpForNextLevel;
+ total -= xpForNextLevel;
+ removed += xpForNextLevel;
+ } while (level > 0);
+
+ entity.setExp(0F);
+ entity.setTotalExperience(0);
+ entity.setLevel(0);
+ return removed;
+ }
+
+ public static int getTotalExp(Player entity) {
+ int rv = 0;
+ int level = Math.min(entity.getLevel(), 20000);
+ for (int i = 0; i < level; i++) {
+ rv += xpForNextLevel(i);
+ }
+ rv += Math.min(1F, Math.max(0F, entity.getExp())) * xpForNextLevel(level);
+ return rv;
+ }
+
+ public static double getTotalExpLevels(Player entity) {
+ int xp = entity.getTotalExperience();
+
+ int level = 0;
+ while (xp > 0 && level < 20000) {
+ int needed = xpForNextLevel(level);
+ if (needed > xp) {
+ return level + ((double) xp / needed);
+ }
+ xp -= needed;
+ level++;
+ }
+
+ return level;
+ }
+
+ public static int getNearbyPlayerCount(Player origin, double range, Predicate<Player> predicate) {
+ List<Entity> entities = origin.getNearbyEntities(range, range, range);
+ int result = 0;
+ for (Entity entity : entities) {
+ if (entity.getType() == EntityType.PLAYER && predicate.test((Player) entity)) {
+ result++;
+ }
+ }
+ return result;
+ }
+
+ public static void getNearbyPlayers(Player origin, double range, Collection<Player> collection, Predicate<Player> predicate) {
+ List<Entity> entities = origin.getNearbyEntities(range, range, range);
+ for (Entity entity : entities) {
+ if (entity.getType() == EntityType.PLAYER && predicate.test((Player) entity)) {
+ collection.add((Player) entity);
+ }
+ }
+ }
+
+ public static void forEachNearbyPlayer(Player origin, double range, Consumer<Player> action) {
+ List<Entity> entities = origin.getNearbyEntities(range, range, range);
+ for (Entity entity : entities) {
+ if (entity.getType() == EntityType.PLAYER) {
+ action.accept((Player) entity);
+ }
+ }
+ }
+
+ public static double distanceSquared(Location first, Location second) {
+ double dx = first.getX() - second.getX();
+ double dy = first.getY() - second.getY();
+ double dz = first.getZ() - second.getZ();
+
+ return dx * dx + dy * dy + dz * dz;
+ }
+
+
+ public static <T extends Entity> Iterator<T> findNearbyEntities(Entity origin, boolean includeSelf, Predicate<Entity> predicate, double horizontalRange, double verticalRange) {
+ Objects.requireNonNull(origin);
+ return new Iterator<T>() {
+ Entity next;
+ List<Entity> nearby;
+ int index = 0;
+ int size;
+
+ {
+ if (includeSelf) {
+ next = origin;
+ } else {
+ next = findNext();
+ }
+ }
+
+ Entity findNext() {
+ if (nearby == null) {
+ nearby = origin.getNearbyEntities(horizontalRange, verticalRange, horizontalRange);
+ size = nearby.size();
+ }
+
+ while (index < size) {
+ Entity e = nearby.get(index++);
+ if (predicate.test(e)) {
+ return e;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ @Override
+ public T next() {
+ if (next == null) {
+ throw new NoSuchElementException();
+ }
+ Entity result = next;
+ next = findNext();
+ //noinspection unchecked
+ return (T) result;
+ }
+
+ };
+ }
+
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/StringUtil.java b/dicore3/core/src/main/java/io/dico/dicore/StringUtil.java
index 62a389e..fb76755 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/StringUtil.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/StringUtil.java
@@ -1,473 +1,473 @@
-package io.dico.dicore;
-
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.IntStream;
-
-public class StringUtil {
-
- public static String capitalize(String input) {
- if (input.length() > 0) {
- char first = input.charAt(0);
- if (first != (first = Character.toUpperCase(first))) {
- char[] result = input.toCharArray();
- result[0] = first;
- return String.valueOf(result);
- }
- }
- return input;
- }
-
- /**
- * Capitalizes the first character of the string or the first character of each word
- *
- * @param input the string to capitalize
- * @param spaceChar the character separating each word. If @code '\0' is passed, only the first character of
- * the input is capitalized.
- * @return the capitalized string
- */
- public static String capitalize(String input, char spaceChar) {
- if (spaceChar == '\0') {
- return capitalize(input);
- }
-
- char[] result = null;
- boolean capitalize = true;
- for (int n = input.length(), i = 0; i < n; i++) {
- char c = input.charAt(i);
- if (capitalize && c != (c = Character.toUpperCase(c))) {
- if (result == null) result = input.toCharArray();
- result[i] = c;
- }
- capitalize = c == spaceChar;
- }
- return result != null ? String.valueOf(result) : input;
- }
-
- public static String capitalize(String input, char spaceChar, char newSpaceChar) {
- if (newSpaceChar == '\0') {
- return capitalize(input, spaceChar);
- }
-
- char[] result = null;
- boolean capitalize = true;
- for (int n = input.length(), i = 0; i < n; i++) {
- char c = input.charAt(i);
- if (capitalize && c != (c = Character.toUpperCase(c))) {
- if (result == null) result = input.toCharArray();
- result[i] = c;
- }
- if (capitalize = c == spaceChar) {
- if (result == null) result = input.toCharArray();
- result[i] = newSpaceChar;
- }
- }
- return result != null ? String.valueOf(result) : input;
- }
-
- /**
- * Returns a lowercase version of the input with _ replaced with a space.
- * Mainly used for making names of enum constants readable.
- *
- * @param input
- * @return a humanified version of @code input
- */
- public static String humanify(String input) {
- return input == null ? null : input.toLowerCase().replace('_', ' ');
- }
-
- /**
- * Enumerate the given items, separating them by ", " and finally by " and "
- *
- * @param words the items to enumerate (it's not really enumerating....)
- * @return the enumerated string
- */
- public static String enumerate(String... words) {
- StringBuilder result = new StringBuilder();
- int size = words.length;
- int secondLastIndex = size - 2;
- for (int i = 0; i < size; i++) {
- String word = words[i];
- if (word.isEmpty())
- continue;
- result.append(word);
- if (i < secondLastIndex)
- result.append(", ");
- else if (i == secondLastIndex)
- result.append(" and ");
- }
- return result.toString();
- }
-
- public static String enumerate(String list, String regex) {
- return enumerate(list.split(regex));
- }
-
- /**
- * Return a formatted string of the length in millis, containing days, hours and minutes.
- *
- * @param length The delay in milliseconds
- * @return the formatted string
- */
- public static String getTimeLength(long length) {
- int minute = 60000; // in millis
- int hour = 60 * minute;
- int day = 24 * hour;
-
- int minutes = (int) ((length / minute) % 60);
- int hours = (int) ((length / hour) % 24);
- int days = (int) (length / day); //returns floor
-
- String result = ""; // It will be splitted at "|"
- if (days != 0)
- result += days + " days|";
- if (hours != 0)
- result += hours + " hours|";
- if (minutes != 0)
- result += minutes + " minutes|";
- return enumerate(result.split("\\|"));
- }
-
- /**
- * Return a formatted String to represent the given time length, in the given units
- *
- * @param sourceAmount Amount of delay
- * @param sourceUnit Unit of delay
- * @param ifEmpty the String to return if the
- * @param displayedUnits units displayed
- * @return the formatted string
- * @throws IllegalArgumentException if there are no displayed units
- */
- public static String getTimeLength(long sourceAmount, TimeUnit sourceUnit, String ifEmpty, TimeUnit... displayedUnits) {
- if (displayedUnits.length == 0) {
- throw new IllegalArgumentException("No displayed units");
- }
- Arrays.sort(displayedUnits, Collections.reverseOrder(TimeUnit::compareTo)); // sort by opposite of enum declaration order (largest -> smallest)
- List<String> segments = new ArrayList<>(displayedUnits.length);
- for (TimeUnit unit : displayedUnits) {
- long displayedAmount = unit.convert(sourceAmount, sourceUnit);
- sourceAmount -= sourceUnit.convert(displayedAmount, unit);
- if (displayedAmount > 0) {
- String unitWord = unit.name().toLowerCase(); // plural
- if (displayedAmount == 1) {
- unitWord = unitWord.substring(0, unitWord.length() - 1); // remove s at the end
- }
- segments.add(displayedAmount + " " + unitWord);
- }
- }
- return segments.isEmpty() ? ifEmpty : enumerate(segments.toArray(new String[segments.size()]));
- }
-
- /**
- * Returns the delay represented by a ban-like delay representation, in milliseconds
- * Example: "5d2h5m3s" for 5 days, 2 hours, 5 minutes and 3 seconds.
- * <p>
- * Supported characters are s, m, h, d, w.
- * Negative numbers are supported.
- *
- * @param input The input string
- * @return The delay in milliseconds
- * @throws IllegalArgumentException if the input string isn't properly formatted, or any non-digit character isn't recognized (capitals are not recognized).
- */
- public static long getTimeLength(String input) { //if -1: error
- long count = 0;
- int i = 0;
- while (i < input.length()) {
- int num = 0;
- char unit = '\0';
- boolean negate;
- if (negate = input.charAt(i) == '-') {
- i++;
- }
- do {
- char c = input.charAt(i);
- int digit = c - '0';
- if (0 <= digit && digit < 10) {
- num = 10 * num + digit;
- } else {
- unit = c;
- break;
- }
- } while (i < input.length());
-
- long unitTime = getUnitTime(unit);
- if (unitTime == -1)
- throw new IllegalArgumentException();
- if (negate) {
- unitTime = -unitTime;
- }
- count += (num * unitTime);
- }
- return count;
- }
-
- /**
- * Returns the time represented by the given unit character in milliseconds.
- * <p>
- * 's' -> 1000
- * 'm' -> 1000 * 60
- * 'h' -> 1000 * 60 * 60
- * 'd' -> 1000 * 60 * 60 * 24
- * 'w' -> 1000 * 60 * 60 * 24 * 7
- * anything else -> -1
- *
- * @param unit The unit character, as shown above
- * @return the millisecond delay represented by the unit
- */
- public static long getUnitTime(char unit) { //if -1: no value found
- switch (Character.toLowerCase(unit)) {
- case 's':
- return 1000;
- case 'm':
- return 1000 * 60;
- case 'h':
- return 1000 * 60 * 60;
- case 'd':
- return 1000 * 60 * 60 * 24;
- case 'w':
- return 1000 * 60 * 60 * 24 * 7;
- default:
- return -1;
- }
- }
-
- /**
- * Computes a binary representation of the value.
- * The returned representation always displays 64 bits.
- * Every 8 bits, the digits are seperated by an _
- * The representation is prefixed by 0b.
- * <p>
- * Example: 0b00000000_11111111_00000001_11110000_00001111_11001100_00001111_10111010
- *
- * @param entry the value to represent in binary
- * @return A binary representation of the long value
- */
- public static String toBinaryString(long entry) {
- String binary = Long.toBinaryString(entry);
- String binary64 = String.valueOf(new char[64 - binary.length()]).replace('\0', '0') + binary;
- String withUnderscores = String.join("_", IntStream.range(0, 8).mapToObj(x -> binary64.substring(x * 8, x * 8 + 8)).toArray(String[]::new));
- return "0b" + withUnderscores;
- }
-
- /**
- * Turns a generic java classname into a name formatted properly to be an enum constant.
- *
- * @param name The string value I'd describe as a generic java classname (so we have CapitalCase)
- * @return An enum constant version of it (ENUM_FORMAT: CAPITAL_CASE)
- */
- public static String toEnumFormat(String name) {
- StringBuilder result = new StringBuilder(name.length() + 2);
-
- boolean capital = true;
- for (int i = 0, n = name.length(); i < n; i++) {
- char c = name.charAt(i);
- if (capital) {
- capital = Character.isUpperCase(c);
- } else if (Character.isUpperCase(c)) {
- capital = true;
- result.append('_');
- }
- result.append(capital ? c : Character.toUpperCase(c));
- }
-
- return result.toString();
- }
-
- /**
- * Replaces any occurrence of toReplace with another string.
- * Any colours that occured before the occurence of toReplace, are copied to the end of the replacement.
- *
- * @param target The String to query
- * @param toReplace The sequence to replace
- * @param with the replacing sequence
- * @return the result
- */
- public static String replaceKeepColours(String target, String toReplace, String with) {
- int index = -toReplace.length();
- while ((index = target.indexOf(toReplace, index + toReplace.length())) != -1) {
- String start = target.substring(0, index);
- Formatting coloursBefore = Formatting.getFormats(start);
- String after;
- try {
- after = target.substring(index + toReplace.length());
- } catch (IndexOutOfBoundsException e) {
- after = "";
- }
- target = start + with + coloursBefore + after;
- }
- return target;
- }
-
- public static String replParam(String target, String param, Object repl) {
- return replParam(target, param, repl, false);
- }
-
- public static String replParams(String target, String[] params, Object[] repls) {
- return replParams(target, params, repls, false, false);
- }
-
- public static boolean replParams(String[] target, String[] params, Object[] repls) {
- return replParams(target, 0, target.length, params, repls);
- }
-
- public static boolean replParams(String[] target, int from, int to, String[] params, Object[] repls) {
- return replParams(target, from, to, params, repls, false);
- }
-
- public static boolean replParams(List<String> target, String[] params, Object[] repls) {
- return replParams(target, 0, target.size(), params, repls);
- }
-
- public static boolean replParams(List<String> target, int from, int to, String[] params, Object[] repls) {
- return replParams(target, from, to, params, repls, false);
- }
-
- public static String replParamAndTranslate(String target, String param, Object repl) {
- return replParam(target, param, repl, true);
- }
-
- public static String replParamsAndTranslate(String target, String[] params, Object[] repls) {
- return replParams(target, params, repls, false, true);
- }
-
- public static boolean replParamsAndTranslate(String[] target, String[] params, Object[] repls) {
- return replParamsAndTranslate(target, 0, target.length, params, repls);
- }
-
- public static boolean replParamsAndTranslate(String[] target, int from, int to, String[] params, Object[] repls) {
- return replParams(target, from, to, params, repls, true);
- }
-
- public static boolean replParamsAndTranslate(List<String> target, String[] params, Object[] repls) {
- return replParamsAndTranslate(target, 0, target.size(), params, repls);
- }
-
- public static boolean replParamsAndTranslate(List<String> target, int from, int to, String[] params, Object[] repls) {
- return replParams(target, from, to, params, repls, true);
- }
-
- private static String replParam(String target, String param, Object replacementObj, boolean translate) {
- int idx = target.indexOf(param, 0);
- if (idx == -1) {
- return translate ? Formatting.translate(target) : target;
- }
-
- String rep = replacementObj.toString();
- StringBuilder builder = new StringBuilder(target);
- do {
- builder.replace(idx, idx + param.length(), rep);
- idx = builder.indexOf(param, idx + rep.length());
- } while (idx != -1);
-
- if (translate) {
- Formatting.translate(builder);
- }
-
- return builder.toString();
- }
-
- @SuppressWarnings("StringEquality")
- private static boolean replParams(String[] target, int from, int to, String[] params, Object[] repls, boolean translate) {
- if (from < 0 || to < from || to > target.length) {
- throw new IllegalArgumentException("Invalid from-to for array size " + target.length + ": " + from + "-" + to);
- }
-
- boolean change = false;
- for (int i = from; i < to; i++) {
- String val = target[i];
- if (val != (val = replParams(val, params, repls, true, translate))) {
- target[i] = val;
- change = true;
- }
- }
- return change;
- }
-
- @SuppressWarnings("StringEquality")
- private static boolean replParams(List<String> target, int from, int to, String[] params, Object[] repls, boolean translate) {
- if (from < 0 || to < from || to > target.size()) {
- throw new IllegalArgumentException("Invalid from-to for list size " + target.size() + ": " + from + "-" + to);
- }
-
- boolean change = false;
- if (target instanceof RandomAccess) {
- for (int i = from; i < to; i++) {
- String val = target.get(i);
- if (val != (val = replParams(val, params, repls, true, translate))) {
- target.set(i, val);
- change = true;
- }
- }
- } else {
- ListIterator<String> itr = target.listIterator(from);
- for (int n = to - from, i = 0; i < n && itr.hasNext(); i++) {
- String val = itr.next();
- if (val != (val = replParams(val, params, repls, true, translate))) {
- itr.set(val);
- change = true;
- }
- }
- }
- return change;
- }
-
- private static String replParams(String target, String[] params, Object[] repls, boolean updateRepls, boolean translate) {
- int n = params.length;
- if (n != repls.length) {
- throw new IllegalArgumentException();
- }
-
- String param = null;
- int idx = -1;
- int i;
- for (i = 0; i < n; i++) {
- param = params[i];
- if (param == null) {
- continue;
- }
- idx = target.indexOf(param, 0);
- if (idx != -1) {
- break;
- }
- }
-
- if (idx == -1) {
- return translate ? Formatting.translate(target) : target;
- }
-
- String repl = repls[i].toString();
- if (updateRepls) {
- repls[i] = repl;
- }
-
- StringBuilder builder = new StringBuilder(target);
- do {
- builder.replace(idx, idx + param.length(), repl);
- idx = builder.indexOf(param, idx + repl.length());
- } while (idx != -1);
-
- for (i++; i < n; i++) {
- param = params[i];
- if (param == null || (idx = builder.indexOf(param, 0)) == -1) {
- continue;
- }
-
- repl = repls[i].toString();
- if (updateRepls) {
- repls[i] = repl;
- }
-
- do {
- builder.replace(idx, idx + param.length(), repl);
- idx = builder.indexOf(param, idx + repl.length());
- } while (idx != -1);
- }
-
- if (translate) {
- Formatting.translate(builder);
- }
-
- return builder.toString();
- }
-
-}
+package io.dico.dicore;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.IntStream;
+
+public class StringUtil {
+
+ public static String capitalize(String input) {
+ if (input.length() > 0) {
+ char first = input.charAt(0);
+ if (first != (first = Character.toUpperCase(first))) {
+ char[] result = input.toCharArray();
+ result[0] = first;
+ return String.valueOf(result);
+ }
+ }
+ return input;
+ }
+
+ /**
+ * Capitalizes the first character of the string or the first character of each word
+ *
+ * @param input the string to capitalize
+ * @param spaceChar the character separating each word. If @code '\0' is passed, only the first character of
+ * the input is capitalized.
+ * @return the capitalized string
+ */
+ public static String capitalize(String input, char spaceChar) {
+ if (spaceChar == '\0') {
+ return capitalize(input);
+ }
+
+ char[] result = null;
+ boolean capitalize = true;
+ for (int n = input.length(), i = 0; i < n; i++) {
+ char c = input.charAt(i);
+ if (capitalize && c != (c = Character.toUpperCase(c))) {
+ if (result == null) result = input.toCharArray();
+ result[i] = c;
+ }
+ capitalize = c == spaceChar;
+ }
+ return result != null ? String.valueOf(result) : input;
+ }
+
+ public static String capitalize(String input, char spaceChar, char newSpaceChar) {
+ if (newSpaceChar == '\0') {
+ return capitalize(input, spaceChar);
+ }
+
+ char[] result = null;
+ boolean capitalize = true;
+ for (int n = input.length(), i = 0; i < n; i++) {
+ char c = input.charAt(i);
+ if (capitalize && c != (c = Character.toUpperCase(c))) {
+ if (result == null) result = input.toCharArray();
+ result[i] = c;
+ }
+ if (capitalize = c == spaceChar) {
+ if (result == null) result = input.toCharArray();
+ result[i] = newSpaceChar;
+ }
+ }
+ return result != null ? String.valueOf(result) : input;
+ }
+
+ /**
+ * Returns a lowercase version of the input with _ replaced with a space.
+ * Mainly used for making names of enum constants readable.
+ *
+ * @param input
+ * @return a humanified version of @code input
+ */
+ public static String humanify(String input) {
+ return input == null ? null : input.toLowerCase().replace('_', ' ');
+ }
+
+ /**
+ * Enumerate the given items, separating them by ", " and finally by " and "
+ *
+ * @param words the items to enumerate (it's not really enumerating....)
+ * @return the enumerated string
+ */
+ public static String enumerate(String... words) {
+ StringBuilder result = new StringBuilder();
+ int size = words.length;
+ int secondLastIndex = size - 2;
+ for (int i = 0; i < size; i++) {
+ String word = words[i];
+ if (word.isEmpty())
+ continue;
+ result.append(word);
+ if (i < secondLastIndex)
+ result.append(", ");
+ else if (i == secondLastIndex)
+ result.append(" and ");
+ }
+ return result.toString();
+ }
+
+ public static String enumerate(String list, String regex) {
+ return enumerate(list.split(regex));
+ }
+
+ /**
+ * Return a formatted string of the length in millis, containing days, hours and minutes.
+ *
+ * @param length The delay in milliseconds
+ * @return the formatted string
+ */
+ public static String getTimeLength(long length) {
+ int minute = 60000; // in millis
+ int hour = 60 * minute;
+ int day = 24 * hour;
+
+ int minutes = (int) ((length / minute) % 60);
+ int hours = (int) ((length / hour) % 24);
+ int days = (int) (length / day); //returns floor
+
+ String result = ""; // It will be splitted at "|"
+ if (days != 0)
+ result += days + " days|";
+ if (hours != 0)
+ result += hours + " hours|";
+ if (minutes != 0)
+ result += minutes + " minutes|";
+ return enumerate(result.split("\\|"));
+ }
+
+ /**
+ * Return a formatted String to represent the given time length, in the given units
+ *
+ * @param sourceAmount Amount of delay
+ * @param sourceUnit Unit of delay
+ * @param ifEmpty the String to return if the
+ * @param displayedUnits units displayed
+ * @return the formatted string
+ * @throws IllegalArgumentException if there are no displayed units
+ */
+ public static String getTimeLength(long sourceAmount, TimeUnit sourceUnit, String ifEmpty, TimeUnit... displayedUnits) {
+ if (displayedUnits.length == 0) {
+ throw new IllegalArgumentException("No displayed units");
+ }
+ Arrays.sort(displayedUnits, Collections.reverseOrder(TimeUnit::compareTo)); // sort by opposite of enum declaration order (largest -> smallest)
+ List<String> segments = new ArrayList<>(displayedUnits.length);
+ for (TimeUnit unit : displayedUnits) {
+ long displayedAmount = unit.convert(sourceAmount, sourceUnit);
+ sourceAmount -= sourceUnit.convert(displayedAmount, unit);
+ if (displayedAmount > 0) {
+ String unitWord = unit.name().toLowerCase(); // plural
+ if (displayedAmount == 1) {
+ unitWord = unitWord.substring(0, unitWord.length() - 1); // remove s at the end
+ }
+ segments.add(displayedAmount + " " + unitWord);
+ }
+ }
+ return segments.isEmpty() ? ifEmpty : enumerate(segments.toArray(new String[segments.size()]));
+ }
+
+ /**
+ * Returns the delay represented by a ban-like delay representation, in milliseconds
+ * Example: "5d2h5m3s" for 5 days, 2 hours, 5 minutes and 3 seconds.
+ * <p>
+ * Supported characters are s, m, h, d, w.
+ * Negative numbers are supported.
+ *
+ * @param input The input string
+ * @return The delay in milliseconds
+ * @throws IllegalArgumentException if the input string isn't properly formatted, or any non-digit character isn't recognized (capitals are not recognized).
+ */
+ public static long getTimeLength(String input) { //if -1: error
+ long count = 0;
+ int i = 0;
+ while (i < input.length()) {
+ int num = 0;
+ char unit = '\0';
+ boolean negate;
+ if (negate = input.charAt(i) == '-') {
+ i++;
+ }
+ do {
+ char c = input.charAt(i);
+ int digit = c - '0';
+ if (0 <= digit && digit < 10) {
+ num = 10 * num + digit;
+ } else {
+ unit = c;
+ break;
+ }
+ } while (i < input.length());
+
+ long unitTime = getUnitTime(unit);
+ if (unitTime == -1)
+ throw new IllegalArgumentException();
+ if (negate) {
+ unitTime = -unitTime;
+ }
+ count += (num * unitTime);
+ }
+ return count;
+ }
+
+ /**
+ * Returns the time represented by the given unit character in milliseconds.
+ * <p>
+ * 's' -> 1000
+ * 'm' -> 1000 * 60
+ * 'h' -> 1000 * 60 * 60
+ * 'd' -> 1000 * 60 * 60 * 24
+ * 'w' -> 1000 * 60 * 60 * 24 * 7
+ * anything else -> -1
+ *
+ * @param unit The unit character, as shown above
+ * @return the millisecond delay represented by the unit
+ */
+ public static long getUnitTime(char unit) { //if -1: no value found
+ switch (Character.toLowerCase(unit)) {
+ case 's':
+ return 1000;
+ case 'm':
+ return 1000 * 60;
+ case 'h':
+ return 1000 * 60 * 60;
+ case 'd':
+ return 1000 * 60 * 60 * 24;
+ case 'w':
+ return 1000 * 60 * 60 * 24 * 7;
+ default:
+ return -1;
+ }
+ }
+
+ /**
+ * Computes a binary representation of the value.
+ * The returned representation always displays 64 bits.
+ * Every 8 bits, the digits are seperated by an _
+ * The representation is prefixed by 0b.
+ * <p>
+ * Example: 0b00000000_11111111_00000001_11110000_00001111_11001100_00001111_10111010
+ *
+ * @param entry the value to represent in binary
+ * @return A binary representation of the long value
+ */
+ public static String toBinaryString(long entry) {
+ String binary = Long.toBinaryString(entry);
+ String binary64 = String.valueOf(new char[64 - binary.length()]).replace('\0', '0') + binary;
+ String withUnderscores = String.join("_", IntStream.range(0, 8).mapToObj(x -> binary64.substring(x * 8, x * 8 + 8)).toArray(String[]::new));
+ return "0b" + withUnderscores;
+ }
+
+ /**
+ * Turns a generic java classname into a name formatted properly to be an enum constant.
+ *
+ * @param name The string value I'd describe as a generic java classname (so we have CapitalCase)
+ * @return An enum constant version of it (ENUM_FORMAT: CAPITAL_CASE)
+ */
+ public static String toEnumFormat(String name) {
+ StringBuilder result = new StringBuilder(name.length() + 2);
+
+ boolean capital = true;
+ for (int i = 0, n = name.length(); i < n; i++) {
+ char c = name.charAt(i);
+ if (capital) {
+ capital = Character.isUpperCase(c);
+ } else if (Character.isUpperCase(c)) {
+ capital = true;
+ result.append('_');
+ }
+ result.append(capital ? c : Character.toUpperCase(c));
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Replaces any occurrence of toReplace with another string.
+ * Any colours that occured before the occurence of toReplace, are copied to the end of the replacement.
+ *
+ * @param target The String to query
+ * @param toReplace The sequence to replace
+ * @param with the replacing sequence
+ * @return the result
+ */
+ public static String replaceKeepColours(String target, String toReplace, String with) {
+ int index = -toReplace.length();
+ while ((index = target.indexOf(toReplace, index + toReplace.length())) != -1) {
+ String start = target.substring(0, index);
+ Formatting coloursBefore = Formatting.getFormats(start);
+ String after;
+ try {
+ after = target.substring(index + toReplace.length());
+ } catch (IndexOutOfBoundsException e) {
+ after = "";
+ }
+ target = start + with + coloursBefore + after;
+ }
+ return target;
+ }
+
+ public static String replParam(String target, String param, Object repl) {
+ return replParam(target, param, repl, false);
+ }
+
+ public static String replParams(String target, String[] params, Object[] repls) {
+ return replParams(target, params, repls, false, false);
+ }
+
+ public static boolean replParams(String[] target, String[] params, Object[] repls) {
+ return replParams(target, 0, target.length, params, repls);
+ }
+
+ public static boolean replParams(String[] target, int from, int to, String[] params, Object[] repls) {
+ return replParams(target, from, to, params, repls, false);
+ }
+
+ public static boolean replParams(List<String> target, String[] params, Object[] repls) {
+ return replParams(target, 0, target.size(), params, repls);
+ }
+
+ public static boolean replParams(List<String> target, int from, int to, String[] params, Object[] repls) {
+ return replParams(target, from, to, params, repls, false);
+ }
+
+ public static String replParamAndTranslate(String target, String param, Object repl) {
+ return replParam(target, param, repl, true);
+ }
+
+ public static String replParamsAndTranslate(String target, String[] params, Object[] repls) {
+ return replParams(target, params, repls, false, true);
+ }
+
+ public static boolean replParamsAndTranslate(String[] target, String[] params, Object[] repls) {
+ return replParamsAndTranslate(target, 0, target.length, params, repls);
+ }
+
+ public static boolean replParamsAndTranslate(String[] target, int from, int to, String[] params, Object[] repls) {
+ return replParams(target, from, to, params, repls, true);
+ }
+
+ public static boolean replParamsAndTranslate(List<String> target, String[] params, Object[] repls) {
+ return replParamsAndTranslate(target, 0, target.size(), params, repls);
+ }
+
+ public static boolean replParamsAndTranslate(List<String> target, int from, int to, String[] params, Object[] repls) {
+ return replParams(target, from, to, params, repls, true);
+ }
+
+ private static String replParam(String target, String param, Object replacementObj, boolean translate) {
+ int idx = target.indexOf(param, 0);
+ if (idx == -1) {
+ return translate ? Formatting.translate(target) : target;
+ }
+
+ String rep = replacementObj.toString();
+ StringBuilder builder = new StringBuilder(target);
+ do {
+ builder.replace(idx, idx + param.length(), rep);
+ idx = builder.indexOf(param, idx + rep.length());
+ } while (idx != -1);
+
+ if (translate) {
+ Formatting.translate(builder);
+ }
+
+ return builder.toString();
+ }
+
+ @SuppressWarnings("StringEquality")
+ private static boolean replParams(String[] target, int from, int to, String[] params, Object[] repls, boolean translate) {
+ if (from < 0 || to < from || to > target.length) {
+ throw new IllegalArgumentException("Invalid from-to for array size " + target.length + ": " + from + "-" + to);
+ }
+
+ boolean change = false;
+ for (int i = from; i < to; i++) {
+ String val = target[i];
+ if (val != (val = replParams(val, params, repls, true, translate))) {
+ target[i] = val;
+ change = true;
+ }
+ }
+ return change;
+ }
+
+ @SuppressWarnings("StringEquality")
+ private static boolean replParams(List<String> target, int from, int to, String[] params, Object[] repls, boolean translate) {
+ if (from < 0 || to < from || to > target.size()) {
+ throw new IllegalArgumentException("Invalid from-to for list size " + target.size() + ": " + from + "-" + to);
+ }
+
+ boolean change = false;
+ if (target instanceof RandomAccess) {
+ for (int i = from; i < to; i++) {
+ String val = target.get(i);
+ if (val != (val = replParams(val, params, repls, true, translate))) {
+ target.set(i, val);
+ change = true;
+ }
+ }
+ } else {
+ ListIterator<String> itr = target.listIterator(from);
+ for (int n = to - from, i = 0; i < n && itr.hasNext(); i++) {
+ String val = itr.next();
+ if (val != (val = replParams(val, params, repls, true, translate))) {
+ itr.set(val);
+ change = true;
+ }
+ }
+ }
+ return change;
+ }
+
+ private static String replParams(String target, String[] params, Object[] repls, boolean updateRepls, boolean translate) {
+ int n = params.length;
+ if (n != repls.length) {
+ throw new IllegalArgumentException();
+ }
+
+ String param = null;
+ int idx = -1;
+ int i;
+ for (i = 0; i < n; i++) {
+ param = params[i];
+ if (param == null) {
+ continue;
+ }
+ idx = target.indexOf(param, 0);
+ if (idx != -1) {
+ break;
+ }
+ }
+
+ if (idx == -1) {
+ return translate ? Formatting.translate(target) : target;
+ }
+
+ String repl = repls[i].toString();
+ if (updateRepls) {
+ repls[i] = repl;
+ }
+
+ StringBuilder builder = new StringBuilder(target);
+ do {
+ builder.replace(idx, idx + param.length(), repl);
+ idx = builder.indexOf(param, idx + repl.length());
+ } while (idx != -1);
+
+ for (i++; i < n; i++) {
+ param = params[i];
+ if (param == null || (idx = builder.indexOf(param, 0)) == -1) {
+ continue;
+ }
+
+ repl = repls[i].toString();
+ if (updateRepls) {
+ repls[i] = repl;
+ }
+
+ do {
+ builder.replace(idx, idx + param.length(), repl);
+ idx = builder.indexOf(param, idx + repl.length());
+ } while (idx != -1);
+ }
+
+ if (translate) {
+ Formatting.translate(builder);
+ }
+
+ return builder.toString();
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/Whitelist.java b/dicore3/core/src/main/java/io/dico/dicore/Whitelist.java
index 5f8f4e2..e467d91 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/Whitelist.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/Whitelist.java
@@ -1,91 +1,91 @@
-package io.dico.dicore;
-
-import org.bukkit.configuration.ConfigurationSection;
-
-import java.util.*;
-import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-@FunctionalInterface
-public interface Whitelist extends Predicate {
-
- Whitelist EVERYTHING = item -> true;
- Whitelist NOTHING = item -> false;
- Whitelist NOT_NULL = Objects::nonNull;
-
- static <T> Predicate<T> everythingAsPredicate() {
- return (Predicate<T>) EVERYTHING;
- }
-
- static <T> Predicate<T> nothingAsPredicate() {
- return (Predicate<T>) NOTHING;
- }
-
- static <T> Predicate<T> notNullAsPredicate() {
- return (Predicate<T>) NOT_NULL;
- }
-
- static Whitelist only(Object item) {
- return item::equals;
- }
-
- static Whitelist not(Object item) {
- return o -> !item.equals(o);
- }
-
- static Whitelist only(Object item1, Object item2) {
- return item -> item1.equals(item) || item2.equals(item);
- }
-
- static Whitelist not(Object item1, Object item2) {
- return item -> !(item1.equals(item) || item2.equals(item));
- }
-
- static Whitelist only(Object[] objects) {
- return new SetBasedWhitelist(objects, false);
- }
-
- static Whitelist not(Object[] objects) {
- return new SetBasedWhitelist(objects, true);
- }
-
- static Whitelist fromConfig(ConfigurationSection section, Function<String, ?> parser) {
- if (section == null) {
- return NOTHING;
- }
- boolean blacklist = section.getBoolean("blacklist", false);
- Set list = section.getStringList("listed").stream().map(parser).filter(Objects::nonNull).collect(Collectors.toSet());
- switch (list.size()) {
- case 0:
- return blacklist ? EVERYTHING : NOTHING;
- case 1: {
- Iterator iterator = list.iterator();
- return blacklist ? not(iterator.next()) : only(iterator.next());
- }
- case 2: {
- Iterator iterator = list.iterator();
- return blacklist ? not(iterator.next(), iterator.next()) : only(iterator.next(), iterator.next());
- }
- default:
- Object item = list.iterator().next();
- if (item instanceof Enum) {
- list = EnumSet.copyOf(list);
- }
- return new SetBasedWhitelist(list, blacklist);
- }
- }
-
- static void copyIntoConfig(ConfigurationSection target, Function<Object, String> mapper, boolean blacklist, Object... objects) {
- target.set("blacklist", blacklist);
- target.set("listed", Arrays.stream(objects).map(mapper).unordered().distinct().collect(Collectors.toList()));
- }
-
- @Override
- default boolean test(Object o) {
- return isWhitelisted(o);
- }
-
- boolean isWhitelisted(Object o);
-}
-
+package io.dico.dicore;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+@FunctionalInterface
+public interface Whitelist extends Predicate {
+
+ Whitelist EVERYTHING = item -> true;
+ Whitelist NOTHING = item -> false;
+ Whitelist NOT_NULL = Objects::nonNull;
+
+ static <T> Predicate<T> everythingAsPredicate() {
+ return (Predicate<T>) EVERYTHING;
+ }
+
+ static <T> Predicate<T> nothingAsPredicate() {
+ return (Predicate<T>) NOTHING;
+ }
+
+ static <T> Predicate<T> notNullAsPredicate() {
+ return (Predicate<T>) NOT_NULL;
+ }
+
+ static Whitelist only(Object item) {
+ return item::equals;
+ }
+
+ static Whitelist not(Object item) {
+ return o -> !item.equals(o);
+ }
+
+ static Whitelist only(Object item1, Object item2) {
+ return item -> item1.equals(item) || item2.equals(item);
+ }
+
+ static Whitelist not(Object item1, Object item2) {
+ return item -> !(item1.equals(item) || item2.equals(item));
+ }
+
+ static Whitelist only(Object[] objects) {
+ return new SetBasedWhitelist(objects, false);
+ }
+
+ static Whitelist not(Object[] objects) {
+ return new SetBasedWhitelist(objects, true);
+ }
+
+ static Whitelist fromConfig(ConfigurationSection section, Function<String, ?> parser) {
+ if (section == null) {
+ return NOTHING;
+ }
+ boolean blacklist = section.getBoolean("blacklist", false);
+ Set list = section.getStringList("listed").stream().map(parser).filter(Objects::nonNull).collect(Collectors.toSet());
+ switch (list.size()) {
+ case 0:
+ return blacklist ? EVERYTHING : NOTHING;
+ case 1: {
+ Iterator iterator = list.iterator();
+ return blacklist ? not(iterator.next()) : only(iterator.next());
+ }
+ case 2: {
+ Iterator iterator = list.iterator();
+ return blacklist ? not(iterator.next(), iterator.next()) : only(iterator.next(), iterator.next());
+ }
+ default:
+ Object item = list.iterator().next();
+ if (item instanceof Enum) {
+ list = EnumSet.copyOf(list);
+ }
+ return new SetBasedWhitelist(list, blacklist);
+ }
+ }
+
+ static void copyIntoConfig(ConfigurationSection target, Function<Object, String> mapper, boolean blacklist, Object... objects) {
+ target.set("blacklist", blacklist);
+ target.set("listed", Arrays.stream(objects).map(mapper).unordered().distinct().collect(Collectors.toList()));
+ }
+
+ @Override
+ default boolean test(Object o) {
+ return isWhitelisted(o);
+ }
+
+ boolean isWhitelisted(Object o);
+}
+
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListener.java b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListener.java
index 93584ea..378424d 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListener.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListener.java
@@ -1,46 +1,46 @@
-package io.dico.dicore.event;
-
-import io.dico.dicore.InterfaceChain;
-
-public interface ChainedListener<T> extends InterfaceChain<SimpleListener<T>, ChainedListener<T>>, SimpleListener<T> {
-
- @Override
- default ChainedListener<T> getEmptyInstance() {
- return ChainedListeners.empty();
- }
-
- @Override
- default ChainedListener<T> withElement(SimpleListener<T> element) {
- if (element == null) {
- return this;
- }
-
- int count = getElementCount() + 1;
- return new ChainedListener<T>() {
- @Override
- public void accept(T event) {
- try {
- ChainedListener.this.accept(event);
- } finally {
- element.accept(event);
- }
- }
-
- @Override
- public ChainedListener<T> withoutLastNode() {
- return ChainedListener.this;
- }
-
- @Override
- public SimpleListener<T> getDelegateOfLastNode() {
- return element;
- }
-
- @Override
- public int getElementCount() {
- return count;
- }
- };
- }
-
-}
+package io.dico.dicore.event;
+
+import io.dico.dicore.InterfaceChain;
+
+public interface ChainedListener<T> extends InterfaceChain<SimpleListener<T>, ChainedListener<T>>, SimpleListener<T> {
+
+ @Override
+ default ChainedListener<T> getEmptyInstance() {
+ return ChainedListeners.empty();
+ }
+
+ @Override
+ default ChainedListener<T> withElement(SimpleListener<T> element) {
+ if (element == null) {
+ return this;
+ }
+
+ int count = getElementCount() + 1;
+ return new ChainedListener<T>() {
+ @Override
+ public void accept(T event) {
+ try {
+ ChainedListener.this.accept(event);
+ } finally {
+ element.accept(event);
+ }
+ }
+
+ @Override
+ public ChainedListener<T> withoutLastNode() {
+ return ChainedListener.this;
+ }
+
+ @Override
+ public SimpleListener<T> getDelegateOfLastNode() {
+ return element;
+ }
+
+ @Override
+ public int getElementCount() {
+ return count;
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandle.java b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandle.java
index 86b8448..875c131 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandle.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandle.java
@@ -1,55 +1,55 @@
-package io.dico.dicore.event;
-
-import io.dico.dicore.InterfaceChain;
-
-public interface ChainedListenerHandle extends InterfaceChain<ListenerHandle, ChainedListenerHandle>, ListenerHandle {
-
- @Override
- default ChainedListenerHandle getEmptyInstance() {
- return ChainedListenerHandles.empty();
- }
-
- @Override
- default ChainedListenerHandle withElement(ListenerHandle element) {
- if (element == null) {
- return this;
- }
-
- int count = getElementCount() + 1;
- return new ChainedListenerHandle() {
- @Override
- public void register() {
- try {
- ChainedListenerHandle.this.register();
- } finally {
- element.register();
- }
- }
-
- @Override
- public void unregister() {
- try {
- ChainedListenerHandle.this.unregister();
- } finally {
- element.unregister();
- }
- }
-
- @Override
- public ChainedListenerHandle withoutLastNode() {
- return ChainedListenerHandle.this;
- }
-
- @Override
- public ListenerHandle getDelegateOfLastNode() {
- return element;
- }
-
- @Override
- public int getElementCount() {
- return count;
- }
- };
- }
-
-}
+package io.dico.dicore.event;
+
+import io.dico.dicore.InterfaceChain;
+
+public interface ChainedListenerHandle extends InterfaceChain<ListenerHandle, ChainedListenerHandle>, ListenerHandle {
+
+ @Override
+ default ChainedListenerHandle getEmptyInstance() {
+ return ChainedListenerHandles.empty();
+ }
+
+ @Override
+ default ChainedListenerHandle withElement(ListenerHandle element) {
+ if (element == null) {
+ return this;
+ }
+
+ int count = getElementCount() + 1;
+ return new ChainedListenerHandle() {
+ @Override
+ public void register() {
+ try {
+ ChainedListenerHandle.this.register();
+ } finally {
+ element.register();
+ }
+ }
+
+ @Override
+ public void unregister() {
+ try {
+ ChainedListenerHandle.this.unregister();
+ } finally {
+ element.unregister();
+ }
+ }
+
+ @Override
+ public ChainedListenerHandle withoutLastNode() {
+ return ChainedListenerHandle.this;
+ }
+
+ @Override
+ public ListenerHandle getDelegateOfLastNode() {
+ return element;
+ }
+
+ @Override
+ public int getElementCount() {
+ return count;
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandles.java b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandles.java
index 0be0508..15c4553 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandles.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListenerHandles.java
@@ -1,63 +1,63 @@
-package io.dico.dicore.event;
-
-public class ChainedListenerHandles {
-
- private ChainedListenerHandles() {
-
- }
-
- private static final ChainedListenerHandle empty = new ChainedListenerHandle() {
- @Override
- public void register() {
-
- }
-
- public void unregister() {
-
- }
-
- @Override
- public ChainedListenerHandle withElement(ListenerHandle other) {
- return ChainedListenerHandles.singleton(other);
- }
-
- @Override
- public int getElementCount() {
- return 0;
- }
-
- @Override
- public ListenerHandle getDelegateOfLastNode() {
- return null;
- }
- };
-
- public static ChainedListenerHandle empty() {
- return empty;
- }
-
- public static ChainedListenerHandle singleton(ListenerHandle element) {
- if (element instanceof ChainedListenerHandle) {
- return (ChainedListenerHandle) element;
- }
- if (element == null) {
- return empty();
- }
- return new ChainedListenerHandle() {
- @Override
- public void register() {
- element.register();
- }
-
- public void unregister() {
- element.unregister();
- }
-
- @Override
- public ListenerHandle getDelegateOfLastNode() {
- return element;
- }
- };
- }
-
-}
+package io.dico.dicore.event;
+
+public class ChainedListenerHandles {
+
+ private ChainedListenerHandles() {
+
+ }
+
+ private static final ChainedListenerHandle empty = new ChainedListenerHandle() {
+ @Override
+ public void register() {
+
+ }
+
+ public void unregister() {
+
+ }
+
+ @Override
+ public ChainedListenerHandle withElement(ListenerHandle other) {
+ return ChainedListenerHandles.singleton(other);
+ }
+
+ @Override
+ public int getElementCount() {
+ return 0;
+ }
+
+ @Override
+ public ListenerHandle getDelegateOfLastNode() {
+ return null;
+ }
+ };
+
+ public static ChainedListenerHandle empty() {
+ return empty;
+ }
+
+ public static ChainedListenerHandle singleton(ListenerHandle element) {
+ if (element instanceof ChainedListenerHandle) {
+ return (ChainedListenerHandle) element;
+ }
+ if (element == null) {
+ return empty();
+ }
+ return new ChainedListenerHandle() {
+ @Override
+ public void register() {
+ element.register();
+ }
+
+ public void unregister() {
+ element.unregister();
+ }
+
+ @Override
+ public ListenerHandle getDelegateOfLastNode() {
+ return element;
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListeners.java b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListeners.java
index 1d2bcd4..44050a2 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListeners.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/ChainedListeners.java
@@ -1,56 +1,56 @@
-package io.dico.dicore.event;
-
-@SuppressWarnings("unchecked")
-public class ChainedListeners {
-
- private static final ChainedListener<?> empty = new ChainedListener<Object>() {
- @Override
- public void accept(Object event) {
-
- }
-
- @Override
- public ChainedListener<Object> withElement(SimpleListener other) {
- return ChainedListeners.singleton(other);
- }
-
- @Override
- public int getElementCount() {
- return 0;
- }
-
- @Override
- public SimpleListener<Object> getDelegateOfLastNode() {
- return null;
- }
- };
-
- private ChainedListeners() {
-
- }
-
- public static <T> ChainedListener<T> empty() {
- return (ChainedListener<T>) empty;
- }
-
- public static <T> ChainedListener<T> singleton(SimpleListener<T> element) {
- if (element instanceof ChainedListener) {
- return (ChainedListener<T>) element;
- }
- if (element == null) {
- return empty();
- }
- return new ChainedListener<T>() {
- @Override
- public void accept(T event) {
- element.accept(event);
- }
-
- @Override
- public SimpleListener getDelegateOfLastNode() {
- return element;
- }
- };
- }
-
-}
+package io.dico.dicore.event;
+
+@SuppressWarnings("unchecked")
+public class ChainedListeners {
+
+ private static final ChainedListener<?> empty = new ChainedListener<Object>() {
+ @Override
+ public void accept(Object event) {
+
+ }
+
+ @Override
+ public ChainedListener<Object> withElement(SimpleListener other) {
+ return ChainedListeners.singleton(other);
+ }
+
+ @Override
+ public int getElementCount() {
+ return 0;
+ }
+
+ @Override
+ public SimpleListener<Object> getDelegateOfLastNode() {
+ return null;
+ }
+ };
+
+ private ChainedListeners() {
+
+ }
+
+ public static <T> ChainedListener<T> empty() {
+ return (ChainedListener<T>) empty;
+ }
+
+ public static <T> ChainedListener<T> singleton(SimpleListener<T> element) {
+ if (element instanceof ChainedListener) {
+ return (ChainedListener<T>) element;
+ }
+ if (element == null) {
+ return empty();
+ }
+ return new ChainedListener<T>() {
+ @Override
+ public void accept(T event) {
+ element.accept(event);
+ }
+
+ @Override
+ public SimpleListener getDelegateOfLastNode() {
+ return element;
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/HandlerList.java b/dicore3/core/src/main/java/io/dico/dicore/event/HandlerList.java
index 56265bb..fa290c0 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/HandlerList.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/HandlerList.java
@@ -1,91 +1,91 @@
-package io.dico.dicore.event;
-
-import org.bukkit.event.Cancellable;
-import org.bukkit.event.EventPriority;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.function.Consumer;
-
-public final class HandlerList<T> {
- private final List<Listener<T>> source = new ArrayList<>();
- private Listener<T>[] listeners = newArray(0);
-
- public void refresh() {
- source.sort(Comparator.comparingInt(l -> l.getPriority().ordinal()));
- listeners = source.toArray(newArray(source.size()));
- }
-
- @SuppressWarnings("unchecked")
- private static <T> Listener<T>[] newArray(int length) {
- return new Listener[length];
- }
-
- public void register(Listener<T> listener) {
- if (!source.contains(listener) && source.add(listener)) {
- refresh();
- }
- }
-
- public ListenerHandle getListenerHandle(Listener<T> listener) {
- return new ListenerHandle() {
- @Override
- public void register() {
- HandlerList.this.register(listener);
- }
-
- @Override
- public void unregister() {
- HandlerList.this.unregister(listener);
- }
- };
- }
-
- public void register(EventPriority priority, Consumer<T> listener) {
- register(new Listener<T>() {
- @Override
- public EventPriority getPriority() {
- return priority;
- }
-
- @Override
- public void accept(T event) {
- listener.accept(event);
- }
- });
- }
-
- public List<Listener<T>> getRegistrations() {
- return Collections.unmodifiableList(source);
- }
-
- public void unregister(Listener<T> listener) {
- if (source.remove(listener)) {
- refresh();
- }
- }
-
- public void callEvent(T event) {
- if (event instanceof Cancellable) {
- Cancellable c = (Cancellable) event;
- boolean cancelled = c.isCancelled();
- for (Listener<T> listener : listeners) {
- if (listener.listensToCancelledState(cancelled)) {
- //EnchantsPlugin.getInstance().debug("Listener acceptance: " + listener.getClass().getSimpleName());
- listener.accept(event);
- cancelled = c.isCancelled();
- } /*else {
- EnchantsPlugin.getInstance().debug("Listener does not listen to cancelled state of " + cancelled + ": " + listener.getClass().getSimpleName());
- }*/
- }
- } else {
- for (Listener<T> listener : listeners) {
- //EnchantsPlugin.getInstance().debug("Listener acceptance: " + listener.getClass().getSimpleName());
- listener.accept(event);
- }
- }
- }
-
-}
+package io.dico.dicore.event;
+
+import org.bukkit.event.Cancellable;
+import org.bukkit.event.EventPriority;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.function.Consumer;
+
+public final class HandlerList<T> {
+ private final List<Listener<T>> source = new ArrayList<>();
+ private Listener<T>[] listeners = newArray(0);
+
+ public void refresh() {
+ source.sort(Comparator.comparingInt(l -> l.getPriority().ordinal()));
+ listeners = source.toArray(newArray(source.size()));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> Listener<T>[] newArray(int length) {
+ return new Listener[length];
+ }
+
+ public void register(Listener<T> listener) {
+ if (!source.contains(listener) && source.add(listener)) {
+ refresh();
+ }
+ }
+
+ public ListenerHandle getListenerHandle(Listener<T> listener) {
+ return new ListenerHandle() {
+ @Override
+ public void register() {
+ HandlerList.this.register(listener);
+ }
+
+ @Override
+ public void unregister() {
+ HandlerList.this.unregister(listener);
+ }
+ };
+ }
+
+ public void register(EventPriority priority, Consumer<T> listener) {
+ register(new Listener<T>() {
+ @Override
+ public EventPriority getPriority() {
+ return priority;
+ }
+
+ @Override
+ public void accept(T event) {
+ listener.accept(event);
+ }
+ });
+ }
+
+ public List<Listener<T>> getRegistrations() {
+ return Collections.unmodifiableList(source);
+ }
+
+ public void unregister(Listener<T> listener) {
+ if (source.remove(listener)) {
+ refresh();
+ }
+ }
+
+ public void callEvent(T event) {
+ if (event instanceof Cancellable) {
+ Cancellable c = (Cancellable) event;
+ boolean cancelled = c.isCancelled();
+ for (Listener<T> listener : listeners) {
+ if (listener.listensToCancelledState(cancelled)) {
+ //EnchantsPlugin.getInstance().debug("Listener acceptance: " + listener.getClass().getSimpleName());
+ listener.accept(event);
+ cancelled = c.isCancelled();
+ } /*else {
+ EnchantsPlugin.getInstance().debug("Listener does not listen to cancelled state of " + cancelled + ": " + listener.getClass().getSimpleName());
+ }*/
+ }
+ } else {
+ for (Listener<T> listener : listeners) {
+ //EnchantsPlugin.getInstance().debug("Listener acceptance: " + listener.getClass().getSimpleName());
+ listener.accept(event);
+ }
+ }
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/Listener.java b/dicore3/core/src/main/java/io/dico/dicore/event/Listener.java
index c3e5413..064cd28 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/Listener.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/Listener.java
@@ -1,17 +1,17 @@
-package io.dico.dicore.event;
-
-import org.bukkit.event.EventPriority;
-
-public interface Listener<T> {
-
- default EventPriority getPriority() {
- return EventPriority.NORMAL;
- }
-
- default boolean listensToCancelledState(boolean cancelled) {
- return !cancelled;
- }
-
- void accept(T event);
-
-}
+package io.dico.dicore.event;
+
+import org.bukkit.event.EventPriority;
+
+public interface Listener<T> {
+
+ default EventPriority getPriority() {
+ return EventPriority.NORMAL;
+ }
+
+ default boolean listensToCancelledState(boolean cancelled) {
+ return !cancelled;
+ }
+
+ void accept(T event);
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/ListenerHandle.java b/dicore3/core/src/main/java/io/dico/dicore/event/ListenerHandle.java
index 6042954..fbedd9f 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/ListenerHandle.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/ListenerHandle.java
@@ -1,9 +1,9 @@
-package io.dico.dicore.event;
-
-public interface ListenerHandle {
-
- void register();
-
- void unregister();
-
-}
+package io.dico.dicore.event;
+
+public interface ListenerHandle {
+
+ void register();
+
+ void unregister();
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/event/SimpleListener.java b/dicore3/core/src/main/java/io/dico/dicore/event/SimpleListener.java
index 9688975..4e49a55 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/event/SimpleListener.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/event/SimpleListener.java
@@ -1,7 +1,7 @@
-package io.dico.dicore.event;
-
-public interface SimpleListener<T> {
-
- void accept(T event);
-
-}
+package io.dico.dicore.event;
+
+public interface SimpleListener<T> {
+
+ void accept(T event);
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/ExceptionHandler.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/ExceptionHandler.java
index e95b65e..2777125 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/ExceptionHandler.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/ExceptionHandler.java
@@ -1,203 +1,203 @@
-package io.dico.dicore.exceptions;
-
-import io.dico.dicore.exceptions.checkedfunctions.CheckedRunnable;
-import io.dico.dicore.exceptions.checkedfunctions.CheckedSupplier;
-import io.dico.dicore.exceptions.checkedfunctions.CheckedFunctionalObject;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.sql.SQLException;
-import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
-
-@FunctionalInterface
-public interface ExceptionHandler {
-
- /**
- * Handle the given exception according to this handler's implementation
- *
- * @param ex The exception to be handled
- * @throws NullPointerException if ex is null, unless the implementation specifies otherwise
- * @throws Error ex if ex is an instance of Error, unless the implementation specifies otherwise
- */
- void handle(Throwable ex);
-
- /**
- * Handle the given exception according to this handler's implementation
- * This method is intended for use by {@link CheckedFunctionalObject} and subinterfaces.
- * It supplies exception handlers the option to acquire more information, by overriding this method and calling it from {@link #handle(Throwable)}
- *
- * @param ex The exception to be handled
- * @param args Any arguments passed, this is used by {@link CheckedFunctionalObject} and subinterfaces.
- * @return {@code null} (unless specified otherwise by the implementation)
- * @throws NullPointerException if ex is null, unless the implementation specifies otherwise
- * @throws Error ex if ex is an instance of Error, unless the implementation specifies otherwise
- */
- default Object handleGenericException(Throwable ex, Object... args) {
- handle(ex);
- return null;
- }
-
- /**
- * @return true if this {@link ExceptionHandler}'s {@link #handleGenericException(Throwable, Object...)} method is <b>never</b> expected to throw
- * an unchecked exception other than {@link Error}
- */
- default boolean isSafe() {
- return true;
- }
-
- /**
- * Runs the given checked action, handling any thrown exceptions using this exception handler.
- * <p>
- * Any exceptions thrown by this handler are delegated to the caller.
- *
- * @param action The action to run
- * @throws NullPointerException if action is null
- */
- default void runSafe(CheckedRunnable<? extends Throwable> action) {
- Objects.requireNonNull(action);
- try {
- action.checkedRun();
- } catch (Throwable ex) {
- handle(ex);
- }
- }
-
- /**
- * Computes the result of the given checked supplier, handling any thrown exceptions using this exception handler.
- * <p>
- * Any exceptions thrown by this handler are delegated to the caller.
- *
- * @param action The supplier whose result to compute
- * @param <T> generic type parameter for the supplier and the result type of this method
- * @return The result of this computation, or null if an error occurred
- * @throws NullPointerException if action is null
- */
-
- default <T> T supplySafe(CheckedSupplier<T, ? extends Throwable> action) {
- Objects.requireNonNull(action);
- try {
- return action.checkedGet();
- } catch (Throwable ex) {
- handle(ex);
- return null;
- }
- }
-
- /**
- * @param action The action to wrap
- * @return A runnable that wraps the given action using this handler's {@link #runSafe(CheckedRunnable)} method.
- * @see #runSafe(CheckedRunnable)
- */
- default Runnable safeRunnable(CheckedRunnable<? extends Throwable> action) {
- return () -> runSafe(action);
- }
-
- /**
- * @param supplier The computation to wrap
- * @return A supplier that wraps the given computation using this handler's {@link #supplySafe(CheckedSupplier)} method.
- * @see #supplySafe(CheckedSupplier)
- */
- default <T> Supplier<T> safeSupplier(CheckedSupplier<T, ? extends Throwable> supplier) {
- return () -> supplySafe(supplier);
- }
-
- /**
- * Logs the given exception as an error to {@code out}
- * <p>
- * Format: Error occurred while {@code failedActivityDescription}, followed by additional details and a stack trace
- *
- * @param out The consumer to accept the error message, for instance {@code {@link java.util.logging.Logger logger}::warning}.
- * @param failedActivityDescription A description of the activity that was being executed when the exception was thrown
- * @param ex The exception that was thrown
- * @throws NullPointerException if any argument is null
- */
- static void log(Consumer<String> out, String failedActivityDescription, Throwable ex) {
- if (out == null || failedActivityDescription == null || ex == null) {
- throw new NullPointerException();
- }
-
- StringWriter msg = new StringWriter(1024);
- msg.append("Error occurred while ").append(failedActivityDescription).append(':');
-
- if (ex instanceof SQLException) {
- SQLException sqlex = (SQLException) ex;
- msg.append('\n').append("Error code: ").append(Integer.toString(sqlex.getErrorCode()));
- msg.append('\n').append("SQL State: ").append(sqlex.getSQLState());
- }
-
- msg.append('\n').append("=======START STACK=======");
- try (PrintWriter pw = new PrintWriter(msg)) {
- ex.printStackTrace(pw);
- }
- msg.append('\n').append("========END STACK========");
-
- out.accept(msg.toString());
- }
-
- /**
- * @param activityDescription The activity description
- * @return An ExceptionHandler that prints to {@link System#out}
- * @see #log(Consumer, String)
- */
- static ExceptionHandler log(String activityDescription) {
- // A method reference would cache the current value in System.out
- // This would update if the value in System.out is changed (by for example, applying a PrintStream that handles colours).
- return log(msg -> System.out.println(msg), activityDescription);
- }
-
- /**
- * @param out The Consumer to be passed to {@link #log(Consumer, String, Throwable)}
- * @param activityDescription The activity description to be passed to {@link #log(Consumer, String, Throwable)}
- * @return An ExceptionHandler that passes exceptions with given arguments to {@link #log(Consumer, String, Throwable)}
- * @see #log(Consumer, String, Throwable)
- */
- static ExceptionHandler log(Consumer<String> out, String activityDescription) {
- return ex -> log(out, activityDescription, ex);
- }
-
- /**
- * This ExceptionHandler turns any Throwable into an unchecked exception, then throws it again.
- */
- ExceptionHandler UNCHECKED = new ExceptionHandler() {
- @Override
- public void handle(Throwable ex) {
- errorFilter(ex);
- if (ex instanceof RuntimeException) {
- throw (RuntimeException) ex;
- }
- throw new RuntimeException(ex);
- }
-
- @Override
- public boolean isSafe() {
- return false;
- }
- };
-
- /**
- * This ExceptionHandler suppresses all exceptions,
- * apart from {@link Error} because that is not usually supposed to be caught
- */
- ExceptionHandler SUPPRESS = ExceptionHandler::errorFilter;
-
- /**
- * This ExceptionHandler calls {@link Throwable#printStackTrace()} unless it is a {@link NullPointerException} or {@link Error}.
- */
- ExceptionHandler PRINT_UNLESS_NP = ex -> {
- errorFilter(ex);
- if (!(ex instanceof NullPointerException)) {
- ex.printStackTrace();
- }
- };
-
- static void errorFilter(Throwable ex) {
- if (ex instanceof Error) {
- throw (Error) ex;
- } else if (ex == null) {
- throw new NullPointerException();
- }
- }
-
-}
+package io.dico.dicore.exceptions;
+
+import io.dico.dicore.exceptions.checkedfunctions.CheckedRunnable;
+import io.dico.dicore.exceptions.checkedfunctions.CheckedSupplier;
+import io.dico.dicore.exceptions.checkedfunctions.CheckedFunctionalObject;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.sql.SQLException;
+import java.util.Objects;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+@FunctionalInterface
+public interface ExceptionHandler {
+
+ /**
+ * Handle the given exception according to this handler's implementation
+ *
+ * @param ex The exception to be handled
+ * @throws NullPointerException if ex is null, unless the implementation specifies otherwise
+ * @throws Error ex if ex is an instance of Error, unless the implementation specifies otherwise
+ */
+ void handle(Throwable ex);
+
+ /**
+ * Handle the given exception according to this handler's implementation
+ * This method is intended for use by {@link CheckedFunctionalObject} and subinterfaces.
+ * It supplies exception handlers the option to acquire more information, by overriding this method and calling it from {@link #handle(Throwable)}
+ *
+ * @param ex The exception to be handled
+ * @param args Any arguments passed, this is used by {@link CheckedFunctionalObject} and subinterfaces.
+ * @return {@code null} (unless specified otherwise by the implementation)
+ * @throws NullPointerException if ex is null, unless the implementation specifies otherwise
+ * @throws Error ex if ex is an instance of Error, unless the implementation specifies otherwise
+ */
+ default Object handleGenericException(Throwable ex, Object... args) {
+ handle(ex);
+ return null;
+ }
+
+ /**
+ * @return true if this {@link ExceptionHandler}'s {@link #handleGenericException(Throwable, Object...)} method is <b>never</b> expected to throw
+ * an unchecked exception other than {@link Error}
+ */
+ default boolean isSafe() {
+ return true;
+ }
+
+ /**
+ * Runs the given checked action, handling any thrown exceptions using this exception handler.
+ * <p>
+ * Any exceptions thrown by this handler are delegated to the caller.
+ *
+ * @param action The action to run
+ * @throws NullPointerException if action is null
+ */
+ default void runSafe(CheckedRunnable<? extends Throwable> action) {
+ Objects.requireNonNull(action);
+ try {
+ action.checkedRun();
+ } catch (Throwable ex) {
+ handle(ex);
+ }
+ }
+
+ /**
+ * Computes the result of the given checked supplier, handling any thrown exceptions using this exception handler.
+ * <p>
+ * Any exceptions thrown by this handler are delegated to the caller.
+ *
+ * @param action The supplier whose result to compute
+ * @param <T> generic type parameter for the supplier and the result type of this method
+ * @return The result of this computation, or null if an error occurred
+ * @throws NullPointerException if action is null
+ */
+
+ default <T> T supplySafe(CheckedSupplier<T, ? extends Throwable> action) {
+ Objects.requireNonNull(action);
+ try {
+ return action.checkedGet();
+ } catch (Throwable ex) {
+ handle(ex);
+ return null;
+ }
+ }
+
+ /**
+ * @param action The action to wrap
+ * @return A runnable that wraps the given action using this handler's {@link #runSafe(CheckedRunnable)} method.
+ * @see #runSafe(CheckedRunnable)
+ */
+ default Runnable safeRunnable(CheckedRunnable<? extends Throwable> action) {
+ return () -> runSafe(action);
+ }
+
+ /**
+ * @param supplier The computation to wrap
+ * @return A supplier that wraps the given computation using this handler's {@link #supplySafe(CheckedSupplier)} method.
+ * @see #supplySafe(CheckedSupplier)
+ */
+ default <T> Supplier<T> safeSupplier(CheckedSupplier<T, ? extends Throwable> supplier) {
+ return () -> supplySafe(supplier);
+ }
+
+ /**
+ * Logs the given exception as an error to {@code out}
+ * <p>
+ * Format: Error occurred while {@code failedActivityDescription}, followed by additional details and a stack trace
+ *
+ * @param out The consumer to accept the error message, for instance {@code {@link java.util.logging.Logger logger}::warning}.
+ * @param failedActivityDescription A description of the activity that was being executed when the exception was thrown
+ * @param ex The exception that was thrown
+ * @throws NullPointerException if any argument is null
+ */
+ static void log(Consumer<String> out, String failedActivityDescription, Throwable ex) {
+ if (out == null || failedActivityDescription == null || ex == null) {
+ throw new NullPointerException();
+ }
+
+ StringWriter msg = new StringWriter(1024);
+ msg.append("Error occurred while ").append(failedActivityDescription).append(':');
+
+ if (ex instanceof SQLException) {
+ SQLException sqlex = (SQLException) ex;
+ msg.append('\n').append("Error code: ").append(Integer.toString(sqlex.getErrorCode()));
+ msg.append('\n').append("SQL State: ").append(sqlex.getSQLState());
+ }
+
+ msg.append('\n').append("=======START STACK=======");
+ try (PrintWriter pw = new PrintWriter(msg)) {
+ ex.printStackTrace(pw);
+ }
+ msg.append('\n').append("========END STACK========");
+
+ out.accept(msg.toString());
+ }
+
+ /**
+ * @param activityDescription The activity description
+ * @return An ExceptionHandler that prints to {@link System#out}
+ * @see #log(Consumer, String)
+ */
+ static ExceptionHandler log(String activityDescription) {
+ // A method reference would cache the current value in System.out
+ // This would update if the value in System.out is changed (by for example, applying a PrintStream that handles colours).
+ return log(msg -> System.out.println(msg), activityDescription);
+ }
+
+ /**
+ * @param out The Consumer to be passed to {@link #log(Consumer, String, Throwable)}
+ * @param activityDescription The activity description to be passed to {@link #log(Consumer, String, Throwable)}
+ * @return An ExceptionHandler that passes exceptions with given arguments to {@link #log(Consumer, String, Throwable)}
+ * @see #log(Consumer, String, Throwable)
+ */
+ static ExceptionHandler log(Consumer<String> out, String activityDescription) {
+ return ex -> log(out, activityDescription, ex);
+ }
+
+ /**
+ * This ExceptionHandler turns any Throwable into an unchecked exception, then throws it again.
+ */
+ ExceptionHandler UNCHECKED = new ExceptionHandler() {
+ @Override
+ public void handle(Throwable ex) {
+ errorFilter(ex);
+ if (ex instanceof RuntimeException) {
+ throw (RuntimeException) ex;
+ }
+ throw new RuntimeException(ex);
+ }
+
+ @Override
+ public boolean isSafe() {
+ return false;
+ }
+ };
+
+ /**
+ * This ExceptionHandler suppresses all exceptions,
+ * apart from {@link Error} because that is not usually supposed to be caught
+ */
+ ExceptionHandler SUPPRESS = ExceptionHandler::errorFilter;
+
+ /**
+ * This ExceptionHandler calls {@link Throwable#printStackTrace()} unless it is a {@link NullPointerException} or {@link Error}.
+ */
+ ExceptionHandler PRINT_UNLESS_NP = ex -> {
+ errorFilter(ex);
+ if (!(ex instanceof NullPointerException)) {
+ ex.printStackTrace();
+ }
+ };
+
+ static void errorFilter(Throwable ex) {
+ if (ex instanceof Error) {
+ throw (Error) ex;
+ } else if (ex == null) {
+ throw new NullPointerException();
+ }
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiConsumer.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiConsumer.java
index badf05b..bfcafe8 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiConsumer.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiConsumer.java
@@ -1,69 +1,69 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-import java.util.function.BiConsumer;
-
-/**
- * checked mimic of {@link BiConsumer}
- *
- * @param <TParam1>
- * @param <TParam2>
- * @param <TException>
- */
-@FunctionalInterface
-public interface CheckedBiConsumer<TParam1, TParam2, TException extends Throwable>
- extends CheckedFunctionalObject<Void, TException>, BiConsumer<TParam1, TParam2> {
-
- /**
- * The consuming action
- *
- * @param t the first argument to consume
- * @param u the second argument to consume
- * @throws TException if an exception occurs
- */
- void checkedAccept(TParam1 t, TParam2 u) throws TException;
-
- /**
- * unchecked wrapper for {@link #checkedAccept(Object, Object)}
- * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
- *
- * @param t the first input
- * @param u the second input
- * @see #checkedAccept(Object, Object)
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- default void accept(TParam1 t, TParam2 u) {
- try {
- checkedAccept(t, u);
- } catch (Throwable ex) {
- handleGenericException(ex, t, u);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- default CheckedBiConsumer<TParam1, TParam2, TException> handleExceptionsWith(ExceptionHandler handler) {
- return new CheckedBiConsumer<TParam1, TParam2, TException>() {
- @Override
- public void checkedAccept(TParam1 t, TParam2 u) throws TException {
- CheckedBiConsumer.this.checkedAccept(t, u);
- }
-
- @Override
- public Void handleGenericException(Throwable thrown, Object... args) {
- handler.handleGenericException(thrown, args);
- return null;
- }
-
- @Override
- public CheckedBiConsumer<TParam1, TParam2, TException> handleExceptionsWith(ExceptionHandler handler) {
- return CheckedBiConsumer.this.handleExceptionsWith(handler);
- }
- };
- }
-
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+import java.util.function.BiConsumer;
+
+/**
+ * checked mimic of {@link BiConsumer}
+ *
+ * @param <TParam1>
+ * @param <TParam2>
+ * @param <TException>
+ */
+@FunctionalInterface
+public interface CheckedBiConsumer<TParam1, TParam2, TException extends Throwable>
+ extends CheckedFunctionalObject<Void, TException>, BiConsumer<TParam1, TParam2> {
+
+ /**
+ * The consuming action
+ *
+ * @param t the first argument to consume
+ * @param u the second argument to consume
+ * @throws TException if an exception occurs
+ */
+ void checkedAccept(TParam1 t, TParam2 u) throws TException;
+
+ /**
+ * unchecked wrapper for {@link #checkedAccept(Object, Object)}
+ * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
+ *
+ * @param t the first input
+ * @param u the second input
+ * @see #checkedAccept(Object, Object)
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ default void accept(TParam1 t, TParam2 u) {
+ try {
+ checkedAccept(t, u);
+ } catch (Throwable ex) {
+ handleGenericException(ex, t, u);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ default CheckedBiConsumer<TParam1, TParam2, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return new CheckedBiConsumer<TParam1, TParam2, TException>() {
+ @Override
+ public void checkedAccept(TParam1 t, TParam2 u) throws TException {
+ CheckedBiConsumer.this.checkedAccept(t, u);
+ }
+
+ @Override
+ public Void handleGenericException(Throwable thrown, Object... args) {
+ handler.handleGenericException(thrown, args);
+ return null;
+ }
+
+ @Override
+ public CheckedBiConsumer<TParam1, TParam2, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return CheckedBiConsumer.this.handleExceptionsWith(handler);
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiFunction.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiFunction.java
index 9b39325..11fca3f 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiFunction.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedBiFunction.java
@@ -1,76 +1,76 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-import java.util.function.BiFunction;
-
-/**
- * checked mimic of {@link BiFunction}
- *
- * @param <TParam1>
- * @param <TParam2>
- * @param <TResult>
- * @param <TException>
- */
-@FunctionalInterface
-public interface CheckedBiFunction<TParam1, TParam2, TResult, TException extends Throwable>
- extends CheckedFunctionalObject<TResult, TException>, BiFunction<TParam1, TParam2, TResult> {
-
- /**
- * the functional method
- *
- * @param t the first input
- * @param u the second input
- * @return the function output
- * @throws TException if an exception occurs
- */
- TResult checkedApply(TParam1 t, TParam2 u) throws TException;
-
- /**
- * unchecked wrapper for {@link #checkedApply(Object, Object)}
- * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
- *
- * @param t the first input
- * @param u the second input
- * @return the function output, or the result from {@link #resultOnError(Throwable, Object...)} if an exception was thrown
- * @see #checkedApply(Object, Object)
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- default TResult apply(TParam1 t, TParam2 u) {
- try {
- return checkedApply(t, u);
- } catch (Throwable ex) {
- return handleGenericException(ex, t, u);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- default CheckedBiFunction<TParam1, TParam2, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
- return new CheckedBiFunction<TParam1, TParam2, TResult, TException>() {
- @Override
- public TResult checkedApply(TParam1 t, TParam2 u) throws TException {
- return CheckedBiFunction.this.checkedApply(t, u);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public TResult handleGenericException(Throwable thrown, Object... args) {
- Object result = handler.handleGenericException(thrown, args);
- try {
- return (TResult) result;
- } catch (Exception ex) {
- return null;
- }
- }
-
- @Override
- public CheckedBiFunction<TParam1, TParam2, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
- return CheckedBiFunction.this.handleExceptionsWith(handler);
- }
- };
- }
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+import java.util.function.BiFunction;
+
+/**
+ * checked mimic of {@link BiFunction}
+ *
+ * @param <TParam1>
+ * @param <TParam2>
+ * @param <TResult>
+ * @param <TException>
+ */
+@FunctionalInterface
+public interface CheckedBiFunction<TParam1, TParam2, TResult, TException extends Throwable>
+ extends CheckedFunctionalObject<TResult, TException>, BiFunction<TParam1, TParam2, TResult> {
+
+ /**
+ * the functional method
+ *
+ * @param t the first input
+ * @param u the second input
+ * @return the function output
+ * @throws TException if an exception occurs
+ */
+ TResult checkedApply(TParam1 t, TParam2 u) throws TException;
+
+ /**
+ * unchecked wrapper for {@link #checkedApply(Object, Object)}
+ * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
+ *
+ * @param t the first input
+ * @param u the second input
+ * @return the function output, or the result from {@link #resultOnError(Throwable, Object...)} if an exception was thrown
+ * @see #checkedApply(Object, Object)
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ default TResult apply(TParam1 t, TParam2 u) {
+ try {
+ return checkedApply(t, u);
+ } catch (Throwable ex) {
+ return handleGenericException(ex, t, u);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ default CheckedBiFunction<TParam1, TParam2, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return new CheckedBiFunction<TParam1, TParam2, TResult, TException>() {
+ @Override
+ public TResult checkedApply(TParam1 t, TParam2 u) throws TException {
+ return CheckedBiFunction.this.checkedApply(t, u);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public TResult handleGenericException(Throwable thrown, Object... args) {
+ Object result = handler.handleGenericException(thrown, args);
+ try {
+ return (TResult) result;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ @Override
+ public CheckedBiFunction<TParam1, TParam2, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return CheckedBiFunction.this.handleExceptionsWith(handler);
+ }
+ };
+ }
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedConsumer.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedConsumer.java
index fa48ae8..abe6d53 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedConsumer.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedConsumer.java
@@ -1,67 +1,67 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-import java.util.function.Consumer;
-
-/**
- * checked mimic of {@link Consumer}
- *
- * @param <TParam>
- * @param <TException>
- */
-@FunctionalInterface
-public interface CheckedConsumer<TParam, TException extends Throwable>
- extends CheckedFunctionalObject<Void, TException>, Consumer<TParam> {
-
- /**
- * The consuming action
- *
- * @param t the argument to consume
- * @throws TException if an error occurs
- */
- void checkedAccept(TParam t) throws TException;
-
- /**
- * Unchecked version of {@link #checkedAccept(Object)}
- * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
- *
- * @param t the argument to consume
- * @see #checkedAccept(Object)
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- default void accept(TParam t) {
- try {
- checkedAccept(t);
- } catch (Throwable ex) {
- handleGenericException(ex, t);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- default CheckedConsumer<TParam, TException> handleExceptionsWith(ExceptionHandler handler) {
- return new CheckedConsumer<TParam, TException>() {
- @Override
- public void checkedAccept(TParam t) throws TException {
- CheckedConsumer.this.checkedAccept(t);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Void handleGenericException(Throwable thrown, Object... args) {
- handler.handleGenericException(thrown, args);
- return null;
- }
-
- @Override
- public CheckedConsumer<TParam, TException> handleExceptionsWith(ExceptionHandler handler) {
- return CheckedConsumer.this.handleExceptionsWith(handler);
- }
- };
- }
-
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+import java.util.function.Consumer;
+
+/**
+ * checked mimic of {@link Consumer}
+ *
+ * @param <TParam>
+ * @param <TException>
+ */
+@FunctionalInterface
+public interface CheckedConsumer<TParam, TException extends Throwable>
+ extends CheckedFunctionalObject<Void, TException>, Consumer<TParam> {
+
+ /**
+ * The consuming action
+ *
+ * @param t the argument to consume
+ * @throws TException if an error occurs
+ */
+ void checkedAccept(TParam t) throws TException;
+
+ /**
+ * Unchecked version of {@link #checkedAccept(Object)}
+ * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
+ *
+ * @param t the argument to consume
+ * @see #checkedAccept(Object)
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ default void accept(TParam t) {
+ try {
+ checkedAccept(t);
+ } catch (Throwable ex) {
+ handleGenericException(ex, t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ default CheckedConsumer<TParam, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return new CheckedConsumer<TParam, TException>() {
+ @Override
+ public void checkedAccept(TParam t) throws TException {
+ CheckedConsumer.this.checkedAccept(t);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Void handleGenericException(Throwable thrown, Object... args) {
+ handler.handleGenericException(thrown, args);
+ return null;
+ }
+
+ @Override
+ public CheckedConsumer<TParam, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return CheckedConsumer.this.handleExceptionsWith(handler);
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunction.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunction.java
index 9ff806a..48ac207 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunction.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunction.java
@@ -1,74 +1,74 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-import java.util.function.Function;
-
-/**
- * checked mimic of {@link Function}
- *
- * @param <TParam>
- * @param <TResult>
- * @param <TException>
- */
-@FunctionalInterface
-public interface CheckedFunction<TParam, TResult, TException extends Throwable>
- extends CheckedFunctionalObject<TResult, TException>, Function<TParam, TResult> {
-
- /**
- * the functional method
- *
- * @param t the input
- * @return the function output
- * @throws TException if an exception occurs
- */
- TResult checkedApply(TParam t) throws TException;
-
- /**
- * unchecked wrapper for {@link #checkedApply(Object)}
- * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
- *
- * @param t the input
- * @return the function output, or the result from {@link #resultOnError(Throwable, Object...)} if an exception was thrown
- * @see #checkedApply(Object)
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- default TResult apply(TParam t) {
- try {
- return checkedApply(t);
- } catch (Throwable ex) {
- return handleGenericException(ex, t);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- default CheckedFunction<TParam, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
- return new CheckedFunction<TParam, TResult, TException>() {
- @Override
- public TResult checkedApply(TParam t) throws TException {
- return CheckedFunction.this.checkedApply(t);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public TResult handleGenericException(Throwable thrown, Object... args) {
- Object result = handler.handleGenericException(thrown, args);
- try {
- return (TResult) result;
- } catch (Exception ex) {
- return null;
- }
- }
-
- @Override
- public CheckedFunction<TParam, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
- return CheckedFunction.this.handleExceptionsWith(handler);
- }
- };
- }
-
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+import java.util.function.Function;
+
+/**
+ * checked mimic of {@link Function}
+ *
+ * @param <TParam>
+ * @param <TResult>
+ * @param <TException>
+ */
+@FunctionalInterface
+public interface CheckedFunction<TParam, TResult, TException extends Throwable>
+ extends CheckedFunctionalObject<TResult, TException>, Function<TParam, TResult> {
+
+ /**
+ * the functional method
+ *
+ * @param t the input
+ * @return the function output
+ * @throws TException if an exception occurs
+ */
+ TResult checkedApply(TParam t) throws TException;
+
+ /**
+ * unchecked wrapper for {@link #checkedApply(Object)}
+ * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
+ *
+ * @param t the input
+ * @return the function output, or the result from {@link #resultOnError(Throwable, Object...)} if an exception was thrown
+ * @see #checkedApply(Object)
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ default TResult apply(TParam t) {
+ try {
+ return checkedApply(t);
+ } catch (Throwable ex) {
+ return handleGenericException(ex, t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ default CheckedFunction<TParam, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return new CheckedFunction<TParam, TResult, TException>() {
+ @Override
+ public TResult checkedApply(TParam t) throws TException {
+ return CheckedFunction.this.checkedApply(t);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public TResult handleGenericException(Throwable thrown, Object... args) {
+ Object result = handler.handleGenericException(thrown, args);
+ try {
+ return (TResult) result;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ @Override
+ public CheckedFunction<TParam, TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return CheckedFunction.this.handleExceptionsWith(handler);
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunctionalObject.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunctionalObject.java
index e84b33d..d9d7a53 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunctionalObject.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedFunctionalObject.java
@@ -1,85 +1,85 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-/**
- * Base interface for all checked functional interfaces
- * Most subinterfaces will mimic interfaces in the package {@link java.util.function}
- * <p>
- * Checked functional interfaces are functions with throws declarations.
- * The name comes from the fact that they can throw <b>checked</b> exceptions.
- * <p>
- * They extend their non-checked counterparts, whose methods are implemented by
- * returning the result of {@link #resultOnError(TException, Object...)} when an exception is thrown
- * <p>
- * Made public to allow more specialized checked functional interfaces to subclass it.
- * Making primitive versions shouldn't provide a significant performance increase because we're checking for exceptions,
- * the performance impact of which is probably a few magnitudes larger. Don't quote me on this.
- *
- * @param <TResult> The return type of this functional interface's method
- * @param <TException> The type of exception that might be thrown
- */
-public interface CheckedFunctionalObject<TResult, TException extends Throwable> extends ExceptionHandler {
-
- /**
- * {@inheritDoc}
- *
- * @param ex The exception to be handled
- */
- @Override
- default void handle(Throwable ex) {
- handleGenericException(ex);
- }
-
- /**
- * {@inheritDoc}
- * <p>
- * Method to handle exceptions thrown by the default implementations of subinterfaces.
- * Since you can't catch a type parameter as exception, this code is in place to take care of it.
- * <p>
- * If the thrown exception is not a TException, an unchecked version is thrown by calling this method.
- *
- * @param thrown The thrown exception
- * @param args the arguments supplied to the method that threw the exception, if any. These are not guaranteed to be given if parameters are present.
- * @return The result computed by {@link #resultOnError(Throwable, Object...)}
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- @SuppressWarnings("unchecked")
- default TResult handleGenericException(Throwable thrown, Object... args) {
-
- // check if the throwable is a TException
- TException castedException;
- try {
- castedException = (TException) thrown;
- } catch (ClassCastException ex) {
- // if not, throw an unchecked version of it
- ExceptionHandler.UNCHECKED.handleGenericException(thrown);
- // this code is never reached.
- return null;
- }
-
- // if it is a TException, use resultOnError to compute result.
- return resultOnError(castedException, args);
- }
-
- /**
- * This method handles the exceptions thrown by the checked method of this object, when called by its unchecked wrapper.
- *
- * @param ex The exception thrown
- * @param args The (typed) arguments passed, if any
- * @return The result to return, if any
- */
- default TResult resultOnError(TException ex, Object... args) {
- return null;
- }
-
- /**
- * Creates a new functional object that uses the given exception handler to handle exceptions.
- *
- * @param handler The handler to handle exceptions
- * @return a new functional object that uses the given exception handler to handle exceptions
- */
- CheckedFunctionalObject<TResult, TException> handleExceptionsWith(ExceptionHandler handler);
-
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+/**
+ * Base interface for all checked functional interfaces
+ * Most subinterfaces will mimic interfaces in the package {@link java.util.function}
+ * <p>
+ * Checked functional interfaces are functions with throws declarations.
+ * The name comes from the fact that they can throw <b>checked</b> exceptions.
+ * <p>
+ * They extend their non-checked counterparts, whose methods are implemented by
+ * returning the result of {@link #resultOnError(TException, Object...)} when an exception is thrown
+ * <p>
+ * Made public to allow more specialized checked functional interfaces to subclass it.
+ * Making primitive versions shouldn't provide a significant performance increase because we're checking for exceptions,
+ * the performance impact of which is probably a few magnitudes larger. Don't quote me on this.
+ *
+ * @param <TResult> The return type of this functional interface's method
+ * @param <TException> The type of exception that might be thrown
+ */
+public interface CheckedFunctionalObject<TResult, TException extends Throwable> extends ExceptionHandler {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param ex The exception to be handled
+ */
+ @Override
+ default void handle(Throwable ex) {
+ handleGenericException(ex);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Method to handle exceptions thrown by the default implementations of subinterfaces.
+ * Since you can't catch a type parameter as exception, this code is in place to take care of it.
+ * <p>
+ * If the thrown exception is not a TException, an unchecked version is thrown by calling this method.
+ *
+ * @param thrown The thrown exception
+ * @param args the arguments supplied to the method that threw the exception, if any. These are not guaranteed to be given if parameters are present.
+ * @return The result computed by {@link #resultOnError(Throwable, Object...)}
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ @SuppressWarnings("unchecked")
+ default TResult handleGenericException(Throwable thrown, Object... args) {
+
+ // check if the throwable is a TException
+ TException castedException;
+ try {
+ castedException = (TException) thrown;
+ } catch (ClassCastException ex) {
+ // if not, throw an unchecked version of it
+ ExceptionHandler.UNCHECKED.handleGenericException(thrown);
+ // this code is never reached.
+ return null;
+ }
+
+ // if it is a TException, use resultOnError to compute result.
+ return resultOnError(castedException, args);
+ }
+
+ /**
+ * This method handles the exceptions thrown by the checked method of this object, when called by its unchecked wrapper.
+ *
+ * @param ex The exception thrown
+ * @param args The (typed) arguments passed, if any
+ * @return The result to return, if any
+ */
+ default TResult resultOnError(TException ex, Object... args) {
+ return null;
+ }
+
+ /**
+ * Creates a new functional object that uses the given exception handler to handle exceptions.
+ *
+ * @param handler The handler to handle exceptions
+ * @return a new functional object that uses the given exception handler to handle exceptions
+ */
+ CheckedFunctionalObject<TResult, TException> handleExceptionsWith(ExceptionHandler handler);
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedRunnable.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedRunnable.java
index 55de6f8..110c988 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedRunnable.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedRunnable.java
@@ -1,62 +1,62 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-/**
- * checked mimic of {@link Runnable}
- *
- * @param <TException>
- */
-@FunctionalInterface
-public interface CheckedRunnable<TException extends Throwable>
- extends CheckedFunctionalObject<Void, TException>, Runnable {
-
- /**
- * The runnable action
- *
- * @throws TException if an exception occurs
- */
- void checkedRun() throws TException;
-
- /**
- * Unchecked version of {@link #checkedRun()}
- * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
- *
- * @see #checkedRun()
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- default void run() {
- try {
- checkedRun();
- } catch (Throwable ex) {
- handleGenericException(ex);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- default CheckedRunnable<TException> handleExceptionsWith(ExceptionHandler handler) {
- return new CheckedRunnable<TException>() {
- @Override
- public void checkedRun() throws TException {
- CheckedRunnable.this.checkedRun();
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public Void handleGenericException(Throwable thrown, Object... args) {
- handler.handleGenericException(thrown, args);
- return null;
- }
-
- @Override
- public CheckedRunnable<TException> handleExceptionsWith(ExceptionHandler handler) {
- return CheckedRunnable.this.handleExceptionsWith(handler);
- }
- };
- }
-
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+/**
+ * checked mimic of {@link Runnable}
+ *
+ * @param <TException>
+ */
+@FunctionalInterface
+public interface CheckedRunnable<TException extends Throwable>
+ extends CheckedFunctionalObject<Void, TException>, Runnable {
+
+ /**
+ * The runnable action
+ *
+ * @throws TException if an exception occurs
+ */
+ void checkedRun() throws TException;
+
+ /**
+ * Unchecked version of {@link #checkedRun()}
+ * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
+ *
+ * @see #checkedRun()
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ default void run() {
+ try {
+ checkedRun();
+ } catch (Throwable ex) {
+ handleGenericException(ex);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ default CheckedRunnable<TException> handleExceptionsWith(ExceptionHandler handler) {
+ return new CheckedRunnable<TException>() {
+ @Override
+ public void checkedRun() throws TException {
+ CheckedRunnable.this.checkedRun();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Void handleGenericException(Throwable thrown, Object... args) {
+ handler.handleGenericException(thrown, args);
+ return null;
+ }
+
+ @Override
+ public CheckedRunnable<TException> handleExceptionsWith(ExceptionHandler handler) {
+ return CheckedRunnable.this.handleExceptionsWith(handler);
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedSupplier.java b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedSupplier.java
index dec2e7e..7820428 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedSupplier.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/exceptions/checkedfunctions/CheckedSupplier.java
@@ -1,70 +1,70 @@
-package io.dico.dicore.exceptions.checkedfunctions;
-
-import io.dico.dicore.exceptions.ExceptionHandler;
-
-import java.util.function.Supplier;
-
-/**
- * checked mimic of {@link Supplier}
- *
- * @param <TResult>
- * @param <TException>
- */
-@FunctionalInterface
-public interface CheckedSupplier<TResult, TException extends Throwable>
- extends CheckedFunctionalObject<TResult, TException>, Supplier<TResult> {
-
- /**
- * The computation
- *
- * @return the result of this computation
- * @throws TException if an error occurs
- */
- TResult checkedGet() throws TException;
-
- /**
- * Unchecked version of {@link #checkedGet()}
- * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
- *
- * @return the result of this computation
- * @see #checkedGet()
- * @see #resultOnError(Throwable, Object...)
- */
- @Override
- default TResult get() {
- try {
- return checkedGet();
- } catch (Throwable ex) {
- return handleGenericException(ex);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- default CheckedSupplier<TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
- return new CheckedSupplier<TResult, TException>() {
- @Override
- public TResult checkedGet() throws TException {
- return CheckedSupplier.this.checkedGet();
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public TResult handleGenericException(Throwable thrown, Object... args) {
- Object result = handler.handleGenericException(thrown, args);
- try {
- return (TResult) result;
- } catch (Exception ex) {
- return null;
- }
- }
-
- @Override
- public CheckedSupplier<TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
- return CheckedSupplier.this.handleExceptionsWith(handler);
- }
- };
- }
-}
+package io.dico.dicore.exceptions.checkedfunctions;
+
+import io.dico.dicore.exceptions.ExceptionHandler;
+
+import java.util.function.Supplier;
+
+/**
+ * checked mimic of {@link Supplier}
+ *
+ * @param <TResult>
+ * @param <TException>
+ */
+@FunctionalInterface
+public interface CheckedSupplier<TResult, TException extends Throwable>
+ extends CheckedFunctionalObject<TResult, TException>, Supplier<TResult> {
+
+ /**
+ * The computation
+ *
+ * @return the result of this computation
+ * @throws TException if an error occurs
+ */
+ TResult checkedGet() throws TException;
+
+ /**
+ * Unchecked version of {@link #checkedGet()}
+ * If a {@link TException} occurs, an unchecked one might be thrown by {@link #resultOnError(Throwable, Object...)}
+ *
+ * @return the result of this computation
+ * @see #checkedGet()
+ * @see #resultOnError(Throwable, Object...)
+ */
+ @Override
+ default TResult get() {
+ try {
+ return checkedGet();
+ } catch (Throwable ex) {
+ return handleGenericException(ex);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ default CheckedSupplier<TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return new CheckedSupplier<TResult, TException>() {
+ @Override
+ public TResult checkedGet() throws TException {
+ return CheckedSupplier.this.checkedGet();
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public TResult handleGenericException(Throwable thrown, Object... args) {
+ Object result = handler.handleGenericException(thrown, args);
+ try {
+ return (TResult) result;
+ } catch (Exception ex) {
+ return null;
+ }
+ }
+
+ @Override
+ public CheckedSupplier<TResult, TException> handleExceptionsWith(ExceptionHandler handler) {
+ return CheckedSupplier.this.handleExceptionsWith(handler);
+ }
+ };
+ }
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/task/BaseTask.java b/dicore3/core/src/main/java/io/dico/dicore/task/BaseTask.java
index b400cce..43db459 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/task/BaseTask.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/task/BaseTask.java
@@ -1,108 +1,108 @@
-package io.dico.dicore.task;
-
-import org.bukkit.Bukkit;
-import org.bukkit.plugin.Plugin;
-
-import java.util.NoSuchElementException;
-
-public abstract class BaseTask<T> {
- private boolean running = false;
- private Integer taskId = null;
- private long workTime = 5L;
- private int workCount;
-
- public void start(Plugin plugin, int delay, int period, long workTime) {
- doStartChecks();
- this.workTime = workTime;
- workCount = 0;
- running = true;
-
- if (delay == -1) {
- run();
- if (!running) {
- return;
- }
- delay = period;
- }
-
- taskId = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, this::run, delay, period);
- }
-
- public void startImmediately(Plugin plugin, int period, long workTime) {
- start(plugin, -1, period, workTime);
- }
-
- protected void doStartChecks() {
- if (isRunning()) {
- throw new IllegalStateException("Can't start when already running");
- }
- }
-
- public void start(Plugin plugin) {
- start(plugin, -1, 20, 5L);
- }
-
- protected void onFinish(boolean early) {
- }
-
- protected long getWorkTime() {
- return workTime;
- }
-
- protected abstract boolean process(T object);
-
- private void run() {
- workCount++;
- final long stop = System.currentTimeMillis() + getWorkTime();
- do {
- if (!processNext()) {
- return;
- }
- } while (System.currentTimeMillis() < stop);
- }
-
- public int getTaskId() {
- return running ? taskId : -1;
- }
-
- public int getWorkCount() {
- return workCount;
- }
-
- public boolean isRunning() {
- return running;
- }
-
- protected abstract T supply() throws NoSuchElementException;
-
- private void cancelTask(boolean early) {
- if (taskId != null) {
- Bukkit.getScheduler().cancelTask(taskId);
- }
- running = false;
- taskId = null;
- onFinish(early);
- }
-
- private boolean processNext() {
- T object;
- try {
- object = supply();
- } catch (NoSuchElementException e) {
- cancelTask(false);
- return false;
- }
-
- try {
- if (process(object)) {
- return true;
- }
- } catch (RuntimeException e) {
- e.printStackTrace();
- }
-
- cancelTask(true);
- return false;
- }
-
-}
+package io.dico.dicore.task;
+
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.Plugin;
+
+import java.util.NoSuchElementException;
+
+public abstract class BaseTask<T> {
+ private boolean running = false;
+ private Integer taskId = null;
+ private long workTime = 5L;
+ private int workCount;
+
+ public void start(Plugin plugin, int delay, int period, long workTime) {
+ doStartChecks();
+ this.workTime = workTime;
+ workCount = 0;
+ running = true;
+
+ if (delay == -1) {
+ run();
+ if (!running) {
+ return;
+ }
+ delay = period;
+ }
+
+ taskId = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, this::run, delay, period);
+ }
+
+ public void startImmediately(Plugin plugin, int period, long workTime) {
+ start(plugin, -1, period, workTime);
+ }
+
+ protected void doStartChecks() {
+ if (isRunning()) {
+ throw new IllegalStateException("Can't start when already running");
+ }
+ }
+
+ public void start(Plugin plugin) {
+ start(plugin, -1, 20, 5L);
+ }
+
+ protected void onFinish(boolean early) {
+ }
+
+ protected long getWorkTime() {
+ return workTime;
+ }
+
+ protected abstract boolean process(T object);
+
+ private void run() {
+ workCount++;
+ final long stop = System.currentTimeMillis() + getWorkTime();
+ do {
+ if (!processNext()) {
+ return;
+ }
+ } while (System.currentTimeMillis() < stop);
+ }
+
+ public int getTaskId() {
+ return running ? taskId : -1;
+ }
+
+ public int getWorkCount() {
+ return workCount;
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ protected abstract T supply() throws NoSuchElementException;
+
+ private void cancelTask(boolean early) {
+ if (taskId != null) {
+ Bukkit.getScheduler().cancelTask(taskId);
+ }
+ running = false;
+ taskId = null;
+ onFinish(early);
+ }
+
+ private boolean processNext() {
+ T object;
+ try {
+ object = supply();
+ } catch (NoSuchElementException e) {
+ cancelTask(false);
+ return false;
+ }
+
+ try {
+ if (process(object)) {
+ return true;
+ }
+ } catch (RuntimeException e) {
+ e.printStackTrace();
+ }
+
+ cancelTask(true);
+ return false;
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/task/IteratorTask.java b/dicore3/core/src/main/java/io/dico/dicore/task/IteratorTask.java
index e58814c..3ff7be7 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/task/IteratorTask.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/task/IteratorTask.java
@@ -1,120 +1,120 @@
-package io.dico.dicore.task;
-
-import java.util.*;
-import java.util.function.BiConsumer;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
-import java.util.function.Predicate;
-
-public abstract class IteratorTask<T> extends BaseTask<T> {
-
- private Iterator<? extends T> iterator;
-
- public IteratorTask() {
- }
-
- @SuppressWarnings("unchecked")
- public IteratorTask(Iterable<? extends T> iterable, boolean clone) {
- refresh(iterable, clone);
- }
-
- public IteratorTask(Iterable<? extends T> iterable) {
- this(iterable, false);
- }
-
- public IteratorTask(Iterator<? extends T> iterator) {
- refresh(iterator);
- }
-
- @Override
- protected void doStartChecks() {
- super.doStartChecks();
- if (iterator == null) {
- throw new IllegalStateException("An iterator must be supplied first");
- }
- }
-
- protected final void refresh(Iterable<? extends T> iterable, boolean clone) {
- if (clone) {
- Collection<T> collection;
- if (!(iterable instanceof Collection)) {
- collection = new LinkedList<>();
- for (T next : iterable) {
- collection.add(next);
- }
- } else {
- collection = new ArrayList((Collection) iterable);
- }
- iterator = collection.iterator();
- } else {
- iterator = iterable.iterator();
- }
- }
-
- protected final void refresh(Iterator<? extends T> iterator) {
- Objects.requireNonNull(iterator);
- this.iterator = iterator;
- }
-
- @Override
- protected T supply() {
- return iterator.next();
- }
-
- protected void remove() {
- iterator.remove();
- }
-
- // One argument: The processed object
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, Consumer<T> processor) {
- return create(iterable, false, processor);
- }
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, Consumer<T> processor) {
- return create(iterable, clone, object -> {
- processor.accept(object);
- return true;
- });
- }
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, Predicate<T> processor) {
- return create(iterable, false, processor);
- }
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, Predicate<T> processor) {
- return new IteratorTask<T>(iterable, clone) {
- @Override
- protected boolean process(T object) {
- return processor.test(object);
- }
- };
- }
-
- // Two arguments: the processed object, and a runnable to remove it from the iterator.
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, BiConsumer<T, Runnable> processor) {
- return create(iterable, false, processor);
- }
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, BiConsumer<T, Runnable> processor) {
- return create(iterable, clone, (object, runnable) -> {
- processor.accept(object, runnable);
- return true;
- });
- }
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, BiPredicate<T, Runnable> processor) {
- return create(iterable, false, processor);
- }
-
- public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, BiPredicate<T, Runnable> processor) {
- return new IteratorTask<T>(iterable, clone) {
- @Override
- protected boolean process(T object) {
- return processor.test(object, this::remove);
- }
- };
- }
-
-}
+package io.dico.dicore.task;
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public abstract class IteratorTask<T> extends BaseTask<T> {
+
+ private Iterator<? extends T> iterator;
+
+ public IteratorTask() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public IteratorTask(Iterable<? extends T> iterable, boolean clone) {
+ refresh(iterable, clone);
+ }
+
+ public IteratorTask(Iterable<? extends T> iterable) {
+ this(iterable, false);
+ }
+
+ public IteratorTask(Iterator<? extends T> iterator) {
+ refresh(iterator);
+ }
+
+ @Override
+ protected void doStartChecks() {
+ super.doStartChecks();
+ if (iterator == null) {
+ throw new IllegalStateException("An iterator must be supplied first");
+ }
+ }
+
+ protected final void refresh(Iterable<? extends T> iterable, boolean clone) {
+ if (clone) {
+ Collection<T> collection;
+ if (!(iterable instanceof Collection)) {
+ collection = new LinkedList<>();
+ for (T next : iterable) {
+ collection.add(next);
+ }
+ } else {
+ collection = new ArrayList((Collection) iterable);
+ }
+ iterator = collection.iterator();
+ } else {
+ iterator = iterable.iterator();
+ }
+ }
+
+ protected final void refresh(Iterator<? extends T> iterator) {
+ Objects.requireNonNull(iterator);
+ this.iterator = iterator;
+ }
+
+ @Override
+ protected T supply() {
+ return iterator.next();
+ }
+
+ protected void remove() {
+ iterator.remove();
+ }
+
+ // One argument: The processed object
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, Consumer<T> processor) {
+ return create(iterable, false, processor);
+ }
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, Consumer<T> processor) {
+ return create(iterable, clone, object -> {
+ processor.accept(object);
+ return true;
+ });
+ }
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, Predicate<T> processor) {
+ return create(iterable, false, processor);
+ }
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, Predicate<T> processor) {
+ return new IteratorTask<T>(iterable, clone) {
+ @Override
+ protected boolean process(T object) {
+ return processor.test(object);
+ }
+ };
+ }
+
+ // Two arguments: the processed object, and a runnable to remove it from the iterator.
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, BiConsumer<T, Runnable> processor) {
+ return create(iterable, false, processor);
+ }
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, BiConsumer<T, Runnable> processor) {
+ return create(iterable, clone, (object, runnable) -> {
+ processor.accept(object, runnable);
+ return true;
+ });
+ }
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, BiPredicate<T, Runnable> processor) {
+ return create(iterable, false, processor);
+ }
+
+ public static <T> IteratorTask<T> create(Iterable<? extends T> iterable, boolean clone, BiPredicate<T, Runnable> processor) {
+ return new IteratorTask<T>(iterable, clone) {
+ @Override
+ protected boolean process(T object) {
+ return processor.test(object, this::remove);
+ }
+ };
+ }
+
+}
diff --git a/dicore3/core/src/main/java/io/dico/dicore/task/VoidTask.java b/dicore3/core/src/main/java/io/dico/dicore/task/VoidTask.java
index 1298c4c..6204bee 100644
--- a/dicore3/core/src/main/java/io/dico/dicore/task/VoidTask.java
+++ b/dicore3/core/src/main/java/io/dico/dicore/task/VoidTask.java
@@ -1,19 +1,19 @@
-package io.dico.dicore.task;
-
-import java.util.NoSuchElementException;
-
-public abstract class VoidTask extends BaseTask<Void> {
-
- @Override
- protected final boolean process(Void object) {
- return process();
- }
-
- @Override
- protected final Void supply() throws NoSuchElementException {
- return null;
- }
-
- protected abstract boolean process();
-
-}
+package io.dico.dicore.task;
+
+import java.util.NoSuchElementException;
+
+public abstract class VoidTask extends BaseTask<Void> {
+
+ @Override
+ protected final boolean process(Void object) {
+ return process();
+ }
+
+ @Override
+ protected final Void supply() throws NoSuchElementException {
+ return null;
+ }
+
+ protected abstract boolean process();
+
+}