Skip to content

Commit

Permalink
Make commands use exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
ExE-Boss committed Jan 13, 2017
1 parent f4ce57f commit b100ef4
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 43 deletions.
4 changes: 2 additions & 2 deletions src/main/java/nova/commands/Args.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,8 @@ public Stream<Object> parallelStream() {
public int hashCode() {
int hash = 5;
hash = 97 * hash + Arrays.deepHashCode(this.requiredArgs);
hash = 97 * hash + this.optionalArgsString.hashCode();
hash = 97 * hash + this.optionalArgsChar.hashCode();
hash = 97 * hash + Objects.hashCode(this.optionalArgsString);
hash = 97 * hash + Objects.hashCode(this.optionalArgsChar);
return hash;
}

Expand Down
13 changes: 8 additions & 5 deletions src/main/java/nova/commands/ArgsParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package nova.commands;

import nova.commands.exception.CommandParseException;
import nova.core.retention.Data;
import nova.core.util.EnumSelector;

Expand Down Expand Up @@ -181,10 +182,10 @@ public ArgsParser opt(char shortName) {
* After this method is called, no more edits are allowed.
*
* @return The parsed {@link Args} instance.
* @throws IllegalStateException The {@link #args(java.lang.Class...)}
* @throws CommandParseException The {@link #args(java.lang.Class...)}
* hasn't been called and the constructor arguments parameter isn't empty.
*/
public Args parse() throws IllegalArgumentException {
public Args parse() throws CommandParseException {
if (parsed != null)
return parsed;

Expand All @@ -194,7 +195,7 @@ public Args parse() throws IllegalArgumentException {
}

if (required.length == 0)
throw new IllegalStateException("Cannot parse ArgParser without specifying required arguments.");
throw new CommandParseException("Cannot parse ArgParser without specifying required arguments.", Errors.UNSPECIFIED_REQUIRED_ARGUMENTS);

int requiredPos = 0;
boolean continuos = false;
Expand Down Expand Up @@ -296,7 +297,7 @@ public Args parse() throws IllegalArgumentException {
errored.lock();

if (!errored.blocksAll())
throw new IllegalArgumentException("Errors with command: " + errored.toSet());
throw new CommandParseException("Errors with command", errored);

parsed = new Args(required, optsStr, optsChar);
return parsed;
Expand Down Expand Up @@ -371,7 +372,9 @@ public boolean locked() {
return parsed != null;
}

private static enum Errors {
public static enum Errors {
PARSER_IS_LOCKED("Parser is locked"),
UNSPECIFIED_REQUIRED_ARGUMENTS("Required arguments unspecified"),
TOO_LONG("Arguments too long"),
UNENDED_QUOTES("Unended quotes"),
UNKNOWN_OPTIONAL("Unknown optional argument");
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/nova/commands/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package nova.commands;

import nova.commands.exception.CommandException;
import nova.core.entity.component.Player;
import nova.core.event.bus.Event;
import nova.core.event.bus.EventBus;
Expand Down Expand Up @@ -61,8 +62,10 @@ public Command(String command) {
* @param player The player who issued this command.
* Won't be present if the command was issued from the server command line.
* @param args The arguments that were given by the player.
*
* @throws CommandException If something goes wrong during command execution.
*/
public abstract void handle(Optional<Player> player, String... args);
public abstract void handle(Optional<Player> player, String... args) throws CommandException;

/**
* Get a list of possible ways the command could auto-complete.
Expand All @@ -74,7 +77,7 @@ public Command(String command) {
* @param args The already completed arguments
* @return The list. Must not be null.
*/
public List<String> getAutocompleteList(Optional<Player> player, int pos, String startsWith, String... args) {
public List<String> getAutocompleteList(Optional<Player> player, String... args) {
return Collections.emptyList();
}

Expand Down
20 changes: 0 additions & 20 deletions src/main/java/nova/commands/event/CommandEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,6 @@ public CommandHandleEvent(Optional<Player> player, Command command, String... ar
}
}

/**
* Event is triggered when a command execution fails.
*/
public static class CommandHandleErrorEvent extends CommandHandleEvent {
public final Optional<String> message;
public final Object[] messageParameters;

public CommandHandleErrorEvent(Optional<Player> player, Command command, String... args) {
super(player, command, args);
this.message = Optional.empty();
this.messageParameters = new Object[0];
}

public CommandHandleErrorEvent(Optional<Player> player, Command command, String[] args, String message, Object... messageParameters) {
super(player, command, args);
this.message = Optional.ofNullable(message);
this.messageParameters = Arrays.copyOf(messageParameters, messageParameters.length);
}
}

/**
* Event is triggered when a Command is registered.
*
Expand Down
69 changes: 69 additions & 0 deletions src/main/java/nova/commands/exception/CommandException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2017 NOVA, All rights reserved.
* This library is free software, licensed under GNU Lesser General Public License version 3
*
* This file is part of NOVA.
*
* NOVA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NOVA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NOVA. If not, see <http://www.gnu.org/licenses/>.
*/

package nova.commands.exception;

import nova.core.util.exception.NovaException;

import java.util.Arrays;
import java.util.Optional;

/**
* @author ExE Boss
*/
public class CommandException extends NovaException {

private static final long serialVersionUID = 1L;
private final Object[] arguments;

public CommandException() {
this.arguments = null;
}

public CommandException(String message, Object... parameters) {
super(message, parameters);
this.arguments = Arrays.copyOf(parameters, parameters.length);
}

public CommandException(String message) {
super(message);
this.arguments = null;
}

public CommandException(String message, Throwable cause) {
super(message, cause);
this.arguments = null;
}

public CommandException(String message, Throwable cause, Object... parameters) {
super(message, parameters);
this.initCause(cause);
this.arguments = Arrays.copyOf(parameters, parameters.length);
}

public CommandException(Throwable cause) {
super(cause);
this.arguments = null;
}

public Optional<Object[]> getArguments() {
return Optional.ofNullable(Arrays.copyOf(arguments, arguments.length));
}
}
77 changes: 77 additions & 0 deletions src/main/java/nova/commands/exception/CommandParseException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2017 NOVA, All rights reserved.
* This library is free software, licensed under GNU Lesser General Public License version 3
*
* This file is part of NOVA.
*
* NOVA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NOVA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NOVA. If not, see <http://www.gnu.org/licenses/>.
*/

package nova.commands.exception;

import nova.commands.ArgsParser;
import nova.core.util.EnumSelector;

import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;

/**
* @author ExE Boss
*/
public class CommandParseException extends CommandException {

private static final long serialVersionUID = 1L;

private final Set<ArgsParser.Errors> errors;

public CommandParseException(String message) {
super(message);
this.errors = null;
}

public CommandParseException(String message, Throwable cause) {
super(message, cause);
this.errors = null;
}

private CommandParseException(String message, Set<ArgsParser.Errors> errors) {
super(message + ": " + errors);
this.errors = errors;
}

public CommandParseException(String message, ArgsParser.Errors... errors) {
this(message, toEnumSet(errors));
}

public CommandParseException(String message, EnumSet<ArgsParser.Errors> errors) {
this(message, Collections.unmodifiableSet(errors));
}

public CommandParseException(String message, EnumSelector<ArgsParser.Errors> errors) {
this(message, errors.toSet());
}

public Optional<Set<ArgsParser.Errors>> getErrors() {
return Optional.ofNullable(errors);
}

private static EnumSet<ArgsParser.Errors> toEnumSet(ArgsParser.Errors... errors) {
EnumSet<ArgsParser.Errors> set = EnumSet.noneOf(ArgsParser.Errors.class);
set.addAll(Arrays.asList(errors));
return set;
}
}
6 changes: 6 additions & 0 deletions src/test/java/nova/commands/CommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package nova.commands;

import nova.commands.exception.CommandException;
import nova.core.event.bus.Event;
import nova.core.event.bus.EventBus;
import org.junit.Before;
Expand Down Expand Up @@ -55,6 +56,11 @@ public void testHandle() {
command.handle(null, new String[]{"test"}, Optional.of(events));
}

@Test(expected = CommandException.class)
public void testHandleException() {
command.handleError(null, new String[0], "Message");
}

@Test
public void testGetCommandName() {
assertThat(command.getCommandName()).isEqualTo("Test_Command");
Expand Down
12 changes: 6 additions & 6 deletions src/test/java/nova/commands/TestCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*/
package nova.commands;

import nova.commands.event.CommandEvent;
import nova.commands.exception.CommandException;
import nova.core.entity.component.Player;
import nova.core.event.bus.Event;
import nova.core.event.bus.EventBus;
Expand All @@ -39,22 +39,22 @@ public TestCommand(String command) {
super(command);
}

public void handle(Optional<Player> player, String[] args, Optional<EventBus<Event>> events) {
public void handle(Optional<Player> player, String[] args, Optional<EventBus<Event>> events) throws CommandException {
Args argsObj = new ArgsParser(args).args(String.class).parse();
events.ifPresent(evt -> evt.publish(new TestCommandHandleEvent(player, this, argsObj)));
}

public void handleError(Optional<Player> player, String[] args, Optional<EventBus<Event>> events, String message) {
events.ifPresent(evt -> evt.publish(new CommandEvent.CommandHandleErrorEvent(player, this, args, message)));
public void handleError(Optional<Player> player, String[] args, String message) throws CommandException {
throw new CommandException(message);
}

@Override
public void handle(Optional<Player> player, String... args) {
public void handle(Optional<Player> player, String... args) throws CommandException {
this.handle(player, args, Optional.empty());
}

@Override
public String getCommandUsage(Optional<Player> player) {
public String getCommandUsage(Optional<Player> player) throws CommandException {
return "";
}
}
9 changes: 1 addition & 8 deletions src/test/java/nova/commands/event/CommandEventTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package nova.commands.event;

import nova.commands.TestCommand;
import nova.commands.TestCommandHandleEvent;
import nova.core.event.bus.Event;
import nova.core.event.bus.EventBus;
import org.junit.Before;
Expand All @@ -44,14 +45,6 @@ public void setUp() {
command = new TestCommand();
}

@Test
public void testCommandHandleErrorEvent() {
events.on(CommandEvent.CommandHandleErrorEvent.class).bind(evt -> {
evt.message.ifPresent(msg -> assertThat(msg).isEqualTo("Message"));
});
command.handleError(null, new String[0], Optional.of(events), "Message");
}

@Test
public void testCommandRegister() {
events.on(CommandEvent.Register.class).bind(evt -> {
Expand Down

0 comments on commit b100ef4

Please sign in to comment.