Skip to content

Commit

Permalink
Merge pull request #72 from HanB1n/branch-tagging
Browse files Browse the repository at this point in the history
Update Feature Tagging
  • Loading branch information
dasha3412 authored Oct 10, 2024
2 parents 26a9a27 + 323697c commit 3681ac4
Show file tree
Hide file tree
Showing 40 changed files with 1,332 additions and 43 deletions.
10 changes: 10 additions & 0 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import seedu.address.logic.parser.Prefix;
import seedu.address.model.person.Person;
import seedu.address.model.tag.Tag;

/**
* Container for user visible messages.
Expand Down Expand Up @@ -48,4 +49,13 @@ public static String format(Person person) {
return builder.toString();
}

/**
* Formats the {@code tag} for display to the user.
*/
public static String format(Tag tag) {
final StringBuilder builder = new StringBuilder();
builder.append(tag.getTagName());
return builder.toString();
}

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

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

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.tag.Tag;

/**
* Adds a tag to the address book.
*/
public class CreateTagCommand extends Command {

public static final String COMMAND_WORD = "create-tag";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Creates a tag in the address book. "
+ "Parameters: "
+ PREFIX_TAG + "TAG\n"
+ "Example: " + COMMAND_WORD + " "
+ PREFIX_TAG + "florist";

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

private final Tag toAdd;

/**
* Creates an CreateTagCommand to add the specified {@code Tag}
*/
public CreateTagCommand(Tag tag) {
requireNonNull(tag);
toAdd = tag;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);

if (model.hasTag(toAdd)) {
throw new CommandException(MESSAGE_DUPLICATE_TAG);
}

model.addTag(toAdd);
return new CommandResult(String.format(MESSAGE_SUCCESS, Messages.format(toAdd)));
}

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

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

CreateTagCommand otherCreateTagCommand = (CreateTagCommand) other;
return toAdd.equals(otherCreateTagCommand.toAdd);
}

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

import static java.util.Objects.requireNonNull;

import java.util.List;

import seedu.address.commons.util.ToStringBuilder;
import seedu.address.logic.Messages;
import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.Model;
import seedu.address.model.tag.Tag;

/**
* Deletes a person identified using it's displayed index from the address book.
*/
public class DeleteTagCommand extends Command {

public static final String COMMAND_WORD = "delete-tag";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Deletes the tag identified by the tag name.\n"
+ "Parameters: TAG_NAME (must exists in the AddressBook)\n"
+ "Example: " + COMMAND_WORD + " florist";

public static final String MESSAGE_DELETE_TAG_SUCCESS = "Deleted Tag: %1$s";
public static final String MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED = "The Tag: %1$s is still used";
public static final String MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND = "The Tag: %1$s does not exist";

private final Tag targetTag;

public DeleteTagCommand(Tag targetTag) {
this.targetTag = targetTag;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<Tag> allTags = model.getFilteredTagList();

for (Tag tag : allTags) {
if (tag.getTagName().equals(targetTag.getTagName())) {
if (tag.canBeDeleted()) {
model.deleteTag(tag);
return new CommandResult(String.format(MESSAGE_DELETE_TAG_SUCCESS, Messages.format(targetTag)));
} else {
throw new CommandException(
String.format(MESSAGE_DELETE_TAG_FAILURE_STILL_TAGGED, Messages.format(targetTag)));
}
}
}
throw new CommandException(String.format(MESSAGE_DELETE_TAG_FAILURE_NOT_FOUND, Messages.format(targetTag)));
}

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

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

DeleteTagCommand otherDeleteTagCommand = (DeleteTagCommand) other;
return targetTag.equals(otherDeleteTagCommand.targetTag);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.add("targetTag", targetTag)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import seedu.address.logic.commands.AddCommand;
import seedu.address.logic.commands.ClearCommand;
import seedu.address.logic.commands.Command;
import seedu.address.logic.commands.CreateTagCommand;
import seedu.address.logic.commands.DeleteCommand;
import seedu.address.logic.commands.DeleteTagCommand;
import seedu.address.logic.commands.EditCommand;
import seedu.address.logic.commands.ExitCommand;
import seedu.address.logic.commands.FilterCommand;
Expand Down Expand Up @@ -62,6 +64,8 @@ public Command parseCommand(String userInput) throws ParseException {
case ListCommand.COMMAND_WORD -> new ListCommand();
case ExitCommand.COMMAND_WORD -> new ExitCommand();
case HelpCommand.COMMAND_WORD -> new HelpCommand();
case CreateTagCommand.COMMAND_WORD -> new CreateTagCommandParser().parse(arguments);
case DeleteTagCommand.COMMAND_WORD -> new DeleteTagCommandParser().parse(arguments);
default -> {
logger.finer("This user input caused a ParseException: " + userInput);
throw new ParseException(MESSAGE_UNKNOWN_COMMAND);
Expand Down
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_TAG;

import java.util.stream.Stream;

import seedu.address.logic.commands.CreateTagCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.tag.Tag;

/**
* Parses input arguments and creates a new AddCommand object
*/
public class CreateTagCommandParser implements Parser<CreateTagCommand> {

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

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

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_TAG);
Tag tag = ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).get());
return new CreateTagCommand(tag);
}

/**
* 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());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package seedu.address.logic.parser;

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

import java.util.stream.Stream;

import seedu.address.logic.commands.DeleteTagCommand;
import seedu.address.logic.parser.exceptions.ParseException;
import seedu.address.model.tag.Tag;

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

/**
* Parses the given {@code String} of arguments in the context of the DeleteCommand
* and returns a DeleteCommand object for execution.
* @throws ParseException if the user input does not conform the expected format
*/
public DeleteTagCommand parse(String args) throws ParseException {
ArgumentMultimap argMultimap =
ArgumentTokenizer.tokenize(args, PREFIX_TAG);

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

argMultimap.verifyNoDuplicatePrefixesFor(PREFIX_TAG);
Tag tag = ParserUtil.parseTag(argMultimap.getValue(PREFIX_TAG).get());
return new DeleteTagCommand(tag);
}

/**
* 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());
}
}
5 changes: 3 additions & 2 deletions src/main/java/seedu/address/logic/parser/ParserUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import seedu.address.model.person.Name;
import seedu.address.model.person.Phone;
import seedu.address.model.tag.Tag;
import seedu.address.model.tag.TagName;

/**
* Contains utility methods used for parsing strings in the various *Parser classes.
Expand Down Expand Up @@ -102,9 +103,9 @@ public static Tag parseTag(String tag) throws ParseException {
requireNonNull(tag);
String trimmedTag = tag.trim();
if (!Tag.isValidTagName(trimmedTag)) {
throw new ParseException(Tag.MESSAGE_CONSTRAINTS);
throw new ParseException(TagName.MESSAGE_CONSTRAINTS);
}
return new Tag(trimmedTag);
return new Tag(new TagName(trimmedTag));
}

/**
Expand Down
51 changes: 50 additions & 1 deletion src/main/java/seedu/address/model/AddressBook.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import seedu.address.commons.util.ToStringBuilder;
import seedu.address.model.person.Person;
import seedu.address.model.person.UniquePersonList;
import seedu.address.model.tag.Tag;
import seedu.address.model.tag.UniqueTagList;

/**
* Wraps all data at the address-book level
Expand All @@ -16,16 +18,18 @@
public class AddressBook implements ReadOnlyAddressBook {

private final UniquePersonList persons;
private final UniqueTagList tags;

/*
* The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication
* between constructors. See https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
*
* Note that non-static init blocks are not recommended to use. There are other ways to avoid duplication
* among constructors.
* among constructors.
*/
{
persons = new UniquePersonList();
tags = new UniqueTagList();
}

public AddressBook() {}
Expand Down Expand Up @@ -55,8 +59,15 @@ public void resetData(ReadOnlyAddressBook newData) {
requireNonNull(newData);

setPersons(newData.getPersonList());
setTags(newData.getTagList());
}

/**
* Replaces the contents of the tag list with {@code tags}.
* {@code tags} must not contain duplicate tags.
*/
public void setTags(List<Tag> tags) { this.tags.setTags(tags); }

//// person-level operations

/**
Expand Down Expand Up @@ -94,6 +105,39 @@ public void removePerson(Person key) {
persons.remove(key);
}

//// tag-level operations

/**
* Adds a tag to the address book.
* The tag must not already exist in the address book.
*/
public void addTag(Tag tag) { tags.add(tag); }

/**
* Returns true if a tag with the same name as {@code tag} exists in the address book.
*/
public boolean hasTag(Tag tag) {
requireNonNull(tag);
return tags.contains(tag);
}

/**
* Replaces the given tag {@code target} in the list with {@code editedTag}.
* {@code target} must exist in the address book.
* The person identity of {@code editedTag} must not be the same as another existing tag in the address book.
*/
public void setTag(Tag target, Tag editedTag) {
requireNonNull(editedTag);

tags.setTag(target, editedTag);
}

/**
* Removes {@code key} from this {@code AddressBook}.
* {@code key} must exist in the address book.
*/
public void removeTag(Tag key) { tags.remove(key); }

//// util methods

@Override
Expand All @@ -108,6 +152,9 @@ public ObservableList<Person> getPersonList() {
return persons.asUnmodifiableObservableList();
}

@Override
public ObservableList<Tag> getTagList() { return tags.asUnmodifiableObservableList(); }

@Override
public boolean equals(Object other) {
if (other == this) {
Expand All @@ -127,4 +174,6 @@ public boolean equals(Object other) {
public int hashCode() {
return persons.hashCode();
}


}
Loading

0 comments on commit 3681ac4

Please sign in to comment.