diff --git a/src/main/java/com/intellectualsites/commands/CommandTree.java b/src/main/java/com/intellectualsites/commands/CommandTree.java index 9847171d..3c099e84 100644 --- a/src/main/java/com/intellectualsites/commands/CommandTree.java +++ b/src/main/java/com/intellectualsites/commands/CommandTree.java @@ -1,14 +1,37 @@ +// +// MIT License +// +// Copyright (c) 2020 IntellectualSites +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// package com.intellectualsites.commands; import com.google.common.base.Objects; import com.intellectualsites.commands.components.CommandComponent; import com.intellectualsites.commands.components.StaticComponent; +import com.intellectualsites.commands.parser.ComponentParseResult; +import com.intellectualsites.commands.sender.CommandSender; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; +import java.util.*; /** * Tree containing all commands and command paths @@ -29,6 +52,41 @@ public class CommandTree { return new CommandTree(); } + public Optional parse(@Nonnull final String[] args) { + final CommandSender tempSender = new CommandSender() { + }; + + final Queue commandQueue = new LinkedList<>(Arrays.asList(args)); + return parseCommand(tempSender, commandQueue, this.internalTree); + } + + private Optional parseCommand(@Nonnull final CommandSender commandSender, @Nonnull final Queue commandQueue, + @Nonnull final Node> root) { + final Iterator>> childIterator = root.getChildren().iterator(); + if (childIterator.hasNext()) { + while (childIterator.hasNext()) { + final Node> child = childIterator.next(); + if (child.getValue() != null) { + final ComponentParseResult result = child.getValue().getParser().parse(commandSender, commandQueue); + if (result.getParsedValue().isPresent()) { + /* TODO: Add to some context */ + return this.parseCommand(commandSender, commandQueue, child); + } else if (result.getFailure().isPresent() && root.children.size() == 1) { + /* Return the error somehow :D */ + } + } + } + } else { + /* We are at the bottom. Check if there's a command attached, in which case we're done */ + if (root.getValue() != null && root.getValue().getOwningCommand() != null) { + return Optional.of(root.getValue().getOwningCommand()); + } else { + /* TODO: Indicate that we could not resolve the command here */ + } + } + return Optional.empty(); + } + /** * Insert a new command into the command tree * diff --git a/src/main/java/com/intellectualsites/commands/components/StaticComponent.java b/src/main/java/com/intellectualsites/commands/components/StaticComponent.java index e3c46f78..a7c22f94 100644 --- a/src/main/java/com/intellectualsites/commands/components/StaticComponent.java +++ b/src/main/java/com/intellectualsites/commands/components/StaticComponent.java @@ -23,9 +23,15 @@ // package com.intellectualsites.commands.components; +import com.intellectualsites.commands.parser.ComponentParseResult; import com.intellectualsites.commands.parser.ComponentParser; +import com.intellectualsites.commands.sender.CommandSender; import javax.annotation.Nonnull; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Queue; +import java.util.Set; public final class StaticComponent extends CommandComponent { @@ -36,7 +42,27 @@ public final class StaticComponent extends CommandComponent { private static final class StaticComponentParser implements ComponentParser { + private final String name; + private final Set acceptedStrings = new HashSet<>(); + private StaticComponentParser(@Nonnull final String name, @Nonnull final String ... aliases) { + this.acceptedStrings.add(this.name = name); + this.acceptedStrings.addAll(Arrays.asList(aliases)); + } + + @Nonnull @Override public ComponentParseResult parse(@Nonnull final CommandSender sender, @Nonnull final Queue inputQueue) { + final String string = inputQueue.peek(); + if (string == null) { + return ComponentParseResult.failure(this.name); + } + for (final String acceptedString : this.acceptedStrings) { + if (string.equalsIgnoreCase(acceptedString)) { + // Remove the head of the queue + inputQueue.remove(); + return ComponentParseResult.success(this.name); + } + } + return ComponentParseResult.failure(this.name); } } diff --git a/src/main/java/com/intellectualsites/commands/parser/ComponentParseResult.java b/src/main/java/com/intellectualsites/commands/parser/ComponentParseResult.java new file mode 100644 index 00000000..aa07116c --- /dev/null +++ b/src/main/java/com/intellectualsites/commands/parser/ComponentParseResult.java @@ -0,0 +1,83 @@ +// +// MIT License +// +// Copyright (c) 2020 IntellectualSites +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +package com.intellectualsites.commands.parser; + +import javax.annotation.Nonnull; +import java.util.Optional; + +public abstract class ComponentParseResult { + + private ComponentParseResult() { + } + + @Nonnull public static ComponentParseResult failure(@Nonnull final String failure) { + return new ParseFailure<>(failure); + } + + @Nonnull public static ComponentParseResult success(@Nonnull final T value) { + return new ParseSuccess<>(value); + } + + @Nonnull public abstract Optional getParsedValue(); + + @Nonnull public abstract Optional getFailure(); + + + private static final class ParseSuccess extends ComponentParseResult { + + private final T value; + + private ParseSuccess(@Nonnull final T value) { + this.value = value; + } + + @Nonnull @Override public Optional getParsedValue() { + return Optional.of(this.value); + } + + @Nonnull @Override public Optional getFailure() { + return Optional.empty(); + } + + } + + + private static final class ParseFailure extends ComponentParseResult { + + private final String failure; + + private ParseFailure(@Nonnull final String failure) { + this.failure = failure; + } + + @Nonnull @Override public Optional getParsedValue() { + return Optional.empty(); + } + + @Nonnull @Override public Optional getFailure() { + return Optional.of(this.failure); + } + } + +} diff --git a/src/main/java/com/intellectualsites/commands/parser/ComponentParser.java b/src/main/java/com/intellectualsites/commands/parser/ComponentParser.java index 57b9b16e..276da6f5 100644 --- a/src/main/java/com/intellectualsites/commands/parser/ComponentParser.java +++ b/src/main/java/com/intellectualsites/commands/parser/ComponentParser.java @@ -23,5 +23,20 @@ // package com.intellectualsites.commands.parser; -public interface ComponentParser { +import com.intellectualsites.commands.sender.CommandSender; + +import javax.annotation.Nonnull; +import java.util.Queue; + +@FunctionalInterface public interface ComponentParser { + + /** + * Parse command input into a command result + * + * @param sender Sender who sent the command + * @param inputQueue The queue of arguments + * @return Parsed command result + */ + @Nonnull ComponentParseResult parse(@Nonnull CommandSender sender, @Nonnull Queue inputQueue); + } diff --git a/src/main/java/com/intellectualsites/commands/sender/CommandSender.java b/src/main/java/com/intellectualsites/commands/sender/CommandSender.java new file mode 100644 index 00000000..d80a60f3 --- /dev/null +++ b/src/main/java/com/intellectualsites/commands/sender/CommandSender.java @@ -0,0 +1,27 @@ +// +// MIT License +// +// Copyright (c) 2020 IntellectualSites +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +package com.intellectualsites.commands.sender; + +public interface CommandSender { +}