Initial
This commit is contained in:
commit
e443249166
29 changed files with 2887 additions and 0 deletions
20
io/pom.xml
Normal file
20
io/pom.xml
Normal 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>
|
||||
41
io/src/main/java/org/zhdev/config/Config.java
Normal file
41
io/src/main/java/org/zhdev/config/Config.java
Normal 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;
|
||||
}
|
||||
18
io/src/main/java/org/zhdev/config/ConfigException.java
Normal file
18
io/src/main/java/org/zhdev/config/ConfigException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
123
io/src/main/java/org/zhdev/config/ConfigSection.java
Normal file
123
io/src/main/java/org/zhdev/config/ConfigSection.java
Normal 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();
|
||||
}
|
||||
19
io/src/main/java/org/zhdev/config/ConfigSectionNode.java
Normal file
19
io/src/main/java/org/zhdev/config/ConfigSectionNode.java
Normal 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() {
|
||||
}
|
||||
}
|
||||
469
io/src/main/java/org/zhdev/config/MapConfigSection.java
Normal file
469
io/src/main/java/org/zhdev/config/MapConfigSection.java
Normal 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();
|
||||
}
|
||||
}
|
||||
258
io/src/main/java/org/zhdev/config/YamlConfig.java
Normal file
258
io/src/main/java/org/zhdev/config/YamlConfig.java
Normal 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);
|
||||
}
|
||||
}
|
||||
16
io/src/main/java/org/zhdev/config/YamlConfigConstructor.java
Normal file
16
io/src/main/java/org/zhdev/config/YamlConfigConstructor.java
Normal 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);
|
||||
}
|
||||
}
|
||||
10
io/src/main/java/org/zhdev/config/YamlConfigRepresenter.java
Normal file
10
io/src/main/java/org/zhdev/config/YamlConfigRepresenter.java
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue