Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor parser #39

Merged
merged 16 commits into from
Oct 2, 2020
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies {
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac'
implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux'

implementation group: 'commons-cli', name: 'commons-cli', version: '1.4'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.7.0'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.7.4'

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.CommandResult;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.AddressBookParser;
import seedu.address.logic.parser.McGymmyParser;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.Model;
import seedu.address.model.ReadOnlyAddressBook;
Expand All @@ -26,23 +26,23 @@ public class LogicManager implements Logic {

private final Model model;
private final Storage storage;
private final AddressBookParser addressBookParser;
private final McGymmyParser mcGymmyParser;

/**
* Constructs a {@code LogicManager} with the given {@code Model} and {@code Storage}.
*/
public LogicManager(Model model, Storage storage) {
this.model = model;
this.storage = storage;
addressBookParser = new AddressBookParser();
mcGymmyParser = new McGymmyParser();
}

@Override
public CommandResult execute(String commandText) throws CommandException, ParseException {
logger.info("----------------[USER COMMAND][" + commandText + "]");

CommandResult commandResult;
Command command = addressBookParser.parseCommand(commandText);
Command command = mcGymmyParser.parse(commandText);
commandResult = command.execute(model);

try {
Expand Down
70 changes: 33 additions & 37 deletions src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
@@ -1,54 +1,57 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG;

import java.util.HashSet;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.ParserUtil;
import seedu.address.logic.parser.parameter.Parameter;
import seedu.address.model.Model;
import seedu.address.model.person.Address;
import seedu.address.model.person.Email;
import seedu.address.model.person.Name;
import seedu.address.model.person.Person;
import seedu.address.model.person.Phone;

/**
* Adds a person to the address book.
*/
public class AddCommand extends Command {

public static final String COMMAND_WORD = "add";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. "
+ "Parameters: "
+ PREFIX_NAME + "NAME "
+ PREFIX_PHONE + "PHONE "
+ PREFIX_EMAIL + "EMAIL "
+ PREFIX_ADDRESS + "ADDRESS "
+ "[" + PREFIX_TAG + "TAG]...\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_NAME + "John Doe "
+ PREFIX_PHONE + "98765432 "
+ PREFIX_EMAIL + "johnd@example.com "
+ PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 "
+ PREFIX_TAG + "friends "
+ PREFIX_TAG + "owesMoney";

public static final String MESSAGE_SUCCESS = "New person added: %1$s";
public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book";

private final Person toAdd;

/**
* Creates an AddCommand to add the specified {@code Person}
*/
public AddCommand(Person person) {
requireNonNull(person);
toAdd = person;
}
private final Parameter<Name> nameParameter = this.addParameter(
"name",
"n",
"Name of person to add",
"John Doe",
ParserUtil::parseName
);
private final Parameter<Phone> phoneParameter = this.addParameter(
"phone",
"p",
"Phone number of person to add",
"98765432",
ParserUtil::parsePhone
);
private final Parameter<Email> emailParameter = this.addParameter(
"email",
"e",
"Email address of person to add",
"johnd@example.com",
ParserUtil::parseEmail

);

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
// rewriting this class as an example, address and tags not implemented.
Person toAdd = new Person(nameParameter.consume(), phoneParameter.consume(), emailParameter.consume(),
new Address("dummy value"), new HashSet<>());

if (model.hasPerson(toAdd)) {
throw new CommandException(MESSAGE_DUPLICATE_PERSON);
Expand All @@ -57,11 +60,4 @@ public CommandResult execute(Model model) throws CommandException {
model.addPerson(toAdd);
return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof AddCommand // instanceof handles nulls
&& toAdd.equals(((AddCommand) other).toAdd));
}
}
86 changes: 86 additions & 0 deletions src/main/java/seedu/address/logic/commands/Command.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
package seedu.address.logic.commands;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParameterConflictException;
import seedu.address.logic.parser.parameter.AbstractParameter;
import seedu.address.logic.parser.parameter.OptionalParameter;
import seedu.address.logic.parser.parameter.Parameter;
import seedu.address.logic.parser.parameter.ParameterConverter;
import seedu.address.logic.parser.parameter.ParameterSet;
import seedu.address.model.Model;

/**
* Represents a command with hidden internal logic and the ability to be executed.
*/
public abstract class Command {
private final ParameterSet parameterSet;

protected Command() {
this.parameterSet = new ParameterSet();
}

/**
* Executes the command and returns the result message.
Expand All @@ -17,4 +28,79 @@ public abstract class Command {
*/
public abstract CommandResult execute(Model model) throws CommandException;

/**
* Registers a parameter for use in the parameter set.
* Only registered parameters will be used in parsing.
* @param parameter parameter to be registered.
*/
protected void registerParameter(AbstractParameter parameter) {
try {
this.parameterSet.addParameter(parameter);
} catch (ParameterConflictException e) {
// Commands can only be created by the developers so any parameter conflicts
// should not happen, and should fail here during testing.
assert false : e.getMessage();
}
}

/**
* Creates a new required parameter for this command. Also registers it for parsing in the parameter set,
* i.e. will be used in the parser.
* @param name Name of the parameter.
* @param flag flag used in the command, e.g. '-c' in 'add banana -c 100'
* @param description short description of what the parameter represents, e.g. 'carbs as an integer'
* @param example example value, e.g. '100'
* @param converter Function to parse the value from a String to T. May throw a ParseError.
*/
protected <T> Parameter<T> addParameter(String name, String flag, String description,
String example, ParameterConverter<T> converter) {
Parameter<T> parameter = new Parameter<>(name, flag, description, example, converter);
this.registerParameter(parameter);
return parameter;
}

/**
* Creates a new required parameter for this command. Parameter will contain the raw input from the user.
* Also registers it for parsing in the parameter set, i.e. will be used in the parser.
* @param name Name of the parameter.
* @param flag flag used in the command, e.g. '-c' in 'add banana -c 100'
* @param description short description of what the parameter represents, e.g. 'carbs as an integer'
* @param example example value, e.g. '100'
*/
protected Parameter<String> addParameter(String name, String flag, String description, String example) {
return this.addParameter(name, flag, description, example, (s) -> s);
}

/**
* Creates a new optional parameter for this command. Also registers it for parsing in the parameter set,
* i.e. will be used in the parser.
* @param name Name of the parameter.
* @param flag flag used in the command, e.g. '-c' in 'add banana -c 100'
* @param description short description of what the parameter represents, e.g. 'carbs as an integer'
* @param example example value, e.g. '100'
* @param converter Function to parse the value from a String to T. May throw a ParseError.
*/
protected <T> OptionalParameter<T> addOptionalParameter(String name, String flag, String description,
String example, ParameterConverter<T> converter) {
OptionalParameter<T> parameter = new OptionalParameter<>(name, flag, description, example, converter);
this.registerParameter(parameter);
return parameter;
}

/**
* Creates a new optional parameter for this command. Parameter will contain the raw input from the user.
* Also registers it for parsing in the parameter set, i.e. will be used in the parser.
* @param name Name of the parameter.
* @param flag flag used in the command, e.g. '-c' in 'add banana -c 100'
* @param description short description of what the parameter represents, e.g. 'carbs as an integer'
* @param example example value, e.g. '100'
*/
protected OptionalParameter<String> addOptionalParameter(String name, String flag, String description,
String example) {
return this.addOptionalParameter(name, flag, description, example, (s) -> s);
}

public ParameterSet getParameterSet() {
return parameterSet;
}
}
29 changes: 10 additions & 19 deletions src/main/java/seedu/address/logic/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import seedu.address.commons.core.Messages;
import seedu.address.commons.core.index.Index;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.ParserUtil;
import seedu.address.logic.parser.parameter.Parameter;
import seedu.address.model.Model;
import seedu.address.model.person.Person;

Expand All @@ -15,25 +17,21 @@
*/
public class DeleteCommand extends Command {

public static final String COMMAND_WORD = "delete";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Deletes the person identified by the index number used in the displayed person list.\n"
+ "Parameters: INDEX (must be a positive integer)\n"
+ "Example: " + COMMAND_WORD + " 1";

public static final String MESSAGE_DELETE_PERSON_SUCCESS = "Deleted Person: %1$s";

private final Index targetIndex;

public DeleteCommand(Index targetIndex) {
this.targetIndex = targetIndex;
}
private final Parameter<Index> indexParameter = this.addParameter(
"index",
"",
"index number used in the displayed person list.",
"2",
ParserUtil::parseIndex
);

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Person> lastShownList = model.getFilteredPersonList();
Index targetIndex = indexParameter.consume();

if (targetIndex.getZeroBased() >= lastShownList.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX);
Expand All @@ -43,11 +41,4 @@ public CommandResult execute(Model model) throws CommandException {
model.deletePerson(personToDelete);
return new CommandResult(String.format(MESSAGE_DELETE_PERSON_SUCCESS, personToDelete));
}

@Override
public boolean equals(Object other) {
return other == this // short circuit if same object
|| (other instanceof DeleteCommand // instanceof handles nulls
&& targetIndex.equals(((DeleteCommand) other).targetIndex)); // state check
}
}