From 61fd71f69e080790da722e0e03b71ecd7c2538a2 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Tue, 10 May 2016 16:02:45 -0400 Subject: General update --- .../bjc/utils/examples/parsing/ShuntTester.java | 4 +- .../utils/examples/parsing/TreeConstructTest.java | 14 +- .../bjc/utils/examples/rangen/DiabloItemGen.java | 4 +- .../examples/rangen/RandomStringExamples.java | 6 +- .../src/main/java/bjc/utils/cli/CLICommander.java | 46 ++- .../main/java/bjc/utils/cli/DelegatingCommand.java | 15 +- .../main/java/bjc/utils/cli/GenericCommand.java | 15 +- .../java/bjc/utils/cli/GenericCommandMode.java | 81 +++-- .../src/main/java/bjc/utils/cli/GenericHelp.java | 13 +- .../src/main/java/bjc/utils/cli/ICommand.java | 2 +- .../main/java/bjc/utils/cli/ICommandHandler.java | 5 +- .../src/main/java/bjc/utils/cli/ICommandHelp.java | 10 +- .../src/main/java/bjc/utils/cli/ICommandMode.java | 6 +- .../bjc/utils/components/ComponentDescription.java | 13 +- .../components/ComponentDescriptionFileParser.java | 60 +--- .../components/ComponentDescriptionState.java | 4 + .../utils/components/FileComponentRepository.java | 127 ++++---- .../bjc/utils/components/IComponentRepository.java | 19 +- .../src/main/java/bjc/utils/data/BoundLazy.java | 69 +++- .../main/java/bjc/utils/data/BoundListHolder.java | 10 +- BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java | 10 +- .../src/main/java/bjc/utils/data/ListHolder.java | 10 +- BJC-Utils2/src/main/java/bjc/utils/data/Pair.java | 26 ++ .../main/java/bjc/utils/funcdata/ExtendedMap.java | 18 +- .../java/bjc/utils/funcdata/FunctionalList.java | 42 +-- .../java/bjc/utils/funcdata/FunctionalMap.java | 12 +- .../utils/funcdata/FunctionalStringTokenizer.java | 6 +- .../java/bjc/utils/funcdata/IFunctionalList.java | 350 --------------------- .../java/bjc/utils/funcdata/IFunctionalMap.java | 137 -------- .../src/main/java/bjc/utils/funcdata/IList.java | 350 +++++++++++++++++++++ .../src/main/java/bjc/utils/funcdata/IMap.java | 137 ++++++++ .../src/main/java/bjc/utils/funcdata/ITree.java | 2 +- .../main/java/bjc/utils/funcdata/PushdownMap.java | 10 +- .../bjc/utils/funcdata/TransformedValueMap.java | 14 +- .../src/main/java/bjc/utils/funcdata/Tree.java | 16 +- .../bjc/utils/funcdata/bst/BinarySearchTree.java | 6 +- .../main/java/bjc/utils/funcutils/EnumUtils.java | 4 +- .../bjc/utils/funcutils/GroupPartIteration.java | 14 +- .../main/java/bjc/utils/funcutils/ListUtils.java | 48 +-- .../java/bjc/utils/funcutils/TokenDeaffixer.java | 6 +- .../java/bjc/utils/funcutils/TokenSplitter.java | 10 +- .../src/main/java/bjc/utils/gen/RandomGrammar.java | 12 +- .../main/java/bjc/utils/gen/WeightedGrammar.java | 52 +-- .../main/java/bjc/utils/gen/WeightedRandom.java | 10 +- .../main/java/bjc/utils/graph/AdjacencyMap.java | 12 +- .../src/main/java/bjc/utils/graph/Graph.java | 10 +- .../java/bjc/utils/gui/ExtensionFileFilter.java | 4 +- .../java/bjc/utils/gui/ListParameterPanel.java | 4 +- .../bjc/utils/gui/awt/ExtensionFileFilter.java | 4 +- .../utils/parserutils/RuleBasedReaderPragmas.java | 81 +++++ .../java/bjc/utils/parserutils/ShuntingYard.java | 16 +- .../bjc/utils/parserutils/TreeConstructor.java | 6 +- 52 files changed, 1087 insertions(+), 875 deletions(-) delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java delete mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java (limited to 'BJC-Utils2/src') diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/ShuntTester.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/ShuntTester.java index 9744653..5148be4 100644 --- a/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/ShuntTester.java +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/ShuntTester.java @@ -3,7 +3,7 @@ package bjc.utils.examples.parsing; import java.util.Scanner; import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.parserutils.ShuntingYard; /** @@ -27,7 +27,7 @@ public class ShuntTester { ShuntingYard yard = new ShuntingYard<>(true); - IFunctionalList shuntedTokens = yard + IList shuntedTokens = yard .postfix(new FunctionalStringTokenizer(line) .toList((strang) -> strang), (strang) -> strang); diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/TreeConstructTest.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/TreeConstructTest.java index faeb3a6..e737b4d 100644 --- a/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/TreeConstructTest.java +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/parsing/TreeConstructTest.java @@ -10,8 +10,8 @@ import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.utils.funcdata.FunctionalMap; import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; import bjc.utils.funcdata.ITree; import bjc.utils.funcdata.Tree; import bjc.utils.funcutils.ListUtils; @@ -61,7 +61,7 @@ public class TreeConstructTest { System.out.print("Enter a expression to parse: "); String line = inputSource.nextLine(); - IFunctionalList tokens = new FunctionalStringTokenizer( + IList tokens = new FunctionalStringTokenizer( line).toList(); ShuntingYard yard = new ShuntingYard<>(true); @@ -75,7 +75,7 @@ public class TreeConstructTest { ops.add(new Pair<>(":=", ":=")); ops.add(new Pair<>("=>", "=>")); - IFunctionalList semiExpandedTokens = ListUtils + IList semiExpandedTokens = ListUtils .splitTokens(tokens, ops); ops = new LinkedList<>(); @@ -85,12 +85,12 @@ public class TreeConstructTest { ops.add(new Pair<>("[", "\\[")); ops.add(new Pair<>("]", "\\]")); - IFunctionalList fullyExpandedTokens = ListUtils + IList fullyExpandedTokens = ListUtils .deAffixTokens(semiExpandedTokens, ops); fullyExpandedTokens.removeIf((strang) -> strang.equals("")); - IFunctionalList shuntedTokens = yard + IList shuntedTokens = yard .postfix(fullyExpandedTokens, (token) -> token); System.out.println("Shunted: " + shuntedTokens.toString()); @@ -105,7 +105,7 @@ public class TreeConstructTest { return false; }; - IFunctionalMap>, ITree>> operators = new FunctionalMap<>(); + IMap>, ITree>> operators = new FunctionalMap<>(); operators.put("[", (queuedTrees) -> { return null; diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/DiabloItemGen.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/DiabloItemGen.java index 09530ba..4686643 100644 --- a/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/DiabloItemGen.java +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/DiabloItemGen.java @@ -1,7 +1,7 @@ package bjc.utils.examples.rangen; import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.gen.WeightedGrammar; /** @@ -83,7 +83,7 @@ public class DiabloItemGen { addInfixRules(); for (int i = 0; i < 100; i++) { - IFunctionalList ls = rules.generateListValues("", + IList ls = rules.generateListValues("", " "); StringBuilder sb = new StringBuilder(); diff --git a/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/RandomStringExamples.java b/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/RandomStringExamples.java index 4eaeadb..fc1724e 100644 --- a/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/RandomStringExamples.java +++ b/BJC-Utils2/src/examples/java/bjc/utils/examples/rangen/RandomStringExamples.java @@ -2,7 +2,7 @@ package bjc.utils.examples.rangen; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.gen.RandomGrammar; /** @@ -15,7 +15,7 @@ public class RandomStringExamples { private static RandomGrammar rg; private static void addRule(String rule, String... cases) { - IFunctionalList> cses = new FunctionalList<>(); + IList> cses = new FunctionalList<>(); for (String strang : cases) { cses.add(FunctionalStringTokenizer.fromString(strang) @@ -56,7 +56,7 @@ public class RandomStringExamples { ""); for (int i = 0; i < 10; i++) { - IFunctionalList ls = rg + IList ls = rg .generateListValues("", " "); StringBuilder sb = new StringBuilder(); diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java b/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java index e1a57c2..5a7f95b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java @@ -7,27 +7,33 @@ import java.util.Arrays; import java.util.Scanner; /** - * Runs a CLI interface from the provided set of streams + * Runs a CLI interface from the provided set of streams. * * @author ben * */ public class CLICommander { + /* + * The streams used for input and normal/error output + */ private InputStream input; private OutputStream output; private OutputStream error; + /* + * The command mode to start execution in + */ private ICommandMode initialMode; /** - * Create a new CLI interface powered by streams + * Create a new CLI interface powered by streams. * * @param input - * The stream to get user input from + * The stream to get user input from. * @param output - * The stream to send user output to + * The stream to send normal output to. * @param error - * The stream to send error messages to + * The stream to send error output to. */ public CLICommander(InputStream input, OutputStream output, OutputStream error) { @@ -48,32 +54,51 @@ public class CLICommander { } /** - * Run a set of commands through this commander + * Start handling commands from the given input stream. */ public void runCommands() { + // Setup output streams PrintStream normalOutput = new PrintStream(output); PrintStream errorOutput = new PrintStream(error); + /* + * Set up input streams. + * + * We're suppressing the warning because we might use the input + * stream multiple times + */ @SuppressWarnings("resource") - // We might use this stream multiple times. Don't close it Scanner inputSource = new Scanner(input); + /* + * The mode currently being used to handle commands. + * + * Used to preserve the initial mode + */ ICommandMode currentMode = initialMode; + // Process commands until we're told to stop while (currentMode != null) { - if (currentMode.useCustomPrompt()) { + /* + * Print out the command prompt, using a custom prompt if one + * is specified + */ + if (currentMode.isCustomPromptEnabled()) { normalOutput.print(currentMode.getCustomPrompt()); } else { normalOutput.print(currentMode.getName() + ">> "); } + // Read in a command String currentLine = inputSource.nextLine(); - if (currentMode.canHandleCommand(currentLine)) { + // Handle handleable commands + if (currentMode.canHandle(currentLine)) { String[] commandTokens = currentLine.split(" "); String[] commandArgs; + // Parse args if they are present if (commandTokens.length > 1) { commandArgs = Arrays.copyOfRange(commandTokens, 1, commandTokens.length); @@ -81,7 +106,8 @@ public class CLICommander { commandArgs = null; } - currentMode = currentMode.processCommand(commandTokens[0], + // Process command + currentMode = currentMode.process(commandTokens[0], commandArgs); } else { errorOutput.print( diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java index 28e0347..ad115d7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/DelegatingCommand.java @@ -1,14 +1,27 @@ package bjc.utils.cli; +/** + * A class for a command that delegates to another command + * + * @author ben + * + */ class DelegatingCommand implements ICommand { + // The command to delegate to private ICommand delegate; + /** + * Create a new command that delegates to another command + * + * @param delegate + * The command to delegate to + */ public DelegatingCommand(ICommand delegate) { this.delegate = delegate; } @Override - public ICommand createAlias() { + public ICommand aliased() { return new DelegatingCommand(delegate); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java index 529635d..1a95018 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommand.java @@ -7,7 +7,9 @@ package bjc.utils.cli; * */ public class GenericCommand implements ICommand { + // The behavior for invoking the command private ICommandHandler handler; + // The help for the command private ICommandHelp help; /** @@ -22,17 +24,16 @@ public class GenericCommand implements ICommand { */ public GenericCommand(ICommandHandler handler, String description, String help) { + if(handler == null) { + throw new NullPointerException("Command handler must not be null"); + } + this.handler = handler; this.help = new GenericHelp(description, help); } - - /** - * Create a command that is an alias to this one - * - * @return A command that is an alias to this one - */ + @Override - public ICommand createAlias() { + public ICommand aliased() { return new DelegatingCommand(this); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java index 0007616..59d3dc3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericCommandMode.java @@ -5,7 +5,7 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IMap; /** * A general command mode, with a customizable set of commands @@ -18,18 +18,26 @@ import bjc.utils.funcdata.IFunctionalMap; * */ public class GenericCommandMode implements ICommandMode { - private IFunctionalMap commandHandlers; - private IFunctionalMap defaultHandlers; + /* + * Contains the commands this mode handles + */ + private IMap commandHandlers; + private IMap defaultHandlers; - private IFunctionalMap helpTopics; + // Contains help topics without an associated command + private IMap helpTopics; + // The action to execute upon encountering an unknown command private BiConsumer unknownCommandHandler; + // The functions to use for input/output private Consumer errorOutput; private Consumer normalOutput; + // The name of this command mode, or null if it is unnamed private String modeName; + // The custom prompt to use, or null if none is specified private String customPrompt; /** @@ -45,6 +53,7 @@ public class GenericCommandMode implements ICommandMode { this.normalOutput = normalOutput; this.errorOutput = errorOutput; + // Initialize handler maps so that they sort in alphabetical order commandHandlers = new FunctionalMap<>(new TreeMap<>()); defaultHandlers = new FunctionalMap<>(new TreeMap<>()); helpTopics = new FunctionalMap<>(new TreeMap<>()); @@ -81,12 +90,13 @@ public class GenericCommandMode implements ICommandMode { + aliasName + "' to a command with a bound handler"); } else { ICommand aliasedCommand; + if (defaultHandlers.containsKey(commandName)) { aliasedCommand = defaultHandlers.get(commandName) - .createAlias(); + .aliased(); } else { aliasedCommand = commandHandlers.get(commandName) - .createAlias(); + .aliased(); } commandHandlers.put(aliasName, aliasedCommand); @@ -97,7 +107,7 @@ public class GenericCommandMode implements ICommandMode { * Add a command to this command mode * * @param command - * The command to add + * The name of the command to add * @param handler * The handler to use for the specified command * @@ -110,7 +120,7 @@ public class GenericCommandMode implements ICommandMode { throw new NullPointerException("Command must not be null"); } else if (handler == null) { throw new NullPointerException("Handler must not be null"); - } else if (canHandleCommand(command)) { + } else if (canHandle(command)) { throw new IllegalArgumentException("Command " + command + " already has a handler registered"); } else { @@ -123,22 +133,28 @@ public class GenericCommandMode implements ICommandMode { * * @param topicName * The name of the topic - * @param help + * @param topic * The contents of the topic */ - public void addHelpTopic(String topicName, ICommandHelp help) { - helpTopics.put(topicName, help); + public void addHelpTopic(String topicName, ICommandHelp topic) { + helpTopics.put(topicName, topic); } + // ------------------------------------------------------------------------- + /* + * Default command builders + */ + // ------------------------------------------------------------------------- + private GenericCommand buildAliasCommand() { return new GenericCommand((args) -> { doAliasCommands(args); return this; }, "alias\tAlias one command to another", - "alias gives a command another name it can be invoked by. It is invoked" - + " with two arguments, the name of the command to alias" - + ", and the alias to give that command."); + "Gives a command another name it can be invoked by. Invoke" + + " with two arguments: the name of the command to alias" + + "followed by the name of the alias to give that command."); } private GenericCommand buildClearCommands() { @@ -148,8 +164,8 @@ public class GenericCommandMode implements ICommandMode { return this; }, "clear\tClear the screen", - "clear clears the screen of all the text on it," - + " and prepares a fresh prompt."); + "Clears the screen of all the text on it," + + " and prints a new prompt."); } private GenericCommand buildExitCommand() { @@ -158,9 +174,9 @@ public class GenericCommandMode implements ICommandMode { "ERROR: This console doesn't support auto-exiting"); return this; - }, "exit\tExit the game", - "exit first prompts the user to make sure they want to exit," - + " and if they affirm it, it quits"); + }, "exit\tExit the console", + "First prompts the user to make sure they want to exit," + + " and if they affirm it, it immediately exits"); } private GenericCommand buildHelpCommand() { @@ -175,10 +191,10 @@ public class GenericCommandMode implements ICommandMode { return this; }, "help\tConsult the help system", - "help consults the internal help system." - + " It can be invoked in two ways. Invoking it with no arguments" - + " causes it to print out all the topics you can ask for details on," - + " while invoking it with the name of a topic will print the entry" + "Consults the internal help system." + + " Invoked in two different ways. Invoking with no arguments" + + " causes all the topics you can ask for details on to be list," + + " while invoking with the name of a topic will print the entry" + " for that topic"); } @@ -193,11 +209,17 @@ public class GenericCommandMode implements ICommandMode { } @Override - public boolean canHandleCommand(String command) { + public boolean canHandle(String command) { return commandHandlers.containsKey(command) || defaultHandlers.containsKey(command); } + // ------------------------------------------------------------------------- + /* + * Implement default commands + */ + // ------------------------------------------------------------------------- + private void doAliasCommands(String[] args) { if (args.length != 2) { errorOutput.accept("ERROR: Alias requires two arguments. " @@ -206,10 +228,10 @@ public class GenericCommandMode implements ICommandMode { String commandName = args[0]; String aliasName = args[1]; - if (!canHandleCommand(commandName)) { + if (!canHandle(commandName)) { errorOutput.accept("ERROR: '" + commandName + "' is not a valid command."); - } else if (canHandleCommand(aliasName)) { + } else if (canHandle(aliasName)) { errorOutput.accept("ERROR: Cannot overwrite command '" + aliasName + "'"); } else { @@ -310,7 +332,7 @@ public class GenericCommandMode implements ICommandMode { } @Override - public ICommandMode processCommand(String command, String[] args) { + public ICommandMode process(String command, String[] args) { normalOutput.accept("\n"); if (defaultHandlers.containsKey(command)) { @@ -363,7 +385,8 @@ public class GenericCommandMode implements ICommandMode { * Set the handler to use for unknown commands * * @param handler - * The handler to use for unknown commands + * The handler to use for unknown commands, or null to throw + * on unknown commands */ public void setUnknownCommandHandler( BiConsumer handler) { @@ -393,7 +416,7 @@ public class GenericCommandMode implements ICommandMode { } @Override - public boolean useCustomPrompt() { + public boolean isCustomPromptEnabled() { return customPrompt != null; } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java index f2fb146..8742b5d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GenericHelp.java @@ -7,6 +7,7 @@ package bjc.utils.cli; * */ public class GenericHelp implements ICommandHelp { + // The strings for this help topic private String summary; private String description; @@ -16,15 +17,25 @@ public class GenericHelp implements ICommandHelp { * @param summary * The summary of this help topic * @param description - * The description of this help topic + * The description of this help topic, or null if this help + * topic doesn't have a more detailed description */ public GenericHelp(String summary, String description) { + if (summary == null) { + throw new NullPointerException( + "Help summary must be non-null"); + } + this.summary = summary; this.description = description; } @Override public String getDescription() { + if (description == null) { + return summary; + } + return description; } diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java index ff15a37..a72ecdf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommand.java @@ -12,7 +12,7 @@ public interface ICommand { * * @return A command that serves as an alias to this one */ - public ICommand createAlias(); + public ICommand aliased(); /** * Get the handler that executes this command diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java index f806676..3d451a7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java @@ -10,11 +10,12 @@ import java.util.function.Function; */ public interface ICommandHandler extends Function { /** - * Handle the command this handler handles + * Execute this command * * @param args * The arguments for this command - * @return The command mode to go to after this command + * @return The command mode to switch to after this command, or null to + * stop executing commands */ public default ICommandMode handle(String[] args) { return this.apply(args); diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java index d475335..bd81537 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHelp.java @@ -8,18 +8,18 @@ package bjc.utils.cli; */ public interface ICommandHelp { /** - * Get the description of a command + * Get the description of a command. * * @return The description of a command */ public String getDescription(); /** - * Get the summary line for a command - * - * Used for 'help commands' which gives the user a brief idea what all - * the commands do + * Get the summary line for a command. * + * A summary line should consist of a string of the following format + * "\t" + * where anything in angle brackets should be filled in. * @return The summary line line for a command */ public String getSummary(); diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java index 48a741c..f60e571 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java @@ -16,7 +16,7 @@ public interface ICommandMode { * @return Whether or not this mode can handle the command. It is * assumed not by default */ - public default boolean canHandleCommand(String command) { + public default boolean canHandle(String command) { return false; }; @@ -53,7 +53,7 @@ public interface ICommandMode { * @return The command mode to use for the next command. Defaults to * returning this, and doing nothing else */ - public default ICommandMode processCommand(String command, + public default ICommandMode process(String command, String[] args) { return this; } @@ -63,7 +63,7 @@ public interface ICommandMode { * * @return Whether or not this mode uses a custom prompt */ - public default boolean useCustomPrompt() { + public default boolean isCustomPromptEnabled() { return false; } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java index 9429dde..ab48c9b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java @@ -10,19 +10,19 @@ public class ComponentDescription implements IDescribedComponent { private static void sanityCheckArgs(String name, String author, String description, int version) { if (name == null) { - throw new IllegalArgumentException( - "Component name can't be null"); + throw new NullPointerException("Component name can't be null"); } else if (author == null) { - throw new IllegalArgumentException( + throw new NullPointerException( "Component author can't be null"); } else if (description == null) { - throw new IllegalArgumentException( + throw new NullPointerException( "Component description can't be null"); - } else if (version < 0) { + } else if (version <= 0) { throw new IllegalArgumentException( "Component version must be greater than 0"); } } + /** * The author of the component */ @@ -53,8 +53,7 @@ public class ComponentDescription implements IDescribedComponent { * @param version * The version of the component * @throws IllegalArgumentException - * thrown if name, author or description is null, or if - * version is less than 1 + * thrown if version is less than 1 */ public ComponentDescription(String name, String author, String description, int version) { diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java index be0a65b..b35c77b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java @@ -1,13 +1,11 @@ package bjc.utils.components; import java.io.InputStream; -import java.util.function.BiConsumer; -import bjc.utils.exceptions.PragmaFormatException; -import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcutils.ListUtils; import bjc.utils.parserutils.RuleBasedConfigReader; +import static bjc.utils.parserutils.RuleBasedReaderPragmas.*; + /** * Read a component description from a file * @@ -15,8 +13,10 @@ import bjc.utils.parserutils.RuleBasedConfigReader; * */ public class ComponentDescriptionFileParser { + // The reader used to read in component descriptions private static RuleBasedConfigReader reader; + // Initialize the reader and its pragmas static { // This reader works entirely off of pragmas, so no need to handle // rules @@ -31,19 +31,6 @@ public class ComponentDescriptionFileParser { setupReaderPragmas(); } - private static BiConsumer buildStringCollapserPragma( - String pragmaName) { - return (tokenizer, state) -> { - if (!tokenizer.hasMoreTokens()) { - throw new PragmaFormatException("Pragma " + pragmaName - + " requires one string argument"); - } - - state.setName(ListUtils - .collapseTokens(tokenizer.toList((strang) -> strang))); - }; - } - /** * Parse a component description from a stream * @@ -51,42 +38,29 @@ public class ComponentDescriptionFileParser { * The stream to parse from * @return The description parsed from the stream */ - public static ComponentDescription fromStream( - InputStream inputSource) { + public static ComponentDescription + fromStream(InputStream inputSource) { ComponentDescriptionState readState = reader .fromStream(inputSource, new ComponentDescriptionState()); return readState.toDescription(); } + /* + * Create all the pragmas the reader needs to function + */ private static void setupReaderPragmas() { - reader.addPragma("name", buildStringCollapserPragma("name")); + reader.addPragma("name", buildStringCollapser("name", + (name, state) -> state.setName(name))); - reader.addPragma("author", buildStringCollapserPragma("author")); + reader.addPragma("author", buildStringCollapser("author", + (author, state) -> state.setAuthor(author))); reader.addPragma("description", - buildStringCollapserPragma("description")); + buildStringCollapser("description", (description, + state) -> state.setDescription(description))); - reader.addPragma("version", (tokenizer, state) -> { - if (!tokenizer.hasMoreTokens()) { - throw new PragmaFormatException( - "Pragma version requires one integer argument"); - } - - String token = tokenizer.nextToken(); - - try { - state.setVersion(Integer.parseInt(token)); - } catch (NumberFormatException nfex) { - PragmaFormatException pfex = new PragmaFormatException( - "Argument " + token - + " to version pragma isn't a valid integer. " - + "This pragma requires a integer argument"); - - pfex.initCause(nfex); - - throw pfex; - } - }); + reader.addPragma("version", buildInteger("version", + (version, state) -> state.setVersion(version))); } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java index 199009c..a17a70b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java @@ -7,12 +7,16 @@ package bjc.utils.components; * */ public class ComponentDescriptionState { + // Tentative name of this component private String name; + // Tentative description of this componet private String description; + // Tentative author of this component private String author; + // Tentative version of this component private int version; /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java index e05afc0..182549c 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java @@ -6,42 +6,36 @@ import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.function.BiPredicate; import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; import bjc.utils.data.IHolder; import bjc.utils.data.Identity; -import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; import bjc.utils.funcutils.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * A component repository that loads its components from files in a * directory * * @author ben * - * @param + * @param * The type of component being read in */ -public class FileComponentRepository - implements IComponentRepository { +public class FileComponentRepository + implements IComponentRepository { + // The logger to use for storing data about this class + private static final Logger CLASS_LOGGER = + Logger.getLogger("FileComponentRepository"); - private static final Logger CLASS_LOGGER = LoggerFactory - .getLogger(FileComponentRepository.class); + // The internal storage of components + private IMap components; - /** - * The internal storage of components - */ - private IFunctionalMap components; - - /** - * The path that all the components came from - */ - private Path sourceDirectory; + // The path that all the components came from + private Path sourceDirectory; /** * Create a new component repository sourcing components from files in @@ -57,33 +51,47 @@ public class FileComponentRepository * The function to use to convert files to components */ public FileComponentRepository(File directory, - Function componentReader) { + Function componentReader) { + // Make sure we have valid arguments if (!directory.isDirectory()) { throw new IllegalArgumentException("File " + directory + " is not a directory.\n" + "Components can only be read from a directory"); + } else if (componentReader == null) { + throw new NullPointerException( + "Component reader must not be null"); } + // Initialize our fields components = new FunctionalMap<>(); - sourceDirectory = directory.toPath().toAbsolutePath(); + // Marker for making sure we don't skip the parent IHolder isFirstDir = new Identity<>(true); - BiPredicate firstLevelTraverser = (pth, - attr) -> { - if (attr.isDirectory() && !isFirstDir.getValue()) { - // Don't skip the first directory, that's the - // parent - isFirstDir.replace(false); - // Skip directories, they probably have - // component - return false; - } - - return true; - }; - + // Predicate to use to traverse all the files in a directory, but + // not recurse into sub-directories + BiPredicate firstLevelTraverser = + (pth, attr) -> { + if (attr.isDirectory() && !isFirstDir.getValue()) { + + /* + * Skip directories, they probably have component + * support files. + */ + return false; + } + + /* + * Don't skip the first directory, that's the parent + * directory + */ + isFirstDir.replace(false); + + return true; + }; + + // Try reading components try { FileUtils.traverseDirectory(sourceDirectory, firstLevelTraverser, (pth, attr) -> { @@ -93,28 +101,23 @@ public class FileComponentRepository return true; }); } catch (IOException ioex) { - CLASS_LOGGER.warn("Error found reading component from file.", - ioex); + CLASS_LOGGER.log(Level.WARNING, ioex, + () -> "Error found reading component from file."); } } @Override - public E getComponentByName(String name) { + public ComponentType getByName(String name) { return components.get(name); } @Override - public IFunctionalList getComponentList() { - IFunctionalList returnedList = new FunctionalList<>(); - - components - .forEach((name, component) -> returnedList.add(component)); - - return returnedList; + public IList getList() { + return components.valueList(); } @Override - public IFunctionalMap getComponents() { + public IMap getAll() { return components; } @@ -123,26 +126,38 @@ public class FileComponentRepository return "Components read from directory " + sourceDirectory + "."; } - private void loadComponent(Function componentReader, + /* + * Load a component from a file + */ + private void loadComponent( + Function componentReader, Path pth) { try { - E component = componentReader.apply(pth.toFile()); + // Try to load the component + ComponentType component = componentReader.apply(pth.toFile()); if (component == null) { throw new NullPointerException( "Component reader read null component"); } else if (!components.containsKey(component.getName())) { - components.put(component.getName(), component); + // We only care about the latest version of a component + ComponentType oldComponent = + components.put(component.getName(), component); + + if (oldComponent.getVersion() > component.getVersion()) { + components.put(oldComponent.getName(), oldComponent); + } } else { - CLASS_LOGGER.warn("Found a duplicate component.\n" + CLASS_LOGGER.warning("Found a duplicate component.\n" + "Multiple versions of the same component are not currently supported.\n" - + "The component" + component - + " will not be registered ."); + + "Only the latest version of the component" + + component + " will be registered ."); } } catch (Exception ex) { - CLASS_LOGGER.warn("Error found reading component from file " - + pth.toString() - + ". This component will not be loaded", ex); + CLASS_LOGGER.log(Level.WARNING, ex, + () -> "Error found reading component from file " + + pth.toString() + + ". This component will not be loaded"); } } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java index 6780f2e..2644276 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java @@ -1,17 +1,18 @@ package bjc.utils.components; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; /** - * A collection of implementations of {@link IDescribedComponent} + * A collection of implementations of a particular type of + * {@link IDescribedComponent} * * @author ben * - * @param + * @param * The type of components contained in this repository */ -public interface IComponentRepository { +public interface IComponentRepository { /** * Get a component with a specific name * @@ -20,15 +21,15 @@ public interface IComponentRepository { * @return The named component, or null if no component with that name * exists */ - public E getComponentByName(String name); + public ComponentType getByName(String name); /** * Get a list of all the registered componets * * @return A list of all the registered components */ - public default IFunctionalList getComponentList() { - return getComponents().valueList(); + public default IList getList() { + return getAll().valueList(); } /** @@ -37,7 +38,7 @@ public interface IComponentRepository { * @return A map from component name to component, containing all of * the components in the repositories */ - public IFunctionalMap getComponents(); + public IMap getAll(); /** * Get the source from which these components came diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java index 9ab3c05..1256e31 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundLazy.java @@ -5,20 +5,42 @@ import java.util.function.Supplier; import java.util.function.UnaryOperator; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; +/* + * Implements a lazy holder that has been bound + */ class BoundLazy implements IHolder { + /* + * The old value + */ private Supplier> oldSupplier; + /* + * The function to use to transform the old value into a new value + */ private Function> binder; + /* + * The bound value being held + */ private IHolder boundHolder; + /* + * Whether the bound value has been actualized or not + */ private boolean holderBound; - private IFunctionalList> actions = new FunctionalList<>(); + /* + * Transformations currently pending on the bound value + */ + private IList> actions = + new FunctionalList<>(); + /* + * Create a new bound lazy value + */ public BoundLazy(Supplier> supp, Function> binder) { oldSupplier = supp; @@ -26,19 +48,31 @@ class BoundLazy } @Override - public IHolder bind( - Function> bindr) { - IFunctionalList> pendingActions = new FunctionalList<>(); - + public IHolder + bind(Function> bindr) { + /* + * Prepare a list of pending actions + */ + IList> pendingActions = + new FunctionalList<>(); actions.forEach(pendingActions::add); + /* + * Create the new supplier of a value + */ Supplier> typeSupplier = () -> { IHolder oldHolder = boundHolder; + /* + * Bind the value if it hasn't been bound before + */ if (!holderBound) { oldHolder = oldSupplier.get().unwrap(binder); } + /* + * Apply all the pending actions + */ return pendingActions.reduceAux(oldHolder, (action, state) -> { return state.transform(action); }, (value) -> value); @@ -48,15 +82,18 @@ class BoundLazy } @Override - public IHolder map( - Function mapper) { - IFunctionalList> pendingActions = new FunctionalList<>(); - + public IHolder + map(Function mapper) { + // Prepare a list of pending actions + IList> pendingActions = + new FunctionalList<>(); actions.forEach(pendingActions::add); + // Prepare the new supplier Supplier typeSupplier = () -> { IHolder oldHolder = boundHolder; + // Bound the value if it hasn't been bound if (!holderBound) { oldHolder = oldSupplier.get().unwrap(binder); } @@ -80,16 +117,16 @@ class BoundLazy } @Override - public IHolder transform( - UnaryOperator transformer) { + public IHolder + transform(UnaryOperator transformer) { actions.add(transformer); return this; } @Override - public UnwrappedType unwrap( - Function unwrapper) { + public UnwrappedType + unwrap(Function unwrapper) { if (!holderBound) { boundHolder = oldSupplier.get().unwrap(binder::apply); } @@ -98,8 +135,8 @@ class BoundLazy } @Override - public Function> lift( - Function func) { + public Function> + lift(Function func) { return (val) -> { return new Lazy<>(func.apply(val)); }; diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java index fcb62f6..85ec8f6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/BoundListHolder.java @@ -3,20 +3,20 @@ package bjc.utils.data; import java.util.function.Function; import java.util.function.UnaryOperator; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; class BoundListHolder implements IHolder { - private IFunctionalList> heldHolders; + private IList> heldHolders; public BoundListHolder( - IFunctionalList> toHold) { + IList> toHold) { heldHolders = toHold; } @Override public IHolder bind( Function> binder) { - IFunctionalList> boundHolders = heldHolders + IList> boundHolders = heldHolders .map((containedHolder) -> { return containedHolder.bind(binder); }); @@ -27,7 +27,7 @@ class BoundListHolder implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList> mappedHolders = heldHolders + IList> mappedHolders = heldHolders .map((containedHolder) -> { return containedHolder.map(mapper); }); diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java index 62b0bb0..fb1a517 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Lazy.java @@ -5,7 +5,7 @@ import java.util.function.Supplier; import java.util.function.UnaryOperator; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * A holder that holds a means to create a value, but doesn't actually @@ -18,7 +18,7 @@ import bjc.utils.funcdata.IFunctionalList; public class Lazy implements IHolder { private Supplier valueSupplier; - private IFunctionalList> actions = new FunctionalList<>(); + private IList> actions = new FunctionalList<>(); private boolean valueMaterialized; @@ -49,7 +49,7 @@ public class Lazy implements IHolder { } private Lazy(Supplier supp, - IFunctionalList> pendingActions) { + IList> pendingActions) { valueSupplier = supp; actions = pendingActions; @@ -58,7 +58,7 @@ public class Lazy implements IHolder { @Override public IHolder bind( Function> binder) { - IFunctionalList> pendingActions = new FunctionalList<>(); + IList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -78,7 +78,7 @@ public class Lazy implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList> pendingActions = new FunctionalList<>(); + IList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java index 8dc33d3..03765ed 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/ListHolder.java @@ -4,7 +4,7 @@ import java.util.function.Function; import java.util.function.UnaryOperator; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * A holder that represents a set of non-deterministic computations @@ -15,9 +15,9 @@ import bjc.utils.funcdata.IFunctionalList; * The type of contained value */ public class ListHolder implements IHolder { - private IFunctionalList heldValues; + private IList heldValues; - private ListHolder(IFunctionalList toHold) { + private ListHolder(IList toHold) { heldValues = toHold; } @@ -41,7 +41,7 @@ public class ListHolder implements IHolder { @Override public IHolder bind( Function> binder) { - IFunctionalList> boundValues = heldValues + IList> boundValues = heldValues .map(binder); return new BoundListHolder<>(boundValues); @@ -50,7 +50,7 @@ public class ListHolder implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList mappedValues = heldValues.map(mapper); + IList mappedValues = heldValues.map(mapper); return new ListHolder<>(mappedValues); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java index 0d2c1b0..eb421bc 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java @@ -15,7 +15,9 @@ import java.util.function.Function; */ public class Pair implements IPair { + // The left value private LeftType leftValue; + // The right value private RightType rightValue; /** @@ -40,24 +42,40 @@ public class Pair @Override public IPair bind( BiFunction> binder) { + if (binder == null) { + throw new NullPointerException("Binder must not be null."); + } + return binder.apply(leftValue, rightValue); } @Override public IPair bindLeft( Function> leftBinder) { + if (leftBinder == null) { + throw new NullPointerException("Binder must not be null"); + } + return leftBinder.apply(leftValue); } @Override public IPair bindRight( Function> rightBinder) { + if (rightBinder == null) { + throw new NullPointerException("Binder must not be null"); + } + return rightBinder.apply(rightValue); } @Override public MergedType merge(BiFunction merger) { + if (merger == null) { + throw new NullPointerException("Merger must not be null"); + } + return merger.apply(leftValue, rightValue); } @@ -70,12 +88,20 @@ public class Pair @Override public IPair mapLeft(Function mapper) { + if (mapper == null) { + throw new NullPointerException("Mapper must not be null"); + } + return new Pair<>(mapper.apply(leftValue), rightValue); } @Override public IPair mapRight(Function mapper) { + if (mapper == null) { + throw new NullPointerException("Mapper must not be null"); + } + return new Pair<>(leftValue, mapper.apply(rightValue)); } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java index 9776961..378a4a0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ExtendedMap.java @@ -7,13 +7,13 @@ import java.util.function.Function; import bjc.utils.funcutils.ListUtils; class ExtendedMap - implements IFunctionalMap { - private IFunctionalMap delegate; + implements IMap { + private IMap delegate; - private IFunctionalMap store; + private IMap store; - public ExtendedMap(IFunctionalMap delegate, - IFunctionalMap store) { + public ExtendedMap(IMap delegate, + IMap store) { this.delegate = delegate; this.store = store; } @@ -28,7 +28,7 @@ class ExtendedMap } @Override - public IFunctionalMap extend() { + public IMap extend() { return new ExtendedMap<>(this, new FunctionalMap<>()); } @@ -68,12 +68,12 @@ class ExtendedMap } @Override - public IFunctionalList keyList() { + public IList keyList() { return ListUtils.mergeLists(store.keyList(), delegate.keyList()); } @Override - public IFunctionalMap mapValues( + public IMap mapValues( Function transformer) { return new TransformedValueMap<>(this, transformer); } @@ -89,7 +89,7 @@ class ExtendedMap } @Override - public IFunctionalList valueList() { + public IList valueList() { return ListUtils.mergeLists(store.valueList(), delegate.valueList()); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java index 8579693..638ad7e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java @@ -27,7 +27,7 @@ import bjc.utils.data.Pair; * @param * The type in this list */ -public class FunctionalList implements Cloneable, IFunctionalList { +public class FunctionalList implements Cloneable, IList { /** * The list used as a backing store */ @@ -148,8 +148,8 @@ public class FunctionalList implements Cloneable, IFunctionalList { * @return A list */ @Override - public IFunctionalList clone() { - IFunctionalList clonedList = new FunctionalList<>(); + public IList clone() { + IList clonedList = new FunctionalList<>(); for (E element : wrappedList) { clonedList.add(element); @@ -166,8 +166,8 @@ public class FunctionalList implements Cloneable, IFunctionalList { * IFunctionalList, java.util.function.BiFunction) */ @Override - public IFunctionalList combineWith( - IFunctionalList rightList, + public IList combineWith( + IList rightList, BiFunction itemCombiner) { if (rightList == null) { throw new NullPointerException( @@ -176,7 +176,7 @@ public class FunctionalList implements Cloneable, IFunctionalList { throw new NullPointerException("Combiner must not be null"); } - IFunctionalList returnedList = new FunctionalList<>(); + IList returnedList = new FunctionalList<>(); // Get the iterator for the other list Iterator rightIterator = rightList.toIterable().iterator(); @@ -227,17 +227,17 @@ public class FunctionalList implements Cloneable, IFunctionalList { * Function) */ @Override - public IFunctionalList flatMap( - Function> elementExpander) { + public IList flatMap( + Function> elementExpander) { if (elementExpander == null) { throw new NullPointerException("Expander must not be null"); } - IFunctionalList returnedList = new FunctionalList<>( + IList returnedList = new FunctionalList<>( this.wrappedList.size()); forEach(element -> { - IFunctionalList expandedElement = elementExpander + IList expandedElement = elementExpander .apply(element); if (expandedElement == null) { @@ -320,12 +320,12 @@ public class FunctionalList implements Cloneable, IFunctionalList { * Predicate) */ @Override - public IFunctionalList getMatching(Predicate matchPredicate) { + public IList getMatching(Predicate matchPredicate) { if (matchPredicate == null) { throw new NullPointerException("Predicate must not be null"); } - IFunctionalList returnedList = new FunctionalList<>(); + IList returnedList = new FunctionalList<>(); wrappedList.forEach((element) -> { if (matchPredicate.test(element)) { @@ -361,7 +361,7 @@ public class FunctionalList implements Cloneable, IFunctionalList { * Check if a partition has room for another item */ private Boolean isPartitionFull(int numberPerPartition, - IHolder> currentPartition) { + IHolder> currentPartition) { return currentPartition.unwrap( (partition) -> partition.getSize() >= numberPerPartition); } @@ -373,12 +373,12 @@ public class FunctionalList implements Cloneable, IFunctionalList { * bjc.utils.funcdata.IFunctionalList#map(java.util.function.Function) */ @Override - public IFunctionalList map(Function elementTransformer) { + public IList map(Function elementTransformer) { if (elementTransformer == null) { throw new NullPointerException("Transformer must be not null"); } - IFunctionalList returnedList = new FunctionalList<>( + IList returnedList = new FunctionalList<>( this.wrappedList.size()); forEach(element -> { @@ -396,8 +396,8 @@ public class FunctionalList implements Cloneable, IFunctionalList { * IFunctionalList) */ @Override - public IFunctionalList> pairWith( - IFunctionalList rightList) { + public IList> pairWith( + IList rightList) { return combineWith(rightList, Pair::new); } @@ -407,7 +407,7 @@ public class FunctionalList implements Cloneable, IFunctionalList { * @see bjc.utils.funcdata.IFunctionalList#partition(int) */ @Override - public IFunctionalList> partition( + public IList> partition( int numberPerPartition) { if (numberPerPartition < 1 || numberPerPartition > wrappedList.size()) { @@ -416,10 +416,10 @@ public class FunctionalList implements Cloneable, IFunctionalList { + wrappedList.size()); } - IFunctionalList> returnedList = new FunctionalList<>(); + IList> returnedList = new FunctionalList<>(); // The current partition being filled - IHolder> currentPartition = new Identity<>( + IHolder> currentPartition = new Identity<>( new FunctionalList<>()); this.forEach((element) -> { @@ -559,7 +559,7 @@ public class FunctionalList implements Cloneable, IFunctionalList { } @Override - public IFunctionalList tail() { + public IList tail() { return new FunctionalList<>(wrappedList.subList(1, getSize())); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java index fb8bb81..0002a58 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java @@ -9,7 +9,7 @@ import java.util.function.Function; import bjc.utils.data.IPair; /** - * Basic implementation of {@link IFunctionalMap} + * Basic implementation of {@link IMap} * * @author ben * @@ -19,7 +19,7 @@ import bjc.utils.data.IPair; * The type of the map's values */ public class FunctionalMap - implements IFunctionalMap { + implements IMap { private Map wrappedMap; /** @@ -71,7 +71,7 @@ public class FunctionalMap } @Override - public IFunctionalMap extend() { + public IMap extend() { return new ExtendedMap<>(this, new FunctionalMap<>()); } @@ -115,7 +115,7 @@ public class FunctionalMap } @Override - public IFunctionalList keyList() { + public IList keyList() { FunctionalList keys = new FunctionalList<>(); wrappedMap.keySet().forEach((key) -> { @@ -132,7 +132,7 @@ public class FunctionalMap * Function) */ @Override - public IFunctionalMap mapValues( + public IMap mapValues( Function transformer) { if (transformer == null) { throw new NullPointerException("Transformer must not be null"); @@ -166,7 +166,7 @@ public class FunctionalMap } @Override - public IFunctionalList valueList() { + public IList valueList() { FunctionalList values = new FunctionalList<>(); wrappedMap.values().forEach((value) -> { diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java index aa6fca3..18617d1 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java @@ -140,7 +140,7 @@ public class FunctionalStringTokenizer { * * @return This tokenizer, converted into a list of strings */ - public IFunctionalList toList() { + public IList toList() { return toList((String element) -> element); } @@ -155,13 +155,13 @@ public class FunctionalStringTokenizer { * The function to use to convert tokens. * @return A list containing all of the converted tokens. */ - public IFunctionalList toList( + public IList toList( Function tokenTransformer) { if (tokenTransformer == null) { throw new NullPointerException("Transformer must not be null"); } - IFunctionalList returnList = new FunctionalList<>(); + IList returnList = new FunctionalList<>(); // Add each token to the list after transforming it forEachToken(token -> { diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java deleted file mode 100644 index 5327dbe..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalList.java +++ /dev/null @@ -1,350 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.Comparator; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Predicate; - -import bjc.utils.data.IPair; - -/** - * A wrapper over another list that provides eager functional operations - * over it. Differs from a stream in every way except for the fact that - * they both provide functional operations. - * - * NOTE: The indications of complexity for methods assume that the backing - * list has performance on the order of an array - * - * @author ben - * - * @param - * The type in this list - */ -public interface IFunctionalList { - - /** - * Add an item to this list - * - * Takes O(1) time. - * - * @param item - * The item to add to this list. - * @return Whether the item was added to the list succesfully. - */ - boolean add(ContainedType item); - - /** - * Check if all of the elements of this list match the specified - * predicate. - * - * Takes O(f * p(n)) time on average, where f is defined as the average - * number of elements in a list until the predicate returns false, and - * p is the average running time of the predicate - * - * @param matchPredicate - * The predicate to use for checking. - * @return Whether all of the elements of the list match the specified - * predicate. - */ - boolean allMatch(Predicate matchPredicate); - - /** - * Check if any of the elements in this list match the specified list. - * - * Takes O(f * p(n)) time on average, where f is defined as the average - * number of elements in a list until the predicate returns true, and p - * is the average running time of the predicate - * - * @param matchPredicate - * The predicate to use for checking. - * @return Whether any element in the list matches the provided - * predicate. - */ - boolean anyMatch(Predicate matchPredicate); - - /** - * Combine this list with another one into a new list and merge the - * results. Works sort of like a combined zip/map over resulting pairs. - * Does not change the underlying list. - * - * NOTE: The returned list will have the length of the shorter of this - * list and the combined one. - * - * Takes O(q * c(q)), where q is defined as the length of the shorter - * of this list and the provided one, and c is the running time of the - * combiner. - * - * @param - * The type of the second list - * @param - * The type of the combined list - * - * @param rightList - * The list to combine with - * @param itemCombiner - * The function to use for combining element pairs. - * @return A new list containing the merged pairs of lists. - */ - IFunctionalList combineWith( - IFunctionalList rightList, - BiFunction itemCombiner); - - /** - * Check if the list contains the specified item - * - * Takes O(n) time, assuming object compare in constant time. - * - * @param item - * The item to see if it is contained - * @return Whether or not the specified item is in the list - */ - boolean contains(ContainedType item); - - /** - * Get the first element in the list - * - * Takes O(1) time - * - * @return The first element in this list. - */ - ContainedType first(); - - /** - * Apply a function to each member of the list, then flatten the - * results. Does not change the underlying list. - * - * Takes O(n * m) time, where m is the average number of elements in - * the returned list. - * - * @param - * The type of the flattened list - * - * @param elementExpander - * The function to apply to each member of the list. - * @return A new list containing the flattened results of applying the - * provided function. - */ - IFunctionalList flatMap( - Function> elementExpander); - - /** - * Apply a given action for each member of the list - * - * Takes O(n * f(n)) time, where n is the length of the list, and f is - * the running time of the action. - * - * @param action - * The action to apply to each member of the list. - */ - void forEach(Consumer action); - - /** - * Apply a given function to each element in the list and its index. - * - * Takes O(n * f(n)) time, where n is the length of the list, and f is - * the running time of the action. - * - * @param indexedAction - * The function to apply to each element in the list and its - * index. - */ - void forEachIndexed(BiConsumer indexedAction); - - /** - * Retrieve a value in the list by its index. - * - * Takes O(1) time. - * - * @param index - * The index to retrieve a value from. - * @return The value at the specified index in the list. - */ - ContainedType getByIndex(int index); - - /** - * Retrieve a list containing all elements matching a predicate - * - * Takes O(n) time, where n is the number of elements in the list - * - * @param matchPredicate - * The predicate to match by - * @return A list containing all elements that match the predicate - */ - IFunctionalList getMatching( - Predicate matchPredicate); - - /** - * Retrieve the size of the wrapped list - * - * @return The size of the wrapped list - */ - int getSize(); - - /** - * Check if this list is empty. - * - * @return Whether or not this list is empty. - */ - boolean isEmpty(); - - /** - * Create a new list by applying the given function to each element in - * the list. Does not change the underlying list. - * - * @param - * The type of the transformed list - * - * @param elementTransformer - * The function to apply to each element in the list - * @return A new list containing the mapped elements of this list. - */ - IFunctionalList map( - Function elementTransformer); - - /** - * Zip two lists into a list of pairs - * - * @param - * The type of the second list - * - * @param rightList - * The list to use as the left side of the pair - * @return A list containing pairs of this element and the specified - * list - */ - IFunctionalList> pairWith( - IFunctionalList rightList); - - /** - * Partition this list into a list of sublists - * - * @param numberPerPartition - * The size of elements to put into each one of the sublists - * @return A list partitioned into partitions of size nPerPart - */ - IFunctionalList> partition( - int numberPerPartition); - - /** - * Prepend an item to the list - * - * @param item - * The item to prepend to the list - */ - void prepend(ContainedType item); - - /** - * Select a random item from this list, using the provided random - * number generator. - * - * @param rnd - * The random number generator to use. - * @return A random element from this list. - */ - ContainedType randItem(Function rnd); - - /** - * Select a random item from the list, using a default random number - * generator - * - * @return A random item from the list - */ - default ContainedType randItem() { - return randItem((num) -> (int) (Math.random() * num)); - } - - /** - * Reduce this list to a single value, using a accumulative approach. - * - * @param - * The in-between type of the values - * @param - * The final value type - * - * @param initialValue - * The initial value of the accumulative state. - * @param stateAccumulator - * The function to use to combine a list element with the - * accumulative state. - * @param resultTransformer - * The function to use to convert the accumulative state - * into a final result. - * @return A single value condensed from this list and transformed into - * its final state. - */ - ReducedType reduceAux(StateType initialValue, - BiFunction stateAccumulator, - Function resultTransformer); - - /** - * Remove all elements that match a given predicate - * - * @param removePredicate - * The predicate to use to determine elements to delete - * @return Whether there was anything that satisfied the predicate - */ - boolean removeIf(Predicate removePredicate); - - /** - * Remove all parameters that match a given parameter - * - * @param desiredElement - * The object to remove all matching copies of - */ - void removeMatching(ContainedType desiredElement); - - /** - * Reverse the contents of this list in place - */ - void reverse(); - - /** - * Perform a binary search for the specified key using the provided - * means of comparing elements. Since this IS a binary search, the list - * must have been sorted before hand. - * - * @param searchKey - * The key to search for. - * @param comparator - * The way to compare elements for searching. Pass null to - * use the natural ordering for E - * @return The element if it is in this list, or null if it is not. - */ - ContainedType search(ContainedType searchKey, - Comparator comparator); - - /** - * Sort the elements of this list using the provided way of comparing - * elements. Does change the underlying list. - * - * @param comparator - * The way to compare elements for sorting. Pass null to use - * E's natural ordering - */ - void sort(Comparator comparator); - - /** - * Get the tail of this list (the list without the first element - * - * @return The list without the first element - */ - public IFunctionalList tail(); - - /** - * Convert this list into an array - * - * @param arrType - * The type of array to return - * @return The list, as an array - */ - ContainedType[] toArray(ContainedType[] arrType); - - /** - * Convert the list into a iterable - * - * @return An iterable view onto the list - */ - Iterable toIterable(); -} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java deleted file mode 100644 index 8a54246..0000000 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IFunctionalMap.java +++ /dev/null @@ -1,137 +0,0 @@ -package bjc.utils.funcdata; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Functional wrapper over map providing some useful things - * - * @author ben - * - * @param - * The type of this map's keys - * @param - * The type of this map's values - * - */ -public interface IFunctionalMap { - - /** - * Check if this map contains the specified key - * - * @param key - * The key to check - * @return Whether or not the map contains the key - */ - boolean containsKey(KeyType key); - - /** - * Extends this map, creating a new map that will delegate queries to - * the map, but store any added values itself - * - * @return An extended map - */ - IFunctionalMap extend(); - - /** - * Execute an action for each entry in the map - * - * @param action - * the action to execute for each entry in the map - */ - void forEach(BiConsumer action); - - /** - * Perform an action for each key in the map - * - * @param action - * The action to perform on each key in the map - */ - void forEachKey(Consumer action); - - /** - * Perform an action for each value in the map - * - * @param action - * The action to perform on each value in the map - */ - void forEachValue(Consumer action); - - /** - * Get the value assigned to the given key - * - * @param key - * The key to look for a value under - * @return The value of the key - * - * - */ - ValueType get(KeyType key); - - /** - * Get the number of entries in this map - * - * @return The number of entries in this map - */ - int getSize(); - - /** - * Get a list of all the keys in this map - * - * @return A list of all the keys in this map - */ - IFunctionalList keyList(); - - /** - * Transform the values returned by this map. - * - * NOTE: This transform is applied once for each lookup of a value, so - * the transform passed should be a proper function, or things will - * likely not work as expected. - * - * @param - * The new type of returned values - * @param transformer - * The function to use to transform values - * @return The map where each value will be transformed after lookup - */ - IFunctionalMap mapValues( - Function transformer); - - /** - * Add an entry to the map - * - * @param key - * The key to put the value under - * @param val - * The value to add - * @return The previous value of the key in the map, or null if the key - * wasn't in the map. However, note that it may also return - * null if the key was set to null. - * - * @throws UnsupportedOperationException - * if the map implementation doesn't support modifying the - * map - */ - ValueType put(KeyType key, ValueType val); - - /** - * Remove the value bound to the key - * - * @param key - * The key to remove from the map - * @return The previous value for the key in the map, or null if the - * key wasn't in the class. NOTE: Just because you recieved - * null, doesn't mean the map wasn't changed. It may mean that - * someone put a null value for that key into the map - */ - ValueType remove(KeyType key); - - /** - * Get a list of the values in this map - * - * @return A list of values in this map - */ - IFunctionalList valueList(); -} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java new file mode 100644 index 0000000..c45551e --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IList.java @@ -0,0 +1,350 @@ +package bjc.utils.funcdata; + +import java.util.Comparator; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +import bjc.utils.data.IPair; + +/** + * A wrapper over another list that provides eager functional operations + * over it. Differs from a stream in every way except for the fact that + * they both provide functional operations. + * + * NOTE: The indications of complexity for methods assume that the backing + * list has performance on the order of an array + * + * @author ben + * + * @param + * The type in this list + */ +public interface IList { + + /** + * Add an item to this list + * + * Takes O(1) time. + * + * @param item + * The item to add to this list. + * @return Whether the item was added to the list succesfully. + */ + boolean add(ContainedType item); + + /** + * Check if all of the elements of this list match the specified + * predicate. + * + * Takes O(f * p(n)) time on average, where f is defined as the average + * number of elements in a list until the predicate returns false, and + * p is the average running time of the predicate + * + * @param matchPredicate + * The predicate to use for checking. + * @return Whether all of the elements of the list match the specified + * predicate. + */ + boolean allMatch(Predicate matchPredicate); + + /** + * Check if any of the elements in this list match the specified list. + * + * Takes O(f * p(n)) time on average, where f is defined as the average + * number of elements in a list until the predicate returns true, and p + * is the average running time of the predicate + * + * @param matchPredicate + * The predicate to use for checking. + * @return Whether any element in the list matches the provided + * predicate. + */ + boolean anyMatch(Predicate matchPredicate); + + /** + * Combine this list with another one into a new list and merge the + * results. Works sort of like a combined zip/map over resulting pairs. + * Does not change the underlying list. + * + * NOTE: The returned list will have the length of the shorter of this + * list and the combined one. + * + * Takes O(q * c(q)), where q is defined as the length of the shorter + * of this list and the provided one, and c is the running time of the + * combiner. + * + * @param + * The type of the second list + * @param + * The type of the combined list + * + * @param rightList + * The list to combine with + * @param itemCombiner + * The function to use for combining element pairs. + * @return A new list containing the merged pairs of lists. + */ + IList combineWith( + IList rightList, + BiFunction itemCombiner); + + /** + * Check if the list contains the specified item + * + * Takes O(n) time, assuming object compare in constant time. + * + * @param item + * The item to see if it is contained + * @return Whether or not the specified item is in the list + */ + boolean contains(ContainedType item); + + /** + * Get the first element in the list + * + * Takes O(1) time + * + * @return The first element in this list. + */ + ContainedType first(); + + /** + * Apply a function to each member of the list, then flatten the + * results. Does not change the underlying list. + * + * Takes O(n * m) time, where m is the average number of elements in + * the returned list. + * + * @param + * The type of the flattened list + * + * @param elementExpander + * The function to apply to each member of the list. + * @return A new list containing the flattened results of applying the + * provided function. + */ + IList flatMap( + Function> elementExpander); + + /** + * Apply a given action for each member of the list + * + * Takes O(n * f(n)) time, where n is the length of the list, and f is + * the running time of the action. + * + * @param action + * The action to apply to each member of the list. + */ + void forEach(Consumer action); + + /** + * Apply a given function to each element in the list and its index. + * + * Takes O(n * f(n)) time, where n is the length of the list, and f is + * the running time of the action. + * + * @param indexedAction + * The function to apply to each element in the list and its + * index. + */ + void forEachIndexed(BiConsumer indexedAction); + + /** + * Retrieve a value in the list by its index. + * + * Takes O(1) time. + * + * @param index + * The index to retrieve a value from. + * @return The value at the specified index in the list. + */ + ContainedType getByIndex(int index); + + /** + * Retrieve a list containing all elements matching a predicate + * + * Takes O(n) time, where n is the number of elements in the list + * + * @param matchPredicate + * The predicate to match by + * @return A list containing all elements that match the predicate + */ + IList getMatching( + Predicate matchPredicate); + + /** + * Retrieve the size of the wrapped list + * + * @return The size of the wrapped list + */ + int getSize(); + + /** + * Check if this list is empty. + * + * @return Whether or not this list is empty. + */ + boolean isEmpty(); + + /** + * Create a new list by applying the given function to each element in + * the list. Does not change the underlying list. + * + * @param + * The type of the transformed list + * + * @param elementTransformer + * The function to apply to each element in the list + * @return A new list containing the mapped elements of this list. + */ + IList map( + Function elementTransformer); + + /** + * Zip two lists into a list of pairs + * + * @param + * The type of the second list + * + * @param rightList + * The list to use as the left side of the pair + * @return A list containing pairs of this element and the specified + * list + */ + IList> pairWith( + IList rightList); + + /** + * Partition this list into a list of sublists + * + * @param numberPerPartition + * The size of elements to put into each one of the sublists + * @return A list partitioned into partitions of size nPerPart + */ + IList> partition( + int numberPerPartition); + + /** + * Prepend an item to the list + * + * @param item + * The item to prepend to the list + */ + void prepend(ContainedType item); + + /** + * Select a random item from this list, using the provided random + * number generator. + * + * @param rnd + * The random number generator to use. + * @return A random element from this list. + */ + ContainedType randItem(Function rnd); + + /** + * Select a random item from the list, using a default random number + * generator + * + * @return A random item from the list + */ + default ContainedType randItem() { + return randItem((num) -> (int) (Math.random() * num)); + } + + /** + * Reduce this list to a single value, using a accumulative approach. + * + * @param + * The in-between type of the values + * @param + * The final value type + * + * @param initialValue + * The initial value of the accumulative state. + * @param stateAccumulator + * The function to use to combine a list element with the + * accumulative state. + * @param resultTransformer + * The function to use to convert the accumulative state + * into a final result. + * @return A single value condensed from this list and transformed into + * its final state. + */ + ReducedType reduceAux(StateType initialValue, + BiFunction stateAccumulator, + Function resultTransformer); + + /** + * Remove all elements that match a given predicate + * + * @param removePredicate + * The predicate to use to determine elements to delete + * @return Whether there was anything that satisfied the predicate + */ + boolean removeIf(Predicate removePredicate); + + /** + * Remove all parameters that match a given parameter + * + * @param desiredElement + * The object to remove all matching copies of + */ + void removeMatching(ContainedType desiredElement); + + /** + * Reverse the contents of this list in place + */ + void reverse(); + + /** + * Perform a binary search for the specified key using the provided + * means of comparing elements. Since this IS a binary search, the list + * must have been sorted before hand. + * + * @param searchKey + * The key to search for. + * @param comparator + * The way to compare elements for searching. Pass null to + * use the natural ordering for E + * @return The element if it is in this list, or null if it is not. + */ + ContainedType search(ContainedType searchKey, + Comparator comparator); + + /** + * Sort the elements of this list using the provided way of comparing + * elements. Does change the underlying list. + * + * @param comparator + * The way to compare elements for sorting. Pass null to use + * E's natural ordering + */ + void sort(Comparator comparator); + + /** + * Get the tail of this list (the list without the first element + * + * @return The list without the first element + */ + public IList tail(); + + /** + * Convert this list into an array + * + * @param arrType + * The type of array to return + * @return The list, as an array + */ + ContainedType[] toArray(ContainedType[] arrType); + + /** + * Convert the list into a iterable + * + * @return An iterable view onto the list + */ + Iterable toIterable(); +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java new file mode 100644 index 0000000..f5f7a26 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/IMap.java @@ -0,0 +1,137 @@ +package bjc.utils.funcdata; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * Functional wrapper over map providing some useful things + * + * @author ben + * + * @param + * The type of this map's keys + * @param + * The type of this map's values + * + */ +public interface IMap { + + /** + * Check if this map contains the specified key + * + * @param key + * The key to check + * @return Whether or not the map contains the key + */ + boolean containsKey(KeyType key); + + /** + * Extends this map, creating a new map that will delegate queries to + * the map, but store any added values itself + * + * @return An extended map + */ + IMap extend(); + + /** + * Execute an action for each entry in the map + * + * @param action + * the action to execute for each entry in the map + */ + void forEach(BiConsumer action); + + /** + * Perform an action for each key in the map + * + * @param action + * The action to perform on each key in the map + */ + void forEachKey(Consumer action); + + /** + * Perform an action for each value in the map + * + * @param action + * The action to perform on each value in the map + */ + void forEachValue(Consumer action); + + /** + * Get the value assigned to the given key + * + * @param key + * The key to look for a value under + * @return The value of the key + * + * + */ + ValueType get(KeyType key); + + /** + * Get the number of entries in this map + * + * @return The number of entries in this map + */ + int getSize(); + + /** + * Get a list of all the keys in this map + * + * @return A list of all the keys in this map + */ + IList keyList(); + + /** + * Transform the values returned by this map. + * + * NOTE: This transform is applied once for each lookup of a value, so + * the transform passed should be a proper function, or things will + * likely not work as expected. + * + * @param + * The new type of returned values + * @param transformer + * The function to use to transform values + * @return The map where each value will be transformed after lookup + */ + IMap mapValues( + Function transformer); + + /** + * Add an entry to the map + * + * @param key + * The key to put the value under + * @param val + * The value to add + * @return The previous value of the key in the map, or null if the key + * wasn't in the map. However, note that it may also return + * null if the key was set to null. + * + * @throws UnsupportedOperationException + * if the map implementation doesn't support modifying the + * map + */ + ValueType put(KeyType key, ValueType val); + + /** + * Remove the value bound to the key + * + * @param key + * The key to remove from the map + * @return The previous value for the key in the map, or null if the + * key wasn't in the class. NOTE: Just because you recieved + * null, doesn't mean the map wasn't changed. It may mean that + * someone put a null value for that key into the map + */ + ValueType remove(KeyType key); + + /** + * Get a list of the values in this map + * + * @return A list of values in this map + */ + IList valueList(); +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ITree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ITree.java index 026f3f8..e0c63e3 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/ITree.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/ITree.java @@ -43,7 +43,7 @@ public interface ITree { */ public ReturnedType collapse( Function leafTransform, - Function, NewType>> nodeCollapser, + Function, NewType>> nodeCollapser, Function resultTransformer); /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java index cc31923..ed9aa63 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/PushdownMap.java @@ -13,7 +13,7 @@ import java.util.function.Function; * @param */ public class PushdownMap - implements IFunctionalMap { + implements IMap { @Override public boolean containsKey(KeyType key) { @@ -22,7 +22,7 @@ public class PushdownMap } @Override - public IFunctionalMap extend() { + public IMap extend() { // TODO Auto-generated method stub return null; } @@ -58,13 +58,13 @@ public class PushdownMap } @Override - public IFunctionalList keyList() { + public IList keyList() { // TODO Auto-generated method stub return null; } @Override - public IFunctionalMap mapValues( + public IMap mapValues( Function transformer) { // TODO Auto-generated method stub return null; @@ -83,7 +83,7 @@ public class PushdownMap } @Override - public IFunctionalList valueList() { + public IList valueList() { // TODO Auto-generated method stub return null; } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java index 1d52d82..cf54935 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/TransformedValueMap.java @@ -17,11 +17,11 @@ import java.util.function.Function; * The type of the transformed values */ final class TransformedValueMap - implements IFunctionalMap { - private IFunctionalMap mapToTransform; + implements IMap { + private IMap mapToTransform; private Function transformer; - public TransformedValueMap(IFunctionalMap destMap, + public TransformedValueMap(IMap destMap, Function transform) { mapToTransform = destMap; transformer = transform; @@ -33,7 +33,7 @@ final class TransformedValueMap } @Override - public IFunctionalMap extend() { + public IMap extend() { return new ExtendedMap<>(this, new FunctionalMap<>()); } @@ -67,12 +67,12 @@ final class TransformedValueMap } @Override - public IFunctionalList keyList() { + public IList keyList() { return mapToTransform.keyList(); } @Override - public IFunctionalMap mapValues( + public IMap mapValues( Function transform) { return new TransformedValueMap<>(this, transform); } @@ -94,7 +94,7 @@ final class TransformedValueMap } @Override - public IFunctionalList valueList() { + public IList valueList() { return mapToTransform.valueList().map(transformer); } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java index 4ddcd45..34b70d5 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/Tree.java @@ -17,7 +17,7 @@ import bjc.utils.funcutils.StringUtils; */ public class Tree implements ITree { private ContainedType data; - private IFunctionalList> children; + private IList> children; private boolean hasChildren; @@ -44,7 +44,7 @@ public class Tree implements ITree { * A list of children for this node */ public Tree(ContainedType leafToken, - IFunctionalList> childrn) { + IList> childrn) { data = leafToken; hasChildren = true; @@ -95,7 +95,7 @@ public class Tree implements ITree { @Override public ReturnedType collapse( Function leafTransform, - Function, NewType>> nodeCollapser, + Function, NewType>> nodeCollapser, Function resultTransformer) { return resultTransformer @@ -129,12 +129,12 @@ public class Tree implements ITree { protected NewType internalCollapse( Function leafTransform, - Function, NewType>> nodeCollapser) { + Function, NewType>> nodeCollapser) { if (hasChildren) { - Function, NewType> nodeTransformer = nodeCollapser + Function, NewType> nodeTransformer = nodeCollapser .apply(data); - IFunctionalList collapsedChildren = children + IList collapsedChildren = children .map((child) -> { return child.collapse(leafTransform, nodeCollapser, (subTreeVal) -> subTreeVal); @@ -169,7 +169,7 @@ public class Tree implements ITree { Function leafTransformer, Function operatorTransformer) { if (hasChildren) { - IFunctionalList> mappedChildren = children + IList> mappedChildren = children .map((child) -> { return child.rebuildTree(leafTransformer, operatorTransformer); @@ -279,7 +279,7 @@ public class Tree implements ITree { public ITree transformTree( Function transformer) { if (hasChildren) { - IFunctionalList> transformedChildren = children + IList> transformedChildren = children .map((child) -> child.transformTree(transformer)); return new Tree<>(transformer.apply(data), diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java index 712f0e3..9cfc9a4 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTree.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.function.Predicate; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * A binary search tree, with some mild support for functional traversal. @@ -74,7 +74,7 @@ public class BinarySearchTree { * The distance from the pivot * @return Whether the adjusted pivot is with the list */ - private boolean adjustedPivotInBounds(IFunctionalList elements, + private boolean adjustedPivotInBounds(IList elements, int pivot, int pivotAdjustment) { return (pivot - pivotAdjustment) >= 0 && (pivot + pivotAdjustment) < elements.getSize(); @@ -85,7 +85,7 @@ public class BinarySearchTree { * time, but also O(N) space. */ public void balance() { - IFunctionalList elements = new FunctionalList<>(); + IList elements = new FunctionalList<>(); // Add each element to the list in sorted order rootElement.forEach(TreeLinearizationMethod.INORDER, diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java index 67fd5ec..61b13ea 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/EnumUtils.java @@ -4,7 +4,7 @@ import java.util.Random; import java.util.function.Consumer; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * Utility methods on enums @@ -31,7 +31,7 @@ public class EnumUtils { int nValues, Consumer action, Random rnd) { E[] enumValues = enumClass.getEnumConstants(); - IFunctionalList valueList = new FunctionalList<>(enumValues); + IList valueList = new FunctionalList<>(enumValues); int randomValueCount = enumValues.length - nValues; diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java index 67cf4b1..34a7ee0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/GroupPartIteration.java @@ -5,7 +5,7 @@ import java.util.function.Function; import bjc.utils.data.IHolder; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * Implements a single group partitioning pass on a list @@ -16,16 +16,16 @@ import bjc.utils.funcdata.IFunctionalList; * The type of element in the list being partitioned */ final class GroupPartIteration implements Consumer { - private IFunctionalList> returnedList; - private IHolder> currentPartition; - private IFunctionalList rejectedItems; + private IList> returnedList; + private IHolder> currentPartition; + private IList rejectedItems; private IHolder numberInCurrentPartition; private int numberPerPartition; private Function elementCounter; - public GroupPartIteration(IFunctionalList> returned, - IHolder> currPart, - IFunctionalList rejects, IHolder numInCurrPart, + public GroupPartIteration(IList> returned, + IHolder> currPart, + IList rejects, IHolder numInCurrPart, int nPerPart, Function eleCount) { this.returnedList = returned; this.currentPartition = currPart; diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java index ea15a78..913ccc4 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java @@ -8,7 +8,7 @@ import bjc.utils.data.IHolder; import bjc.utils.data.IPair; import bjc.utils.data.Identity; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * Utilities for manipulating FunctionalLists that don't belong in the @@ -28,7 +28,7 @@ public class ListUtils { * The list of tokens to collapse * @return The collapsed string of tokens */ - public static String collapseTokens(IFunctionalList input) { + public static String collapseTokens(IList input) { if (input == null) { throw new NullPointerException("Input must not be null"); } @@ -46,7 +46,7 @@ public class ListUtils { * The seperator to use for seperating tokens * @return The collapsed string of tokens */ - public static String collapseTokens(IFunctionalList input, + public static String collapseTokens(IList input, String seperator) { if (input == null) { throw new NullPointerException("Input must not be null"); @@ -78,8 +78,8 @@ public class ListUtils { * @return The tokens that have been deaffixed * */ - public static IFunctionalList deAffixTokens( - IFunctionalList input, + public static IList deAffixTokens( + IList input, Deque> operators) { if (input == null) { throw new NullPointerException("Input must not be null"); @@ -88,7 +88,7 @@ public class ListUtils { "Set of operators must not be null"); } - IHolder> returnedList = new Identity<>( + IHolder> returnedList = new Identity<>( input); operators.forEach((operator) -> returnedList @@ -115,10 +115,10 @@ public class ListUtils { * selected from the specified list without replacement */ - public static IFunctionalList drawWithoutReplacement( - IFunctionalList list, int numberOfItems, + public static IList drawWithoutReplacement( + IList list, int numberOfItems, Function rng) { - IFunctionalList selectedItems = new FunctionalList<>( + IList selectedItems = new FunctionalList<>( new ArrayList<>(numberOfItems)); int totalItems = list.getSize(); @@ -153,10 +153,10 @@ public class ListUtils { * @return A new list containing the desired number of items randomly * selected from the specified list */ - public static IFunctionalList drawWithReplacement( - IFunctionalList list, int numberOfItems, + public static IList drawWithReplacement( + IList list, int numberOfItems, Function rng) { - IFunctionalList selectedItems = new FunctionalList<>( + IList selectedItems = new FunctionalList<>( new ArrayList<>(numberOfItems)); for (int i = 0; i < numberOfItems; i++) { @@ -181,8 +181,8 @@ public class ListUtils { * The number of elements to put in each partition * @return A list partitioned according to the above rules */ - public static IFunctionalList> groupPartition( - IFunctionalList input, Function elementCounter, + public static IList> groupPartition( + IList input, Function elementCounter, int numberPerPartition) { if (input == null) { throw new NullPointerException("Input list must not be null"); @@ -199,17 +199,17 @@ public class ListUtils { /* * List that holds our results */ - IFunctionalList> returnedList = new FunctionalList<>(); + IList> returnedList = new FunctionalList<>(); /* * List that holds current partition */ - IHolder> currentPartition = new Identity<>( + IHolder> currentPartition = new Identity<>( new FunctionalList<>()); /* * List that holds elements rejected during current pass */ - IFunctionalList rejectedElements = new FunctionalList<>(); + IList rejectedElements = new FunctionalList<>(); /* * The effective number of elements in the current partitition @@ -254,11 +254,11 @@ public class ListUtils { * @return A list containing all the elements of the lists */ @SafeVarargs - public static IFunctionalList mergeLists( - IFunctionalList... lists) { - IFunctionalList returnedList = new FunctionalList<>(); + public static IList mergeLists( + IList... lists) { + IList returnedList = new FunctionalList<>(); - for (IFunctionalList list : lists) { + for (IList list : lists) { list.forEach(returnedList::add); } @@ -279,8 +279,8 @@ public class ListUtils { * @return A list of tokens split on all the operators * */ - public static IFunctionalList splitTokens( - IFunctionalList input, + public static IList splitTokens( + IList input, Deque> operators) { if (input == null) { throw new NullPointerException("Input must not be null"); @@ -289,7 +289,7 @@ public class ListUtils { "Set of operators must not be null"); } - IHolder> returnedList = new Identity<>( + IHolder> returnedList = new Identity<>( input); operators.forEach((operator) -> { diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java index 9ea3596..6ed4ecf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenDeaffixer.java @@ -3,10 +3,10 @@ package bjc.utils.funcutils; import java.util.function.BiFunction; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; final class TokenDeaffixer - implements BiFunction> { + implements BiFunction> { private String token; public TokenDeaffixer(String tok) { @@ -14,7 +14,7 @@ final class TokenDeaffixer } @Override - public IFunctionalList apply(String operatorName, + public IList apply(String operatorName, String operatorRegex) { if (operatorName == null) { throw new NullPointerException( diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java index 68dde25..b9693a7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/TokenSplitter.java @@ -3,10 +3,10 @@ package bjc.utils.funcutils; import java.util.function.BiFunction; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; final class TokenSplitter - implements BiFunction> { + implements BiFunction> { private String tokenToSplit; public TokenSplitter(String tok) { @@ -14,7 +14,7 @@ final class TokenSplitter } @Override - public IFunctionalList apply(String operatorName, + public IList apply(String operatorName, String operatorRegex) { if (operatorName == null) { throw new NullPointerException( @@ -29,10 +29,10 @@ final class TokenSplitter return new FunctionalList<>(tokenToSplit); } - IFunctionalList splitTokens = new FunctionalList<>( + IList splitTokens = new FunctionalList<>( tokenToSplit.split(operatorRegex)); - IFunctionalList result = new FunctionalList<>(); + IList result = new FunctionalList<>(); int tokenExpansionSize = splitTokens.getSize(); diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java index 963fb32..a764a08 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/RandomGrammar.java @@ -1,7 +1,7 @@ package bjc.utils.gen; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * A weighted grammar where all the rules have a equal chance of occuring. @@ -28,8 +28,8 @@ public class RandomGrammar extends WeightedGrammar { * The cases to add for this rule. */ @SafeVarargs - public final void addCases(E rule, IFunctionalList... cases) { - for (IFunctionalList currentCase : cases) { + public final void addCases(E rule, IList... cases) { + for (IList currentCase : cases) { super.addCase(rule, 1, currentCase); } } @@ -43,10 +43,10 @@ public class RandomGrammar extends WeightedGrammar { * The cases to add for this rule. */ @SafeVarargs - public final void makeRule(E rule, IFunctionalList... cases) { + public final void makeRule(E rule, IList... cases) { super.addRule(rule); - for (IFunctionalList currentCase : cases) { + for (IList currentCase : cases) { super.addCase(rule, 1, currentCase); } } @@ -60,7 +60,7 @@ public class RandomGrammar extends WeightedGrammar { * The cases to add for this rule. */ public void makeRule(E rule, - IFunctionalList> cases) { + IList> cases) { if (cases == null) { throw new NullPointerException("Cases must not be null"); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java index 131e507..78db7d8 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java @@ -7,8 +7,8 @@ import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; /** * A random grammar, where certain rules will come up more often than @@ -28,7 +28,7 @@ public class WeightedGrammar { /** * The rules currently in this grammar */ - protected IFunctionalMap>> rules; + protected IMap>> rules; /** * The random number generator used for random numbers @@ -38,7 +38,7 @@ public class WeightedGrammar { /** * All of the subgrammars of this grammar */ - protected IFunctionalMap> subgrammars; + protected IMap> subgrammars; /** * Create a new weighted grammar. @@ -77,7 +77,7 @@ public class WeightedGrammar { * The case being added. */ public void addCase(E ruleName, int probability, - IFunctionalList cse) { + IList cse) { if (ruleName == null) { throw new NullPointerException("Rule name must be not null"); } else if (cse == null) { @@ -146,7 +146,7 @@ public class WeightedGrammar { * @return Whether or not the rule was succesfully added. */ public boolean addRule(E name, - WeightedRandom> cases) { + WeightedRandom> cases) { if (name == null) { throw new NullPointerException("Name must not be null"); } else if (cases == null) { @@ -222,15 +222,15 @@ public class WeightedGrammar { * The rule to test. * @return A set of sentances generated by the specified rule. */ - public IFunctionalList> generateDebugValues( + public IList> generateDebugValues( E ruleName) { if (ruleName == null) { throw new NullPointerException("Rule name must not be null"); } - IFunctionalList> returnedList = new FunctionalList<>(); + IList> returnedList = new FunctionalList<>(); - WeightedRandom> ruleGenerator = rules + WeightedRandom> ruleGenerator = rules .get(ruleName); for (int i = 0; i < 10; i++) { @@ -255,7 +255,7 @@ public class WeightedGrammar { * @return A randomly generated sentance from the specified initial * rule. */ - public IFunctionalList generateGenericValues(E initRule, + public IList generateGenericValues(E initRule, Function tokenTransformer, T spacer) { if (initRule == null) { throw new NullPointerException( @@ -266,7 +266,7 @@ public class WeightedGrammar { throw new NullPointerException("Spacer must not be null"); } - IFunctionalList returnedList = new FunctionalList<>(); + IList returnedList = new FunctionalList<>(); if (subgrammars.containsKey(initRule)) { subgrammars.get(initRule).generateGenericValues(initRule, @@ -309,7 +309,7 @@ public class WeightedGrammar { * @return A list of random grammar elements generated by the specified * rule. */ - public IFunctionalList generateListValues(E initRule, E spacer) { + public IList generateListValues(E initRule, E spacer) { return generateGenericValues(initRule, strang -> strang, spacer); } @@ -336,7 +336,7 @@ public class WeightedGrammar { * * @return The set of all rule names in this grammar */ - public IFunctionalList getRuleNames() { + public IList getRuleNames() { return rules.keyList(); } @@ -389,16 +389,16 @@ public class WeightedGrammar { "Number of times to prefix must be positive."); } - WeightedRandom> rule = rules.get(ruleName); + WeightedRandom> rule = rules.get(ruleName); - IFunctionalList>> newResults = new FunctionalList<>(); + IList>> newResults = new FunctionalList<>(); rule.getValues().forEach((pair) -> { - IFunctionalList> newRule = new FunctionalList<>(); + IList> newRule = new FunctionalList<>(); for (int i = 1; i <= numberOfTimes; i++) { - IFunctionalList newCase = pair.merge((left, right) -> { - IFunctionalList returnVal = new FunctionalList<>(); + IList newCase = pair.merge((left, right) -> { + IList returnVal = new FunctionalList<>(); for (E val : right.toIterable()) { returnVal.add(val); @@ -449,13 +449,13 @@ public class WeightedGrammar { "Prefix token must not be null"); } - WeightedRandom> rule = rules.get(ruleName); + WeightedRandom> rule = rules.get(ruleName); - IFunctionalList>> newResults = new FunctionalList<>(); + IList>> newResults = new FunctionalList<>(); rule.getValues().forEach((pair) -> { - IFunctionalList newCase = pair.merge((left, right) -> { - IFunctionalList returnVal = new FunctionalList<>(); + IList newCase = pair.merge((left, right) -> { + IList returnVal = new FunctionalList<>(); for (E val : right.toIterable()) { returnVal.add(val); @@ -503,13 +503,13 @@ public class WeightedGrammar { "Prefix token must not be null"); } - WeightedRandom> rule = rules.get(ruleName); + WeightedRandom> rule = rules.get(ruleName); - IFunctionalList>> newResults = new FunctionalList<>(); + IList>> newResults = new FunctionalList<>(); rule.getValues().forEach((par) -> { - IFunctionalList newCase = par.merge((left, right) -> { - IFunctionalList returnVal = new FunctionalList<>(); + IList newCase = par.merge((left, right) -> { + IList returnVal = new FunctionalList<>(); for (E val : right.toIterable()) { returnVal.add(val); diff --git a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java index 43d9928..7c6af23 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedRandom.java @@ -6,7 +6,7 @@ import bjc.utils.data.IHolder; import bjc.utils.data.IPair; import bjc.utils.data.Identity; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * Represents a random number generator where certain results are weighted @@ -21,12 +21,12 @@ public class WeightedRandom { /** * The list of probabilities for each result */ - private IFunctionalList probabilities; + private IList probabilities; /** * The list of possible results to pick from */ - private IFunctionalList results; + private IList results; /** * The source for any needed random numbers @@ -103,7 +103,7 @@ public class WeightedRandom { * * @return A list of all the values that can be generated */ - public IFunctionalList getResults() { + public IList getResults() { return results; } @@ -113,7 +113,7 @@ public class WeightedRandom { * * @return A list of pairs of values and value probabilities */ - public IFunctionalList> getValues() { + public IList> getValues() { return probabilities.pairWith(results); } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java index 32d3b34..ff9103e 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java @@ -10,8 +10,8 @@ import bjc.utils.data.IHolder; import bjc.utils.data.Identity; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; import bjc.utils.funcutils.FuncUtils; /** @@ -65,7 +65,7 @@ public class AdjacencyMap { "The number of vertices must be greater than 0"); } - IFunctionalList vertices = new FunctionalList<>(); + IList vertices = new FunctionalList<>(); FuncUtils.doTimes(numVertices, (vertexNo) -> vertices.add(vertexNo)); @@ -119,7 +119,7 @@ public class AdjacencyMap { /** * The backing storage of the map */ - private IFunctionalMap> adjacencyMap = new FunctionalMap<>(); + private IMap> adjacencyMap = new FunctionalMap<>(); /** * Create a new map from a set of vertices @@ -127,13 +127,13 @@ public class AdjacencyMap { * @param vertices * The set of vertices to create a map from */ - public AdjacencyMap(IFunctionalList vertices) { + public AdjacencyMap(IList vertices) { if (vertices == null) { throw new NullPointerException("Vertices must not be null"); } vertices.forEach(vertex -> { - IFunctionalMap vertexRow = new FunctionalMap<>(); + IMap vertexRow = new FunctionalMap<>(); vertices.forEach(targetVertex -> { vertexRow.put(targetVertex, 0); diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java index 0574325..798d20d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java @@ -13,8 +13,8 @@ import java.util.function.BiPredicate; import bjc.utils.data.IHolder; import bjc.utils.data.Identity; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; /** * A directed weighted graph, where the vertices have some arbitrary label @@ -49,7 +49,7 @@ public class Graph { /** * The backing representation of the graph */ - private final IFunctionalMap> backingGraph; + private final IMap> backingGraph; /** * Create a new graph @@ -135,7 +135,7 @@ public class Graph { * The vertex to use as a source * @return All of the edges with the specified vertex as a source */ - public IFunctionalMap getEdges(T source) { + public IMap getEdges(T source) { // Can't find edges for a null source if (source == null) { throw new NullPointerException("The source cannot be null."); @@ -230,7 +230,7 @@ public class Graph { * * @return A unmodifiable set of all the vertices in the graph. */ - public IFunctionalList getVertices() { + public IList getVertices() { return backingGraph.keyList(); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/ExtensionFileFilter.java b/BJC-Utils2/src/main/java/bjc/utils/gui/ExtensionFileFilter.java index c020bac..bb147df 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/ExtensionFileFilter.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/ExtensionFileFilter.java @@ -6,7 +6,7 @@ import java.util.List; import javax.swing.filechooser.FileFilter; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * A file filter based on extensions. @@ -20,7 +20,7 @@ public class ExtensionFileFilter extends FileFilter { /** * The list holding all filtered extensions */ - private IFunctionalList extensions; + private IList extensions; /** * Create a new filter only showing files with the specified diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java b/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java index b22f8f4..a116f15 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/ListParameterPanel.java @@ -9,7 +9,7 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListSelectionModel; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.gui.layout.HLayout; import bjc.utils.gui.layout.VLayout; @@ -54,7 +54,7 @@ public class ListParameterPanel extends JPanel { */ public ListParameterPanel(Supplier addAction, Consumer editAction, Consumer removeAction, - IFunctionalList defaultValues) { + IList defaultValues) { setLayout(new VLayout(2)); JList list; diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/awt/ExtensionFileFilter.java b/BJC-Utils2/src/main/java/bjc/utils/gui/awt/ExtensionFileFilter.java index 230b768..a375a98 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/awt/ExtensionFileFilter.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/awt/ExtensionFileFilter.java @@ -5,7 +5,7 @@ import java.io.FilenameFilter; import java.util.List; import bjc.utils.funcdata.FunctionalList; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; /** * Filter a set of filenames by extension. @@ -19,7 +19,7 @@ public class ExtensionFileFilter implements FilenameFilter { /** * The list of extensions to filter */ - private IFunctionalList extensions; + private IList extensions; /** * Create a new filter only showing files with the specified diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java new file mode 100644 index 0000000..9d9d1b1 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/RuleBasedReaderPragmas.java @@ -0,0 +1,81 @@ +package bjc.utils.parserutils; + +import java.util.function.BiConsumer; + +import bjc.utils.exceptions.PragmaFormatException; +import bjc.utils.funcdata.FunctionalStringTokenizer; +import bjc.utils.funcutils.ListUtils; + +/** + * Contains factory methods for common pragma types + * + * @author ben + * + */ +public class RuleBasedReaderPragmas { + + /** + * Creates a pragma that takes any number of arguments and collapses + * them all into a single string + * + * @param + * The type of state that goes along with this pragma + * @param name + * The name of this pragma, for error message purpose + * @param consumer + * The function to invoke with the parsed string + * @return A pragma that functions as described above. + */ + public static + BiConsumer + buildStringCollapser(String name, + BiConsumer consumer) { + return (tokenizer, state) -> { + if (!tokenizer.hasMoreTokens()) { + throw new PragmaFormatException("Pragma " + name + + " requires one string argument"); + } + + consumer.accept(ListUtils.collapseTokens( + tokenizer.toList((strang) -> strang)), state); + }; + } + + /** + * Creates a pragma that takes a single integer argument + * + * @param + * The type of state that goes along with this pragma + * @param name + * The name of this pragma, for error message purpose + * @param consumer + * The function to invoke with the parsed integer + * @return A pragma that functions as described above. + */ + public static + BiConsumer buildInteger( + String name, BiConsumer consumer) { + return (tokenizer, state) -> { + if (!tokenizer.hasMoreTokens()) { + throw new PragmaFormatException("Pragma " + name + + " requires one integer argument"); + } + + String token = tokenizer.nextToken(); + + try { + consumer.accept(Integer.parseInt(token), state); + } catch (NumberFormatException nfex) { + PragmaFormatException pfex = + new PragmaFormatException("Argument " + token + + " to version pragma isn't a valid integer. " + + "This pragma requires a integer argument"); + + pfex.initCause(nfex); + + throw pfex; + } + }; + } + +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java index 2ea23c6..8118faa 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/ShuntingYard.java @@ -7,8 +7,8 @@ import java.util.function.Function; import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; import bjc.utils.funcutils.StringUtils; /** @@ -63,11 +63,11 @@ public class ShuntingYard { } private final class TokenShunter implements Consumer { - private IFunctionalList output; + private IList output; private Deque stack; private Function transform; - public TokenShunter(IFunctionalList outpt, + public TokenShunter(IList outpt, Deque stack, Function transform) { this.output = outpt; @@ -105,7 +105,7 @@ public class ShuntingYard { /** * Holds all the shuntable operations */ - private IFunctionalMap operators; + private IMap operators; /** * Create a new shunting yard with a default set of operators @@ -176,8 +176,8 @@ public class ShuntingYard { * The function to use to transform strings to tokens * @return A list of tokens in postfix notation */ - public IFunctionalList postfix( - IFunctionalList input, + public IList postfix( + IList input, Function tokenTransformer) { if (input == null) { throw new NullPointerException("Input must not be null"); @@ -185,7 +185,7 @@ public class ShuntingYard { throw new NullPointerException("Transformer must not be null"); } - IFunctionalList output = new FunctionalList<>(); + IList output = new FunctionalList<>(); Deque stack = new LinkedList<>(); diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java index 283d16e..c703a72 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -9,7 +9,7 @@ import bjc.utils.data.IHolder; import bjc.utils.data.IPair; import bjc.utils.data.Identity; import bjc.utils.data.Pair; -import bjc.utils.funcdata.IFunctionalList; +import bjc.utils.funcdata.IList; import bjc.utils.funcdata.ITree; /** @@ -34,7 +34,7 @@ public class TreeConstructor { * @return A AST from the expression */ public static ITree constructTree( - IFunctionalList tokens, + IList tokens, Predicate operatorPredicate) { return constructTree(tokens, operatorPredicate, (op) -> false, null); @@ -65,7 +65,7 @@ public class TreeConstructor { * works */ public static ITree constructTree( - IFunctionalList tokens, + IList tokens, Predicate operatorPredicate, Predicate isSpecialOperator, Function>, ITree>> handleSpecialOperator) { -- cgit v1.2.3