diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c5f3f6b..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "interactive" -} \ No newline at end of file diff --git a/build.gradle b/build.gradle index fa678bc..0d6df7f 100644 --- a/build.gradle +++ b/build.gradle @@ -11,14 +11,27 @@ plugins { id 'application' } +// Apply a specific Java toolchain to ease working on different environments. +java { + toolchain { + languageVersion = JavaLanguageVersion.of(24) + } +} + application { mainClass = 'lodge.TestReservations' + applicationDefaultJvmArgs = ["--add-opens", "java.base/jdk.internal.loader=ALL-UNNAMED"] } sourceSets { main { java { - srcDirs = ['src/java'] + srcDirs = ['src/main/java'] + } + } + test { + java { + srcDirs = ['src/test/java'] } runtimeClasspath = files("$projectDir/libs/*.jars") } @@ -30,6 +43,8 @@ repositories { } dependencies { + + //https://mvnrepository.com/artifact/com.google.code.gson/gson implementation 'com.google.code.gson:gson:2.13.2' } @@ -46,4 +61,4 @@ tasks.named('jar') { 'Main-Class': 'lodge.TestReservations', 'Class-Path': 'lodge.reservationsystem com.google.gson .' ) } -} \ No newline at end of file +} diff --git a/libs/com.google.code.gson:gson:2.13.2.jar b/libs/com.google.code.gson:gson:2.13.2.jar deleted file mode 100644 index 5a1b74e..0000000 Binary files a/libs/com.google.code.gson:gson:2.13.2.jar and /dev/null differ diff --git a/sdd/Software_Detail_Design.docx b/sdd/Software_Detail_Design.docx index df3d036..231d04c 100644 Binary files a/sdd/Software_Detail_Design.docx and b/sdd/Software_Detail_Design.docx differ diff --git a/sdd/ui-idea1.pptx b/sdd/ui-idea1.pptx new file mode 100644 index 0000000..17b7954 Binary files /dev/null and b/sdd/ui-idea1.pptx differ diff --git a/src/java/lodge/TestAccountLoad.java b/src/main/java/lodge/TestAccountLoad.java similarity index 95% rename from src/java/lodge/TestAccountLoad.java rename to src/main/java/lodge/TestAccountLoad.java index d147de6..3ea07d4 100755 --- a/src/java/lodge/TestAccountLoad.java +++ b/src/main/java/lodge/TestAccountLoad.java @@ -5,9 +5,9 @@ package lodge; -import lodge.data.Account; -import lodge.data.Address; -import lodge.data.EmailAddress; +import lodge.datamodel.Account; +import lodge.datamodel.Address; +import lodge.datamodel.EmailAddress; import lodge.reservationsystem.AccomodationManager; /** diff --git a/src/java/lodge/TestReservations.java b/src/main/java/lodge/TestReservations.java similarity index 96% rename from src/java/lodge/TestReservations.java rename to src/main/java/lodge/TestReservations.java index a54bbae..7444a66 100644 --- a/src/java/lodge/TestReservations.java +++ b/src/main/java/lodge/TestReservations.java @@ -9,18 +9,17 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -import lodge.data.Account; -import lodge.data.Address; -import lodge.data.DuplicateObjectException; -import lodge.data.EmailAddress; -import lodge.data.ReservationStatusEnum; -import lodge.reservation.IReservation; -import lodge.reservation.Reservation; +import lodge.datamodel.Account; +import lodge.datamodel.Address; +import lodge.datamodel.DuplicateObjectException; +import lodge.datamodel.EmailAddress; +import lodge.datamodel.IReservation; +import lodge.datamodel.Reservation; +import lodge.datamodel.ReservationStatusEnum; import lodge.reservationsystem.AccomodationManager; import lodge.reservationsystem.CabinReservation; import lodge.reservationsystem.HotelReservation; import lodge.reservationsystem.HouseReservation; - /** * The Tests for the ReservationSystem Module * @@ -58,7 +57,6 @@ public final class TestReservations { mgr.UpdateAccount(acct); } - public static void main(String[] args) throws Exception { // Configure data repository diff --git a/src/java/lodge/data/Account.java b/src/main/java/lodge/datamodel/Account.java similarity index 73% rename from src/java/lodge/data/Account.java rename to src/main/java/lodge/datamodel/Account.java index bed4424..18c9635 100644 --- a/src/java/lodge/data/Account.java +++ b/src/main/java/lodge/datamodel/Account.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; import java.io.BufferedWriter; import java.io.IOException; @@ -12,9 +12,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ListIterator; -import lodge.reservation.IReservation; -import lodge.reservation.Reservation; import lodge.reservationsystem.DataRepository; + /** * Concrete account data class for account json storage record. * Collects account attributes, and hash instance to enforce uniqueness. @@ -41,11 +40,25 @@ public class Account { this.email_address = email_address; } - public Account(String phone_number, Address mailing_address, EmailAddress email_address) { - this(AccountList.accountSerial(phone_number, mailing_address, email_address), - phone_number, - mailing_address, - email_address); + public Account(String phone_number, Address mailing_address, EmailAddress email_address) + throws IllegalArgumentException { + if (phone_number == null) { + throw new IllegalArgumentException(String.format("%s %s", "Account: requires phone number", + mailing_address.toString())); + } + if (mailing_address == null) { + throw new IllegalArgumentException(String.format("%s %s", "Account: requires mailing address", + phone_number.substring(phone_number.length() - 4))); + } + if (email_address == null) { + throw new IllegalArgumentException(String.format("%s %s", "Account: requires phone number", + mailing_address.toString())); + } + + this.account_number = AccountList.accountSerial(phone_number, mailing_address, email_address); + this.phone_number = phone_number; + this.mailing_address = mailing_address; + this.email_address = email_address; } @Override @@ -157,6 +170,22 @@ public class Account { return true; } + public boolean checkValid() throws IllegalArgumentException { + if (email_address == null) { + throw new IllegalArgumentException( + String.format("not valid, email_address %s", this.getAccount_number())); + } + if (phone_number == null) { + throw new IllegalArgumentException( + String.format("not valid, phone_number: %s", this.getAccount_number())); + } + if (getMailing_address() == null) { + throw new IllegalArgumentException( + String.format("not valid, mailing_address: %s", this.getAccount_number())); + } + return true; + } + public void update(Account acct) { this.setEmail_address(acct.email_address); this.setPhone_number(acct.phone_number); diff --git a/src/java/lodge/data/AccountList.java b/src/main/java/lodge/datamodel/AccountList.java similarity index 97% rename from src/java/lodge/data/AccountList.java rename to src/main/java/lodge/datamodel/AccountList.java index de39859..3909cf9 100755 --- a/src/java/lodge/data/AccountList.java +++ b/src/main/java/lodge/datamodel/AccountList.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; import java.io.IOException; import java.util.ArrayList; @@ -10,8 +10,6 @@ import java.util.Collections; import java.util.List; import java.util.ListIterator; -import lodge.reservation.IReservation; - public class AccountList extends ArrayList { public static String accountSerial(String phone_number, Address mailing_address, EmailAddress email_address) { diff --git a/src/java/lodge/data/AccountReservationList.java b/src/main/java/lodge/datamodel/AccountReservationList.java similarity index 96% rename from src/java/lodge/data/AccountReservationList.java rename to src/main/java/lodge/datamodel/AccountReservationList.java index b962715..5f82a1c 100755 --- a/src/java/lodge/data/AccountReservationList.java +++ b/src/main/java/lodge/datamodel/AccountReservationList.java @@ -2,13 +2,10 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; import java.util.ArrayList; -import lodge.reservation.IReservation; -import lodge.reservation.Reservation; - class AccountReservationList extends ArrayList { private static String reservationSerial(Reservation reservation) { diff --git a/src/java/lodge/data/Address.java b/src/main/java/lodge/datamodel/Address.java similarity index 99% rename from src/java/lodge/data/Address.java rename to src/main/java/lodge/datamodel/Address.java index d889876..8a30195 100644 --- a/src/java/lodge/data/Address.java +++ b/src/main/java/lodge/datamodel/Address.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; public final class Address{ diff --git a/src/java/lodge/data/DuplicateObjectException.java b/src/main/java/lodge/datamodel/DuplicateObjectException.java similarity index 91% rename from src/java/lodge/data/DuplicateObjectException.java rename to src/main/java/lodge/datamodel/DuplicateObjectException.java index d0bccd1..7d6f7af 100644 --- a/src/java/lodge/data/DuplicateObjectException.java +++ b/src/main/java/lodge/datamodel/DuplicateObjectException.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; public class DuplicateObjectException extends RuntimeException { public DuplicateObjectException() { diff --git a/src/java/lodge/data/EmailAddress.java b/src/main/java/lodge/datamodel/EmailAddress.java similarity index 98% rename from src/java/lodge/data/EmailAddress.java rename to src/main/java/lodge/datamodel/EmailAddress.java index d7acfe0..3b5caf6 100644 --- a/src/java/lodge/data/EmailAddress.java +++ b/src/main/java/lodge/datamodel/EmailAddress.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; public class EmailAddress{ String email_address; diff --git a/src/java/lodge/reservation/IReservation.java b/src/main/java/lodge/datamodel/IReservation.java similarity index 87% rename from src/java/lodge/reservation/IReservation.java rename to src/main/java/lodge/datamodel/IReservation.java index 7cbdf6d..5f5083b 100644 --- a/src/java/lodge/reservation/IReservation.java +++ b/src/main/java/lodge/datamodel/IReservation.java @@ -1,6 +1,4 @@ -package lodge.reservation; - -import lodge.data.Address; +package lodge.datamodel; public interface IReservation { diff --git a/src/java/lodge/data/IllegalOperationException.java b/src/main/java/lodge/datamodel/IllegalOperationException.java similarity index 91% rename from src/java/lodge/data/IllegalOperationException.java rename to src/main/java/lodge/datamodel/IllegalOperationException.java index a455ad2..b6d32b6 100644 --- a/src/java/lodge/data/IllegalOperationException.java +++ b/src/main/java/lodge/datamodel/IllegalOperationException.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; public class IllegalOperationException extends RuntimeException { public IllegalOperationException () { diff --git a/src/java/lodge/data/KitchenTypeEnum.java b/src/main/java/lodge/datamodel/KitchenTypeEnum.java similarity index 82% rename from src/java/lodge/data/KitchenTypeEnum.java rename to src/main/java/lodge/datamodel/KitchenTypeEnum.java index 9ea8866..3a6680c 100644 --- a/src/java/lodge/data/KitchenTypeEnum.java +++ b/src/main/java/lodge/datamodel/KitchenTypeEnum.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; public enum KitchenTypeEnum { None, Kitchenette, FullKitchen; diff --git a/src/java/lodge/reservation/Reservation.java b/src/main/java/lodge/datamodel/Reservation.java similarity index 97% rename from src/java/lodge/reservation/Reservation.java rename to src/main/java/lodge/datamodel/Reservation.java index 077a814..e851d75 100644 --- a/src/java/lodge/reservation/Reservation.java +++ b/src/main/java/lodge/datamodel/Reservation.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.reservation; +package lodge.datamodel; import java.io.BufferedWriter; import java.io.IOException; @@ -12,10 +12,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.time.ZonedDateTime; -import lodge.data.Address; -import lodge.data.IllegalOperationException; -import lodge.data.KitchenTypeEnum; -import lodge.data.ReservationStatusEnum; import lodge.reservationsystem.DataRepository; public abstract class Reservation implements IReservation{ diff --git a/src/java/lodge/data/ReservationStatusEnum.java b/src/main/java/lodge/datamodel/ReservationStatusEnum.java similarity index 83% rename from src/java/lodge/data/ReservationStatusEnum.java rename to src/main/java/lodge/datamodel/ReservationStatusEnum.java index 5c8b875..a82298c 100644 --- a/src/java/lodge/data/ReservationStatusEnum.java +++ b/src/main/java/lodge/datamodel/ReservationStatusEnum.java @@ -2,7 +2,7 @@ * license: GPLv3 * lodge.reservationsystem */ -package lodge.data; +package lodge.datamodel; public enum ReservationStatusEnum { Draft, diff --git a/src/java/lodge/reservationsystem/AccomodationManager.java b/src/main/java/lodge/reservationsystem/AccomodationManager.java similarity index 79% rename from src/java/lodge/reservationsystem/AccomodationManager.java rename to src/main/java/lodge/reservationsystem/AccomodationManager.java index cb44cdf..129ad5b 100644 --- a/src/java/lodge/reservationsystem/AccomodationManager.java +++ b/src/main/java/lodge/reservationsystem/AccomodationManager.java @@ -4,17 +4,20 @@ */ package lodge.reservationsystem; +import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.List; -import lodge.data.Account; -import lodge.data.AccountList; -import lodge.data.Address; -import lodge.data.EmailAddress; -import lodge.reservation.IReservation; -import lodge.reservation.Reservation; +import lodge.datamodel.Account; +import lodge.datamodel.AccountList; +import lodge.datamodel.Address; +import lodge.datamodel.DuplicateObjectException; +import lodge.datamodel.EmailAddress; +import lodge.datamodel.IReservation; +import lodge.datamodel.IllegalOperationException; +import lodge.datamodel.Reservation; public final class AccomodationManager { @@ -33,7 +36,7 @@ public final class AccomodationManager { DataRepository.setDataStoreRoot(home); } - public final void loadAll() throws Exception { + public final void loadAll()throws IOException,IllegalArgumentException,IllegalOperationException,DuplicateObjectException{ accounts.clear(); // walk directories Path rootDir = Paths.get(DataRepository.getPath()); @@ -42,12 +45,13 @@ public final class AccomodationManager { } // Load / Deserialize Account - protected void load(Path file) throws Exception { + protected void load(Path file) throws IOException,IllegalArgumentException,IllegalOperationException,DuplicateObjectException { Account account = DataRepository.LoadAccount(file); if (account == null) { - System.out.println(String.format("%s", file.toString())); + System.out.println(String.format("No Account: %s", file.toString())); } else { + account.checkValid(); accounts.add(account); } } diff --git a/src/java/lodge/reservationsystem/CabinReservation.java b/src/main/java/lodge/reservationsystem/CabinReservation.java similarity index 95% rename from src/java/lodge/reservationsystem/CabinReservation.java rename to src/main/java/lodge/reservationsystem/CabinReservation.java index f708a70..14e116b 100644 --- a/src/java/lodge/reservationsystem/CabinReservation.java +++ b/src/main/java/lodge/reservationsystem/CabinReservation.java @@ -7,9 +7,9 @@ package lodge.reservationsystem; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -import lodge.data.Address; -import lodge.data.KitchenTypeEnum; -import lodge.reservation.Reservation; +import lodge.datamodel.Address; +import lodge.datamodel.KitchenTypeEnum; +import lodge.datamodel.Reservation; /** * Concrete reservation data class for reservation storage record diff --git a/src/java/lodge/reservationsystem/DataRepository.java b/src/main/java/lodge/reservationsystem/DataRepository.java similarity index 97% rename from src/java/lodge/reservationsystem/DataRepository.java rename to src/main/java/lodge/reservationsystem/DataRepository.java index 02cbd64..8fe7a98 100644 --- a/src/java/lodge/reservationsystem/DataRepository.java +++ b/src/main/java/lodge/reservationsystem/DataRepository.java @@ -17,12 +17,13 @@ import java.nio.file.attribute.BasicFileAttributes; import java.time.ZonedDateTime; import com.google.gson.stream.JsonReader; -import lodge.data.Address; -import lodge.data.EmailAddress; -import lodge.data.Account; -import lodge.data.KitchenTypeEnum; -import lodge.data.ReservationStatusEnum; -import lodge.reservation.Reservation; + +import lodge.datamodel.Account; +import lodge.datamodel.Address; +import lodge.datamodel.EmailAddress; +import lodge.datamodel.KitchenTypeEnum; +import lodge.datamodel.Reservation; +import lodge.datamodel.ReservationStatusEnum; public final class DataRepository { // SINGLETON CLASS @@ -162,7 +163,7 @@ public final class DataRepository { } private static void loadReservation(Account ac, String reservationType, - String reservationNumber) throws NullPointerException, IOException { + String reservationNumber) throws IOException { String filename = String.format("rsv-%s.json", reservationNumber); Path basePath = Paths.get(getPath()); Path resolvedPath = basePath.resolve(filename); diff --git a/src/java/lodge/reservationsystem/HotelReservation.java b/src/main/java/lodge/reservationsystem/HotelReservation.java similarity index 96% rename from src/java/lodge/reservationsystem/HotelReservation.java rename to src/main/java/lodge/reservationsystem/HotelReservation.java index a6727f7..2494098 100644 --- a/src/java/lodge/reservationsystem/HotelReservation.java +++ b/src/main/java/lodge/reservationsystem/HotelReservation.java @@ -8,9 +8,9 @@ import java.time.LocalTime; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -import lodge.data.Address; -import lodge.data.KitchenTypeEnum; -import lodge.reservation.Reservation; +import lodge.datamodel.Address; +import lodge.datamodel.KitchenTypeEnum; +import lodge.datamodel.Reservation; /** * Concrete reservation data class for reservation storage record diff --git a/src/java/lodge/reservationsystem/HouseReservation.java b/src/main/java/lodge/reservationsystem/HouseReservation.java similarity index 95% rename from src/java/lodge/reservationsystem/HouseReservation.java rename to src/main/java/lodge/reservationsystem/HouseReservation.java index 51d3c7b..668b13c 100644 --- a/src/java/lodge/reservationsystem/HouseReservation.java +++ b/src/main/java/lodge/reservationsystem/HouseReservation.java @@ -7,9 +7,9 @@ package lodge.reservationsystem; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; -import lodge.data.Address; -import lodge.data.KitchenTypeEnum; -import lodge.reservation.Reservation; +import lodge.datamodel.Address; +import lodge.datamodel.KitchenTypeEnum; +import lodge.datamodel.Reservation; /** * Concrete reservation data class for reservation storage record diff --git a/src/resources/acc-A1450981765.json b/src/resources/acc-A1450981765.json index e9fcb96..64286ac 100755 --- 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"}},"reservations":[{"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":[]}} \ No newline at end of file diff --git a/uml/classdiagram.dot b/uml/classdiagram.dot index 8aa62f5..baf7abb 100644 --- a/uml/classdiagram.dot +++ b/uml/classdiagram.dot @@ -1,8 +1,8 @@ digraph LodgeReservationSystem { // Graph attributes rankdir=TB; - node [shape=record, fontname="Arial", fontsize=10]; - edge [fontname="Arial", fontsize=9]; + node [shape=record, fontname="Times New Roman", fontsize=10]; + edge [fontname="Times New Roman", fontsize=9]; // Package clustering subgraph cluster_data { diff --git a/uml/classdiagram4.dot b/uml/classdiagram4.dot new file mode 100644 index 0000000..e46d9e9 --- /dev/null +++ b/uml/classdiagram4.dot @@ -0,0 +1,44 @@ +digraph ReservationsSystemSequence { + rankdir=TB; + splines=ortho; + node [shape=box, style=rounded]; + + actor -> "TestReservations" [label="main(args)"]; + + "TestReservations" -> "AccomodationManager" [label="1: new AccomodationManager(path)"]; + "TestReservations" -> "AccomodationManager" [label="2: loadAll()"]; + "AccomodationManager" -> "DataRepository" [label="3: WalkFileSystemTree(this, path)"]; + "DataRepository" -> "AccomodationManager" [label="4: load(file)"]; + "AccomodationManager" -> "DataRepository" [label="5: LoadAccount(file)"]; + "DataRepository" -> "Account" [label="6: new Account()"]; + "DataRepository" -> "DataRepository" [label="7: loadReservationRefList(jsonReader, account)"]; + "DataRepository" -> "DataRepository" [label="8: loadReservation(account, type, number)"]; + "DataRepository" -> "Reservation" [label="9: new [Hotel/Cabin/House]Reservation()"]; + "DataRepository" -> "Account" [label="10: add(reservation)"]; + "Account" -> "AccountReservationList" [label="11: add(reservation)"]; + "DataRepository" -> "AccomodationManager" [label="12: return Account"]; + "AccomodationManager" -> "AccountList" [label="13: add(account)"]; + + "TestReservations" -> "AccomodationManager" [label="14: newAccount(...)"]; + "AccomodationManager" -> "Account" [label="15: new Account(...)"]; + "TestReservations" -> "AccomodationManager" [label="16: AddAccount(account)"]; + "AccomodationManager" -> "AccountList" [label="17: add(account)"]; + "TestReservations" -> "AccomodationManager" [label="18: UpdateAccount(account)"]; + "AccomodationManager" -> "Account" [label="19: Write(account)"]; + "Account" -> "DataRepository" [label="20: getPath()"]; + "Account" -> "Reservation" [label="21: Write(reservation)"]; + + "TestReservations" -> "Reservation" [label="22: new [Hotel/Cabin/House]Reservation()"]; + "TestReservations" -> "AccomodationManager" [label="23: addReservation(account, reservation)"]; + "AccomodationManager" -> "Account" [label="24: add(reservation)"]; + "Account" -> "AccountReservationList" [label="25: add(reservation)"]; + "TestReservations" -> "AccomodationManager" [label="26: UpdateAccount(account)"]; + "AccomodationManager" -> "Account" [label="27: Write(account)"]; + + "TestReservations" -> "Reservation" [label="28: Change(reservation, newStatus)"]; + "Reservation" -> "Reservation" [label="29: calculatePrice()"]; + "TestReservations" -> "AccomodationManager" [label="30: UpdateAccount(account)"]; + + "TestReservations" -> "Reservation" [label="31: getPricePerNight()"]; + "TestReservations" -> "Reservation" [label="32: calculatePrice()"]; +} diff --git a/uml/classdiagram5.dot b/uml/classdiagram5.dot new file mode 100644 index 0000000..3098840 --- /dev/null +++ b/uml/classdiagram5.dot @@ -0,0 +1,65 @@ +digraph ReservationSystemClassDiagram { + rankdir=BT; + splines=ortho; + node [shape=record, style=rounded, fontname="Helvetica"]; + edge [fontname="Helvetica"]; + + // --- Interfaces --- + IReservation [label="{«interface»\nIReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l+ getPricePerNight()\l...}", style=dashed]; + + // --- Abstract Classes --- + Reservation [label="{«abstract»\nReservation|- 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- price: Float\l- accountNumber: String\l|+ Write(Reservation)\l+ Change(Reservation, ReservationStatusEnum)\l+ ReservationType()\l...}"]; + + // --- Concrete Classes --- + TestReservations [label="{TestReservations|+ main(String[])\l- Test_AddAccount(...)\l- Test_AddReservation(...)\l}"]; + AccomodationManager [label="{AccomodationManager|- accounts: AccountList\l|+ loadAll()\l+ retrieveAccount(String)\l+ AddAccount(Account)\l+ UpdateAccount(Account)\l+ newAccount(...)\l+ addReservation(Account, Reservation)\l...}"]; + DataRepository [label="{DataRepository|- directoryPath: String\l- instance: DataRepository\l+ getInstance()\l+ WalkFileSystemTree(...)\l+ LoadAccount(Path)\l+ Reservation(String)\l...}"]; + Account [label="{Account|- account_number: String\l- phone_number: String\l- mailing_address: Address\l- email_address: EmailAddress\l- reservations: AccountReservationList\l|+ add(Reservation)\l+ Write(Account)\l+ findReservation(String)\l...}"]; + AccountList [label="{AccountList|+ add(Account)\l+ find(String)\l+ save(Account)\l...}"]; + AccountReservationList [label="{AccountReservationList|+ add(IReservation)\l+ find(String)\l...}"]; + HotelReservation [label="{HotelReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l...}"]; + CabinReservation [label="{CabinReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l...}"]; + HouseReservation [label="{HouseReservation|+ ReservationType()\l+ checkValid()\l+ calculatePrice()\l...}"]; + Address [label="{Address|- street: String\l- city: String\l- state: String\l- zip: String\l}"]; + EmailAddress [label="{EmailAddress|- email: String\l}"]; + + // --- Enums --- + ReservationStatusEnum [label="{«enumeration»\nReservationStatusEnum|Draft\lCompleted\lCanceled\l}", style=filled, fillcolor=lightgrey]; + KitchenTypeEnum [label="{«enumeration»\nKitchenTypeEnum|None\lKitchenette\lFullKitchen\l}", style=filled, fillcolor=lightgrey]; + + // --- Inheritance & Implementation --- + edge [arrowhead=empty, style=solid]; + HotelReservation -> Reservation; + CabinReservation -> Reservation; + HouseReservation -> Reservation; + + edge [arrowhead=empty, style=dashed]; + Reservation -> IReservation; + + // --- Aggregation & Composition --- + edge [arrowhead=diamond, style=solid, label="1"]; + AccomodationManager -> AccountList [label="1..*", headlabel="manages"]; + Account -> AccountReservationList [label="1..*", headlabel="has"]; + Account -> Address [label="1", headlabel="mailing"]; + Account -> EmailAddress [label="1"]; + Reservation -> Address [label="0..2", headlabel="physical/mailing"]; + Reservation -> ReservationStatusEnum [label="1"]; + Reservation -> KitchenTypeEnum [label="1"]; + AccountReservationList -> IReservation [arrowhead=odiamond, label="0..*"]; + AccountList -> Account [arrowhead=odiamond, label="0..*"]; + + + // --- Dependencies --- + edge [arrowhead=vee, style=dashed, label="«uses»"]; + TestReservations -> AccomodationManager; + TestReservations -> HotelReservation; + TestReservations -> CabinReservation; + TestReservations -> HouseReservation; + AccomodationManager -> DataRepository; + + DataRepository -> AccomodationManager; + DataRepository -> Account; + DataRepository -> Reservation; + Account -> DataRepository; + Reservation -> DataRepository; +} diff --git a/uml/classdiagram6.dot b/uml/classdiagram6.dot new file mode 100644 index 0000000..31a19ef --- /dev/null +++ b/uml/classdiagram6.dot @@ -0,0 +1,97 @@ +digraph "Reservation System" { + // General graph settings + graph [ + rankdir="TB", + splines=ortho, + nodesep=1.0, + ranksep=1.0, + fontname="Arial", + fontsize=12 + ]; + + // General node and edge settings + node [ + shape=record, + style=filled, + fillcolor=lightyellow, + fontname="Arial", + fontsize=10 + ]; + edge [ + fontname="Arial", + fontsize=9 + ]; + + // Packages + subgraph cluster_reservationsystem { + label="lodge.reservationsystem"; + style=filled; + color=lightgrey; + + AccomodationManager [label="{AccomodationManager|+ AccomodationManager(String)\l+ loadAll(): void\l+ retrieveAccount(String): Account\l+ retrieveLoadedAccounts(): AccountList\l+ newAccount(String, Address, EmailAddress): Account\l+ AddAccount(Account): void\l+ UpdateAccount(Account): void\l+ addReservation(Account, Reservation): boolean\l+ showReservationList(): void\l}"]; + DataRepository [label="{DataRepository (Singleton)|- directoryPath: String\l- instance: DataRepository\l|+ getInstance(): DataRepository\l+ setDataStoreRoot(path: String)\l+ getPath(): String\l+ Reservation(type: String): Reservation\l+ WalkFileSystemTree(manager: AccomodationManager, rootDir: Path)\l+ LoadAccount(file: Path): Account\l- loadReservationRefList(rdr: JsonReader, ac: Account)\l- loadReservation(ac: Account, type: String, num: String)\l}"]; + HotelReservation [label="{HotelReservation|+ HotelReservation(physicalAddress: Address)\l}"]; + HouseReservation [label="{HouseReservation|+ HouseReservation(physicalAddress: Address)\l}"]; + CabinReservation [label="{CabinReservation|+ CabinReservation(physicalAddress: Address)\l}"]; + } + + subgraph cluster_datamodel { + label="lodge.datamodel"; + style=filled; + color=lightblue; + + IReservation [label="<>\nIReservation"]; + Reservation [label="{Reservation|+ Reservation()\l+ Reservation(physicalAddress: Address)\l+ Change(rsrv: Reservation, status: ReservationStatusEnum)\l+ update(rsrv: Reservation)\l+ calculatePrice(): float\l+ getPricePerNight(): float\l+ ReservationType(): String\l}"]; + Account [label="{Account|+ Account()\l+ add(rsrv: Reservation)\l+ findReservation(reservationNumber: String): Reservation\l+ getAllReservations(): Iterator\l}"]; + Address [label="{Address|+ Address(street: String, city: String, state: String, zip: String)\l}"]; + EmailAddress [label="{EmailAddress|+ EmailAddress(email: String)\l}"]; + ReservationStatusEnum [label="<>\nReservationStatusEnum|DRAFT\lCOMPLETED\lCANCELED\l"]; + KitchenTypeEnum [label="<>\nKitchenTypeEnum|NONE\lPARTIAL\lFULL\l"]; + DuplicateObjectException [label="<>\nDuplicateObjectException"]; + } + + subgraph cluster_test { + label="lodge (Test)"; + style=filled; + color=honeydew; + TestReservations [label="{TestReservations|+ main(args: String[])\l}"]; + } + + + // Relationships + AccomodationManager -> Account [label="manages"]; + AccomodationManager -> Reservation [label="manages"]; + AccomodationManager -> DataRepository [label="uses"]; + + DataRepository -> AccomodationManager [label="uses"]; + DataRepository -> Reservation [label="creates"]; + DataRepository -> HotelReservation [label="creates"]; + DataRepository -> HouseReservation [label="creates"]; + DataRepository -> CabinReservation [label="creates"]; + DataRepository -> Account [label="loads/updates"]; + + TestReservations -> AccomodationManager [label="uses"]; + TestReservations -> Account [label="uses"]; + TestReservations -> HotelReservation [label="creates"]; + TestReservations -> HouseReservation [label="creates"]; + TestReservations -> CabinReservation [label="creates"]; + + Account -> IReservation [label="contains 0..*"]; + Account -> Address [label="has mailing"]; + Account -> EmailAddress [label="has"]; + + Reservation -> IReservation [style=dashed, arrowhead=empty, label="implements"]; + Reservation -> Address [label="has physical/mailing"]; + Reservation -> ReservationStatusEnum; + Reservation -> KitchenTypeEnum; + + HotelReservation -> Reservation [style=dashed, arrowhead=empty, label="extends"]; + HouseReservation -> Reservation [style=dashed, arrowhead=empty, label="extends"]; + CabinReservation -> Reservation [style=dashed, arrowhead=empty, label="extends"]; + + // Exceptions + edge [color=red, style=dashed, arrowhead=open]; + AccomodationManager -> DuplicateObjectException [label="<>"]; + AccomodationManager -> Exception [label="<>"]; + DataRepository -> IOException [label="<>"]; +} diff --git a/uml/classdiagram6.svg b/uml/classdiagram6.svg new file mode 100644 index 0000000..e1d746f --- /dev/null +++ b/uml/classdiagram6.svg @@ -0,0 +1,367 @@ + + + + + + +Reservation System + + +cluster_reservationsystem + +lodge.reservationsystem + + +cluster_datamodel + +lodge.datamodel + + +cluster_test + +lodge (Test) + + + +AccomodationManager + +AccomodationManager + ++ AccomodationManager(String) ++ loadAll(): void ++ retrieveAccount(String): Account ++ retrieveLoadedAccounts(): AccountList ++ newAccount(String, Address, EmailAddress): Account ++ AddAccount(Account): void ++ UpdateAccount(Account): void ++ addReservation(Account, Reservation): boolean ++ showReservationList(): void + + + +DataRepository + +DataRepository (Singleton) + +- directoryPath: String +- instance: DataRepository + ++ getInstance(): DataRepository ++ setDataStoreRoot(path: String) ++ getPath(): String ++ Reservation(type: String): Reservation ++ WalkFileSystemTree(manager: AccomodationManager, rootDir: Path) ++ LoadAccount(file: Path): Account +- loadReservationRefList(rdr: JsonReader, ac: Account) +- loadReservation(ac: Account, type: String, num: String) + + + +AccomodationManager->DataRepository + + +uses + + + +Reservation + +Reservation + ++ Reservation() ++ Reservation(physicalAddress: Address) ++ Change(rsrv: Reservation, status: ReservationStatusEnum) ++ update(rsrv: Reservation) ++ calculatePrice(): float ++ getPricePerNight(): float ++ ReservationType(): String + + + +AccomodationManager->Reservation + + +manages + + + +Account + +Account + + + + +AccomodationManager->Account + + +manages + + + +DuplicateObjectException + +DuplicateObjectException + + + +AccomodationManager->DuplicateObjectException + + +<<throws>> + + + +Exception + +Exception + + + +AccomodationManager->Exception + + +<<throws>> + + + +DataRepository->AccomodationManager + + +uses + + + +HotelReservation + +HotelReservation + ++ HotelReservation(physicalAddress: Address) + + + +DataRepository->HotelReservation + + +creates + + + +HouseReservation + +HouseReservation + ++ HouseReservation(physicalAddress: Address) + + + +DataRepository->HouseReservation + + +creates + + + +CabinReservation + +CabinReservation + ++ CabinReservation(physicalAddress: Address) + + + +DataRepository->CabinReservation + + +creates + + + +DataRepository->Reservation + + +creates + + + +DataRepository->Account + + +loads/updates + + + +IOException + +IOException + + + +DataRepository->IOException + + +<<throws>> + + + +NullPointerException + +NullPointerException + + + +DataRepository->NullPointerException + + +<<throws>> + + + +HotelReservation->Reservation + + +extends + + + +HouseReservation->Reservation + + +extends + + + +CabinReservation->Reservation + + +extends + + + +IReservation + +IReservation + + + +Reservation->IReservation + + +implements + + + +Address + +Address + ++ Address(street: String, city: String, state: String, zip: String) + + + +Reservation->Address + + +has physical/mailing + + + +ReservationStatusEnum + +ReservationStatusEnum + + + +Reservation->ReservationStatusEnum + + + + + +KitchenTypeEnum + +KitchenTypeEnum + + + +Reservation->KitchenTypeEnum + + + + + +Account->IReservation + + +contains 0..* + + + +Account->Address + + +has mailing + + + +EmailAddress + +EmailAddress + ++ EmailAddress(email: String) + + + +Account->EmailAddress + + +has + + + +TestReservations + +TestReservations + ++ main(args: String[]) + + + +TestReservations->AccomodationManager + + +uses + + + +TestReservations->HotelReservation + + +creates + + + +TestReservations->HouseReservation + + +creates + + + +TestReservations->CabinReservation + + +creates + + + +TestReservations->Account + + +uses + + + diff --git a/uml/classdiagram7.dot b/uml/classdiagram7.dot new file mode 100644 index 0000000..74467da --- /dev/null +++ b/uml/classdiagram7.dot @@ -0,0 +1,83 @@ +digraph "Reservation System - Account Load" { + // General graph settings + graph [ + rankdir="TB", + splines=ortho, + nodesep=1.0, + ranksep=1.0, + fontname="Arial", + fontsize=12, + label="Reservation System - Account Loading" + ]; + + // General node and edge settings + node [ + shape=record, + style=filled, + fillcolor=lightyellow, + fontname="Arial", + fontsize=10 + ]; + edge [ + fontname="Arial", + fontsize=9 + ]; + + // Packages + subgraph cluster_reservationsystem { + label="lodge.reservationsystem"; + style=filled; + color=lightgrey; + + AccomodationManager [label="{AccomodationManager|+ AccomodationManager(home: String)\l+ newAccount(phone: String, addr: Address, email: EmailAddress): Account\l+ AddAccount(acct: Account)\l+ UpdateAccount(acct: Account)\l+ showAccountList()\l}"]; + DataRepository [label="{DataRepository (Singleton)|- directoryPath: String\l- instance: DataRepository\l|+ getInstance(): DataRepository\l+ setDataStoreRoot(path: String)\l+ getPath(): String\l+ LoadAccount(file: Path): Account\l}"]; + } + + subgraph cluster_datamodel { + label="lodge.datamodel"; + style=filled; + color=lightblue; + + Account [label="{Account|+ Account()\l+ Account(phone: String, mailAddr: Address, email: EmailAddress)\l+ Write(acct: Account)\l+ checkValid()\l}"]; + AccountList [label="{AccountList|+ add(acct: Account)\l+ save(acct: Account)\l+ find(account_number: String): Account\l+ showAccountList()\l}"]; + Address [label="{Address|+ Address(street: String, city: String, state: String, zip: String)\l}"]; + EmailAddress [label="{EmailAddress|+ EmailAddress(email: String)\l}"]; + DuplicateObjectException [label="<>\nDuplicateObjectException"]; + IllegalArgumentException [label="<>\nIllegalArgumentException"]; + } + + subgraph cluster_test { + label="lodge (Test)"; + style=filled; + color=honeydew; + TestAccountLoad [label="{TestAccountLoad|+ main(args: String[])\l- Test_AddAccount(mgr: AccomodationManager, acct: Account)\l}"]; + TestAccountLoad_getRepositoryConfig [label="{getRepositoryConfig|+ getPath(): String\l}"]; + } + + // Class Relationships + TestAccountLoad -> AccomodationManager [label="uses"]; + TestAccountLoad -> Account [label="uses"]; + TestAccountLoad -> Address [label="creates"]; + TestAccountLoad -> EmailAddress [label="creates"]; + TestAccountLoad -> TestAccountLoad_getRepositoryConfig [style=dashed, arrowhead=open, label="has inner"]; + + AccomodationManager -> AccountList [arrowhead=diamond,label="manages 1"]; + AccomodationManager -> DataRepository [label="uses"]; + AccomodationManager -> Account [label="creates/updates"]; + + AccountList -> Account [arrowhead=odiamond, label="0..*"]; + + Account -> Address [label="has mailing"]; + Account -> EmailAddress [label="has"]; + Account -> DataRepository [label="uses for persistence"]; + + DataRepository -> Account [label="loads"]; + + // Exception Relationships + edge [color=red, style=dashed, arrowhead=open]; + AccomodationManager -> Exception [label="<>"]; + AccountList -> DuplicateObjectException [label="<>"]; + Account -> IllegalArgumentException [label="<>"]; + Account -> IOException [label="<>"]; + DataRepository -> IOException [label="<>"]; +} diff --git a/uml/classdiagram7.svg b/uml/classdiagram7.svg new file mode 100644 index 0000000..69a34b6 --- /dev/null +++ b/uml/classdiagram7.svg @@ -0,0 +1,260 @@ + + + + + + +Reservation System - Account Load + +Reservation System - Account Loading + +cluster_reservationsystem + +lodge.reservationsystem + + +cluster_datamodel + +lodge.datamodel + + +cluster_test + +lodge (Test) + + + +AccomodationManager + +AccomodationManager + ++ AccomodationManager(home: String) ++ newAccount(phone: String, addr: Address, email: EmailAddress): Account ++ AddAccount(acct: Account) ++ UpdateAccount(acct: Account) ++ showAccountList() + + + +DataRepository + +DataRepository (Singleton) + +- directoryPath: String +- instance: DataRepository + ++ getInstance(): DataRepository ++ setDataStoreRoot(path: String) ++ getPath(): String ++ LoadAccount(file: Path): Account + + + +AccomodationManager->DataRepository + + +uses + + + +Account + +Account + ++ Account() ++ Account(phone: String, mailAddr: Address, email: EmailAddress) ++ Write(acct: Account) ++ checkValid() + + + +AccomodationManager->Account + + +creates/updates + + + +AccountList + +AccountList + ++ add(acct: Account) ++ save(acct: Account) ++ find(account_number: String): Account ++ showAccountList() + + + +AccomodationManager->AccountList + + +manages 1 + + + +Exception + +Exception + + + +AccomodationManager->Exception + + +<<throws>> + + + +DataRepository->Account + + +loads + + + +IOException + +IOException + + + +DataRepository->IOException + + +<<throws>> + + + +Account->DataRepository + + +uses for persistence + + + +Address + +Address + ++ Address(street: String, city: String, state: String, zip: String) + + + +Account->Address + + +has mailing + + + +EmailAddress + +EmailAddress + ++ EmailAddress(email: String) + + + +Account->EmailAddress + + +has + + + +IllegalArgumentException + +IllegalArgumentException + + + +Account->IllegalArgumentException + + +<<throws>> + + + +Account->IOException + + +<<throws>> + + + +AccountList->Account + + +0..* + + + +DuplicateObjectException + +DuplicateObjectException + + + +AccountList->DuplicateObjectException + + +<<throws>> + + + +TestAccountLoad + +TestAccountLoad + ++ main(args: String[]) +- Test_AddAccount(mgr: AccomodationManager, acct: Account) + + + +TestAccountLoad->AccomodationManager + + +uses + + + +TestAccountLoad->Account + + +uses + + + +TestAccountLoad->Address + + +creates + + + +TestAccountLoad->EmailAddress + + +creates + + + +TestAccountLoad_getRepositoryConfig + +getRepositoryConfig + ++ getPath(): String + + + +TestAccountLoad->TestAccountLoad_getRepositoryConfig + + +has inner + + +