From 79d3a4a47cbc1fcf17c77c6fc12ff826a3077bac Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Wed, 6 Apr 2016 13:50:00 -0400 Subject: Minor bugfixes/changes, as well as beginnings of CLI systems --- .../src/main/java/bjc/utils/cli/CLICommander.java | 60 +++++ .../java/bjc/utils/cli/GeneralCommandMode.java | 246 +++++++++++++++++++++ .../main/java/bjc/utils/cli/ICommandHandler.java | 22 ++ .../src/main/java/bjc/utils/cli/ICommandMode.java | 68 ++++++ .../src/main/java/bjc/utils/cli/package-info.java | 7 + .../components/ComponentDescriptionFileParser.java | 50 +++-- .../utils/components/FileComponentRepository.java | 2 +- .../main/java/bjc/utils/data/lazy/LazyHolder.java | 17 +- .../java/bjc/utils/funcdata/FunctionalList.java | 41 ++-- .../java/bjc/utils/funcdata/FunctionalMap.java | 10 +- .../utils/funcdata/FunctionalStringTokenizer.java | 10 +- .../utils/funcdata/bst/BinarySearchTreeNode.java | 30 +-- .../main/java/bjc/utils/funcutils/ListUtils.java | 58 +++-- .../main/java/bjc/utils/gen/WeightedGrammar.java | 61 +++-- .../main/java/bjc/utils/graph/AdjacencyMap.java | 16 +- .../src/main/java/bjc/utils/gui/SimpleDialogs.java | 10 +- .../main/java/bjc/utils/gui/SimpleFileChooser.java | 12 +- .../src/main/java/bjc/utils/parserutils/AST.java | 157 ++++++------- 18 files changed, 649 insertions(+), 228 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/GeneralCommandMode.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/cli/package-info.java (limited to 'BJC-Utils2/src/main/java') diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java b/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java new file mode 100644 index 0000000..f48f08e --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/CLICommander.java @@ -0,0 +1,60 @@ +package bjc.utils.cli; + +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Runs a CLI interface from the provided set of streams + * + * @author ben + * + */ +public class CLICommander { + private InputStream input; + private OutputStream output; + private OutputStream error; + private ICommandMode initialMode; + + /** + * Create a new CLI interface powered by streams + * + * @param input + * The stream to get user input from + * @param output + * The stream to send user output to + * @param error + * The stream to send error messages to + */ + public CLICommander(InputStream input, OutputStream output, + OutputStream error) { + if (input == null) { + throw new NullPointerException( + "Input stream must not be null"); + } else if (output == null) { + throw new NullPointerException( + "Output stream must not be null"); + } else if (error == null) { + throw new NullPointerException( + "Error stream must not be null"); + } + + this.input = input; + this.output = output; + this.error = error; + } + + /** + * Set the initial command mode to use + * + * @param initialMode + * The initial command mode to use + */ + public void setInitialCommandMode(ICommandMode initialMode) { + if (initialMode == null) { + throw new NullPointerException( + "Initial mode must be non-zero"); + } + + this.initialMode = initialMode; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/GeneralCommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/GeneralCommandMode.java new file mode 100644 index 0000000..4a41c1c --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/GeneralCommandMode.java @@ -0,0 +1,246 @@ +package bjc.utils.cli; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * A general command mode, with a customizable set of commands + * + * There is a small set of commands which is handled by default. The first + * is 'list', which lists all the commands the user can input. The second + * is 'alias', which allows the user to bind a new name to a command + * + * @author ben + * + */ +public class GeneralCommandMode implements ICommandMode { + private Map commandHandlers; + private String customPrompt; + + private Map defaultHandlers; + + private Consumer errorOutput; + private String modeName; + + private Consumer normalOutput; + + private BiConsumer unknownCommandHandler; + + /** + * Create a new general command mode + * + * @param normalOutput + * The function to use for normal output + * @param errorOutput + * The function to use for error output + */ + public GeneralCommandMode(Consumer normalOutput, + Consumer errorOutput) { + this.normalOutput = normalOutput; + this.errorOutput = errorOutput; + + commandHandlers = new HashMap<>(); + defaultHandlers = new HashMap<>(); + + defaultHandlers.put("list", (args) -> { + listCommands(); + + return this; + }); + + defaultHandlers.put("alias", (args) -> { + aliasCommands(args); + + return this; + }); + } + + /** + * Add an alias to an existing command + * + * @param commandName + * The name of the command to add an alias for + * @param aliasName + * The new alias for the command + * + * @throws IllegalArgumentException + * if the specified command doesn't have a bound handler, + * or if the alias name already has a bound value + */ + public void addCommandAlias(String commandName, String aliasName) { + if (commandName == null) { + throw new NullPointerException( + "Command name must not be null"); + } else if (aliasName == null) { + throw new NullPointerException("Alias name must not be null"); + } else if (!commandHandlers.containsKey(commandName)) { + throw new IllegalArgumentException( + "Cannot alias non-existant command '" + commandName + + "'"); + } else if (commandHandlers.containsKey(aliasName)) { + throw new IllegalArgumentException("Cannot bind alias '" + + aliasName + "' to a command with a bound handler"); + } else { + commandHandlers.put(aliasName, + commandHandlers.get(commandName)); + } + } + + /** + * Add a command to this command mode + * + * @param command + * The command to add + * @param handler + * The handler to use for the specified command + * + * @throws IllegalArgumentException + * if the specified command already has a handler + * registered + */ + public void addCommandHandler(String command, + ICommandHandler handler) { + if (command == null) { + throw new NullPointerException("Command must not be null"); + } else if (handler == null) { + throw new NullPointerException("Handler must not be null"); + } else if (canHandleCommand(command)) { + throw new IllegalArgumentException("Command " + command + + " already has a handler registered"); + } else { + commandHandlers.put(command, handler); + } + } + + private void aliasCommands(String[] args) { + if (args.length != 2) { + errorOutput.accept("ERROR: Alias requires two arguments. " + + "The command name, and the alias for that command"); + } else { + String commandName = args[0]; + String aliasName = args[1]; + + if (!canHandleCommand(commandName)) { + errorOutput.accept("ERROR: '" + commandName + + "' is not a valid command."); + } else if (canHandleCommand(aliasName)) { + errorOutput.accept("ERROR: Cannot overwrite command '" + + aliasName + "'"); + } else { + addCommandAlias(commandName, aliasName); + } + } + } + + @Override + public boolean canHandleCommand(String command) { + return commandHandlers.containsKey(command) + || defaultHandlers.containsKey(command); + } + + @Override + public String getCustomPrompt() { + if (customPrompt != null) { + return customPrompt; + } + + return ICommandMode.super.getCustomPrompt(); + } + + @Override + public String getName() { + if (modeName != null) { + return modeName; + } + + return ICommandMode.super.getName(); + } + + private void listCommands() { + normalOutput.accept( + "The available commands for this mode are as follows:\n"); + + commandHandlers.keySet().forEach((commandName) -> { + normalOutput.accept("\t" + commandName); + }); + + normalOutput.accept( + "\nThe following commands are available in all modes:\n"); + + defaultHandlers.keySet().forEach((commandName) -> { + normalOutput.accept("\t" + commandName); + }); + + normalOutput.accept("\n"); + } + + @Override + public ICommandMode processCommand(String command, String[] args) { + normalOutput.accept("\n"); + + if (defaultHandlers.containsKey(command)) { + return defaultHandlers.get(command).handle(args); + } else if (commandHandlers.containsKey(command)) { + return commandHandlers.get(command).handle(args); + } else { + if (unknownCommandHandler == null) { + throw new UnsupportedOperationException( + "Command " + command + " is invalid."); + } else if (args != null) { + errorOutput.accept("ERROR: Unrecognized command " + command + + String.join(" ", args)); + } else { + errorOutput + .accept("ERROR: Unrecognized command " + command); + } + + unknownCommandHandler.accept(command, args); + } + + return this; + } + + /** + * Set the custom prompt for this mode + * + * @param prompt + * The custom prompt for this mode, or null to disable the + * custom prompt + */ + public void setCustomPrompt(String prompt) { + customPrompt = prompt; + } + + /** + * Set the name of this mode + * + * @param name + * The desired name of this mode, or null to use the default + * name + */ + public void setModeName(String name) { + modeName = name; + } + + /** + * Set the handler to use for unknown commands + * + * @param handler + * The handler to use for unknown commands + */ + public void setUnknownCommandHandler( + BiConsumer handler) { + if (handler == null) { + throw new NullPointerException("Handler must not be null"); + } + + unknownCommandHandler = handler; + } + + @Override + public boolean useCustomPrompt() { + return customPrompt != null; + } +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java new file mode 100644 index 0000000..f806676 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandHandler.java @@ -0,0 +1,22 @@ +package bjc.utils.cli; + +import java.util.function.Function; + +/** + * A handler for a command + * + * @author ben + * + */ +public interface ICommandHandler extends Function { + /** + * Handle the command this handler handles + * + * @param args + * The arguments for this command + * @return The command mode to go to after this command + */ + public default ICommandMode handle(String[] args) { + return this.apply(args); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java new file mode 100644 index 0000000..5208657 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/ICommandMode.java @@ -0,0 +1,68 @@ +package bjc.utils.cli; + +/** + * A mode for determining the commands that are valid to enter, and then + * handling those commands + * + * @author ben + * + */ +public interface ICommandMode { + /** + * Process a command in this mode + * + * @param command + * The command to process + * @param args + * A list of arguments to the command + * @return The command mode to use for the next command. Defaults to + * returning this, and doing nothing else + */ + public default ICommandMode processCommand(String command, + String[] args) { + return this; + }; + + /** + * Check to see if this mode can handle the specified command + * + * @param command + * The command to check + * @return Whether or not this mode can handle the command. It is + * assumed not by default + */ + public default boolean canHandleCommand(String command) { + return false; + } + + /** + * Get the name of this command mode + * + * @return The name of this command mode, which is "crawler" by default + */ + public default String getName() { + return "crawler"; + } + + /** + * Check if this mode uses a custom prompt + * + * @return Whether or not this mode uses a custom prompt + */ + public default boolean useCustomPrompt() { + return false; + } + + /** + * Get the custom prompt for this mode + * + * @return the custom prompt for this mode + * + * @throws UnsupportedOperationException + * if this mode doesn't support a custom prompt + */ + public default String getCustomPrompt() { + throw new UnsupportedOperationException( + "This mode doesn't support a custom prompt"); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/cli/package-info.java b/BJC-Utils2/src/main/java/bjc/utils/cli/package-info.java new file mode 100644 index 0000000..a87aa24 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/cli/package-info.java @@ -0,0 +1,7 @@ +/** + * Holds classes for easier CLI design + * + * @author ben + * + */ +package bjc.utils.cli; \ No newline at end of file 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 5ab87bb..254e380 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java @@ -19,54 +19,62 @@ public class ComponentDescriptionFileParser { // This reader works entirely off of pragmas, so no need to handle // rules reader = new RuleBasedConfigReader<>((tokenizer, statePair) -> { + // Don't need to do anything on rule start }, (tokenizer, state) -> { + // Don't need to do anything on rule continuation }, (state) -> { + // Don't need to do anything on rule end }); reader.addPragma("name", (tokenizer, state) -> { if (!tokenizer.hasMoreTokens()) { throw new PragmaFormatException( "Pragma name requires one string argument"); - } else { - state.setName(ListUtils.collapseTokens( - tokenizer.toList((strang) -> strang))); } + + state.setName(ListUtils + .collapseTokens(tokenizer.toList((strang) -> strang))); }); reader.addPragma("author", (tokenizer, state) -> { if (!tokenizer.hasMoreTokens()) { throw new PragmaFormatException( "Pragma author requires one string argument"); - } else { - state.setAuthor(ListUtils.collapseTokens( - tokenizer.toList((strang) -> strang))); } + + state.setAuthor(ListUtils + .collapseTokens(tokenizer.toList((strang) -> strang))); }); reader.addPragma("description", (tokenizer, state) -> { if (!tokenizer.hasMoreTokens()) { throw new PragmaFormatException( "Pragma description requires one string argument"); - } else { - state.setDescription(ListUtils.collapseTokens( - tokenizer.toList((strang) -> strang))); } + + state.setDescription(ListUtils + .collapseTokens(tokenizer.toList((strang) -> strang))); }); reader.addPragma("version", (tokenizer, state) -> { if (!tokenizer.hasMoreTokens()) { throw new PragmaFormatException( "Pragma name requires one integer argument"); - } else { - String token = tokenizer.nextToken(); - - try { - state.setVersion(Integer.parseInt(token)); - } catch (NumberFormatException nfex) { - throw new PragmaFormatException("Argument " + token - + " to version pragma isn't a valid integer. " - + "This pragma requires a 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; } }); } @@ -78,8 +86,8 @@ 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()); 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 4b8d87b..4aea0d6 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java @@ -92,7 +92,7 @@ public class FileComponentRepository CLASS_LOGGER .warn("Error found reading component from file " + componentFile.toString() - + ". This component will not be loaded"); + + ". This component will not be loaded", ex); } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java index 61a5956..4b8ed30 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java @@ -40,18 +40,17 @@ public class LazyHolder implements IHolder, ILazy { if (heldValue == null) { return pendingActions.reduceAux(heldSource.get(), Function::apply, pendingTransform::apply); - } else { - return pendingActions.reduceAux(heldValue, - Function::apply, pendingTransform::apply); } + + return pendingActions.reduceAux(heldValue, + Function::apply, pendingTransform::apply); } } /** * List of queued actions to be performed on realized values */ - private FunctionalList> actions = - new FunctionalList<>(); + private FunctionalList> actions = new FunctionalList<>(); /** * The value internally held by this lazy holder @@ -148,10 +147,10 @@ public class LazyHolder implements IHolder, ILazy { if (heldSource != null) { // We're materialized if a value exists return heldValue == null; - } else { - // We're materialized by default - return true; } + + // We're materialized by default + return true; } @Override @@ -170,7 +169,7 @@ public class LazyHolder implements IHolder, ILazy { @Override public void applyPendingActions() { materialize(); - + actions.forEach((action) -> { heldValue = action.apply(heldValue); }); 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 ff02515..c680879 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalList.java @@ -207,8 +207,8 @@ public class FunctionalList implements Cloneable { // Get the iterator for the other list Iterator rightIterator = rightList.toIterable().iterator(); - for (Iterator leftIterator = - wrappedList.iterator(); leftIterator.hasNext() + for (Iterator leftIterator = wrappedList + .iterator(); leftIterator.hasNext() && rightIterator.hasNext();) { // Add the transformed items to the result list E leftVal = leftIterator.next(); @@ -258,18 +258,18 @@ public class FunctionalList implements Cloneable { * @return A new list containing the flattened results of applying the * provided function. */ - public FunctionalList - flatMap(Function> elementExpander) { + public FunctionalList flatMap( + Function> elementExpander) { if (elementExpander == null) { throw new NullPointerException("Expander must not be null"); } - FunctionalList returnedList = - new FunctionalList<>(this.wrappedList.size()); + FunctionalList returnedList = new FunctionalList<>( + this.wrappedList.size()); forEach(element -> { - FunctionalList expandedElement = - elementExpander.apply(element); + FunctionalList expandedElement = elementExpander + .apply(element); if (expandedElement == null) { throw new NullPointerException( @@ -400,8 +400,8 @@ public class FunctionalList implements Cloneable { throw new NullPointerException("Transformer must be not null"); } - FunctionalList returnedList = - new FunctionalList<>(this.wrappedList.size()); + FunctionalList returnedList = new FunctionalList<>( + this.wrappedList.size()); forEach(element -> { // Add the transformed item to the result @@ -422,8 +422,8 @@ public class FunctionalList implements Cloneable { * @return A list containing pairs of this element and the specified * list */ - public FunctionalList> - pairWith(FunctionalList rightList) { + public FunctionalList> pairWith( + FunctionalList rightList) { return combineWith(rightList, Pair::new); } @@ -434,8 +434,8 @@ public class FunctionalList implements Cloneable { * The size of elements to put into each one of the sublists * @return A list partitioned into partitions of size nPerPart */ - public FunctionalList> - partition(int numberPerPartition) { + public FunctionalList> partition( + int numberPerPartition) { if (numberPerPartition < 1 || numberPerPartition > wrappedList.size()) { throw new IllegalArgumentException("" + numberPerPartition @@ -443,12 +443,11 @@ public class FunctionalList implements Cloneable { + wrappedList.size()); } - FunctionalList> returnedList = - new FunctionalList<>(); + FunctionalList> returnedList = new FunctionalList<>(); // The current partition being filled - GenHolder> currentPartition = - new GenHolder<>(new FunctionalList<>()); + GenHolder> currentPartition = new GenHolder<>( + new FunctionalList<>()); this.forEach((element) -> { if (isPartitionFull(numberPerPartition, currentPartition)) { @@ -593,10 +592,10 @@ public class FunctionalList implements Cloneable { if (foundIndex >= 0) { // We found a matching element return wrappedList.get(foundIndex); - } else { - // We didn't find an element - return null; } + + // We didn't find an element + return null; } /** 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 f1d4cc6..0453988 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalMap.java @@ -118,12 +118,12 @@ public class FunctionalMap { throw new NullPointerException("Key must not be null"); } - if (wrappedMap.containsKey(key)) { - return wrappedMap.get(key); - } else { + if (!wrappedMap.containsKey(key)) { throw new IllegalArgumentException( "Key " + key + " is not present in the map"); } + + return wrappedMap.get(key); } /** @@ -139,8 +139,8 @@ public class FunctionalMap { * The function to use to transform values * @return The map where each value will be transformed after lookup */ - public FunctionalMap - mapValues(Function transformer) { + public FunctionalMap mapValues( + Function transformer) { if (transformer == null) { throw new NullPointerException("Transformer must not be null"); } 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 386b732..9ef59fb 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/FunctionalStringTokenizer.java @@ -120,10 +120,10 @@ public class FunctionalStringTokenizer { if (input.hasMoreTokens()) { // Return the next availible token return input.nextToken(); - } else { - // Return no token - return null; } + + // Return no token + return null; } /** @@ -137,8 +137,8 @@ public class FunctionalStringTokenizer { * The function to use to convert tokens. * @return A list containing all of the converted tokens. */ - public FunctionalList - toList(Function tokenTransformer) { + public FunctionalList toList( + Function tokenTransformer) { if (tokenTransformer == null) { throw new NullPointerException("Transformer must not be null"); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java index 09a4912..58e07f7 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcdata/bst/BinarySearchTreeNode.java @@ -90,8 +90,8 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { E collapsedNode = nodeCollapser.apply(data); if (leftBranch != null) { - E collapsedLeftBranch = - leftBranch.collapse(nodeCollapser, branchCollapser); + E collapsedLeftBranch = leftBranch.collapse(nodeCollapser, + branchCollapser); if (rightBranch != null) { E collapsedRightBranch = rightBranch .collapse(nodeCollapser, branchCollapser); @@ -101,21 +101,21 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { return branchCollapser.apply(collapsedNode, collapsedBranches); - } else { - return branchCollapser.apply(collapsedNode, - collapsedLeftBranch); } - } else { - if (rightBranch != null) { - E collapsedRightBranch = rightBranch - .collapse(nodeCollapser, branchCollapser); - return branchCollapser.apply(collapsedNode, - collapsedRightBranch); - } else { - return collapsedNode; - } + return branchCollapser.apply(collapsedNode, + collapsedLeftBranch); + } + + if (rightBranch != null) { + E collapsedRightBranch = rightBranch.collapse(nodeCollapser, + branchCollapser); + + return branchCollapser.apply(collapsedNode, + collapsedRightBranch); } + + return collapsedNode; } @Override @@ -188,7 +188,7 @@ public class BinarySearchTreeNode extends BinarySearchTreeLeaf { } else if (traversalPredicate == null) { throw new NullPointerException("Predicate must not be null"); } - + switch (linearizationMethod) { case PREORDER: return preorderTraverse(linearizationMethod, 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 5eb488a..1d2750b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java +++ b/BJC-Utils2/src/main/java/bjc/utils/funcutils/ListUtils.java @@ -75,31 +75,30 @@ public class ListUtils { if (StringUtils.containsOnly(tokenToSplit, operatorRegex)) { return new FunctionalList<>(tokenToSplit); - } else { - FunctionalList splitTokens = - new FunctionalList<>( - tokenToSplit.split(operatorRegex)); + } - FunctionalList result = new FunctionalList<>(); + FunctionalList splitTokens = new FunctionalList<>( + tokenToSplit.split(operatorRegex)); - int tokenExpansionSize = splitTokens.getSize(); + FunctionalList result = new FunctionalList<>(); - splitTokens.forEachIndexed((tokenIndex, token) -> { + int tokenExpansionSize = splitTokens.getSize(); - if (tokenIndex != tokenExpansionSize - && tokenIndex != 0) { - result.add(operatorName); - result.add(token); - } else { - result.add(token); - } - }); + splitTokens.forEachIndexed((tokenIndex, token) -> { - return result; - } - } else { - return new FunctionalList<>(tokenToSplit); + if (tokenIndex != tokenExpansionSize + && tokenIndex != 0) { + result.add(operatorName); + result.add(token); + } else { + result.add(token); + } + }); + + return result; } + + return new FunctionalList<>(tokenToSplit); } } @@ -193,14 +192,13 @@ public class ListUtils { /* * List that holds our results */ - FunctionalList> returnedList = - new FunctionalList<>(); + FunctionalList> returnedList = new FunctionalList<>(); /* * List that holds current partition */ - GenHolder> currentPartition = - new GenHolder<>(new FunctionalList<>()); + GenHolder> currentPartition = new GenHolder<>( + new FunctionalList<>()); /* * List that holds elements rejected during current pass */ @@ -214,10 +212,8 @@ public class ListUtils { /* * Run up to a certain number of passes */ - for (int numberOfIterations = - 0; numberOfIterations < MAX_NTRIESPART - && !rejectedElements - .isEmpty(); numberOfIterations++) { + for (int numberOfIterations = 0; numberOfIterations < MAX_NTRIESPART + && !rejectedElements.isEmpty(); numberOfIterations++) { input.forEach(new GroupPartIteration<>(returnedList, currentPartition, rejectedElements, numberInCurrentPartition, numberPerPartition, @@ -265,8 +261,8 @@ public class ListUtils { "Set of operators must not be null"); } - GenHolder> returnedList = - new GenHolder<>(input); + GenHolder> returnedList = new GenHolder<>( + input); operators.forEach((operator) -> returnedList .transform((oldReturn) -> oldReturn.flatMap((token) -> { @@ -296,8 +292,8 @@ public class ListUtils { "Set of operators must not be null"); } - GenHolder> returnedList = - new GenHolder<>(input); + GenHolder> returnedList = new GenHolder<>( + input); operators.forEach((operator) -> returnedList .transform((oldReturn) -> oldReturn.flatMap((token) -> { 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 cdfe056..5d61201 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gen/WeightedGrammar.java @@ -106,14 +106,14 @@ public class WeightedGrammar { if (subgrammars.containsKey(alias)) { return false; - } else { - if (subgrammars.containsKey(name)) { - subgrammars.put(alias, subgrammars.get(name)); - return true; - } else { - return false; - } } + + if (subgrammars.containsKey(name)) { + subgrammars.put(alias, subgrammars.get(name)); + return true; + } + + return false; } /** @@ -154,10 +154,10 @@ public class WeightedGrammar { if (rules.containsKey(name)) { return false; - } else { - rules.put(name, cases); - return true; } + + rules.put(name, cases); + return true; } /** @@ -179,10 +179,10 @@ public class WeightedGrammar { if (subgrammars.containsKey(name)) { return false; - } else { - subgrammars.put(name, subgrammar); - return true; } + + subgrammars.put(name, subgrammar); + return true; } /** @@ -193,17 +193,16 @@ public class WeightedGrammar { * The rule to test. * @return A set of sentances generated by the specified rule. */ - public FunctionalList> - generateDebugValues(E ruleName) { + public FunctionalList> generateDebugValues( + E ruleName) { if (ruleName == null) { throw new NullPointerException("Rule name must not be null"); } - FunctionalList> returnedList = - new FunctionalList<>(); + FunctionalList> returnedList = new FunctionalList<>(); - WeightedRandom> ruleGenerator = - rules.get(ruleName); + WeightedRandom> ruleGenerator = rules + .get(ruleName); for (int i = 0; i < 10; i++) { returnedList.add(ruleGenerator.generateValue()); @@ -345,16 +344,14 @@ public class WeightedGrammar { WeightedRandom> rule = rules.get(ruleName); - FunctionalList>> newResults = - new FunctionalList<>(); + FunctionalList>> newResults = new FunctionalList<>(); rule.getValues().forEach((pair) -> { - FunctionalList> newRule = - new FunctionalList<>(); + FunctionalList> newRule = new FunctionalList<>(); for (int i = 1; i <= numberOfTimes; i++) { - FunctionalList newCase = - pair.merge((left, right) -> right.clone()); + FunctionalList newCase = pair + .merge((left, right) -> right.clone()); for (int j = 1; j <= i; j++) { newCase.prepend(prefixToken); @@ -397,12 +394,11 @@ public class WeightedGrammar { WeightedRandom> rule = rules.get(ruleName); - FunctionalList>> newResults = - new FunctionalList<>(); + FunctionalList>> newResults = new FunctionalList<>(); rule.getValues().forEach((pair) -> { - FunctionalList newCase = - pair.merge((left, right) -> right.clone()); + FunctionalList newCase = pair + .merge((left, right) -> right.clone()); newCase.prepend(prefixToken); newResults.add(new Pair<>(pair.merge((left, right) -> left) @@ -490,12 +486,11 @@ public class WeightedGrammar { WeightedRandom> rule = rules.get(ruleName); - FunctionalList>> newResults = - new FunctionalList<>(); + FunctionalList>> newResults = new FunctionalList<>(); rule.getValues().forEach((par) -> { - FunctionalList newCase = - par.merge((left, right) -> right.clone()); + FunctionalList newCase = par + .merge((left, right) -> right.clone()); newCase.add(suffixToken); newResults.add(new Pair<>(par.merge((left, right) -> left) 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 e583210..247ee31 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java @@ -50,10 +50,14 @@ public class AdjacencyMap { // First, read in number of vertices numVertices = Integer.parseInt(possibleVertices); } catch (NumberFormatException nfex) { - throw new InputMismatchException( + InputMismatchException imex = new InputMismatchException( "The first line must contain the number of vertices. " + possibleVertices + " is not a valid number"); + + imex.initCause(nfex); + + throw imex; } if (numVertices <= 0) { @@ -87,8 +91,12 @@ public class AdjacencyMap { try { columnWeight = Integer.parseInt(part); } catch (NumberFormatException nfex) { - throw new InputMismatchException( + InputMismatchException imex = new InputMismatchException( "" + part + " is not a valid weight."); + + imex.initCause(nfex); + + throw imex; } adjacencyMap.setWeight(row.unwrap(number -> number), @@ -143,8 +151,8 @@ public class AdjacencyMap { GenHolder result = new GenHolder<>(true); adjacencyMap.entrySet().forEach(mapEntry -> { - Set> entryVertices = - mapEntry.getValue().entrySet(); + Set> entryVertices = mapEntry.getValue() + .entrySet(); entryVertices.forEach(targetVertex -> { int leftValue = targetVertex.getValue(); diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleDialogs.java b/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleDialogs.java index b09fbd8..37f7edf 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleDialogs.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleDialogs.java @@ -43,7 +43,9 @@ public class SimpleDialogs { int value = Integer.parseInt(strang); return (value < upperBound) && (value > lowerBound); - } catch (NumberFormatException nfe) { + } catch (@SuppressWarnings("unused") NumberFormatException nfex) { + // We don't care about the specifics of the exception, just + // that this value isn't good return false; } }, Integer::parseInt); @@ -125,7 +127,9 @@ public class SimpleDialogs { try { Integer.parseInt(strang); return true; - } catch (NumberFormatException nfe) { + } catch (@SuppressWarnings("unused") NumberFormatException nfex) { + // We don't care about this exception, just mark the value + // as not good return false; } }, Integer::parseInt); @@ -257,7 +261,7 @@ public class SimpleDialogs { throw new NullPointerException( "Error message must not be null"); } - + JOptionPane.showMessageDialog(parent, errorMessage, title, JOptionPane.ERROR_MESSAGE); } diff --git a/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleFileChooser.java b/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleFileChooser.java index f39ff7c..b4c6d73 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleFileChooser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/gui/SimpleFileChooser.java @@ -31,7 +31,8 @@ public class SimpleFileChooser { maybeDoOpenFile(parent, files); success = true; - } catch (FileNotChosenException e) { + } catch (@SuppressWarnings("unused") FileNotChosenException fncx) { + // We don't care about specifics SimpleDialogs.showError(parent, "I/O Error", "Please pick a file to open"); } @@ -55,7 +56,8 @@ public class SimpleFileChooser { maybeDoSaveFile(parent, files); return files.getSelectedFile(); - } catch (FileNotChosenException e) { + } catch (@SuppressWarnings("unused") FileNotChosenException fncex) { + // We don't care about specifics SimpleDialogs.showError(parent, "I/O Error", "Please pick a file to save to"); } @@ -187,7 +189,8 @@ public class SimpleFileChooser { try { maybeDoOpenFile(parent, files); - } catch (FileNotChosenException e) { + } catch (@SuppressWarnings("unused") FileNotChosenException fncex) { + // We don't care about specifics } return files.getSelectedFile(); @@ -212,7 +215,8 @@ public class SimpleFileChooser { try { maybeDoSaveFile(parent, files); - } catch (FileNotChosenException e) { + } catch (@SuppressWarnings("unused") FileNotChosenException fncex) { + // We don't care about specifics } return files.getSelectedFile(); diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java index 4b00b63..90961d5 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/AST.java @@ -67,6 +67,57 @@ public class AST { right = rght; } + /** + * Apply an action to the head node of this AST + * + * @param + * The type of the returned value + * @param headAction + * The action to apply to the head node + * @return The result of applying the action + */ + public E applyToHead(Function headAction) { + if (headAction == null) { + throw new NullPointerException("Action must not be null"); + } + + return headAction.apply(token); + } + + /** + * Apply an action to the left side of this AST + * + * @param + * The type of the returned value + * @param leftAction + * The action to apply to the left side + * @return The result of applying the action + */ + public E applyToLeft(Function, E> leftAction) { + if (leftAction == null) { + throw new NullPointerException("Action must not be null"); + } + + return leftAction.apply(left); + } + + /** + * Apply an action to the right side of this AST + * + * @param + * The type of the returned value + * @param rightAction + * The action to apply to the right side + * @return The result of applying the action + */ + public E applyToRight(Function, E> rightAction) { + if (rightAction == null) { + throw new NullPointerException("Action must not be null"); + } + + return rightAction.apply(right); + } + /** * Collapse this tree into a single node * @@ -97,12 +148,36 @@ public class AST { if (resultTransformer != null) { return resultTransformer.apply( internalCollapse(tokenTransformer, nodeTransformer)); + } + + // This is valid because if the user passes null as the last + // parameter, E will be inferred as Object, but will actually + // be T2 + return (E) internalCollapse(tokenTransformer, nodeTransformer); + } + + private T2 collapseBranches(Function tokenTransformer, + Function> nodeTransformer) { + T2 leftCollapsed; + + if (left == null) { + leftCollapsed = null; } else { - // This is valid because if the user passes null as the last - // parameter, E will be inferred as Object, but will actually - // be T2 - return (E) internalCollapse(tokenTransformer, nodeTransformer); + leftCollapsed = left.internalCollapse(tokenTransformer, + nodeTransformer); } + + T2 rightCollapsed; + + if (right == null) { + rightCollapsed = null; + } else { + rightCollapsed = right.internalCollapse(tokenTransformer, + nodeTransformer); + } + + return nodeTransformer.apply(token).apply(leftCollapsed, + rightCollapsed); } /** @@ -129,28 +204,9 @@ public class AST { Function> nodeTransformer) { if (left == null && right == null) { return tokenTransformer.apply(token); - } else { - T2 leftCollapsed; - - if (left == null) { - leftCollapsed = null; - } else { - leftCollapsed = left.internalCollapse(tokenTransformer, - nodeTransformer); - } - - T2 rightCollapsed; - - if (right == null) { - rightCollapsed = null; - } else { - rightCollapsed = right.internalCollapse(tokenTransformer, - nodeTransformer); - } - - return nodeTransformer.apply(token).apply(leftCollapsed, - rightCollapsed); } + + return collapseBranches(tokenTransformer, nodeTransformer); } /** @@ -302,55 +358,4 @@ public class AST { action.accept(token); } } - - /** - * Apply an action to the head node of this AST - * - * @param - * The type of the returned value - * @param headAction - * The action to apply to the head node - * @return The result of applying the action - */ - public E applyToHead(Function headAction) { - if (headAction == null) { - throw new NullPointerException("Action must not be null"); - } - - return headAction.apply(token); - } - - /** - * Apply an action to the left side of this AST - * - * @param - * The type of the returned value - * @param leftAction - * The action to apply to the left side - * @return The result of applying the action - */ - public E applyToLeft(Function, E> leftAction) { - if (leftAction == null) { - throw new NullPointerException("Action must not be null"); - } - - return leftAction.apply(left); - } - - /** - * Apply an action to the right side of this AST - * - * @param - * The type of the returned value - * @param rightAction - * The action to apply to the right side - * @return The result of applying the action - */ - public E applyToRight(Function, E> rightAction) { - if (rightAction == null) { - throw new NullPointerException("Action must not be null"); - } - - return rightAction.apply(right); - } } -- cgit v1.2.3