diff --git a/build.gradle b/build.gradle index 225bb6c..58a1aea 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ jar { tasks.named('jar') { manifest { - attributes('Implementation-Title': 'reservationsystem', + attributes('Implementation-Title': 'lodge.reservationsystem', 'Implementation-Version': 1.0, 'Main-Class': 'lodge.TestReservations', 'Class-Path': 'lodge.reservationsystem com.google.gson .' ) diff --git a/reservationsystem_0915.png b/reservationsystem_0915.png new file mode 100644 index 0000000..2312798 Binary files /dev/null and b/reservationsystem_0915.png differ diff --git a/src/java/lodge/TestReservations.java b/src/java/lodge/TestReservations.java index 8df2f8c..c58b35b 100644 --- a/src/java/lodge/TestReservations.java +++ b/src/java/lodge/TestReservations.java @@ -8,16 +8,17 @@ package lodge; import java.time.ZoneId; import java.time.ZonedDateTime; +import lodge.data.Account; +import lodge.data.Address; +import lodge.data.DuplicateObjectException; +import lodge.data.EmailAddress; +import lodge.data.Reservation; +import lodge.data.ReservationStatusEnum; import lodge.reservationsystem.AccomodationManager; -import lodge.reservationsystem.Account; -import lodge.reservationsystem.Address; import lodge.reservationsystem.CabinReservation; -import lodge.reservationsystem.DuplicateObjectException; -import lodge.reservationsystem.EmailAddress; import lodge.reservationsystem.HotelReservation; import lodge.reservationsystem.HouseReservation; -import lodge.reservationsystem.Reservation; -import lodge.reservationsystem.ReservationStatusEnum; +import lodge.reservationsystem.IReservation; public final class TestReservations { public static void main(String[] args) throws Exception { @@ -101,27 +102,30 @@ public final class TestReservations { mgr.UpdateAccount(acct); try { - mgr.addReservation(acct, cabin); - mgr.UpdateAccount(mgr.retrieveAccount(acct.getAccount_number())); + if( mgr.addReservation(acct, cabin) ){ + mgr.UpdateAccount(mgr.retrieveAccount(acct.getAccount_number())); + } } catch (DuplicateObjectException e) { System.out.println(e.getMessage()); } - Account account = mgr.retrieveLoadedAccounts().getFirst(); + Account account = mgr.retrieveLoadedAccounts().get(0); - Reservation rsrv = account.findReservation(house.getReservation_number()); // 6. Complete reservation that is associated with an account - mgr.retreiveReservation(house.getReservation_number()); - house.Change(house, ReservationStatusEnum.Completed); + Reservation rsrv = account.findReservation(house.getReservation_number()); + house.Change(rsrv, ReservationStatusEnum.Completed); mgr.UpdateAccount(mgr.retrieveAccount(acct.getAccount_number())); // 7. Cancel reservation that is associated with an account - mgr.retreiveReservation(house.getReservation_number()); - house.Change(house, ReservationStatusEnum.Canceled); - mgr.UpdateAccount(mgr.retrieveAccount(acct.getAccount_number())); + account = mgr.retrieveLoadedAccounts().getLast(); + IReservation ir = account.getAllReservations().next(); + rsrv = (Reservation)ir; + rsrv.Change(rsrv, ReservationStatusEnum.Canceled); + mgr.UpdateAccount(mgr.retrieveAccount(rsrv.getAccountNumber())); // 8. Change reservation values that can be changed (if reservation is // cancelled, completed, or for past date, it is considered an error) + rsrv.Change(rsrv, ReservationStatusEnum.Completed); house.update(house); // 9. Request for price per night to be calculated and returned for a diff --git a/src/java/lodge/reservationsystem/Account.java b/src/java/lodge/data/Account.java similarity index 89% rename from src/java/lodge/reservationsystem/Account.java rename to src/java/lodge/data/Account.java index cce1483..6cbbbd6 100644 --- a/src/java/lodge/reservationsystem/Account.java +++ b/src/java/lodge/data/Account.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; import java.io.BufferedWriter; import java.io.IOException; @@ -12,11 +12,14 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ListIterator; +import lodge.reservationsystem.IReservation; + public class Account { private String account_number = "-99"; private String phone_number; private Address mailing_address; private EmailAddress email_address; + private final AccountReservationList reservations = new AccountReservationList(); protected Account() { @@ -40,8 +43,6 @@ public class Account { email_address); } - private final AccountReservationList reservation_list = new AccountReservationList();; - @Override public String toString() { @@ -51,7 +52,7 @@ public class Account { sb.append("\"phone_number\": \"").append(phone_number).append("\","); sb.append("\"mailing_address\": ").append(mailing_address).append(","); sb.append("\"email_address\": ").append(email_address).append(","); - sb.append(this.reservation_list.toString()); + sb.append(this.reservations.toString()); sb.append("}}"); return sb.toString(); } @@ -62,7 +63,7 @@ public class Account { return false; } try { - result = reservation_list.add(rsrv); + result = reservations.add((IReservation) rsrv); } catch (DuplicateObjectException e) { System.out.println(String.format("%s", e.getMessage())); } finally { @@ -84,7 +85,8 @@ public class Account { writer.flush(); } - for (Reservation r : acct.reservation_list) { + for (IReservation i : acct.reservations) { + Reservation r = (Reservation) i; r.Write(r); } } @@ -130,7 +132,7 @@ public class Account { } public Reservation findReservation(String reservation_number) { - return this.reservation_list.find(reservation_number); + return this.reservations.find(reservation_number); } @Override @@ -156,8 +158,8 @@ public class Account { this.setMailing_address(acct.mailing_address); } - public ListIterator getAllReservations() { - return this.reservation_list.listIterator(); + public ListIterator getAllReservations() { + return this.reservations.listIterator(); } } \ No newline at end of file diff --git a/src/java/lodge/reservationsystem/AccountList.java b/src/java/lodge/data/AccountList.java similarity index 84% rename from src/java/lodge/reservationsystem/AccountList.java rename to src/java/lodge/data/AccountList.java index 9f10c83..2a49606 100644 --- a/src/java/lodge/reservationsystem/AccountList.java +++ b/src/java/lodge/data/AccountList.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; import java.io.IOException; import java.util.ArrayList; @@ -10,7 +10,9 @@ import java.util.Collections; import java.util.List; import java.util.ListIterator; -class AccountList extends ArrayList { +import lodge.reservationsystem.IReservation; + +public class AccountList extends ArrayList { public static String accountSerial(String phone_number, Address mailing_address, EmailAddress email_address) { return String.format("A%09d", Math.abs(java.util.Objects.hash(phone_number, mailing_address, email_address))); @@ -51,10 +53,10 @@ class AccountList extends ArrayList { return null; } - public List getListOfReservations() { - ArrayList readList = new ArrayList<>(); + public List getListOfReservations() { + ArrayList readList = new ArrayList<>(); for (Account acct: this){ - ListIterator itr = acct.getAllReservations(); + ListIterator itr = acct.getAllReservations(); while( itr.hasNext() ){ readList.add(itr.next()); } diff --git a/src/java/lodge/reservationsystem/AccountReservationList.java b/src/java/lodge/data/AccountReservationList.java similarity index 69% rename from src/java/lodge/reservationsystem/AccountReservationList.java rename to src/java/lodge/data/AccountReservationList.java index 5370bd0..2318718 100644 --- a/src/java/lodge/reservationsystem/AccountReservationList.java +++ b/src/java/lodge/data/AccountReservationList.java @@ -2,32 +2,34 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; import java.util.ArrayList; -class AccountReservationList extends ArrayList { +import lodge.reservationsystem.IReservation; + +class AccountReservationList extends ArrayList { private static String reservationSerial(Reservation reservation) { return String.format("R%010d", Math.abs(java.util.Objects.hash(reservation.getPhysical_address()))); } @Override - public synchronized boolean add(final Reservation reservation) throws RuntimeException{ + public synchronized boolean add(final IReservation reservation) throws RuntimeException{ boolean result = true; Reservation rsrv = this.find(reservation.getReservation_number()); result = rsrv == null; if( !result ){ throw new DuplicateObjectException(String.format("Error No Dups, Reservation exists: %s.", rsrv.getReservation_number())); } - result = reservation.checkValid(); + result = ((IReservation)reservation).checkValid(); if(result){ - reservation.setReservation_number(AccountReservationList.reservationSerial(reservation)); - reservation.setPrice(reservation.calculatePrice()); + ((Reservation)reservation).setReservation_number(AccountReservationList.reservationSerial((Reservation)reservation)); + ((Reservation)reservation).setPrice(reservation.calculatePrice()); result = super.add(reservation); }else{ - throw new IllegalArgumentException(String.format("error reservation invalid: %s", reservation.getReservation_number())); + throw new IllegalArgumentException(String.format("error reservation invalid: %s", ((Reservation)reservation).getReservation_number())); } return result; } @@ -35,7 +37,7 @@ class AccountReservationList extends ArrayList { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("\"reservation_list\":["); + sb.append("\"reservations\":["); for (int ix = 0; ix < this.size(); ix++) { String name = this.get(ix).ReservationType() + ""; @@ -53,19 +55,19 @@ class AccountReservationList extends ArrayList { } public Reservation find(String reservation_number) { - for(Reservation rsrv: this){ + for(IReservation rsrv: this){ if( rsrv.getReservation_number().compareTo(reservation_number) == 0 ){ - return rsrv; + return (Reservation)rsrv; } } return null; } public void update(AccountReservationList incoming_reservation_list) { - for (Reservation rsrv : incoming_reservation_list) { + for (IReservation rsrv : incoming_reservation_list) { Reservation onListRsrv = find(rsrv.getReservation_number()); if( onListRsrv != null ){ - onListRsrv.update(rsrv); + onListRsrv.update((Reservation)rsrv); } } } diff --git a/src/java/lodge/reservationsystem/Address.java b/src/java/lodge/data/Address.java similarity index 98% rename from src/java/lodge/reservationsystem/Address.java rename to src/java/lodge/data/Address.java index f4aa9a8..d889876 100644 --- a/src/java/lodge/reservationsystem/Address.java +++ b/src/java/lodge/data/Address.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; public final class Address{ diff --git a/src/java/lodge/reservationsystem/DataRepository.java b/src/java/lodge/data/DataRepository.java similarity index 91% rename from src/java/lodge/reservationsystem/DataRepository.java rename to src/java/lodge/data/DataRepository.java index bc40993..778cd49 100644 --- a/src/java/lodge/reservationsystem/DataRepository.java +++ b/src/java/lodge/data/DataRepository.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; import java.io.BufferedReader; import java.io.FileReader; @@ -18,7 +18,12 @@ import java.time.ZonedDateTime; import com.google.gson.stream.JsonReader; -final class DataRepository { +import lodge.reservationsystem.AccomodationManager; +import lodge.reservationsystem.CabinReservation; +import lodge.reservationsystem.HotelReservation; +import lodge.reservationsystem.HouseReservation; + +public final class DataRepository { // SINGLETON CLASS // hard code data store location for storage of // account data files on filesystem @@ -37,6 +42,18 @@ final class DataRepository { return getInstance().directoryPath; } + public final static Reservation Reservation(String type) { + switch (type) { + case "HotelReservation": + return HotelReservation.copy(type); + case "HouseReservation": + return HouseReservation.copy(type); + case "CabinReservation": + return CabinReservation.copy(type); + } + return null; + } + public static void WalkFileSystemTree(final AccomodationManager manager, final Path rootDir) throws IOException { Files.walkFileTree(rootDir, new SimpleFileVisitor() { @Override @@ -116,7 +133,7 @@ final class DataRepository { jsonReader.endObject(); jsonReader.endObject(); break; - case "reservation_list": + case "reservations": loadReservationRefList(jsonReader, ac); break; default: @@ -159,15 +176,15 @@ final class DataRepository { switch (name) { case "HotelReservation": jsonReader.beginObject(); - rsrv = new HotelReservation(); + rsrv = Reservation("HotelReservation"); break; case "HouseReservation": jsonReader.beginObject(); - rsrv = new HouseReservation(); + rsrv = Reservation("HouseReservation"); break; case "CabinReservation": jsonReader.beginObject(); - rsrv = new CabinReservation(); + rsrv = Reservation("CabinReservation"); break; case "physical_address": jsonReader.beginObject(); @@ -180,7 +197,7 @@ final class DataRepository { jsonReader.nextName(); String state = jsonReader.nextString(); jsonReader.nextName(); - String zip =jsonReader.nextString(); + String zip = jsonReader.nextString(); jsonReader.endObject(); jsonReader.endObject(); rsrv.setPhysical_address(new Address(street, city, state, zip)); @@ -196,7 +213,7 @@ final class DataRepository { jsonReader.nextName(); String mstate = jsonReader.nextString(); jsonReader.nextName(); - String mzip =jsonReader.nextString(); + String mzip = jsonReader.nextString(); jsonReader.endObject(); jsonReader.endObject(); rsrv.setMailing_address(new Address(mstreet, mcity, mstate, mzip)); diff --git a/src/java/lodge/reservationsystem/DuplicateObjectException.java b/src/java/lodge/data/DuplicateObjectException.java similarity index 89% rename from src/java/lodge/reservationsystem/DuplicateObjectException.java rename to src/java/lodge/data/DuplicateObjectException.java index 2f28f66..d0bccd1 100644 --- a/src/java/lodge/reservationsystem/DuplicateObjectException.java +++ b/src/java/lodge/data/DuplicateObjectException.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; public class DuplicateObjectException extends RuntimeException { public DuplicateObjectException() { diff --git a/src/java/lodge/reservationsystem/EmailAddress.java b/src/java/lodge/data/EmailAddress.java similarity index 97% rename from src/java/lodge/reservationsystem/EmailAddress.java rename to src/java/lodge/data/EmailAddress.java index 773cd21..d7acfe0 100644 --- a/src/java/lodge/reservationsystem/EmailAddress.java +++ b/src/java/lodge/data/EmailAddress.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; public class EmailAddress{ String email_address; diff --git a/src/java/lodge/reservationsystem/KitchenTypeEnum.java b/src/java/lodge/data/KitchenTypeEnum.java similarity index 78% rename from src/java/lodge/reservationsystem/KitchenTypeEnum.java rename to src/java/lodge/data/KitchenTypeEnum.java index c94bb5c..9ea8866 100644 --- a/src/java/lodge/reservationsystem/KitchenTypeEnum.java +++ b/src/java/lodge/data/KitchenTypeEnum.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; public enum KitchenTypeEnum { None, Kitchenette, FullKitchen; diff --git a/src/java/lodge/reservationsystem/Reservation.java b/src/java/lodge/data/Reservation.java similarity index 90% rename from src/java/lodge/reservationsystem/Reservation.java rename to src/java/lodge/data/Reservation.java index 32d7ce5..a081cdf 100644 --- a/src/java/lodge/reservationsystem/Reservation.java +++ b/src/java/lodge/data/Reservation.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; import java.io.BufferedWriter; import java.io.IOException; @@ -12,7 +12,10 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.ZonedDateTime; -public abstract class Reservation{ +import lodge.reservationsystem.IReservation; +import lodge.reservationsystem.IllegalOperationException; + +public abstract class Reservation { private char type; private String reservation_number = "-99"; private Address physical_address; @@ -58,7 +61,7 @@ public abstract class Reservation{ return this.accountNumber; } - protected void setAccountNumber(String account_number) { + public void setAccountNumber(String account_number) { this.accountNumber = account_number; } @@ -126,7 +129,7 @@ public abstract class Reservation{ return type; } - protected void setType(char type) { + public void setType(char type) { this.type = type; } @@ -202,8 +205,7 @@ public abstract class Reservation{ @Override public String toString() { StringBuilder sb = new StringBuilder(); - - sb.append(String.format("{ \"%s\":{", ReservationType())); + sb.append(String.format("{ \"%s\":{", this.ReservationType())); sb.append("\"reservation_type\": \"").append(ReservationType()).append("\","); sb.append("\"reservation_number\": \"").append(reservation_number).append("\","); sb.append("\"reservation_status\": \"").append(reservation_status).append("\","); @@ -237,17 +239,20 @@ public abstract class Reservation{ public void Change(Reservation reservation, ReservationStatusEnum newStatus) throws IllegalOperationException { try { - if (reservation.reservation_status == ReservationStatusEnum.Completed) { + if (reservation.reservation_status == ReservationStatusEnum.Completed || + reservation.reservation_status == ReservationStatusEnum.Canceled) { if (newStatus == ReservationStatusEnum.Canceled) { - throw new IllegalOperationException("Invalid Change, reservation has completed."); + throw new IllegalOperationException( + String.format("Invalid Change, reservation has %s.", reservation.getReservation_status())); } if (ZonedDateTime.now().compareTo(this.reservation_start_date) > -1) { - throw new IllegalOperationException("Invalid Change, reservation time started."); + throw new IllegalOperationException("Invalid Change, reservation has begun."); } } if (newStatus == ReservationStatusEnum.Completed) { - this.setPrice(this.calculatePrice()); + IReservation irsrv = (IReservation) this; + this.setPrice(irsrv.calculatePrice()); } reservation.setReservation_status(newStatus); } catch (IllegalOperationException e) { @@ -260,7 +265,4 @@ public abstract class Reservation{ } public abstract String ReservationType(); - public abstract float getPricePerNight(); - public abstract float calculatePrice(); - public abstract boolean checkValid(); } diff --git a/src/java/lodge/reservationsystem/ReservationStatusEnum.java b/src/java/lodge/data/ReservationStatusEnum.java similarity index 79% rename from src/java/lodge/reservationsystem/ReservationStatusEnum.java rename to src/java/lodge/data/ReservationStatusEnum.java index 079435c..5c8b875 100644 --- a/src/java/lodge/reservationsystem/ReservationStatusEnum.java +++ b/src/java/lodge/data/ReservationStatusEnum.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservationsystem; +package lodge.data; public enum ReservationStatusEnum { Draft, diff --git a/src/java/lodge/reservationsystem/AccomodationManager.java b/src/java/lodge/reservationsystem/AccomodationManager.java index 37b2de5..b60dfe8 100644 --- a/src/java/lodge/reservationsystem/AccomodationManager.java +++ b/src/java/lodge/reservationsystem/AccomodationManager.java @@ -6,12 +6,20 @@ package lodge.reservationsystem; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import lodge.data.Account; +import lodge.data.AccountList; +import lodge.data.Address; +import lodge.data.DataRepository; +import lodge.data.EmailAddress; +import lodge.data.Reservation; + public final class AccomodationManager { - private final AccountList account_list = new AccountList(); + private final AccountList accounts = new AccountList(); @SuppressWarnings("unused") private AccomodationManager() { @@ -27,39 +35,39 @@ public final class AccomodationManager { } public final void loadAll() throws Exception { - account_list.clear(); + accounts.clear(); // walk directories Path rootDir = Paths.get(DataRepository.getPath()); DataRepository.WalkFileSystemTree(this, rootDir); - System.out.println(String.format("%s LoadAll Accounts %d", "Deserializing", account_list.size())); + System.out.println(String.format("%s LoadAll Accounts %d", "Deserializing", accounts.size())); } // Load / Deserialize Account - void load(Path file) throws Exception { + public void load(Path file) throws Exception { Account account = DataRepository.LoadAccount(file); if (account == null) { System.out.println(String.format("%s", file.toString())); } else { - account_list.add(account); + accounts.add(account); } } public final List retrieveLoadedAccounts() { - return Collections.unmodifiableList(account_list); + return Collections.unmodifiableList(accounts); } public Account retrieveAccount(String acct_id) { - return account_list.find(acct_id); + return accounts.find(acct_id); } public synchronized void AddAccount(final Account acct) throws Exception { - account_list.add(acct); + accounts.add(acct); } public synchronized void UpdateAccount(final Account acct) throws Exception { if( acct != null ){ - account_list.save(acct); + accounts.save(acct); } } @@ -71,7 +79,7 @@ public final class AccomodationManager { } catch (Exception e) { System.out.println(e.toString()); } - account_list.save(acct); + accounts.save(acct); return acct; } @@ -80,22 +88,22 @@ public final class AccomodationManager { return result; } - public final Reservation retreiveReservation(String reservation_number) { + public final Reservation findReservation(String reservation_number) { Reservation rsrv = null; - for (Account acct : account_list) { + for (Account acct : accounts) { rsrv = acct.findReservation(reservation_number); if( rsrv!=null ) break; } return rsrv; } - public List getReservationList() { - return account_list.getListOfReservations(); + public List getReservationList() { + return accounts.getListOfReservations(); } public void showReservationList() { - for (Reservation rsrv : this.getReservationList()) { - System.out.println(String.format("Account %s:, %s", rsrv.getAccountNumber(), rsrv.getReservation_number())); + for (IReservation irsrv : this.getReservationList()) { + System.out.println(String.format("Account %s: %s, %s", irsrv.getAccountNumber(), irsrv.getReservation_number(), irsrv.getPhysical_address().getStreet())); } } diff --git a/src/java/lodge/reservationsystem/CabinReservation.java b/src/java/lodge/reservationsystem/CabinReservation.java index edb4766..8989b06 100644 --- a/src/java/lodge/reservationsystem/CabinReservation.java +++ b/src/java/lodge/reservationsystem/CabinReservation.java @@ -7,13 +7,21 @@ package lodge.reservationsystem; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -public final class CabinReservation extends Reservation { +import lodge.data.Address; +import lodge.data.KitchenTypeEnum; +import lodge.data.Reservation; - protected CabinReservation() { - setType('C'); +public final class CabinReservation extends Reservation implements IReservation { + + public CabinReservation() { + this.setType('C'); this.setNumberOfBeds(1); this.setKitchen(KitchenTypeEnum.Kitchenette); } + + public static Reservation copy(String reservationType) { + return new CabinReservation(); + } public CabinReservation(final Address physical_address) { this(); @@ -22,8 +30,7 @@ public final class CabinReservation extends Reservation { physical_address.getZip())); } - @Override - public final String ReservationType() { + public String ReservationType() { return "CabinReservation"; } diff --git a/src/java/lodge/reservationsystem/HotelReservation.java b/src/java/lodge/reservationsystem/HotelReservation.java index 88ff36a..6bb0015 100644 --- a/src/java/lodge/reservationsystem/HotelReservation.java +++ b/src/java/lodge/reservationsystem/HotelReservation.java @@ -8,9 +8,13 @@ import java.time.LocalTime; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -public final class HotelReservation extends Reservation { +import lodge.data.Address; +import lodge.data.KitchenTypeEnum; +import lodge.data.Reservation; - protected HotelReservation() { +public final class HotelReservation extends Reservation implements IReservation{ + + public HotelReservation() { this.setType('H'); this.setNumberOfBeds(2); this.setNumberOfBeds(2); @@ -19,6 +23,10 @@ public final class HotelReservation extends Reservation { this.setNumberOfFloors(1); this.setKitchen(KitchenTypeEnum.Kitchenette); } + + public static Reservation copy(String reservationType) { + return new HotelReservation(); + } public HotelReservation(final Address physical_address) { this(); diff --git a/src/java/lodge/reservationsystem/HouseReservation.java b/src/java/lodge/reservationsystem/HouseReservation.java index 698bb20..485e931 100644 --- a/src/java/lodge/reservationsystem/HouseReservation.java +++ b/src/java/lodge/reservationsystem/HouseReservation.java @@ -7,9 +7,13 @@ package lodge.reservationsystem; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -public final class HouseReservation extends Reservation { +import lodge.data.Address; +import lodge.data.KitchenTypeEnum; +import lodge.data.Reservation; - protected HouseReservation() { +public final class HouseReservation extends Reservation implements IReservation { + + public HouseReservation() { this.setType('Z'); this.setNumberOfBeds(2); this.setNumberOfBedRooms(1); @@ -18,6 +22,10 @@ public final class HouseReservation extends Reservation { this.setKitchen(KitchenTypeEnum.Kitchenette); } + public static Reservation copy(String reservationType) { + return new HouseReservation(); + } + public HouseReservation(final Address physical_address) { this(); this.setPhysical_address( diff --git a/src/java/lodge/reservationsystem/IReservation.java b/src/java/lodge/reservationsystem/IReservation.java new file mode 100644 index 0000000..5a37c97 --- /dev/null +++ b/src/java/lodge/reservationsystem/IReservation.java @@ -0,0 +1,16 @@ +package lodge.reservationsystem; + +import lodge.data.Address; +import lodge.data.Reservation; + +public interface IReservation { + + public abstract String ReservationType(); + public static Reservation copy(String type){ return null; }; + public String getReservation_number(); + public String getAccountNumber(); + public Address getPhysical_address(); + public float getPricePerNight(); + public float calculatePrice(); + public boolean checkValid(); +} \ No newline at end of file diff --git a/src/java/lodge/reservationsystem/IllegalOperationException.java b/src/java/lodge/reservationsystem/IllegalOperationException.java index cff2085..2905001 100644 --- a/src/java/lodge/reservationsystem/IllegalOperationException.java +++ b/src/java/lodge/reservationsystem/IllegalOperationException.java @@ -4,7 +4,7 @@ */ package lodge.reservationsystem; -class IllegalOperationException extends RuntimeException { +public class IllegalOperationException extends RuntimeException { public IllegalOperationException () { super(); } diff --git a/src/resources/acc-A1450981765.json b/src/resources/acc-A1450981765.json index aa6c3e3..84ff47e 100644 --- a/src/resources/acc-A1450981765.json +++ b/src/resources/acc-A1450981765.json @@ -1 +1 @@ -{ "Account":{"account_number": "A1450981765","phone_number": "701-456-7890","mailing_address": { "Address":{"street": "10 wilco ave","city": "wilco","state": "WY","zip": "82801"}},"email_address": { "EmailAddress":{"email": "wilco@wyommin.net"}},"reservation_list":[{"HotelReservation":{"reservation_number":"R0123077641"}},{"CabinReservation":{"reservation_number":"R0535276622"}},{"HouseReservation":{"reservation_number":"R0499811708"}}]}} \ No newline at end of file +{ "Account":{"account_number": "A1450981765","phone_number": "701-456-7890","mailing_address": { "Address":{"street": "10 wilco ave","city": "wilco","state": "WY","zip": "82801"}},"email_address": { "EmailAddress":{"email": "wilco@wyommin.net"}},"reservations":[{"HotelReservation":{"reservation_number":"R0123077641"}},{"CabinReservation":{"reservation_number":"R0535276622"}},{"HouseReservation":{"reservation_number":"R0499811708"}}]}} \ No newline at end of file diff --git a/src/resources/acc-A2074212339.json b/src/resources/acc-A2074212339.json index c5165f1..88c61cd 100644 --- a/src/resources/acc-A2074212339.json +++ b/src/resources/acc-A2074212339.json @@ -1,26 +1 @@ -{ - "Account": { - "account_number": "A2074212339", - "phone_number": "301-356-3890", - "mailing_address": { - "Address": { - "street": "30 Amstadam ave", - "city": "New York", - "state": "NY", - "zip": "12010" - } - }, - "email_address": { - "EmailAddress": { - "email": "newbee952@aol.com" - } - }, - "reservation_list": [ - { - "CabinReservation": { - "reservation_number": "R2042828431" - } - } - ] - } -} \ No newline at end of file +{ "Account":{"account_number": "A2074212339","phone_number": "301-356-3890","mailing_address": { "Address":{"street": "30 Amstadam ave","city": "New York","state": "NY","zip": "12010"}},"email_address": { "EmailAddress":{"email": "newbee952@aol.com"}},"reservations":[{"CabinReservation":{"reservation_number":"R2042828431"}}]}} \ No newline at end of file diff --git a/src/resources/rsv-R0499811708.json b/src/resources/rsv-R0499811708.json index 050c33f..fdb62ed 100644 --- a/src/resources/rsv-R0499811708.json +++ b/src/resources/rsv-R0499811708.json @@ -1,33 +1 @@ -{ - "HouseReservation": { - "reservation_type": "HouseReservation", - "reservation_number": "R0499811708", - "reservation_status": "Completed", - "reservation_start_date": "2025-11-05T10:00Z[UTC]", - "reservation_end_date": "2025-11-15T22:00Z[UTC]", - "account_number": "A1450981765", - "physical_address": { - "Address": { - "street": "3000 Osage ave", - "city": "GreenBelt", - "state": "MD", - "zip": "20740" - } - }, - "mailing_address": { - "Address": { - "street": "40012 College ave", - "city": "College Park", - "state": "MD", - "zip": "20740" - } - }, - "kitchen": "Kitchenette", - "numberOfBeds": "4", - "numberOfBedRooms": "3", - "numberOfBathRooms": "1", - "numberOfFloors": "3", - "squareFeet": "1400", - "price": "1215.0" - } -} \ No newline at end of file +{ "HouseReservation":{"reservation_type": "HouseReservation","reservation_number": "R0499811708","reservation_status": "Completed","reservation_start_date": "2025-11-05T10:00Z[UTC]","reservation_end_date": "2025-11-15T22:00Z[UTC]","account_number": "A1450981765","physical_address": { "Address":{"street": "3000 Osage ave","city": "GreenBelt","state": "MD","zip": "20740"}},"mailing_address": { "Address":{"street": "40012 College ave","city": "College Park","state": "MD","zip": "20740"}},"kitchen": "Kitchenette","numberOfBeds": "4","numberOfBedRooms": "3","numberOfBathRooms": "1","numberOfFloors": "3","squareFeet": "1400","price": "1215.0"}} \ No newline at end of file diff --git a/src/resources/rsv-R2042828431.json b/src/resources/rsv-R2042828431.json index b036838..5c10356 100644 --- a/src/resources/rsv-R2042828431.json +++ b/src/resources/rsv-R2042828431.json @@ -1 +1 @@ -{ "CabinReservation":{"reservation_type": "CabinReservation","reservation_number": "R2042828431","reservation_status": "Draft","reservation_start_date": "2025-09-05T10:00Z[UTC]","reservation_end_date": "2025-11-30T22:00Z[UTC]","account_number": "A2074212339","physical_address": { "Address":{"street": "30 cabin ave","city": "Carnelian","state": "CA","zip": "96140"}},"mailing_address": { "Address":{"street": "30 cabin ave","city": "Carnelian Bay","state": "CA","zip": "96140"}},"kitchen": "Kitchenette","numberOfBeds": "4","numberOfBedRooms": "3","numberOfBathRooms": "1","numberOfFloors": "2","squareFeet": "806","price": "10200.0"}} \ No newline at end of file +{ "CabinReservation":{"reservation_type": "CabinReservation","reservation_number": "R2042828431","reservation_status": "Canceled","reservation_start_date": "2025-09-05T10:00Z[UTC]","reservation_end_date": "2025-11-30T22:00Z[UTC]","account_number": "A2074212339","physical_address": { "Address":{"street": "30 cabin ave","city": "Carnelian","state": "CA","zip": "96140"}},"mailing_address": { "Address":{"street": "30 cabin ave","city": "Carnelian Bay","state": "CA","zip": "96140"}},"kitchen": "Kitchenette","numberOfBeds": "4","numberOfBedRooms": "3","numberOfBathRooms": "1","numberOfFloors": "2","squareFeet": "806","price": "10200.0"}} \ No newline at end of file diff --git a/uml/classdiagram.dot b/uml/classdiagram.dot new file mode 100644 index 0000000..19d7e69 --- /dev/null +++ b/uml/classdiagram.dot @@ -0,0 +1,101 @@ +digraph LodgeReservationSystem { + // Graph settings + rankdir=TB; + node [shape=record, fontname="Arial", fontsize=10]; + edge [fontname="Arial", fontsize=8]; + + // Define clusters for packages + subgraph cluster_data { + label="lodge.data"; + style=filled; + color=lightgrey; + + // Data classes + Account [label="{Account|+ account_number: String\l+ phone_number: String\l+ mailing_address: Address\l+ email_address: EmailAddress\l- reservation_list: AccountReservationList\l|+ add(Reservation): boolean\l+ findReservation(String): Reservation\l+ getAllReservations(): ListIterator\\l+ update(Account): void\l+ Write(Account): void\l}"]; + + AccountList [label="{AccountList|extends ArrayList\|+ accountSerial(...): String\l+ add(Account): boolean\l+ find(String): Account\l+ save(Account): void\l+ getListOfReservations(): List\\l}"]; + + AccountReservationList [label="{AccountReservationList|extends ArrayList\|- reservationSerial(Reservation): String\l+ add(IReservation): boolean\l+ find(String): Reservation\l+ update(AccountReservationList): void\l}"]; + + Address [label="{Address|+ street: String\l+ city: String\l+ state: String\l+ zip: String\l|+ getters/setters\l+ hashCode(): int\l+ equals(Object): boolean\l}"]; + + EmailAddress [label="{EmailAddress|+ email_address: String\l|+ getters/setters\l+ hashCode(): int\l+ equals(Object): boolean\l}"]; + + Reservation [label="{Reservation|\<\\>|# type: char\l- reservation_number: String\l- physical_address: Address\l- mailing_address: Address\l- reservation_start_date: ZonedDateTime\l- reservation_end_date: ZonedDateTime\l- reservation_status: ReservationStatusEnum\l- kitchen: KitchenTypeEnum\l- numberOfBeds: Integer\l- numberOfBedRooms: Integer\l- numberOfBathRooms: Integer\l- numberOfFloors: Integer\l- squareFeet: Integer\l- price: Float\l# accountNumber: String\l|+ getters/setters\l+ Write(Reservation): void\l+ Change(Reservation, ReservationStatusEnum): void\l+ update(Reservation): void\l+ \<\\> ReservationType(): String\l}"]; + + DataRepository [label="{DataRepository|\<\\>|- directoryPath: String\l- instance: DataRepository\l|+ setDataStoreRoot(String): void\l+ getPath(): String\l+ Reservation(String): Reservation\l+ WalkFileSystemTree(...): void\l+ LoadAccount(Path): Account\l- loadReservation(...): void\l}"]; + + DuplicateObjectException [label="{DuplicateObjectException|extends RuntimeException||+ DuplicateObjectException()\l+ DuplicateObjectException(String)\l}"]; + + // Enums + KitchenTypeEnum [label="{KitchenTypeEnum|\<\\>|None\lKitchenette\lFullKitchen\l}"]; + + ReservationStatusEnum [label="{ReservationStatusEnum|\<\\>|Draft\lCanceled\lCompleted\l}"]; + } + + subgraph cluster_reservationsystem { + label="lodge.reservationsystem"; + style=filled; + color=lightblue; + + AccomodationManager [label="{AccomodationManager|- accounts: AccountList\l|+ AccomodationManager(String)\l+ loadAll(): void\l+ load(Path): void\l+ retrieveLoadedAccounts(): List\\l+ retrieveAccount(String): Account\l+ AddAccount(Account): void\l+ UpdateAccount(Account): void\l+ newAccount(...): Account\l+ addReservation(...): boolean\l+ findReservation(String): Reservation\l+ getReservationList(): List\\l+ showReservationList(): void\l}"]; + + IReservation [label="{IReservation|\<\\>||+ ReservationType(): String\l+ getReservation_number(): String\l+ getAccountNumber(): String\l+ getPhysical_address(): Address\l+ getPricePerNight(): float\l+ calculatePrice(): float\l+ checkValid(): boolean\l}"]; + + HotelReservation [label="{HotelReservation|extends Reservation\limplements IReservation|# type: 'H'\l|+ HotelReservation(Address)\l+ ReservationType(): String\l+ checkValid(): boolean\l+ getPricePerNight(): float\l+ calculatePrice(): float\l+ Reservation(String): Reservation\l}"]; + + CabinReservation [label="{CabinReservation|extends Reservation\limplements IReservation|# type: 'C'\l|+ CabinReservation(Address)\l+ ReservationType(): String\l+ checkValid(): boolean\l+ getPricePerNight(): float\l+ calculatePrice(): float\l+ Reservation(String): Reservation\l}"]; + + HouseReservation [label="{HouseReservation|extends Reservation\limplements IReservation|# type: 'Z'\l|+ HouseReservation(Address)\l+ ReservationType(): String\l+ checkValid(): boolean\l+ getPricePerNight(): float\l+ calculatePrice(): float\l+ Reservation(String): Reservation\l}"]; + + IllegalOperationException [label="{IllegalOperationException|extends RuntimeException||+ IllegalOperationException()\l+ IllegalOperationException(String)\l}"]; + } + + subgraph cluster_main { + label="lodge"; + style=filled; + color=lightyellow; + + TestReservations [label="{TestReservations||+ main(String[]): void\l}"]; + } + + // Relationships + + // Inheritance relationships + AccountList -> Account [arrowhead=diamond, label="contains"]; + AccountReservationList -> IReservation [arrowhead=diamond, label="contains"]; + + HotelReservation -> Reservation [arrowhead=empty]; + CabinReservation -> Reservation [arrowhead=empty]; + HouseReservation -> Reservation [arrowhead=empty]; + + HotelReservation -> IReservation [arrowhead=empty, style=dashed]; + CabinReservation -> IReservation [arrowhead=empty, style=dashed]; + HouseReservation -> IReservation [arrowhead=empty, style=dashed]; + + // Composition/Aggregation relationships + Account -> Address [arrowhead=diamond, label="mailing_address"]; + Account -> EmailAddress [arrowhead=diamond, label="email_address"]; + Account -> AccountReservationList [arrowhead=diamond, label="reservation_list"]; + + Reservation -> Address [arrowhead=diamond, label="physical_address\nmailing_address"]; + Reservation -> KitchenTypeEnum [arrowhead=open, label="kitchen"]; + Reservation -> ReservationStatusEnum [arrowhead=open, label="reservation_status"]; + + AccomodationManager -> AccountList [arrowhead=diamond, label="accounts"]; + AccomodationManager -> DataRepository [arrowhead=open, label="uses"]; + + // Usage relationships + TestReservations -> AccomodationManager [arrowhead=open, label="uses"]; + TestReservations -> HotelReservation [arrowhead=open, label="creates"]; + TestReservations -> CabinReservation [arrowhead=open, label="creates"]; + TestReservations -> HouseReservation [arrowhead=open, label="creates"]; + + DataRepository -> Account [arrowhead=open, label="loads"]; + DataRepository -> Reservation [arrowhead=open, label="creates"]; + + // Exception relationships + AccountList -> DuplicateObjectException [arrowhead=open, style=dashed, label="throws"]; + AccountReservationList -> DuplicateObjectException [arrowhead=open, style=dashed, label="throws"]; + Reservation -> IllegalOperationException [arrowhead=open, style=dashed, label="throws"]; +} \ No newline at end of file diff --git a/uml/classdiagram.svg b/uml/classdiagram.svg new file mode 100644 index 0000000..77d99eb --- /dev/null +++ b/uml/classdiagram.svg @@ -0,0 +1,465 @@ + + + + + + + + +lodge.data + + + + +lodge.reservationsystem + + + + +lodge + + + + + +Account + ++ account_number: String ++ phone_number: String ++ mailing_address: Address ++ email_address: EmailAddress +- reservation_list: AccountReservationList + ++ add(Reservation): boolean ++ findReservation(String): Reservation ++ getAllReservations(): ListIterator<IReservation> ++ update(Account): void ++ Write(Account): void + + + + + +reservation_list + + + + +AccountReservationList + +extends ArrayList<IReservation> + +- reservationSerial(Reservation): String ++ add(IReservation): boolean ++ find(String): Reservation ++ update(AccountReservationList): void + + + + + + + +mailing_address + + + + +Address + ++ street: String ++ city: String ++ state: String ++ zip: String + ++ getters/setters ++ hashCode(): int ++ equals(Object): boolean + + + + + + + +email_address + + + + +EmailAddress + ++ email_address: String + ++ getters/setters ++ hashCode(): int ++ equals(Object): boolean + + + + + + + +contains + + + + +AccountList + +extends ArrayList<Account> + ++ accountSerial(...): String ++ add(Account): boolean ++ find(String): Account ++ save(Account): void ++ getListOfReservations(): List<IReservation> + + + + + + + +throws + + + + +DuplicateObjectException + +extends RuntimeException + + + ++ DuplicateObjectException() ++ DuplicateObjectException(String) + + + + + +throws + + + + + + + + +contains + + + + +IReservation + +<<interface>> + + + ++ ReservationType(): String ++ getReservation_number(): String ++ getAccountNumber(): String ++ getPhysical_address(): Address ++ getPricePerNight(): float ++ calculatePrice(): float ++ checkValid(): boolean + + + + + + + +physical_address +mailing_address + + + + +Reservation + +<<abstract>> + +# type: char +- reservation_number: String +- physical_address: Address +- mailing_address: Address +- reservation_start_date: ZonedDateTime +- reservation_end_date: ZonedDateTime +- reservation_status: ReservationStatusEnum +- kitchen: KitchenTypeEnum +- numberOfBeds: Integer +- numberOfBedRooms: Integer +- numberOfBathRooms: Integer +- numberOfFloors: Integer +- squareFeet: Integer +- price: Float +# accountNumber: String + ++ getters/setters ++ Write(Reservation): void ++ Change(Reservation, ReservationStatusEnum): void ++ update(Reservation): void ++ <<abstract>> ReservationType(): String + + + + + + + +kitchen + + + + +KitchenTypeEnum + +<<enumeration>> + +None +Kitchenette +FullKitchen + + + + +ReservationStatusEnum + +<<enumeration>> + +Draft +Canceled +Completed + + + + + + +reservation_status + + + + + +IllegalOperationException + +extends RuntimeException + + + ++ IllegalOperationException() ++ IllegalOperationException(String) + + + + + + +throws + + + + + +DataRepository + +<<singleton>> + +- directoryPath: String +- instance: DataRepository + ++ setDataStoreRoot(String): void ++ getPath(): String ++ Reservation(String): Reservation ++ WalkFileSystemTree(...): void ++ LoadAccount(Path): Account +- loadReservation(...): void + + + + + + +loads + + + + + + +creates + + + + + +AccomodationManager + +- accounts: AccountList + ++ AccomodationManager(String) ++ loadAll(): void ++ load(Path): void ++ retrieveLoadedAccounts(): List<Account> ++ retrieveAccount(String): Account ++ AddAccount(Account): void ++ UpdateAccount(Account): void ++ newAccount(...): Account ++ addReservation(...): boolean ++ findReservation(String): Reservation ++ getReservationList(): List<IReservation> ++ showReservationList(): void + + + + + + +accounts + + + + + + +uses + + + + + +HotelReservation + +extends Reservation +implements IReservation + +# type: 'H' + ++ HotelReservation(Address) ++ ReservationType(): String ++ checkValid(): boolean ++ getPricePerNight(): float ++ calculatePrice(): float ++ Reservation(String): Reservation + + + + + + + + + + + + + + + + + +CabinReservation + +extends Reservation +implements IReservation + +# type: 'C' + ++ CabinReservation(Address) ++ ReservationType(): String ++ checkValid(): boolean ++ getPricePerNight(): float ++ calculatePrice(): float ++ Reservation(String): Reservation + + + + + + + + + + + + + + + + + +HouseReservation + +extends Reservation +implements IReservation + +# type: 'Z' + ++ HouseReservation(Address) ++ ReservationType(): String ++ checkValid(): boolean ++ getPricePerNight(): float ++ calculatePrice(): float ++ Reservation(String): Reservation + + + + + + + + + + + + + + + + + +TestReservations + + + ++ main(String[]): void + + + + + + +uses + + + + + + +creates + + + + + + +creates + + + + + + + + +creates + + + + \ No newline at end of file diff --git a/uml/sequencediagram.dot b/uml/sequencediagram.dot new file mode 100644 index 0000000..e69de29