Skip to content

Commit

Permalink
Merge branch 'master' into lingxi/shorten-commands
Browse files Browse the repository at this point in the history
  • Loading branch information
HugeNoob committed Oct 27, 2023
2 parents f0c1a28 + 4b52f11 commit 80b7f18
Show file tree
Hide file tree
Showing 23 changed files with 1,051 additions and 4 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ checkstyle {
toolVersion = '10.2'
}

run {
enableAssertions = true
}

test {
useJUnitPlatform()
finalizedBy jacocoTestReport
Expand Down
1 change: 1 addition & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class Messages {
public static final String MESSAGE_INVALID_TASK_DISPLAYED_INDEX = "The task index provided is invalid";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
public static final String MESSAGE_TASKS_LISTED_OVERVIEW = "%1$d tasks listed!";
public static final String MESSAGE_PERSONS_TASKS_LISTED_OVERVIEW = "%1$d persons and %2$d tasks listed!";
public static final String MESSAGE_DUPLICATE_FIELDS =
"Multiple values specified for the following single-valued field(s): ";

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

import static java.util.Objects.requireNonNull;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.model.Model;
import seedu.address.model.person.PersonContainsTagsPredicate;
import seedu.address.model.task.TaskContainsTagsPredicate;

/**
* Finds and lists all persons and tasks in address book whose tag contains any of the argument keywords.
*/
public class FindTagCommand extends Command {

public static final String COMMAND_WORD = "findTag";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Finds all persons and tasks whose tag contain any of "
+ "the specified keywords (case-insensitive) and displays them as a list with index numbers.\n"
+ "Parameters: KEYWORD [MORE_KEYWORDS]...\n"
+ "Example: " + COMMAND_WORD + " agenda";
private final PersonContainsTagsPredicate personPredicate;
private final TaskContainsTagsPredicate taskPredicate;

/**
* Creates a FindTagCommand to find the specified {@code TaskContainsTagsPredicate} and
* {@code PersonContainsTagsPredicate}
*/
public FindTagCommand(PersonContainsTagsPredicate personPredicate, TaskContainsTagsPredicate taskPredicate) {
this.taskPredicate = taskPredicate;
this.personPredicate = personPredicate;
}

@Override
public CommandResult execute(Model model) {
requireNonNull(model);
model.updateFilteredTaskList(taskPredicate);
model.updateFilteredPersonList(personPredicate);
return new CommandResult(
String.format(Messages.MESSAGE_PERSONS_TASKS_LISTED_OVERVIEW,
model.getFilteredPersonList().size(), model.getFilteredTaskList().size()));
}

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

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

FindTagCommand otherFindTagCommand = (FindTagCommand) other;
return taskPredicate.equals(otherFindTagCommand.taskPredicate)
&& personPredicate.equals(otherFindTagCommand.personPredicate);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("personPredicate", personPredicate)
.add("taskPredicate", taskPredicate)
.toString();
}
}
25 changes: 25 additions & 0 deletions src/main/java/seedu/address/logic/commands/ListTagCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package seedu.address.logic.commands;

import seedu.address.model.Model;
import seedu.address.model.tag.TagFrequencyTable;

/**
* Lists all tags in CoordiMate to the user.
*/
public class ListTagCommand extends Command {
public static final String COMMAND_WORD = "listTag";

public static final String MESSAGE_NO_TAGS_FOUND = "No tags found!";
public static final String MESSAGE_SUCCESS = "Listed all tags: \n%s\n";

@Override
public CommandResult execute(Model model) {
TagFrequencyTable tagFrequencyTable = model.getTagFrequencyTable();

if (tagFrequencyTable.isEmpty()) {
return new CommandResult(MESSAGE_NO_TAGS_FOUND);
}

return new CommandResult(String.format(MESSAGE_SUCCESS, tagFrequencyTable.format()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import seedu.address.logic.commands.FindDoneCommand;
import seedu.address.logic.commands.FindNotDoneCommand;
import seedu.address.logic.commands.FindPersonCommand;
import seedu.address.logic.commands.FindTagCommand;
import seedu.address.logic.commands.FindTaskCommand;
import seedu.address.logic.commands.HelpCommand;
import seedu.address.logic.commands.ListPersonCommand;
import seedu.address.logic.commands.ListTagCommand;
import seedu.address.logic.commands.ListTaskCommand;
import seedu.address.logic.commands.MarkTaskCommand;
import seedu.address.logic.commands.UnmarkTaskCommand;
Expand Down Expand Up @@ -143,6 +145,12 @@ public Command parseCommand(String userInput) throws ParseException {
case DeleteAllTaskCommand.SHORTENED_COMMAND_WORD:
return new DeleteAllTaskCommand();

case FindTagCommand.COMMAND_WORD:
return new FindTagCommandParser().parse(arguments);

case ListTagCommand.COMMAND_WORD:
return new ListTagCommand();

case ExitCommand.COMMAND_WORD:
// Fallthrough
case ExitCommand.SHORTENED_COMMAND_WORD:
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/seedu/address/logic/parser/FindTagCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package seedu.address.logic.parser;

import static seedu.address.logic.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import java.util.Arrays;

import seedu.address.logic.commands.FindTagCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.person.PersonContainsTagsPredicate;
import seedu.address.model.task.TaskContainsTagsPredicate;

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

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

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

return new FindTagCommand(new PersonContainsTagsPredicate(Arrays.asList(tagKeywords)),
new TaskContainsTagsPredicate(Arrays.asList(tagKeywords))
);
}
}
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/model/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.person.Person;
import seedu.address.model.person.UniquePersonList;
import seedu.address.model.tag.TagFrequencyTable;
import seedu.address.model.task.Task;
import seedu.address.model.task.UniqueTaskList;

Expand Down Expand Up @@ -159,6 +160,15 @@ public void deleteAllTask() {
tasks.deleteAll();
}

// =========== Tag Level Operations ======================================================================

/**
* Returns a frequency table of all tags in the address book.
*/
public TagFrequencyTable getTagFrequencyTable() {
return new TagFrequencyTable(persons.asUnmodifiableObservableList(), tasks.asUnmodifiableObservableList());
}

//// util methods

@Override
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/seedu/address/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import javafx.collections.ObservableList;
import seedu.address.commons.core.GuiSettings;
import seedu.address.model.person.Person;
import seedu.address.model.tag.TagFrequencyTable;
import seedu.address.model.task.Status;
import seedu.address.model.task.Task;

Expand Down Expand Up @@ -163,4 +164,10 @@ public interface Model {
*/
Task unmarkTask(Task task);

// =========== Tag Level Operations ======================================================================

/**
* Returns a frequency table of all tags in the address book.
*/
TagFrequencyTable getTagFrequencyTable();
}
8 changes: 8 additions & 0 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import seedu.address.commons.core.GuiSettings;
import seedu.address.commons.core.LogsCenter;
import seedu.address.model.person.Person;
import seedu.address.model.tag.TagFrequencyTable;
import seedu.address.model.task.Task;

/**
Expand Down Expand Up @@ -181,6 +182,13 @@ public Task unmarkTask(Task task) {
return task.unmarkDone();
}

// =========== Tag Level Operations ======================================================================

@Override
public TagFrequencyTable getTagFrequencyTable() {
return addressBook.getTagFrequencyTable();
}

// =========== Filtered Task List Accessors ==============================================================

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package seedu.address.model.person;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import seedu.address.commons.util.StringUtil;
import seedu.address.commons.util.ToStringBuilder;

/**
* Tests that a {@code Person}'s {@code Tags} matches any of the keywords given.
*/
public class PersonContainsTagsPredicate implements Predicate<Person> {
private final List<String> keywords;

public PersonContainsTagsPredicate(List<String> keywords) {
this.keywords = keywords;
}

// Returns true if person's tags contain any of the keywords
@Override
public boolean test(Person person) {

// Convert each tag of the person to its string representation and then concatenate them using spaces.
// The square brackets encapsulate each tag to ensure distinctiveness when checking against keywords.
// For example, tags such as [[Engineer], [Developer]] will translate to the string "[Engineer] [Developer]".
String personTags = person.getTags()
.stream()
.map(Object::toString)
.collect(Collectors.joining(" "));

// Match against the concatenated string of tags.
// The square brackets ensure that keywords match against full tags rather than partial matches.
// This way, a keyword like "[Eng]" won't match with the tag "[Engineer]".
return keywords.stream()
.anyMatch(keyword -> StringUtil.containsWordIgnoreCase(personTags, "[" + keyword + "]"));
}

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

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

PersonContainsTagsPredicate otherPersonContainsTagsPredicate = (PersonContainsTagsPredicate) other;
return keywords.equals(otherPersonContainsTagsPredicate.keywords);
}

@Override
public String toString() {
return new ToStringBuilder(this).add("keywords", keywords).toString();
}
}
9 changes: 7 additions & 2 deletions src/main/java/seedu/address/model/tag/Tag.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Represents a Tag in the address book.
* Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)}
*/
public class Tag {
public class Tag implements Comparable<Tag> {

public static final String MESSAGE_CONSTRAINTS = "Tags names should be alphanumeric";
public static final String VALIDATION_REGEX = "\\p{Alnum}+";
Expand Down Expand Up @@ -53,10 +53,15 @@ public int hashCode() {
}

/**
* Format state as text for viewing.
* Formats tag as text for viewing.
*/
@Override
public String toString() {
return '[' + tagName + ']';
}

@Override
public int compareTo(Tag other) {
return this.tagName.compareTo(other.tagName);
}
}
Loading

0 comments on commit 80b7f18

Please sign in to comment.