diff --git a/common/src/main/java/com/dfsek/terra/api/command/ExecutionState.java b/common/src/main/java/com/dfsek/terra/api/command/ExecutionState.java index 515993a0b..b1665ff90 100644 --- a/common/src/main/java/com/dfsek/terra/api/command/ExecutionState.java +++ b/common/src/main/java/com/dfsek/terra/api/command/ExecutionState.java @@ -6,15 +6,15 @@ import java.util.Map; import java.util.Set; public final class ExecutionState { - private final Set flags = new HashSet<>(); + private final Set switches = new HashSet<>(); private final Map args = new HashMap<>(); protected ExecutionState() { } - protected void addFlag(String flag) { - flags.add(flag); + protected void addSwitch(String flag) { + switches.add(flag); } protected void addArgument(String arg, String value) { @@ -39,7 +39,7 @@ public final class ExecutionState { return (T) value; } - public boolean hasFlag(String flag) { - return flags.contains(flag); + public boolean hasSwitch(String flag) { + return switches.contains(flag); } } diff --git a/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java b/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java index 3a89936a1..57360bb0e 100644 --- a/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java +++ b/common/src/main/java/com/dfsek/terra/api/command/TerraCommandManager.java @@ -3,9 +3,11 @@ package com.dfsek.terra.api.command; import com.dfsek.terra.api.command.annotation.Argument; import com.dfsek.terra.api.command.annotation.Command; import com.dfsek.terra.api.command.annotation.Subcommand; +import com.dfsek.terra.api.command.annotation.Switch; import com.dfsek.terra.api.command.exception.CommandException; import com.dfsek.terra.api.command.exception.InvalidArgumentsException; import com.dfsek.terra.api.command.exception.MalformedCommandException; +import com.dfsek.terra.api.command.exception.SwitchFormatException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -62,14 +64,25 @@ public class TerraCommandManager implements CommandManager { String arg = args.get(0); - if(arg.startsWith("-")) { // flags have started. - if(req) throw new InvalidArgumentsException("Flags must come after arguments."); + if(arg.startsWith("-")) { // switches have started. + if(req) throw new InvalidArgumentsException("Switches must come after arguments."); break; } state.addArgument(argument.value(), args.remove(0)); } + while(!args.isEmpty()) { + String aSwitch = args.remove(0); + if(!aSwitch.startsWith("-")) throw new SwitchFormatException("Invalid switch \"" + aSwitch + "\""); + + String val = aSwitch.substring(1); // remove dash + + if(!commandHolder.switches.containsKey(val)) throw new SwitchFormatException("No such switch \"" + aSwitch + "\""); + + state.addSwitch(commandHolder.switches.get(val)); + } + invoke(commandClass, state); } @@ -91,6 +104,7 @@ public class TerraCommandManager implements CommandManager { private static final class CommandHolder { private final Class clazz; private final Map subcommands = new HashMap<>(); + private final Map switches = new HashMap<>(); private CommandHolder(Class clazz) { this.clazz = clazz; @@ -103,6 +117,12 @@ public class TerraCommandManager implements CommandManager { subcommands.put(alias, holder); } } + for(Switch aSwitch : command.switches()) { + switches.put(aSwitch.value(), aSwitch.value()); + for(String alias : aSwitch.aliases()) { + switches.put(alias, aSwitch.value()); + } + } } } } diff --git a/common/src/main/java/com/dfsek/terra/api/command/annotation/Command.java b/common/src/main/java/com/dfsek/terra/api/command/annotation/Command.java index 01cd11e97..fb5fd81ea 100644 --- a/common/src/main/java/com/dfsek/terra/api/command/annotation/Command.java +++ b/common/src/main/java/com/dfsek/terra/api/command/annotation/Command.java @@ -10,7 +10,7 @@ import java.lang.annotation.Target; public @interface Command { Argument[] arguments() default {}; - Flag[] flags() default {}; + Switch[] switches() default {}; Subcommand[] subcommands() default {}; diff --git a/common/src/main/java/com/dfsek/terra/api/command/annotation/Flag.java b/common/src/main/java/com/dfsek/terra/api/command/annotation/Switch.java similarity index 75% rename from common/src/main/java/com/dfsek/terra/api/command/annotation/Flag.java rename to common/src/main/java/com/dfsek/terra/api/command/annotation/Switch.java index 836b0eb0f..16ea3e21a 100644 --- a/common/src/main/java/com/dfsek/terra/api/command/annotation/Flag.java +++ b/common/src/main/java/com/dfsek/terra/api/command/annotation/Switch.java @@ -7,10 +7,8 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) -public @interface Flag { +public @interface Switch { String value(); - String shorthand() default ""; - - String defaultValue() default ""; + String[] aliases() default {}; } diff --git a/common/src/main/java/com/dfsek/terra/api/command/exception/SwitchFormatException.java b/common/src/main/java/com/dfsek/terra/api/command/exception/SwitchFormatException.java new file mode 100644 index 000000000..c7e545ae7 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/command/exception/SwitchFormatException.java @@ -0,0 +1,13 @@ +package com.dfsek.terra.api.command.exception; + +public class SwitchFormatException extends CommandException { + private static final long serialVersionUID = -965858989317844628L; + + public SwitchFormatException(String message) { + super(message); + } + + public SwitchFormatException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/common/src/main/java/com/dfsek/terra/commands/structure/StructureLoadCommand.java b/common/src/main/java/com/dfsek/terra/commands/structure/StructureLoadCommand.java index 49ced1583..9182b5bbe 100644 --- a/common/src/main/java/com/dfsek/terra/commands/structure/StructureLoadCommand.java +++ b/common/src/main/java/com/dfsek/terra/commands/structure/StructureLoadCommand.java @@ -2,18 +2,21 @@ package com.dfsek.terra.commands.structure; import com.dfsek.terra.api.command.CommandTemplate; import com.dfsek.terra.api.command.ExecutionState; +import com.dfsek.terra.api.command.annotation.Argument; import com.dfsek.terra.api.command.annotation.Command; -import com.dfsek.terra.api.command.annotation.Flag; +import com.dfsek.terra.api.command.annotation.Switch; @Command( - flags = { - @Flag(value = "rotation", - defaultValue = "0", - shorthand = "r" - ), - @Flag(value = "load", - defaultValue = "FULL", - shorthand = "l" + arguments = { + @Argument( + value = "rotation", + required = false, + type = int.class + ) + }, + switches = { + @Switch(value = "chunk", + aliases = "c" ) } ) diff --git a/common/src/test/java/command/CommandTest.java b/common/src/test/java/command/CommandTest.java index 4c2a7c987..1a7df8ccf 100644 --- a/common/src/test/java/command/CommandTest.java +++ b/common/src/test/java/command/CommandTest.java @@ -7,6 +7,7 @@ import com.dfsek.terra.api.command.TerraCommandManager; import com.dfsek.terra.api.command.annotation.Argument; import com.dfsek.terra.api.command.annotation.Command; import com.dfsek.terra.api.command.annotation.Subcommand; +import com.dfsek.terra.api.command.annotation.Switch; import com.dfsek.terra.api.command.exception.CommandException; import com.dfsek.terra.api.command.exception.InvalidArgumentsException; import com.dfsek.terra.api.command.exception.MalformedCommandException; @@ -64,6 +65,24 @@ public class CommandTest { } } + @Test + public void switches() throws CommandException { + CommandManager manager = new TerraCommandManager(); + manager.register("test", DemoSwitchCommand.class); + + manager.execute("test", Arrays.asList("first", "2")); + manager.execute("test", Arrays.asList("first", "2", "3.4")); + + manager.execute("test", Arrays.asList("first", "2", "-a")); + manager.execute("test", Arrays.asList("first", "2", "3.4", "-b")); + + manager.execute("test", Arrays.asList("first", "2", "-aSwitch")); + manager.execute("test", Arrays.asList("first", "2", "3.4", "-bSwitch")); + + manager.execute("test", Arrays.asList("first", "2", "-aSwitch", "-b")); + manager.execute("test", Arrays.asList("first", "2", "3.4", "-bSwitch", "-a")); + } + @Command( arguments = { @Argument(value = "arg0"), @@ -84,6 +103,34 @@ public class CommandTest { } } + @Command( + arguments = { + @Argument(value = "arg0"), + @Argument(value = "arg1", type = int.class), + @Argument(value = "arg2", type = double.class, required = false) + }, + switches = { + @Switch(value = "a", aliases = {"aSwitch"}), + @Switch(value = "b", aliases = {"bSwitch"}) + } + ) + public static final class DemoSwitchCommand implements CommandTemplate { + + @Override + public void execute(ExecutionState state) { + System.out.println(state.getArgument("arg0", String.class)); + System.out.println(state.getArgument("arg1", int.class)); + try { + System.out.println(state.getArgument("arg2", double.class)); + } catch(IllegalArgumentException e) { + System.out.println("arg2 undefined."); + } + + System.out.println("A: " + state.hasSwitch("a")); + System.out.println("B: " + state.hasSwitch("b")); + } + } + @Command( arguments = { @Argument(value = "arg0"),