Skip to content

Commit

Permalink
Merge pull request #72 from yisiox/63-refactor-parser-enum
Browse files Browse the repository at this point in the history
Refactor Logic component to use enum factory pattern
  • Loading branch information
aureliony authored Mar 16, 2024
2 parents 3674f9f + cd46d3d commit 06250eb
Show file tree
Hide file tree
Showing 50 changed files with 755 additions and 900 deletions.
2 changes: 1 addition & 1 deletion docs/tutorials/AddRemark.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ Your code should look something like [this](https://github.com/se-edu/addressboo

Now let’s move on to writing a parser that will extract the index and remark from the input provided by the user.

Create a `RemarkCommandParser` class in the `seedu.address.logic.parser` package. The class must extend the `Parser` interface.
Create a `RemarkCommandParser` class in the `seedu.address.logic.util` package. The class must extend the `Parser` interface.

<puml src="../diagrams/add-remark/ParserClass.puml" alt="The relationship between Parser and RemarkCommandParser"/>

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.logic.util.exceptions.ParseException;
import seedu.address.model.person.Person;
import seedu.address.storage.exceptions.StorageException;

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import seedu.address.commons.core.LogsCenter;
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.parser.AddressBookParser;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.logic.util.AddressBookParser;
import seedu.address.logic.util.exceptions.ParseException;
import seedu.address.model.Model;
import seedu.address.model.person.Person;
import seedu.address.storage.Storage;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import seedu.address.logic.parser.Prefix;
import seedu.address.model.person.Person;
import seedu.address.model.person.fields.Prefix;

/**
* Container for user visible messages.
Expand Down
55 changes: 50 additions & 5 deletions src/main/java/seedu/address/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
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 static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.model.person.fields.Address.PREFIX_ADDRESS;
import static seedu.address.model.person.fields.Email.PREFIX_EMAIL;
import static seedu.address.model.person.fields.Name.PREFIX_NAME;
import static seedu.address.model.person.fields.Phone.PREFIX_PHONE;
import static seedu.address.model.person.fields.Tags.PREFIX_TAG;

import java.util.stream.Stream;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.util.ArgumentMultimap;
import seedu.address.logic.util.ArgumentTokenizer;
import seedu.address.model.Model;
import seedu.address.model.person.Person;
import seedu.address.model.person.fields.Address;
import seedu.address.model.person.fields.Email;
import seedu.address.model.person.fields.Name;
import seedu.address.model.person.fields.Phone;
import seedu.address.model.person.fields.Prefix;
import seedu.address.model.person.fields.Tags;

/**
* Adds a person to the address book.
Expand Down Expand Up @@ -60,6 +71,40 @@ public String execute(Model model) throws CommandException {
return String.format(MESSAGE_SUCCESS, Messages.format(toAdd));
}

/**
* Parses the given {@code String} of arguments in the context of the AddCommand
* and returns an AddCommand object for execution.
* @throws IllegalArgumentException if the user input does not conform the expected format
*/
public static AddCommand of(String args) throws IllegalArgumentException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);

if (!arePrefixesPresent(argMultimap, PREFIX_NAME, PREFIX_ADDRESS, PREFIX_PHONE, PREFIX_EMAIL)
|| !argMultimap.getPreamble().isEmpty()) {
throw new IllegalArgumentException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);
Name name = Name.of(argMultimap.getValue(PREFIX_NAME).get());
Phone phone = Phone.of(argMultimap.getValue(PREFIX_PHONE).get());
Email email = Email.of(argMultimap.getValue(PREFIX_EMAIL).get());
Address address = Address.of(argMultimap.getValue(PREFIX_ADDRESS).get());
Tags tags = Tags.of(argMultimap.getAllValues(PREFIX_TAG));

Person person = new Person(name, phone, email, address, tags);

return new AddCommand(person);
}

/**
* Returns true if none of the prefixes contains empty {@code Optional} values in the given
* {@code ArgumentMultimap}.
*/
private static boolean arePrefixesPresent(ArgumentMultimap argumentMultimap, Prefix... prefixes) {
return Stream.of(prefixes).allMatch(prefix -> argumentMultimap.getValue(prefix).isPresent());
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/logic/commands/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public abstract class Command {
/**
* Executes the command and returns the result message.
*
* @param model {@code Model} which the command should operate on.
* @param model {@code Model} which the command should operate on
* @return feedback message of the operation result for display
* @throws CommandException If an error occurs during command execution.
* @throws CommandException if an error occurs during command execution
*/
public abstract String execute(Model model) throws CommandException;

Expand Down
58 changes: 58 additions & 0 deletions src/main/java/seedu/address/logic/commands/CommandType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package seedu.address.logic.commands;

/**
* Factory enumeration class for {@code Command} objects.
*/
public enum CommandType {

ADD {
@Override
public Command createCommand(String arguments) throws IllegalArgumentException {
return AddCommand.of(arguments);
}
},
EDIT {
@Override
public Command createCommand(String arguments) throws IllegalArgumentException {
return EditCommand.of(arguments);
}
},
DELETE {
@Override
public Command createCommand(String arguments) throws IllegalArgumentException {
return DeleteCommand.of(arguments);
}
},
CLEAR {
@Override
public Command createCommand(String arguments) {
return new ClearCommand();
}
},
FIND {
@Override
public Command createCommand(String arguments) throws IllegalArgumentException {
return FindCommand.of(arguments);
}
},
LIST {
@Override
public Command createCommand(String arguments) {
return new ListCommand();
}
},
EXIT {
@Override
public Command createCommand(String arguments) {
return new ExitCommand();
}
},
HELP {
@Override
public Command createCommand(String arguments) {
return new HelpCommand();
}
};

public abstract Command createCommand(String arguments) throws IllegalArgumentException;
}
18 changes: 18 additions & 0 deletions src/main/java/seedu/address/logic/commands/DeleteCommand.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import java.util.List;

import seedu.address.commons.core.index.Index;
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.util.ParserUtil;
import seedu.address.model.Model;
import seedu.address.model.person.Person;

Expand All @@ -31,6 +33,22 @@ public DeleteCommand(Index targetIndex) {
this.targetIndex = targetIndex;
}

/**
* Parses the given {@code String} of arguments in the context of the DeleteCommand
* and returns a DeleteCommand object for execution.
* @throws IllegalArgumentException if the user input does not conform the expected format
*/
public static DeleteCommand of(String args) throws IllegalArgumentException {
Index index;
try {
index = ParserUtil.parseIndex(args);
} catch (IllegalArgumentException ie) {
throw new IllegalArgumentException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE), ie);
}
return new DeleteCommand(index);
}

@Override
public String execute(Model model) throws CommandException {
requireNonNull(model);
Expand Down
77 changes: 71 additions & 6 deletions src/main/java/seedu/address/logic/commands/EditCommand.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
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 static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.model.Model.PREDICATE_SHOW_ALL_PERSONS;

import static seedu.address.model.person.fields.Address.PREFIX_ADDRESS;
import static seedu.address.model.person.fields.Email.PREFIX_EMAIL;
import static seedu.address.model.person.fields.Name.PREFIX_NAME;
import static seedu.address.model.person.fields.Phone.PREFIX_PHONE;
import static seedu.address.model.person.fields.Tags.PREFIX_TAG;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -17,6 +20,9 @@
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.logic.util.ArgumentMultimap;
import seedu.address.logic.util.ArgumentTokenizer;
import seedu.address.logic.util.ParserUtil;
import seedu.address.model.Model;
import seedu.address.model.person.Person;
import seedu.address.model.person.fields.Address;
Expand Down Expand Up @@ -101,6 +107,65 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript
return new Person(updatedName, updatedPhone, updatedEmail, updatedAddress, updatedTags);
}

/**
* Parses the given {@code String} of arguments in the context of the EditCommand
* and returns an EditCommand object for execution.
* @throws IllegalArgumentException if the user input does not conform the expected format
*/
public static EditCommand of(String args) throws IllegalArgumentException {
requireNonNull(args);
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS, PREFIX_TAG);

Index index;

try {
index = ParserUtil.parseIndex(argMultimap.getPreamble());
} catch (IllegalArgumentException ie) {
throw new IllegalArgumentException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE), ie);
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS);

EditPersonDescriptor editPersonDescriptor = new EditPersonDescriptor();

if (argMultimap.getValue(PREFIX_NAME).isPresent()) {
editPersonDescriptor.setName(Name.of(argMultimap.getValue(PREFIX_NAME).get()));
}
if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
editPersonDescriptor.setPhone(Phone.of(argMultimap.getValue(PREFIX_PHONE).get()));
}
if (argMultimap.getValue(PREFIX_EMAIL).isPresent()) {
editPersonDescriptor.setEmail(Email.of(argMultimap.getValue(PREFIX_EMAIL).get()));
}
if (argMultimap.getValue(PREFIX_ADDRESS).isPresent()) {
editPersonDescriptor.setAddress(Address.of(argMultimap.getValue(PREFIX_ADDRESS).get()));
}
parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags);

if (!editPersonDescriptor.isAnyFieldEdited()) {
throw new IllegalArgumentException(EditCommand.MESSAGE_NOT_EDITED);
}

return new EditCommand(index, editPersonDescriptor);
}

/**
* Parses {@code Collection<String> tags} into a {@code Set<Tag>} if {@code tags} is non-empty.
* If {@code tags} contain only one element which is an empty string, it will be parsed into a
* {@code Set<Tag>} containing zero tags.
*/
private static Optional<Tags> parseTagsForEdit(Collection<String> tags) {
requireNonNull(tags);

if (tags.isEmpty()) {
return Optional.empty();
}
Collection<String> tagSet = tags.size() == 1 && tags.contains("") ? Collections.emptySet() : tags;
return Optional.of(Tags.of(tagSet));
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/seedu/address/logic/commands/FindCommand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import java.util.Arrays;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
Expand Down Expand Up @@ -33,6 +36,23 @@ public String execute(Model model) {
return String.format(Messages.MESSAGE_PERSONS_LISTED_OVERVIEW, model.getFilteredPersonList().size());
}

/**
* Parses the given {@code String} of arguments in the context of the FindCommand
* and returns a FindCommand object for execution.
* @throws IllegalArgumentException if the user input does not conform the expected format
*/
public static FindCommand of(String args) throws IllegalArgumentException {
String trimmedArgs = args.trim();
if (trimmedArgs.isEmpty()) {
throw new IllegalArgumentException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));
}

String[] nameKeywords = trimmedArgs.split("\\s+");

return new FindCommand(new NameContainsKeywordsPredicate(Arrays.asList(nameKeywords)));
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
Loading

0 comments on commit 06250eb

Please sign in to comment.