Skip to content

Commit

Permalink
Merge branch 'master' into update-DG-Week-10
Browse files Browse the repository at this point in the history
  • Loading branch information
CJ-Lee01 authored Oct 26, 2023
2 parents 82d7a30 + 0e7b689 commit 7c3e21d
Show file tree
Hide file tree
Showing 35 changed files with 1,545 additions and 203 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
22 changes: 19 additions & 3 deletions src/main/java/seedu/address/logic/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class Messages {
"Extra irrelevant options found in the command: ";
public static final String MESSAGE_UNEXPECTED_NON_EMPTY_FIELDS =
"The following options may not have any value: ";
public static final String MESSAGE_SIMULTANEOUS_USE_DISALLOWED_FIELDS =
"The following options conflict and cannot be set together: ";

public static final String MESSAGE_INVALID_FIELD =
"The term '%s' is not a valid option!";
Expand All @@ -36,7 +38,7 @@ public static String getErrorMessageForDuplicateFlags(Flag... duplicateFlags) {
Set<String> duplicateFields =
Stream.of(duplicateFlags).map(Flag::toString).collect(Collectors.toSet());

return MESSAGE_DUPLICATE_FIELDS + String.join(" ", duplicateFields);
return MESSAGE_DUPLICATE_FIELDS + String.join(", ", duplicateFields);
}

/**
Expand All @@ -48,17 +50,31 @@ public static String getErrorMessageForExtraneousFlags(Flag... extraneousFlags)
Set<String> extraneousFields =
Stream.of(extraneousFlags).map(Flag::toString).collect(Collectors.toSet());

return MESSAGE_EXTRA_FIELDS + String.join(" ", extraneousFields);
return MESSAGE_EXTRA_FIELDS + String.join(", ", extraneousFields);
}

/**
* Returns an error message indicating the flags have unexpected values.
*/
public static String getErrorMessageForNonEmptyValuedFlags(Flag... nonEmptyValuedFlags) {
assert nonEmptyValuedFlags.length > 0;

Set<String> nonEmptyValuedFields =
Stream.of(nonEmptyValuedFlags).map(Flag::toString).collect(Collectors.toSet());

return MESSAGE_UNEXPECTED_NON_EMPTY_FIELDS + String.join(" ", nonEmptyValuedFields);
return MESSAGE_UNEXPECTED_NON_EMPTY_FIELDS + String.join(", ", nonEmptyValuedFields);
}

/**
* Returns an error message indicating the flags should not exist in the same command together.
*/
public static String getErrorMessageForSimultaneousUseDisallowedFlags(Flag... conflictingFlags) {
assert conflictingFlags.length > 1;

Set<String> conflictingFields =
Stream.of(conflictingFlags).map(Flag::toString).collect(Collectors.toSet());

return MESSAGE_SIMULTANEOUS_USE_DISALLOWED_FIELDS + String.join(", ", conflictingFields);
}

/**
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/seedu/address/logic/parser/ArgumentMultimap.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,18 @@ public void verifyAllEmptyValuesAssignedFor(Flag... flags) throws ParseException
throw new ParseException(Messages.getErrorMessageForNonEmptyValuedFlags(flagsWithUsefulValues));
}
}

/**
* Throws a {@code ParseException} if there are more than one of the given {@code flags} simultanouesly
* put in this map, i.e., they cannot be used together.
*/
public void verifyAtMostOneOfFlagsUsedOutOf(Flag... flags) throws ParseException {
Flag[] existingFlags = Stream.of(flags).distinct()
.filter(flag -> argMultimap.containsKey(flag) && argMultimap.get(flag).size() > 0)
.toArray(Flag[]::new);

if (existingFlags.length > 1) {
throw new ParseException(Messages.getErrorMessageForSimultaneousUseDisallowedFlags(existingFlags));
}
}
}
177 changes: 149 additions & 28 deletions src/main/java/seedu/address/logic/parser/Flag.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,52 +16,110 @@ public class Flag {
public static final String DEFAULT_PREFIX = "--";
public static final String DEFAULT_POSTFIX = "";

public static final String DEFAULT_ALIAS_PREFIX = "-";
public static final String DEFAULT_ALIAS_POSTFIX = "";

private final String name;
private final String prefix;
private final String postfix;

private final String alias;
private final String aliasPrefix;
private final String aliasPostfix;

/**
* Constructs a flag with the {@link #DEFAULT_PREFIX} and {@link #DEFAULT_POSTFIX} surrounding the name.
* If the name has any leading or trailing whitespace, it'll be trimmed.
* No alias will be assigned to this flag. If the name has any leading or trailing whitespace, it'll be trimmed.
*
* @param name The name of the flag. May be null, which will set it to an empty string.
*/
public Flag(String name) {
this(name, DEFAULT_PREFIX, DEFAULT_POSTFIX);
this(
name, DEFAULT_PREFIX, DEFAULT_POSTFIX,
null, null, null
);
}

/**
* Constructs a flag with a custom prefix and custom postfix.
* Constructs a flag with a custom alias.
* Any fields with leading or trailing whitespace are trimmed.
*
* @param name The name of the flag. May be null, which will set it to an empty string.
* @param prefix The prefix of the flag. May be null, which will set it to an empty string.
* @param postfix The postfix of the flag. May be null, which will set it to an empty string.
* @param alias The prefix of the flag. May be null, which will behave as if no alias is set.
*/
public Flag(String name, String prefix, String postfix) {
public Flag(String name, String alias) {
this(
name,
DEFAULT_PREFIX,
DEFAULT_POSTFIX,
alias,
alias == null ? null : DEFAULT_ALIAS_PREFIX,
alias == null ? null : DEFAULT_ALIAS_POSTFIX
);
}

/**
* Constructs a flag with the given properties for the name and alias.
*/
private Flag(String name, String prefix, String postfix, String alias, String aliasPrefix, String aliasPostfix) {
this.name = name == null ? "" : name.trim();
this.prefix = prefix == null ? "" : prefix.trim();
this.postfix = postfix == null ? "" : postfix.trim();

boolean isAliasAvailable = alias != null && !alias.isBlank();

if (isAliasAvailable) {
this.alias = alias.trim();
this.aliasPrefix = aliasPrefix == null ? this.prefix : aliasPrefix.trim();
this.aliasPostfix = aliasPostfix == null ? this.postfix : aliasPostfix.trim();
} else {
this.alias = this.name;
this.aliasPrefix = this.prefix;
this.aliasPostfix = this.postfix;
}
}

/**
* Constructs a flag with a custom name, custom prefix and custom postfix.
* Any fields with leading or trailing whitespace are trimmed.
*
* @param name The name of the flag. May be null, which will set it to an empty string.
* @param prefix The prefix of the flag. May be null, which will set it to an empty string.
* @param postfix The postfix of the flag. May be null, which will set it to an empty string.
*/
public static Flag ofCustomFormat(String name, String prefix, String postfix) {
return new Flag(name, prefix, postfix, null, null, null);
}

/**
* Parses the given string using the default prefix and postfix format into a {@link Flag}.
* This will work for both full flag strings and flag aliases.
*
* @param string The string to check for flag-like formats.
* @param string The string to parse as a flag.
* @return The corresponding {@link Flag} instance.
* @throws ParseException if the flag is invalid.
* @throws ParseException if the flag syntax is invalid.
*/
public static Flag parse(String string) throws ParseException {
if (!isFlagSyntax(string)) {
throw new ParseException(
Messages.getErrorMessageForInvalidFlagString(string)

if (string != null && string.startsWith(DEFAULT_PREFIX) && string.endsWith(DEFAULT_POSTFIX)) {
String flag = string.substring(
DEFAULT_PREFIX.length(),
string.length() - DEFAULT_POSTFIX.length()
);
return new Flag(flag);
}

return new Flag(string.substring(
DEFAULT_PREFIX.length(),
string.length() - DEFAULT_POSTFIX.length()
));
if (string != null && string.startsWith(DEFAULT_ALIAS_PREFIX) && string.endsWith(DEFAULT_ALIAS_POSTFIX)) {
String alias = string.substring(
DEFAULT_ALIAS_PREFIX.length(),
string.length() - DEFAULT_ALIAS_POSTFIX.length()
);
return new Flag(alias, alias); // Treat alias as name, since we don't know any better.
}

throw new ParseException(
Messages.getErrorMessageForInvalidFlagString(string)
);
}

/**
Expand Down Expand Up @@ -90,7 +148,11 @@ public static Optional<Flag> parseOptional(String string) {
*/
public static Optional<Flag> findMatch(String string, Flag[] flags) {
for (Flag flag : flags) {
if (string != null && string.equals(flag.getFlagString())) {
if (string == null) {
break;
}
if (string.equals(flag.getFlagString())
|| string.equals(flag.getFlagAliasString())) {
return Optional.of(flag);
}
}
Expand All @@ -109,19 +171,55 @@ public String getPostfix() {
return postfix;
}

public String getAlias() {
return alias;
}

public String getAliasPrefix() {
return aliasPrefix;
}

public String getAliasPostfix() {
return aliasPostfix;
}

/**
* Returns the full string that would be used by the user to input a flag.
* Equivalent to calling {@link #toString()}.
*
* <p>
* This is the full string that would be used by a user to input a flag.
* This means it's the concatenated result of prefix, name, postfix together.
* </p>
*/
public String getFlagString() {
return this.toString();
return this.getPrefix() + this.getName() + this.getPostfix();
}

/**
* Returns the alias string that would be used by the user to input a flag.
* It may be the same as {@link #getFlagString()} if there's no alias assigned to this flag.
*
* <p>
* This is the full alias string that would be used by a user to input a flag.
* This means it's the concatenated result of alias prefix, alias, alias postfix together.
* </p>
*/
public String getFlagAliasString() {
return this.getAliasPrefix() + this.getAlias() + this.getAliasPostfix();
}

/**
* Returns whether the flag has a distinct alias from its full string form.
*/
public boolean hasAlias() {
return !this.getFlagString().equals(this.getFlagAliasString());
}

/**
* Checks whether the given string representation resembles a flag.
* If this is true, then it resembles the default prefix-name-postfix format specified in {@link Flag},
* and is a plausible output from {@link Flag#getFlagString()}.
* or resembles the equivalent format for the alias counterpart, and thus a plausible output from
* {@link Flag#getFlagString()} or {@link Flag#getFlagAliasString()}.
*
* @param string The string to check for flag-like formats.
* @return true if the string resembles a flag, false otherwise.
Expand All @@ -130,27 +228,47 @@ public static boolean isFlagSyntax(String string) {
if (string == null) {
return false;
}
return string.startsWith(DEFAULT_PREFIX) && string.endsWith(DEFAULT_POSTFIX);
return (string.startsWith(DEFAULT_PREFIX) && string.endsWith(DEFAULT_POSTFIX))
|| (string.startsWith(DEFAULT_ALIAS_PREFIX) && string.endsWith(DEFAULT_ALIAS_POSTFIX));
}

/**
* Returns a string representation of this flag.
*
* <p>
* This is the full string that would be used by a user to input a flag.
* This means it's the concatenated result of prefix, name, postfix together.
* </p>
* Equivalent to the result from {@link #getFlagString()}.
*
* @return The string representation of this flag.
*/
@Override
public String toString() {
return this.getPrefix() + this.getName() + this.getPostfix();
return this.getFlagString();
}

@Override
public int hashCode() {
return name == null ? 0 : name.hashCode();
return Objects.hash(name, prefix, postfix, alias, aliasPrefix, aliasPostfix);
}

/**
* Returns whether the two flags have the same full flag string formats.
*/
public boolean equalsFlagString(Flag other) {
if (other == null) {
return false;
}

return this.getFlagString().equals(other.getFlagString());
}


/**
* Returns whether the two flags have the same flag alias formats.
*/
public boolean equalsFlagAliasString(Flag other) {
if (other == null) {
return false;
}

return this.getFlagAliasString().equals(other.getFlagAliasString());
}

@Override
Expand All @@ -167,6 +285,9 @@ public boolean equals(Object other) {
Flag otherFlag = (Flag) other;
return Objects.equals(name, otherFlag.name)
&& Objects.equals(prefix, otherFlag.prefix)
&& Objects.equals(postfix, otherFlag.postfix);
&& Objects.equals(postfix, otherFlag.postfix)
&& Objects.equals(alias, otherFlag.alias)
&& Objects.equals(aliasPrefix, otherFlag.aliasPrefix)
&& Objects.equals(aliasPostfix, otherFlag.aliasPostfix);
}
}
4 changes: 2 additions & 2 deletions src/main/java/seedu/address/model/contact/Contact.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public Set<Tag> getTags() {
}

/**
* Returns true if both contacts have the same name.
* Returns true if both contacts have the same id.
* This defines a weaker notion of equality between two contacts.
*/
public boolean isSameContact(Contact otherContact) {
Expand All @@ -94,7 +94,7 @@ public boolean isSameContact(Contact otherContact) {
}

return otherContact != null
&& otherContact.getName().equals(getName());
&& otherContact.getId().equals(getId());
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/seedu/address/model/contact/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

/**
* Represents an Organisation's status in the address book.
* Guarantees: immutable; is valid as declared in {@link #isValidPosition(String)}
* Guarantees: immutable; is valid as declared in {@link #isValidStatus(String)}
*/
public class Status {
public static final String MESSAGE_CONSTRAINTS =
Expand Down Expand Up @@ -54,12 +54,12 @@ public boolean equals(Object other) {
}

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

Position otherPosition = (Position) other;
return applicationStatus.equals(otherPosition.jobPosition);
Status otherStatus = (Status) other;
return applicationStatus.equals(otherStatus.applicationStatus);
}

@Override
Expand Down
Loading

0 comments on commit 7c3e21d

Please sign in to comment.