This commit is contained in:
Roman Zhuravlev 2023-07-16 20:06:05 +05:00
commit e443249166
29 changed files with 2887 additions and 0 deletions

11
common/pom.xml Normal file
View file

@ -0,0 +1,11 @@
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>org.zhdev.varioutil</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
</project>

View file

@ -0,0 +1,198 @@
package org.zhdev;
import org.jetbrains.annotations.NotNull;
public final class Version implements Comparable<Version> {
private final int major;
private final int minor;
private final int patch;
private final State state;
private final String string;
public Version(int major, int minor, int patch, @NotNull State state) {
this.major = major;
this.minor = minor;
this.patch = patch;
this.state = state;
this.string = major + "." + minor + (patch > 0 ? "." + patch : "") + (state != State.RELEASE ? '-' + state.name() : "");
}
public int getMajor() {
return major;
}
public int getMinor() {
return minor;
}
public int getPatch() {
return patch;
}
public State getState() {
return state;
}
public int compareTo(int major, int minor, int patch, State state) {
int result = this.major - major;
if (result == 0) {
result = this.minor - minor;
if (result == 0) {
result = this.patch - patch;
if (result == 0) {
result = this.state.compareTo(state);
}
}
}
return result;
}
@Override
public int compareTo(Version version) {
return compareTo(version.major, version.minor, version.patch, version.state);
}
public int compareTo(int major, int minor, int patch) {
int result = this.major - major;
if (result == 0) {
result = this.minor - minor;
if (result == 0) {
result = this.patch - patch;
}
}
return result;
}
public int compareTo(int major, int minor) {
int result = this.major - major;
if (result == 0) {
result = this.minor - minor;
}
return result;
}
public boolean equals(int major, int minor, int patch, State state) {
return major == this.major && minor == this.minor && patch == this.patch && this.state == state;
}
public boolean equals(int major, int minor, int patch) {
return major == this.major && minor == this.minor && patch == this.patch;
}
public boolean equals(int major, int minor) {
return major == this.major && minor == this.minor;
}
public boolean lessThan(Version version) {
return compareTo(version) < 0;
}
public boolean lessThan(int major, int minor, int patch, State state) {
return compareTo(major, minor, patch, state) < 0;
}
public boolean lessThan(int major, int minor, int patch) {
return compareTo(major, minor, patch) < 0;
}
public boolean lessThan(int major, int minor) {
return compareTo(major, minor) < 0;
}
public boolean moreThan(Version version) {
return compareTo(version) > 0;
}
public boolean moreThan(int major, int minor, int patch, State state) {
return compareTo(major, minor, patch, state) > 0;
}
public boolean moreThan(int major, int minor, int patch) {
return compareTo(major, minor, patch) > 0;
}
public boolean moreThan(int major, int minor) {
return compareTo(major, minor) > 0;
}
public boolean moreOrEqual(Version version) {
return compareTo(version) >= 0;
}
public boolean moreOrEqual(int major, int minor, int patch, State state) {
return compareTo(major, minor, patch, state) >= 0;
}
public boolean moreOrEqual(int major, int minor, int patch) {
return compareTo(major, minor, patch) >= 0;
}
public boolean moreOrEqual(int major, int minor) {
return compareTo(major, minor) >= 0;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Version version = (Version) o;
if (major != version.major) return false;
if (minor != version.minor) return false;
if (patch != version.patch) return false;
return state == version.state;
}
@Override
public int hashCode() {
int result = major;
result = 31 * result + minor;
result = 31 * result + patch;
result = 31 * result + (state != null ? state.hashCode() : 0);
return result;
}
@Override
public String toString() {
return string;
}
public static Version fromString(String string) {
String[] semver = string.split("\\.", 3);
if (semver.length < 2) {
throw new IllegalArgumentException("Incorrect semver (" + string + ")");
}
int major = Integer.parseInt(semver[0]);
int minor;
String[] split;
int patch;
if (semver.length < 3) {
split = semver[1].split("-|\\s", 2);
minor = Integer.parseInt(split[0]);
patch = 0;
} else {
split = semver[2].split("-|\\s", 2);
minor = Integer.parseInt(semver[1]);
patch = Integer.parseInt(split[0]);
}
State state;
if (split.length > 1) {
state = State.valueOf(split[1].toUpperCase());
} else {
state = State.RELEASE;
}
return new Version(major, minor, patch, state);
}
public enum State {
SNAPSHOT,
ALPHA,
BETA,
RELEASE
}
}

View file

@ -0,0 +1,83 @@
package org.zhdev.reflection;
import org.zhdev.util.ReflectionUtils;
import java.lang.reflect.Field;
public class FieldSearcher {
private Class<?> type;
private Object instance;
private Class<?> fieldType;
private String[] fieldNames;
public FieldSearcher typeOf(String typeName) {
this.type = ReflectionUtils.getType(typeName);
return this;
}
public FieldSearcher typeOf(String packageName, String typeName) {
this.type = ReflectionUtils.getType(packageName, typeName);
return this;
}
public FieldSearcher typeOf(String... typeNames) {
this.type = ReflectionUtils.searchType(typeNames);
return this;
}
public FieldSearcher typeOf(String packageName, String... typeNames) {
this.type = ReflectionUtils.searchType(new String[] { packageName }, typeNames);
return this;
}
public FieldSearcher type(Class<?> type) {
this.type = type;
return this;
}
public FieldSearcher instance(Object instance) {
this.instance = instance;
return this;
}
public FieldSearcher of(Object instance) {
this.type = instance.getClass();
this.instance = instance;
return this;
}
public FieldSearcher fieldType(Class<?> fieldType) {
this.fieldType = fieldType;
return this;
}
public FieldSearcher fieldTypeOf(String... fieldTypeNames) {
this.fieldType = ReflectionUtils.searchType(fieldTypeNames);
return this;
}
public FieldSearcher fieldOf(String... fieldNames) {
this.fieldNames = fieldNames;
return this;
}
public Field search() {
if (type == null) {
throw new IllegalStateException("Class not defined");
}
if (fieldNames == null || fieldNames.length == 0) {
throw new IllegalStateException("Field names not specified");
}
return ReflectionUtils.searchField(type, fieldType, fieldNames);
}
public Object get() {
return ReflectionUtils.getFieldValue(search(), instance);
}
public <T> T get(Class<T> type) {
return type.cast(get());
}
}

View file

@ -0,0 +1,103 @@
package org.zhdev.reflection;
import org.zhdev.util.ReflectionUtils;
import java.lang.reflect.Method;
public class MethodSearcher {
private Class<?> type;
private Object instance;
private Class<?> returnType;
private String[] methodNames;
private Class<?>[] parameterTypes;
private Object[] args;
public MethodSearcher typeOf(String typeName) {
this.type = ReflectionUtils.getType(typeName);
return this;
}
public MethodSearcher typeOf(String packageName, String typeName) {
this.type = ReflectionUtils.getType(packageName, typeName);
return this;
}
public MethodSearcher typeOf(String... typeNames) {
this.type = ReflectionUtils.searchType(typeNames);
return this;
}
public MethodSearcher typeOf(String packageName, String... typeNames) {
this.type = ReflectionUtils.searchType(new String[] { packageName }, typeNames);
return this;
}
public MethodSearcher type(Class<?> clazz) {
this.type = clazz;
return this;
}
public MethodSearcher instance(Object instance) {
this.instance = instance;
return this;
}
public MethodSearcher of(Object instance) {
this.type = instance.getClass();
this.instance = instance;
return this;
}
public MethodSearcher returns(Class<?> returnType) {
this.returnType = returnType;
return this;
}
public MethodSearcher returnsOf(String... returnTypeNames) {
this.returnType = ReflectionUtils.searchType(returnTypeNames);
return this;
}
public MethodSearcher methodOf(String... methodNames) {
this.methodNames = methodNames;
return this;
}
public MethodSearcher parameters(Class<?>... parameterTypes) {
this.parameterTypes = parameterTypes;
return this;
}
public MethodSearcher args(Object... args) {
this.args = args;
return this;
}
public Method search() {
if (type == null) {
throw new IllegalStateException("Class not defined");
}
if (methodNames == null) {
methodNames = new String[0];
}
if (parameterTypes == null) {
parameterTypes = new Class[0];
}
if (args == null) {
args = new Object[0];
}
return ReflectionUtils.searchMethod(type, returnType, methodNames, parameterTypes);
}
public Object invoke() {
return ReflectionUtils.invokeMethod(instance, search(), args);
}
public <T> T invoke(Class<T> returnType) {
return returnType.cast(invoke());
}
}

View file

@ -0,0 +1,66 @@
package org.zhdev.util;
import java.util.Collection;
import java.util.function.Function;
import java.util.function.IntFunction;
public class ArrayUtils {
public static <T> T get(T[] array, int index) {
return index < array.length ? array[index] : null;
}
public static <T> T get(T[] array, int index, T fallback) {
T t = get(array, index);
return t == null ? fallback : t;
}
public static <T> T get(T[] array, int index, Function<T[], T> fallbackFunction) {
T t = get(array, index);
return t == null ? fallbackFunction.apply(array) : t;
}
public static <T, R> R[] map(T[] array, IntFunction<R[]> arrayConstructor, Function<T, R> function) {
R[] mappedArray = arrayConstructor.apply(array.length);
for (int i = 0; i < array.length; i ++) {
mappedArray[i] = function.apply(array[i]);
}
return mappedArray;
}
public static <T> String[] mapToString(T[] array, IntFunction<String[]> arrayConstructor) {
return map(array, arrayConstructor, String::valueOf);
}
public static <T> Byte[] mapToByte(T[] array, IntFunction<Byte[]> arrayConstructor) {
return map(array, arrayConstructor, NumberUtils::parseByte);
}
public static <T> Short[] mapToShort(T[] array, IntFunction<Short[]> arrayConstructor) {
return map(array, arrayConstructor, NumberUtils::parseShort);
}
public static <T> Integer[] mapToInteger(T[] array, IntFunction<Integer[]> arrayConstructor) {
return map(array, arrayConstructor, NumberUtils::parseInt);
}
public static <T> Long[] mapToLong(T[] array, IntFunction<Long[]> arrayConstructor) {
return map(array, arrayConstructor, NumberUtils::parseLong);
}
public static <T> Float[] mapToFloat(T[] array, IntFunction<Float[]> arrayConstructor) {
return map(array, arrayConstructor, NumberUtils::parseFloat);
}
public static <T> Double[] mapToDouble(T[] array, IntFunction<Double[]> arrayConstructor) {
return map(array, arrayConstructor, NumberUtils::parseDouble);
}
public static <C extends Collection<R>, T, R> C mapAndToCollection(T[] array, IntFunction<C> collectionConstructor, Function<T, R> function) {
C collection = collectionConstructor.apply(array.length);
for (T t : array) {
R r = function.apply(t);
collection.add(r);
}
return collection;
}
}

View file

@ -0,0 +1,68 @@
package org.zhdev.util;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.function.IntFunction;
public class CollectionUtils {
public static <T> T get(List<T> list, int index) {
return index < list.size() ? list.get(index) : null;
}
public static <T> T get(List<T> list, int index, T fallback) {
T t = get(list, index);
return t == null ? fallback : t;
}
public static <T> T get(List<T> list, int index, Function<List<T>, T> fallbackFunction) {
T t = get(list, index);
return t == null ? fallbackFunction.apply(list) : t;
}
public static <C extends Collection<R>, T, R> C map(Collection<T> collection, IntFunction<C> collectionConstructor, Function<T, R> function) {
C mappedCollection = collectionConstructor.apply(collection.size());
for (T t : collection) {
mappedCollection.add(function.apply(t));
}
return mappedCollection;
}
public static <C extends Collection<String>, T> C mapToString(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, String::valueOf);
}
public static <C extends Collection<Byte>, T> C mapToByte(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, NumberUtils::parseByte);
}
public static <C extends Collection<Short>, T> C mapToShort(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, NumberUtils::parseShort);
}
public static <C extends Collection<Integer>, T> C mapToInteger(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, NumberUtils::parseInt);
}
public static <C extends Collection<Long>, T> C mapToLong(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, NumberUtils::parseLong);
}
public static <C extends Collection<Float>, T> C mapToFloat(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, NumberUtils::parseFloat);
}
public static <C extends Collection<Double>, T> C mapToDouble(Collection<T> collection, IntFunction<C> collectionConstructor) {
return map(collection, collectionConstructor, NumberUtils::parseDouble);
}
public static <T, R> R[] mapAndToArray(Collection<T> collection, IntFunction<R[]> arrayConstructor, Function<T, R> function) {
R[] array = arrayConstructor.apply(collection.size());
int i = 0;
for (T t : collection) {
array[i] = function.apply(t);
i++;
}
return array;
}
}

View file

@ -0,0 +1,143 @@
package org.zhdev.util;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DateTimeUtils {
public static final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
public static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1);
public static final long FOUR_HOURS = ONE_HOUR * 5;
public static final long ONE_DAY = TimeUnit.DAYS.toMillis(1);
public static final long TWO_DAYS = ONE_DAY * 2;
public static final long WEEK = ONE_DAY * 7;
public static final String[] DATE_PATTERNS = {"d/M/yyyy", "d MMMM yyyy", "d/M/yy", "d MMM yyyy", "yyyy MMM d", "yyyy MMMM d", "yyyy/M/d", "yyyy-M-d", "d M yyyy", "d.M.yyyy", "yyyy.m.d"};
public static final String[] DATETIME_PATTERNS = {"d/M/yyyy-H:mm", "d MMMM yyyy H:mm", "d/M/yy H:mm", "d MMM yyyy H:mm", "yyyy MMM d H:mm", "yyyy MMMM d H:mm", "yyyy/M/d-H:mm", "yyyy-M-d-H:mm", "d M yyyy H:mm", "d.M.yyyy H:mm", "yyyy.m.d H:mm"};
public static int getAge(LocalDate birthDate) {
return Period.between(birthDate, LocalDate.now()).getYears();
}
public static int getAge(long millis) {
return getAge(Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault()).toLocalDate());
}
public static LocalDate getLocalDate(String input, Locale locale, String... patterns) {
for (String pattern : patterns) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, locale);
return LocalDate.parse(input, formatter);
} catch (DateTimeParseException ignored) {}
}
throw new IllegalArgumentException("Invalid date input: " + input);
}
public static LocalDate getLocalDate(String input, String... patterns) {
return getLocalDate(input, Locale.getDefault(), patterns);
}
public static LocalDateTime getLocalDateTime(String input, Locale locale, String... patterns) {
for (String pattern : patterns) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern, locale);
return LocalDateTime.parse(input, formatter);
} catch (DateTimeParseException ignored) {}
}
throw new IllegalArgumentException("Invalid date input: " + input);
}
public static LocalDateTime getLocalDateTime(String input, String... patterns) {
return getLocalDateTime(input, Locale.getDefault(), patterns);
}
public static long toMillis(String str, TimeUnit unit) {
long total = 0;
Matcher m = Pattern.compile("([0-9]+)(?i)(ms|[a-z])?").matcher(str);
while (m.find()) {
int num = Integer.parseInt(m.group(1));
String type = String.valueOf(m.group(2));
if (type.equalsIgnoreCase("ms")) {
total += num;
} else {
switch (type.charAt(0)) {
case 't': case 'T': {
total += (num / 20.0) * 1000L;
break;
}
case 's': case 'S': {
total += TimeUnit.SECONDS.toMillis(num);
break;
}
case 'm': {
total += TimeUnit.MINUTES.toMillis(num);
break;
}
case 'h': case 'H': {
total += TimeUnit.HOURS.toMillis(num);
break;
}
case 'd': case 'D': {
total += TimeUnit.DAYS.toMillis(num);
break;
}
case 'w': case 'W': {
total += TimeUnit.DAYS.toMillis(num) * 7;
break;
}
case 'M': {
total += TimeUnit.DAYS.toMillis(num) * 31;
break;
}
case 'y': case 'Y': {
total += TimeUnit.DAYS.toMillis(num) * 365;
break;
}
default: {
if (unit == null) {
break;
}
switch (unit) {
case MILLISECONDS: total += num;
break;
case MINUTES: total += TimeUnit.MINUTES.toMillis(num);
break;
case HOURS: total += TimeUnit.HOURS.toMillis(num);
break;
case DAYS: total += TimeUnit.DAYS.toMillis(num);
break;
default: total += TimeUnit.SECONDS.toMillis(num);
break;
}
break;
}
}
}
}
return total;
}
public static long toMillis(String str) {
return toMillis(str, TimeUnit.SECONDS);
}
public static int toTicks(String str, TimeUnit unit) {
return (int) (toMillis(str, unit) / 1000.0 * 20);
}
public static int toTicks(String str) {
return toTicks(str, TimeUnit.SECONDS);
}
public static ZonedDateTime getZonedDateTime(ZoneId zoneId, long millis) {
if (ZoneId.systemDefault().equals(zoneId)) {
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId);
}
return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), zoneId).atZone(ZoneId.systemDefault());
}
}

View file

@ -0,0 +1,82 @@
package org.zhdev.util;
public class EnumUtils {
private static <T extends Enum<T>> T[] getValues(T eNum) {
return getValues(eNum.getDeclaringClass());
}
private static <T extends Enum<T>> T[] getValues(Class<T> clazz) {
return clazz.getEnumConstants();
}
private static <T extends Enum<T>> T indexOf(T[] values, int index, boolean orLast, boolean orFirst) {
if (index < 0) {
return orLast ? values[values.length - 1] : values[0];
}
int max = values.length - 1;
if (index > max) {
return orFirst ? values[0] : values[max];
}
return values[index];
}
private static <T extends Enum<T>> T indexOf(T[] values, int index) {
return indexOf(values, index, false, false);
}
public static <T extends Enum<T>> T indexOf(Class<T> clazz, int index, boolean orLast, boolean orFirst) {
return indexOf(getValues(clazz), index, orLast, orFirst);
}
public static <T extends Enum<T>> T indexOf(Class<T> clazz, int index) {
return indexOf(getValues(clazz), index);
}
public static <T extends Enum<T>> T indexOf(T eNum, int index, boolean orLast, boolean orFirst) {
return indexOf(getValues(eNum), index, orLast, orFirst);
}
public static <T extends Enum<T>> T indexOf(T eNum, int index) {
return indexOf(getValues(eNum), index);
}
public static <T extends Enum<T>> T first(Class<T> clazz) {
return getValues(clazz)[0];
}
public static <T extends Enum<T>> T last(Class<T> clazz) {
T[] values = getValues(clazz);
return values[values.length - 1];
}
public static <T extends Enum<T>> T first(T eNum) {
return getValues(eNum)[0];
}
public static <T extends Enum<T>> T last(T eNum) {
T[] values = getValues(eNum);
return values[values.length - 1];
}
public static <T extends Enum<T>> T previous(T eNum, boolean orLast) {
int previous = eNum.ordinal() - 1;
return previous < 0 ? orLast ? last(eNum) : getValues(eNum)[0] : getValues(eNum)[previous];
}
public static <T extends Enum<T>> T next(T eNum, boolean orFirst) {
T[] values = getValues(eNum);
int max = values.length - 1;
int next = eNum.ordinal() + 1;
return next > max ? (orFirst ? values[0] : values[max]) : values[next];
}
public static <T extends Enum<T>> T previous(T eNum) {
return previous(eNum, false);
}
public static <T extends Enum<T>> T next(T eNum) {
return next(eNum, false);
}
}

View file

@ -0,0 +1,132 @@
package org.zhdev.util;
public class NumberUtils {
public static boolean isDigit(String input) {
for (int i = 0; i < input.length(); i++){
if (!Character.isDigit(input.charAt(i))) {
return false;
}
}
return true;
}
public static byte parseByte(String str, byte def) {
try {
return Byte.parseByte(str);
} catch (NumberFormatException e) {
return def;
}
}
public static short parseShort(String str, short def) {
try {
return Short.parseShort(str);
} catch (NumberFormatException e) {
return def;
}
}
public static int parseInt(String str, int def) {
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
return def;
}
}
public static long parseLong(String str, long def) {
try {
return Long.parseLong(str);
} catch (NumberFormatException e) {
return def;
}
}
public static double parseFloat(String str, float def) {
try {
return Float.parseFloat(str);
} catch (NumberFormatException e) {
return def;
}
}
public static double parseDouble(String str, double def) {
try {
return Double.parseDouble(str);
} catch (NumberFormatException e) {
return def;
}
}
public static Byte parseByte(Object obj, Byte def) {
try {
return Byte.parseByte(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static Byte parseByte(Object obj) {
return parseByte(obj, null);
}
public static Short parseShort(Object obj, Short def) {
try {
return Short.parseShort(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static Short parseShort(Object obj) {
return parseShort(obj, null);
}
public static Integer parseInt(Object obj, Integer def) {
try {
return Integer.parseInt(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static Integer parseInt(Object obj) {
return parseInt(obj, null);
}
public static Long parseLong(Object obj, Long def) {
try {
return Long.parseLong(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static Long parseLong(Object obj) {
return parseLong(obj, null);
}
public static Float parseFloat(Object obj, Float def) {
try {
return Float.parseFloat(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static Float parseFloat(Object obj) {
return parseFloat(obj, null);
}
public static Double parseDouble(Object obj, Double def) {
try {
return Double.parseDouble(String.valueOf(obj));
} catch (NumberFormatException e) {
return def;
}
}
public static Double parseDouble(Object obj) {
return parseDouble(obj, null);
}
}

View file

@ -0,0 +1,231 @@
package org.zhdev.util;
import org.zhdev.reflection.FieldSearcher;
import org.zhdev.reflection.MethodSearcher;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.function.Consumer;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class ReflectionUtils {
private static Method getMethod0(Class<?> type, String methodName, Class<?>... args) throws NoSuchMethodException {
Method method = type.getDeclaredMethod(methodName, args);
method.setAccessible(true);
return method;
}
private static Field getField0(Class<?> type, String fieldName) throws NoSuchFieldException {
Field field = type.getDeclaredField(fieldName);
field.setAccessible(true);
return field;
}
private static boolean compareParameters(Class<?>[] required, Class<?>... parameters) {
if (required.length != parameters.length) {
return false;
}
for (int i = 0; i < required.length; i++) {
if (!parameters[i].isAssignableFrom(required[i])) {
return false;
}
}
return true;
}
private static Method checkMethodType(Method method, Class<?> requiredType) throws IllegalStateException {
if (requiredType == null || requiredType.isAssignableFrom(method.getReturnType())) return method;
throw new IllegalStateException(requiredType + " is not assignable from type of " + method);
}
private static Field checkFieldType(Field field, Class<?> requiredType) throws IllegalStateException {
if (requiredType == null || requiredType.isAssignableFrom(field.getType())) return field;
throw new IllegalStateException(requiredType + " is not assignable from type of " + field);
}
public static Class<?> getType(String typeName) throws NoClassDefFoundError {
try {
return Class.forName(typeName);
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(typeName);
}
}
public static Class<?> searchType(String... typeNames) throws NoClassDefFoundError {
for (String typeName : typeNames) {
try {
return Class.forName(typeName);
} catch (ClassNotFoundException ignored) {}
}
throw new NoClassDefFoundError(String.join(", ", typeNames));
}
public static Class<?> getType(String packageName, String typeSimpleName) throws NoClassDefFoundError {
String typeName = packageName + '.' + typeSimpleName;
try {
return Class.forName(typeName);
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(typeName);
}
}
public static Class<?> searchType(String[] packageNames, String... typeNames) throws NoClassDefFoundError {
for (String packageName : packageNames) {
for (String typeName : typeNames) {
try {
return Class.forName(packageName + '.' + typeName);
} catch (ClassNotFoundException ignored) {}
}
}
throw new NoClassDefFoundError(String.join(", ", typeNames) + " in " + String.join(", ", packageNames));
}
public static Method getMethod(Class<?> type, String methodName, Class<?>... parameterTypes) throws NoSuchMethodError {
try {
return getMethod0(type, methodName, parameterTypes);
} catch (NoSuchMethodException e) {
throw new NoSuchMethodError(e.getMessage());
}
}
public static Method searchMethod(Class<?> type, Class<?> returnType, String[] methodNames, Class<?>... parameterTypes) throws NoSuchMethodError {
IllegalStateException exception = null;
for (String methodName : methodNames) {
try {
return checkMethodType(getMethod0(type, methodName, parameterTypes), returnType);
} catch (IllegalStateException e) {
exception = e;
} catch (NoSuchMethodException ignored) { }
}
if (parameterTypes.length > 0) {
for (Method m : type.getDeclaredMethods()) {
if (compareParameters(parameterTypes, m.getParameterTypes())) {
return checkMethodType(m, returnType);
}
}
}
if (exception != null) {
throw exception;
}
throw new NoSuchMethodError(String.join(", ", methodNames) + " in " + type);
}
public static Object invokeMethod(Object instance, Method method, Object... args) throws IllegalStateException {
try {
return method.invoke(instance, args);
} catch (ReflectiveOperationException e) {
throw new IllegalStateException(e.getMessage());
}
}
public static Field getField(Class<?> type, String fieldName) throws NoSuchFieldError {
try {
return getField0(type, fieldName);
} catch (NoSuchFieldException e) {
throw new NoSuchFieldError(fieldName);
}
}
public static Field searchField(Class<?> type, Class<?> fieldType, String... fieldNames) throws NoSuchFieldError {
IllegalStateException exception = null;
for (String fieldName : fieldNames) {
try {
return checkFieldType(getField0(type, fieldName), fieldType);
} catch (IllegalStateException e) {
exception = e;
} catch (NoSuchFieldException ignored) {}
}
if (exception != null) {
throw exception;
}
throw new NoSuchFieldError(String.join(", ", fieldNames) + " in " + type);
}
public static Object getFieldValue(Field field, Object instance) throws IllegalStateException {
try {
return field.get(instance);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e.getMessage());
}
}
public static void setFieldValue(Field field, Object instance, Object value) throws IllegalStateException {
try {
field.set(instance, value);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e.getMessage());
}
}
public static void forEachClass(ClassLoader loader, JarFile jarFile, String packageName, Consumer<Class<?>> consumer) {
for (Enumeration<JarEntry> entry = jarFile.entries(); entry.hasMoreElements(); ) {
JarEntry jarEntry = entry.nextElement();
String name = jarEntry.getName();
if (!name.endsWith(".class")) {
continue;
}
String link = name.substring(0, name.length() - 6).replace("/", ".");
int index = link.lastIndexOf('.');
String packagePath = index == -1 ? "" : link.substring(0, index);
if (packagePath.equals(packageName)) {
try {
consumer.accept(loader.loadClass(link));
} catch (ClassNotFoundException ignored) {}
}
}
}
public static void forEachClass(ClassLoader loader, File file, String packageName, Consumer<Class<?>> consumer) {
try (JarFile jarFile = new JarFile(file)) {
forEachClass(loader, jarFile, packageName, consumer);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public static void forEachJarEntry(JarFile jarFile, String packageName, Consumer<JarEntry> consumer) {
for (Enumeration<JarEntry> entry = jarFile.entries(); entry.hasMoreElements(); ) {
JarEntry jarEntry = entry.nextElement();
String name = jarEntry.getName();
int index = name.lastIndexOf('/');
String packagePath = index == -1 ? name : name.substring(0, index);
if (packagePath.equals(packageName)) {
consumer.accept(jarEntry);
}
}
}
public static void forEachJarEntry(File file, String packageName, Consumer<JarEntry> consumer) {
try (JarFile jarFile = new JarFile(file)) {
forEachJarEntry(jarFile, packageName, consumer);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public static MethodSearcher methodSearcher() {
return new MethodSearcher();
}
public static FieldSearcher fieldSearcher() {
return new FieldSearcher();
}
}

View file

@ -0,0 +1,67 @@
package org.zhdev.util;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
public class ResourceUtils {
public static InputStream getResource(String path, ClassLoader loader) {
try {
URL url = loader.getResource(path);
if (url == null) {
return null;
}
URLConnection connection = url.openConnection();
connection.setUseCaches(false);
return connection.getInputStream();
} catch (IOException e) {
return null;
}
}
public static InputStream getResource(String path) {
return getResource(path, ResourceUtils.class.getClassLoader());
}
public static boolean saveResource(String resourcePath, File outFile, ClassLoader loader) throws IllegalStateException {
if (resourcePath == null || resourcePath.equals("")) {
return false;
}
resourcePath = resourcePath.replace('\\', '/');
InputStream in = getResource(resourcePath, loader);
if (in == null) {
return false;
}
File parent = outFile.getParentFile();
if (parent != null && !parent.exists()) {
parent.mkdirs();
}
try {
if (!outFile.exists() || outFile.length() == 0) {
OutputStream stream = Files.newOutputStream(outFile.toPath());
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
stream.write(buf, 0, len);
}
stream.close();
in.close();
return true;
}
} catch (IOException e) {
throw new IllegalStateException("Could not save resource " + resourcePath + " to " + outFile, e);
}
return false;
}
public static boolean saveResource(String resourcePath, File outFile) throws IllegalStateException {
return saveResource(resourcePath, outFile);
}
}

View file

@ -0,0 +1,269 @@
package org.zhdev.util;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class StringUtils {
public static String join(int beginIndex, int lastIndex, String delimiter, String lastDelimiter, String... elements) {
StringBuilder builder = new StringBuilder();
for (; beginIndex < elements.length; beginIndex++) {
if (beginIndex == lastIndex) {
builder.append(lastDelimiter);
} else {
builder.append(delimiter);
}
builder.append(elements[beginIndex]);
}
return builder.toString();
}
public static String join(int beginIndex, String delimiter, String lastDelimiter, String... elements) {
return join(beginIndex, elements.length - 1, delimiter, lastDelimiter, elements);
}
public static String join(String delimiter, String lastDelimiter, String... elements) {
return join(0, delimiter, lastDelimiter, elements);
}
public static String join(int beginIndex, int lastIndex, String delimiter, String... elements) {
return join(beginIndex, lastIndex, delimiter, delimiter, elements);
}
public static String join(int beginIndex, String delimiter, String... elements) {
return join(beginIndex, delimiter, delimiter, elements);
}
public static String join(String delimiter, String... elements) {
return join(delimiter, delimiter, elements);
}
public static String join(int beginIndex, int lastIndex, String delimiter, String lastDelimiter, Iterable<String> elements) {
StringBuilder builder = new StringBuilder();
Iterator<String> iterator = elements.iterator();
int i = 0;
while (iterator.hasNext()) {
if (i < beginIndex) {
continue;
}
String element = iterator.next();
if (builder.length() > 0) {
if (iterator.hasNext()) {
builder.append(delimiter);
} else {
builder.append(lastDelimiter);
}
}
builder.append(element);
i++;
if (i == lastIndex) {
break;
}
}
return builder.toString();
}
public static String join(int beginIndex, String delimiter, String lastDelimiter, Iterable<String> elements) {
return join(beginIndex, -1, delimiter, lastDelimiter, elements);
}
public static String join(String delimiter, String lastDelimiter, Iterable<String> elements) {
return join(0, delimiter, lastDelimiter, elements);
}
public static String join(int beginIndex, int lastIndex, String delimiter, Iterable<String> elements) {
return join(beginIndex, lastIndex, delimiter, delimiter, elements);
}
public static String join(int beginIndex, String delimiter, Iterable<String> elements) {
return join(beginIndex, delimiter, delimiter, elements);
}
public static String join(String delimiter, Iterable<String> elements) {
return join(delimiter, delimiter, elements);
}
public static void replaceKeyValue(StringBuilder builder, Object... args) {
Object replacement = null;
for (int i = 0; i < args.length; i++) {
if (i % 2 == 0) {
replacement = args[i];
} else {
replace(builder, String.valueOf(replacement), args[i]);
}
}
}
/**
* <blockquote>For example,
* <pre>{@code
* StringUtils.replaceKeyValue("Hi, %username%! This is %what%",
* "%username%", "human",
* "%what%", "Java program")
* }</pre></blockquote>
*/
public static String replaceKeyValue(String str, Object... args) {
if (args.length == 0) {
return str;
}
StringBuilder builder = new StringBuilder(str);
replaceKeyValue(builder, args);
return builder.toString();
}
public static void replace(StringBuilder builder, String replacement, Object value) {
int index = builder.indexOf(replacement);
if (index == -1) {
return;
}
String result = String.valueOf(value);
do {
builder.replace(index, index + replacement.length(), result);
index = builder.indexOf(replacement, index + result.length());
} while (index != -1);
}
public static String escape(String str, String escape, char... chars) {
StringBuilder builder = new StringBuilder(str);
for (char c : chars) {
replace(builder, String.valueOf(c), escape + c);
}
return builder.toString();
}
public static String escape(String str, char... chars) {
return escape(str, "\\", chars);
}
public static String unescape(String str, String escape, char... chars) {
StringBuilder builder = new StringBuilder(str);
for (char c : chars) {
replace(builder, escape + c, c);
}
return builder.toString();
}
public static String unescape(String str, char... chars) {
return unescape(str, "\\", chars);
}
public static void format(StringBuilder builder, Object... args) {
for (int i = 0; i < args.length; i++) {
String replacement = "{" + i + "}";
Object arg = args[i];
replace(builder, replacement, String.valueOf(arg));
}
}
public static String format(String str, Object... args) {
if (args.length == 0) {
return str;
}
StringBuilder builder = new StringBuilder(str);
format(builder, args);
return builder.toString();
}
public static String[] splitByDelimiter(String line, char delimiter, int limit, char escape, char open, char close) {
StringBuilder builder = new StringBuilder();
List<String> list = new ArrayList<>();
boolean quote = false;
Character previous = null;
for (int i = 0; i < line.length(); i++) {
if (list.size() == limit) {
break;
}
char c = line.charAt(i);
builder.append(c);
if (!quote && c == open || c == close) {
if (previous == null || previous != escape) {
builder.setLength(builder.length() - 1);
quote = !quote;
} else {
builder.setLength(builder.length() - 2);
builder.append(c);
}
} else if (!quote && c == delimiter) {
builder.setLength(builder.length() - 1);
list.add(builder.toString());
builder.setLength(0);
}
previous = c;
}
list.add(builder.toString());
return list.toArray(new String[0]);
}
public static String[] splitByDelimiter(String line, char delimiter, int limit, char escape, char quotation) {
return splitByDelimiter(line, delimiter, limit, escape, quotation, quotation);
}
public static String[] splitByDelimiter(String line, char delimiter, int limit, char escape) {
return splitByDelimiter(line, delimiter, limit, escape, '"');
}
public static String[] splitByDelimiter(String line, char delimiter, int limit) {
return splitByDelimiter(line, delimiter, limit, '\\');
}
public static String[] splitByDelimiter(String line, char delimiter) {
return splitByDelimiter(line, delimiter, -2);
}
public static String[] splitByLength(String str, Character ignore, int length, int limit) {
StringBuilder builder = new StringBuilder();
List<String> list = new ArrayList<>();
int lastStrIndex = str.length() - 1;
boolean flag = false;
for (int i = 0; i < str.length(); i++) {
if (limit > 0 && list.size() == limit) {
break;
}
if (flag) {
builder.append(ignore);
flag = false;
}
char c = str.charAt(i);
if (ignore == null || c != ignore) {
builder.append(c);
} else {
flag = true;
}
if (i == lastStrIndex || (i + 1) % length == 0) {
list.add(builder.toString());
builder.setLength(0);
}
}
return list.toArray(new String[0]);
}
public static String[] splitByLength(String str, char ignore, int length) {
return splitByLength(str, ignore, length, -1);
}
public static String[] splitByLength(String str, int length) {
return splitByLength(str, null, length, -1);
}
public static String upperFirstCase(String str) {
char[] chars = str.toCharArray();
chars[0] = Character.toUpperCase(chars[0]);
return new String(chars);
}
}