summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java
diff options
context:
space:
mode:
authorBenjamin J. Culkin <bjculkin@mix.wvu.edu>2017-10-08 22:39:59 -0300
committerBenjamin J. Culkin <bjculkin@mix.wvu.edu>2017-10-08 22:39:59 -0300
commitc82e3b3b2de0633317ec8fc85925e91422820597 (patch)
tree96567416ce23c5ce85601f9cedc3a94bb1c55cba /BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java
parentb3ac1c8690c3e14c879913e5dcc03a5f5e14876e (diff)
Start splitting into maven modules
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java265
1 files changed, 0 insertions, 265 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java b/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java
deleted file mode 100644
index 7c5205b..0000000
--- a/BJC-Utils2/src/main/java/bjc/utils/ioutils/RuleBasedConfigReader.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package bjc.utils.ioutils;
-
-import java.io.InputStream;
-import java.util.InputMismatchException;
-import java.util.Scanner;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-
-import bjc.utils.data.IHolder;
-import bjc.utils.data.IPair;
-import bjc.utils.data.Identity;
-import bjc.utils.data.Pair;
-import bjc.utils.exceptions.UnknownPragmaException;
-import bjc.utils.funcdata.FunctionalMap;
-import bjc.utils.funcdata.FunctionalStringTokenizer;
-import bjc.utils.funcdata.IMap;
-
-/**
- * This class parses a rules based config file, and uses it to drive a provided
- * set of actions
- *
- * @author ben
- *
- * @param <E>
- * The type of the state object to use
- *
- */
-public class RuleBasedConfigReader<E> {
- /* Function to execute when starting a rule.
- * Takes the tokenizer, and a pair of the read token and application state
- */
- private BiConsumer<FunctionalStringTokenizer, IPair<String, E>> start;
-
- /*
- * Function to use when continuing a rule
- * Takes a tokenizer and application state
- */
- private BiConsumer<FunctionalStringTokenizer, E> continueRule;
-
- /*
- * Function to use when ending a rule
- * Takes an application state
- */
- private Consumer<E> end;
-
- /*
- * Map of pragma names to pragma actions
- * Pragma actions are functions taking a tokenizer and application state
- */
- private final IMap<String, BiConsumer<FunctionalStringTokenizer, E>> pragmas;
-
- /**
- * Create a new rule-based config reader
- *
- * @param start
- * The action to fire when starting a rule
- * @param continueRule
- * The action to fire when continuing a rule
- * @param end
- * The action to fire when ending a rule
- */
- public RuleBasedConfigReader(final BiConsumer<FunctionalStringTokenizer, IPair<String, E>> start,
- final BiConsumer<FunctionalStringTokenizer, E> continueRule, final Consumer<E> end) {
- this.start = start;
- this.continueRule = continueRule;
- this.end = end;
-
- this.pragmas = new FunctionalMap<>();
- }
-
- /**
- * Add a pragma to this reader
- *
- * @param name
- * The name of the pragma to add
- * @param action
- * The function to execute when this pragma is read
- */
- public void addPragma(final String name, final BiConsumer<FunctionalStringTokenizer, E> action) {
- if (name == null) throw new NullPointerException("Pragma name must not be null");
- else if (action == null) throw new NullPointerException("Pragma action must not be null");
-
- pragmas.put(name, action);
- }
-
- private void continueRule(final E state, final boolean isRuleOpen, final String line) {
- // Make sure our input is correct
- if (isRuleOpen == false)
- throw new InputMismatchException("Cannot continue rule with no rule open");
- else if (continueRule == null)
- throw new InputMismatchException("Rule continuation not supported for current grammar");
-
- /*
- * Accept the rule
- */
- continueRule.accept(new FunctionalStringTokenizer(line.substring(1), " "), state);
- }
-
- private boolean endRule(final E state, final boolean isRuleOpen) {
- /*
- * Ignore blank line without an open rule
- */
- if (isRuleOpen == false)
- /*
- * Do nothing
- */
- return false;
- else {
- /*
- * Nothing happens on rule end
- */
- if (end != null) {
- /*
- * Process the rule ending
- */
- end.accept(state);
- }
-
- /*
- * Return a closed rule
- */
- return false;
- }
- }
-
- /**
- * Run a stream through this reader
- *
- * @param input
- * The stream to get input
- * @param initialState
- * The initial state of the reader
- * @return The final state of the reader
- */
- public E fromStream(final InputStream input, final E initialState) {
- if (input == null) throw new NullPointerException("Input stream must not be null");
-
- /*
- * Application state: We're giving this back later
- */
- final E state = initialState;
-
- /*
- * Prepare our input source
- */
- try (Scanner source = new Scanner(input)) {
- source.useDelimiter("\n");
- /*
- * This is true when a rule's open
- */
- final IHolder<Boolean> isRuleOpen = new Identity<>(false);
-
- /*
- * Do something for every line of the file
- */
- source.forEachRemaining((line) -> {
- /*
- * Skip comment lines
- */
- if (line.startsWith("#") || line.startsWith("//"))
- /*
- * It's a comment
- */
- return;
- else if (line.equals("")) {
- /*
- * End the rule
- */
- isRuleOpen.replace(endRule(state, isRuleOpen.getValue()));
- } else if (line.startsWith("\t")) {
- /*
- * Continue the rule
- */
- continueRule(state, isRuleOpen.getValue(), line);
- } else {
- /*
- * Open a rule
- */
- isRuleOpen.replace(startRule(state, isRuleOpen.getValue(), line));
- }
- });
- }
-
- /*
- * Return the state that the user has created
- */
- return state;
- }
-
- /**
- * Set the action to execute when continuing a rule
- *
- * @param continueRule
- * The action to execute on continuation of a rule
- */
- public void setContinueRule(final BiConsumer<FunctionalStringTokenizer, E> continueRule) {
- this.continueRule = continueRule;
- }
-
- /**
- * Set the action to execute when ending a rule
- *
- * @param end
- * The action to execute on ending of a rule
- */
- public void setEndRule(final Consumer<E> end) {
- this.end = end;
- }
-
- /**
- * Set the action to execute when starting a rule
- *
- * @param start
- * The action to execute on starting of a rule
- */
- public void setStartRule(final BiConsumer<FunctionalStringTokenizer, IPair<String, E>> start) {
- if (start == null) throw new NullPointerException("Action on rule start must be non-null");
-
- this.start = start;
- }
-
- private boolean startRule(final E state, boolean isRuleOpen, final String line) {
- /*
- * Create the line tokenizer
- */
- final FunctionalStringTokenizer tokenizer = new FunctionalStringTokenizer(line, " ");
-
- /*
- * Get the initial token
- */
- final String nextToken = tokenizer.nextToken();
-
- /*
- * Handle pragmas
- */
- if (nextToken.equals("pragma")) {
- /*
- * Get the pragma name
- */
- final String token = tokenizer.nextToken();
-
- /*
- * Handle pragmas
- */
- pragmas.getOrDefault(token, (tokenzer, stat) -> {
- throw new UnknownPragmaException("Unknown pragma " + token);
- }).accept(tokenizer, state);
- } else {
- /*
- * Make sure input is correct
- */
- if (isRuleOpen == true)
- throw new InputMismatchException("Nested rules are currently not supported");
-
- /*
- * Start a rule
- */
- start.accept(tokenizer, new Pair<>(nextToken, state));
-
- isRuleOpen = true;
- }
-
- return isRuleOpen;
- }
-}