diff --git a/src/edu/kit/informatik/ui/command/AddSwitch.java b/src/edu/kit/informatik/ui/command/AddSwitch.java index bc77a30..9c47dc0 100644 --- a/src/edu/kit/informatik/ui/command/AddSwitch.java +++ b/src/edu/kit/informatik/ui/command/AddSwitch.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/AddTrack.java b/src/edu/kit/informatik/ui/command/AddTrack.java index 2f873ad..0a1cf89 100644 --- a/src/edu/kit/informatik/ui/command/AddTrack.java +++ b/src/edu/kit/informatik/ui/command/AddTrack.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/AddTrain.java b/src/edu/kit/informatik/ui/command/AddTrain.java index 1541004..43762ce 100644 --- a/src/edu/kit/informatik/ui/command/AddTrain.java +++ b/src/edu/kit/informatik/ui/command/AddTrain.java @@ -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); + } } diff --git a/src/edu/kit/informatik/ui/command/Command.java b/src/edu/kit/informatik/ui/command/Command.java index 4559680..3adf33f 100644 --- a/src/edu/kit/informatik/ui/command/Command.java +++ b/src/edu/kit/informatik/ui/command/Command.java @@ -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; } diff --git a/src/edu/kit/informatik/ui/command/CommandFactory.java b/src/edu/kit/informatik/ui/command/CommandFactory.java index cf3d687..3871a81 100644 --- a/src/edu/kit/informatik/ui/command/CommandFactory.java +++ b/src/edu/kit/informatik/ui/command/CommandFactory.java @@ -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; } } diff --git a/src/edu/kit/informatik/ui/command/CreateCoach.java b/src/edu/kit/informatik/ui/command/CreateCoach.java index d4bcc26..66714e7 100644 --- a/src/edu/kit/informatik/ui/command/CreateCoach.java +++ b/src/edu/kit/informatik/ui/command/CreateCoach.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/CreateEngine.java b/src/edu/kit/informatik/ui/command/CreateEngine.java index fe15dc6..8075837 100644 --- a/src/edu/kit/informatik/ui/command/CreateEngine.java +++ b/src/edu/kit/informatik/ui/command/CreateEngine.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/CreateTrainSet.java b/src/edu/kit/informatik/ui/command/CreateTrainSet.java index 94aa3df..a8b770d 100644 --- a/src/edu/kit/informatik/ui/command/CreateTrainSet.java +++ b/src/edu/kit/informatik/ui/command/CreateTrainSet.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/DeleteRollingStock.java b/src/edu/kit/informatik/ui/command/DeleteRollingStock.java index 1ce3e07..f75f613 100644 --- a/src/edu/kit/informatik/ui/command/DeleteRollingStock.java +++ b/src/edu/kit/informatik/ui/command/DeleteRollingStock.java @@ -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); + } } diff --git a/src/edu/kit/informatik/ui/command/DeleteTrack.java b/src/edu/kit/informatik/ui/command/DeleteTrack.java index 12ca58d..bac78fd 100644 --- a/src/edu/kit/informatik/ui/command/DeleteTrack.java +++ b/src/edu/kit/informatik/ui/command/DeleteTrack.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/DeleteTrain.java b/src/edu/kit/informatik/ui/command/DeleteTrain.java index 9f04422..1d64d48 100644 --- a/src/edu/kit/informatik/ui/command/DeleteTrain.java +++ b/src/edu/kit/informatik/ui/command/DeleteTrain.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/ListCoaches.java b/src/edu/kit/informatik/ui/command/ListCoaches.java index 27100a9..7f81747 100644 --- a/src/edu/kit/informatik/ui/command/ListCoaches.java +++ b/src/edu/kit/informatik/ui/command/ListCoaches.java @@ -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"); + } + } } diff --git a/src/edu/kit/informatik/ui/command/ListEngines.java b/src/edu/kit/informatik/ui/command/ListEngines.java index 9244e3a..80276bb 100644 --- a/src/edu/kit/informatik/ui/command/ListEngines.java +++ b/src/edu/kit/informatik/ui/command/ListEngines.java @@ -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"); + } + } } diff --git a/src/edu/kit/informatik/ui/command/ListTracks.java b/src/edu/kit/informatik/ui/command/ListTracks.java index 32f939a..a2fe4dd 100644 --- a/src/edu/kit/informatik/ui/command/ListTracks.java +++ b/src/edu/kit/informatik/ui/command/ListTracks.java @@ -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"); + } + } } diff --git a/src/edu/kit/informatik/ui/command/ListTrainSets.java b/src/edu/kit/informatik/ui/command/ListTrainSets.java index 202fffd..3689341 100644 --- a/src/edu/kit/informatik/ui/command/ListTrainSets.java +++ b/src/edu/kit/informatik/ui/command/ListTrainSets.java @@ -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"); + } + } } diff --git a/src/edu/kit/informatik/ui/command/ListTrains.java b/src/edu/kit/informatik/ui/command/ListTrains.java index 5a1b0c5..881117c 100644 --- a/src/edu/kit/informatik/ui/command/ListTrains.java +++ b/src/edu/kit/informatik/ui/command/ListTrains.java @@ -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"); + } + } } diff --git a/src/edu/kit/informatik/ui/command/PutTrain.java b/src/edu/kit/informatik/ui/command/PutTrain.java index 8a26b79..352d4e7 100644 --- a/src/edu/kit/informatik/ui/command/PutTrain.java +++ b/src/edu/kit/informatik/ui/command/PutTrain.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/SetSwitch.java b/src/edu/kit/informatik/ui/command/SetSwitch.java index e3a78bf..d6910f9 100644 --- a/src/edu/kit/informatik/ui/command/SetSwitch.java +++ b/src/edu/kit/informatik/ui/command/SetSwitch.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/ShowTrain.java b/src/edu/kit/informatik/ui/command/ShowTrain.java index e26b54a..348e481 100644 --- a/src/edu/kit/informatik/ui/command/ShowTrain.java +++ b/src/edu/kit/informatik/ui/command/ShowTrain.java @@ -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)); + } } diff --git a/src/edu/kit/informatik/ui/command/Step.java b/src/edu/kit/informatik/ui/command/Step.java index fee69da..9ac0b61 100644 --- a/src/edu/kit/informatik/ui/command/Step.java +++ b/src/edu/kit/informatik/ui/command/Step.java @@ -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)); + } }