Skip to content

Commit

Permalink
Implement double HashMap (#108)
Browse files Browse the repository at this point in the history
* configure reposense config.json

* fix _reposense/config.json eof

* implement double hashmap

double hashmap links ItineraryItem to Contact, vice versa. So that
changes to either triggers an update.

* update HashMap to cover Day
  • Loading branch information
KxxMxxx authored and 1nefootstep committed Oct 30, 2019
1 parent 35df366 commit 84fc809
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/main/java/seedu/address/model/Itinerary.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import seedu.address.model.day.Day;
import seedu.address.model.day.UniqueDayList;
import seedu.address.model.field.Name;
import seedu.address.model.itineraryitem.activity.Activity;


/**
Expand Down Expand Up @@ -112,6 +113,10 @@ public void resetDataItinerary(ReadOnlyItinerary newData) {
setDays(newData.getItinerary());
}

public List<Day> getDays(Activity activity) {
return days.getDays(activity);
}

//// util methods

@Override
Expand Down
151 changes: 148 additions & 3 deletions src/main/java/seedu/address/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@

import java.nio.file.Path;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
Expand All @@ -17,8 +21,10 @@
import seedu.address.commons.core.index.Index;
import seedu.address.model.contact.Contact;
import seedu.address.model.contact.Phone;
import seedu.address.model.day.ActivityWithTime;
import seedu.address.model.day.Day;
import seedu.address.model.field.Name;
import seedu.address.model.itineraryitem.ItineraryItem;
import seedu.address.model.itineraryitem.accommodation.Accommodation;
import seedu.address.model.itineraryitem.activity.Activity;

Expand All @@ -37,6 +43,10 @@ public class ModelManager implements Model {
private final FilteredList<Activity> filteredActivities;
private final FilteredList<Contact> filteredContacts;
private final FilteredList<Day> filteredItinerary;
private final HashMap<Contact, List<ItineraryItem>> contactMap;
private final HashMap<ItineraryItem, Contact> itineraryItemMap;
private final HashMap<Activity, List<Day>> activityDayMap;
private final HashMap<Accommodation, List<Day>> accommodationDayMap;

/**
* Initializes a ModelManager with the given address and userPrefs.
Expand All @@ -58,12 +68,141 @@ public ModelManager(ReadOnlyAccommodation accommodations, ReadOnlyActivity activ
filteredActivities = new FilteredList<>(this.activities.getActivityList());
filteredContacts = new FilteredList<>(this.contacts.getContactList());
filteredItinerary = new FilteredList<>(this.itinerary.getItinerary());
contactMap = new HashMap<>();
itineraryItemMap = new HashMap<>();
activityDayMap = new HashMap<>();
accommodationDayMap = new HashMap<>();
initMap();
}

public ModelManager() {
this(new AccommodationManager(), new ActivityManager(), new ContactManager(), new Itinerary(), new UserPrefs());
}

//=========== Mapping ====================================================================================

/**
* Initiates mapping of {@code ItineraryItem} to {@code Contact}, vice versa.
*/
private void initMap() {
populateMap(accommodations.getAccommodationList());
populateMap(activities.getActivityList());
}

/**
* Iterates through the {@code List} of {@code ItineraryItem} and creates a mapping between it's {@code Contact},
* if it possesses one, to itself.
*/
private void populateMap(List<? extends ItineraryItem> list) {
for (ItineraryItem item : list) {
if (item.getContact().isPresent()) {
Contact contact = getContactByPhone(item.getContact().get().getPhone()).get();
if (contactMap.containsKey(contact)) {
contactMap.get(contact).add(item);
} else {
contactMap.put(contact, new ArrayList<>((Arrays.asList(item))));
}
itineraryItemMap.put(item, contact);
}
if (item instanceof Activity) {
List<Day> days = getDays((Activity) item);
activityDayMap.put((Activity) item, days);
}
}
}

/**
* Creates a mapping between an {@code ItineraryItem} and it's {@code Contact}, if it possesses one
*/
private void addItineraryItemMapping(ItineraryItem item) {
if (item.getContact().isPresent()) {
Contact contact = item.getContact().get();
if (contactMap.containsKey(contact)) {
contactMap.get(contact).add(item);
} else {
contactMap.put(contact, new ArrayList<>((Arrays.asList(item))));
}
itineraryItemMap.put(item, contact);
}
}

/**
* Updates the mapping when there is a change to an {@code ItineraryItem}. When the {@code Contact} of the
* {@code ItineraryItem} is changed, the {@code Contact} is also updated.
*/
private void updateMapping(ItineraryItem oldItem, ItineraryItem newItem) {
if (newItem.getContact().isPresent()) {
if (oldItem.getContact().isPresent()) {
Contact oldContact = itineraryItemMap.remove(oldItem);
List<ItineraryItem> oldList = contactMap.remove(oldContact);
Contact newContact = newItem.getContact().get();
oldList.set(oldList.indexOf(oldItem), newItem);

setContact(oldContact, newContact);
contactMap.put(newContact, oldList);
itineraryItemMap.put(newItem, newContact);
} else {
addItineraryItemMapping(newItem);
}
}
if (oldItem instanceof Activity) {
if (activityDayMap.containsKey((Activity) oldItem)) {
List<Day> listOfDays = activityDayMap.remove((Activity) oldItem);
itinerary.getItinerary().forEach(x -> {
if (listOfDays.contains(x)) {
List<ActivityWithTime> listOfActivityWithTime = x.getListOfActivityWithTime();
int indexOfOldItem = listOfActivityWithTime.indexOf(oldItem);
ActivityWithTime oldActivityWithTime = listOfActivityWithTime.get(indexOfOldItem);
listOfActivityWithTime.set(indexOfOldItem, new ActivityWithTime((Activity) oldItem,
oldActivityWithTime.getStartTime(), oldActivityWithTime.getEndTime()));
}
});
activityDayMap.put((Activity) newItem, listOfDays);
}
}
}

/**
* Updates the mapping when there is a change to a {@code Contact}. When the {@code Contact} changes, the
* {@code ItineraryItem}s sharing the same contact is also updated.
*/
private void updateMapping(Contact oldContact, Contact newContact) {
if (contactMap.containsKey(oldContact)) {
List<ItineraryItem> oldList = contactMap.remove(oldContact);
List<ItineraryItem> newList = oldList.stream().map(x -> {
if (x instanceof Activity) {
Activity newActivity = new Activity(x.getName(), x.getAddress(), newContact, x.getTags());
activities.setActivity((Activity) x, newActivity);
itineraryItemMap.remove(x);
itineraryItemMap.put(newActivity, newContact);
if (activityDayMap.containsKey(x)) {
List<Day> listOfDays = activityDayMap.remove(x);
itinerary.getItinerary().forEach(y -> {
if (listOfDays.contains(y)) {
List<ActivityWithTime> listOfActivityWithTime = y.getListOfActivityWithTime();
int indexOfOldItem = listOfActivityWithTime.indexOf(x);
ActivityWithTime oldActivityWithTime = listOfActivityWithTime.get(indexOfOldItem);
listOfActivityWithTime.set(indexOfOldItem, new ActivityWithTime(newActivity,
oldActivityWithTime.getStartTime(), oldActivityWithTime.getEndTime()));
}
});
activityDayMap.put(newActivity, listOfDays);
}
return newActivity;
} else {
Accommodation newAccommodation = new Accommodation(x.getName(), x.getAddress(),
newContact, x.getTags());
accommodations.setAccommodation((Accommodation) x, newAccommodation);
itineraryItemMap.remove(x);
itineraryItemMap.put(newAccommodation, newContact);
return newAccommodation;
}
}).collect(Collectors.toList());
contactMap.put(newContact, newList);
}
}


//=========== UserPrefs ==================================================================================

@Override
Expand Down Expand Up @@ -158,6 +297,7 @@ public void deleteAccommodation(Accommodation target) {
@Override
public void addAccommodation(Accommodation accommodation) {
accommodations.addAccommodation(accommodation);
addItineraryItemMapping(accommodation);
updateFilteredAccommodationList(PREDICATE_SHOW_ALL_ACCOMMODATIONS);
}

Expand All @@ -170,7 +310,7 @@ public void addAccommodationAtIndex(Index index, Accommodation accommodation) {
@Override
public void setAccommodation(Accommodation target, Accommodation editedAccommodation) {
requireAllNonNull(target, editedAccommodation);

updateMapping(target, editedAccommodation);
accommodations.setAccommodation(target, editedAccommodation);
}

Expand Down Expand Up @@ -200,6 +340,7 @@ public void deleteActivity(Activity target) {
@Override
public void addActivity(Activity activity) {
activities.addActivity(activity);
addItineraryItemMapping(activity);
updateFilteredActivityList(PREDICATE_SHOW_ALL_ACTIVITIES);
}

Expand All @@ -212,7 +353,7 @@ public void addActivityAtIndex(Index index, Activity activity) {
@Override
public void setActivity(Activity target, Activity editedActivity) {
requireAllNonNull(target, editedActivity);

updateMapping(target, editedActivity);
activities.setActivity(target, editedActivity);
}

Expand Down Expand Up @@ -260,7 +401,7 @@ public void addContactAtIndex(Index index, Contact contact) {
@Override
public void setContact(Contact target, Contact editedContact) {
requireAllNonNull(target, editedContact);

updateMapping(target, editedContact);
contacts.setContact(target, editedContact);
}

Expand Down Expand Up @@ -322,6 +463,10 @@ public boolean hasDay(Day day) {
return itinerary.hasDay(day);
}

public List<Day> getDays(Activity activity) {
return itinerary.getDays(activity);
}

//=========== Filtered List Accessors =============================================================
// ACCOMMODATION FilteredList
/**
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/seedu/address/model/day/ActivityWithTime.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ public boolean equals(Object other) {
return true;
}

if (other instanceof Activity) {
return this.getActivity().equals(other);
}

if (!(other instanceof ActivityWithTime)) {
return false;
}
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/seedu/address/model/day/Day.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.Optional;

import seedu.address.logic.commands.exceptions.CommandException;
import seedu.address.model.itineraryitem.activity.Activity;

/**
* Represents a Day in the travel planner's planner.
Expand Down Expand Up @@ -52,6 +53,14 @@ public Optional<ActivityWithTime> getActivityWithTime(LocalTime time) {
return this.timetable.getActivityWithTimeAtTime(time);
}

/**
* Checks whether the {@code Day} contains the {@code Activity}.
*/
public boolean hasActivity(Activity activity) {
return timetable.getActivitiesWithTime().stream()
.anyMatch(x -> x.getActivity() == activity);
}

/**
* Returns true if a given string is a valid integer.
*/
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/seedu/address/model/day/UniqueDayList.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import static java.util.Objects.requireNonNull;
import static seedu.address.commons.util.CollectionUtil.requireAllNonNull;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import seedu.address.model.day.exceptions.DayNotFoundException;
import seedu.address.model.day.exceptions.DuplicateDayException;
import seedu.address.model.itineraryitem.activity.Activity;

/**
* Itinerary class helps to manage the list of days in an Planner.
Expand Down Expand Up @@ -101,6 +103,16 @@ public void remove(Day toRemove) {
}
}

public List<Day> getDays(Activity activity) {
List<Day> listOfDays = new ArrayList<>();
for (Day day : internalList) {
if (day.hasActivity(activity)) {
listOfDays.add(day);
}
}
return listOfDays;
}

/**
* Returns the backing list as an unmodifiable {@code ObservableList}.
*/
Expand Down

0 comments on commit 84fc809

Please sign in to comment.