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

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
.idea
target
*/target

21
LICENSE.md Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 rozhur
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

92
README.md Normal file
View file

@ -0,0 +1,92 @@
### Add as maven dependency
```xml
<repositories>
<repository>
<id>zhdev-repo</id>
<url>https://repo.zhdev.org/maven</url>
</repository>
</repositories>
```
```xml
<dependencies>
<dependency>
<groupId>org.zhdev</groupId>
<artifactId>all</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
```
### Example for reflection
#### Maven dependency
```xml
<dependencies>
<dependency>
<groupId>org.zhdev</groupId>
<artifactId>common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
```
#### Code
```java
import java.lang.reflect.Field;
import org.bukkit.Bukkit;
public class BukkitFields {
public static final Field METHOD__CraftServer__getServer;
static {
METHOD__CraftServer__getServer = ReflectionUtils.methodSearcher()
.of(Bukkit.getServer())
.methodOf("getServer")
.returns(CLASS__DedicatedServer)
.search();
}
}
```
### Example for yaml
#### Maven dependency
```xml
<dependencies>
<dependency>
<groupId>org.zhdev</groupId>
<artifactId>io</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
```
#### Code
```java
import org.zhdev.config.Config;
import org.zhdev.config.YamlConfig;
import java.util.List;
public class Main {
public static void main(String[] args) {
Config config = new YamlConfig();
config.load(); // load from ./config.yml file by default
config.load("test.yml"); // load from ./test.yml by 1st argument
// set value to "Hello world!" of 'test' key and set block comment from 3rd argument
config.set("test", "Hello world!", "It's hello world comment!");
config.save(); // save as ./config.yml by default
config.save("test.yml"); // save as ./test.yml by 1st argument
Config anotherConfig = new YamlConfig("another.yml"); // create with default name "another.yml"
config.load(); // load from ./another.yml by default
// get value "test" as integer or "5" if it is null
Integer value = config.getInteger("test", 5);
// get value "foo->bar->testlist" as list
List<?> list = config.getSection("foo", "bar").getList("testlist");
}
}
```

32
all/pom.xml Normal file
View file

@ -0,0 +1,32 @@
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>org.zhdev.varioutil</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>all</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>io</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bukkit</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

51
bukkit/pom.xml Normal file
View file

@ -0,0 +1,51 @@
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>org.zhdev.varioutil</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>bukkit</artifactId>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>io</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>minecraft-server</artifactId>
<version>1.20-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,15 @@
package org.zhdev.config;
import org.bukkit.plugin.Plugin;
import java.io.File;
public interface BukkitConfig extends Config {
File load(Plugin plugin, String path) throws ConfigException;
File load(Plugin plugin) throws ConfigException;
File saveIfEmpty(Plugin plugin, String path) throws ConfigException;
File saveIfEmpty(Plugin plugin) throws ConfigException;
}

View file

@ -0,0 +1,77 @@
package org.zhdev.config;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.plugin.Plugin;
import org.yaml.snakeyaml.nodes.Node;
import org.zhdev.util.ResourceUtils;
import java.io.File;
import java.io.InputStream;
import java.util.LinkedHashMap;
import java.util.Map;
public class BukkitYamlConfig extends YamlConfig implements BukkitConfig {
public BukkitYamlConfig(String key) {
super(key);
}
public BukkitYamlConfig() {}
@Override
protected Object constructHandle(Node keyNode, Node valueNode, String key, Object value) {
if (value instanceof Map) {
Map<?, ?> raw = (Map<?, ?>) valueNode;
if (raw.containsKey(ConfigurationSerialization.SERIALIZED_TYPE_KEY)) {
Map<String, Object> map = new LinkedHashMap<>(raw.size());
for (Map.Entry<?, ?> entry : raw.entrySet()) {
map.put(String.valueOf(entry.getKey()), entry.getValue());
}
return ConfigurationSerialization.deserializeObject(map);
}
}
return super.constructHandle(keyNode, valueNode, key, value);
}
@Override
protected Node representHandle(String key, Object value) {
if (value instanceof ConfigurationSerializable) {
ConfigurationSerializable serializable = (ConfigurationSerializable) value;
Map<String, Object> values = new LinkedHashMap<>();
values.put(ConfigurationSerialization.SERIALIZED_TYPE_KEY, ConfigurationSerialization.getAlias(serializable.getClass()));
values.putAll(serializable.serialize());
return REPRESENTER.represent(values);
}
return super.representHandle(key, value);
}
@Override
public File load(Plugin plugin, String path) throws ConfigException {
ClassLoader classLoader = plugin.getClass().getClassLoader();
InputStream stream = ResourceUtils.getResource(path, classLoader);
if (stream != null) {
load(stream);
}
File file = load(plugin.getDataFolder().getPath() + File.separatorChar + path);
if (file.length() == 0) {
ResourceUtils.saveResource(path, file, classLoader);
}
return load(plugin.getDataFolder().getPath() + File.separatorChar + path);
}
@Override
public File load(Plugin plugin) throws ConfigException {
return load(plugin, key);
}
@Override
public File saveIfEmpty(Plugin plugin, String path) throws ConfigException {
return saveIfEmpty(plugin.getDataFolder().getPath() + File.separatorChar + path);
}
@Override
public File saveIfEmpty(Plugin plugin) throws ConfigException {
return saveIfEmpty(plugin, key);
}
}

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);
}
}

20
io/pom.xml Normal file
View file

@ -0,0 +1,20 @@
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>org.zhdev.varioutil</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>io</artifactId>
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>2.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,41 @@
package org.zhdev.config;
import java.io.*;
public interface Config extends ConfigSection {
String DEFAULT_KEY = "config.yml";
String getKey();
String[] getHeaderComments();
String[] getEndComments();
void setHeaderComments(String... headerComments);
void setEndComments(String... endComments);
void load(Reader reader);
void load(InputStream stream) throws IOException, ConfigException;
void load(File file) throws IOException, ConfigException;
File load(String path) throws ConfigException;
File load() throws ConfigException;
void save(Writer writer);
void save(OutputStream stream) throws IOException, ConfigException;
void save(File file) throws IOException, ConfigException;
File save(String path) throws ConfigException;
File save() throws ConfigException;
File saveIfEmpty(String path) throws ConfigException;
File saveIfEmpty() throws ConfigException;
}

View file

@ -0,0 +1,18 @@
package org.zhdev.config;
public class ConfigException extends RuntimeException {
public ConfigException() {
}
public ConfigException(Throwable cause) {
super(cause);
}
public ConfigException(String s) {
super(s);
}
public ConfigException(String message, Throwable cause) {
super(message, cause);
}
}

View file

@ -0,0 +1,123 @@
package org.zhdev.config;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public interface ConfigSection extends Iterable<String> {
String[] getBlockComments(String key);
String[] getInlineComments(String key);
void setBlockComments(String key, String... blockComments);
void setInlineComments(String key, String... inlineComments);
void removeBlockComments(String key);
void removeInlineComments(String key);
Map<String, Object> toMap();
<T> T get(String key);
<T> T get(String key, T fallback);
<T> T get(String key, Function<String, T> fallback);
<T> T getOrSet(String key, T fallback, String... blockComments);
<T> T getOrSet(String key, Function<String, T> fallback, String... blockComments);
ConfigSection getSection(String key, String... names);
ConfigSection getOrCreateSection(String key, String... names);
Byte getByte(String key);
Byte getByte(String key, Byte fallback);
Byte getByte(String key, Function<String, Byte> fallback);
Byte getOrSetByte(String key, Byte fallback, String... blockComments);
Byte getOrSetByte(String key, Function<String, Byte> fallback, String... blockComments);
Short getShort(String key);
Short getShort(String key, Short fallback);
Short getShort(String key, Function<String, Short> fallback);
Short getOrSetShort(String key, Short fallback, String... blockComments);
Short getOrSetShort(String key, Function<String, Short> fallback, String... blockComments);
Integer getInteger(String key);
Integer getInteger(String key, Integer fallback);
Integer getInteger(String key, Function<String, Integer> fallback);
Integer getOrSetInteger(String key, Integer fallback, String... blockComments);
Integer getOrSetInteger(String key, Function<String, Integer> fallback, String... blockComments);
Long getLong(String key);
Long getLong(String key, Long fallback);
Long getLong(String key, Function<String, Long> fallback);
Long getOrSetLong(String key, Long fallback, String... blockComments);
Long getOrSetLong(String key, Function<String, Long> fallback, String... blockComments);
Float getFloat(String key);
Float getFloat(String key, Float fallback);
Float getFloat(String key, Function<String, Float> fallback);
Float getOrSetFloat(String key, Float fallback, String... blockComments);
Float getOrSetFloat(String key, Function<String, Float> fallback, String... blockComments);
Double getDouble(String key);
Double getDouble(String key, Double fallback);
Double getDouble(String key, Function<String, Double> fallback);
Double getOrSetDouble(String key, Double fallback, String... blockComments);
Double getOrSetDouble(String key, Function<String, Double> fallback, String... blockComments);
String getString(String key);
String getString(String key, String fallback);
String getString(String key, Function<String, String> fallback);
String getOrSetString(String key, String fallback, String... blockComments);
String getOrSetString(String key, Function<String, String> fallback, String... blockComments);
List<?> getList(String key);
List<?> getList(String key, List<?> fallback);
List<?> getList(String key, Function<String, List<?>> fallback);
List<?> getOrSetList(String key, List<?> fallback, String... blockComments);
List<?> getOrSetList(String key, Function<String, List<?>> fallback, String... blockComments);
<T> T set(String key, T object, String... blockComments);
<T> T set(String key, T object);
<T> T remove(String key);
void clear();
}

View file

@ -0,0 +1,19 @@
package org.zhdev.config;
class ConfigSectionNode {
Object value;
String[] blockComments;
String[] inlineComments;
ConfigSectionNode(Object value, String[] blockComments) {
this.value = value;
this.blockComments = blockComments;
}
ConfigSectionNode(Object value) {
this.value = value;
}
ConfigSectionNode() {
}
}

View file

@ -0,0 +1,469 @@
package org.zhdev.config;
import java.util.*;
import java.util.function.Function;
public class MapConfigSection implements ConfigSection {
protected final LinkedHashMap<String, ConfigSectionNode> map;
protected MapConfigSection(LinkedHashMap<String, ConfigSectionNode> map) {;
this.map = map;
}
protected MapConfigSection() {
this(new LinkedHashMap<>());
}
public String[] getBlockComments(String key) {
ConfigSectionNode node = map.get(key);
return node == null ? null : node.blockComments;
}
public String[] getInlineComments(String key) {
ConfigSectionNode node = map.get(key);
return node == null ? null : node.inlineComments;
}
public void setBlockComments(String key, String... blockComments) {
ConfigSectionNode node = map.get(key);
if (node == null) {
node = new ConfigSectionNode();
map.put(key, node);
}
node.blockComments = blockComments;
}
public void setInlineComments(String key, String... inlineComments) {
ConfigSectionNode node = map.get(key);
if (node == null) {
node = new ConfigSectionNode();
map.put(key, node);
}
node.inlineComments = inlineComments;
}
public void removeBlockComments(String key) {
ConfigSectionNode node = map.get(key);
if (node != null) {
node.blockComments = null;
}
}
public void removeInlineComments(String key) {
ConfigSectionNode node = map.get(key);
if (node != null) {
node.inlineComments = null;
}
}
@Override
public Map<String, Object> toMap() {
Map<String, Object> map = new LinkedHashMap<>(this.map.size());
for (Map.Entry<String, ConfigSectionNode> entry : this.map.entrySet()) {
Object obj = entry.getValue().value;
if (obj instanceof MapConfigSection) {
obj = ((MapConfigSection) obj).toMap();
}
map.put(entry.getKey(), obj);
}
return map;
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
ConfigSectionNode node = map.get(key);
return node == null ? null : (T) node.value;
}
@SuppressWarnings("unchecked")
public <T> T get(String key, T fallback) {
ConfigSectionNode node = map.get(key);
return node == null ? fallback : (T) node.value;
}
public <T> T get(String key, Function<String, T> fallback) {
T object = get(key);
return object == null ? fallback.apply(key) : object;
}
public <T> T getOrSet(String key, T fallback, String... blockComments) {
T object = get(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public <T> T getOrSet(String key, Function<String, T> fallback, String... blockComments) {
T object = get(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public MapConfigSection getSection(String key, String... names) {
Object object = get(key);
if (object instanceof MapConfigSection) {
MapConfigSection section = (MapConfigSection) object;
for (String n : names) {
section = section.getSection(n);
if (section == null) return null;
}
return section;
}
return null;
}
public MapConfigSection getOrCreateSection(String key, String... names) {
MapConfigSection section;
Object object = get(key);
if (object instanceof MapConfigSection) {
section = (MapConfigSection) object;
} else {
section = new MapConfigSection();
map.put(key, new ConfigSectionNode(section));
}
for (String n : names) section = section.getOrCreateSection(n);
return section;
}
public Byte getByte(String key) {
Object object = get(key);
if (object instanceof Byte) {
return (Byte) object;
} else if (object instanceof Number) {
Number number = (Number) object;
return number.byteValue();
}
return null;
}
public Byte getByte(String key, Byte fallback) {
Byte object = getByte(key);
return object == null ? fallback : object;
}
public Byte getByte(String key, Function<String, Byte> fallback) {
Byte object = getByte(key);
return object == null ? fallback.apply(key) : object;
}
public Byte getOrSetByte(String key, Byte fallback, String... blockComments) {
Byte object = getByte(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public Byte getOrSetByte(String key, Function<String, Byte> fallback, String... blockComments) {
Byte object = getByte(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public Short getShort(String key) {
Object object = get(key);
if (object instanceof Short) {
return (Short) object;
} else if (object instanceof Number) {
Number number = (Number) object;
return number.shortValue();
}
return null;
}
public Short getShort(String key, Short fallback) {
Short object = getShort(key);
return object == null ? fallback : object;
}
public Short getShort(String key, Function<String, Short> fallback) {
Short object = getShort(key);
return object == null ? fallback.apply(key) : object;
}
public Short getOrSetShort(String key, Short fallback, String... blockComments) {
Short object = getShort(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public Short getOrSetShort(String key, Function<String, Short> fallback, String... blockComments) {
Short object = getShort(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public Integer getInteger(String key) {
Object object = get(key);
if (object instanceof Integer) {
return (Integer) object;
} else if (object instanceof Number) {
Number number = (Number) object;
return number.intValue();
}
return null;
}
public Integer getInteger(String key, Integer fallback) {
Integer object = getInteger(key);
return object == null ? fallback : object;
}
public Integer getInteger(String key, Function<String, Integer> fallback) {
Integer object = getInteger(key);
return object == null ? fallback.apply(key) : object;
}
public Integer getOrSetInteger(String key, Integer fallback, String... blockComments) {
Integer object = getInteger(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public Integer getOrSetInteger(String key, Function<String, Integer> fallback, String... blockComments) {
Integer object = getInteger(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public Long getLong(String key) {
Object object = get(key);
if (object instanceof Long) {
return (Long) object;
} else if (object instanceof Number) {
Number number = (Number) object;
return number.longValue();
}
return null;
}
public Long getLong(String key, Long fallback) {
Long object = getLong(key);
return object == null ? fallback : object;
}
public Long getLong(String key, Function<String, Long> fallback) {
Long object = getLong(key);
return object == null ? fallback.apply(key) : object;
}
public Long getOrSetLong(String key, Long fallback, String... blockComments) {
Long object = getLong(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public Long getOrSetLong(String key, Function<String, Long> fallback, String... blockComments) {
Long object = getLong(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public Float getFloat(String key) {
Object object = get(key);
if (object instanceof Float) {
return (Float) object;
} else if (object instanceof Number) {
Number number = (Number) object;
return number.floatValue();
}
return null;
}
public Float getFloat(String key, Float fallback) {
Float object = getFloat(key);
return object == null ? fallback : object;
}
public Float getFloat(String key, Function<String, Float> fallback) {
Float object = getFloat(key);
return object == null ? fallback.apply(key) : object;
}
public Float getOrSetFloat(String key, Float fallback, String... blockComments) {
Float object = getFloat(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public Float getOrSetFloat(String key, Function<String, Float> fallback, String... blockComments) {
Float object = getFloat(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public Double getDouble(String key) {
Object object = get(key);
if (object instanceof Double) {
return (Double) object;
} else if (object instanceof Number) {
Number number = (Number) object;
return number.doubleValue();
}
return null;
}
public Double getDouble(String key, Double fallback) {
Double object = getDouble(key);
return object == null ? fallback : object;
}
public Double getDouble(String key, Function<String, Double> fallback) {
Double object = getDouble(key);
return object == null ? fallback.apply(key) : object;
}
public Double getOrSetDouble(String key, Double fallback, String... blockComments) {
Double object = getDouble(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public Double getOrSetDouble(String key, Function<String, Double> fallback, String... blockComments) {
Double object = getDouble(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public String getString(String key) {
Object object = get(key);
return object == null ? null : object.toString();
}
public String getString(String key, String fallback) {
String object = getString(key);
return object == null ? fallback : object;
}
public String getString(String key, Function<String, String> fallback) {
String object = getString(key);
return object == null ? fallback.apply(key) : object;
}
public String getOrSetString(String key, String fallback, String... blockComments) {
String object = getString(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public String getOrSetString(String key, Function<String, String> fallback, String... blockComments) {
String object = getString(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(object, blockComments));
}
return object;
}
public List<?> getList(String key) {
Object object = get(key);
return object instanceof List ? (List<?>) object : null;
}
public List<?> getList(String key, List<?> fallback) {
List<?> object = getList(key);
return object == null ? fallback : object;
}
public List<?> getList(String key, Function<String, List<?>> fallback) {
List<?> object = getList(key);
return object == null ? fallback.apply(key) : object;
}
public List<?> getOrSetList(String key, List<?> fallback, String... blockComments) {
List<?> object = getList(key);
if (object == null) {
map.put(key, new ConfigSectionNode(fallback, blockComments));
return fallback;
}
return object;
}
public List<?> getOrSetList(String key, Function<String, List<?>> fallback, String... blockComments) {
List<?> object = getList(key);
if (object == null) {
object = fallback.apply(key);
map.put(key, new ConfigSectionNode(fallback, blockComments));
}
return object;
}
@SuppressWarnings("unchecked")
public <T> T set(String key, T value, String... blockComments) {
ConfigSectionNode node = map.get(key);
if (node == null) {
return (T) map.put(key, new ConfigSectionNode(value, blockComments));
}
Object oldValue = node.value;
node.value = value;
node.blockComments = blockComments;
return (T) oldValue;
}
@SuppressWarnings("unchecked")
public <T> T set(String key, T value) {
ConfigSectionNode node = map.get(key);
if (node == null) {
return (T) map.put(key, new ConfigSectionNode(value));
}
Object oldValue = node.value;
node.value = value;
return (T) oldValue;
}
@SuppressWarnings("unchecked")
public <T> T remove(String key) {
return (T) map.remove(key);
}
public void clear() {
map.clear();
}
@Override
public Iterator<String> iterator() {
return map.keySet().iterator();
}
}

View file

@ -0,0 +1,258 @@
package org.zhdev.config;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.comments.CommentLine;
import org.yaml.snakeyaml.comments.CommentType;
import org.yaml.snakeyaml.nodes.*;
import org.yaml.snakeyaml.parser.ParserException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class YamlConfig extends MapConfigSection implements Config {
protected static final YamlConfigConstructor CONSTRUCTOR;
protected static final YamlConfigRepresenter REPRESENTER;
protected static final Yaml YAML;
protected final String key;
protected String[] headerComments;
protected String[] endComments;
public YamlConfig(String key) {
super(null);
this.key = key;
}
public YamlConfig() {
this(DEFAULT_KEY);
}
@Override
public String getKey() {
return key;
}
@Override
public String[] getHeaderComments() {
return headerComments;
}
@Override
public String[] getEndComments() {
return endComments;
}
@Override
public void setHeaderComments(String... headerComments) {
this.headerComments = headerComments;
}
@Override
public void setEndComments(String... endComments) {
this.endComments = endComments;
}
private String[] createComments(List<CommentLine> lines) {
String[] comments = new String[lines.size()];
for (int i = 0; i < lines.size(); i++) {
CommentLine line = lines.get(i);
comments[i] = line.getValue().trim();
}
return comments;
}
protected Object constructHandle(Node keyNode, Node valueNode, String key, Object value) {
if (valueNode instanceof MappingNode) {
MapConfigSection childSection = new MapConfigSection();
nodesToSections(childSection, (MappingNode) valueNode);
value = childSection;
}
return value;
}
private void nodesToSections(MapConfigSection section, MappingNode node) {
for (NodeTuple tuple : node.getValue()) {
Node keyNode = tuple.getKeyNode();
Node valueNode = tuple.getValueNode();
String key = String.valueOf(CONSTRUCTOR.constructObject(keyNode));
Object value = constructHandle(keyNode, valueNode, key, CONSTRUCTOR.constructObject(valueNode));
ConfigSectionNode sectionNode = new ConfigSectionNode(value);
if (keyNode.getBlockComments() != null && keyNode.getBlockComments().size() > 0) {
sectionNode.blockComments = createComments(keyNode.getBlockComments());
}
if (keyNode.getInLineComments() != null && keyNode.getInLineComments().size() > 0) {
sectionNode.inlineComments = createComments((valueNode instanceof MappingNode || valueNode instanceof SequenceNode ? keyNode : valueNode).getInLineComments());
}
section.map.put(key, sectionNode);
}
}
@Override
public void load(Reader reader) throws ConfigException {
try {
MappingNode node = (MappingNode) YAML.compose(reader);
if (node == null) return;
if (node.getBlockComments() != null && node.getBlockComments().size() > 0) {
headerComments = createComments(node.getBlockComments());
}
if (node.getEndComments() != null && node.getEndComments().size() > 0) {
endComments = createComments(node.getEndComments());
}
nodesToSections(this, node);
} catch (ParserException e) {
throw new ConfigException(e);
}
}
@Override
public void load(InputStream stream) {
load(new InputStreamReader(stream, StandardCharsets.UTF_8));
}
@Override
public void load(File file) throws IOException, ConfigException {
load(Files.newInputStream(file.toPath()));
}
@Override
public File load(String path) throws ConfigException {
File file = new File(path);
try {
if (file.exists()) load(file);
} catch (IOException e) {
throw new ConfigException(e);
}
return file;
}
@Override
public File load() throws ConfigException {
return load(key);
}
private List<CommentLine> createCommentLines(String[] comments, CommentType commentType) {
List<CommentLine> lines = new ArrayList<>(comments.length);
for (String comment : comments) {
lines.add(new CommentLine(null, null, comment.isEmpty() ? comment : " " + comment, commentType));
}
return lines;
}
protected Node representHandle(String key, Object value) {
Node valueNode;
if (value instanceof MapConfigSection) {
valueNode = sectionsToNodes((MapConfigSection) value);
} else {
valueNode = REPRESENTER.represent(value);
}
return valueNode;
}
private MappingNode sectionsToNodes(MapConfigSection section) {
List<NodeTuple> tuples = new ArrayList<>();
for (Map.Entry<String, ConfigSectionNode> entry : section.map.entrySet()) {
String key = entry.getKey();
ConfigSectionNode sectionNode = entry.getValue();
Object value = sectionNode.value;
Node keyNode = REPRESENTER.represent(key);
Node valueNode = representHandle(key, value);
keyNode.setBlockComments(sectionNode.blockComments == null ? null : createCommentLines(sectionNode.blockComments, CommentType.BLOCK));
(valueNode instanceof MappingNode || valueNode instanceof SequenceNode ? keyNode : valueNode).setInLineComments(sectionNode.inlineComments == null ? null : createCommentLines(sectionNode.inlineComments, CommentType.IN_LINE));
tuples.add(new NodeTuple(keyNode, valueNode));
}
return new MappingNode(Tag.MAP, tuples, DumperOptions.FlowStyle.BLOCK);
}
@Override
public void save(Writer writer) {
MappingNode node = sectionsToNodes(this);
node.setBlockComments(headerComments == null ? null : createCommentLines(headerComments, CommentType.BLOCK));
node.setEndComments(endComments == null ? null : createCommentLines(endComments, CommentType.BLOCK));
YAML.serialize(node, writer);
}
@Override
public void save(OutputStream stream) {
save(new OutputStreamWriter(stream, StandardCharsets.UTF_8));
}
@Override
public void save(File file) throws IOException {
save(Files.newOutputStream(file.toPath()));
}
@Override
public File save(String path) throws ConfigException {
File file = new File(path);
if (!file.exists()) {
File parent = file.getParentFile();
if (parent != null) parent.mkdirs();
try {
file.createNewFile();
save(file);
} catch (IOException e) {
throw new ConfigException(e);
}
}
return file;
}
@Override
public File save() throws ConfigException {
return save(key);
}
@Override
public File saveIfEmpty(String path) throws ConfigException {
File file = new File(path);
if (file.length() == 0) {
File parent = file.getParentFile();
if (parent != null) parent.mkdirs();
try {
file.createNewFile();
save(file);
} catch (IOException e) {
throw new ConfigException(e);
}
}
return file;
}
@Override
public File saveIfEmpty() throws ConfigException {
return saveIfEmpty(key);
}
static {
LoaderOptions loaderOptions = new LoaderOptions();
loaderOptions.setProcessComments(true);
DumperOptions dumperOptions = new DumperOptions();
dumperOptions.setProcessComments(true);
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
dumperOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
YamlConfigRepresenter representer = new YamlConfigRepresenter(dumperOptions);
representer.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
representer.setDefaultScalarStyle(DumperOptions.ScalarStyle.PLAIN);
REPRESENTER = representer;
YAML = new Yaml(CONSTRUCTOR = new YamlConfigConstructor(loaderOptions), representer, dumperOptions, loaderOptions);
}
}

View file

@ -0,0 +1,16 @@
package org.zhdev.config;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.nodes.Node;
public class YamlConfigConstructor extends SafeConstructor {
public YamlConfigConstructor(LoaderOptions loaderOptions) {
super(loaderOptions);
}
@Override
protected Object constructObject(Node node) {
return super.constructObject(node);
}
}

View file

@ -0,0 +1,10 @@
package org.zhdev.config;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.representer.Representer;
public class YamlConfigRepresenter extends Representer {
public YamlConfigRepresenter(DumperOptions options) {
super(options);
}
}

169
pom.xml Normal file
View file

@ -0,0 +1,169 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.zhdev.varioutil</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<modules>
<module>common</module>
<module>io</module>
<module>bukkit</module>
<module>all</module>
</modules>
<build>
<defaultGoal>install</defaultGoal>
<resources>
<resource>
<directory>src\main\resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>pattern</directory>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/**</exclude>
</excludes>
</filter>
</filters>
<shadedArtifactAttached>true</shadedArtifactAttached>
<createDependencyReducedPom>false</createDependencyReducedPom>
<minimizeJar>true</minimizeJar>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addClasspath>false</addClasspath>
<addDefaultEntries>false</addDefaultEntries>
<addDefaultImplementationEntries>false</addDefaultImplementationEntries>
</manifest>
<manifestEntries/>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>deploy</id>
<build>
<defaultGoal>clean install deploy</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<configuration>
<altDeploymentRepository>local::default::file:${user.home}/repo/maven/</altDeploymentRepository>
</configuration>
<executions>
<execution>
<id>deploy</id>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>javadoc</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<additionalOptions>
<option>-Xdoclint:none</option>
</additionalOptions>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>source</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations-java5</artifactId>
<version>24.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>