Skip to content

Commit

Permalink
Merge 6d265fa into bd3c2e5
Browse files Browse the repository at this point in the history
  • Loading branch information
e0031374 committed Oct 22, 2019
2 parents bd3c2e5 + 6d265fa commit 338dfea
Show file tree
Hide file tree
Showing 76 changed files with 4,221 additions and 39 deletions.
36 changes: 34 additions & 2 deletions src/main/java/tagline/MainApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import tagline.model.UserPrefs;
import tagline.model.contact.AddressBook;
import tagline.model.contact.ReadOnlyAddressBook;
import tagline.model.group.GroupBook;
import tagline.model.group.ReadOnlyGroupBook;
import tagline.model.note.NoteBook;
import tagline.model.note.ReadOnlyNoteBook;
import tagline.model.util.SampleDataUtil;
Expand All @@ -31,6 +33,8 @@
import tagline.storage.UserPrefsStorage;
import tagline.storage.contact.AddressBookStorage;
import tagline.storage.contact.JsonAddressBookStorage;
import tagline.storage.group.GroupBookStorage;
import tagline.storage.group.JsonGroupBookStorage;
import tagline.storage.note.JsonNoteBookStorage;
import tagline.storage.note.NoteBookStorage;
import tagline.ui.Ui;
Expand Down Expand Up @@ -63,7 +67,9 @@ public void init() throws Exception {
UserPrefs userPrefs = initPrefs(userPrefsStorage);
AddressBookStorage addressBookStorage = new JsonAddressBookStorage(userPrefs.getAddressBookFilePath());
NoteBookStorage noteBookStorage = new JsonNoteBookStorage(userPrefs.getNoteBookFilePath());
storage = new StorageManager(addressBookStorage, noteBookStorage, userPrefsStorage);
GroupBookStorage groupBookStorage = new JsonGroupBookStorage(userPrefs.getGroupBookFilePath());
storage = new StorageManager(addressBookStorage, noteBookStorage,
groupBookStorage, userPrefsStorage);

initLogging(config);

Expand Down Expand Up @@ -122,6 +128,30 @@ private ReadOnlyNoteBook getNoteBookFromStorage(Storage storage) {
return initialNoteBookData;
}

/**
* Gets and returns a {@code ReadOnlyGroupBook} from {@code storage}.
*/
private ReadOnlyGroupBook getGroupBookFromStorage(Storage storage) {
Optional<ReadOnlyGroupBook> groupBookOptional = Optional.empty();
ReadOnlyGroupBook initialGroupBookData;

try {
groupBookOptional = storage.readGroupBook();
if (!groupBookOptional.isPresent()) {
logger.info("Data file not found. Will be starting with a sample group book");
}
initialGroupBookData = groupBookOptional.orElseGet(SampleDataUtil::getSampleGroupBook);
} catch (DataConversionException e) {
logger.warning("Data file not in the correct format. Will be starting with an empty group book");
initialGroupBookData = new GroupBook();
} catch (IOException e) {
logger.warning("Problem while reading from the file. Will be starting with an empty group book");
initialGroupBookData = new GroupBook();
}

return initialGroupBookData;
}

/**
* Returns a {@code ModelManager} with the data from {@code storage}'s address book, note book and
* {@code userPrefs}. <br>
Expand All @@ -132,7 +162,9 @@ private ReadOnlyNoteBook getNoteBookFromStorage(Storage storage) {
private Model initModelManager(Storage storage, ReadOnlyUserPrefs userPrefs) {
ReadOnlyAddressBook initialAddressBookData = getAddressBookFromStorage(storage);
ReadOnlyNoteBook initialNoteBookData = getNoteBookFromStorage(storage);
return new ModelManager(initialAddressBookData, initialNoteBookData, userPrefs);
ReadOnlyGroupBook initialGroupBookData = getGroupBookFromStorage(storage);
return new ModelManager(initialAddressBookData, initialNoteBookData,
initialGroupBookData, userPrefs);
}

private void initLogging(Config config) {
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/tagline/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ public class Messages {
public static final String MESSAGE_INVALID_TAG_FORMAT = "Invalid tag format! \n%1$s";
public static final String MESSAGE_UNKNOWN_TAG = "Unknown tag type!";
public static final String MESSAGE_INVALID_NOTE_INDEX = "The note index provided is invalid";
public static final String MESSAGE_INVALID_GROUP_NAME = "The group name provided is invalid";
public static final String MESSAGE_GROUPS_LISTED_OVERVIEW = "%1$d groups listed!";
public static final String MESSAGE_GROUP_MEMBERS_OVERVIEW = "%1$d group members listed!";

}
16 changes: 16 additions & 0 deletions src/main/java/tagline/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import tagline.logic.parser.exceptions.ParseException;
import tagline.model.contact.Contact;
import tagline.model.contact.ReadOnlyAddressBook;
import tagline.model.group.Group;
import tagline.model.group.ReadOnlyGroupBook;
import tagline.model.note.Note;
import tagline.model.note.ReadOnlyNoteBook;

Expand Down Expand Up @@ -58,6 +60,20 @@ public interface Logic {
*/
Path getNoteBookFilePath();

/**
* Returns the note book.
*
* @see tagline.model.Model#getGroupBook()
*/
ReadOnlyGroupBook getGroupBook();

/** Returns an unmodifiable view of the filtered list of groups */
ObservableList<Group> getFilteredGroupList();

/**
* Returns the user prefs' group book file path.
*/
Path getGroupBookFilePath();
/**
* Returns the user prefs' GUI settings.
*/
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/tagline/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import tagline.model.Model;
import tagline.model.contact.Contact;
import tagline.model.contact.ReadOnlyAddressBook;
import tagline.model.group.Group;
import tagline.model.group.ReadOnlyGroupBook;
import tagline.model.note.Note;
import tagline.model.note.ReadOnlyNoteBook;
import tagline.storage.Storage;
Expand Down Expand Up @@ -48,6 +50,7 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
try {
storage.saveAddressBook(model.getAddressBook());
storage.saveNoteBook(model.getNoteBook());
storage.saveGroupBook(model.getGroupBook());
} catch (IOException ioe) {
throw new CommandException(FILE_OPS_ERROR_MESSAGE + ioe, ioe);
}
Expand Down Expand Up @@ -85,6 +88,21 @@ public Path getNoteBookFilePath() {
return model.getNoteBookFilePath();
}

@Override
public ReadOnlyGroupBook getGroupBook() {
return model.getGroupBook();
}

@Override
public ObservableList<Group> getFilteredGroupList() {
return model.getFilteredGroupList();
}

@Override
public Path getGroupBookFilePath() {
return model.getGroupBookFilePath();
}

@Override
public GuiSettings getGuiSettings() {
return model.getGuiSettings();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package tagline.logic.commands.group;

import static java.util.Objects.requireNonNull;
import static tagline.logic.parser.group.GroupCliSyntax.PREFIX_CONTACTID;
import static tagline.model.group.GroupModel.PREDICATE_SHOW_ALL_GROUPS;

import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

import tagline.commons.util.CollectionUtil;

import tagline.logic.commands.CommandResult;
import tagline.logic.commands.exceptions.CommandException;
import tagline.model.Model;
import tagline.model.group.Group;
import tagline.model.group.GroupDescription;
import tagline.model.group.GroupName;
import tagline.model.group.MemberId;

/**
* Edits the details of an existing group in the address book.
*/
public class AddMemberToGroupCommand extends GroupCommand {

public static final String COMMAND_WORD = "add";

public static final String MESSAGE_USAGE = COMMAND_WORD + ": Add a contact to the group identified "
+ "by the group name and the contact ID number displayed in the contact list.\n "
+ "Parameters: GROUP_NAME (one word, cannot contain space) "
+ "[" + PREFIX_CONTACTID + "CONTACT_ID]...\n"
+ "Example: " + COMMAND_WORD + " BTS_ARMY "
+ PREFIX_CONTACTID + "47337 ";

public static final String MESSAGE_ADD_MEMBER_SUCCESS = "Added contact to Group: %1$s";
public static final String MESSAGE_NOT_ADDED = "At least one field to edit must be provided.";
public static final String MESSAGE_DUPLICATE_MEMBER = "This contact already exists in the Group.";
public static final String MESSAGE_DUPLICATE_PERSON = "This group already exists in the address book.";

//private final Group group;
private final String groupName;
private final EditGroupDescriptor editGroupDescriptor;

/**
* @param groupName of the group in the filtered group list to edit
* @param editGroupDescriptor details to edit the group with
*/

public AddMemberToGroupCommand(String groupName, EditGroupDescriptor editGroupDescriptor) {
requireNonNull(groupName);
requireNonNull(editGroupDescriptor);

//this.index = index;
this.groupName = groupName.trim();
this.editGroupDescriptor = new EditGroupDescriptor(editGroupDescriptor);
}

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

Group groupToEdit = findOneGroup(model, groupName);
// adds all user-input contactIds as members of this Group checks deferred
Group editedGroup = createEditedGroup(groupToEdit, editGroupDescriptor);

// check to ensure Group members are ContactIds that can be found in Model
// this Group should only have contactId of contacts found in ContactList after calling setGroup
Group verifiedGroup = GroupCommand.verifyGroupWithModel(model, editedGroup);
model.setGroup(groupToEdit, verifiedGroup);

model.updateFilteredGroupList(PREDICATE_SHOW_ALL_GROUPS);
return new CommandResult(String.format(MESSAGE_ADD_MEMBER_SUCCESS, verifiedGroup));
}

/**
* Creates and returns a {@code Group} with the details of {@code groupToEdit}
* edited with {@code editGroupDescriptor}.
*/
private static Group createEditedGroup(Group groupToEdit, EditGroupDescriptor editGroupDescriptor) {
assert groupToEdit != null;

GroupName updatedGroupName = editGroupDescriptor.getGroupName().orElse(groupToEdit.getGroupName());
GroupDescription updatedGroupDescription = editGroupDescriptor.getGroupDescription()
.orElse(groupToEdit.getGroupDescription());
Set<MemberId> updatedMemberIds = new HashSet<>();
if (editGroupDescriptor.getMemberIds().isPresent()) {
updatedMemberIds.addAll(editGroupDescriptor.getMemberIds().get());
}
updatedMemberIds.addAll(groupToEdit.getMemberIds());

return new Group(updatedGroupName, updatedGroupDescription, updatedMemberIds);
}

@Override
public boolean equals(Object other) {
// short circuit if same object
if (other == this) {
return true;
}

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

// state check
AddMemberToGroupCommand e = (AddMemberToGroupCommand) other;
return groupName.equals(e.groupName)
&& editGroupDescriptor.equals(e.editGroupDescriptor);
}

/**
* Stores the details to edit the group with. Each non-empty field value will replace the
* corresponding field value of the group.
*/
public static class EditGroupDescriptor {
private GroupName groupName;
private GroupDescription description;
private Set<MemberId> memberIds;
//private Set<Tag> tags;

public EditGroupDescriptor() {}

/**
* Copy constructor.
* A defensive copy of {@code tags} is used internally.
*/
public EditGroupDescriptor(EditGroupDescriptor toCopy) {
setGroupName(toCopy.groupName);
setGroupDescription(toCopy.description);
setMemberIds(toCopy.memberIds);
}

/**
* Returns true if at least one field is edited.
*/
public boolean isAnyFieldEdited() {
return CollectionUtil.isAnyNonNull(groupName, description, memberIds);
}

public void setGroupName(GroupName groupName) {
this.groupName = groupName;
}

public Optional<GroupName> getGroupName() {
return Optional.ofNullable(groupName);
}

public void setGroupDescription(GroupDescription description) {
this.description = description;
}

public Optional<GroupDescription> getGroupDescription() {
return Optional.ofNullable(description);
}

/**
* Sets {@code memberIds} to this object's {@code memberIds}.
* A defensive copy of {@code memberIds} is used internally.
*/
public void setMemberIds(Set<MemberId> memberIds) {
this.memberIds = (memberIds != null) ? new HashSet<>(memberIds) : null;
}

/**
* Adds {@code memberIds} to this object's {@code memberIds}.
* A defensive copy of {@code memberIds} is used internally.
*/
public void addMemberIds(Set<MemberId> memberIds) {
this.memberIds = (memberIds != null) ? new HashSet<>(memberIds) : null;
}
/**
* Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException}
* if modification is attempted.
* Returns {@code Optional#empty()} if {@code tags} is null.
*/
public Optional<Set<MemberId>> getMemberIds() {
return (memberIds != null) ? Optional.of(Collections.unmodifiableSet(memberIds)) : Optional.empty();
}

///**
// * Sets {@code tags} to this object's {@code tags}.
// * A defensive copy of {@code tags} is used internally.
// */
//public void setTags(Set<Tag> tags) {
// this.tags = (tags != null) ? new HashSet<>(tags) : null;
//}

///**
// * Returns an unmodifiable tag set, which throws {@code UnsupportedOperationException}
// * if modification is attempted.
// * Returns {@code Optional#empty()} if {@code tags} is null.
// */
//public Optional<Set<Tag>> getTags() {
// return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty();
//}

@Override
public boolean equals(Object other) {
// short circuit if same object
if (other == this) {
return true;
}

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

// state check
EditGroupDescriptor e = (EditGroupDescriptor) other;

return getGroupName().equals(e.getGroupName())
&& getMemberIds().equals(e.getMemberIds());
}
}
}
Loading

0 comments on commit 338dfea

Please sign in to comment.