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

com.github.bloodshura.ignitium.cfg.props.Properties 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.props;

import com.github.bloodshura.ignitium.cfg.AbstractTransformableMapping;
import com.github.bloodshura.ignitium.cfg.ValueSerializer;
import com.github.bloodshura.ignitium.cfg.props.serial.PropertiesLexer;
import com.github.bloodshura.ignitium.cfg.props.serial.PropertyEntry;
import com.github.bloodshura.ignitium.cfg.props.serial.PropertySerializationAttributes;
import com.github.bloodshura.ignitium.charset.TextBuilder;
import com.github.bloodshura.ignitium.collection.map.XMap;
import com.github.bloodshura.ignitium.collection.map.impl.XLinkedMap;
import com.github.bloodshura.ignitium.collection.store.XStore;
import com.github.bloodshura.ignitium.collection.tuple.Pair;
import com.github.bloodshura.ignitium.collection.view.XTranslatedView;
import com.github.bloodshura.ignitium.collection.view.XView;
import com.github.bloodshura.ignitium.io.stream.TextReader;
import com.github.bloodshura.ignitium.io.stream.TextWriter;
import com.github.bloodshura.ignitium.object.Mutable;
import com.github.bloodshura.ignitium.resource.OutputResource;
import com.github.bloodshura.ignitium.resource.Resource;
import com.github.bloodshura.ignitium.sys.XSystem;
import com.github.bloodshura.ignitium.worker.ParseWorker;
import com.github.bloodshura.ignitium.worker.StringWorker;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.Supplier;

@Mutable
public class Properties extends AbstractTransformableMapping {
	private final PropertySerializationAttributes attributes;
	private Consumer autoSaveConsumer;
	private OutputResource autoSaveOutput;

	public Properties() {
		this(new XLinkedMap<>());
	}

	public Properties(@Nonnull XMap table) {
		super(table);
		this.attributes = new PropertySerializationAttributes();
	}

	public boolean contains(@Nonnull String key, @Nonnull Class type) {
		Class typeOf = typeOf(key);

		return typeOf != null && type.isAssignableFrom(typeOf);
	}

	public void disableAutoSave() {
		this.autoSaveConsumer = null;
		this.autoSaveOutput = null;
	}

	public void enableAutoSave(@Nonnull OutputResource output) {
		enableAutoSave(output, null);
	}

	public void enableAutoSave(@Nonnull OutputResource output, @Nullable Consumer autoSave) {
		this.autoSaveConsumer = autoSave;
		this.autoSaveOutput = output;
	}

	@Nullable
	public  E get(@Nonnull String key, @Nonnull Class objectClass) {
		return get(key, objectClass, null);
	}

	@Nullable
	public  E get(@Nonnull String key, @Nonnull Class objectClass, @Nullable E defaultObject) {
		Object value = get(key);

		if (value != null && objectClass.isAssignableFrom(value.getClass())) {
			return (E) get(key);
		}

		return defaultObject;
	}

	@Nullable
	public  E get(@Nonnull String key, @Nonnull ValueSerializer transformer) {
		return get(key, transformer, null);
	}

	@Nullable
	public  E get(@Nonnull String key, @Nonnull ValueSerializer transformer, @Nullable E defaultObject) {
		Object value = get(key);

		if (value == null) {
			return defaultObject;
		}

		E transformed = transformer.deserialize((Class) defaultObject.getClass(), value);

		return transformed != null ? transformed : defaultObject;
	}

	@Nonnull
	public PropertySerializationAttributes getAttributes() {
		return attributes;
	}

	public char getChar(@Nonnull String key) {
		return getChar(key, (char) 0);
	}

	public char getChar(@Nonnull String key, char defaultChar) {
		return get(key, Character.class, defaultChar);
	}

	@Nullable
	public XView getStrings(@Nonnull String key) {
		return getStrings(key, null);
	}

	@Nullable
	public XView getStrings(@Nonnull String key, @Nullable XView defaultStrings) {
		return contains(key, XStore.class) ? new XTranslatedView((XStore) get(key), Object::toString) : defaultStrings;
	}

	public boolean isAutoSaveEnabled() {
		return autoSaveOutput != null;
	}

	@Override
	public void load(@Nonnull Resource input) throws IOException {
		try (TextReader reader = new TextReader(input)) {
			load(reader);
		}
	}

	@Override
	public void save(@Nonnull OutputResource output) throws IOException {
		try (TextWriter writer = new TextWriter(output)) {
			save(writer);
		}
	}

	@Override
	public void set(@Nonnull String key, @Nullable Object value) {
		if (value instanceof String) {
			String strValue = (String) value;

			if (ParseWorker.isBoolean(strValue)) {
				value = ParseWorker.toBoolean(strValue);
			} else if (ParseWorker.isInt(strValue)) {
				value = ParseWorker.toInt(strValue);
			} else if (ParseWorker.isLong(strValue)) {
				value = ParseWorker.toLong(strValue);
			} else if (ParseWorker.isDouble(strValue)) {
				value = ParseWorker.toDouble(strValue);
			}
		}

		super.set(key, value);

		if (isAutoSaveEnabled()) {
			autoSave();
		}
	}

	public void setAsString(@Nonnull String key, @Nullable Object value) {
		super.set(key, value != null ? value.toString() : null);

		if (isAutoSaveEnabled()) {
			autoSave();
		}
	}

	@Nonnull
	public String toDetailedString() {
		TextBuilder builder = new TextBuilder();

		builder.setSeparator(XSystem.getLineSeparator());
		builder.append("properties x" + size() + " {");

		for (String key : keys()) {
			Object value = get(key);

			builder.append("  " + key + ": " + value + " | " + value.getClass().getSimpleName().toLowerCase());
		}

		builder.newLine();
		builder.append('}');

		return builder.toString();
	}

	@Nonnull
	@Override
	public String toString() {
		TextBuilder builder = new TextBuilder().setSeparator(", ");

		for (Pair pair : this) {
			builder.append(pair.getLeft() + '=' + pair.getRight());
		}

		return '[' + builder.toString() + ']';
	}

	@Nullable
	public Class typeOf(@Nonnull String key) {
		Object value = get(key);

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

	protected void autoSave() {
		try {
			save(autoSaveOutput);
		} catch (Exception exception) {
			autoSaveConsumer.accept(exception);
		}
	}

	protected void load(@Nonnull TextReader reader) throws IOException {
		clear();

		PropertiesLexer lexer = new PropertiesLexer(getAttributes(), reader);
		PropertyEntry lastEntry = null;

		while (lexer.hasNext()) {
			PropertyEntry entry = lexer.next();

			if (entry.type == PropertyEntry.Type.KEY_DEF) {
				lastEntry = entry;
			} else if (entry.type == PropertyEntry.Type.VALUE_DEF) {
				if (lastEntry != null && lastEntry.type == PropertyEntry.Type.KEY_DEF) {
					String key = lastEntry.object.toString();
					Object value = entry.object;

					if (entry.enforce == PropertyEntry.ENFORCE_CHAR && !value.toString().isEmpty()) {
						set(key, value.toString().charAt(0));
					} else if (entry.enforce == PropertyEntry.ENFORCE_STRING) {
						setAsString(key, value);
					} else {
						set(key, value);
					}
				}
			}
		}

		sort();
	}

	protected void save(@Nonnull TextWriter writer) throws IOException {
		PropertySerializationAttributes attributes = getAttributes();
		Iterator> iterator = iterator();
		String separator = String.valueOf(attributes.getSeparator());

		if (attributes.hasSeparatorSuffix()) {
			separator += attributes.getSeparatorSuffix();
		}

		while (iterator.hasNext()) {
			Pair pair = iterator.next();
			String key = pair.getLeft();
			Object value = pair.getRight();
			String output;

			if (value instanceof Supplier) {
				value = ((Supplier) value).get();
			}

			if (value instanceof Character) {
				output = attributes.getCharIndexer() + StringWorker.escape(value.toString()) + attributes.getCharIndexer();
			} else if (value instanceof String) {
				output = attributes.getStringIndexer() + StringWorker.escape((String) value) + attributes.getStringIndexer();
			} else if (value instanceof XStore) {
				XStore store = (XStore) value;
				TextBuilder builder = new TextBuilder().setSeparator(", ");

				for (Object object : store) {
					builder.append(attributes.getStringIndexer() + StringWorker.escape(String.valueOf(object)) + attributes.getStringIndexer());
				}

				output = attributes.getListOpener() + builder.toString() + attributes.getListCloser();
			} else {
				output = StringWorker.escape(String.valueOf(value));
			}

			writer.write(key + separator + output);

			if (iterator.hasNext()) {
				writer.newLine();
			}
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy