All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.morimekta.config.Config Maven / Gradle / Ivy

There is a newer version: 2.7.1
Show newest version
package net.morimekta.config;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * Base configuration object. Essentially a type-safe map from a string key that
 * can look up more than one level into the map (if referencing config objects
 * within the config object). This way, if the config contains a config object
 * on key 'b', then getString('b.c') will look for key 'c' in the config 'b'.
 *
 * It is not implementing the Map base class since it would require also
 * implementing generic entry adders (put, putAll), and type unsafe getters.
 */
public class Config {
    public static class Entry implements Comparable {
        public final String key;
        public final Value.Type type;
        public final Object value;

        private Entry(String key, Value.Type type, Object value) {
            this.key = key;
            this.type = type;
            this.value = value;
        }

        @Override
        public int compareTo(Entry entry) {
            return key.compareTo(entry.key);
        }

        @Override
        public int hashCode() {
            return key.hashCode();
        }
    }

    private Config() {
        map = new LinkedHashMap<>();
    }

    public Set keySet() {
        return new HashSet<>(map.keySet());
    }

    public Set keySet(String prefix) {
        return map.keySet()
                  .stream()
                  .filter(e -> e.equals(prefix) || e.startsWith(prefix + '.'))
                  .collect(Collectors.toSet());
    }

    public Stream keyStream() {
        return StreamSupport.stream(keySpliterator(), false);
    }

    public Spliterator keySpliterator() {
        return Spliterators.spliterator(map.keySet(),
                                        Spliterator.IMMUTABLE |
                                        Spliterator.DISTINCT |
                                        Spliterator.NONNULL |
                                        Spliterator.SIZED |
                                        Spliterator.SUBSIZED);
    }

    public Set entrySet() {
        return map.entrySet()
                  .stream()
                  .map(e -> new Entry(e.getKey(), e.getValue().type, e.getValue().value))
                  .collect(Collectors.toSet());
    }

    public Stream entryStream() {
        return StreamSupport.stream(entrySpliterator(), false);
    }

    public Spliterator entrySpliterator() {
        return Spliterators.spliterator(entrySet(),
                                        Spliterator.IMMUTABLE |
                                        Spliterator.DISTINCT |
                                        Spliterator.NONNULL |
                                        Spliterator.SIZED |
                                        Spliterator.SUBSIZED);
    }

    public boolean containsKey(String key) {
        return map.containsKey(key);
    }

    public boolean containsPrefix(String prefix) throws ConfigException {
        String prefixed = prefix + '.';
        for (String key : keySet()) {
            if (key.equals(prefix) || key.startsWith(prefixed)) {
                return true;
            }
        }
        return false;
    }

    public Value.Type typeOf(String key) throws ConfigException {
        return getValue(key).type;
    }

    public boolean isEmpty() {
        return map.isEmpty();
    }

    public int size() {
        return map.size();
    }

    // --- Type things.

    public String getString(String key) throws ConfigException {
        return getValue(key).asString();
    }

    public String getString(String key, String def) throws ConfigException {
        if (containsKey(key)) {
            return getValue(key).asString();
        }
        return def;
    }

    public boolean getBoolean(String key) throws ConfigException {
        return getValue(key).asBoolean();
    }

    public boolean getBoolean(String key, boolean def) throws ConfigException {
        if (containsKey(key)) {
            return getValue(key).asBoolean();
        }
        return def;
    }

    public int getInteger(String key) throws ConfigException {
        return getValue(key).asInteger();
    }

    public int getInteger(String key, int def) throws ConfigException {
        if (containsKey(key)) {
            return getValue(key).asInteger();
        }
        return def;
    }

    public long getLong(String key) throws ConfigException {
        return getValue(key).asLong();
    }

    public long getLong(String key, long def) throws ConfigException {
        if (containsKey(key)) {
            return getValue(key).asLong();
        }
        return def;
    }

    public double getDouble(String key) throws ConfigException {
        return getValue(key).asDouble();
    }

    public double getDouble(String key, double def) throws ConfigException {
        if (containsKey(key)) {
            return getValue(key).asDouble();
        }
        return def;
    }

    public Sequence getSequence(String key) throws ConfigException {
        return getValue(key).asSequence();
    }

    public Config getConfig(String key) throws ConfigException {
        return getValue(key).asConfig();
    }

    public Value getValue(String key) throws KeyNotFoundException {
        if (!map.containsKey(key)) {
            throw new KeyNotFoundException("No such key " + key);
        }
        return map.get(key);
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (o == null || !(o instanceof Config)) {
            return false;
        }
        Config other = (Config) o;
        if (other.map.size() != map.size() ||
            !other.map.keySet().equals(map.keySet())) {
            return false;
        }

        for (String key : map.keySet()) {
            if (!map.get(key).equals(other.map.get(key))) {
                return false;
            }
        }
        return true;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder(getClass().getSimpleName());
        builder.append('(');

        boolean first = true;
        for (String key : keySet()) {
            if (first) {
                first = false;
            } else {
                builder.append(',');
            }
            builder.append(key).append(":").append(map.get(key).value.toString());
        }

        builder.append(')');
        return builder.toString();
    }

    public Builder mutate() {
        return new Builder(this);
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private final Map map;

        public Builder() {
            map = new HashMap<>();
        }

        public Builder(Config base) {
            map = new HashMap<>();
            map.putAll(base.map);
        }

        public void putAll(Config other) {
            map.putAll(other.map);
        }

        public Builder putBoolean(String key, boolean value) throws ConfigException {
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putInteger(String key, int value) {
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putLong(String key, long value) {
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putDouble(String key, double value) {
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putString(String key, String value) {
            if (value == null) {
                throw new IllegalArgumentException();
            }
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putSequence(String key, Sequence value) {
            if (value == null) {
                throw new IllegalArgumentException();
            }
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putConfig(String key, Config value) {
            if (value == null) {
                throw new IllegalArgumentException();
            }
            map.put(key, Value.create(value));
            return this;
        }

        public Builder putValue(String key, Value value) {
            map.put(key, value);
            return this;
        }

        public Value get(String key) {
            return map.get(key);
        }

        public boolean containsKey(String key) {
            return map.containsKey(key);
        }

        public Builder clear(String key) {
            map.remove(key);
            return this;
        }

        public Builder clear() {
            map.clear();
            return this;
        }

        public Config build() {
            Config cfg = new Config();
            cfg.map.putAll(map);
            return cfg;
        }
    }

    // --- PRIVATE ---

    private final Map map;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy