Refactor command parsing

This commit is contained in:
Arne Keller 2020-02-19 19:28:06 +01:00
parent 7e39a97dd4
commit 1f3802d380
20 changed files with 431 additions and 364 deletions

View File

@ -5,6 +5,12 @@ import edu.kit.informatik.model.Vector2D;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ADD_SWITCH;
import static edu.kit.informatik.ui.command.CommandFactory.VECTOR;
/**
* Command used to add a switch to the rail network.
*
@ -12,31 +18,21 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version 1.0
*/
public class AddSwitch extends Command {
private static final Pattern ADD_SWITCH_ARGUMENTS
= Pattern.compile(" \\((" + VECTOR + ")\\) -> \\((" + VECTOR + ")\\),\\((" + VECTOR + ")\\)");
/**
* Start position of the switch to add.
*/
private final Vector2D start;
private Vector2D start;
/**
* End position 1 of the switch to add.
*/
private final Vector2D end1;
private Vector2D end1;
/**
* End position 2 of the switch to add.
*/
private final Vector2D end2;
/**
* Construct a new 'add switch' command.
* @param start start position
* @param end1 end position 1
* @param end2 end position 2
*/
public AddSwitch(final Vector2D start, final Vector2D end1, final Vector2D end2) {
// make sure caller can not modify internal state
this.start = new Vector2D(start);
this.end1 = new Vector2D(end1);
this.end2 = new Vector2D(end2);
}
private Vector2D end2;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -47,4 +43,18 @@ public class AddSwitch extends Command {
Terminal.printLine(id);
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(ADD_SWITCH)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = ADD_SWITCH_ARGUMENTS.matcher(input.substring(ADD_SWITCH.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid add switch argument syntax");
}
start = Vector2D.parse(matcher.group(1));
end1 = Vector2D.parse(matcher.group(2));
end2 = Vector2D.parse(matcher.group(3));
}
}

View File

@ -5,6 +5,12 @@ import edu.kit.informatik.model.Vector2D;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ADD_TRACK;
import static edu.kit.informatik.ui.command.CommandFactory.VECTOR;
/**
* Command used to add a track to the rail network.
*
@ -12,25 +18,17 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version 1.0
*/
public class AddTrack extends Command {
private static final Pattern ADD_TRACK_ARGUMENTS
= Pattern.compile(" \\((" + VECTOR + ")\\) -> \\((" + VECTOR + ")\\)");
/**
* Start position of the new track.
*/
private final Vector2D start;
private Vector2D start;
/**
* End position of the new track.
*/
private final Vector2D end;
/**
* Construct a new 'add track' command.
* @param start position of the start of the track
* @param end position of the end of the track
*/
public AddTrack(final Vector2D start, final Vector2D end) {
// make sure caller can not modify internal state
this.start = new Vector2D(start);
this.end = new Vector2D(end);
}
private Vector2D end;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -41,4 +39,17 @@ public class AddTrack extends Command {
Terminal.printLine(id);
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(ADD_TRACK)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = ADD_TRACK_ARGUMENTS.matcher(input.substring(ADD_TRACK.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid add track argument syntax");
}
start = Vector2D.parse(matcher.group(1));
end = Vector2D.parse(matcher.group(2));
}
}

View File

@ -5,6 +5,13 @@ import edu.kit.informatik.model.RollingStock;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ADD_TRAIN;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
import static edu.kit.informatik.ui.command.CommandFactory.ROLLING_STOCK_IDENTIFIER;
/**
* Command used to construct a new train or modify an existing train.
*
@ -12,24 +19,17 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version 1.0
*/
public class AddTrain extends Command {
private static final Pattern ADD_TRAIN_ARGUMENTS
= Pattern.compile(" (" + NUMBER + ") (" + ROLLING_STOCK_IDENTIFIER + ")");
/**
* Identifier of the train to add or modify.
*/
private final int trainId;
private int trainId;
/**
* Identifier of the rolling stock to add.
*/
private final String rollingStockId;
/**
* Construct a new 'add train' command.
* @param trainId identifier of the train to be added/modified
* @param rollingStockId identifier of the rolling to be added to the train
*/
public AddTrain(final int trainId, final String rollingStockId) {
this.trainId = trainId;
this.rollingStockId = rollingStockId;
}
private String rollingStockId;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -38,4 +38,17 @@ public class AddTrain extends Command {
Terminal.printLine(String.format("%s %s added to train %d",
rollingStock.description(), rollingStock.getIdentifier(), trainId));
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(ADD_TRAIN)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = ADD_TRAIN_ARGUMENTS.matcher(input.substring(ADD_TRAIN.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid add train arguments");
}
trainId = Integer.parseInt(matcher.group(1));
rollingStockId = matcher.group(2);
}
}

View File

@ -17,4 +17,11 @@ public abstract class Command {
* @throws InvalidInputException on invalid user input
*/
public abstract void apply(ModelRailwaySimulation simulation) throws InvalidInputException;
/**
* Parse user input into the command object.
* @param input one line of user input
* @throws InvalidInputException if user input is in any way invalid
*/
public abstract void parse(String input) throws InvalidInputException;
}

View File

@ -1,13 +1,7 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.Vector2D;
import edu.kit.informatik.ui.CoachType;
import edu.kit.informatik.ui.EngineType;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Factory used to parse user input into commands.
*
@ -15,48 +9,30 @@ import java.util.regex.Pattern;
* @version 1.0
*/
public final class CommandFactory {
private static final String NUMBER = "[+-]?\\d+";
private static final String VECTOR = NUMBER + "," + NUMBER;
private static final String ALPHANUMERIC_WORD = "[\\p{L}\\d]+";
private static final String ROLLING_STOCK_IDENTIFIER
public static final String NUMBER = "[+-]?\\d+";
public static final String VECTOR = NUMBER + "," + NUMBER;
public static final String ALPHANUMERIC_WORD = "[\\p{L}\\d]+";
public static final String ROLLING_STOCK_IDENTIFIER
= "(" + ALPHANUMERIC_WORD + "-" + ALPHANUMERIC_WORD + ")|W" + NUMBER;
private static final String ADD_TRACK = "add track";
private static final Pattern ADD_TRACK_ARGUMENTS
= Pattern.compile(" \\((" + VECTOR + ")\\) -> \\((" + VECTOR + ")\\)");
private static final String ADD_SWITCH = "add switch";
private static final Pattern ADD_SWITCH_ARGUMENTS
= Pattern.compile(" \\((" + VECTOR + ")\\) -> \\((" + VECTOR + ")\\),\\((" + VECTOR + ")\\)");
private static final String DELETE_TRACK = "delete track";
private static final String LIST_TRACKS = "list tracks";
private static final String SET_SWITCH = "set switch";
private static final Pattern SET_SWITCH_ARGUMENTS
= Pattern.compile(" (" + NUMBER + ") position \\((" + VECTOR + ")\\)");
private static final String CREATE_ENGINE = "create engine";
private static final Pattern CREATE_ENGINE_ARGUMENTS
= Pattern.compile(" (electrical|diesel|steam) (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") (" + NUMBER + ") (true|false) (true|false)");
private static final String LIST_ENGINES = "list engines";
private static final String CREATE_COACH = "create coach";
private static final Pattern CREATE_COACH_ARGUMENTS
= Pattern.compile(" (passenger|freight|special) (" + NUMBER + ") (true|false) (true|false)");
private static final String LIST_COACHES = "list coaches";
private static final String CREATE_TRAIN_SET = "create train-set";
private static final Pattern CREATE_TRAIN_SET_ARGUMENTS
= Pattern.compile(" (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") (" + NUMBER + ") (true|false) (true|false)");
private static final String LIST_TRAIN_SETS = "list train-sets";
private static final String DELETE_ROLLING_STOCK = "delete rolling stock";
private static final Pattern DELETE_ROLLING_STOCK_ARGUMENT
= Pattern.compile(" (" + ROLLING_STOCK_IDENTIFIER + ")");
private static final String ADD_TRAIN = "add train";
private static final Pattern ADD_TRAIN_ARGUMENTS
= Pattern.compile(" (" + NUMBER + ") (" + ROLLING_STOCK_IDENTIFIER + ")");
private static final String DELETE_TRAIN = "delete train";
private static final String LIST_TRAINS = "list trains";
private static final String SHOW_TRAIN = "show train";
private static final String PUT_TRAIN = "put train";
private static final Pattern PUT_TRAIN_ARGUMENTS
= Pattern.compile(" (" + NUMBER + ") at \\((" + VECTOR + ")\\) in direction (" + VECTOR + ")");
private static final String STEP = "step";
public static final String ADD_TRACK = "add track";
public static final String ADD_SWITCH = "add switch";
public static final String DELETE_TRACK = "delete track";
public static final String LIST_TRACKS = "list tracks";
public static final String SET_SWITCH = "set switch";
public static final String CREATE_ENGINE = "create engine";
public static final String LIST_ENGINES = "list engines";
public static final String CREATE_COACH = "create coach";
public static final String LIST_COACHES = "list coaches";
public static final String CREATE_TRAIN_SET = "create train-set";
public static final String LIST_TRAIN_SETS = "list train-sets";
public static final String DELETE_ROLLING_STOCK = "delete rolling stock";
public static final String ADD_TRAIN = "add train";
public static final String DELETE_TRAIN = "delete train";
public static final String LIST_TRAINS = "list trains";
public static final String SHOW_TRAIN = "show train";
public static final String PUT_TRAIN = "put train";
public static final String STEP = "step";
/**
* Utility class -> private constructor.
@ -72,158 +48,47 @@ public final class CommandFactory {
* @throws InvalidInputException if user input is invalid
*/
public static Command getCommand(final String command) throws InvalidInputException {
Command commandObject;
if (command.startsWith(ADD_TRACK)) {
String arguments = command.substring(ADD_TRACK.length());
Matcher matcher = ADD_TRACK_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid add track argument syntax");
}
Vector2D start = Vector2D.parse(matcher.group(1));
Vector2D end = Vector2D.parse(matcher.group(2));
return new AddTrack(start, end);
commandObject = new AddTrack();
} else if (command.startsWith(ADD_SWITCH)) {
String arguments = command.substring(ADD_SWITCH.length());
Matcher matcher = ADD_SWITCH_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid add switch argument syntax");
}
Vector2D start = Vector2D.parse(matcher.group(1));
Vector2D end1 = Vector2D.parse(matcher.group(2));
Vector2D end2 = Vector2D.parse(matcher.group(3));
return new AddSwitch(start, end1, end2);
commandObject = new AddSwitch();
} else if (command.startsWith(DELETE_TRACK)) {
String argument = command.substring(DELETE_TRACK.length());
if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid/missing delete track argument");
}
int id = Integer.parseInt(argument.substring(1));
return new DeleteTrack(id);
commandObject = new DeleteTrack();
} else if (command.startsWith(LIST_TRACKS)) {
if (command.length() > LIST_TRACKS.length()) {
throw new InvalidInputException("too many arguments for list tracks");
}
return new ListTracks();
commandObject = new ListTracks();
} else if (command.startsWith(SET_SWITCH)) {
String arguments = command.substring(SET_SWITCH.length());
Matcher matcher = SET_SWITCH_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid set switch argument syntax");
}
int id = Integer.parseInt(matcher.group(1));
Vector2D point = Vector2D.parse(matcher.group(2));
return new SetSwitch(id, point);
commandObject = new SetSwitch();
} else if (command.startsWith(CREATE_ENGINE)) {
String arguments = command.substring(CREATE_ENGINE.length());
Matcher matcher = CREATE_ENGINE_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid create engine argument syntax");
}
EngineType type = EngineType.parse(matcher.group(1));
String series = matcher.group(2);
if ("W".equals(series)) {
throw new InvalidInputException("invalid engine class/series");
}
String name = matcher.group(3);
int length = Integer.parseInt(matcher.group(4));
boolean couplingFront = Boolean.parseBoolean(matcher.group(5));
boolean couplingBack = Boolean.parseBoolean(matcher.group(6));
return new CreateEngine(type, series, name, length, couplingFront, couplingBack);
commandObject = new CreateEngine();
} else if (command.startsWith(LIST_ENGINES)) {
if (command.length() > LIST_ENGINES.length()) {
throw new InvalidInputException("too many list engines arguments");
}
return new ListEngines();
commandObject = new ListEngines();
} else if (command.startsWith(CREATE_COACH)) {
String arguments = command.substring(CREATE_COACH.length());
Matcher matcher = CREATE_COACH_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid create coach arguments");
}
CoachType type = CoachType.parse(matcher.group(1));
int length = Integer.parseInt(matcher.group(2));
boolean couplingFront = Boolean.parseBoolean(matcher.group(3));
boolean couplingBack = Boolean.parseBoolean(matcher.group(4));
return new CreateCoach(type, length, couplingFront, couplingBack);
commandObject = new CreateCoach();
} else if (command.startsWith(LIST_COACHES)) {
if (command.length() > LIST_COACHES.length()) {
throw new InvalidInputException("too many list coaches arguments");
}
return new ListCoaches();
commandObject = new ListCoaches();
} else if (command.startsWith(CREATE_TRAIN_SET)) {
String arguments = command.substring(CREATE_TRAIN_SET.length());
Matcher matcher = CREATE_TRAIN_SET_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid create train-set arguments");
}
String series = matcher.group(1);
if ("W".equals(series)) {
throw new InvalidInputException("invalid train-set class/series");
}
String name = matcher.group(2);
int length = Integer.parseInt(matcher.group(3));
boolean couplingFront = Boolean.parseBoolean(matcher.group(4));
boolean couplingBack = Boolean.parseBoolean(matcher.group(5));
return new CreateTrainSet(series, name, length, couplingFront, couplingBack);
commandObject = new CreateTrainSet();
} else if (command.startsWith(LIST_TRAIN_SETS)) {
if (command.length() > LIST_TRAIN_SETS.length()) {
throw new InvalidInputException("too many list train-sets arguments");
}
return new ListTrainSets();
commandObject = new ListTrainSets();
} else if (command.startsWith(DELETE_ROLLING_STOCK)) {
String argument = command.substring(DELETE_ROLLING_STOCK.length());
Matcher matcher = DELETE_ROLLING_STOCK_ARGUMENT.matcher(argument);
if (!matcher.matches()) {
throw new InvalidInputException("invalid delete rolling stock argument");
}
String id = matcher.group(1);
return new DeleteRollingStock(id);
commandObject = new DeleteRollingStock();
} else if (command.startsWith(ADD_TRAIN)) {
String arguments = command.substring(ADD_TRAIN.length());
Matcher matcher = ADD_TRAIN_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid add train arguments");
}
int trainId = Integer.parseInt(matcher.group(1));
String rollingStockId = matcher.group(2);
return new AddTrain(trainId, rollingStockId);
commandObject = new AddTrain();
} else if (command.startsWith(DELETE_TRAIN)) {
String argument = command.substring(DELETE_TRAIN.length());
if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid delete train argument");
}
int id = Integer.parseInt(argument.substring(1));
return new DeleteTrain(id);
commandObject = new DeleteTrain();
} else if (command.startsWith(LIST_TRAINS)) {
if (command.length() > LIST_TRAINS.length()) {
throw new InvalidInputException("too many list trains arguments");
}
return new ListTrains();
commandObject = new ListTrains();
} else if (command.startsWith(SHOW_TRAIN)) {
String argument = command.substring(SHOW_TRAIN.length());
if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid show train argument");
}
int id = Integer.parseInt(argument.substring(1));
return new ShowTrain(id);
commandObject = new ShowTrain();
} else if (command.startsWith(PUT_TRAIN)) {
String arguments = command.substring(PUT_TRAIN.length());
Matcher matcher = PUT_TRAIN_ARGUMENTS.matcher(arguments);
if (!matcher.matches()) {
throw new InvalidInputException("invalid put train arguments");
}
int id = Integer.parseInt(matcher.group(1));
Vector2D point = Vector2D.parse(matcher.group(2));
Vector2D direction = Vector2D.parse(matcher.group(3));
return new PutTrain(id, point, direction);
commandObject = new PutTrain();
} else if (command.startsWith(STEP)) {
String argument = command.substring(STEP.length());
if (!argument.matches(" [+-]?\\d+")) {
throw new InvalidInputException("invalid step argument");
}
short speed = Short.parseShort(argument.substring(1));
return new Step(speed);
commandObject = new Step();
} else {
throw new InvalidInputException("unknown command");
}
commandObject.parse(command);
return commandObject;
}
}

View File

@ -5,6 +5,12 @@ import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.CREATE_COACH;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
/**
* Command used to create a single coach.
*
@ -12,40 +18,25 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version 1.0
*/
public class CreateCoach extends Command {
private static final Pattern CREATE_COACH_ARGUMENTS
= Pattern.compile(" (passenger|freight|special) (" + NUMBER + ") (true|false) (true|false)");
/**
* Type of the new coach.
*/
private final CoachType type;
private CoachType type;
/**
* Length of the new coach.
*/
private final int length;
private int length;
/**
* Whether the new coach should have a front coupling.
*/
private final boolean couplingFront;
private boolean couplingFront;
/**
* Whether the new coach should have a back coupling.
*/
private final boolean couplingBack;
/**
* Create a new 'create coach' command.
* @param type type of the coach
* @param length length of the coach
* @param couplingFront whether the coach should have a front coupling
* @param couplingBack whether the coach should have a back coupling
*/
public CreateCoach(final CoachType type, final int length,
final boolean couplingFront, final boolean couplingBack) {
if (type == null) {
throw new IllegalArgumentException("coach type is null");
}
this.type = type;
this.length = length;
this.couplingFront = couplingFront;
this.couplingBack = couplingBack;
}
private boolean couplingBack;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -56,4 +47,19 @@ public class CreateCoach extends Command {
Terminal.printLine(id);
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(CREATE_COACH)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = CREATE_COACH_ARGUMENTS.matcher(input.substring(CREATE_COACH.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid create coach arguments");
}
type = CoachType.parse(matcher.group(1));
length = Integer.parseInt(matcher.group(2));
couplingFront = Boolean.parseBoolean(matcher.group(3));
couplingBack = Boolean.parseBoolean(matcher.group(4));
}
}

View File

@ -9,6 +9,13 @@ import edu.kit.informatik.model.SteamEngine;
import edu.kit.informatik.ui.EngineType;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ALPHANUMERIC_WORD;
import static edu.kit.informatik.ui.command.CommandFactory.CREATE_ENGINE;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
/**
* Command used to create a single engine.
*
@ -16,52 +23,33 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version 1.0
*/
public class CreateEngine extends Command {
private static final Pattern CREATE_ENGINE_ARGUMENTS
= Pattern.compile(" (electrical|diesel|steam) (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") (" + NUMBER + ") (true|false) (true|false)");
/**
* Type of the new engine.
*/
private final EngineType type;
private EngineType type;
/**
* Series (class) of the new engine.
*/
private final String series;
private String series;
/**
* Name of the new engine.
*/
private final String name;
private String name;
/**
* Length of the new engine.
*/
private final int length;
private int length;
/**
* Whether the new engine should have a front coupling.
*/
private final boolean couplingFront;
private boolean couplingFront;
/**
* Whether the new engine should have a back coupling.
*/
private final boolean couplingBack;
/**
* Construct a new 'create engine' command.
* @param type type of the engine
* @param series series/class of the engine
* @param name name of the engine
* @param length length of the engine
* @param couplingFront whether the new engine should have a front coupling
* @param couplingBack whether the new engine should have a back coupling
*/
public CreateEngine(final EngineType type, final String series, final String name, final int length,
final boolean couplingFront, final boolean couplingBack) {
if (type == null) {
throw new IllegalArgumentException("engine type is null!");
}
this.type = type;
this.series = series;
this.name = name;
this.length = length;
this.couplingFront = couplingFront;
this.couplingBack = couplingBack;
}
private boolean couplingBack;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -82,4 +70,24 @@ public class CreateEngine extends Command {
simulation.createEngine(engine);
Terminal.printLine(engine.getIdentifier());
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(CREATE_ENGINE)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = CREATE_ENGINE_ARGUMENTS.matcher(input.substring(CREATE_ENGINE.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid create engine argument syntax");
}
type = EngineType.parse(matcher.group(1));
series = matcher.group(2);
if ("W".equals(series)) {
throw new InvalidInputException("invalid engine class/series");
}
name = matcher.group(3);
length = Integer.parseInt(matcher.group(4));
couplingFront = Boolean.parseBoolean(matcher.group(5));
couplingBack = Boolean.parseBoolean(matcher.group(6));
}
}

View File

@ -5,6 +5,13 @@ import edu.kit.informatik.Terminal;
import edu.kit.informatik.model.TrainSet;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.ALPHANUMERIC_WORD;
import static edu.kit.informatik.ui.command.CommandFactory.CREATE_TRAIN_SET;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
/**
* Command used to add a new train set.
*
@ -12,43 +19,29 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version Arne Keller
*/
public class CreateTrainSet extends Command {
private static final Pattern CREATE_TRAIN_SET_ARGUMENTS
= Pattern.compile(" (" + ALPHANUMERIC_WORD + ") (" + ALPHANUMERIC_WORD + ") (" + NUMBER + ") (true|false) (true|false)");
/**
* Series (class) of the new train set.
*/
private final String series;
private String series;
/**
* Name of the new train set.
*/
private final String name;
private String name;
/**
* Length of the new train set.
*/
private final int length;
private int length;
/**
* Whether the new train set should have front coupling.
*/
private final boolean couplingFront;
private boolean couplingFront;
/**
* Whether the new train set should have a back coupling.
*/
private final boolean couplingBack;
/**
* Construct a new 'create train-set' command.
* @param series series/class of the train set
* @param name name of the train set
* @param length length of the train set
* @param couplingFront whether the train set should have a front coupling
* @param couplingBack whether the train set should have a back coupling
*/
public CreateTrainSet(final String series, final String name, final int length,
final boolean couplingFront, final boolean couplingBack) {
this.series = series;
this.name = name;
this.length = length;
this.couplingFront = couplingFront;
this.couplingBack = couplingBack;
}
private boolean couplingBack;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -56,4 +49,23 @@ public class CreateTrainSet extends Command {
simulation.createTrainSet(trainSet);
Terminal.printLine(trainSet.getIdentifier());
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(CREATE_TRAIN_SET)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = CREATE_TRAIN_SET_ARGUMENTS.matcher(input.substring(CREATE_TRAIN_SET.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid create train-set arguments");
}
series = matcher.group(1);
if ("W".equals(series)) {
throw new InvalidInputException("invalid train-set class/series");
}
name = matcher.group(2);
length = Integer.parseInt(matcher.group(3));
couplingFront = Boolean.parseBoolean(matcher.group(4));
couplingBack = Boolean.parseBoolean(matcher.group(5));
}
}

View File

@ -2,6 +2,13 @@ package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.DELETE_ROLLING_STOCK;
import static edu.kit.informatik.ui.command.CommandFactory.ROLLING_STOCK_IDENTIFIER;
/**
* Command used to delete rolling stock.
@ -10,18 +17,13 @@ import edu.kit.informatik.Terminal;
* @version 1.0
*/
public class DeleteRollingStock extends Command {
private static final Pattern DELETE_ROLLING_STOCK_ARGUMENT
= Pattern.compile(" (" + ROLLING_STOCK_IDENTIFIER + ")");
/**
* Identifier of the rolling stock to delete.
*/
private final String id;
/**
* Construct a new 'delete rolling stock' command.
* @param id identifier of the rolling stock to delete
*/
public DeleteRollingStock(final String id) {
this.id = id;
}
private String id;
@Override
public void apply(final ModelRailwaySimulation simulation) {
@ -31,4 +33,16 @@ public class DeleteRollingStock extends Command {
Terminal.printError("could not delete rolling stock");
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(DELETE_ROLLING_STOCK)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = DELETE_ROLLING_STOCK_ARGUMENT.matcher(input.substring(DELETE_ROLLING_STOCK.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid delete rolling stock argument");
}
id = matcher.group(1);
}
}

View File

@ -2,6 +2,10 @@ package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.DELETE_TRACK;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
/**
* Command used to delete a track or switch.
@ -13,15 +17,7 @@ public class DeleteTrack extends Command {
/**
* Identifier of the rail to delete.
*/
private final int id;
/**
* Construct a new 'delete track' command.
* @param id identifier of the track/switch to delete
*/
public DeleteTrack(final int id) {
this.id = id;
}
private int id;
@Override
public void apply(final ModelRailwaySimulation simulation) {
@ -31,4 +27,16 @@ public class DeleteTrack extends Command {
Terminal.printError("could not delete rail segment");
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(DELETE_TRACK)) {
throw new InvalidInputException("unknown command");
}
String argument = input.substring(DELETE_TRACK.length());
if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid/missing delete track argument");
}
id = Integer.parseInt(argument.substring(1));
}
}

View File

@ -2,6 +2,10 @@ package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.DELETE_TRAIN;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
/**
* Command used to delete a train, without deleting rolling stock of the train.
@ -13,15 +17,7 @@ public class DeleteTrain extends Command {
/**
* Identifier of the train to delete.
*/
private final int id;
/**
* Construct a new 'delete train' command.
* @param id identifier of the train to delete
*/
public DeleteTrain(final int id) {
this.id = id;
}
private int id;
@Override
public void apply(final ModelRailwaySimulation simulation) {
@ -31,4 +27,16 @@ public class DeleteTrain extends Command {
Terminal.printError("could not remove train");
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(DELETE_TRAIN)) {
throw new InvalidInputException("unknown command");
}
String argument = input.substring(DELETE_TRAIN.length());
if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid delete train argument");
}
id = Integer.parseInt(argument.substring(1));
}
}

View File

@ -1,6 +1,9 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.LIST_COACHES;
/**
* Command used to print a list of coaches.
@ -13,4 +16,14 @@ public class ListCoaches extends Command {
public void apply(final ModelRailwaySimulation simulation) {
simulation.printCoaches();
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(LIST_COACHES)) {
throw new InvalidInputException("unknown command");
}
if (input.length() > LIST_COACHES.length()) {
throw new InvalidInputException("too many list coaches arguments");
}
}
}

View File

@ -1,6 +1,9 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.LIST_ENGINES;
/**
* Command used to print a list of engines.
@ -13,4 +16,14 @@ public class ListEngines extends Command {
public void apply(final ModelRailwaySimulation simulation) {
simulation.printEngines();
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(LIST_ENGINES)) {
throw new InvalidInputException("unknown command");
}
if (input.length() > LIST_ENGINES.length()) {
throw new InvalidInputException("too many list engines arguments");
}
}
}

View File

@ -1,6 +1,9 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRACKS;
/**
* Command used to print a list of tracks and switches.
@ -13,4 +16,14 @@ public class ListTracks extends Command {
public void apply(final ModelRailwaySimulation simulation) {
simulation.printTracks();
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(LIST_TRACKS)) {
throw new InvalidInputException("unknown command");
}
if (input.length() > LIST_TRACKS.length()) {
throw new InvalidInputException("too many arguments for list tracks");
}
}
}

View File

@ -1,6 +1,9 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRAIN_SETS;
/**
* Command used to print a list of train sets on the terminal.
@ -13,4 +16,14 @@ public class ListTrainSets extends Command {
public void apply(final ModelRailwaySimulation simulation) {
simulation.printTrainSets();
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(LIST_TRAIN_SETS)) {
throw new InvalidInputException("unknown command");
}
if (input.length() > LIST_TRAIN_SETS.length()) {
throw new InvalidInputException("too many list train-sets arguments");
}
}
}

View File

@ -1,6 +1,9 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.LIST_TRAINS;
/**
* Command used to print a list of trains on the terminal.
@ -13,4 +16,14 @@ public class ListTrains extends Command {
public void apply(final ModelRailwaySimulation simulation) {
simulation.printTrains();
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(LIST_TRAINS)) {
throw new InvalidInputException("unknown command");
}
if (input.length() > LIST_TRAINS.length()) {
throw new InvalidInputException("too many list trains arguments");
}
}
}

View File

@ -5,6 +5,13 @@ import edu.kit.informatik.model.Vector2D;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
import static edu.kit.informatik.ui.command.CommandFactory.PUT_TRAIN;
import static edu.kit.informatik.ui.command.CommandFactory.VECTOR;
/**
* Command used to put a train on the rail network.
*
@ -12,30 +19,21 @@ import edu.kit.informatik.ui.InvalidInputException;
* @version 1.0
*/
public class PutTrain extends Command {
private static final Pattern PUT_TRAIN_ARGUMENTS
= Pattern.compile(" (" + NUMBER + ") at \\((" + VECTOR + ")\\) in direction (" + VECTOR + ")");
/**
* Identifier of the train to place.
*/
private final int id;
private int id;
/**
* Where to place the train.
*/
private final Vector2D point;
private Vector2D point;
/**
* Initial direction of the train.
*/
private final Vector2D direction;
/**
* Construct a new 'put train' command.
* @param id identifier of the train
* @param point where to put the train
* @param direction initial direction
*/
public PutTrain(final int id, final Vector2D point, final Vector2D direction) {
this.id = id;
this.point = point;
this.direction = direction;
}
private Vector2D direction;
@Override
public void apply(final ModelRailwaySimulation simulation) throws InvalidInputException {
@ -45,4 +43,18 @@ public class PutTrain extends Command {
Terminal.printError("could not place train");
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(PUT_TRAIN)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = PUT_TRAIN_ARGUMENTS.matcher(input.substring(PUT_TRAIN.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid put train arguments");
}
id = Integer.parseInt(matcher.group(1));
point = Vector2D.parse(matcher.group(2));
direction = Vector2D.parse(matcher.group(3));
}
}

View File

@ -3,6 +3,14 @@ package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.model.Vector2D;
import edu.kit.informatik.Terminal;
import edu.kit.informatik.ui.InvalidInputException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
import static edu.kit.informatik.ui.command.CommandFactory.SET_SWITCH;
import static edu.kit.informatik.ui.command.CommandFactory.VECTOR;
/**
* Command used to specify the position a switch is set to.
@ -11,25 +19,17 @@ import edu.kit.informatik.Terminal;
* @version 1.0
*/
public class SetSwitch extends Command {
private static final Pattern SET_SWITCH_ARGUMENTS
= Pattern.compile(" (" + NUMBER + ") position \\((" + VECTOR + ")\\)");
/**
* Identifier of the switch to configure.
*/
private final int id;
private int id;
/**
* Position to set the switch to.
*/
private final Vector2D point;
/**
* Construct a new 'set switch' command.
* @param id identifier of the switch
* @param point position to set the switch to
*/
public SetSwitch(final int id, final Vector2D point) {
this.id = id;
// make sure caller can not modify internal state
this.point = new Vector2D(point);
}
private Vector2D point;
@Override
public void apply(final ModelRailwaySimulation simulation) {
@ -39,4 +39,17 @@ public class SetSwitch extends Command {
Terminal.printError("could not set switch");
}
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(SET_SWITCH)) {
throw new InvalidInputException("unknown command");
}
Matcher matcher = SET_SWITCH_ARGUMENTS.matcher(input.substring(SET_SWITCH.length()));
if (!matcher.matches()) {
throw new InvalidInputException("invalid set switch argument syntax");
}
id = Integer.parseInt(matcher.group(1));
point = Vector2D.parse(matcher.group(2));
}
}

View File

@ -1,6 +1,10 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.NUMBER;
import static edu.kit.informatik.ui.command.CommandFactory.SHOW_TRAIN;
/**
* Command used to print a train as ASCII art.
@ -12,18 +16,22 @@ public class ShowTrain extends Command {
/**
* Identifier of the train to display.
*/
private final int id;
/**
* Construct a new 'show train' command.
* @param id identifier of the train to show
*/
public ShowTrain(final int id) {
this.id = id;
}
private int id;
@Override
public void apply(final ModelRailwaySimulation simulation) {
simulation.printTrain(id);
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(SHOW_TRAIN)) {
throw new InvalidInputException("unknown command");
}
String argument = input.substring(SHOW_TRAIN.length());
if (!argument.matches(" " + NUMBER)) {
throw new InvalidInputException("invalid show train argument");
}
id = Integer.parseInt(argument.substring(1));
}
}

View File

@ -1,6 +1,9 @@
package edu.kit.informatik.ui.command;
import edu.kit.informatik.model.ModelRailwaySimulation;
import edu.kit.informatik.ui.InvalidInputException;
import static edu.kit.informatik.ui.command.CommandFactory.STEP;
/**
* Command used to advance the simulation.
@ -12,18 +15,22 @@ public class Step extends Command {
/**
* Amount of steps to perform (= speed).
*/
private final short speed;
/**
* Construct a new 'step' command.
* @param speed the amount of steps to perform, can be any value
*/
public Step(final short speed) {
this.speed = speed;
}
private short speed;
@Override
public void apply(final ModelRailwaySimulation simulation) {
simulation.step(speed);
}
@Override
public void parse(String input) throws InvalidInputException {
if (input == null || !input.startsWith(STEP)) {
throw new InvalidInputException("unknown command");
}
String argument = input.substring(STEP.length());
if (!argument.matches(" [+-]?\\d+")) {
throw new InvalidInputException("invalid step argument");
}
speed = Short.parseShort(argument.substring(1));
}
}