diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index 16c2d92ff1ae..c67b4d15b89b 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.nio.file.Path; +import java.text.ParseException; import java.util.Optional; import java.util.logging.Logger; @@ -23,12 +24,7 @@ import seedu.address.model.*; import seedu.address.model.AddressBookModelManager; import seedu.address.model.util.SampleDataUtil; -import seedu.address.storage.AddressBookStorage; -import seedu.address.storage.JsonUserPrefsStorage; -import seedu.address.storage.Storage; -import seedu.address.storage.StorageManager; -import seedu.address.storage.UserPrefsStorage; -import seedu.address.storage.XmlAddressBookStorage; +import seedu.address.storage.*; import seedu.address.ui.Ui; import seedu.address.ui.UiManager; @@ -45,13 +41,14 @@ public class MainApp extends Application { protected Logic logic; protected Storage storage; protected AddressBookModel addressBookModel; + protected ScheduleModel scheduleModel; protected Config config; protected UserPrefs userPrefs; @Override public void init() throws Exception { - logger.info("=============================[ Initializing AddressBook ]==========================="); + logger.info("=============================[ Initializing PatientBook ]==========================="); super.init(); AppParameters appParameters = AppParameters.parse(getParameters()); @@ -60,18 +57,48 @@ public void init() throws Exception { UserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(config.getUserPrefsFilePath()); userPrefs = initPrefs(userPrefsStorage); AddressBookStorage addressBookStorage = new XmlAddressBookStorage(userPrefs.getAddressBookFilePath()); - storage = new StorageManager(addressBookStorage, userPrefsStorage); + ScheduleStorage scheduleStorage = new XmlScheduleStorage(userPrefs.getScheduleFilePath()); + storage = new StorageManager(addressBookStorage, scheduleStorage, userPrefsStorage); initLogging(config); addressBookModel = initModelManager(storage, userPrefs); + scheduleModel = initScheduleModel(storage, userPrefs); - logic = new LogicManager(addressBookModel); + logic = new LogicManager(addressBookModel, scheduleModel); ui = new UiManager(logic, config, userPrefs); initEventsCenter(); } + /** + * Returns a {@code ScheduleModelManager} with the data from [@code storage}'s scheduel and {@code userPrefs}.
+ * The data fromthe sample schedule will be used instead if {@code storage}'s schedule is not found, + * or an empty schedule will be used instead if errors occur when reading {@code storage}'s schedule. + */ + private ScheduleModel initScheduleModel(Storage storage, UserPrefs userPrefs){ + Optional scheduleOptional; + ReadOnlySchedule initialData; + + try { + scheduleOptional = storage.readSchedule(); + if (!scheduleOptional.isPresent()) { + logger.info("Data file not found. Will be staring with sample Schedule."); + } + initialData = scheduleOptional.orElseGet(SampleDataUtil::getSampleSchedule); + } catch (DataConversionException e) { + logger.warning("Data file not in the correct format. Will be starting with an empty Schedule."); + initialData = new Schedule(); + } catch (IOException e) { + logger.warning("Error reading from file. Will be starting with an empty schedule."); + initialData = new Schedule(); + } catch (ParseException e) { + logger.warning("Error parsing dates from file. Will be starting with an empty schedule."); + initialData = new Schedule(); + } + + return new ScheduleModelManager(initialData, userPrefs); + } /** * Returns a {@code AddressBookModelManager} with the data from {@code storage}'s address book and {@code userPrefs}.
@@ -84,11 +111,11 @@ private AddressBookModel initModelManager(Storage storage, UserPrefs userPrefs) try { addressBookOptional = storage.readAddressBook(); if (!addressBookOptional.isPresent()) { - logger.info("Data file not found. Will be starting with a sample AddressBook"); + logger.info("Data file not found. Will be starting with a sample AddressBook."); } initialData = addressBookOptional.orElseGet(SampleDataUtil::getSampleAddressBook); } catch (DataConversionException e) { - logger.warning("Data file not in the correct format. Will be starting with an empty AddressBook"); + logger.warning("Data file not in the correct format. Will be starting with an empty AddressBook."); initialData = new AddressBook(); } catch (IOException e) { logger.warning("Problem while reading from the file. Will be starting with an empty AddressBook"); @@ -176,7 +203,7 @@ private void initEventsCenter() { @Override public void start(Stage primaryStage) { - logger.info("Starting AddressBook " + MainApp.VERSION); + logger.info("Starting PatientBook " + MainApp.VERSION); ui.start(primaryStage); } diff --git a/src/main/java/seedu/address/logic/LogicManager.java b/src/main/java/seedu/address/logic/LogicManager.java index c4d04ab2c599..02536c27268d 100644 --- a/src/main/java/seedu/address/logic/LogicManager.java +++ b/src/main/java/seedu/address/logic/LogicManager.java @@ -8,9 +8,10 @@ import seedu.address.logic.commands.Command; import seedu.address.logic.commands.CommandResult; import seedu.address.logic.commands.exceptions.CommandException; -import seedu.address.logic.parser.AddressBookParser; +import seedu.address.logic.parser.PatientBookParser; import seedu.address.logic.parser.exceptions.ParseException; import seedu.address.model.AddressBookModel; +import seedu.address.model.ScheduleModel; import seedu.address.model.person.Person; /** @@ -20,20 +21,22 @@ public class LogicManager extends ComponentManager implements Logic { private final Logger logger = LogsCenter.getLogger(LogicManager.class); private final AddressBookModel addressBookModel; + private final ScheduleModel scheduleModel; private final CommandHistory history; - private final AddressBookParser addressBookParser; + private final PatientBookParser patientBookParser; - public LogicManager(AddressBookModel addressBookModel) { + public LogicManager(AddressBookModel addressBookModel, ScheduleModel scheduleModel) { this.addressBookModel = addressBookModel; + this.scheduleModel = scheduleModel; history = new CommandHistory(); - addressBookParser = new AddressBookParser(); + patientBookParser = new PatientBookParser(); } @Override public CommandResult execute(String commandText) throws CommandException, ParseException { logger.info("----------------[USER COMMAND][" + commandText + "]"); try { - Command command = addressBookParser.parseCommand(commandText); + Command command = patientBookParser.parseCommand(commandText); return command.execute(addressBookModel, history); } finally { history.add(commandText); diff --git a/src/main/java/seedu/address/logic/parser/AddressBookParser.java b/src/main/java/seedu/address/logic/parser/PatientBookParser.java similarity index 98% rename from src/main/java/seedu/address/logic/parser/AddressBookParser.java rename to src/main/java/seedu/address/logic/parser/PatientBookParser.java index 0b5e562ec8ea..d334c15f3653 100644 --- a/src/main/java/seedu/address/logic/parser/AddressBookParser.java +++ b/src/main/java/seedu/address/logic/parser/PatientBookParser.java @@ -13,7 +13,7 @@ /** * Parses user input. */ -public class AddressBookParser { +public class PatientBookParser { /** * Used for initial separation of command word and args. diff --git a/src/main/java/seedu/address/model/Model.java b/src/main/java/seedu/address/model/Model.java deleted file mode 100644 index 2ab46e038ab6..000000000000 --- a/src/main/java/seedu/address/model/Model.java +++ /dev/null @@ -1,14 +0,0 @@ -package seedu.address.model; - -import static java.util.Objects.requireNonNull; -import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; - -import java.util.function.Predicate; -import java.util.logging.Logger; - -/** - * Encapsulates the different functions of PatientBook. Contains an AddressBook and a Schedule. - */ -// TODO: Update Logic to utilize this new model. -public class Model { -} diff --git a/src/main/java/seedu/address/model/UserPrefs.java b/src/main/java/seedu/address/model/UserPrefs.java index 980b2b388852..5811368fc2a0 100644 --- a/src/main/java/seedu/address/model/UserPrefs.java +++ b/src/main/java/seedu/address/model/UserPrefs.java @@ -12,7 +12,8 @@ public class UserPrefs { private GuiSettings guiSettings; - private Path addressBookFilePath = Paths.get("data" , "addressbook.xml"); + private Path addressBookFilePath = Paths.get("addressBookData" , "addressbook.xml"); + private Path scheduleFilePath = Paths.get("scheduleData", "schedule.xml"); public UserPrefs() { setGuiSettings(500, 500, 0, 0); @@ -38,6 +39,10 @@ public void setAddressBookFilePath(Path addressBookFilePath) { this.addressBookFilePath = addressBookFilePath; } + public Path getScheduleFilePath() { return scheduleFilePath; } + + public void setScheduleFilePath(Path scheduleFilePath) { this.scheduleFilePath = scheduleFilePath; } + @Override public boolean equals(Object other) { if (other == this) { @@ -50,19 +55,21 @@ public boolean equals(Object other) { UserPrefs o = (UserPrefs) other; return Objects.equals(guiSettings, o.guiSettings) - && Objects.equals(addressBookFilePath, o.addressBookFilePath); + && Objects.equals(addressBookFilePath, o.addressBookFilePath) + && Objects.equals(scheduleFilePath, o.scheduleFilePath); } @Override public int hashCode() { - return Objects.hash(guiSettings, addressBookFilePath); + return Objects.hash(guiSettings, addressBookFilePath, scheduleFilePath); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Gui Settings : " + guiSettings.toString()); - sb.append("\nLocal data file location : " + addressBookFilePath); + sb.append("\nLocal address book data file location : " + addressBookFilePath); + sb.append("\nLocal schedule data file location : " + scheduleFilePath); return sb.toString(); } diff --git a/src/main/java/seedu/address/model/event/EventID.java b/src/main/java/seedu/address/model/event/EventID.java index 37b80edf3e03..2e7df059f2a2 100644 --- a/src/main/java/seedu/address/model/event/EventID.java +++ b/src/main/java/seedu/address/model/event/EventID.java @@ -1,11 +1,16 @@ package seedu.address.model.event; +import static java.util.Objects.requireNonNull; + /** * Represents a EventID for a ScheduleEvent in the calendar for patient book. * EventID only increases, and each event is bound to its EventID forever. */ public class EventID { + public static final String MESSAGE_EVENTID_CONSTRAINTS = + "Event ID should start with e, followed by a sequence of integers."; + // EventID iterator private static int idCounter = 0; @@ -17,8 +22,21 @@ public class EventID { */ public EventID() { value = getNewID(); } + /** + * Constructs an {@code EventID} based on an existing ID. + */ + public EventID(String value) { + requireNonNull(value); + + this.value = value; + int idValue = Integer.parseInt(value.substring(1, value.length()-1)); + if (idValue >= idCounter) { + idCounter = idValue + 1; + } + } + private static String getNewID() { - String id = new String("e"+Integer.toString(idCounter)); + String id = "e"+Integer.toString(idCounter); idCounter += 1; return id; } diff --git a/src/main/java/seedu/address/model/event/ScheduleEvent.java b/src/main/java/seedu/address/model/event/ScheduleEvent.java index 706b3d101731..0d441dd5d792 100644 --- a/src/main/java/seedu/address/model/event/ScheduleEvent.java +++ b/src/main/java/seedu/address/model/event/ScheduleEvent.java @@ -2,10 +2,12 @@ import static seedu.address.commons.util.CollectionUtil.requireAllNonNull; +import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Locale; import java.util.Objects; import java.util.Set; import javafx.util.Pair; @@ -19,6 +21,13 @@ */ public class ScheduleEvent { + // Standard datetime String format to be used by this application + public static final SimpleDateFormat sdf; + + static { + sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH); + } + // Enumerated Variable to represent calendar event attributes private enum ScheduleEventProperty { DATETIME, PERSONID, DETAILS, TAGS} @@ -29,12 +38,15 @@ private enum ScheduleEventProperty { private final EventID id; /** - * * Every field must be present and not null. */ public ScheduleEvent(Pair date, PersonID personID, String details, Set tags) { - requireAllNonNull(date, personID, details, tags); - this.id = new EventID(); + this(new EventID(), date, personID, details, tags); + } + + public ScheduleEvent(EventID eventID, Pair date, PersonID personID, String details, Set tags) { + requireAllNonNull(eventID, date, personID, details, tags); + this.id = eventID; this.attributes = new HashMap<>(); Pair scheduleEventDate = new Pair<>(date.getKey(), date.getValue()); @@ -108,9 +120,9 @@ public String toString() { builder.append("ScheduleEvent (Appointment) for PersonID: ") .append(getID()) .append(" for daterange ") - .append(getDate().getKey()) + .append(sdf.format(getDate().getKey().getTime())) .append(" to ") - .append(getDate().getValue()) + .append(sdf.format(getDate().getValue().getTime())) .append("\nDetails: ") .append(getDetails()) .append("\nTags: "); diff --git a/src/main/java/seedu/address/model/person/Person.java b/src/main/java/seedu/address/model/person/Person.java index 15df559c6f95..8e8c9c603bb2 100644 --- a/src/main/java/seedu/address/model/person/Person.java +++ b/src/main/java/seedu/address/model/person/Person.java @@ -39,8 +39,9 @@ private enum PersonProperty {NAME, PHONE, EMAIL, ADDRESS, TAGS} * * Every field must be present and not null. */ - public Person(Name name, Phone phone, Email email, Address address, Set tags) { - requireAllNonNull(name, phone, email, address, tags); + + public Person(PersonID personID, Name name, Phone phone, Email email, Address address, boolean exists, Set tags) { + requireAllNonNull(personID, name, phone, email, address, tags); this.id = new PersonID(); this.exists = true; this.attributes = new HashMap<>(); @@ -51,16 +52,13 @@ public Person(Name name, Phone phone, Email email, Address address, Set tag Set personTags = new HashSet<>(tags); // adds all tags into here this.attributes.put(PersonProperty.TAGS, personTags); + } - /* - this.name = name; - this.phone = phone; - this.email = email; - this.address = address; - this.tags.addAll(tags); - */ + public Person(Name name, Phone phone, Email email, Address address, Set tags) { + this(new PersonID(), name, phone, email, address, true, tags); } + public PersonID getID() { return this.id; } diff --git a/src/main/java/seedu/address/model/person/PersonID.java b/src/main/java/seedu/address/model/person/PersonID.java index e3600d205c7b..baf5c031b540 100644 --- a/src/main/java/seedu/address/model/person/PersonID.java +++ b/src/main/java/seedu/address/model/person/PersonID.java @@ -1,11 +1,15 @@ package seedu.address.model.person; +import static java.util.Objects.requireNonNull; /** * Represents a Person's PersonID in the address book. * PersonID only increases, and a person is bound to their PersonID forever. */ public class PersonID { + public static final String MESSAGE_PERSONID_CONSTRAINTS = + "Person ID should start with p, followed by a sequence of integers."; + // PersonID iterator private static int idCounter = 0; @@ -19,8 +23,21 @@ public PersonID() { value = getNewID(); } + /** + * Constructs a {@code PersonID} from an existing ID. + */ + public PersonID(String value) { + requireNonNull(value); + + this.value = value; + int idValue = Integer.parseInt(value.substring(1, value.length()-1)); + if (idValue >= idCounter) { + idCounter = idValue + 1; + } + } + private static String getNewID(){ - String id = new String("p"+Integer.toString(idCounter)); + String id = "p"+Integer.toString(idCounter); idCounter += 1; return id; } diff --git a/src/main/java/seedu/address/model/util/SampleDataUtil.java b/src/main/java/seedu/address/model/util/SampleDataUtil.java index 1806da4facfa..cd8bfd4d8813 100644 --- a/src/main/java/seedu/address/model/util/SampleDataUtil.java +++ b/src/main/java/seedu/address/model/util/SampleDataUtil.java @@ -6,6 +6,9 @@ import seedu.address.model.AddressBook; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.ReadOnlySchedule; +import seedu.address.model.Schedule; +import seedu.address.model.event.ScheduleEvent; import seedu.address.model.person.Address; import seedu.address.model.person.Email; import seedu.address.model.person.Name; @@ -40,6 +43,12 @@ public static Person[] getSamplePersons() { }; } + public static ScheduleEvent[] getSampleEvents() { + return new ScheduleEvent[] { + + }; + } + public static ReadOnlyAddressBook getSampleAddressBook() { AddressBook sampleAb = new AddressBook(); for (Person samplePerson : getSamplePersons()) { @@ -48,6 +57,14 @@ public static ReadOnlyAddressBook getSampleAddressBook() { return sampleAb; } + public static ReadOnlySchedule getSampleSchedule() { + Schedule sampleSchedule = new Schedule(); + for (ScheduleEvent e : getSampleEvents()) { + sampleSchedule.addScheduleEvent(e); + } + return sampleSchedule; + } + /** * Returns a tag set containing the list of strings given. */ diff --git a/src/main/java/seedu/address/storage/ScheduleStorage.java b/src/main/java/seedu/address/storage/ScheduleStorage.java new file mode 100644 index 000000000000..f6dd612d6db5 --- /dev/null +++ b/src/main/java/seedu/address/storage/ScheduleStorage.java @@ -0,0 +1,46 @@ +package seedu.address.storage; + +import java.io.IOException; +import java.nio.file.Path; +import java.text.ParseException; +import java.util.Optional; + +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.model.ReadOnlySchedule; + +/** + * Represents a storage for {@link seedu.address.model.Schedule}. + */ +public interface ScheduleStorage { + + /** + * Returns the file path of the data file. + */ + Path getScheduleFilePath(); + + /** + * Returns Schedule data as a {@link ReadOnlySchedule}. + * Returns {@code Optional.empty()} if storage file is not found. + * @throws DataConversionException if the data in storage is not in expected format. + * @throws IOException if there was any problem when reading from the storage. + */ + Optional readSchedule() throws DataConversionException, IOException, ParseException; + + /** + * @see #getScheduleFilePath() + */ + Optional readSchedule(Path filePath) throws DataConversionException, IOException, ParseException; + + /** + * Saves the given {@link ReadOnlySchedule} to the storage. + * @param schedule cannot be null. + * @throws IOException if there was any problem writing to the file. + */ + void saveSchedule(ReadOnlySchedule schedule) throws IOException; + + /** + * @see #saveSchedule(ReadOnlySchedule) + */ + void saveSchedule(ReadOnlySchedule schedule, Path filePath) throws IOException; + +} diff --git a/src/main/java/seedu/address/storage/Storage.java b/src/main/java/seedu/address/storage/Storage.java index 28791127999b..dd355667f84f 100644 --- a/src/main/java/seedu/address/storage/Storage.java +++ b/src/main/java/seedu/address/storage/Storage.java @@ -2,18 +2,21 @@ import java.io.IOException; import java.nio.file.Path; +import java.text.ParseException; import java.util.Optional; import seedu.address.commons.events.model.AddressBookChangedEvent; +import seedu.address.commons.events.model.ScheduleChangedEvent; import seedu.address.commons.events.storage.DataSavingExceptionEvent; import seedu.address.commons.exceptions.DataConversionException; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.ReadOnlySchedule; import seedu.address.model.UserPrefs; /** * API of the Storage component */ -public interface Storage extends AddressBookStorage, UserPrefsStorage { +public interface Storage extends AddressBookStorage, ScheduleStorage, UserPrefsStorage { @Override Optional readUserPrefs() throws DataConversionException, IOException; @@ -30,10 +33,27 @@ public interface Storage extends AddressBookStorage, UserPrefsStorage { @Override void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException; + @Override + Path getScheduleFilePath(); + + @Override + Optional readSchedule() throws DataConversionException, IOException, ParseException; + + @Override + void saveSchedule(ReadOnlySchedule schedule) throws IOException; + + /** * Saves the current version of the Address Book to the hard disk. * Creates the data file if it is missing. * Raises {@link DataSavingExceptionEvent} if there was an error during saving. */ void handleAddressBookChangedEvent(AddressBookChangedEvent abce); + + /** + * Saves the current version of the Schedule to the hard disk. + * Creates the data file if it is missing. + * Raises {@link DataSavingExceptionEvent} if there was an error during saving. + */ + void handleScheduleChangedEvent(ScheduleChangedEvent sce); } diff --git a/src/main/java/seedu/address/storage/StorageManager.java b/src/main/java/seedu/address/storage/StorageManager.java index b0df908a76a7..023d7528f3d9 100644 --- a/src/main/java/seedu/address/storage/StorageManager.java +++ b/src/main/java/seedu/address/storage/StorageManager.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.nio.file.Path; +import java.text.ParseException; import java.util.Optional; import java.util.logging.Logger; @@ -10,9 +11,11 @@ import seedu.address.commons.core.ComponentManager; import seedu.address.commons.core.LogsCenter; import seedu.address.commons.events.model.AddressBookChangedEvent; +import seedu.address.commons.events.model.ScheduleChangedEvent; import seedu.address.commons.events.storage.DataSavingExceptionEvent; import seedu.address.commons.exceptions.DataConversionException; import seedu.address.model.ReadOnlyAddressBook; +import seedu.address.model.ReadOnlySchedule; import seedu.address.model.UserPrefs; /** @@ -22,12 +25,15 @@ public class StorageManager extends ComponentManager implements Storage { private static final Logger logger = LogsCenter.getLogger(StorageManager.class); private AddressBookStorage addressBookStorage; + private ScheduleStorage scheduleStorage; private UserPrefsStorage userPrefsStorage; - public StorageManager(AddressBookStorage addressBookStorage, UserPrefsStorage userPrefsStorage) { + public StorageManager(AddressBookStorage addressBookStorage, ScheduleStorage scheduleStorage, + UserPrefsStorage userPrefsStorage) { super(); this.addressBookStorage = addressBookStorage; + this.scheduleStorage = scheduleStorage; this.userPrefsStorage = userPrefsStorage; } @@ -63,7 +69,7 @@ public Optional readAddressBook() throws DataConversionExce @Override public Optional readAddressBook(Path filePath) throws DataConversionException, IOException { - logger.fine("Attempting to read data from file: " + filePath); + logger.fine("Attempting to read address book from file: " + filePath); return addressBookStorage.readAddressBook(filePath); } @@ -74,7 +80,7 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook) throws IOException @Override public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) throws IOException { - logger.fine("Attempting to write to data file: " + filePath); + logger.fine("Attempting to write to address book data file: " + filePath); addressBookStorage.saveAddressBook(addressBook, filePath); } @@ -82,7 +88,7 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) thro @Override @Subscribe public void handleAddressBookChangedEvent(AddressBookChangedEvent event) { - logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local data changed, saving to file")); + logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local address book changed, saving to file")); try { saveAddressBook(event.data); } catch (IOException e) { @@ -90,4 +96,39 @@ public void handleAddressBookChangedEvent(AddressBookChangedEvent event) { } } + @Override + public Path getScheduleFilePath() { return scheduleStorage.getScheduleFilePath(); } + + @Override + public Optional readSchedule() throws DataConversionException, IOException, ParseException { + return readSchedule(scheduleStorage.getScheduleFilePath()); + } + + @Override + public Optional readSchedule(Path filePath) throws DataConversionException, IOException, ParseException { + logger.fine("Attempting to read schedule from file: " + filePath); + return scheduleStorage.readSchedule(filePath); + } + + @Override + public void saveSchedule(ReadOnlySchedule schedule) throws IOException { + saveSchedule(schedule, scheduleStorage.getScheduleFilePath()); + } + + @Override + public void saveSchedule(ReadOnlySchedule schedule, Path filePath) throws IOException { + logger.fine("Attempting to write to schedule data file: " + filePath); + scheduleStorage.saveSchedule(schedule, filePath); + } + + @Override + @Subscribe + public void handleScheduleChangedEvent(ScheduleChangedEvent event) { + logger.info(LogsCenter.getEventHandlingLogMessage(event, "Local schedule changed, saving to file")); + try { + saveSchedule(event.data); + } catch (IOException e) { + raise(new DataSavingExceptionEvent(e)); + } + } } diff --git a/src/main/java/seedu/address/storage/XmlAdaptedEvent.java b/src/main/java/seedu/address/storage/XmlAdaptedEvent.java new file mode 100644 index 000000000000..f53ba7cb06bd --- /dev/null +++ b/src/main/java/seedu/address/storage/XmlAdaptedEvent.java @@ -0,0 +1,149 @@ +package seedu.address.storage; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +import java.util.Calendar; +import javafx.util.Pair; +import javax.xml.bind.annotation.XmlElement; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.event.EventID; +import seedu.address.model.person.PersonID; +import seedu.address.model.event.ScheduleEvent; +import seedu.address.model.tag.Tag; + +/** + * JAXB-friendly version of the Event. + */ +public class XmlAdaptedEvent { + + public static final String MISSING_FIELD_MESSAGE_FORMAT = "Event's %s field is missing!"; + + @XmlElement(required = true) + private String eventID; + + @XmlElement(required = true) + private String datetimeStart; + + @XmlElement(required = true) + private String datetimeEnd; + + @XmlElement(required = true) + private String personID; + + @XmlElement(required = true) + private String details; + + @XmlElement + private List tagged = new ArrayList<>(); + + /** + * Constructs an XmlAdaptedEvent. + * This is the no-arg constructor that is required by JAXB. + */ + public XmlAdaptedEvent() {} + + /** + * Construcst an {@code XmlAdaptedEvent} with the given event details. + */ + public XmlAdaptedEvent(String eventID, String datetimeStart, String datetimeEnd, String personID, String details, List tagged) { + this.eventID = eventID; + this.datetimeStart = datetimeStart; + this.datetimeEnd = datetimeEnd; + this.personID = personID; + this.details = details; + if (tagged != null) { + this.tagged = new ArrayList<>(tagged); + } + } + + /** + * Converts a given Event into this class for JAXB use. + * + * @param source future changes to this will not affect the created XmlAdaptedEvent + */ + public XmlAdaptedEvent(ScheduleEvent source) { + eventID = source.getID().toString(); + datetimeStart = ScheduleEvent.sdf.format(source.getDate().getKey().getTime()); + datetimeEnd = ScheduleEvent.sdf.format(source.getDate().getValue().getTime()); + personID = source.getPersonID().toString(); + details = source.getDetails(); + tagged = source.getTags().stream() + .map(XmlAdaptedTag::new) + .collect(Collectors.toList()); + } + + public ScheduleEvent toModelType() throws IllegalValueException, ParseException { + final List eventTags = new ArrayList<>(); + for (XmlAdaptedTag tag : tagged) { + eventTags.add(tag.toModelType()); + } + + if (eventID == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, EventID.class.getSimpleName())); + } + if (!EventID.isValidID(eventID)) { + throw new IllegalValueException(EventID.MESSAGE_EVENTID_CONSTRAINTS); + } + final EventID modelEventID = new EventID(eventID); + + if (datetimeStart == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "Calendar Start")); + } + if (ScheduleEvent.sdf.parse(datetimeStart) == null) { + throw new IllegalValueException("Unable to parse datetime start"); + } + if (datetimeEnd == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "Calendar End")); + } + if (ScheduleEvent.sdf.parse(datetimeEnd) == null) { + throw new IllegalValueException("Unable to parse datetime end"); + } + Calendar startTime = Calendar.getInstance(); + startTime.setTime(ScheduleEvent.sdf.parse(datetimeStart)); + Calendar endTime = Calendar.getInstance(); + endTime.setTime(ScheduleEvent.sdf.parse(datetimeEnd)); + final Pair modelCalendarPair = new Pair<>(startTime, endTime); + + if (personID == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, PersonID.class.getSimpleName())); + } + if (!PersonID.isValidID(personID)) { + throw new IllegalValueException(PersonID.MESSAGE_PERSONID_CONSTRAINTS); + } + final PersonID modelPersonID = new PersonID(personID); + + if (details == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "Details")); + } + final String modelDetails = details; + + final Set modelTags = new HashSet<>(eventTags); + return new ScheduleEvent(modelEventID, modelCalendarPair, modelPersonID, modelDetails, modelTags); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof XmlAdaptedEvent)) { + return false; + } + + XmlAdaptedEvent otherEvent = (XmlAdaptedEvent) other; + return Objects.equals(eventID, otherEvent.eventID) + && Objects.equals(datetimeStart, otherEvent.datetimeStart) + && Objects.equals(datetimeEnd, otherEvent.datetimeEnd) + && Objects.equals(personID, otherEvent.personID) + && Objects.equals(details, otherEvent.details) + && tagged.equals(otherEvent.tagged); + } +} diff --git a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java index 2e22709cbbbe..603031db1619 100644 --- a/src/main/java/seedu/address/storage/XmlAdaptedPerson.java +++ b/src/main/java/seedu/address/storage/XmlAdaptedPerson.java @@ -14,6 +14,7 @@ import seedu.address.model.person.Email; import seedu.address.model.person.Name; import seedu.address.model.person.Person; +import seedu.address.model.person.PersonID; import seedu.address.model.person.Phone; import seedu.address.model.tag.Tag; @@ -24,6 +25,8 @@ public class XmlAdaptedPerson { public static final String MISSING_FIELD_MESSAGE_FORMAT = "Person's %s field is missing!"; + @XmlElement(required = true) + private String personID; @XmlElement(required = true) private String name; @XmlElement(required = true) @@ -32,6 +35,8 @@ public class XmlAdaptedPerson { private String email; @XmlElement(required = true) private String address; + @XmlElement(required = true) + private String exists; @XmlElement private List tagged = new ArrayList<>(); @@ -45,11 +50,13 @@ public XmlAdaptedPerson() {} /** * Constructs an {@code XmlAdaptedPerson} with the given person details. */ - public XmlAdaptedPerson(String name, String phone, String email, String address, List tagged) { + public XmlAdaptedPerson(String personID, String name, String phone, String email, String address, String exists, List tagged) { + this.personID = personID; this.name = name; this.phone = phone; this.email = email; this.address = address; + this.exists = exists; if (tagged != null) { this.tagged = new ArrayList<>(tagged); } @@ -61,10 +68,12 @@ public XmlAdaptedPerson(String name, String phone, String email, String address, * @param source future changes to this will not affect the created XmlAdaptedPerson */ public XmlAdaptedPerson(Person source) { + personID = source.getID().toString(); name = source.getName().fullName; phone = source.getPhone().value; email = source.getEmail().value; address = source.getAddress().value; + exists = source.getExists() ? "true" : "false"; tagged = source.getTags().stream() .map(XmlAdaptedTag::new) .collect(Collectors.toList()); @@ -81,6 +90,14 @@ public Person toModelType() throws IllegalValueException { personTags.add(tag.toModelType()); } + if (personID == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, PersonID.class.getSimpleName())); + } + if (!PersonID.isValidID(personID)) { + throw new IllegalValueException(PersonID.MESSAGE_PERSONID_CONSTRAINTS); + } + final PersonID modelPersonID = new PersonID(personID); + if (name == null) { throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName())); } @@ -113,8 +130,16 @@ public Person toModelType() throws IllegalValueException { } final Address modelAddress = new Address(address); + if (exists == null) { + throw new IllegalValueException(String.format(MISSING_FIELD_MESSAGE_FORMAT, "exists")); + } + if(!(exists.equals("true") || exists.equals("false"))) { + throw new IllegalValueException("Existence must either be true or false"); + } + final boolean modelExists = exists.equals("true"); + final Set modelTags = new HashSet<>(personTags); - return new Person(modelName, modelPhone, modelEmail, modelAddress, modelTags); + return new Person(modelPersonID, modelName, modelPhone, modelEmail, modelAddress, modelExists, modelTags); } @Override @@ -128,10 +153,12 @@ public boolean equals(Object other) { } XmlAdaptedPerson otherPerson = (XmlAdaptedPerson) other; - return Objects.equals(name, otherPerson.name) + return Objects.equals(personID, otherPerson.personID) + && Objects.equals(name, otherPerson.name) && Objects.equals(phone, otherPerson.phone) && Objects.equals(email, otherPerson.email) && Objects.equals(address, otherPerson.address) + && exists == otherPerson.exists && tagged.equals(otherPerson.tagged); } } diff --git a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java index ecf0e7ec23a8..3feaf26e766a 100644 --- a/src/main/java/seedu/address/storage/XmlAddressBookStorage.java +++ b/src/main/java/seedu/address/storage/XmlAddressBookStorage.java @@ -51,7 +51,7 @@ public Optional readAddressBook(Path filePath) throws DataC return Optional.empty(); } - XmlSerializableAddressBook xmlAddressBook = XmlFileStorage.loadDataFromSaveFile(filePath); + XmlSerializableAddressBook xmlAddressBook = XmlFileStorage.loadAddressBookFromSaveFile(filePath); try { return Optional.of(xmlAddressBook.toModelType()); } catch (IllegalValueException ive) { @@ -74,7 +74,7 @@ public void saveAddressBook(ReadOnlyAddressBook addressBook, Path filePath) thro requireNonNull(filePath); FileUtil.createIfMissing(filePath); - XmlFileStorage.saveDataToFile(filePath, new XmlSerializableAddressBook(addressBook)); + XmlFileStorage.saveAddressBookToFile(filePath, new XmlSerializableAddressBook(addressBook)); } } diff --git a/src/main/java/seedu/address/storage/XmlFileStorage.java b/src/main/java/seedu/address/storage/XmlFileStorage.java index d8f65dc036ab..e2f978d6ef9a 100644 --- a/src/main/java/seedu/address/storage/XmlFileStorage.java +++ b/src/main/java/seedu/address/storage/XmlFileStorage.java @@ -15,7 +15,7 @@ public class XmlFileStorage { /** * Saves the given addressbook data to the specified file. */ - public static void saveDataToFile(Path file, XmlSerializableAddressBook addressBook) + public static void saveAddressBookToFile(Path file, XmlSerializableAddressBook addressBook) throws FileNotFoundException { try { XmlUtil.saveDataToFile(file, addressBook); @@ -27,7 +27,7 @@ public static void saveDataToFile(Path file, XmlSerializableAddressBook addressB /** * Returns address book in the file or an empty address book */ - public static XmlSerializableAddressBook loadDataFromSaveFile(Path file) throws DataConversionException, + public static XmlSerializableAddressBook loadAddressBookFromSaveFile(Path file) throws DataConversionException, FileNotFoundException { try { return XmlUtil.getDataFromFile(file, XmlSerializableAddressBook.class); @@ -36,4 +36,24 @@ public static XmlSerializableAddressBook loadDataFromSaveFile(Path file) throws } } + public static void saveScheduleToFile(Path file, XmlSerializableSchedule schedule) + throws FileNotFoundException { + try { + XmlUtil.saveDataToFile(file, schedule); + } catch (JAXBException e) { + throw new AssertionError("Unexpected exception " + e.getMessage(), e); + } + } + + /** + * Returns schedule in the file or an empty schedule + */ + public static XmlSerializableSchedule loadScheduleFromSaveFile(Path file) throws DataConversionException, + FileNotFoundException { + try { + return XmlUtil.getDataFromFile(file, XmlSerializableSchedule.class); + } catch (JAXBException e) { + throw new DataConversionException(e); + } + } } diff --git a/src/main/java/seedu/address/storage/XmlScheduleStorage.java b/src/main/java/seedu/address/storage/XmlScheduleStorage.java new file mode 100644 index 000000000000..213fb0259b85 --- /dev/null +++ b/src/main/java/seedu/address/storage/XmlScheduleStorage.java @@ -0,0 +1,78 @@ +package seedu.address.storage; + +import static java.util.Objects.requireNonNull; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.ParseException; +import java.util.Optional; +import java.util.logging.Logger; + +import seedu.address.commons.core.LogsCenter; +import seedu.address.commons.exceptions.DataConversionException; +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.commons.util.FileUtil; +import seedu.address.model.ReadOnlySchedule; + + +/** + * A class to access Schedule data stored as an xml file on the hard disk. + */ +public class XmlScheduleStorage implements ScheduleStorage { + + private static final Logger logger = LogsCenter.getLogger(XmlScheduleStorage.class); + + private Path filePath; + + public XmlScheduleStorage(Path filePath) { this.filePath = filePath; } + + public Path getScheduleFilePath() { return filePath; } + + @Override + public Optional readSchedule() throws DataConversionException, IOException, ParseException { + return readSchedule(filePath); + } + + /** + * Similar to {@link #readSchedule()} + * @param filePath location of the data. Cannot be null. + * @throws DataConversionException if the file is not in the correct format. + */ + public Optional readSchedule(Path filePath) throws DataConversionException, + FileNotFoundException, + ParseException { + requireNonNull(filePath); + + if(!Files.exists(filePath)) { + logger.info("Schedule file " + filePath + " not found"); + return Optional.empty(); + } + + XmlSerializableSchedule xmlSchedule = XmlFileStorage.loadScheduleFromSaveFile(filePath); + try { + return Optional.of(xmlSchedule.toModelType()); + } catch (IllegalValueException ive) { + logger.info("Illegal values found in " + filePath + ": " + ive.getMessage()); + throw new DataConversionException(ive); + } + } + + @Override + public void saveSchedule(ReadOnlySchedule schedule) throws IOException { + saveSchedule(schedule, filePath); + } + + /** + * Similar to {@link #saveSchedule(ReadOnlySchedule}} + * @param filePath location of the data. Cannot be null + */ + public void saveSchedule(ReadOnlySchedule schedule, Path filePath) throws IOException { + requireNonNull(schedule); + requireNonNull(filePath); + + FileUtil.createIfMissing(filePath); + XmlFileStorage.saveScheduleToFile(filePath, new XmlSerializableSchedule(schedule)); + } +} diff --git a/src/main/java/seedu/address/storage/XmlSerializableSchedule.java b/src/main/java/seedu/address/storage/XmlSerializableSchedule.java new file mode 100644 index 000000000000..dd73ba5338a9 --- /dev/null +++ b/src/main/java/seedu/address/storage/XmlSerializableSchedule.java @@ -0,0 +1,69 @@ +package seedu.address.storage; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import seedu.address.commons.exceptions.IllegalValueException; +import seedu.address.model.Schedule; +import seedu.address.model.ReadOnlySchedule; +import seedu.address.model.event.ScheduleEvent; + +/** + * An Immutable Schedule that is serializable to XML format + */ +public class XmlSerializableSchedule { + + public static final String MESSAGE_DUPLICATE_EVENT = "Event list contains duplicate event(s)."; + + @XmlElement + private List events; + + /** + * Creates an empty XmlSerializableSchedule. + * This empty constructor is required for marshalling. + */ + public XmlSerializableSchedule() { events = new ArrayList<>(); } + + /** + * Conversion + */ + public XmlSerializableSchedule(ReadOnlySchedule src) { + this(); + events.addAll(src.getAllEventList().stream().map(XmlAdaptedEvent::new).collect(Collectors.toList())); + } + + /** + * Converts this schedule into the scheduleModels' {@code Schedule} object. + * + * @throws IllegalValueException if there was any data constraints violated or duplicates in the + * {@code XmlAdaptedEvent}. + */ + public Schedule toModelType() throws IllegalValueException, ParseException { + Schedule schedule = new Schedule(); + for (XmlAdaptedEvent e : events) { + ScheduleEvent event = e.toModelType(); + if (schedule.hasScheduleEvent(event)) { + throw new IllegalValueException(MESSAGE_DUPLICATE_EVENT); + } + schedule.addScheduleEvent(event); + } + return schedule; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + + if (!(other instanceof XmlSerializableSchedule)) { + return false; + } + return events.equals(((XmlSerializableSchedule) other).events); + } +} diff --git a/src/test/java/seedu/address/commons/util/XmlUtilTest.java b/src/test/java/seedu/address/commons/util/XmlUtilTest.java index 83f1eab8dfed..06ded2b9470f 100644 --- a/src/test/java/seedu/address/commons/util/XmlUtilTest.java +++ b/src/test/java/seedu/address/commons/util/XmlUtilTest.java @@ -36,10 +36,12 @@ public class XmlUtilTest { private static final String INVALID_PHONE = "9482asf424"; + private static final String VALID_PERSONID = "p123"; private static final String VALID_NAME = "Hans Muster"; private static final String VALID_PHONE = "9482424"; private static final String VALID_EMAIL = "hans@example"; private static final String VALID_ADDRESS = "4th street"; + private static final String VALID_EXISTS = "true"; private static final List VALID_TAGS = Collections.singletonList(new XmlAdaptedTag("friends")); @Rule @@ -80,7 +82,7 @@ public void xmlAdaptedPersonFromFile_fileWithMissingPersonField_validResult() th XmlAdaptedPerson actualPerson = XmlUtil.getDataFromFile( MISSING_PERSON_FIELD_FILE, XmlAdaptedPersonWithRootElement.class); XmlAdaptedPerson expectedPerson = new XmlAdaptedPerson( - null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + VALID_PERSONID, null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); assertEquals(expectedPerson, actualPerson); } @@ -89,7 +91,7 @@ public void xmlAdaptedPersonFromFile_fileWithInvalidPersonField_validResult() th XmlAdaptedPerson actualPerson = XmlUtil.getDataFromFile( INVALID_PERSON_FIELD_FILE, XmlAdaptedPersonWithRootElement.class); XmlAdaptedPerson expectedPerson = new XmlAdaptedPerson( - VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + VALID_PERSONID, VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); assertEquals(expectedPerson, actualPerson); } @@ -98,7 +100,7 @@ public void xmlAdaptedPersonFromFile_fileWithValidPerson_validResult() throws Ex XmlAdaptedPerson actualPerson = XmlUtil.getDataFromFile( VALID_PERSON_FILE, XmlAdaptedPersonWithRootElement.class); XmlAdaptedPerson expectedPerson = new XmlAdaptedPerson( - VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + VALID_PERSONID, VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); assertEquals(expectedPerson, actualPerson); } diff --git a/src/test/java/seedu/address/logic/LogicManagerTest.java b/src/test/java/seedu/address/logic/LogicManagerTest.java index 7c62dcc02259..9502b9cc5343 100644 --- a/src/test/java/seedu/address/logic/LogicManagerTest.java +++ b/src/test/java/seedu/address/logic/LogicManagerTest.java @@ -13,9 +13,7 @@ import seedu.address.logic.commands.ListPersonCommand; import seedu.address.logic.commands.exceptions.CommandException; import seedu.address.logic.parser.exceptions.ParseException; -import seedu.address.model.AddressBookModel; -import seedu.address.model.AddressBookModelManager; -import seedu.address.model.UserPrefs; +import seedu.address.model.*; public class LogicManagerTest { @@ -23,7 +21,8 @@ public class LogicManagerTest { public ExpectedException thrown = ExpectedException.none(); private AddressBookModel addressBookModel = new AddressBookModelManager(); - private Logic logic = new LogicManager(addressBookModel); + private ScheduleModel scheduleModel = new ScheduleModelManager(); + private Logic logic = new LogicManager(addressBookModel, scheduleModel); @Test public void execute_invalidCommandFormat_throwsParseException() { diff --git a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java b/src/test/java/seedu/address/logic/parser/patientBookParserTest.java similarity index 98% rename from src/test/java/seedu/address/logic/parser/AddressBookParserTest.java rename to src/test/java/seedu/address/logic/parser/patientBookParserTest.java index dbb33d433f82..ee43b2a90c54 100644 --- a/src/test/java/seedu/address/logic/parser/AddressBookParserTest.java +++ b/src/test/java/seedu/address/logic/parser/patientBookParserTest.java @@ -24,11 +24,11 @@ import seedu.address.testutil.PersonBuilder; import seedu.address.testutil.PersonUtil; -public class AddressBookParserTest { +public class patientBookParserTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private final AddressBookParser parser = new AddressBookParser(); + private final PatientBookParser parser = new PatientBookParser(); @Test public void parseCommand_add() throws Exception { diff --git a/src/test/java/seedu/address/storage/StorageManagerTest.java b/src/test/java/seedu/address/storage/StorageManagerTest.java index 215ce2bcb0e1..207e8c494405 100644 --- a/src/test/java/seedu/address/storage/StorageManagerTest.java +++ b/src/test/java/seedu/address/storage/StorageManagerTest.java @@ -33,8 +33,9 @@ public class StorageManagerTest { @Before public void setUp() { XmlAddressBookStorage addressBookStorage = new XmlAddressBookStorage(getTempFilePath("ab")); + XmlScheduleStorage scheduleStorage = new XmlScheduleStorage(getTempFilePath("s")); JsonUserPrefsStorage userPrefsStorage = new JsonUserPrefsStorage(getTempFilePath("prefs")); - storageManager = new StorageManager(addressBookStorage, userPrefsStorage); + storageManager = new StorageManager(addressBookStorage, scheduleStorage, userPrefsStorage); } private Path getTempFilePath(String fileName) { @@ -77,7 +78,10 @@ public void getAddressBookFilePath() { @Test public void handleAddressBookChangedEvent_exceptionThrown_eventRaised() { // Create a StorageManager while injecting a stub that throws an exception when the save method is called + // TODO: probably have to add some test for xml schedule storage that does the same as the xml + // addressbook storage Storage storage = new StorageManager(new XmlAddressBookStorageExceptionThrowingStub(Paths.get("dummy")), + new XmlScheduleStorage(Paths.get("dummy")), new JsonUserPrefsStorage(Paths.get("dummy"))); storage.handleAddressBookChangedEvent(new AddressBookChangedEvent(new AddressBook())); assertTrue(eventsCollectorRule.eventsCollector.getMostRecent() instanceof DataSavingExceptionEvent); diff --git a/src/test/java/seedu/address/storage/XmlAdaptedPersonTest.java b/src/test/java/seedu/address/storage/XmlAdaptedPersonTest.java index c3c91a5c27a7..5f0bf9bf6f9a 100644 --- a/src/test/java/seedu/address/storage/XmlAdaptedPersonTest.java +++ b/src/test/java/seedu/address/storage/XmlAdaptedPersonTest.java @@ -18,16 +18,20 @@ import seedu.address.testutil.Assert; public class XmlAdaptedPersonTest { + private static final String INVALID_PERSONID = "1123"; private static final String INVALID_NAME = "R@chel"; private static final String INVALID_PHONE = "+651234"; private static final String INVALID_ADDRESS = " "; private static final String INVALID_EMAIL = "example.com"; + private static final String INVALID_EXISTS = "yes"; private static final String INVALID_TAG = "#friend"; + private static final String VALID_PERSONID = "p123"; private static final String VALID_NAME = BENSON.getName().toString(); private static final String VALID_PHONE = BENSON.getPhone().toString(); private static final String VALID_EMAIL = BENSON.getEmail().toString(); private static final String VALID_ADDRESS = BENSON.getAddress().toString(); + private static final String VALID_EXISTS = "true"; private static final List VALID_TAGS = BENSON.getTags().stream() .map(XmlAdaptedTag::new) .collect(Collectors.toList()); @@ -38,17 +42,25 @@ public void toModelType_validPersonDetails_returnsPerson() throws Exception { assertEquals(BENSON, person.toModelType()); } + @Test + public void toModelType_invalidPersonID_throwsIllegalValueException() { + XmlAdaptedPerson person = + new XmlAdaptedPerson(INVALID_PERSONID, VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); + String expectedMessage = Name.MESSAGE_NAME_CONSTRAINTS; + Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); + } + @Test public void toModelType_invalidName_throwsIllegalValueException() { XmlAdaptedPerson person = - new XmlAdaptedPerson(INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + new XmlAdaptedPerson(VALID_PERSONID, INVALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = Name.MESSAGE_NAME_CONSTRAINTS; Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullName_throwsIllegalValueException() { - XmlAdaptedPerson person = new XmlAdaptedPerson(null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_PERSONID, null, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Name.class.getSimpleName()); Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -56,14 +68,14 @@ public void toModelType_nullName_throwsIllegalValueException() { @Test public void toModelType_invalidPhone_throwsIllegalValueException() { XmlAdaptedPerson person = - new XmlAdaptedPerson(VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, INVALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = Phone.MESSAGE_PHONE_CONSTRAINTS; Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullPhone_throwsIllegalValueException() { - XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, null, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Phone.class.getSimpleName()); Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -71,14 +83,14 @@ public void toModelType_nullPhone_throwsIllegalValueException() { @Test public void toModelType_invalidEmail_throwsIllegalValueException() { XmlAdaptedPerson person = - new XmlAdaptedPerson(VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_TAGS); + new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, VALID_PHONE, INVALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = Email.MESSAGE_EMAIL_CONSTRAINTS; Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullEmail_throwsIllegalValueException() { - XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_TAGS); + XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, VALID_PHONE, null, VALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Email.class.getSimpleName()); Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -86,15 +98,23 @@ public void toModelType_nullEmail_throwsIllegalValueException() { @Test public void toModelType_invalidAddress_throwsIllegalValueException() { XmlAdaptedPerson person = - new XmlAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_TAGS); + new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, VALID_PHONE, VALID_EMAIL, INVALID_ADDRESS, VALID_EXISTS, VALID_TAGS); String expectedMessage = Address.MESSAGE_ADDRESS_CONSTRAINTS; Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @Test public void toModelType_nullAddress_throwsIllegalValueException() { - XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_TAGS); + XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, VALID_PHONE, VALID_EMAIL, null, VALID_EXISTS, VALID_TAGS); + String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()); + Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); + } + + @Test + public void toModelType_nullExists_throwsIllegalValueException() { + XmlAdaptedPerson person = new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, null, VALID_TAGS); String expectedMessage = String.format(MISSING_FIELD_MESSAGE_FORMAT, Address.class.getSimpleName()); + // TODO: Change this, and add the appropriate unit tests for personID and exists Assert.assertThrows(IllegalValueException.class, expectedMessage, person::toModelType); } @@ -103,7 +123,7 @@ public void toModelType_invalidTags_throwsIllegalValueException() { List invalidTags = new ArrayList<>(VALID_TAGS); invalidTags.add(new XmlAdaptedTag(INVALID_TAG)); XmlAdaptedPerson person = - new XmlAdaptedPerson(VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, invalidTags); + new XmlAdaptedPerson(VALID_PERSONID, VALID_NAME, VALID_PHONE, VALID_EMAIL, VALID_ADDRESS, VALID_EXISTS, invalidTags); Assert.assertThrows(IllegalValueException.class, person::toModelType); } diff --git a/src/test/java/seedu/address/ui/CommandBoxTest.java b/src/test/java/seedu/address/ui/CommandBoxTest.java index 5b929ccf9993..1bf079b1bc17 100644 --- a/src/test/java/seedu/address/ui/CommandBoxTest.java +++ b/src/test/java/seedu/address/ui/CommandBoxTest.java @@ -14,6 +14,8 @@ import seedu.address.logic.commands.ListPersonCommand; import seedu.address.model.AddressBookModel; import seedu.address.model.AddressBookModelManager; +import seedu.address.model.ScheduleModel; +import seedu.address.model.ScheduleModelManager; public class CommandBoxTest extends GuiUnitTest { @@ -28,7 +30,8 @@ public class CommandBoxTest extends GuiUnitTest { @Before public void setUp() { AddressBookModel addressBookModel = new AddressBookModelManager(); - Logic logic = new LogicManager(addressBookModel); + ScheduleModel scheduleModel = new ScheduleModelManager(); + Logic logic = new LogicManager(addressBookModel, scheduleModel); CommandBox commandBox = new CommandBox(logic); commandBoxHandle = new CommandBoxHandle(getChildNode(commandBox.getRoot(), diff --git a/src/test/java/seedu/address/ui/MainWindowCloseTest.java b/src/test/java/seedu/address/ui/MainWindowCloseTest.java index 3862e51864a3..3e7374361ef3 100644 --- a/src/test/java/seedu/address/ui/MainWindowCloseTest.java +++ b/src/test/java/seedu/address/ui/MainWindowCloseTest.java @@ -14,6 +14,7 @@ import seedu.address.commons.events.ui.ExitAppRequestEvent; import seedu.address.logic.LogicManager; import seedu.address.model.AddressBookModelManager; +import seedu.address.model.ScheduleModelManager; import seedu.address.model.UserPrefs; import seedu.address.ui.testutil.EventsCollectorRule; @@ -32,7 +33,7 @@ public class MainWindowCloseTest extends GuiUnitTest { public void setUp() throws Exception { FxToolkit.setupStage(stage -> { this.stage = stage; - mainWindow = new MainWindow(stage, new Config(), new UserPrefs(), new LogicManager(new AddressBookModelManager())); + mainWindow = new MainWindow(stage, new Config(), new UserPrefs(), new LogicManager(new AddressBookModelManager(), new ScheduleModelManager())); mainWindowHandle = new EmptyMainWindowHandle(stage); stage.setScene(mainWindow.getRoot().getScene());