From 1bc540427afe81214fa5f067ffbc23113bc9ca7e Mon Sep 17 00:00:00 2001 From: mms37 Date: Sat, 9 Jul 2022 10:26:29 -0700 Subject: [PATCH] initial --- .idea/.gitignore | 3 + .idea/libraries/google_code_gson.xml | 10 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/uiDesigner.xml | 124 ++++++++ .idea/vcs.xml | 7 + cmpt213-a3.iml | 12 + list.json | 1 + .../assignment3/packagedeliveries/Main.class | Bin 0 -> 1425 bytes .../control/PackageDeliveriesTracker$1.class | Bin 0 -> 1758 bytes .../control/PackageDeliveriesTracker$2.class | Bin 0 -> 888 bytes .../control/PackageDeliveriesTracker.class | Bin 0 -> 5425 bytes .../PackageFactory$PackageType$1.class | Bin 0 -> 1290 bytes .../PackageFactory$PackageType$2.class | Bin 0 -> 1303 bytes .../PackageFactory$PackageType$3.class | Bin 0 -> 1279 bytes .../control/PackageFactory$PackageType.class | Bin 0 -> 2006 bytes .../control/PackageFactory.class | Bin 0 -> 1623 bytes .../packagedeliveries/control/TextMenu.class | Bin 0 -> 8859 bytes .../extras/RuntimeTypeAdapterFactory$1.class | Bin 0 -> 4964 bytes .../extras/RuntimeTypeAdapterFactory.class | Bin 0 -> 5816 bytes .../packagedeliveries/model/BookPackage.class | Bin 0 -> 1425 bytes .../model/ElectronicPackage.class | Bin 0 -> 1426 bytes .../packagedeliveries/model/PackageInfo.class | Bin 0 -> 3465 bytes .../model/PerishablePackage.class | Bin 0 -> 1695 bytes .../packagedeliveries/view/Input$1.class | Bin 0 -> 1602 bytes .../packagedeliveries/view/Input.class | Bin 0 -> 1934 bytes .../view/JavaSwingUI$1.class | Bin 0 -> 1159 bytes .../packagedeliveries/view/JavaSwingUI.class | Bin 0 -> 3317 bytes .../assignment3/packagedeliveries/Main.java | 15 + .../control/PackageDeliveriesTracker.java | 113 +++++++ .../control/PackageFactory.java | 73 +++++ .../packagedeliveries/control/TextMenu.java | 280 ++++++++++++++++++ .../extras/RuntimeTypeAdapterFactory.java | 256 ++++++++++++++++ .../packagedeliveries/model/BookPackage.java | 23 ++ .../model/ElectronicPackage.java | 21 ++ .../packagedeliveries/model/PackageInfo.java | 85 ++++++ .../model/PerishablePackage.java | 24 ++ .../packagedeliveries/view/Input.java | 46 +++ .../packagedeliveries/view/JavaSwingUI.java | 73 +++++ .../packagedeliveries/view/package-info.java | 1 + 40 files changed, 1181 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/libraries/google_code_gson.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/uiDesigner.xml create mode 100644 .idea/vcs.xml create mode 100644 cmpt213-a3.iml create mode 100644 list.json create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/Main.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker$1.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker$2.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$1.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$2.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$3.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/TextMenu.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/gson/extras/RuntimeTypeAdapterFactory$1.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/gson/extras/RuntimeTypeAdapterFactory.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/BookPackage.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/PackageInfo.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/Input$1.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/Input.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI$1.class create mode 100644 out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI.class create mode 100644 src/cmpt213/assignment3/packagedeliveries/Main.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/control/PackageFactory.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/control/TextMenu.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/gson/extras/RuntimeTypeAdapterFactory.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/model/BookPackage.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/model/PackageInfo.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/view/Input.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI.java create mode 100644 src/cmpt213/assignment3/packagedeliveries/view/package-info.java diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/libraries/google_code_gson.xml b/.idea/libraries/google_code_gson.xml new file mode 100644 index 0000000..b8c8e54 --- /dev/null +++ b/.idea/libraries/google_code_gson.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..a346fd7 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..50ccbd9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..77a3cc7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/cmpt213-a3.iml b/cmpt213-a3.iml new file mode 100644 index 0000000..b5d0958 --- /dev/null +++ b/cmpt213-a3.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/list.json b/list.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/list.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/Main.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..33b5bb914ba50b866a0842923e8a97f28c83956f GIT binary patch literal 1425 zcma)6YflqF6g|^Iw_TQ35fD^fg0>Y|9*SsrC{+Y4N-Q=pewwyp8QAVNyIYW-r60gx z;tw$XCgYv9!Q~M`n%wE!x#ygF@7$f=e@}h^SjKA|A%r!w7-&U=p=+1#bJOB>*?eEv z6-A#RvM6ooFEfM_$$Sh^#5Cvz+F+as&mDTcs8EzsBT#R)P9z<3%ayjD^IgF!=_ooF zjCEmI&d7n|TBT7PUFg;jH_(F{3_X{i7__S5uxz4DG0~}mrSuu-$4!!V zYZTX)NCpBw)NGp^@E(U+F=rSKTqq`mL#i7fYp z%g`SbKIKd1HH?q&UKS-`$$jAxrMWM~f%%3c8&VrO zh7nfgu7PpY{LYf}sun-oH8%JiG?_EpvU1WF=`KX5D=RuC@Z7+(8bM>jwuPIqXp)7eA;U0np-Gq3 ztKk*H(AA;zlr)-yQBn-iM+=0()WbveKJ83e8Lh3UW3X@ZCxir9bqr`ok~JCuNZ|qP zVwl83@+feIqE%e?cWCkUBXpji7x;mJ|3n?6r$AAtcc&vj*o`StN0+YJ&?H=G61M-u z@TX&pzD*rr>^xZ;ks0)BKP8J&K{J>op)lsihVTfFX;qoelW&Qh-6gyrk4~Odyu=y? F{sDcla76$B literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker$1.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b819504265285939ff996c50de91affe0a7c8522 GIT binary patch literal 1758 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 Z_PZD(OIV?OnvfKhP^srAJ^Hq$z612)SMvY> literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$2.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$2.class new file mode 100644 index 0000000000000000000000000000000000000000..7ba71cfefd8c3e33604563be076b735022cf7849 GIT binary patch literal 1303 zcmb_b-A)rh6#k~PY`ZOjtsqtWuSlu70+&TXLT#w2goK7f;?1xf+R^Q7vpYrmBtC+- zdPSm%58y)?&uljlgN;pOH`zVsn>puv=kLeQuipV|Vbw+gQx=jrq%h5}>-PG3eQm?x zVJJJQCzRfB`rLiTJEAQ-c`5=aLdW%$4t&qqADz^>tNmbDiq+PzFBqmbrILD!VPU2D zmY;IRDYwNXB_kY;#3S-hT4!JT~y9(MV$C*nXhEZBy5mf_7`qFjtys~wF% zEqlUg`Y!isT#FWI)v*VL>kPxo$+-TzHl=ljYGi2fs7Hv8>V#tXPec@`+HZ#Cb97~sc@PY370fS98 zG8m35vR$s)9u0I|kiC824+2-zrRihg&)s-xxKh7gDA)5tvUnxPAMr@ak!;~A@}yCAxE7m#L>4oI6~4iGU3pwyOwC)xbkROT<}<+w{C4#ua&-dRT#sED zX&wua`vR_$WH=VEh+@R5fEy&GBJ3uXXyMK2E!;*rlJ1a2CX((FHu8LrEV4-AKH&*G dK#Bgz$nV1lS;h+e^MoX@jB+hQ>Cv-2_Y3C-T@e5P literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$3.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/PackageFactory$PackageType$3.class new file mode 100644 index 0000000000000000000000000000000000000000..ea86c825e6701d08dad45a60763cb10f6399f361 GIT binary patch literal 1279 zcmb_b+iuf95IvhFbrPqvB(x+@?x8d-!jwFwRF&#R4GI-fqe}E`>ui$+XC2v_LcWAg z;1!-Kfy4*!QHWW`5}NIKnAl6d){EEpKR0} z9!0XJ214n&GvwZD-Vi_hj2u7hNn$q;K^y>~hGF++OyUO!}h&-MPibp)M`y$eNL8L7_VA#A! zgXuyor9`;n)0Ubd*gq}a_G1)ir_Gb1m$n)Vmq^>d484H0w!VA@_Ax#%PhWGum>1|< zh-C|xQ6!CShbxKuJF?9YR{9L<<@&=~IkRY0vSs@Wxeo-V@FP?`4t0XOIi7?v(ju1P z@FiR&$#5*8j7rR^gli;aV(dDWX|av<25ur7OSi})7fZJZn?$}t9yZdrOLz+RP^Eu5 Zj(a~wROT}R?C@~cAP zj6~ySf0XguuIdb!n7A(4$vyWu=RCdV+^65ZfBFJo9xD?17*>tOjyIRdYI?J2*6jwj zy{xvQ8?W^`-{h9L%UzQ}k!U`gYl3j9~*9`Yd zy-J=F*<%XgBD=g!oSNHu&GL)(D^PrQ(c%V?v`s^xk105g1cQ{UES8=Y%M1^m_l}PY z6@wBI3Wji!A!1mL%^8ML>C!8GSJy1vu4|8LuZU4j#t2SHIIUn5XNcHuK+$eBh~cho zwfN&LhU=-W=w*vqlIwDmJ=e7Bx$X)gfuDa&!8x2~h~`b(^yV3cyHf>`Yw3!F3)Gih zwI!K}AtGZOV-hBNnRhORxQwL8o9<=aYz&Hw6vkwlkShvip@|9c8_;BUm`e9>MyMM< z6Ni_bO&X8mCDZ1QT8$caH^lfdygZ^!>E4YggIaP7-KyxWDGCNv!?xa_;_BhyqPy#D zn{*WMGO2;?wOqo5Qt1jqf1P`4cGJ^sgM4p~AbvPqq42EZ^vnj=d@2Rq;~TU(VzU1V zE&S_|H0YRriPW0C<>W{<@`e>$iWglB#ns98?xg3bl3aFLuEAGK(b>U2rE*r>dLr|P zH@#J-=}A~($p6np6eYOZFg=fNmRmJL$OWg)DQmXPU0*%KvcF5C3m0hYM@ap{3#Wxr z17t~4eM=$=Bu0g55+X|etI!Caq16Og@yL4^_<$2%p}wOP!yNrb{kbT`& zZigA}AV;qvi|ZW_(h#OyU?ln(tQy)ws9X*2K`K`xd(^kXZxcfvw}ap(LGbJW#;fW? zsEv#J2pu3akBkj^86VTOrge!{(g ztCsiX;8^&YVR%(4sp||wrShJO5o8^>dE}61cFb63rYZJ?#pHTubN;6>F}1vOblXXD8XwkyNePc~7IU zpE$Mb2(KCXJZNw&cFDS6_oZ7K<>uAu=!8_%-zqlLQCM>@#;|&|?2B)KA-zVh4C76y z#CET9AfjD<5RhlmRY3#l;t=lqYs9*8O7yq&KP}efuNE&*x1~uTlkgYZiShhbY;*bLS46gXl zrO7i)W+-0DT0-DG-43H9Lq?}bMy}1(VL$`3E-2sK344(*)}+pGy5A!Py7H$%6*};pO#9Ly>Zzv_AwSZnQ)1lnJqlCv8rRULnDNyq; zOzSvV9!W+rQ~3t=#fB$nHDO>3w`k2L8!(9}va%>(nmi`?BY}>REL0Y%<(bU1QyeK~ zi|$PBE1b{dPvHz})?yvOHT!WJcSss-21Scsz+KYJ5evA7`xvs?1JW{9dx%GHtTs!< zj96`sGO|{CLcRofo-%Tj{gnJEJi~L6F4B}yLIqVUl09ebQFx6kdFgvKL9s+u6Zr?S Co6EWY literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/TextMenu.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/control/TextMenu.class new file mode 100644 index 0000000000000000000000000000000000000000..0a984e791733dd895f35ab63cad66a5e39695de9 GIT binary patch literal 8859 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 literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/BookPackage.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/BookPackage.class new file mode 100644 index 0000000000000000000000000000000000000000..01e0c080819eb89029ef2e25aaa2f115a9ccdce8 GIT binary patch literal 1425 zcmb7D>rN9<5dKbSyX{h1EFiQhf`Zb5tbod;hD6&CN$MqnHNjt}+he=5-EDSHQC`IO z7@DXg{O|#MDC6uUv8Ed$Y4*&V>74oI^3AW`=RX1LqNE~%5e3l{Vu&+r>fN4PU)#{Q z;}}h|D@?he^|;>VP02DfpKz_i&8BuB zZNqGqhAoxKk#CenS7=pB=bZ|d;*f5oLM@2|k_yxmMv=N?R!=Rf9b`sX@xE+XHbZte zg#^+J(K@-S1UH_-6=WF{N65p|o?w^?DWp(y8#bB36s|HPq~#aLFu7D1M#xf+XHv)^ z&oJHPZBe#Noy)g|Y?0q>rB3!>0vJwNM z_~)U^#t`>+1O6}T$JC0_AV-1_W!~u=7*doHc)&2q)F<9T?94Ih;J#@JyWF8&7mk8W zhQ*;G!*W-!%`khhD-F&s6!WxP5n2RBA8j+85z=G0M(1_9eL@l{$$W8nr7#nlQgVqi zuwpLx9ZE4f_5+!(-kTeAW)Y=xjDBfMAVZTG$1GW169z@VP0W#WwRu8v5%ai3nv0*u zZ7g8K(-ujKdDCBc9$^bR$o&Cq0dyJw literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.class new file mode 100644 index 0000000000000000000000000000000000000000..6ab09a077bb608b381e51f3bf8eb3d7bdfdef8c6 GIT binary patch literal 1426 zcmbtTZBG+H5Pr6_y|x?_%4<;(6oeM!1XPgvlGsWlsV@;y6a2JXmv-s(uDM%K{)q8s zXrhwv!5`p{GR|EuTGL8m%;k1xW@mSvnP=wvkMnN;9-@#!1brH!I%0@3Y?#fKT3cN= zxaY~5-4wQ3H(K0m@S3O!OP&Z<3eRXdq!=&T_8t4sVTj+Cwp0%pii_nVe!>ll+cjfX zxzer`x-F&Be%q*IQy68(=6xQa=AV^nx_-BryvslZOChhUJ zLe}bvAsIHEs1k4c47zyNB6>yDZx)8^Uwer7-F1##Q*28=v+=I3Sn*LX3_W%n^S0b^UE@o-EA~Xq%ei~<5BP7RgiPp=cy+@Ml zz*K%|IX4*_)3S*(u>5553$%P@;49Lff;(4e%^*svjsf~cFi8BQF-?|N6oX#CRm{-t zOS8BZM4ZBPlKl8nn4_D0fizE2ERb$s0a_p}A{V~mqfF9m8uAe1Cf)P#59ZG>lK%|t u923AtvP9tHiU+470T#XO8Di-}KJZ$?GVKXEyGj2#?vR!u=`J?0h3rp9$aNI} literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/PackageInfo.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/PackageInfo.class new file mode 100644 index 0000000000000000000000000000000000000000..a1c3f03504368058b6b7dd190d11f2f2cc2e0134 GIT binary patch literal 3465 zcmbVPSyL2O6#g#EOb=tLWJD3sh(?qd(1}}IK$JxT1P}!wVzy@H0xdJ$lkP?(`@XML zc}Vh*SM!jEBo&OsLn_btQJU}eG)x17WmzSC?>%#t?=1J+<9`p9{sGX5?-Qs(wT6g} zC}IM&H;r3HCU00Xnafi*W!4jjb(ogvbqZ9sq{eFyM~#Mrj!n=7PGt*4@7U4f8N+qW z8LJ>I?|7zYWao?-nUi_*mUK+%W(qbBnUNB`-8*0?EO$!BNjKt(kUZVvCNg zN`J(%J*fy!=}2OmK(y$XS;~oCMcuArhoZ)AOLJz{Q>2|b8n8>CCNM8^WS&&N?AEad zPYdYsPLYnuT(99#Q$q=XXBK2;(9RlpMIPhH2hyZtpAW=aD9Qx2Jfq_PngzDbNblk* zMU5?~4OJy@2rU{?I?`wrsP~;-Z<4UHcA;oEa*QELwS@F#XC2$JGd=#Y8fU6Mj>AN> zu&{7=Xy|Y**VNZ{wophQgJ(4y)o~2R1@@P1PTNkw@G{GeUhUgS-T&E4OIp9!VqfEfpZ!rhYl%GKzj&G~8MBDlJ=E1*-H^ zF{kWcqkM-9Z{8vBYzTM25~7sz-SNaB?`#)HjN0=~R$eky;nap6xg)B!Nb0t2&-EOm zI3&GUJLhhV;k^Xj#|IidRJZ6O#;#n3rgh7nlbMpArAvIt$a=QJnEe>eM8H^5+Gkj~ zymSu?+Vu7#QlO&8$md5*PqxSL2^|$p%&gnw$b!L< z!J3KVGj@}JYI7FI&C58x5ExWNdbUX4>KPg7!N%RZyT}KC#(1 zTrv_33=5dJSwXn|w>84)io$cq2g02+r7*|Rjf_e;9%_aKP7wP^U&D?P*NWdUKMM*q zN4E+<8rOPpx+0JQtaU(`w7qMAbP-7R20&C9C?I^k0$mpZr*ww1vGpGI-^0PRf$0lr z(^uTmVKcExTX8u#;u!VE7z{hvb{|Iu@8iT!83kgyj)>;+0N8!SwzBbNd^K>YR zTa=kVx-{H=$aF_F!~+s3i1EXJ)%+igS|74>*Kla7Ie4n=Vm20nY#a}= zQIl@{7x8;|X>BSthf1R+@FIdYh_4E7;w^uD8}D$fqX+L&?Z^K2Q~&!pzT__nQoq7C I_zn&K0|9h6i~s-t literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.class new file mode 100644 index 0000000000000000000000000000000000000000..1a5ea69e1ad187c3f0013efefe8ce681da0b8616 GIT binary patch literal 1695 zcmbtU>rxa)6#g1mW_L0Qu7WNxNE8!x6-OloWbwwXh*gWB0)q4YcT{+niVJH6D>6Lw2E+--6#HtAHaZk13($$)9$8(0i?z6cdTjJkZs6&XGT zQ~Val@Gv&OQ2C_YB2E%-a3pUMict%vP-ZY9p*If$k{`?Queue-@r;Erj58FqO8sUy zGgIyNy@+!Rqlfg(uC2|s+f%Eni=Jm<0^b@qZ{a&kGF(i8m_%n+g&x=Thxn`{M=e5z zlG*_#PK2izyew?Mzz&KnpKWA$RS~jCkNUB8pU4&+)EI zg*9#AGJaq<>+wC&P`<nW|MVk9M%17HDsT}nT&vP8@7yVp;^+e_WmB%pDpyFm2 zX-Qu^+4putxEU7{LpkBy;-QSs+2xS#N^<93>#It%PG)`XB}V$1Cw^0L0z6}qFNV@7VWg!%?-65I$}k}9*nOa)pph!*J5i_jLS;tNQXRF z6S}L~(a10sP1Lbu;7*)N>g(x`z@&em_C(g)X?j<zmg5ofGfC4 zdrZyZT4HemHc_$t30%hw3?|e~q6!H$ho4|1)Gfl6YKc*nNSa1khVeeh#rVf-Z*aPN z_AM&4zhS(_g?G3F{7EkZi17`lTnQ#Cqf<^kJv^Y3Nz^i$SV84K D1Om*) literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/Input$1.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/Input$1.class new file mode 100644 index 0000000000000000000000000000000000000000..9975519a8bcf8029fb92a9842fa929e272588ef2 GIT binary patch literal 1602 zcmb7EO>Y}j6g|&&GLAj9Q#VdR8#ksHu$>R*ql6NdLK702;-r-vWx?**evPLc&zPC9 zlS(Z30Z6P75@LtctdQCuv8Y(HqV`bsA)$**7|6{CySF zl}&rq+6q)hV60dQ5xnZVYGCqA$a>%rT>=xhY~l*01mbP!x7XbkGhq0wIIarB8m{|D zAIh6}8`p?Xebtk;PdLT@$0&UnM?oObCEtEqHf$Bgd(=a8p6gi65fo7}P&P4xS%HP~ zGA}R^kmH(cC|h9iEYZ8_Fxa$|-KxehFOZbIpzV5jM|M;K3s^L;WMUcD1;)>C`O;3n z@KvDI*YZ0dt6JKNV}*{@Vb}5==UXyhf;R-rwscxH>C8V+%D}2XF08FQ2r8=2ZmisH z2A1p8EI&|=@&szd^EchuWM6hwX^&+(DO%Q_HxL!xK1f~aV@p|eTng$XmAZRyr(mQWH#3Nme z{J-llpkLrZJ>ae0mfb-niMreKnrhS1xhBG^J+IA(Y{O~VuFslmD|SIk-??ppORvD& z^w=07r1*~VgFCLzvYT5D3$$)?k|-Z}-g6TIA0aY2s;@gh$(h436ycjjmGUN6>y%Nw zQ=WMSQJ#GUqx>t9zk~-r=KnC=02evEfboIxC-{__cB5Si+~zuhQLfhLP-w?OLm1-z zQTZv1V_f_l6Wg;pk(JooG2S}j2R=J|qnKa)i?WdWCwhf)d8Y8^*OY5>ncOj^zegdu z68jlf=Q8hvYBr|T^jzlMP#qpxiDhF?XuxOlM1&}(xSrv=%J||b-p?>@g?>)e4?;D4 zs(wgSCmn@O`WoW=A48HO>>EyzZ!wAQa2Y>v;{1plo?tp8Bp-5jgi}I}@EJBpKoUO@ z%;yAhhkmk%zrYOx6a0x(Dw#{A{^pSww)ioEyZC}K#tBmk8HsRpk2?uE(#7KQFO#2y A`Tzg` literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/Input.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/Input.class new file mode 100644 index 0000000000000000000000000000000000000000..7470d0169f6e6b83c03321bd1dfa29ceca6305a8 GIT binary patch literal 1934 zcmb7FT~ixX7=BLk$u=z^KxwR2N@-1ivgJe31WVggEEp(lkQ(dPCON=DvKu$cS8u)1 zJFk1?rB{x65oXNjj9xkZD97jQrkF6jVKUi0`|kVkywCfbv;X}2+aCb#pr+v*0ucmb z2q7#G-!b+Ly=qun`lHg0EV}~XdDAl8I|6}JdZPzX^hBV=a2~NP_rg)bl{I?Vdkh-P zdx=b2Uvo^$Ex3*}YS}0*3Y=fE>U-{RxoR{T8sg}SAQ3}91_b(F5hM_)s}xm>SyO&m z4byX5y2&agbF>>8wa%M%WH-us~QGXYsqeyUQ`rU1cD{o-i_i70j(|_v$1WI zsxpc<`7En!-LWmR9Kki#?M!~(KFk|O>{7!pt}EU~1unOd83(SOvn|&!E$L*J(i;lI z%^2Q7N}#79T|ZRdN=JZiTQMwSi$SWPu~Rjdb9Sv{v$BRXCREK^0+&+HI_U7n-Ed~`~~95M<(Rv@3spEW_& zYxZQsFBu^qMaugzs(C@6&!|-Hm0k9mHz`O?L13h#5xGyKdbfwy)4kIg${Qu6p}R^$ z56E_>2A0?5p}T0xYDGg1fhayCr%e*$AEp+&(L9l%0E2mtHs2X*Y={ZEz(09dH&M_Ci{?Npg0D zTIkJF(5rj3l62P9HX&JgyKGc9498T@ZDY{gHX9Vj*@w$YHEtRT@&EpP6au0yFwhO$ z+u#HpRJ{><=T2xJ3_NMtdR+H>hPpGH=!Z$vuIL_g0i3KBi@Z=5M)<()!ofF~qNkBrY`3+rnV+7(*-J-*LGZNW4}k1{1FrilM~S z!sloviU^3XkWU)_7#IGLXb`vwoFjpK)((}D0=G!SVp%(5k z_x((`g&Y?jWFkr0hKtEiz|WZsCl;G{n54sGF+Lqndig#|hLYhX@=tk>_;;@${*F(3 z4r{-#ivXVTx{L&`8iMNE!`}cdAcc!Ozk0F256K$(@FhmDjqCUtqj-)R_zpMmJx|{s z==md$iJvisKQWF^nCXen5Q_MePvi>E@EQ3Vz)$!bUy$DvUNGZVtiOP7V4%d>+w?B; vZHP4&C)o9g literal 0 HcmV?d00001 diff --git a/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI$1.class b/out/production/cmpt213-a3/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI$1.class new file mode 100644 index 0000000000000000000000000000000000000000..d9ca48e77d2afca20edc7942f0e9077b727dafa2 GIT binary patch literal 1159 zcmbVLVQxX-Qi^f0oJI z5Kb6piwP-u>A}R21oIdNz@y+tL;L{qBkIkNAm0k!;(uxO2>X zsm|k|rrM6-#grLKwFUzt^1{EoVn`i&ecuu-sS3$lY5g^21y#G{S|i{0M0o1i25QQv zwDQE^pZ2(P4`_y{!}diGZhJwx+b;?6=NWPx~=kfvtIp?D=v{xVM!=!uc?n%J? zJ$K)8!Rg8%lHHbV`8O!UQoR!iv|*`+gpPLT z3j2#Q6@TZBfsEmK*0eoi+WtVMViZpq(`LymTeGHXnO>&o*uLwOGlj5cc(LcO%NEmB zXrDIyobCCBT{IO&Q@#1WXXfluEW>gQojO(^sWAA*rk%CSxy&f37@xE3>DzJ&ZIwl= z2mUT>Lgp$RtA+S@*)d8Qx)qWVg3}pKR?dv>ca0gd4QmzFMZEUZiS6-2{u1cIdWqmA z3aeB3dJM;Xm$PJhCxnJeb!yPHSrt|Vrp;?*WwOmWwqPqwJ<}hz?qf(=Q@Nak zzYCY^xB@AKHS8NUj~mspKU8)+^H9Zf4c~HXI+LQUhBVPMIl+4yZDWQ_jk=^p!!-)K{+cef?nqz|*9xrb6tby5sEiBcMHE8GZXMTyiMGNhl_o8_ zn}J(F+1Nde}T2L@9wBVxp-r9S3oUMWSkj(d%xO)cFBf z4Yw$CH>zQDyvUkRmSG7LFfJq>rcHyRL(WXavFU8!T@DjECdIpUdN)$Ce1q=E*eM-H zM3U>oYt!|uqEQZK-)Fc5r)(9^2)}pgxC?i)kkLhj^lvZJsJ-*6OQPPR!@#jnuX_b{ zP~m}e}Rw&;pW~X(W z!F?gDf@>Z(UDqsyiQgEH#nC}LEIgp&K|B-+c5hMK_&vckTLe=)f`4fEr;bO3*>#Iq z9|}CQ9}%$=8Ouc2KvB#Xb}50!@q~sabv%Wqn>Ma61T5Jn4DZB{Q(^{i>&nT1f9d!) zo~2yPd#gs7!E36P;f|N>JtFz=yp9(n9}=WK3buw96|Vdfl_Fxi3^P+uH&nsnCn|oj|v=SZ)LwDwytZ$DJ{m zqZ=Fex=0k{PC*gcCH0)W*hoPSr#&x=WN6)(txT|Sp9wu?R3Ziw<4)Brn)@x`xO23A z64)+*Vg)*Adj6OxfgsU(&SsGwD)SU%de}tuv_Roi#CXQymdiV&O!A(TV+fy1*v|tO z@Bii3b%8ygr{|&4-#|Nuj<49>g4cMLBN{kooMT_-o6b>k{~!L(r@|YH^L)WMrSE9^ zYjo7GGQEJVspOh@tUHGdY}>Fx{lxzoHpxeF_2@U^6T87Tk@k4bYE9&|73T ziYR!6WQm(2#GIR&$Ia)EUqC^C<>zs0UY-PeTVH2a4Yv!Tz8dbBlxALZ_Gk^o$mn<- z;AU2C@VwHFQ~+%w(zpzL*p7be<^g1wZ^CI;xOfDto2_r+EkbLNO)-M_CfSvU4llr( zN}ig>3=!JIS{dsX4*O#Pd-wJenLEiQZ;E7h?wm)phB<-UFOd64;r$mP+(9CDQW*o( z%T+{pHGhLVpI?I^>(Q9QO|1B~pd=@P35#Lw>gkoy79+SpUJ6 z!T7cs9{Y?2 zE1})U-!OkdUkGj_0>@?X0Y2m;t+e?F9}~ { + JavaSwingUI ui = new JavaSwingUI(); +ui.displayMainPage(); + }); + } +} diff --git a/src/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker.java b/src/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker.java new file mode 100644 index 0000000..57a4487 --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/control/PackageDeliveriesTracker.java @@ -0,0 +1,113 @@ +package cmpt213.assignment3.packagedeliveries.control; + +import cmpt213.assignment3.packagedeliveries.gson.extras.RuntimeTypeAdapterFactory; +import cmpt213.assignment3.packagedeliveries.model.BookPackage; +import cmpt213.assignment3.packagedeliveries.model.ElectronicPackage; +import cmpt213.assignment3.packagedeliveries.model.PackageInfo; +import cmpt213.assignment3.packagedeliveries.model.PerishablePackage; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.TypeAdapter; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import java.io.*; +import java.lang.reflect.Type; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Scanner; + +/** + * It's a class that contains a main method that creates a TextMenu object, loads a list of packages + * from a file, and then loops through a menu of options until the user chooses to quit + */ +public class PackageDeliveriesTracker { + private static final String fileName = "list.json"; + private static final RuntimeTypeAdapterFactory r = RuntimeTypeAdapterFactory.of(PackageInfo.class, "type") + .registerSubtype(BookPackage.class, "book") + .registerSubtype(PerishablePackage.class, "perishable") + .registerSubtype(ElectronicPackage.class, "electronic"); + private static final Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, + new TypeAdapter() { + @Override + public void write(JsonWriter jsonWriter, + LocalDateTime localDateTime) throws IOException { + jsonWriter.value(localDateTime.toString()); + } + + @Override + public LocalDateTime read(JsonReader jsonReader) throws IOException { + return LocalDateTime.parse(jsonReader.nextString()); + } + }).registerTypeAdapterFactory(r).create(); + private static ArrayList packageList = new ArrayList<>(); + + private static PackageDeliveriesTracker instance; + + public static PackageDeliveriesTracker getInstance(){ + if (instance == null){ + instance=new PackageDeliveriesTracker(); + } + return instance; + } + + /** + * It saves the packageList to a file. + */ + public void save() { + try { + Writer w = new FileWriter(fileName); + gson.toJson(packageList, w); + w.flush(); + w.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * It reads the json file, converts it to a list of PackageInfo objects, and then sets the type of + * each object to the appropriate type + */ + public void load() { + File file = new File(fileName); + try { + String json = Files.readString(Paths.get(fileName)); + Type lType = new TypeToken>() { + }.getType(); + packageList = gson.fromJson(json, lType); + for (PackageInfo p : packageList) { + if (p instanceof BookPackage) { + p.setType("book"); + } else if (p instanceof PerishablePackage) { + p.setType("perishable"); + } else if (p instanceof ElectronicPackage) { + p.setType("electronic"); + } + } + System.out.println("packages loaded"); + } catch (FileNotFoundException e) { + System.out.println("no packages to load"); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public String getAllPackages(){ + StringBuilder b= new StringBuilder(); + if (packageList.size() == 0) { + return("No packages to show"); + } else { + Collections.sort(packageList); + for (int i = 0; i < packageList.size(); i++) { + String bString=("Package #" + (i + 1)) + "\n" + packageList.get(i) + "\n"; + b.append(bString); + } + } +return b.toString(); + } +} + diff --git a/src/cmpt213/assignment3/packagedeliveries/control/PackageFactory.java b/src/cmpt213/assignment3/packagedeliveries/control/PackageFactory.java new file mode 100644 index 0000000..593be05 --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/control/PackageFactory.java @@ -0,0 +1,73 @@ +package cmpt213.assignment3.packagedeliveries.control; + +import cmpt213.assignment3.packagedeliveries.model.BookPackage; +import cmpt213.assignment3.packagedeliveries.model.ElectronicPackage; +import cmpt213.assignment3.packagedeliveries.model.PackageInfo; +import cmpt213.assignment3.packagedeliveries.model.PerishablePackage; + +import java.time.LocalDateTime; + +/** + * The PackageFactory class is a factory class that creates a package object based on the type of + * package that is passed in + */ +public class PackageFactory { + /** + * > This function creates a new package object based on the package type + * + * @param type The type of package. + * @param name The name of the package. + * @param notes A string of notes about the package. + * @param price The price of the package + * @param weight The weight of the package in kilograms + * @param delivered Whether or not the package has been delivered + * @param expectDate The date the package is expected to be delivered. + * @param author The author of the book. + * @param expiryDate The date the package expires. + * @param handlingFee The handling fee for the package. + * @return A new instance of the package type. + */ + + public static PackageInfo create(PackageType type, String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectDate, String author, LocalDateTime expiryDate, double handlingFee) { + return type.getInstance(name, notes, price, weight, delivered, expectDate, author, expiryDate, handlingFee); + } + + // Creating an enum called PackageType. + public enum PackageType { + Book { + public PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee) { + return new BookPackage(name, notes, price, weight, delivered, expectedDate, author); + } + }, + + Perishable { + public PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee) { + return new PerishablePackage(name, notes, price, weight, delivered, expectedDate, expiryDate); + } + }, + + Electronic { + public PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee) { + return new ElectronicPackage(name, notes, price, weight, delivered, expectedDate, handlingFee); + } + }; + + /** + * It returns a PackageInfo object. + * + * @param name The name of the package. + * @param notes a string that describes the package + * @param price The price of the package + * @param weight the weight of the package in kg + * @param delivered true if the package has been delivered, false otherwise + * @param expectedDate The date the package is expected to be delivered. + * @param author The name of the author of the book. + * @param expiryDate The date when the package expires. + * @param handlingFee The handling fee for the package. + * @return A package object + */ + + public abstract PackageInfo getInstance(String name, String notes, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author, LocalDateTime expiryDate, double handlingFee); + } + +} \ No newline at end of file diff --git a/src/cmpt213/assignment3/packagedeliveries/control/TextMenu.java b/src/cmpt213/assignment3/packagedeliveries/control/TextMenu.java new file mode 100644 index 0000000..cdedd9a --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/control/TextMenu.java @@ -0,0 +1,280 @@ +package cmpt213.assignment3.packagedeliveries.control; + + +import cmpt213.assignment3.packagedeliveries.model.PackageInfo; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.util.*; + +/** + * It's a class that displays a menu and allows the user to interact with the program + */ +public class TextMenu { + private final String title = "Package Tracker"; + private final String[] options = new String[]{ + "List of all packages", + "Add a package", + "remove a package", + "list overdue packages", + "List upcoming packages", + "mark package as delivered", + "exit"}; + + /** + * This function displays the title of the menu, the current date, and the options available to the + * user + */ + public void display() { + int tag = title.length(); + for (int i = 0; i <= tag + 3; i++) { + System.out.print("#"); + } + System.out.println("\n# " + title + " #"); + for (int i = 0; i <= tag + 3; i++) { + System.out.print("#"); + } + DateFormat today = new SimpleDateFormat("yyy-MM-dd"); + Calendar cal = Calendar.getInstance(); + System.out.println("\nToday is: " + today.format(cal.getTime())); + for (int i = 0; i < options.length; i++) { + System.out.println((i + 1) + ": " + options[i]); + } + } + + /** + * This function takes an ArrayList of PackageInfo objects and prints them out in reverse order + * + * @param packageList The list of packages to be displayed + */ + public void list(ArrayList packageList) { + if (packageList.size() == 0) { + System.out.println("No packages to show"); + } else { + Collections.sort(packageList); + for (int i = 0; i < packageList.size(); i++) { + System.out.println("Package #" + (i + 1)); + System.out.println(packageList.get(i) + "\n"); + } + } + } + + /** + * This function allows the user to add a package to the list of packages + * + * @param packageList the list of packages + */ + public void add(ArrayList packageList) { + Scanner scan = new Scanner(System.in); + int itemType; + do { + System.out.println("please select (1) book, (2) perishable, or (3) electronic package"); + itemType = Integer.parseInt(scan.nextLine()); + } + while (itemType < 1 || itemType > 3); + PackageFactory.PackageType pType = PackageFactory.PackageType.Book; + String author = ""; + LocalDateTime expiryDate = LocalDateTime.now(); + double handlingFee = 0.0; + String pName; + do { + System.out.println("enter a valid package name:"); + pName = scan.nextLine(); + } + while (pName.length() == 0); + System.out.println("notes:"); + String pNotes = scan.nextLine(); + boolean checkDate = false; + DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm"); + LocalDateTime pDate = LocalDateTime.now(); + while (checkDate == false) { + try { + System.out.println("enter date as yyyy-mm-dd hh:mm:"); + pDate = LocalDateTime.parse(scan.nextLine(), format); + checkDate = true; + } catch (DateTimeParseException e) { + System.out.println("invalid date format"); + } + } + double pPrice; + do { + System.out.println("enter price:"); + pPrice = Double.parseDouble(scan.nextLine()); + } + while (pPrice < 0); + double pWeight; + do { + System.out.println("enter weight:"); + pWeight = Double.parseDouble(scan.nextLine()); + } + while (pWeight <= 0); + switch (itemType) { + case 1: + do { + System.out.println("enter author"); + author = scan.nextLine(); + } + while (author.length() == 0); + break; + case 2: + boolean checkExpDate = false; + while (checkExpDate == false) { + try { + System.out.println("enter expiry date as yyyy-mm-dd hh:mm"); + expiryDate = LocalDateTime.parse(scan.nextLine(), format); + checkExpDate = true; + } catch (DateTimeParseException e) { + System.out.println("invalid date format"); + } + } + pType = PackageFactory.PackageType.Perishable; + break; + case 3: + do { + System.out.println("enter handling fee"); + handlingFee = Double.parseDouble(scan.nextLine()); + } + while (handlingFee <= 0); + pType = PackageFactory.PackageType.Electronic; + break; + } + PackageInfo p = PackageFactory.create(pType, pName, pNotes, pPrice, pWeight, false, pDate, author, expiryDate, handlingFee); + packageList.add(p); + System.out.println(pName + " has been added to the list!"); + } + + /** + * This function takes in an ArrayList of PackageInfo objects and prints out the list of packages + * in the ArrayList. The user is then prompted to enter the number of the package they want to + * remove. If the user enters a number that is not in the list, the user is prompted to enter a + * number again. If the user enters 0, the function returns without removing anything. If the user + * enters a number that is in the list, the package is removed from the list and the user is + * notified + * + * @param packageList the list of packages to be displayed + */ + public void remove(ArrayList packageList) { + this.list(packageList); + if (packageList.size() == 0) { + return; + } + Scanner scan = new Scanner(System.in); + int n; + do { + System.out.println("enter item number you want to remove (0 to cancel):"); + n = scan.nextInt(); + } + while (n < 0 || n > packageList.size()); + if (n > 0) { + System.out.println(packageList.get(n - 1).getName() + " has been removed from the list."); + packageList.remove(n - 1); + } + } + + /** + * This function takes in a list of packages, a boolean for whether or not the user wants to see + * packages that are due, and a boolean for whether or not the user wants to see all packages. It + * then returns a list of packages that are sorted by their expected delivery date + * + * @param pList the list of packages to be sorted + * @param due true if you want to sort the list by due date, false if you want to sort the list by + * expected date + * @return An ArrayList of PackageInfo objects. + */ + //due=true returns overdue packages, else upcoming packages + public ArrayList sortList(ArrayList pList, boolean due) { + ArrayList sortedList = new ArrayList<>(); + LocalDateTime today = LocalDateTime.now(); + DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm"); + today.format(format); + for (int i = 0; i < pList.size(); i++) { + PackageInfo p = pList.get(i); + if (!p.getDelivered()) { + if (due && today.isAfter(p.getExpectedDate())) { + sortedList.add(p); + } else if (!due && today.isBefore(p.getExpectedDate())) { + sortedList.add(p); + } + } + } + Collections.sort(sortedList); + return sortedList; + } + + /** + * This function takes in a list of packages and returns a list of packages that are overdue + * + * @param packageList the list of packages to be sorted + */ + public void overDueList(ArrayList packageList) { + ArrayList overdue = sortList(packageList, true); + if (overdue.size() == 0) { + System.out.println("no overdue packages to show"); + return; + } + this.list(overdue); + } + + /** + * This function takes in a list of packages and prints out the packages that are upcoming + * + * @param packageList the list of packages to be sorted + */ + public void upcomingList(ArrayList packageList) { + ArrayList upcoming = sortList(packageList, false); + if (upcoming.size() == 0) { + System.out.println("no upcoming packages to show"); + return; + } + this.list(upcoming); + } + + /** + * This function takes a list of packages and returns a list of packages that have not been + * delivered + * + * @param packageList The list of packages to be filtered + * @return An ArrayList of PackageInfo objects that have not been delivered. + */ + public ArrayList getUndelivered(List packageList) { + ArrayList undelivered = new ArrayList<>(); + for (int i = 0; i < packageList.size(); i++) { + if (packageList.get(i).getDelivered() == false) { + undelivered.add(packageList.get(i)); + } + } + return undelivered; + } + + /** + * This function takes a list of packages and prints out the undelivered packages, then asks the + * user to select a package to mark as delivered + * + * @param packageList the list of packages to be marked as delivered + */ + public void markDelivered(ArrayList packageList) { + ArrayList undelivered = getUndelivered(packageList); + if (undelivered.size() == 0) { + System.out.println("No undelivered packages to show"); + return; + } + this.list(undelivered); + Scanner scan = new Scanner(System.in); + int n; + do { + System.out.println("enter item number you want to mark delivered (0 to cancel):"); + n = scan.nextInt(); + } + while (n < 0 || n > undelivered.size()); + if (n > 0) { + PackageInfo p = undelivered.get(n - 1); + packageList.get(packageList.indexOf(p)).setDelivered(true); + System.out.println(p.getName() + " has been delivered."); + } + } + + +} diff --git a/src/cmpt213/assignment3/packagedeliveries/gson/extras/RuntimeTypeAdapterFactory.java b/src/cmpt213/assignment3/packagedeliveries/gson/extras/RuntimeTypeAdapterFactory.java new file mode 100644 index 0000000..4ee4bc1 --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/gson/extras/RuntimeTypeAdapterFactory.java @@ -0,0 +1,256 @@ +package cmpt213.assignment3.packagedeliveries.gson.extras; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Adapts values whose runtime type may differ from their declaration type. This + * is necessary when a field's type is not the same type that GSON should create + * when deserializing that field. For example, consider these types: + *
   {@code
+ *   abstract class Shape {
+ *     int x;
+ *     int y;
+ *   }
+ *   class Circle extends Shape {
+ *     int radius;
+ *   }
+ *   class Rectangle extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Diamond extends Shape {
+ *     int width;
+ *     int height;
+ *   }
+ *   class Drawing {
+ *     Shape bottomShape;
+ *     Shape topShape;
+ *   }
+ * }
+ *

Without additional type information, the serialized JSON is ambiguous. Is + * the bottom shape in this drawing a rectangle or a diamond?

   {@code
+ *   {
+ *     "bottomShape": {
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * This class addresses this problem by adding type information to the + * serialized JSON and honoring that type information when the JSON is + * deserialized:
   {@code
+ *   {
+ *     "bottomShape": {
+ *       "type": "Diamond",
+ *       "width": 10,
+ *       "height": 5,
+ *       "x": 0,
+ *       "y": 0
+ *     },
+ *     "topShape": {
+ *       "type": "Circle",
+ *       "radius": 2,
+ *       "x": 4,
+ *       "y": 1
+ *     }
+ *   }}
+ * Both the type field name ({@code "type"}) and the type labels ({@code + * "Rectangle"}) are configurable. + * + *

Registering Types

+ * Create a {@code cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory} by passing the base type and type field + * name to the {@link #of} factory method. If you don't supply an explicit type + * field name, {@code "type"} will be used.
   {@code
+ *   cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory shapeAdapterFactory
+ *       = cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory.of(Shape.class, "type");
+ * }
+ * Next register all of your subtypes. Every subtype must be explicitly + * registered. This protects your application from injection attacks. If you + * don't supply an explicit type label, the type's simple name will be used. + *
   {@code
+ *   shapeAdapterFactory.registerSubtype(Rectangle.class, "Rectangle");
+ *   shapeAdapterFactory.registerSubtype(Circle.class, "Circle");
+ *   shapeAdapterFactory.registerSubtype(Diamond.class, "Diamond");
+ * }
+ * Finally, register the type adapter factory in your application's GSON builder: + *
   {@code
+ *   Gson gson = new GsonBuilder()
+ *       .registerTypeAdapterFactory(shapeAdapterFactory)
+ *       .create();
+ * }
+ * Like {@code GsonBuilder}, this API supports chaining:
   {@code
+ *   cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory shapeAdapterFactory = cmpt213.assignment2.packagedeliveriestracker.gson.extras.RuntimeTypeAdapterFactory.of(Shape.class)
+ *       .registerSubtype(Rectangle.class)
+ *       .registerSubtype(Circle.class)
+ *       .registerSubtype(Diamond.class);
+ * }
+ * + *

Serialization and deserialization

+ * In order to serialize and deserialize a polymorphic object, + * you must specify the base type explicitly. + *
   {@code
+ *   Diamond diamond = new Diamond();
+ *   String json = gson.toJson(diamond, Shape.class);
+ * }
+ * And then: + *
   {@code
+ *   Shape shape = gson.fromJson(json, Shape.class);
+ * }
+ */ +public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory { + private final Class baseType; + private final String typeFieldName; + private final Map> labelToSubtype = new LinkedHashMap<>(); + private final Map, String> subtypeToLabel = new LinkedHashMap<>(); + private final boolean maintainType; + + private RuntimeTypeAdapterFactory(Class baseType, String typeFieldName, boolean maintainType) { + if (typeFieldName == null || baseType == null) { + throw new NullPointerException(); + } + this.baseType = baseType; + this.typeFieldName = typeFieldName; + this.maintainType = maintainType; + } + + /** + * Creates a new runtime type adapter using for {@code baseType} using {@code + * typeFieldName} as the type field name. Type field names are case sensitive. + * {@code maintainType} flag decide if the type will be stored in pojo or not. + */ + public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName, boolean maintainType) { + return new RuntimeTypeAdapterFactory<>(baseType, typeFieldName, maintainType); + } + + /** + * Creates a new runtime type adapter using for {@code baseType} using {@code + * typeFieldName} as the type field name. Type field names are case sensitive. + */ + public static RuntimeTypeAdapterFactory of(Class baseType, String typeFieldName) { + return new RuntimeTypeAdapterFactory<>(baseType, typeFieldName, false); + } + + /** + * Creates a new runtime type adapter for {@code baseType} using {@code "type"} as + * the type field name. + */ + public static RuntimeTypeAdapterFactory of(Class baseType) { + return new RuntimeTypeAdapterFactory<>(baseType, "type", false); + } + + /** + * Registers {@code type} identified by {@code label}. Labels are case + * sensitive. + * + * @throws IllegalArgumentException if either {@code type} or {@code label} + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type, String label) { + if (type == null || label == null) { + throw new NullPointerException(); + } + if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) { + throw new IllegalArgumentException("types and labels must be unique"); + } + labelToSubtype.put(label, type); + subtypeToLabel.put(type, label); + return this; + } + + /** + * Registers {@code type} identified by its {@link Class#getSimpleName simple + * name}. Labels are case sensitive. + * + * @throws IllegalArgumentException if either {@code type} or its simple name + * have already been registered on this type adapter. + */ + public RuntimeTypeAdapterFactory registerSubtype(Class type) { + return registerSubtype(type, type.getSimpleName()); + } + + @Override + public TypeAdapter create(Gson gson, TypeToken type) { + if (type.getRawType() != baseType) { + return null; + } + + final TypeAdapter jsonElementAdapter = gson.getAdapter(JsonElement.class); + final Map> labelToDelegate = new LinkedHashMap<>(); + final Map, TypeAdapter> subtypeToDelegate = new LinkedHashMap<>(); + for (Map.Entry> entry : labelToSubtype.entrySet()) { + TypeAdapter delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue())); + labelToDelegate.put(entry.getKey(), delegate); + subtypeToDelegate.put(entry.getValue(), delegate); + } + + return new TypeAdapter() { + @Override + public R read(JsonReader in) throws IOException { + JsonElement jsonElement = jsonElementAdapter.read(in); + JsonElement labelJsonElement; + if (maintainType) { + labelJsonElement = jsonElement.getAsJsonObject().get(typeFieldName); + } else { + labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName); + } + + if (labelJsonElement == null) { + throw new JsonParseException("cannot deserialize " + baseType + + " because it does not define a field named " + typeFieldName); + } + String label = labelJsonElement.getAsString(); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) labelToDelegate.get(label); + if (delegate == null) { + throw new JsonParseException("cannot deserialize " + baseType + " subtype named " + + label + "; did you forget to register a subtype?"); + } + return delegate.fromJsonTree(jsonElement); + } + + @Override + public void write(JsonWriter out, R value) throws IOException { + Class srcType = value.getClass(); + String label = subtypeToLabel.get(srcType); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType); + if (delegate == null) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + "; did you forget to register a subtype?"); + } + JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); + + if (maintainType) { + jsonElementAdapter.write(out, jsonObject); + return; + } + + JsonObject clone = new JsonObject(); + + if (jsonObject.has(typeFieldName)) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + " because it already defines a field named " + typeFieldName); + } + clone.add(typeFieldName, new JsonPrimitive(label)); + + for (Map.Entry e : jsonObject.entrySet()) { + clone.add(e.getKey(), e.getValue()); + } + jsonElementAdapter.write(out, clone); + } + }.nullSafe(); + } +} \ No newline at end of file diff --git a/src/cmpt213/assignment3/packagedeliveries/model/BookPackage.java b/src/cmpt213/assignment3/packagedeliveries/model/BookPackage.java new file mode 100644 index 0000000..35afc2c --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/model/BookPackage.java @@ -0,0 +1,23 @@ +package cmpt213.assignment3.packagedeliveries.model; + +import java.time.LocalDateTime; + +/** + * It's a subclass of PackageInfo that adds an author field + */ +public class BookPackage extends PackageInfo { + String author; + + public BookPackage(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate, String author) { + + super(name, note, price, weight, delivered, expectedDate); + this.author = author; + this.setType("book"); + } + + @Override + public String toString() { + return super.toString() + "\nAuthor: " + author; + } +} + diff --git a/src/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.java b/src/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.java new file mode 100644 index 0000000..21b270d --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/model/ElectronicPackage.java @@ -0,0 +1,21 @@ +package cmpt213.assignment3.packagedeliveries.model; + +import java.time.LocalDateTime; + +/** + * ElectronicPackage is a subclass of PackageInfo that adds a handlingFee attribute + */ +public class ElectronicPackage extends PackageInfo { + double handlingFee; + + public ElectronicPackage(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate, double handlingFee) { + super(name, note, price, weight, delivered, expectedDate); + this.handlingFee = handlingFee; + this.setType("electronic"); + } + + @Override + public String toString() { + return super.toString() + "\nHandling fee: " + handlingFee; + } +} diff --git a/src/cmpt213/assignment3/packagedeliveries/model/PackageInfo.java b/src/cmpt213/assignment3/packagedeliveries/model/PackageInfo.java new file mode 100644 index 0000000..0077cb5 --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/model/PackageInfo.java @@ -0,0 +1,85 @@ +package cmpt213.assignment3.packagedeliveries.model; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; + +import static java.lang.Math.abs; + +/** + * PackageInfo is a class that contains information about a package + */ + +public class PackageInfo implements Comparable { + private final String name; + private final String note; + private final double price; + private final double weight; + private final LocalDateTime expectedDate; + private boolean delivered; + private String type; + + public PackageInfo(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate) { + this.name = name; + this.note = note; + this.price = price; + this.weight = weight; + this.delivered = delivered; + this.expectedDate = expectedDate; + } + + /** + * This function returns the name of the person. + * + * @return The name of the person. + */ + public String getName() { + return name; + } + + + public boolean getDelivered() { + return delivered; + } + + /** + * This function sets the value of the delivered variable to the value of the delivered parameter. + * + * @param delivered This is a boolean value that indicates whether the message has been delivered + * to the recipient. + */ + public void setDelivered(boolean delivered) { + this.delivered = delivered; + } + + public LocalDateTime getExpectedDate() { + return expectedDate; + } + + /** + * This function sets the type of the object to the type passed in as a parameter + * + * @param type The type of the event. + */ + public void setType(String type) { + this.type = type; + } + + // Comparing the expected date of the package to the expected date of the package passed in as a + // parameter. + @Override + public int compareTo(PackageInfo p) { + return this.expectedDate.compareTo(p.getExpectedDate()); + } + + // Overriding the toString method. + @Override + public String toString() { + DateTimeFormatter format = DateTimeFormatter.ofPattern("yyy-MM-dd HH:mm"); + LocalDateTime today = LocalDateTime.now(); + today.format(format); + long diff = ChronoUnit.DAYS.between(today, expectedDate); + String isDelivered = delivered ? "yes" : "no"; + return "Name: " + name + "\n" + "Notes: " + note + "\n" + "Price: " + price + "\n" + "Weight: " + weight + "\n" + "Expected Delivery Date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expectedDate) + "\n" + "Delivered? " + isDelivered + "\n" + ((diff > 0 && !delivered) ? diff + " days remaining" : abs(diff) + " days overdue"); + } +} diff --git a/src/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.java b/src/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.java new file mode 100644 index 0000000..1b58f35 --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/model/PerishablePackage.java @@ -0,0 +1,24 @@ +package cmpt213.assignment3.packagedeliveries.model; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * It's a subclass of PackageInfo that adds an expiry date + */ +public class PerishablePackage extends PackageInfo { + LocalDateTime expiryDate; + + // It's a constructor that initializes the object with the given parameters. + public PerishablePackage(String name, String note, double price, double weight, boolean delivered, LocalDateTime expectedDate, LocalDateTime expiryDate) { + super(name, note, price, weight, delivered, expectedDate); + this.expiryDate = expiryDate; + this.setType("perishable"); + } + + // It's a method that returns a string representation of the object. + @Override + public String toString() { + return super.toString() + "\nExpiry date: " + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").format(expiryDate); + } +} diff --git a/src/cmpt213/assignment3/packagedeliveries/view/Input.java b/src/cmpt213/assignment3/packagedeliveries/view/Input.java new file mode 100644 index 0000000..3549f4a --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/view/Input.java @@ -0,0 +1,46 @@ +package cmpt213.assignment3.packagedeliveries.view; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class Input { + JTextField typeLabel; + public Input(Frame main){ + JPanel p = new JPanel(); + String[] type={"book", "perishable", "electronic"}; + p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); + JComboBox packageType=new JComboBox<>(type); + packageType.setPreferredSize(new Dimension(300, 30)); + packageType.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + String p=(String) packageType.getSelectedItem(); + switch (p){ + case "book": + typeLabel.setText("author name"); + break; + case "perishable": + typeLabel.setText("expiry date"); + break; + case "electronic": + typeLabel.setText("handling fee"); + } + } + }); + +JPanel name=new JPanel(); +JLabel nameLabel=new JLabel(); +JTextField namefield= new JTextField(); +name.setLayout(new BoxLayout(name, BoxLayout.X_AXIS)); +nameLabel.setText("name:"); +nameLabel.setPreferredSize(new Dimension(50, 25)); +name.add(nameLabel); + name.add(namefield); + name.setPreferredSize(new Dimension(200, 50)); + + + } + +} diff --git a/src/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI.java b/src/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI.java new file mode 100644 index 0000000..8a5176e --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/view/JavaSwingUI.java @@ -0,0 +1,73 @@ +package cmpt213.assignment3.packagedeliveries.view; + +import cmpt213.assignment3.packagedeliveries.control.PackageDeliveriesTracker; +import com.sun.tools.jconsole.JConsoleContext; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Objects; + +public class JavaSwingUI implements ActionListener { + JFrame uiFrame; + JTextPane uiPane; + private final PackageDeliveriesTracker pTracker=PackageDeliveriesTracker.getInstance(); + + public void displayMainPage(){ + pTracker.load(); + uiFrame=new JFrame("package deliveries tracker"); + uiFrame.setSize(500, 500); + uiFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + uiFrame.setLayout(new BoxLayout(uiFrame.getContentPane(), BoxLayout.Y_AXIS)); + uiFrame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + pTracker.save(); + super.windowClosing(e); + uiFrame.dispose(); + } + }); + uiFrame.setVisible(true); + displayPackages(); + addButton(); + } + + private void displayPackages(){ + uiPane=new JTextPane(); + JScrollPane scrollView=new JScrollPane(uiPane); + uiPane.setEditable(false); + scrollView.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + uiFrame.add(scrollView); + uiPane.setText(pTracker.getAllPackages()); + uiPane.setCaretPosition(0); + } + + private void addButton(){ + JButton add=new JButton("add a package"); + JPanel addPanel=new JPanel(); + addPanel.setLayout(new BoxLayout(addPanel, BoxLayout.X_AXIS)); + addPanel.add(add); + addPanel.setPreferredSize(new Dimension(500, 50)); + uiFrame.add(addPanel); + add.addActionListener(this); + } + + + @Override + public void actionPerformed(ActionEvent e) { + String actionString= e.getActionCommand(); + switch (actionString){ + case "add a package": + addPackage(); + break; + } + + } + + private void addPackage(){ +new Input(uiFrame); + } +} diff --git a/src/cmpt213/assignment3/packagedeliveries/view/package-info.java b/src/cmpt213/assignment3/packagedeliveries/view/package-info.java new file mode 100644 index 0000000..e66ca18 --- /dev/null +++ b/src/cmpt213/assignment3/packagedeliveries/view/package-info.java @@ -0,0 +1 @@ +package cmpt213.assignment3.packagedeliveries.view; \ No newline at end of file