Skip to content

Commit 0041ed7

Browse files
authored
Support adding a module tag #80
2 parents 911c8fa + eaf3054 commit 0041ed7

30 files changed

+500
-76
lines changed

src/main/java/seedu/address/logic/commands/AddCommand.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
55
import static seedu.address.logic.parser.CliSyntax.PREFIX_BIRTHDAY;
66
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
7+
import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE;
78
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
89
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
910
import static seedu.address.logic.parser.CliSyntax.PREFIX_SOCMED_INSTAGRAM;
@@ -32,6 +33,7 @@ public class AddCommand extends Command {
3233
+ "[" + PREFIX_SOCMED_TELEGRAM + "TELEGRAM] "
3334
+ "[" + PREFIX_SOCMED_WHATSAPP + "WHATSAPP] "
3435
+ "[" + PREFIX_BIRTHDAY + "BIRTHDAY] "
36+
+ "[" + PREFIX_MODULE + "MODULE]... "
3537
+ "[" + PREFIX_TAG + "TAG]...\n"
3638
+ "Example: " + COMMAND_WORD + " "
3739
+ PREFIX_NAME + "John Doe "
@@ -42,6 +44,8 @@ public class AddCommand extends Command {
4244
+ PREFIX_SOCMED_INSTAGRAM + "john.doe "
4345
+ PREFIX_SOCMED_WHATSAPP + "98765432 "
4446
+ PREFIX_BIRTHDAY + "01/01/1990 "
47+
+ PREFIX_MODULE + "CS2103T "
48+
+ PREFIX_MODULE + "CS2101 "
4549
+ PREFIX_TAG + "friends "
4650
+ PREFIX_TAG + "owesMoney";
4751

src/main/java/seedu/address/logic/commands/EditCommand.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
55
import static seedu.address.logic.parser.CliSyntax.PREFIX_BIRTHDAY;
66
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
7+
import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE;
78
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
89
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
910
import static seedu.address.logic.parser.CliSyntax.PREFIX_SOCMED_INSTAGRAM;
@@ -30,6 +31,7 @@
3031
import seedu.address.model.person.Person;
3132
import seedu.address.model.person.Phone;
3233
import seedu.address.model.socialmedia.SocialMedia;
34+
import seedu.address.model.tag.Module;
3335
import seedu.address.model.tag.Tag;
3436

3537
/**
@@ -47,10 +49,11 @@ public class EditCommand extends Command {
4749
+ "[" + PREFIX_PHONE + "PHONE] "
4850
+ "[" + PREFIX_EMAIL + "EMAIL] "
4951
+ "[" + PREFIX_ADDRESS + "ADDRESS] "
50-
+ "[" + PREFIX_SOCMED_INSTAGRAM + "INSTAGRAM] "
51-
+ "[" + PREFIX_SOCMED_TELEGRAM + "TELEGRAM] "
52-
+ "[" + PREFIX_SOCMED_WHATSAPP + "WHATSAPP] "
53-
+ "[" + PREFIX_BIRTHDAY + "BIRTHDAY] "
52+
+ "[" + PREFIX_SOCMED_INSTAGRAM + "INSTAGRAM] "
53+
+ "[" + PREFIX_SOCMED_TELEGRAM + "TELEGRAM] "
54+
+ "[" + PREFIX_SOCMED_WHATSAPP + "WHATSAPP] "
55+
+ "[" + PREFIX_BIRTHDAY + "BIRTHDAY] "
56+
+ "[" + PREFIX_MODULE + "MODULE]... "
5457
+ "[" + PREFIX_TAG + "TAG]...\n"
5558
+ "Example: " + COMMAND_WORD + " 1 "
5659
+ PREFIX_PHONE + "91234567 "
@@ -105,8 +108,9 @@ private static Person createEditedPerson(Person personToEdit, EditPersonDescript
105108

106109
Name updatedName = editPersonDescriptor.getName().orElse(personToEdit.getName());
107110
Set<Tag> updatedTags = editPersonDescriptor.getTags().orElse(personToEdit.getTags());
111+
Set<Module> updatedModules = editPersonDescriptor.getModules().orElse(personToEdit.getModules());
108112

109-
Person p = new Person(updatedName, updatedTags);
113+
Person p = new Person(updatedName, updatedTags, updatedModules);
110114

111115
if (editPersonDescriptor.getPhone().isPresent()) {
112116
p.setPhone(editPersonDescriptor.getPhone().get());
@@ -182,8 +186,8 @@ public static class EditPersonDescriptor {
182186
private Address address;
183187
private SocialMedia socialMedia;
184188
private Set<Tag> tags;
185-
186189
private Birthday birthday;
190+
private Set<Module> modules;
187191

188192
public EditPersonDescriptor() {
189193
}
@@ -199,6 +203,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) {
199203
setAddress(toCopy.address);
200204
setSocialMedia(toCopy.socialMedia);
201205
setTags(toCopy.tags);
206+
setModules(toCopy.modules);
202207

203208
setBirthday(toCopy.birthday);
204209
}
@@ -207,7 +212,7 @@ public EditPersonDescriptor(EditPersonDescriptor toCopy) {
207212
* Returns true if at least one field is edited.
208213
*/
209214
public boolean isAnyFieldEdited() {
210-
return CollectionUtil.isAnyNonNull(name, phone, email, address, socialMedia, tags, birthday);
215+
return CollectionUtil.isAnyNonNull(name, phone, email, address, socialMedia, tags, birthday, modules);
211216
}
212217

213218
public void setName(Name name) {
@@ -278,6 +283,25 @@ public Optional<Set<Tag>> getTags() {
278283
return (tags != null) ? Optional.of(Collections.unmodifiableSet(tags)) : Optional.empty();
279284
}
280285

286+
287+
/**
288+
* Sets {@code modules} to this object's {@code modules}.
289+
* A defensive copy of {@code modules} is used internally.
290+
*/
291+
public void setModules(Set<Module> modules) {
292+
this.modules = (modules != null) ? new HashSet<>(modules) : null;
293+
}
294+
295+
/**
296+
* Returns an unmodifiable modules set, which throws
297+
* {@code UnsupportedOperationException}
298+
* if modification is attempted.
299+
* Returns {@code Optional#empty()} if {@code modules} is null.
300+
*/
301+
public Optional<Set<Module>> getModules() {
302+
return (modules != null) ? Optional.of(Collections.unmodifiableSet(modules)) : Optional.empty();
303+
}
304+
281305
@Override
282306
public boolean equals(Object other) {
283307
// short circuit if same object

src/main/java/seedu/address/logic/parser/AddCommandParser.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
55
import static seedu.address.logic.parser.CliSyntax.PREFIX_BIRTHDAY;
66
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
7+
import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE;
78
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
89
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
910
import static seedu.address.logic.parser.CliSyntax.PREFIX_SOCMED;
@@ -21,6 +22,7 @@
2122
import seedu.address.model.person.Person;
2223
import seedu.address.model.person.Phone;
2324
import seedu.address.model.socialmedia.SocialMedia;
25+
import seedu.address.model.tag.Module;
2426
import seedu.address.model.tag.Tag;
2527

2628
/**
@@ -35,9 +37,8 @@ public class AddCommandParser implements Parser<AddCommand> {
3537
* @throws ParseException if the user input does not conform the expected format
3638
*/
3739
public AddCommand parse(String args) throws ParseException {
38-
ArgumentMultimap argMultimap =
39-
ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL, PREFIX_ADDRESS,
40-
PREFIX_BIRTHDAY, PREFIX_SOCMED, PREFIX_TAG);
40+
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL,
41+
PREFIX_ADDRESS, PREFIX_BIRTHDAY, PREFIX_SOCMED, PREFIX_TAG, PREFIX_MODULE);
4142

4243
if (!arePrefixesPresent(argMultimap, PREFIX_NAME)
4344
|| !argMultimap.getPreamble().isEmpty()) {
@@ -46,8 +47,9 @@ public AddCommand parse(String args) throws ParseException {
4647

4748
Name name = ParserUtil.parseName(argMultimap.getValue(PREFIX_NAME).get());
4849
Set<Tag> tagList = ParserUtil.parseTags(argMultimap.getAllValues(PREFIX_TAG));
50+
Set<Module> moduleList = ParserUtil.parseModules(argMultimap.getAllValues(PREFIX_MODULE));
4951

50-
Person person = new Person(name, tagList);
52+
Person person = new Person(name, tagList, moduleList);
5153

5254
if (argMultimap.getValue(PREFIX_PHONE).isPresent()) {
5355
Phone phone = ParserUtil.parsePhone(argMultimap.getValue(PREFIX_PHONE).get());

src/main/java/seedu/address/logic/parser/CliSyntax.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ public class CliSyntax {
1313
public static final Prefix PREFIX_ADDRESS = new Prefix("a/");
1414
public static final Prefix PREFIX_TAG = new Prefix("t/");
1515
public static final Prefix PREFIX_BIRTHDAY = new Prefix("b/");
16+
public static final Prefix PREFIX_MODULE = new Prefix("mod/");
1617
public static final Prefix PREFIX_SOCMED = new Prefix("sm/");
1718
public static final Prefix PREFIX_SOCMED_INSTAGRAM = new Prefix("ig/");
1819
public static final Prefix PREFIX_SOCMED_TELEGRAM = new Prefix("tg/");
1920
public static final Prefix PREFIX_SOCMED_WHATSAPP = new Prefix("wa/");
20-
2121
}

src/main/java/seedu/address/logic/parser/EditCommandParser.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS;
66
import static seedu.address.logic.parser.CliSyntax.PREFIX_BIRTHDAY;
77
import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL;
8+
import static seedu.address.logic.parser.CliSyntax.PREFIX_MODULE;
89
import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME;
910
import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE;
1011
import static seedu.address.logic.parser.CliSyntax.PREFIX_SOCMED;
@@ -19,6 +20,7 @@
1920
import seedu.address.logic.commands.EditCommand;
2021
import seedu.address.logic.commands.EditCommand.EditPersonDescriptor;
2122
import seedu.address.logic.parser.exceptions.ParseException;
23+
import seedu.address.model.tag.Module;
2224
import seedu.address.model.tag.Tag;
2325

2426
/**
@@ -36,7 +38,7 @@ public class EditCommandParser implements Parser<EditCommand> {
3638
public EditCommand parse(String args) throws ParseException {
3739
requireNonNull(args);
3840
ArgumentMultimap argMultimap = ArgumentTokenizer.tokenize(args, PREFIX_NAME, PREFIX_PHONE, PREFIX_EMAIL,
39-
PREFIX_SOCMED, PREFIX_ADDRESS, PREFIX_TAG, PREFIX_BIRTHDAY);
41+
PREFIX_ADDRESS, PREFIX_SOCMED, PREFIX_TAG, PREFIX_BIRTHDAY, PREFIX_MODULE);
4042

4143
Index index;
4244

@@ -66,6 +68,7 @@ public EditCommand parse(String args) throws ParseException {
6668
editPersonDescriptor.setSocialMedia(ParserUtil.parseSocialMedia(argMultimap.getValue(PREFIX_SOCMED).get()));
6769
}
6870
parseTagsForEdit(argMultimap.getAllValues(PREFIX_TAG)).ifPresent(editPersonDescriptor::setTags);
71+
parseModulesForEdit(argMultimap.getAllValues(PREFIX_MODULE)).ifPresent(editPersonDescriptor::setModules);
6972

7073
if (!editPersonDescriptor.isAnyFieldEdited()) {
7174
throw new ParseException(EditCommand.MESSAGE_NOT_EDITED);
@@ -91,4 +94,20 @@ private Optional<Set<Tag>> parseTagsForEdit(Collection<String> tags) throws Pars
9194
return Optional.of(ParserUtil.parseTags(tagSet));
9295
}
9396

97+
/**
98+
* Parses {@code Collection<String> modules} into a {@code Set<Module>} if
99+
* {@code modules} is non-empty.
100+
* If {@code modules} contain only one element which is an empty string, it will be
101+
* parsed into a
102+
* {@code Set<module>} containing zero modules.
103+
*/
104+
private Optional<Set<Module>> parseModulesForEdit(Collection<String> modules) throws ParseException {
105+
assert modules != null;
106+
107+
if (modules.isEmpty()) {
108+
return Optional.empty();
109+
}
110+
Collection<String> moduleSet = modules.size() == 1 && modules.contains("") ? Collections.emptySet() : modules;
111+
return Optional.of(ParserUtil.parseModules(moduleSet));
112+
}
94113
}

src/main/java/seedu/address/logic/parser/ParserUtil.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import seedu.address.model.socialmedia.SocialMedia;
2222
import seedu.address.model.socialmedia.Telegram;
2323
import seedu.address.model.socialmedia.WhatsApp;
24+
import seedu.address.model.tag.Module;
2425
import seedu.address.model.tag.Tag;
2526

2627
/**
@@ -135,6 +136,21 @@ public static Tag parseTag(String tag) throws ParseException {
135136
return new Tag(trimmedTag);
136137
}
137138

139+
/**
140+
* Parses a {@code String module} into a {@code module}.
141+
* Leading and trailing whitespaces will be trimmed.
142+
*
143+
* @throws ParseException if the given {@code module} is invalid.
144+
*/
145+
public static Module parseModule(String module) throws ParseException {
146+
requireNonNull(module);
147+
String trimmedModule = module.trim();
148+
if (!Module.isValidTagName(trimmedModule)) {
149+
throw new ParseException(Module.MESSAGE_CONSTRAINTS);
150+
}
151+
return new Module(trimmedModule);
152+
}
153+
138154
/**
139155
* Parses {@code Collection<String> tags} into a {@code Set<Tag>}.
140156
*/
@@ -147,6 +163,18 @@ public static Set<Tag> parseTags(Collection<String> tags) throws ParseException
147163
return tagSet;
148164
}
149165

166+
/**
167+
* Parses {@code Collection<String> modules} into a {@code Set<Module>}.
168+
*/
169+
public static Set<Module> parseModules(Collection<String> modules) throws ParseException {
170+
requireNonNull(modules);
171+
final Set<Module> moduleSet = new HashSet<>();
172+
for (String moduleName : modules) {
173+
moduleSet.add(parseModule(moduleName));
174+
}
175+
return moduleSet;
176+
}
177+
150178
private static Instagram parseInstagram(String instagram) {
151179
if (instagram == null || instagram.isEmpty()) {
152180
return null;

src/main/java/seedu/address/model/person/Person.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.Set;
1010

1111
import seedu.address.model.socialmedia.SocialMedia;
12+
import seedu.address.model.tag.Module;
1213
import seedu.address.model.tag.Tag;
1314

1415
/**
@@ -26,6 +27,7 @@ public class Person {
2627
// Data fields
2728
private Optional<Address> address;
2829
private final Set<Tag> tags = new HashSet<>();
30+
private final Set<Module> modules = new HashSet<>();
2931
private Optional<Birthday> birthday;
3032

3133
// Social media fields
@@ -34,15 +36,16 @@ public class Person {
3436
/**
3537
* Every field must be present and not null.
3638
*/
37-
public Person(Name name, Set<Tag> tags) {
38-
requireAllNonNull(name, tags);
39+
public Person(Name name, Set<Tag> tags, Set<Module> modules) {
40+
requireAllNonNull(name, tags, modules);
3941
this.name = name;
4042
this.phone = Optional.empty();
4143
this.email = Optional.empty();
4244
this.address = Optional.empty();
4345
this.socialMedia = Optional.empty();
4446
this.tags.addAll(tags);
4547
this.birthday = Optional.empty();
48+
this.modules.addAll(modules);
4649
}
4750

4851
public void setPhone(Phone phone) {
@@ -98,6 +101,15 @@ public Set<Tag> getTags() {
98101
return Collections.unmodifiableSet(tags);
99102
}
100103

104+
/**
105+
* Returns an immutable module set, which throws
106+
* {@code UnsupportedOperationException}
107+
* if modification is attempted.
108+
*/
109+
public Set<Module> getModules() {
110+
return Collections.unmodifiableSet(modules);
111+
}
112+
101113
/**
102114
* Returns true if both persons have the same name.
103115
* This defines a weaker notion of equality between two persons.
@@ -130,13 +142,14 @@ public boolean equals(Object other) {
130142
&& otherPerson.getPhone().equals(getPhone())
131143
&& otherPerson.getEmail().equals(getEmail())
132144
&& otherPerson.getAddress().equals(getAddress())
133-
&& otherPerson.getTags().equals(getTags());
145+
&& otherPerson.getTags().equals(getTags())
146+
&& otherPerson.getModules().equals(getModules());
134147
}
135148

136149
@Override
137150
public int hashCode() {
138151
// use this method for custom fields hashing instead of implementing your own
139-
return Objects.hash(name, phone, email, address, tags);
152+
return Objects.hash(name, phone, email, address, tags, modules);
140153
}
141154

142155
@Override
@@ -159,6 +172,11 @@ public String toString() {
159172
builder.append("; Tags: ");
160173
tags.forEach(builder::append);
161174
}
175+
Set<Module> modules = getModules();
176+
if (!modules.isEmpty()) {
177+
builder.append("; Modules: ");
178+
modules.forEach(builder::append);
179+
}
162180
return builder.toString();
163181
}
164182

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package seedu.address.model.tag;
2+
3+
/**
4+
* Represents a Module in the address book.
5+
* Guarantees: immutable; name is valid as declared in {@link #isValidTagName(String)}
6+
*/
7+
public class Module extends Tag {
8+
9+
public static final String MESSAGE_CONSTRAINTS = "Module names should be alphanumeric";
10+
public final String moduleName;
11+
12+
/**
13+
* Constructs a {@code Module}.
14+
*
15+
* @param moduleName A valid module name.
16+
*/
17+
public Module(String moduleName) {
18+
super(moduleName, MESSAGE_CONSTRAINTS);
19+
this.moduleName = moduleName;
20+
}
21+
/**
22+
* Returns true if a given string is a valid module name.
23+
*/
24+
public static boolean isValidModuleName(String test) {
25+
return isValidTagName(test);
26+
}
27+
}

src/main/java/seedu/address/model/tag/Tag.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ public Tag(String tagName) {
2525
this.tagName = tagName;
2626
}
2727

28+
/**
29+
* Constructs a {@code Tag}.
30+
*
31+
* @param tagName A valid tag name.
32+
*/
33+
public Tag(String tagName, String message) {
34+
requireNonNull(tagName);
35+
checkArgument(isValidTagName(tagName), message);
36+
this.tagName = tagName;
37+
}
38+
2839
/**
2940
* Returns true if a given string is a valid tag name.
3041
*/

0 commit comments

Comments
 (0)