Modularise project
This commit is contained in:
parent
2be3825438
commit
4416d55173
55 changed files with 388 additions and 331 deletions
|
|
@ -0,0 +1,15 @@
|
|||
package net.frankheijden.serverutils.common.reflection;
|
||||
|
||||
public class FieldParam {
|
||||
public String field;
|
||||
public VersionParam versionParam;
|
||||
|
||||
private FieldParam(String field, VersionParam versionParam) {
|
||||
this.field = field;
|
||||
this.versionParam = versionParam;
|
||||
}
|
||||
|
||||
public static FieldParam fieldOf(String field, VersionParam versionParam) {
|
||||
return new FieldParam(field, versionParam);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package net.frankheijden.serverutils.common.reflection;
|
||||
|
||||
public class MethodParam {
|
||||
|
||||
public String method;
|
||||
public VersionParam versionParam;
|
||||
public Class<?>[] params;
|
||||
|
||||
private MethodParam(String method, VersionParam versionParam, Class<?>... params) {
|
||||
this.method = method;
|
||||
this.versionParam = versionParam;
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public static MethodParam methodOf(String method, VersionParam versionParam, Class<?>... params) {
|
||||
return new MethodParam(method, versionParam, params);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
package net.frankheijden.serverutils.common.reflection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class ReflectionUtils {
|
||||
|
||||
private static ReflectionUtils instance;
|
||||
|
||||
public ReflectionUtils() {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static ReflectionUtils getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public abstract boolean isCompatible(VersionParam param);
|
||||
|
||||
/**
|
||||
* Retrieves a declared field from a class and makes it accessible.
|
||||
* @param clazz The class of the method.
|
||||
* @param field The field name.
|
||||
* @return The specified field.
|
||||
* @throws NoSuchFieldException iff field doesn't exist.
|
||||
*/
|
||||
public static Field getDeclaredField(Class<?> clazz, String field) throws NoSuchFieldException {
|
||||
Field f = clazz.getDeclaredField(field);
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a field from a class and makes it accessible.
|
||||
* @param clazz The class of the method.
|
||||
* @param field The field name.
|
||||
* @return The specified field.
|
||||
* @throws NoSuchFieldException iff field doesn't exist.
|
||||
*/
|
||||
public static Field getField(Class<?> clazz, String field) throws NoSuchFieldException {
|
||||
Field f = clazz.getField(field);
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a declared method from a class and makes it accessible.
|
||||
* @param clazz The class of the method.
|
||||
* @param method The method name.
|
||||
* @param params The parameters of the method.
|
||||
* @return The specified method.
|
||||
* @throws NoSuchMethodException iff method doesn't exist.
|
||||
*/
|
||||
public static Method getDeclaredMethod(Class<?> clazz, String method, Class<?>... params)
|
||||
throws NoSuchMethodException {
|
||||
Method m = clazz.getDeclaredMethod(method, params);
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a method from a class and makes it accessible.
|
||||
* @param clazz The class of the method.
|
||||
* @param method The method name.
|
||||
* @param params The parameters of the method.
|
||||
* @return The specified method.
|
||||
* @throws NoSuchMethodException iff method doesn't exist.
|
||||
*/
|
||||
public static Method getMethod(Class<?> clazz, String method, Class<?>... params)
|
||||
throws NoSuchMethodException {
|
||||
Method m = clazz.getMethod(method, params);
|
||||
m.setAccessible(true);
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves fields from a class based on the specified FieldParams.
|
||||
* @param clazz The class of the fields.
|
||||
* @param fieldParams The fields which will be collected.
|
||||
* @return A map with key the field name and value the actual field.
|
||||
*/
|
||||
public static Map<String, Field> getAllFields(Class<?> clazz, FieldParam... fieldParams) {
|
||||
Map<String, Field> map = new HashMap<>();
|
||||
for (FieldParam fieldParam : fieldParams) {
|
||||
if (!getInstance().isCompatible(fieldParam.versionParam)) continue;
|
||||
try {
|
||||
map.put(fieldParam.field, getDeclaredField(clazz, fieldParam.field));
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
try {
|
||||
map.put(fieldParam.field, getField(clazz, fieldParam.field));
|
||||
} catch (NoSuchFieldException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves methods from a class based on the specified MethodParams.
|
||||
* @param clazz The class of the methods.
|
||||
* @param methodParams The methods which will be collected.
|
||||
* @return A map with key the method name and value the actual method.
|
||||
*/
|
||||
public static Map<String, Method> getAllMethods(Class<?> clazz, MethodParam... methodParams) {
|
||||
Map<String, Method> map = new HashMap<>();
|
||||
for (MethodParam methodParam : methodParams) {
|
||||
if (!getInstance().isCompatible(methodParam.versionParam)) continue;
|
||||
try {
|
||||
map.put(methodParam.method, getDeclaredMethod(clazz, methodParam.method, methodParam.params));
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
try {
|
||||
map.put(methodParam.method, getMethod(clazz, methodParam.method, methodParam.params));
|
||||
} catch (NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a method on an instance.
|
||||
* Will return null if method not present in map.
|
||||
* @param map The map with methods.
|
||||
* @param instance The instance of the class.
|
||||
* @param methodName The name of the method.
|
||||
* @param params The parameters of the method.
|
||||
* @return The object returned by the method, or null if not present in map.
|
||||
* @throws InvocationTargetException If the method call produced an exception.
|
||||
* @throws IllegalAccessException When prohibited access to the method.
|
||||
*/
|
||||
public static Object invoke(Map<String, Method> map, Object instance, String methodName, Object... params)
|
||||
throws InvocationTargetException, IllegalAccessException {
|
||||
Method method = map.get(methodName);
|
||||
if (method == null) return null;
|
||||
return method.invoke(instance, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specified field from an object instance.
|
||||
* Returns null if the field is not in the map.
|
||||
* @param map The map with fields.
|
||||
* @param instance The instance of the class.
|
||||
* @param fieldName The field name.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
public static Object get(Map<String, Field> map, Object instance, String fieldName) throws IllegalAccessException {
|
||||
Field field = map.get(fieldName);
|
||||
if (field == null) return null;
|
||||
return field.get(instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified field to the specified value.
|
||||
* Will silently fail if the field is not in the map.
|
||||
* @param map The map with fields.
|
||||
* @param instance The instance of the class.
|
||||
* @param fieldName The field name.
|
||||
* @param value The value to set the field to.
|
||||
* @throws IllegalAccessException When prohibited access to the field.
|
||||
*/
|
||||
public static void set(Map<String, Field> map, Object instance, String fieldName, Object value)
|
||||
throws IllegalAccessException {
|
||||
Field field = map.get(fieldName);
|
||||
if (field == null) return;
|
||||
field.set(instance, value);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.frankheijden.serverutils.common.reflection;
|
||||
|
||||
public class VersionParam {
|
||||
|
||||
public static VersionParam ALL_VERSIONS = new VersionParam(Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
|
||||
public int min;
|
||||
public int max;
|
||||
|
||||
private VersionParam(int min, int max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public static VersionParam versionOf(int ver) {
|
||||
return new VersionParam(ver, ver);
|
||||
}
|
||||
|
||||
public static VersionParam between(int min, int max) {
|
||||
return new VersionParam(min, max);
|
||||
}
|
||||
|
||||
public static VersionParam min(int min) {
|
||||
return between(min, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public static VersionParam max(int max) {
|
||||
return between(Integer.MIN_VALUE, max);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0)"
|
||||
+ " Gecko/20100101"
|
||||
+ " Firefox/77.0";
|
||||
|
||||
/**
|
||||
* Downloads file from a URL to a file location.
|
||||
* @param urlString The url to download.
|
||||
* @param target The location to save the output to.
|
||||
* @throws IOException If an I/O exception occurs.
|
||||
*/
|
||||
public static void download(String urlString, File target) throws IOException {
|
||||
try (InputStream is = stream(urlString)) {
|
||||
if (is == null) return;
|
||||
try (ReadableByteChannel rbc = Channels.newChannel(is);
|
||||
FileOutputStream fos = new FileOutputStream(target)) {
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a stream to an url.
|
||||
* @param url The url to stream.
|
||||
* @return An InputStream of the url.
|
||||
* @throws IOException If an I/O exception occurs.
|
||||
*/
|
||||
public static InputStream stream(String url) throws IOException {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setRequestProperty("User-Agent", USER_AGENT);
|
||||
conn.setConnectTimeout(10000);
|
||||
int res = conn.getResponseCode();
|
||||
return (res >= 200 && res <= 299) ? conn.getInputStream() : conn.getErrorStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all bytes from a reader and appends them to a string result.
|
||||
* @param reader The reader to read from.
|
||||
* @return All byte characters.
|
||||
* @throws IOException If an I/O exception occurs.
|
||||
*/
|
||||
public static String readAll(BufferedReader reader) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int cp;
|
||||
while ((cp = reader.read()) != -1) {
|
||||
sb.append((char) cp);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an url and converts it into a JsonElement.
|
||||
* @param url The url to read from.
|
||||
* @return The JsonElement.
|
||||
* @throws IOException If an I/O exception occurs.
|
||||
*/
|
||||
public static JsonElement readJsonFromUrl(String url) throws IOException {
|
||||
try (InputStream is = stream(url)) {
|
||||
if (is == null) return null;
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
|
||||
String jsonText = readAll(reader);
|
||||
return new JsonParser().parse(jsonText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ListBuilder<T> {
|
||||
|
||||
private final List<T> list;
|
||||
private ListFormat<T> formatter;
|
||||
private String seperator;
|
||||
private String lastSeperator;
|
||||
|
||||
private ListBuilder(List<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public static <T> ListBuilder<T> create(List<T> list) {
|
||||
return new ListBuilder<>(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a pre-defined ListBuilder with type String.
|
||||
* @param list The collection to be used.
|
||||
* @return The ListBuilder.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static ListBuilder<String> createStrings(List<? extends String> list) {
|
||||
ListBuilder<String> builder = create((List<String>) list);
|
||||
builder.format(ListFormat.stringFormat);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public ListBuilder<T> format(ListFormat<T> formatter) {
|
||||
this.formatter = formatter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ListBuilder<T> seperator(String seperator) {
|
||||
this.seperator = seperator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ListBuilder<T> lastSeperator(String lastSeperator) {
|
||||
this.lastSeperator = lastSeperator;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (list.size() == 1) {
|
||||
return formatter.format(list.iterator().next());
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int i = 1;
|
||||
for (T t : list) {
|
||||
sb.append(formatter.format(t));
|
||||
if (i == list.size() - 1 && lastSeperator != null) {
|
||||
sb.append(lastSeperator);
|
||||
} else if (i != list.size() && seperator != null) {
|
||||
sb.append(seperator);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
public interface ListFormat<T> {
|
||||
|
||||
ListFormat<String> stringFormat = String::toString;
|
||||
|
||||
String format(T t);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class MapUtils {
|
||||
|
||||
/**
|
||||
* Removes keys from a map using a predicate.
|
||||
* @param map The map.
|
||||
* @param predicate The predicate used to test removal.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static void removeKeys(Map map, Predicate<Object> predicate) {
|
||||
Set<Object> keysToRemove = new HashSet<>();
|
||||
map.forEach((k, v) -> {
|
||||
if (predicate.test(k)) {
|
||||
keysToRemove.add(k);
|
||||
}
|
||||
});
|
||||
keysToRemove.forEach(map::remove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes values from a map using a predicate.
|
||||
* @param map The map.
|
||||
* @param predicate The predicate used to test removal.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static void removeValues(Map map, Predicate<Object> predicate) {
|
||||
Set<Object> keysToRemove = new HashSet<>();
|
||||
map.forEach((k, v) -> {
|
||||
if (predicate.test(v)) {
|
||||
keysToRemove.add(k);
|
||||
}
|
||||
});
|
||||
keysToRemove.forEach(map::remove);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class PredicateFilter implements Filter {
|
||||
|
||||
private Predicate<LogRecord> predicate;
|
||||
private Filter filter;
|
||||
|
||||
public void setPredicate(Predicate<LogRecord> predicate) {
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
public void start(Logger logger) {
|
||||
this.filter = logger.getFilter();
|
||||
logger.setFilter(this);
|
||||
}
|
||||
|
||||
public void stop(Logger logger) {
|
||||
logger.setFilter(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord record) {
|
||||
return predicate.test(record);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class VersionUtils {
|
||||
|
||||
private static final Pattern integerPattern = Pattern.compile("[^0-9]");
|
||||
|
||||
/**
|
||||
* Compares two versions in X.X.X format.
|
||||
* Returns true if version is newer than the old one.
|
||||
* @param oldVersion The old version.
|
||||
* @param newVersion The new version.
|
||||
* @return true iff new version is newer than old version.
|
||||
*/
|
||||
public static boolean isNewVersion(String oldVersion, String newVersion) {
|
||||
if (oldVersion == null || newVersion == null) return false;
|
||||
String[] oldVersionSplit = oldVersion.split("\\.");
|
||||
String[] newVersionSplit = newVersion.split("\\.");
|
||||
|
||||
int i = 0;
|
||||
while (i < oldVersionSplit.length && i < newVersionSplit.length) {
|
||||
int o = extractInteger(oldVersionSplit[i]);
|
||||
int n = extractInteger(newVersionSplit[i]);
|
||||
if (i != oldVersionSplit.length - 1 && i != newVersionSplit.length - 1) {
|
||||
if (n < o) return false;
|
||||
}
|
||||
if (n > o) return true;
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Integer extractInteger(String str) {
|
||||
return Integer.parseInt(integerPattern.matcher(str).replaceAll(""));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ListBuilderTest {
|
||||
|
||||
private final String seperator = ", ";
|
||||
private final String lastSeperator = " and ";
|
||||
|
||||
@Test
|
||||
void testToStringOneElement() {
|
||||
String list = ListBuilder.createStrings(singletonList("Nice"))
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString();
|
||||
assertEquals("Nice", list);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToStringTwoElements() {
|
||||
String list = ListBuilder.createStrings(asList("Nice", "List"))
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString();
|
||||
assertEquals("Nice and List", list);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToStringMultipleElements() {
|
||||
String list = ListBuilder.createStrings(asList("Nice", "List", "You", "Having", "There"))
|
||||
.seperator(seperator)
|
||||
.lastSeperator(lastSeperator)
|
||||
.toString();
|
||||
assertEquals("Nice, List, You, Having and There", list);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testToStringCustomFormat() {
|
||||
List<TestObject> objects = asList(
|
||||
new TestObject("pre1", 2),
|
||||
new TestObject("pre2", 3),
|
||||
new TestObject("pre3", 4)
|
||||
);
|
||||
|
||||
String list = ListBuilder.create(objects)
|
||||
.format(obj -> obj.prefix + "-" + obj.value)
|
||||
.seperator("; ")
|
||||
.lastSeperator(" and at last ")
|
||||
.toString();
|
||||
assertEquals("pre1-2; pre2-3 and at last pre3-4", list);
|
||||
}
|
||||
|
||||
private static class TestObject {
|
||||
private final String prefix;
|
||||
private final int value;
|
||||
|
||||
public TestObject(String prefix, int value) {
|
||||
this.prefix = prefix;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package net.frankheijden.serverutils.common.utils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.params.provider.Arguments.of;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
class VersionUtilsTest {
|
||||
|
||||
@ParameterizedTest(name = "old = {0}, new = {1}, expected = {2}")
|
||||
@MethodSource("versionGenerator")
|
||||
void isNewVersion(String oldVersion, String newVersion, boolean expected) {
|
||||
assertThat(VersionUtils.isNewVersion(oldVersion, newVersion)).isEqualTo(expected);
|
||||
}
|
||||
|
||||
private static Stream<Arguments> versionGenerator() {
|
||||
return Stream.of(
|
||||
of("0", "1", true),
|
||||
of("1", "0", false),
|
||||
of("9", "10", true),
|
||||
of("10", "9", false),
|
||||
of("-1", "5", true),
|
||||
of("5", "-1", false),
|
||||
of("10.1", "10.0", false),
|
||||
of("100.0", "120.0", true),
|
||||
of("1.0.0", "1.0.1", true),
|
||||
of("1.0.0", "1.1.0", true),
|
||||
of("1.0.0", "2.0.0", true),
|
||||
of("0.0.1", "0.0.1", false),
|
||||
of("0.0.1", "0.0.0", false),
|
||||
of("0.1.0", "0.0.1", false),
|
||||
of("1.0.0", "0.0.1", false),
|
||||
of("1.1.0", "0.1.1", false),
|
||||
of("1.0.0.0", "1.0.0.1", true),
|
||||
of("1.0.1-DEV", "1.0.2", true)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue