Add checkstyle and add 950 billion comments

This commit is contained in:
Alexander Söderberg 2020-09-11 22:36:51 +02:00
parent 784656b891
commit f90ce38a36
No known key found for this signature in database
GPG key ID: C0207FF7EA146678
47 changed files with 1055 additions and 88 deletions

199
checkstyle.xml Normal file
View file

@ -0,0 +1,199 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the sun coding conventions from:
- the Java Language Specification at
https://docs.oracle.com/javase/specs/jls/se11/html/index.html
- the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
- the Javadoc guidelines at
https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html
- the JDK Api documentation https://docs.oracle.com/en/java/javase/11/
- some best practices
Checkstyle is very configurable. Be sure to read the documentation at
https://checkstyle.org (or in your downloaded distribution).
Most Checks are configurable, be sure to consult the documentation.
To completely disable a check, just comment it out or delete it from the file.
To suppress certain violations please review suppression filters.
Finally, it is worth reading the documentation.
-->
<module name="Checker">
<!--
If you set the basedir property below, then all reported file
names will be relative to the specified directory. See
https://checkstyle.org/config.html#Checker
<property name="basedir" value="${basedir}"/>
-->
<property name="severity" value="error"/>
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Excludes all 'module-info.java' files -->
<!-- See https://checkstyle.org/config_filefilters.html -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
<module name="SuppressionFilter">
<property name="file" value="${org.checkstyle.sun.suppressionfilter.config}"
default="checkstyle-suppressions.xml" />
<property name="optional" value="true"/>
</module>
<!-- Checks that a package-info.java file exists for each package. -->
<!-- See https://checkstyle.org/config_javadoc.html#JavadocPackage -->
<module name="JavadocPackage"/>
<!-- Checks whether files end with a new line. -->
<!-- See https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
<module name="NewlineAtEndOfFile"/>
<!-- Checks that property files contain the same keys. -->
<!-- See https://checkstyle.org/config_misc.html#Translation -->
<module name="Translation"/>
<!-- Checks for Size Violations. -->
<!-- See https://checkstyle.org/config_sizes.html -->
<module name="FileLength"/>
<module name="LineLength">
<property name="fileExtensions" value="java"/>
<property name="max" value="130" />
</module>
<!-- Checks for whitespace -->
<!-- See https://checkstyle.org/config_whitespace.html -->
<module name="FileTabCharacter"/>
<!-- Miscellaneous other checks. -->
<!-- See https://checkstyle.org/config_misc.html -->
<module name="RegexpSingleline">
<property name="format" value="\s+$"/>
<property name="minimum" value="0"/>
<property name="maximum" value="0"/>
<property name="message" value="Line has trailing spaces."/>
</module>
<!-- Checks for Headers -->
<!-- See https://checkstyle.org/config_header.html -->
<!-- <module name="Header"> -->
<!-- <property name="headerFile" value="${checkstyle.header.file}"/> -->
<!-- <property name="fileExtensions" value="java"/> -->
<!-- </module> -->
<module name="TreeWalker">
<!-- Checks for Javadoc comments. -->
<!-- See https://checkstyle.org/config_javadoc.html -->
<module name="InvalidJavadocPosition"/>
<module name="JavadocMethod"/>
<module name="JavadocType"/>
<module name="JavadocStyle">
<property name="checkFirstSentence" value="false" />
</module>
<module name="MissingJavadocMethod"/>
<!-- Checks for Naming Conventions. -->
<!-- See https://checkstyle.org/config_naming.html -->
<module name="ConstantName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!-- Checks for imports -->
<!-- See https://checkstyle.org/config_imports.html -->
<module name="AvoidStarImport"/>
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
<module name="RedundantImport"/>
<module name="UnusedImports">
<property name="processJavadoc" value="false"/>
</module>
<!-- Checks for Size Violations. -->
<!-- See https://checkstyle.org/config_sizes.html -->
<module name="MethodLength"/>
<module name="ParameterNumber"/>
<!-- Checks for whitespace -->
<!-- See https://checkstyle.org/config_whitespace.html -->
<module name="EmptyForIteratorPad"/>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!-- Modifier Checks -->
<!-- See https://checkstyle.org/config_modifiers.html -->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!-- Checks for blocks. You know, those {}'s -->
<!-- See https://checkstyle.org/config_blocks.html -->
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="NeedBraces"/>
<module name="RightCurly"/>
<!-- Checks for common coding problems -->
<!-- See https://checkstyle.org/config_coding.html -->
<module name="EmptyStatement"/>
<module name="EqualsHashCode"/>
<module name="IllegalInstantiation"/>
<module name="InnerAssignment"/>
<module name="MagicNumber"/>
<module name="MissingSwitchDefault"/>
<module name="MultipleVariableDeclarations"/>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<!-- Checks for class design -->
<!-- See https://checkstyle.org/config_design.html -->
<module name="DesignForExtension"/>
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<module name="VisibilityModifier"/>
<!-- Miscellaneous other checks. -->
<!-- See https://checkstyle.org/config_misc.html -->
<module name="ArrayTypeStyle"/>
<module name="FinalParameters"/>
<module name="TodoComment"/>
<module name="UpperEll"/>
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
<module name="SuppressionXpathFilter">
<property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}"
default="checkstyle-xpath-suppressions.xml" />
<property name="optional" value="true"/>
</module>
</module>
</module>

View file

@ -31,7 +31,11 @@ import com.intellectualsites.commands.sender.CommandSender;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
/**
@ -49,6 +53,15 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
@Nonnull private final String commandPermission;
@Nonnull private final M commandMeta;
/**
* Construct a new command
*
* @param commandComponents Command components
* @param commandExecutionHandler Execution handler
* @param senderType Required sender type. May be {@code null}
* @param commandPermission Command permission
* @param commandMeta Command meta instance
*/
public Command(@Nonnull final List<CommandComponent<C, ?>> commandComponents,
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
@Nullable final Class<? extends C> senderType,
@ -78,6 +91,14 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
this.commandMeta = commandMeta;
}
/**
* Construct a new command
*
* @param commandComponents Command components
* @param commandExecutionHandler Execution handler
* @param senderType Required sender type. May be {@code null}
* @param commandMeta Command meta instance
*/
public Command(@Nonnull final List<CommandComponent<C, ?>> commandComponents,
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
@Nullable final Class<? extends C> senderType,
@ -85,6 +106,14 @@ public class Command<C extends CommandSender, M extends CommandMeta> {
this(commandComponents, commandExecutionHandler, senderType, "", commandMeta);
}
/**
* Construct a new command
*
* @param commandComponents Command components
* @param commandExecutionHandler Execution handler
* @param commandPermission Command permission
* @param commandMeta Command meta instance
*/
public Command(@Nonnull final List<CommandComponent<C, ?>> commandComponents,
@Nonnull final CommandExecutionHandler<C> commandExecutionHandler,
@Nonnull final String commandPermission,

View file

@ -58,6 +58,12 @@ public abstract class CommandManager<C extends CommandSender, M extends CommandM
private CommandSyntaxFormatter<C> commandSyntaxFormatter = new StandardCommandSyntaxFormatter<>();
/**
* Create a new command manager instance
*
* @param commandExecutionCoordinator Execution coordinator instance
* @param commandRegistrationHandler Command registration handler
*/
public CommandManager(
@Nonnull final Function<CommandTree<C, M>, CommandExecutionCoordinator<C, M>> commandExecutionCoordinator,
@Nonnull final CommandRegistrationHandler<M> commandRegistrationHandler) {

View file

@ -57,7 +57,7 @@ import java.util.stream.Collectors;
* @param <C> Command sender type
* @param <M> Command meta type
*/
public class CommandTree<C extends CommandSender, M extends CommandMeta> {
public final class CommandTree<C extends CommandSender, M extends CommandMeta> {
private final Object commandLock = new Object();
@ -106,8 +106,8 @@ public class CommandTree<C extends CommandSender, M extends CommandMeta> {
private Optional<Command<C, M>> parseCommand(@Nonnull final CommandContext<C> commandContext,
@Nonnull final Queue<String> commandQueue,
@Nonnull final Node<CommandComponent<C, ?>> root) {
String permission;
if ((permission = this.isPermitted(commandContext.getCommandSender(), root)) != null) {
String permission = this.isPermitted(commandContext.getCommandSender(), root);
if (permission != null) {
throw new NoPermissionException(permission, commandContext.getCommandSender(), this.getChain(root)
.stream()
.map(Node::getValue)
@ -179,7 +179,8 @@ public class CommandTree<C extends CommandSender, M extends CommandMeta> {
if (children.size() == 1 && !(children.get(0).getValue() instanceof StaticComponent)) {
// The value has to be a variable
final Node<CommandComponent<C, ?>> child = children.get(0);
if ((permission = this.isPermitted(commandContext.getCommandSender(), child)) != null) {
permission = this.isPermitted(commandContext.getCommandSender(), child);
if (permission != null) {
throw new NoPermissionException(permission, commandContext.getCommandSender(), this.getChain(child)
.stream()
.map(Node::getValue)
@ -220,7 +221,7 @@ public class CommandTree<C extends CommandSender, M extends CommandMeta> {
/* Too many arguments. We have a unique path, so we can send the entire context */
throw new InvalidSyntaxException(this.commandManager.getCommandSyntaxFormatter()
.apply(Objects.requireNonNull(child.getValue()
.getOwningCommand())
.getOwningCommand())
.getComponents()),
commandContext.getCommandSender(), this.getChain(root)
.stream()
@ -244,13 +245,20 @@ public class CommandTree<C extends CommandSender, M extends CommandMeta> {
return null;
}
/**
* Get suggestions from the input queue
*
* @param context Context instance
* @param commandQueue Input queue
* @return String suggestions. These should be filtered based on {@link String#startsWith(String)}
*/
@Nonnull
public List<String> getSuggestions(@Nonnull final CommandContext<C> context, @Nonnull final Queue<String> commandQueue) {
return getSuggestions(context, commandQueue, this.internalTree);
}
@Nonnull
public List<String> getSuggestions(@Nonnull final CommandContext<C> commandContext,
private List<String> getSuggestions(@Nonnull final CommandContext<C> commandContext,
@Nonnull final Queue<String> commandQueue,
@Nonnull final Node<CommandComponent<C, ?>> root) {
@ -281,7 +289,7 @@ public class CommandTree<C extends CommandSender, M extends CommandMeta> {
commandContext.store(child.getValue().getName(), result.getParsedValue().get());
return this.getSuggestions(commandContext, commandQueue, child);
} else if (result.getFailure().isPresent()) {
/* TODO: Return error */
/* I need to return ze error */
return Collections.emptyList();
}
}
@ -417,7 +425,7 @@ public class CommandTree<C extends CommandSender, M extends CommandMeta> {
if (commandComponentNode.nodeMeta.containsKey("permission") && !commandComponentNode.nodeMeta.get("permission")
.equalsIgnoreCase(
node.nodeMeta
.get("permission"))) {
.get("permission"))) {
commandComponentNode.nodeMeta.put("permission", "");
} else {
commandComponentNode.nodeMeta.put("permission", node.nodeMeta.get("permission"));

View file

@ -42,6 +42,9 @@ import java.util.regex.Pattern;
@SuppressWarnings("unused")
public class CommandComponent<C extends CommandSender, T> implements Comparable<CommandComponent<?, ?>> {
/**
* Pattern for command component names
*/
private static final Pattern NAME_PATTERN = Pattern.compile("[A-Za-z0-9]+");
/**
@ -69,6 +72,14 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
private Command<C, ?> owningCommand;
/**
* Construct a new command component
*
* @param required Whether or not the component is required
* @param name The component name
* @param parser The component parser
* @param defaultValue Default value used when no value is provided by the command sender
*/
public CommandComponent(final boolean required, @Nonnull final String name,
@Nonnull final ComponentParser<C, T> parser, @Nonnull final String defaultValue) {
this.required = required;
@ -80,6 +91,13 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
this.defaultValue = defaultValue;
}
/**
* Construct a new command component
*
* @param required Whether or not the component is required
* @param name The component name
* @param parser The component parser
*/
public CommandComponent(final boolean required, @Nonnull final String name,
@Nonnull final ComponentParser<C, T> parser) {
this(required, name, parser, "");
@ -95,7 +113,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
* @return Component builder
*/
@Nonnull
public static <C extends CommandSender, T> CommandComponent.Builder<C, T> ofType(@Nonnull final Class<T> clazz, @Nonnull final String name) {
public static <C extends CommandSender, T> CommandComponent.Builder<C, T> ofType(@Nonnull final Class<T> clazz,
@Nonnull final String name) {
return new Builder<>(name);
}
@ -131,7 +150,7 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
@Nonnull
@Override
public String toString() {
public final String toString() {
return String.format("CommandComponent{name=%s}", this.name);
}
@ -158,7 +177,7 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
}
@Override
public boolean equals(final Object o) {
public final boolean equals(final Object o) {
if (this == o) {
return true;
}
@ -170,12 +189,12 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
}
@Override
public int hashCode() {
public final int hashCode() {
return Objects.hash(isRequired(), getName());
}
@Override
public int compareTo(@Nonnull final CommandComponent<?, ?> o) {
public final int compareTo(@Nonnull final CommandComponent<?, ?> o) {
if (this instanceof StaticComponent) {
if (o instanceof StaticComponent) {
return (this.getName().compareTo(o.getName()));
@ -196,7 +215,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
*
* @return Default value
*/
@Nonnull public String getDefaultValue() {
@Nonnull
public String getDefaultValue() {
return this.defaultValue;
}
@ -206,8 +226,8 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
* @return {@code true} if the component has a default value, {@code false} if not
*/
public boolean hasDefaultValue() {
return !this.isRequired() &&
!this.getDefaultValue().isEmpty();
return !this.isRequired()
&& !this.getDefaultValue().isEmpty();
}
@ -219,10 +239,11 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
*/
public static class Builder<C extends CommandSender, T> {
protected final String name;
protected boolean required = true;
protected ComponentParser<C, T> parser = (c, i) -> ComponentParseResult.failure(new UnsupportedOperationException("No parser was specified"));
protected String defaultValue = "";
private final String name;
private boolean required = true;
private ComponentParser<C, T> parser = (c, i) -> ComponentParseResult.failure(
new UnsupportedOperationException("No parser was specified"));
private String defaultValue = "";
protected Builder(@Nonnull final String name) {
this.name = name;
@ -297,6 +318,24 @@ public class CommandComponent<C extends CommandSender, T> implements Comparable<
return new CommandComponent<>(this.required, this.name, this.parser, this.defaultValue);
}
@Nonnull
protected final String getName() {
return this.name;
}
protected final boolean isRequired() {
return this.required;
}
@Nonnull
protected final ComponentParser<C, T> getParser() {
return this.parser;
}
@Nonnull
protected final String getDefaultValue() {
return this.defaultValue;
}
}
}

View file

@ -41,12 +41,9 @@ import java.util.List;
*/
public class StandardCommandSyntaxFormatter<C extends CommandSender> implements CommandSyntaxFormatter<C> {
public StandardCommandSyntaxFormatter() {
}
@Nonnull
@Override
public String apply(@Nonnull final List<CommandComponent<C, ?>> commandComponents) {
public final String apply(@Nonnull final List<CommandComponent<C, ?>> commandComponents) {
final StringBuilder stringBuilder = new StringBuilder();
final Iterator<CommandComponent<C, ?>> iterator = commandComponents.iterator();
while (iterator.hasNext()) {

View file

@ -83,7 +83,8 @@ public final class StaticComponent<C extends CommandSender> extends CommandCompo
private final Set<String> acceptedStrings = new HashSet<>();
private StaticComponentParser(@Nonnull final String name, @Nonnull final String... aliases) {
this.acceptedStrings.add(this.name = name);
this.name = name;
this.acceptedStrings.add(this.name);
this.acceptedStrings.addAll(Arrays.asList(aliases));
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Command components that are used to build command parsing chains
*/
package com.intellectualsites.commands.components;

View file

@ -79,6 +79,9 @@ public abstract class ComponentParseResult<T> {
private static final class ParseSuccess<T> extends ComponentParseResult<T> {
/**
* Parsed value
*/
private final T value;
private ParseSuccess(@Nonnull final T value) {
@ -102,6 +105,9 @@ public abstract class ComponentParseResult<T> {
private static final class ParseFailure<T> extends ComponentParseResult<T> {
/**
* Parse failure
*/
private final Throwable failure;
private ParseFailure(@Nonnull final Throwable failure) {

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Parser classes used to parse {@link com.intellectualsites.commands.components.CommandComponent}
*/
package com.intellectualsites.commands.components.parser;

View file

@ -34,33 +34,64 @@ import javax.annotation.Nonnull;
import java.util.Queue;
@SuppressWarnings("unused")
public class ByteComponent<C extends CommandSender> extends CommandComponent<C, Byte> {
public final class ByteComponent<C extends CommandSender> extends CommandComponent<C, Byte> {
private final byte min;
private final byte max;
private ByteComponent(final boolean required, @Nonnull final String name, final byte min, final byte max, final String defaultValue) {
private ByteComponent(final boolean required, @Nonnull final String name, final byte min,
final byte max, final String defaultValue) {
super(required, name, new ByteParser<>(min, max), defaultValue);
this.min = min;
this.max = max;
}
/**
* Create a new builder
*
* @param name Name of the component
* @param <C> Command sender type
* @return Created builder
*/
@Nonnull
public static <C extends CommandSender> Builder<C> newBuilder(@Nonnull final String name) {
return new Builder<>(name);
}
/**
* Create a new required command component
*
* @param name Component name
* @param <C> Command sender type
* @return Created component
*/
@Nonnull
public static <C extends CommandSender> CommandComponent<C, Byte> required(@Nonnull final String name) {
return ByteComponent.<C>newBuilder(name).asRequired().build();
}
/**
* Create a new optional command component
*
* @param name Component name
* @param <C> Command sender type
* @return Created component
*/
@Nonnull
public static <C extends CommandSender> CommandComponent<C, Byte> optional(@Nonnull final String name) {
return ByteComponent.<C>newBuilder(name).asOptional().build();
}
@Nonnull public static <C extends CommandSender> CommandComponent<C, Byte> optional(@Nonnull final String name, final byte defaultNum) {
/**
* Create a new required command component with a default value
*
* @param name Component name
* @param defaultNum Default num
* @param <C> Command sender type
* @return Created component
*/
@Nonnull public static <C extends CommandSender> CommandComponent<C, Byte> optional(@Nonnull final String name,
final byte defaultNum) {
return ByteComponent.<C>newBuilder(name).asOptionalWithDefault(Byte.toString(defaultNum)).build();
}
@ -74,22 +105,39 @@ public class ByteComponent<C extends CommandSender> extends CommandComponent<C,
super(name);
}
/**
* Set a minimum value
*
* @param min Minimum value
* @return Builder instance
*/
@Nonnull
public Builder<C> withMin(final byte min) {
this.min = min;
return this;
}
/**
* Set a maximum value
*
* @param max Maximum value
* @return Builder instance
*/
@Nonnull
public Builder<C> withMax(final byte max) {
this.max = max;
return this;
}
/**
* Builder a new byte component
*
* @return Constructed component
*/
@Nonnull
@Override
public ByteComponent<C> build() {
return new ByteComponent<>(this.required, this.name, this.min, this.max, this.defaultValue);
return new ByteComponent<>(this.isRequired(), this.getName(), this.min, this.max, this.getDefaultValue());
}
}
@ -119,7 +167,7 @@ public class ByteComponent<C extends CommandSender> extends CommandComponent<C,
private final byte min;
private final byte max;
public ByteParser(final byte min, final byte max) {
private ByteParser(final byte min, final byte max) {
this.min = min;
this.max = max;
}
@ -153,8 +201,18 @@ public class ByteComponent<C extends CommandSender> extends CommandComponent<C,
}
/**
* Byte parse exception
*/
public static final class ByteParseException extends NumberParseException {
/**
* Construct a new byte parse exception
*
* @param input String input
* @param min Minimum value
* @param max Maximum value
*/
public ByteParseException(@Nonnull final String input, final byte min, final byte max) {
super(input, min, max);
}
@ -170,6 +228,7 @@ public class ByteComponent<C extends CommandSender> extends CommandComponent<C,
}
@Override
@Nonnull
public String getNumberType() {
return "byte";
}

View file

@ -34,30 +34,68 @@ import javax.annotation.Nonnull;
import java.util.Queue;
@SuppressWarnings("unused")
public class IntegerComponent<C extends CommandSender> extends CommandComponent<C, Integer> {
public final class IntegerComponent<C extends CommandSender> extends CommandComponent<C, Integer> {
private final int min;
private final int max;
private IntegerComponent(final boolean required, @Nonnull final String name, final int min, final int max, final String defaultValue) {
private IntegerComponent(final boolean required,
@Nonnull final String name,
final int min,
final int max,
final String defaultValue) {
super(required, name, new IntegerParser<>(min, max), defaultValue);
this.min = min;
this.max = max;
}
@Nonnull public static <C extends CommandSender> Builder<C> newBuilder(@Nonnull final String name) {
/**
* Create a new builder
*
* @param name Name of the component
* @param <C> Command sender type
* @return Created builder
*/
@Nonnull
public static <C extends CommandSender> Builder<C> newBuilder(@Nonnull final String name) {
return new Builder<>(name);
}
@Nonnull public static <C extends CommandSender> CommandComponent<C, Integer> required(@Nonnull final String name) {
/**
* Create a new required command component
*
* @param name Component name
* @param <C> Command sender type
* @return Created component
*/
@Nonnull
public static <C extends CommandSender> CommandComponent<C, Integer> required(@Nonnull final String name) {
return IntegerComponent.<C>newBuilder(name).asRequired().build();
}
@Nonnull public static <C extends CommandSender> CommandComponent<C, Integer> optional(@Nonnull final String name) {
/**
* Create a new optional command component
*
* @param name Component name
* @param <C> Command sender type
* @return Created component
*/
@Nonnull
public static <C extends CommandSender> CommandComponent<C, Integer> optional(@Nonnull final String name) {
return IntegerComponent.<C>newBuilder(name).asOptional().build();
}
@Nonnull public static <C extends CommandSender> CommandComponent<C, Integer> optional(@Nonnull final String name, final int defaultNum) {
/**
* Create a new required command component with a default value
*
* @param name Component name
* @param defaultNum Default num
* @param <C> Command sender type
* @return Created component
*/
@Nonnull
public static <C extends CommandSender> CommandComponent<C, Integer> optional(@Nonnull final String name,
final int defaultNum) {
return IntegerComponent.<C>newBuilder(name).asOptionalWithDefault(Integer.toString(defaultNum)).build();
}
@ -71,20 +109,39 @@ public class IntegerComponent<C extends CommandSender> extends CommandComponent<
super(name);
}
@Nonnull public Builder<C> withMin(final int min) {
/**
* Set a minimum value
*
* @param min Minimum value
* @return Builder instance
*/
@Nonnull
public Builder<C> withMin(final int min) {
this.min = min;
return this;
}
@Nonnull public Builder<C> withMax(final int max) {
/**
* Set a maximum value
*
* @param max Maximum value
* @return Builder instance
*/
@Nonnull
public Builder<C> withMax(final int max) {
this.max = max;
return this;
}
/**
* Builder a new integer component
*
* @return Constructed component
*/
@Nonnull
@Override
public IntegerComponent<C> build() {
return new IntegerComponent<>(this.required, this.name, this.min, this.max, this.defaultValue);
return new IntegerComponent<>(this.isRequired(), this.getName(), this.min, this.max, this.getDefaultValue());
}
}
@ -114,7 +171,7 @@ public class IntegerComponent<C extends CommandSender> extends CommandComponent<
private final int min;
private final int max;
public IntegerParser(final int min, final int max) {
private IntegerParser(final int min, final int max) {
this.min = min;
this.max = max;
}
@ -145,6 +202,13 @@ public class IntegerComponent<C extends CommandSender> extends CommandComponent<
public static final class IntegerParseException extends NumberParseException {
/**
* Construct a new integer parse exception
*
* @param input String input
* @param min Minimum value
* @param max Maximum value
*/
public IntegerParseException(@Nonnull final String input, final int min, final int max) {
super(input, min, max);
}
@ -160,6 +224,7 @@ public class IntegerComponent<C extends CommandSender> extends CommandComponent<
}
@Override
@Nonnull
public String getNumberType() {
return "integer";
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Standard command component types
*/
package com.intellectualsites.commands.components.standard;

View file

@ -29,6 +29,8 @@ import javax.annotation.Nonnull;
/**
* Factory for {@link CommandContext} instances
*
* @param <C> Command sender
*/
public interface CommandContextFactory<C extends CommandSender> {

View file

@ -29,6 +29,12 @@ import javax.annotation.Nonnull;
public final class StandardCommandContextFactory<C extends CommandSender> implements CommandContextFactory<C> {
/**
* Construct a new command context
*
* @param sender Command sender
* @return Created context
*/
@Nonnull
@Override
public CommandContext<C> create(@Nonnull final C sender) {

View file

@ -0,0 +1,29 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Command context stores values for a {@link com.intellectualsites.commands.sender.CommandSender}
* before and during command execution and parsing
*/
package com.intellectualsites.commands.context;

View file

@ -33,11 +33,25 @@ public class ComponentParseException extends CommandParseException {
private final Throwable cause;
public ComponentParseException(@Nonnull final Throwable throwable, @Nonnull final CommandSender commandSender, @Nonnull final List<CommandComponent<?, ?>> currentChain) {
/**
* Create a new command parse exception
*
* @param throwable Exception that caused the parsing error
* @param commandSender Command sender
* @param currentChain Chain leading up to the exception
*/
public ComponentParseException(@Nonnull final Throwable throwable,
@Nonnull final CommandSender commandSender,
@Nonnull final List<CommandComponent<?, ?>> currentChain) {
super(commandSender, currentChain);
this.cause = throwable;
}
/**
* Get the cause of the exception
*
* @return Cause
*/
@Nonnull
public Throwable getCause() {
return this.cause;

View file

@ -37,6 +37,13 @@ public class InvalidSyntaxException extends CommandParseException {
private final String correctSyntax;
/**
* Create a new invalid syntax exception instance
*
* @param correctSyntax Expected syntax
* @param commandSender Sender that sent the command
* @param currentChain Chain leading up to issue
*/
public InvalidSyntaxException(@Nonnull final String correctSyntax,
@Nonnull final CommandSender commandSender,
@Nonnull final List<CommandComponent<?, ?>> currentChain) {
@ -54,8 +61,9 @@ public class InvalidSyntaxException extends CommandParseException {
return this.correctSyntax;
}
@Override
public String getMessage() {
public final String getMessage() {
return String.format("Invalid command syntax. Correct syntax is: %s", this.correctSyntax);
}

View file

@ -36,6 +36,11 @@ public final class NoCommandInLeafException extends IllegalStateException {
private final CommandComponent<?, ?> commandComponent;
/**
* Create a new no command in leaf exception instance
*
* @param commandComponent Command component that caused the exception
*/
public NoCommandInLeafException(@Nonnull final CommandComponent<?, ?> commandComponent) {
super(String.format("Leaf node '%s' does not have associated owning command", commandComponent.getName()));
this.commandComponent = commandComponent;

View file

@ -38,6 +38,13 @@ public class NoPermissionException extends CommandParseException {
private final String missingPermission;
/**
* Construct a new no permission exception
*
* @param missingPermission Missing permission node
* @param commandSender Command sender
* @param currentChain Chain leading up to the exception
*/
public NoPermissionException(@Nonnull final String missingPermission,
@Nonnull final CommandSender commandSender,
@Nonnull final List<CommandComponent<?, ?>> currentChain) {
@ -46,10 +53,15 @@ public class NoPermissionException extends CommandParseException {
}
@Override
public String getMessage() {
public final String getMessage() {
return String.format("Missing permission '%s'", this.missingPermission);
}
/**
* Get the missing permission node
*
* @return Get the missing permission node
*/
@Nonnull
public String getMissingPermission() {
return this.missingPermission;

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* cloud related exceptions
*/
package com.intellectualsites.commands.exceptions;

View file

@ -31,6 +31,13 @@ public abstract class NumberParseException extends IllegalArgumentException {
private final Number min;
private final Number max;
/**
* Construct a new number parse exception
*
* @param input Input
* @param min Maximum value
* @param max Minimum value
*/
public NumberParseException(@Nonnull final String input, final int min, final int max) {
this.input = input;
this.min = min;
@ -38,9 +45,10 @@ public abstract class NumberParseException extends IllegalArgumentException {
}
@Override
public String getMessage() {
public final String getMessage() {
if (this.hasMin() && this.hasMax()) {
return "'" + this.input + "' is not a valid " + this.getNumberType() + " in the range [" + this.min + ", " + this.max + "]";
return "'" + this.input + "' is not a valid " + this.getNumberType() + " in the range ["
+ this.min + ", " + this.max + "]";
} else if (this.hasMin()) {
return "'" + this.input + "' is not a valid " + this.getNumberType() + " above " + this.min;
} else if (this.hasMax()) {
@ -50,10 +58,26 @@ public abstract class NumberParseException extends IllegalArgumentException {
}
}
/**
* Get the number type
*
* @return Number type
*/
@Nonnull
public abstract String getNumberType();
/**
* If the parser had a maximum value
*
* @return {@code true} if there was a maximum value, else {@code false}
*/
public abstract boolean hasMax();
/**
* If the parser had a minimum value
*
* @return {@code true} if there was a minimum value, else {@code false}
*/
public abstract boolean hasMin();
/**
@ -61,7 +85,8 @@ public abstract class NumberParseException extends IllegalArgumentException {
*
* @return Input
*/
@Nonnull public String getInput() {
@Nonnull
public String getInput() {
return this.input;
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Parsing related exceptions
*/
package com.intellectualsites.commands.exceptions.parsing;

View file

@ -23,9 +23,9 @@
//
package com.intellectualsites.commands.execution;
import com.intellectualsites.commands.meta.CommandMeta;
import com.intellectualsites.commands.CommandTree;
import com.intellectualsites.commands.context.CommandContext;
import com.intellectualsites.commands.meta.CommandMeta;
import com.intellectualsites.commands.sender.CommandSender;
import javax.annotation.Nonnull;
@ -62,12 +62,20 @@ public abstract class CommandExecutionCoordinator<C extends CommandSender, M ext
* @param <M> Command meta type
* @return New coordinator instance
*/
public static <C extends CommandSender, M extends CommandMeta> Function<CommandTree<C, M>, CommandExecutionCoordinator<C, M>> simpleCoordinator() {
public static <C extends CommandSender, M extends CommandMeta> Function<CommandTree<C, M>,
CommandExecutionCoordinator<C, M>> simpleCoordinator() {
return SimpleCoordinator::new;
}
public abstract CompletableFuture<CommandResult> coordinateExecution(@Nonnull final CommandContext<C> commandContext,
@Nonnull final Queue<String> input);
/**
* Coordinate the execution of a command and return the result
*
* @param commandContext Command context
* @param input Command input
* @return Future that completes with the result
*/
public abstract CompletableFuture<CommandResult> coordinateExecution(@Nonnull CommandContext<C> commandContext,
@Nonnull Queue<String> input);
/**
* Get the command tree
@ -86,15 +94,16 @@ public abstract class CommandExecutionCoordinator<C extends CommandSender, M ext
* @param <C> Command sender type
* @param <M> Command meta type
*/
public static final class SimpleCoordinator<C extends CommandSender, M extends CommandMeta> extends CommandExecutionCoordinator<C, M> {
public static final class SimpleCoordinator<C extends CommandSender, M extends CommandMeta> extends
CommandExecutionCoordinator<C, M> {
private SimpleCoordinator(@Nonnull final CommandTree<C, M> commandTree) {
super(commandTree);
}
@Override
public CompletableFuture<CommandResult> coordinateExecution(@Nonnull CommandContext<C> commandContext,
@Nonnull Queue<String> input) {
public CompletableFuture<CommandResult> coordinateExecution(@Nonnull final CommandContext<C> commandContext,
@Nonnull final Queue<String> input) {
final CompletableFuture<CommandResult> completableFuture = new CompletableFuture<>();
try {
this.getCommandTree().parse(commandContext, input).ifPresent(

View file

@ -42,7 +42,7 @@ public interface CommandExecutionHandler<C extends CommandSender> {
*
* @param commandContext Command context
*/
void execute(@Nonnull final CommandContext<C> commandContext);
void execute(@Nonnull CommandContext<C> commandContext);
/**

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Classes related to command execution and execution coordination
*/
package com.intellectualsites.commands.execution;

View file

@ -45,8 +45,14 @@ public interface CommandRegistrationHandler<M extends CommandMeta> {
* @return {@code true} if the command was registered successfully,
* else {@code false}
*/
boolean registerCommand(@Nonnull final Command<?, M> command);
boolean registerCommand(@Nonnull Command<?, M> command);
/**
* Create a new {@link CommandRegistrationHandler} that does nothing
*
* @param <M> Command meta type
* @return Constructed registration
*/
static <M extends CommandMeta> CommandRegistrationHandler<M> nullCommandRegistrationHandler() {
return new NullCommandRegistrationHandler<>();
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Classes that should be used internally in command managers
*/
package com.intellectualsites.commands.internal;

View file

@ -33,9 +33,20 @@ import javax.annotation.Nonnull;
*/
public class CommandMeta {
/**
* Create a new simple command meta builder
*
* @return Builder instance
*/
@Nonnull
public static SimpleCommandMeta.Builder simple() {
return SimpleCommandMeta.builder();
}
@Nonnull
@Override
public final String toString() {
return "";
}
}

View file

@ -95,7 +95,7 @@ public class SimpleCommandMeta extends CommandMeta {
}
@Override
public boolean equals(final Object o) {
public final boolean equals(final Object o) {
if (this == o) {
return true;
}
@ -107,7 +107,7 @@ public class SimpleCommandMeta extends CommandMeta {
}
@Override
public int hashCode() {
public final int hashCode() {
return Objects.hashCode(metaMap);
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Command meta are classes associated with commands that store arbitrary data
*/
package com.intellectualsites.commands.meta;

View file

@ -0,0 +1,29 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* cloud API main package
* @see com.intellectualsites.commands.CommandManager Command manager class
*/
package com.intellectualsites.commands;

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Command sender related classes
*/
package com.intellectualsites.commands.sender;

View file

@ -40,6 +40,7 @@ import java.util.Optional;
class CommandTreeTest {
private static final int EXPECTED_INPUT_NUMBER = 15;
private static CommandManager<CommandSender, SimpleCommandMeta> commandManager;
@BeforeAll
@ -51,26 +52,38 @@ class CommandTreeTest {
.withComponent(StaticComponent.required("two")).withPermission("no").build())
.registerCommand(commandManager.commandBuilder("test", SimpleCommandMeta.empty())
.withComponent(StaticComponent.required("opt"))
.withComponent(IntegerComponent.optional("num", 15)).build());
.withComponent(IntegerComponent
.optional("num", EXPECTED_INPUT_NUMBER))
.build());
}
@Test
void parse() {
final Optional<Command<CommandSender, SimpleCommandMeta>> command = commandManager.getCommandTree().parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
Arrays.asList("test", "one")));
final Optional<Command<CommandSender, SimpleCommandMeta>> command = commandManager.getCommandTree()
.parse(new CommandContext<>(
new TestCommandSender()),
new LinkedList<>(
Arrays.asList("test",
"one")));
Assertions.assertTrue(command.isPresent());
Assertions.assertThrows(NoPermissionException.class, () -> commandManager.getCommandTree().parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
Arrays.asList("test", "two"))));
commandManager.getCommandTree().parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt")))
Assertions.assertThrows(NoPermissionException.class, () -> commandManager.getCommandTree()
.parse(new CommandContext<>(
new TestCommandSender()),
new LinkedList<>(
Arrays.asList("test", "two"))));
commandManager.getCommandTree()
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt")))
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
commandManager.getCommandTree().parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt", "12")))
commandManager.getCommandTree()
.parse(new CommandContext<>(new TestCommandSender()), new LinkedList<>(Arrays.asList("test", "opt", "12")))
.ifPresent(c -> c.getCommandExecutionHandler().execute(new CommandContext<>(new TestCommandSender())));
}
@Test
void getSuggestions() {
Assertions.assertFalse(commandManager.getCommandTree().getSuggestions(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
Collections.singletonList("test"))).isEmpty());
Assertions.assertFalse(
commandManager.getCommandTree().getSuggestions(new CommandContext<>(new TestCommandSender()), new LinkedList<>(
Collections.singletonList("test"))).isEmpty());
}
}

View file

@ -38,7 +38,7 @@ public class TestCommandManager extends CommandManager<CommandSender, SimpleComm
@Nonnull
@Override
public SimpleCommandMeta createDefaultCommandMeta() {
public final SimpleCommandMeta createDefaultCommandMeta() {
return SimpleCommandMeta.empty();
}

View file

@ -30,7 +30,7 @@ import javax.annotation.Nonnull;
public class TestCommandSender implements CommandSender {
@Override
public boolean hasPermission(@Nonnull final String permission) {
public final boolean hasPermission(@Nonnull final String permission) {
if (permission.equalsIgnoreCase("no")) {
return false;
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* Command tests
*/
package com.intellectualsites.commands;

View file

@ -49,13 +49,23 @@ import java.util.function.Function;
*/
public class JLineCommandManager extends CommandManager<JLineCommandSender, SimpleCommandMeta> implements Completer {
/**
* Construct a new JLine command manager
*
* @param executionCoordinatorFunction Function producing a new coordinator
*/
public JLineCommandManager(@Nonnull final Function<CommandTree<JLineCommandSender, SimpleCommandMeta>,
CommandExecutionCoordinator<JLineCommandSender, SimpleCommandMeta>> executionCoordinatorFunction) {
super(executionCoordinatorFunction, CommandRegistrationHandler.nullCommandRegistrationHandler());
}
public static void main(String[] args) throws Exception {
// TODO: REMOVE THIS!!!!
/**
* Main method
*
* @param args Arguments
* @throws Exception Any and all exceptions
*/
public static void main(final String[] args) throws Exception {
final JLineCommandManager jLineCommandManager = new JLineCommandManager(CommandExecutionCoordinator.simpleCoordinator());
final Terminal terminal = TerminalBuilder.builder().build();
LineReader lineReader = LineReaderBuilder.builder()
@ -74,7 +84,8 @@ public class JLineCommandManager extends CommandManager<JLineCommandSender, Simp
.withComponent(String.class, "string", builder ->
builder.asRequired()
.withParser(((commandContext, inputQueue) -> {
final StringBuilder stringBuilder = new StringBuilder();
final StringBuilder stringBuilder =
new StringBuilder();
while (!inputQueue.isEmpty()) {
stringBuilder.append(inputQueue.remove());
if (!inputQueue.isEmpty()) {
@ -86,16 +97,16 @@ public class JLineCommandManager extends CommandManager<JLineCommandSender, Simp
})).build())
.withHandler(commandContext -> commandContext.get("string")
.ifPresent(
System.out::println))
System.out::println))
.build())
.registerCommand(jLineCommandManager.commandBuilder("test", SimpleCommandMeta.empty())
.withComponent(StaticComponent.required("one"))
.withHandler(commandContext -> System.out.println("Test (1)"))
.build())
.withComponent(StaticComponent.required("one"))
.withHandler(commandContext -> System.out.println("Test (1)"))
.build())
.registerCommand(jLineCommandManager.commandBuilder("test", SimpleCommandMeta.empty())
.withComponent(StaticComponent.required("two"))
.withHandler(commandContext -> System.out.println("Test (2)"))
.build());
.withComponent(StaticComponent.required("two"))
.withHandler(commandContext -> System.out.println("Test (2)"))
.build());
System.out.println("Ready...");
while (!shouldStop[0]) {
final String line = lineReader.readLine();
@ -127,7 +138,7 @@ public class JLineCommandManager extends CommandManager<JLineCommandSender, Simp
}
@Override
public void complete(@Nonnull final LineReader lineReader,
public final void complete(@Nonnull final LineReader lineReader,
@Nonnull final ParsedLine parsedLine,
@Nonnull final List<Candidate> list) {
final String line = parsedLine.line();
@ -140,7 +151,7 @@ public class JLineCommandManager extends CommandManager<JLineCommandSender, Simp
@Nonnull
@Override
public SimpleCommandMeta createDefaultCommandMeta() {
public final SimpleCommandMeta createDefaultCommandMeta() {
return SimpleCommandMeta.empty();
}

View file

@ -30,7 +30,7 @@ import javax.annotation.Nonnull;
public class JLineCommandSender implements CommandSender {
@Override
public boolean hasPermission(@Nonnull final String permission) {
public final boolean hasPermission(@Nonnull final String permission) {
return true;
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* cloud implementation for JLine3
*/
package com.intellectualsites.commands.jline;

View file

@ -46,7 +46,7 @@ public class BukkitCommandManager extends CommandManager<BukkitCommandSender, Bu
*/
public BukkitCommandManager(@Nonnull final Plugin owningPlugin,
@Nonnull final Function<CommandTree<BukkitCommandSender, BukkitCommandMeta>,
CommandExecutionCoordinator<BukkitCommandSender, BukkitCommandMeta>> commandExecutionCoordinator)
CommandExecutionCoordinator<BukkitCommandSender, BukkitCommandMeta>> commandExecutionCoordinator)
throws Exception {
super(commandExecutionCoordinator, new BukkitPluginRegistrationHandler());
((BukkitPluginRegistrationHandler) this.getCommandRegistrationHandler()).initialize(this);
@ -63,6 +63,11 @@ public class BukkitCommandManager extends CommandManager<BukkitCommandSender, Bu
return this.owningPlugin;
}
/**
* Create default command meta data
*
* @return Meta data
*/
@Nonnull
@Override
public BukkitCommandMeta createDefaultCommandMeta() {

View file

@ -29,6 +29,11 @@ import javax.annotation.Nonnull;
public class BukkitCommandMeta extends SimpleCommandMeta {
/**
* Bukkit command meta data
*
* @param simpleCommandMeta Simple command meta data instance that gets mirrored
*/
public BukkitCommandMeta(@Nonnull final SimpleCommandMeta simpleCommandMeta) {
super(simpleCommandMeta.getAll());
}

View file

@ -32,15 +32,27 @@ public final class BukkitCommandMetaBuilder {
private BukkitCommandMetaBuilder() {
}
/**
* Create a new builder stage 1
*
* @return Builder instance
*/
@Nonnull public static BuilderStage1 builder() {
return new BuilderStage1();
}
public static final class BuilderStage1 {
private BuilderStage1() {
}
/**
* Set the command description
*
* @param description Command description
* @return Builder instance
*/
@Nonnull public BuilderStage2 withDescription(@Nonnull final String description) {
return new BuilderStage2(description);
}
@ -56,6 +68,11 @@ public final class BukkitCommandMetaBuilder {
this.description = description;
}
/**
* Build the command meta instance
*
* @return Meta instance
*/
@Nonnull public BukkitCommandMeta build() {
return new BukkitCommandMeta(CommandMeta.simple().with("description", this.description).build());
}

View file

@ -77,7 +77,7 @@ public abstract class BukkitCommandSender implements CommandSender {
}
@Override
public boolean equals(final Object o) {
public final boolean equals(final Object o) {
if (this == o) {
return true;
}
@ -89,7 +89,7 @@ public abstract class BukkitCommandSender implements CommandSender {
}
@Override
public int hashCode() {
public final int hashCode() {
return Objects.hashCode(internalSender);
}
@ -120,7 +120,7 @@ public abstract class BukkitCommandSender implements CommandSender {
public abstract Player asPlayer();
@Override
public boolean hasPermission(@Nonnull final String permission) {
public final boolean hasPermission(@Nonnull final String permission) {
return this.internalSender.hasPermission(permission);
}

View file

@ -52,8 +52,8 @@ final class BukkitPluginRegistrationHandler implements CommandRegistrationHandle
final Field knownCommands = SimpleCommandMap.class.getDeclaredField("knownCommands");
knownCommands.setAccessible(true);
@SuppressWarnings("ALL")
final Map<String, org.bukkit.command.Command> bukkitCommands = (Map<String, org.bukkit.command.Command>) knownCommands.get(
commandMap);
final Map<String, org.bukkit.command.Command> bukkitCommands =
(Map<String, org.bukkit.command.Command>) knownCommands.get(commandMap);
this.bukkitCommands = bukkitCommands;
this.bukkitCommandManager = bukkitCommandManager;
}

View file

@ -0,0 +1,28 @@
//
// MIT License
//
// Copyright (c) 2020 Alexander Söderberg
//
// 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.
//
/**
* cloud implementation for Bukkit 1.8-1.16
*/
package com.intellectualsites.commands;

15
pom.xml
View file

@ -47,6 +47,21 @@
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<configLocation>checkstyle.xml</configLocation>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>