TypedParser.java
package it.fulminazzo.yagl.parsers;
import it.fulminazzo.yagl.utils.ParserUtils;
import it.fulminazzo.fulmicollection.interfaces.functions.TriConsumer;
import it.fulminazzo.fulmicollection.objects.Refl;
import it.fulminazzo.yamlparser.configuration.ConfigurationSection;
import it.fulminazzo.yamlparser.configuration.IConfiguration;
import it.fulminazzo.yamlparser.parsers.CallableYAMLParser;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* This parser allows parsing an object using the {@link CallableYAMLParser} methods.
* However, it forces the saved object to store a <i>type</i> field, that contains the class name of the original object.
* Upon loading, this class is retrieved (and will throw errors for invalid values) to recreate the object.
*
* @param <C> the type parameter
*/
public abstract class TypedParser<C> extends CallableYAMLParser<C> {
protected static final String TYPE_FIELD = "type";
/**
* Instantiates a new Typed parser.
*
* @param clazz the clazz
*/
public TypedParser(final @NotNull Class<C> clazz) {
super(clazz, c -> getObjectFromType(clazz, c));
}
@SuppressWarnings("unchecked")
@Override
protected TriConsumer<IConfiguration, String, C> getDumper() {
return (c, s, g) -> {
super.getDumper().accept(c, s, g);
if (g == null) return;
c.set(s + "." + TYPE_FIELD, ParserUtils.classToType(getOClass(), (Class<? extends C>) g.getClass()));
};
}
/**
* Tries to get the corresponding {@link #TYPE_FIELD} type from the given section, and coverts it to an instance.
* Throws an {@link IllegalArgumentException} in case no type is provided or no class is found.
*
* @param <T> the type of the object
* @param objectClass the object class
* @param section the section
* @param parameters the parameters for the constructor
* @return the object
*/
protected static <T> T getObjectFromType(final @NotNull Class<T> objectClass,
final @NotNull ConfigurationSection section,
final Object @Nullable ... parameters) {
String type = section.getString(TYPE_FIELD);
if (type == null) throw new IllegalArgumentException(String.format("'%s' cannot be null", TYPE_FIELD));
Class<? extends T> clazz = ParserUtils.typeToClass(objectClass, type);
return new Refl<>(clazz, parameters).getObject();
}
}