Skip to content

Commit

Permalink
Merge pull request #81 from jayasting98/feature-group-storage
Browse files Browse the repository at this point in the history
Add storage functionality for groups
  • Loading branch information
thanwinnikki committed Oct 11, 2021
2 parents 095893e + 463dcd2 commit d164e4d
Show file tree
Hide file tree
Showing 8 changed files with 464 additions and 86 deletions.
134 changes: 134 additions & 0 deletions src/main/java/seedu/address/storage/Id.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package seedu.address.storage;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Objects;
import java.util.Set;

import seedu.address.commons.exceptions.IllegalValueException;

public class Id implements Comparable<Id> {

private static final String DELIMITER = "-";
private static final String MESSAGE_MALFORMED_ID = "This ID is malformed.";
private static final int EPOCH_DAY_TOKEN_INDEX = 0;
private static final int NANO_OF_DAY_TOKEN_INDEX = 1;
private static final int HEX_RADIX = 16;
private static final String STRING_REPRESENTATION_FORMAT = "%s-%s";

private final LocalDateTime localDateTime;

private Id() {
localDateTime = LocalDateTime.now();
}

private Id(LocalDateTime localDateTime) {
this.localDateTime = localDateTime;
}

/**
* Generates an {@code Id} object that is unique within the passed set of {@code Id} objects.
*
* @param idSet The set of {@code Id} objects that the generated {@code Id} must be unique in.
* @return The generated {@code Id}.
*/
public static Id generateUniqueId(Set<Id> idSet) {
Id id = generateId();
while (idSet.contains(id)) {
id = generateId();
}
return id;
}

/**
* Generates an {@code Id}.
*
* @return The generated {@code Id}.
*/
public static Id generateId() {
return new Id();
}

/**
* Parses the given {@code String} ID to produce the corresponding {@code Id}.
*
* @param idString The {@code String} ID.
* @return The corresponding {@code Id}.
* @throws IllegalValueException If a malformed {@code String} ID is passed.
*/
public static Id parse(String idString) throws IllegalValueException {
String[] tokens = getTokens(idString);
String epochDayHex = tokens[EPOCH_DAY_TOKEN_INDEX];
LocalDate localDate = parseLocalDate(epochDayHex);
String nanoOfDayHex = tokens[NANO_OF_DAY_TOKEN_INDEX];
LocalTime localTime = parseLocalTime(nanoOfDayHex);
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
return new Id(localDateTime);
}

private static String[] getTokens(String idString) throws IllegalValueException {
String[] tokens = idString.split(DELIMITER);
if (tokens.length != 2) {
throw new IllegalValueException(MESSAGE_MALFORMED_ID);
}
return tokens;
}

private static LocalDate parseLocalDate(String epochDayHex) throws IllegalValueException {
long epochDay;
try {
epochDay = Long.parseLong(epochDayHex, HEX_RADIX);
} catch (NumberFormatException e) {
throw new IllegalValueException(MESSAGE_MALFORMED_ID);
}
LocalDate localDate = LocalDate.ofEpochDay(epochDay);
return localDate;
}

private static LocalTime parseLocalTime(String nanoOfDayHex) throws IllegalValueException {
long nanoOfDay;
try {
nanoOfDay = Long.parseLong(nanoOfDayHex, HEX_RADIX);
} catch (NumberFormatException e) {
throw new IllegalValueException(MESSAGE_MALFORMED_ID);
}
LocalTime localTime = LocalTime.ofNanoOfDay(nanoOfDay);
return localTime;
}

@Override
public int compareTo(Id o) {
return localDateTime.compareTo(o.localDateTime);
}

@Override
public boolean equals(Object o) {
if (!(o instanceof Id)) {
return false;
}

if (this == o) {
return true;
}

Id other = (Id) o;
return localDateTime.equals(other.localDateTime);
}

@Override
public int hashCode() {
// use this method for custom fields hashing instead of implementing your own
return Objects.hash(localDateTime);
}

@Override
public String toString() {
long epochDay = localDateTime.toLocalDate().toEpochDay();
long nanoOfDay = localDateTime.toLocalTime().toNanoOfDay();
String epochDayHex = Long.toHexString(epochDay);
String nanoOfDayHex = Long.toHexString(nanoOfDay);
String stringRepresentation = String.format(STRING_REPRESENTATION_FORMAT, epochDayHex, nanoOfDayHex);
return stringRepresentation;
}
}
125 changes: 125 additions & 0 deletions src/main/java/seedu/address/storage/JsonAdaptedGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package seedu.address.storage;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import seedu.address.commons.exceptions.IllegalValueException;
import seedu.address.model.group.Group;
import seedu.address.model.names.Name;
import seedu.address.model.person.Person;
import seedu.address.model.person.UniquePersonList;
import seedu.address.model.person.exceptions.DuplicatePersonException;

/**
* Jackson-friendly version of {@link Group}.
*/
@JsonDeserialize(builder = JsonAdaptedGroup.Builder.class)
public class JsonAdaptedGroup {

public static final String MISSING_FIELD_MESSAGE_FORMAT = "Group's %s field is missing!";
public static final String MESSAGE_DUPLICATE_GROUP_MATE = "Duplicate group mates(s) found in storage.";
public static final String MESSAGE_NO_SUCH_PERSON = "There is no such person that has the ID of this group mate.";

private final String name;
private final List<String> groupMateIds;

/**
* Builder class for {@code JsonAdaptedGroup}.
*/
public static class Builder {

private JsonAdaptedGroup groupToBuild;

/**
* Constructs a {@code JsonAdaptedGroup.Builder} for a {@code JsonAdaptedPerson} with the given group details.
*
* @param name The group's name.
* @param groupMateIds The list of the person IDs of all the group mates that belong to the group.
*/
@JsonCreator
public Builder(@JsonProperty("name") String name, @JsonProperty("groupMateIds") List<String> groupMateIds) {
groupToBuild = new JsonAdaptedGroup(name, groupMateIds);
}

/**
* Converts the given {@code Group} to a {@code JsonAdaptedGroup} using a {@code JsonAdaptedGroup.Builder}.
*
* @param source The {@code Group} object to be converted.
* @param personToIdMap The mapping from each {@code Person} object to its respective stored person ID.
*/
public Builder(Group source, Map<Person, String> personToIdMap) {
groupToBuild = new JsonAdaptedGroup(source, personToIdMap);
}

/**
* Completes the {@code JsonAdaptedGroup} being built by this {@code JsonAdaptedGroup.Builder}.
*
* @return The completed {@code JsonAdaptedGroup} object.
*/
public JsonAdaptedGroup build() {
return groupToBuild;
}
}

private JsonAdaptedGroup(String name, List<String> groupMateIds) {
this.name = name;
this.groupMateIds = new ArrayList<>(groupMateIds);
}

private JsonAdaptedGroup(Group source, Map<Person, String> personToIdMap) {
name = source.getName().fullName;
groupMateIds = new ArrayList<>();
UniquePersonList persons = source.getPersons();
for (Person person : persons) {
String personId = personToIdMap.get(person);
groupMateIds.add(personId);
}
}

/**
* Converts this Jackson-friendly adapted person object into the model's {@code Group} object.
* The mapping from each stored person ID to its respective {@code Person} object is required in order to add the
* correct group mates that belong to this {@code Group} object.
*
* @param idToPersonMap The mapping from each stored person ID to its respective {@code Person} object.
* @return The {@code Group} object.
* @throws IllegalValueException If there were any data constraints violated in the adapted group.
*/
public Group toModelType(Map<Id, Person> idToPersonMap) throws IllegalValueException {
final Name modelName = createName();
Group group = new Group(modelName);
addGroupMates(group, idToPersonMap);
return group;
}

private Name createName() throws IllegalValueException {
if (name == null) {
throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()));
}
if (!Name.isValidName(name)) {
throw new IllegalValueException(Name.MESSAGE_CONSTRAINTS);
}
return new Name(name);
}

private void addGroupMates(Group group, Map<Id, Person> idToPersonMap) throws IllegalValueException {
UniquePersonList persons = group.getPersons();
for (String personIdString : groupMateIds) {
Id personId = Id.parse(personIdString);
Person person = idToPersonMap.get(personId);
if (person == null) {
throw new IllegalValueException(MESSAGE_NO_SUCH_PERSON);
}
try {
persons.add(person);
} catch (DuplicatePersonException e) {
throw new IllegalValueException(MESSAGE_DUPLICATE_GROUP_MATE);
}
}
}
}

0 comments on commit d164e4d

Please sign in to comment.