Skip to content

Commit

Permalink
Merge pull request AY2324S2-CS2103T-W12-1#93 from solomonng2001/add-s…
Browse files Browse the repository at this point in the history
…ort-by-priority

Add sorting for person attributes
  • Loading branch information
solomonng2001 authored Mar 27, 2024
2 parents 5e35d90 + 4daa4a8 commit c12467f
Show file tree
Hide file tree
Showing 32 changed files with 1,123 additions and 17 deletions.
92 changes: 92 additions & 0 deletions src/main/java/seedu/address/logic/commands/SortCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package seedu.address.logic.commands;

import static java.util.Objects.requireNonNull;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SORT_ORDER;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.person.PersonComparator;
import seedu.address.model.person.SortCriteria;
import seedu.address.model.person.SortOrder;

/**
* Sorts the client list in the address book.
*/
public class SortCommand extends Command {

public static final String COMMAND_WORD = "sort";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": sorts the client list in the address book. "
+ "Parameters: "
+ "CRITERIA "
+ PREFIX_SORT_ORDER + "ORDER\n"
+ "Example: " + COMMAND_WORD + " "
+ "priority "
+ PREFIX_SORT_ORDER + "desc";

private static final String MESSAGE_SUCCESS = "Client list sorted by %s in %s order.";
private final SortCriteria sortCriteria;
private final SortOrder sortOrder;

/**
* Creates a SortCommand to sort the client list.
*/
public SortCommand(SortCriteria sortCriteria, SortOrder sortOrder) {
requireNonNull(sortCriteria);
requireNonNull(sortOrder);

this.sortCriteria = sortCriteria;
this.sortOrder = sortOrder;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
model.sortFilteredPersonList(PersonComparator.getComparator(sortCriteria, sortOrder));
return new CommandResult(getMessageSuccess(sortCriteria, sortOrder));
}

/**
* Returns a success message based on the sort criteria and sort order.
*
* @param sortCriteria the sort criteria
* @param sortOrder the sort order
* @return the success message
*/
public static String getMessageSuccess(SortCriteria sortCriteria, SortOrder sortOrder)
throws IllegalArgumentException {
if (sortCriteria == null || sortOrder == null) {
throw new IllegalArgumentException("SortCriteria and SortOrder cannot be null.");
}
if (sortCriteria == SortCriteria.INVALID || sortOrder == SortOrder.INVALID) {
return String.format(MESSAGE_SUCCESS, SortCriteria.NAME, SortOrder.ASC);
}
return String.format(MESSAGE_SUCCESS, sortCriteria, sortOrder);
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof SortCommand)) {
return false;
}

SortCommand otherSortCommand = (SortCommand) other;
return sortCriteria.equals(otherSortCommand.sortCriteria)
&& sortOrder.equals(otherSortCommand.sortOrder);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("sortCriteria", sortCriteria)
.add("sortOrder", sortOrder)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import seedu.address.logic.commands.ListCommand;
import seedu.address.logic.commands.MarkCommand;
import seedu.address.logic.commands.ScheduleCommand;
import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.commands.ViewCommand;
import seedu.address.logic.parser.exceptions.ParseException;

Expand Down Expand Up @@ -101,6 +102,9 @@ public Command parseCommand(String userInput) throws ParseException {
case DeletePolicyCommand.COMMAND_WORD:
return new DeletePolicyCommandParser().parse(arguments);

case SortCommand.COMMAND_WORD:
return new SortCommandParser().parse(arguments);

default:
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/seedu/address/logic/parser/CliSyntax.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ public class CliSyntax {
public static final Prefix PREFIX_TAG = new Prefix("t/");
public static final Prefix PREFIX_POLICYNAME = new Prefix("n/");
public static final Prefix PREFIX_POLICYID = new Prefix("i/");

public static final Prefix PREFIX_SORT_ORDER = new Prefix("o/");
}
34 changes: 34 additions & 0 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
import seedu.address.model.person.Name;
import seedu.address.model.person.Phone;
import seedu.address.model.person.Priority;
import seedu.address.model.person.SortCriteria;
import seedu.address.model.person.SortOrder;
import seedu.address.model.policy.Policy;
import seedu.address.model.tag.Tag;

Expand Down Expand Up @@ -207,4 +209,36 @@ public static String parsePolicyId(String policyId) throws ParseException {
}
return trimmedPolicyId;
}

/**
* Parses {@code String sortOrder} into a {@code SortOrder}.
*
* @param sortOrder the sort order
* @return the sort order
* @throws ParseException if the given {@code sortOrder} is invalid
*/
public static SortOrder parseSortOrder(String sortOrder) throws ParseException {
requireNonNull(sortOrder);
String trimmedSortOrder = sortOrder.trim();
if (!SortOrder.isValidSortOrder(trimmedSortOrder)) {
throw new ParseException(SortOrder.MESSAGE_CONSTRAINTS);
}
return SortOrder.getSortOrder(trimmedSortOrder);
}

/**
* Parses {@code String sortCriteria} into a {@code SortCriteria}.
*
* @param sortCriteria the sort criteria
* @return the sort criteria
* @throws ParseException if the given {@code sortCriteria} is invalid
*/
public static SortCriteria parseSortCriteria(String sortCriteria) throws ParseException {
requireNonNull(sortCriteria);
String trimmedSortCriteria = sortCriteria.trim();
if (!SortCriteria.isValidSortCriteria(trimmedSortCriteria)) {
throw new ParseException(SortCriteria.MESSAGE_CONSTRAINTS);
}
return SortCriteria.getSortCriteria(trimmedSortCriteria);
}
}
44 changes: 44 additions & 0 deletions src/main/java/seedu/address/logic/parser/SortCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;
import static seedu.address.logic.parser.CliSyntax.PREFIX_SORT_ORDER;

import java.util.stream.Stream;

import seedu.address.logic.commands.SortCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.SortCriteria;
import seedu.address.model.person.SortOrder;

/**
* Parses input arguments and creates a new SortCommand object
*/
public class SortCommandParser implements Parser<SortCommand> {

/**
* Parses the given {@code String} of arguments in the context of the SortCommand
* and returns an SortCommand object for execution.
*/
public SortCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_SORT_ORDER);

if (!arePrefixesPresent(argMultimap, PREFIX_SORT_ORDER)
|| argMultimap.getPreamble().isEmpty()) {
throw new ParseException(String.format(MESSAGE_INVALID_COMMAND_FORMAT, SortCommand.MESSAGE_USAGE));
}

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_SORT_ORDER);
SortCriteria sortCriteria = ParserUtil.parseSortCriteria(argMultimap.getPreamble());
SortOrder sortOrder = ParserUtil.parseSortOrder(argMultimap.getValue(PREFIX_SORT_ORDER).get());

return new SortCommand(sortCriteria, sortOrder);
}

/**
* 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());
}
}
7 changes: 7 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package seedu.address.model;

import java.nio.file.Path;
import java.util.Comparator;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
Expand Down Expand Up @@ -86,6 +87,12 @@ public interface Model {
*/
void updateFilteredPersonList(Predicate<Person> predicate);

/**
* Sorts the filtered person list by the given {@code comparator}.
* @throws NullPointerException if {@code comparator} is null.
*/
void sortFilteredPersonList(Comparator<Person> comparator);

/**
* Returns the client to be displayed in ClientViewPanel.
*/
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.nio.file.Path;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.logging.Logger;

Expand All @@ -27,7 +28,7 @@ public class ModelManager implements Model {

private final AddressBook addressBook;
private final UserPrefs userPrefs;
private final FilteredList<Person> filteredPersons;
private FilteredList<Person> filteredPersons;
private final DisplayClient displayClient;

/**
Expand Down Expand Up @@ -166,6 +167,13 @@ public void updateFilteredPersonList(Predicate<Person> predicate) {
filteredPersons.setPredicate(predicate);
}

@Override
public void sortFilteredPersonList(Comparator<Person> comparator) {
requireNonNull(comparator);
ObservableList<Person> sortedList = this.addressBook.getPersonList().sorted(comparator);
filteredPersons = new FilteredList<>(sortedList);
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/seedu/address/model/person/Address.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Represents a Person's address in the address book.
* Guarantees: immutable; is valid as declared in {@link #isValidAddress(String)}
*/
public class Address {
public class Address implements Comparable<Address> {

public static final String MESSAGE_CONSTRAINTS = "Addresses can take any values, and it should not be blank";

Expand Down Expand Up @@ -62,4 +62,8 @@ public int hashCode() {
return value.hashCode();
}

@Override
public int compareTo(Address other) {
return this.value.compareTo(other.value);
}
}
7 changes: 6 additions & 1 deletion src/main/java/seedu/address/model/person/Birthday.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Represents a Client's birthday in the address book.
* Guarantees: immutable; is valid as declared in {@link #isValidBirthday(String)}
*/
public class Birthday {
public class Birthday implements Comparable<Birthday> {
public static final String MESSAGE_CONSTRAINTS = DateUtil.getMessageConstraintsForDateType("Birthday");
public final LocalDate date;

Expand Down Expand Up @@ -64,4 +64,9 @@ public boolean equals(Object other) {
public int hashCode() {
return date.hashCode();
}

@Override
public int compareTo(Birthday other) {
return date.compareTo(other.date);
}
}
6 changes: 5 additions & 1 deletion src/main/java/seedu/address/model/person/Email.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Represents a Person's email in the address book.
* Guarantees: immutable; is valid as declared in {@link #isValidEmail(String)}
*/
public class Email {
public class Email implements Comparable<Email> {

private static final String SPECIAL_CHARACTERS = "+_.-";
public static final String MESSAGE_CONSTRAINTS = "Emails should be of the format local-part@domain "
Expand Down Expand Up @@ -76,4 +76,8 @@ public int hashCode() {
return value.hashCode();
}

@Override
public int compareTo(Email other) {
return this.value.compareTo(other.value);
}
}
23 changes: 22 additions & 1 deletion src/main/java/seedu/address/model/person/LastMet.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Represents the last met date with a Client in the address book.
*/
public class LastMet {
public class LastMet implements Comparable<LastMet> {
private static long lastMetDuration = 90;
private final LocalDate lastMetDate;
private boolean isOverdue;
Expand Down Expand Up @@ -82,6 +82,7 @@ public String showLastMet() {
* @param other
* @return An integer value based on the comparison of the lastMetDate of two LastMet objects.
*/
@Override
public int compareTo(LastMet other) {
return this.lastMetDate.compareTo(other.lastMetDate);
}
Expand All @@ -90,4 +91,24 @@ public int compareTo(LastMet other) {
public String toString() {
return DateUtil.parseDateToString(this.lastMetDate);
}

@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}

// instanceof handles nulls
if (!(other instanceof LastMet)) {
return false;
}

LastMet otherLastMet = (LastMet) other;
return lastMetDate.equals(otherLastMet.lastMetDate);
}

@Override
public int hashCode() {
return lastMetDate.hashCode();
}
}
6 changes: 5 additions & 1 deletion src/main/java/seedu/address/model/person/Name.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Represents a Person's name in the address book.
* Guarantees: immutable; is valid as declared in {@link #isValidName(String)}
*/
public class Name {
public class Name implements Comparable<Name> {

public static final String MESSAGE_CONSTRAINTS =
"Names should only contain alphanumeric characters and spaces, and it should not be blank";
Expand Down Expand Up @@ -64,4 +64,8 @@ public int hashCode() {
return fullName.hashCode();
}

@Override
public int compareTo(Name other) {
return this.fullName.compareTo(other.fullName);
}
}
Loading

0 comments on commit c12467f

Please sign in to comment.