package tc.oc.commons.core.configuration; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.annotation.Nullable; import javax.inject.Inject; import com.google.common.collect.Lists; import tc.oc.commons.core.util.Numbers; import tc.oc.minecraft.api.configuration.AbstractConfigurationSection; import tc.oc.minecraft.api.configuration.Configuration; import tc.oc.minecraft.api.configuration.ConfigurationSection; public class TestConfiguration extends AbstractConfigurationSection implements Configuration { private static final TestConfiguration EMPTY = new TestConfiguration(); private final String path; private final Map<String, Object> values; @Inject public TestConfiguration() { this("", new LinkedHashMap<>()); } public TestConfiguration(String path, Map<String, Object> values) { this.path = path; this.values = values; } private String[] split(Object key) { return String.valueOf(key).split("\\."); } private Object getLocal(String key) { final Object o = values.get(key); return o instanceof Map ? new TestConfiguration(resolvePath(key), (Map<String, Object>) o) : o; } private Object getPath(String[] path, int i) { if(path.length <= i) { throw new IllegalArgumentException(); } else { final Object o = getLocal(path[i]); if(path.length == i + 1) { return o; } else if(o instanceof TestConfiguration) { return ((TestConfiguration) o).getPath(path, i + 1); } else { return null; } } } @Override public void set(String path, Object value) { throw new UnsupportedOperationException(); } @Override public String getCurrentPath() { return path; } @Override public @Nullable ConfigurationSection getSection(String path) { final Object o = getPath(split(path), 0); if(o instanceof ConfigurationSection) { return (ConfigurationSection) o; } else { return null; } } @Override public Collection<String> getKeys() { return values.keySet(); } @Override public Object get(String path) { return getPath(split(path), 0); } @Override public Object get(String path, Object def) { final Object v = get(path); return v != null ? v : def; } private <T> T get(String path, Class<T> type, T def) { final Object o = get(path); return type.isInstance(o) ? type.cast(o) : def; } private <T> T get(String path, Class<T> type) { return get(path, type, null); } @Override public int getInt(String path, int def) { return get(path, Integer.class, def); } @Override public int getInt(String path) { return getInt(path, 0); } @Override public boolean getBoolean(String path, boolean def) { return get(path, Boolean.class, def); } @Override public boolean getBoolean(String path) { return getBoolean(path, false); } @Override public String getString(String path, String def) { return get(path, String.class, def); } @Override public String getString(String path) { return getString(path, null); } @Override public long getLong(String path, long def) { return get(path, Long.class, def); } @Override public long getLong(String path) { return getLong(path, 0); } @Override public double getDouble(String path, double def) { return get(path, Double.class, def); } @Override public double getDouble(String path) { return getDouble(path, 0); } @Override public List<?> getList(String path, List<?> def) { return get(path, List.class, def); } @Override public List<?> getList(String path) { return getList(path, null); } @Override public List<String> getStringList(String path) { final List<?> list = getList(path); return list == null ? Collections.emptyList() : Lists.transform(list, Object::toString); } private <T extends Number> List<T> getNumberList(String path, Class<T> type) { final List<?> list = getList(path); return list == null ? Collections.emptyList() : Lists.transform(list, n -> Numbers.coerce(n, type, false)); } @Override public List<Boolean> getBooleanList(String path) { final List<?> list = getList(path); return list == null ? Collections.emptyList() : Lists.transform(list, b -> b instanceof Boolean && (Boolean) b); } @Override public List<Byte> getByteList(String path) { return getNumberList(path, Byte.class); } @Override public List<Short> getShortList(String path) { return getNumberList(path, Short.class); } @Override public List<Long> getLongList(String path) { return getNumberList(path, Long.class); } @Override public List<Float> getFloatList(String path) { return getNumberList(path, Float.class); } @Override public List<Double> getDoubleList(String path) { return getNumberList(path, Double.class); } @Override public Configuration getDefaults() { return EMPTY; } }