From a0bc85a8992782d59d4e0556efd025db048b9fc2 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Fri, 28 Jul 2017 20:03:50 -0700 Subject: [PATCH] Create a ConfigurationObject class. --- build.gradle | 1 + .../nwapw/abacus/config/Configuration.java | 18 +++ .../abacus/config/ConfigurationObject.java | 146 ++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 src/org/nwapw/abacus/config/Configuration.java create mode 100644 src/org/nwapw/abacus/config/ConfigurationObject.java diff --git a/build.gradle b/build.gradle index 7733484..36fd331 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,7 @@ repositories { } dependencies { + compile 'com.moandjiezana.toml:toml4j:0.7.1' testCompile 'junit:junit:4.12' } diff --git a/src/org/nwapw/abacus/config/Configuration.java b/src/org/nwapw/abacus/config/Configuration.java new file mode 100644 index 0000000..d22d50d --- /dev/null +++ b/src/org/nwapw/abacus/config/Configuration.java @@ -0,0 +1,18 @@ +package org.nwapw.abacus.config; + +/** + * Serializable class that will be used to load TOML + * configurations. + */ +public class Configuration { + + /** + * The precision to which the calculator should operator. + */ + public int decimalPrecision; + /** + * The type of number this calculator should use. + */ + public String numberType; + +} diff --git a/src/org/nwapw/abacus/config/ConfigurationObject.java b/src/org/nwapw/abacus/config/ConfigurationObject.java new file mode 100644 index 0000000..c8147a4 --- /dev/null +++ b/src/org/nwapw/abacus/config/ConfigurationObject.java @@ -0,0 +1,146 @@ +package org.nwapw.abacus.config; + +import com.moandjiezana.toml.Toml; +import com.moandjiezana.toml.TomlWriter; +import org.nwapw.abacus.number.NaiveNumber; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +/** + * A configuration object, which essentially + * manages saving, loading, and getting values + * from the configuration. While Configuration is + * the data model, this is the interface with it. + */ +public class ConfigurationObject { + + /** + * The default implementation to use for instantiating numbers. + */ + private static final Class DEFAULT_IMPLEMENTATION = NaiveNumber.class; + /** + * The writer used to store the configuration. + */ + private static final TomlWriter TOML_WRITER = new TomlWriter(); + /** + * The configuration instance being modeled. + */ + private Configuration configuration; + /** + * A map of number names to their implementations, which + * will be provided by plugins. + */ + private Map> numberImplementations; + + /** + * Sets up the ConfigurationObject. + * different constructors do different things, + * but they all lead here. + * @param configuration the configuration to set up with. + */ + private void setup(Configuration configuration){ + this.configuration = configuration; + numberImplementations = new HashMap<>(); + } + + /** + * Creates a default configuration. + * @return the newly created default configuration. + */ + private Configuration getDefaultConfig(){ + configuration = new Configuration(); + configuration.decimalPrecision = -1; + configuration.numberType = "naive"; + return configuration; + } + + /** + * Register a number implementation. + * @param name the name of the number implementation to register the class as. + * @param newClass the class that will be used to instantiate the new number. + * It is required that this class provides a Number(String) constructor. + */ + public void registerImplementation(String name, Class newClass){ + numberImplementations.put(name, newClass); + } + + /** + * Creates a new number with the configured type, passing + * it the given string. + * @param string the string from which the number should be parsed. + * @return the resulting number, or null if an error occurred. + */ + public NaiveNumber numberFromString(String string) { + Class toLoad = + numberImplementations.getOrDefault(configuration.numberType, DEFAULT_IMPLEMENTATION); + try { + return toLoad.getConstructor(String.class).newInstance(string); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Returns the configured, user-requested precision. + * @return the precision. + */ + public int getPrecision(){ + return configuration.decimalPrecision; + } + + /** + * Saves the ConfigurationObject to the given file. + * @param toFile the file to save ot. + * @return true if the save succeed, false if otherwise. + */ + public boolean save(File toFile){ + if(toFile.getParentFile() != null) toFile.getParentFile().mkdirs(); + try { + TOML_WRITER.write(configuration, toFile); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + /** + * Creates a new configuration object with the given config. + * @param config the config to use. + */ + public ConfigurationObject(Configuration config){ + setup(config); + } + + /** + * Create a configuration object by attempting to + * load a config from the given path, using the + * default configuration otherwise. + * @param path the path to attempt to load. + */ + public ConfigurationObject(File path){ + Configuration config; + if(!path.exists()) { + config = getDefaultConfig(); + } else { + Toml parse = new Toml(); + parse.read(path); + config = parse.to(Configuration.class); + } + setup(config); + } + + /** + * Creates a new configuration object with the + * default configuration. + */ + public ConfigurationObject(){ + setup(getDefaultConfig()); + } + +}