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

com.github.bloodshura.ignitium.cfg.AbstractTransformableMapping Maven / Gradle / Ivy

Go to download

A collection of configuration and serialization readers and writers, like JSON, internationalization (I18n), and CSV.

There is a newer version: 1.0.1
Show newest version
package com.github.bloodshura.ignitium.cfg;

import com.github.bloodshura.ignitium.collection.list.XList;
import com.github.bloodshura.ignitium.collection.list.XListIterator;
import com.github.bloodshura.ignitium.collection.list.impl.XArrayList;
import com.github.bloodshura.ignitium.collection.map.XMap;
import com.github.bloodshura.ignitium.collection.map.impl.XKeyView;
import com.github.bloodshura.ignitium.collection.map.impl.XValueView;
import com.github.bloodshura.ignitium.collection.tuple.Pair;
import com.github.bloodshura.ignitium.collection.tuple.PairLeftComparator;
import com.github.bloodshura.ignitium.lang.SelfFactory;
import com.github.bloodshura.ignitium.object.Base;
import com.github.bloodshura.ignitium.resource.OutputResource;
import com.github.bloodshura.ignitium.resource.Resource;
import com.github.bloodshura.ignitium.util.XApi;
import com.github.bloodshura.ignitium.worker.UtilWorker;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;

public abstract class AbstractTransformableMapping extends Base implements Iterable>, SelfFactory {
	private final XList> serializers;
	private final XMap table;

	public AbstractTransformableMapping(@Nonnull XMap table) {
		this.serializers = new XArrayList<>(ValueSerializer.COLOR, ValueSerializer.ENUM);
		this.table = table;
	}

	public final void clear() {
		entries().clear();
	}

	public final boolean contains(@Nonnull String key) {
		return entries().containsKey(key);
	}

	@Nonnull
	public final XMap entries() {
		return table;
	}

	@Nullable
	public final Object get(@Nonnull String key) {
		return entries().get(key);
	}

	@Nullable
	public final  E getAs(@Nonnull String key, @Nonnull Class type) {
		return getAs(key, type, null);
	}

	@Nonnull
	public final  E getAs(@Nonnull String key, @Nonnull E defaultValue) {
		return getAs(key, (Class) defaultValue.getClass(), defaultValue);
	}

	public final boolean getBoolean(@Nonnull String key) {
		return getBoolean(key, false);
	}

	public final boolean getBoolean(@Nonnull String key, boolean defaultValue) {
		return defaultGet(key, Boolean.class, defaultValue);
	}

	@Nullable
	public final Boolean getBooleanOrNull(@Nonnull String key) {
		return defaultGet(key, Boolean.class, null);
	}

	public final double getDecimal(@Nonnull String key) {
		return getDecimal(key, 0.0D);
	}

	public final double getDecimal(@Nonnull String key, double defaultDouble) {
		return defaultGet(key, Number.class, defaultDouble).doubleValue();
	}

	@Nullable
	public final Double getDecimalOrNull(@Nonnull String key) {
		Number number = defaultGet(key, Number.class, null);

		return number != null ? number.doubleValue() : null;
	}

	public final int getInt(@Nonnull String key) {
		return getInt(key, 0);
	}

	public final int getInt(@Nonnull String key, int defaultInt) {
		return defaultGet(key, Number.class, defaultInt).intValue();
	}

	@Nullable
	public final Integer getIntOrNull(@Nonnull String key) {
		Number number = defaultGet(key, Number.class, null);

		return number != null ? number.intValue() : null;
	}

	public final long getLong(@Nonnull String key) {
		return getLong(key, 0L);
	}

	public final long getLong(@Nonnull String key, long defaultLong) {
		return defaultGet(key, Number.class, defaultLong).longValue();
	}

	@Nullable
	public final Long getLongOrNull(@Nonnull String key) {
		Number number = defaultGet(key, Number.class, null);

		return number != null ? number.longValue() : null;
	}

	@Nonnull
	public final XList> getSerializers() {
		return serializers;
	}

	@Nullable
	public final String getString(@Nonnull String key) {
		return getString(key, null);
	}

	@Nullable
	public final String getString(@Nonnull String key, @Nullable String defaultString) {
		Object value = get(key);

		return value != null ? value.toString() : defaultString;
	}

	public final boolean isEmpty() {
		return entries().isEmpty();
	}

	@Nonnull
	@Override
	public final XListIterator> iterator() {
		return entries().iterator();
	}

	@Nonnull
	public final XKeyView keys() {
		return entries().keys();
	}

	public final void load(@Nonnull AbstractTransformableMapping mapping) {
		clear();
		entries().addAll(mapping);
	}

	public final void load(@Nonnull Object... entries) throws IllegalArgumentException {
		XApi.require(entries.length % 2 == 0, "Values must consist of (key, value)...");
		clear();

		for (int i = 0; i < entries.length; i += 2) {
			XApi.requireNonNull(entries[i], "values[" + i + ']');
			set(entries[i].toString(), entries[i + 1]);
		}
	}

	@Override
	public abstract void load(@Nonnull Resource resource) throws IOException;

	public final void remove(@Nonnull String key) {
		set(key, null);
	}

	@Override
	public abstract void save(@Nonnull OutputResource resource) throws IOException;

	@Nullable
	public final  ValueSerializer serializerFor(@Nonnull Class type) {
		return (ValueSerializer) getSerializers().selectFirst(s -> s.getAcceptableType().isAssignableFrom(type));
	}

	public  void set(@Nonnull String key, @Nullable E value) {
		if (value != null) {
			Object target;

			if (entries().canInsert(new Pair<>(key, value))) {
				target = value;
			} else {
				ValueSerializer serializer = serializerFor((Class) value.getClass());

				if (serializer != null) {
					target = serializer.serialize(value);
				} else {
					target = value.toString();
				}
			}

			entries().set(key, target);
		} else {
			entries().removeKey(key);
		}
	}

	public final int size() {
		return entries().size();
	}

	public final void sort() {
		entries().sort(new PairLeftComparator<>());
	}

	@Nonnull
	@Override
	public abstract String toString();

	@Nonnull
	public final XValueView values() {
		return entries().values();
	}

	@Nullable
	protected  E defaultGet(@Nonnull String key, @Nonnull Class type, @Nullable E defaultValue) {
		Object value = get(key);

		if (value != null && (type.isAssignableFrom(value.getClass()) || UtilWorker.primitiveClassMatch(type, value.getClass()))) {
			return (E) get(key);
		}

		return defaultValue;
	}

	@Nullable
	protected  E getAs(@Nonnull String key, @Nonnull Class type, @Nullable E defaultValue) {
		Object value = get(key);

		if (value != null) {
			if (type.isAssignableFrom(value.getClass()) || UtilWorker.primitiveClassMatch(type, value.getClass())) {
				return (E) get(key);
			}

			ValueSerializer serializer = serializerFor(type);

			if (serializer != null) {
				E transformed = serializer.deserialize(type, value);

				if (transformed != null) {
					return transformed;
				}
			}
		}

		return defaultValue;
	}

	@Nonnull
	@Override
	protected final Object[] stringValues() {
		return new Object[] { entries() };
	}
}