forked from nus-cs2103-AY2122S1/tp
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #81 from jayasting98/feature-group-storage
Add storage functionality for groups
- Loading branch information
Showing
8 changed files
with
464 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
125
src/main/java/seedu/address/storage/JsonAdaptedGroup.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.