From 28ad2b878f1a21d03879e81cd441d0175d89e6b1 Mon Sep 17 00:00:00 2001 From: damithc Date: Mon, 25 May 2020 00:58:18 +0800 Subject: [PATCH 01/57] Add Gradle support --- build.gradle | 41 +++++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 183 +++++++++++++++++++++++ gradlew.bat | 103 +++++++++++++ text-ui-test/runtest.sh | 0 6 files changed, 332 insertions(+) create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat mode change 100644 => 100755 text-ui-test/runtest.sh diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..885198fcfa --- /dev/null +++ b/build.gradle @@ -0,0 +1,41 @@ +plugins { + id 'java' + id 'application' + id 'com.github.johnrengelman.shadow' version '5.1.0' +} + +repositories { + mavenCentral() +} + +dependencies { + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' +} + +test { + useJUnitPlatform() + + testLogging { + events "passed", "skipped", "failed" + + showExceptions true + exceptionFormat "full" + showCauses true + showStackTraces true + showStandardStreams = false + } +} + +application { + mainClassName = "seedu.duke.Duke" +} + +shadowJar { + archiveBaseName = "duke" + archiveClassifier = null +} + +run{ + standardInput = System.in +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..f3d88b1c2faf2fc91d853cd5d4242b5547257070 GIT binary patch literal 58695 zcma&OV~}Oh(k5J8>Mq;vvTfV8ZQE5{wr$(iDciPf+tV}m-if*I+;_h3N1nY;M6TF7 zBc7A_WUgl&IY|&uNFbnJzkq;%`2QLZ5b*!{1OkHidzBVe;-?mu5upVElKVGD>pC88 zzP}E3wRHBgaO?2nzdZ5pL;m-xf&RU>buj(E-s=DK zf%>P9se`_emGS@673tqyT^;o8?2H}$uO&&u^TlmHfPgSSfPiTK^AZ7DTPH`Szw4#- z&21E&^c|dx9f;^@46XDX9itS+ZRYuqx#wG*>5Bs&gxwSQbj8grds#xkl;ikls1%(2 zR-`Tn(#9}E_aQ!zu~_iyc0gXp2I`O?erY?=JK{M`Ew(*RP3vy^0=b2E0^PSZgm(P6 z+U<&w#)I=>0z=IC4 zh4Q;eq94OGttUh7AGWu7m){;^Qk*5F6eTn+Ky$x>9Ntl~n0KDzFmB0lBI6?o!({iX zQt=|-9TPjAmCP!eA{r|^71cIvI(1#UCSzPw(L2>8OG0O_RQeJ{{MG)tLQ*aSX{AMS zP-;|nj+9{J&c9UV5Ww|#OE*Ah6?9WaR?B04N|#`m0G-IqwdN~Z{8)!$@UsK>l9H81 z?z`Z@`dWZEvuABvItgYLk-FA(u-$4mfW@2(Eh(9fe`5?WUda#wQa54 z3dXE&-*@lsrR~U#4NqkGM7Yu4#pfGqAmxmGr&Ep?&MwQ9?Z*twtODbi;vK|nQ~d_N z;T5Gtj_HZKu&oTfqQ~i`K!L||U1U=EfW@FzKSx!_`brOs#}9d(!Cu>cN51(FstP_2dJh>IHldL~vIwjZChS-*KcKk5Gz zyoiecAu;ImgF&DPrY6!68)9CM-S8*T5$damK&KdK4S6yg#i9%YBH>Yuw0f280eAv3 za@9e0+I>F}6&QZE5*T8$5__$L>39+GL+Q(}j71dS!_w%B5BdDS56%xX1~(pKYRjT; zbVy6V@Go&vbd_OzK^&!o{)$xIfnHbMJZMOo``vQfBpg7dzc^+&gfh7_=oxk5n(SO3 zr$pV6O0%ZXyK~yn++5#x`M^HzFb3N>Vb-4J%(TAy#3qjo2RzzD*|8Y} z7fEdoY5x9b3idE~-!45v?HQ$IQWc(c>@OZ>p*o&Om#YU904cMNGuEfV=7=&sEBWEO z0*!=GVSv0>d^i9z7Sg{z#So+GM2TEu7$KXJ6>)Bor8P5J(xrxgx+fTLn1?Jlotz*U z(ekS*a2*ml5ft&R;h3Gc2ndTElB!bdMa>UptgIl{pA+&b+z_Y&aS7SWUlwJf-+PRv z$#v|!SP92+41^ppe}~aariwztUtwKA8BBLa5=?j3@~qHfjxkvID8CD`t5*+4s|u4T zLJ9iEfhO4YuAl$)?VsWcln|?(P=CA|!u}ab3c3fL8ej9fW;K|@3-c@y4I;^8?K!i0 zS(5Cm#i85BGZov}qp+<-5!Fh+KZev3(sA2D_4Z~ZLmB5B$_Yw2aY{kA$zuzggbD{T zE>#yd3ilpjM4F^dmfW#p#*;@RgBg{!_3b6cW?^iYcP!mjj!}pkNi{2da-ZCD2TKKz zH^x^+YgBb=dtg@_(Cy33D|#IZ&8t?w8$E8P0fmX#GIzq~w51uYmFs{aY76e0_~z2M z(o%PNTIipeOIq(H5O>OJ*v8KZE>U@kw5(LkumNrY>Rv7BlW7{_R9v@N63rK)*tu|S zKzq|aNs@81YUVZ5vm>+pc42CDPwQa>oxrsXkRdowWP!w?=M(fn3y6frEV*;WwfUV$s31D!S_;_~E@MEZ>|~wmIr05#z2J+& zBme6rnxfCp&kP@sP)NwG>!#WqzG>KN7VC~Gdg493So%%-P%Rk!<|~-U|L3VASMj9K zk(Pfm1oj~>$A>MFFdAC8M&X0i9-cV7Q($(R5C&nR5RH$T&7M=pCDl`MpAHPOha!4r zQnYz$7B1iLK$>_Ai%kZQaj-9)nH$)tESWUSDGs2|7plF4cq1Oj-U|+l4Ga}>k!efC z*ecEudbliG+%wI8J#qI!s@t%0y9R$MBUFB)4d47VmI`FjtzNd_xit&l1T@drx z&4>Aj<2{1gUW8&EihwT1mZeliwrCN{R|4@w4@@Btov?x5ZVzrs&gF0n4jGSE33ddUnBg_nO4Zw)yB$J-{@a8 z);m%fvX2fvXxogriNb}}A8HxA)1P-oK+Da4C3pofK3>U_6%DsXFpPX}3F8O`uIpLn zdKjq(QxJTJ4xh->(=lxWO#^XAa~<7UxQl8~8=izS!TcPmAiBP5Et7y?qEbFd9Q=%IJ;%Kn$lto-~3`}&`x=AVS+Uo7N*hbUxhqVH_w^sn!74z{Ka#*U6s z=8jIrHpUMBC@@9Jn~GS<$lse*EKuX%3Swl5&3~GiK_$vn8Vjqe{mjhBlH}m4I8qK+ ztU50COh7)d-gXpq-|}T;biGa^e=VjxjjFuoGIA8`2jJ}wNBRcsx24?7lJ7W4ksNPv zA7|gcXT@~7KTID#0|EX#OAXvgaBJ8Jg!7X#kc1^Tvl;I(=~(jtn-(5bhB=~J^w5bw z8^Hifeupm;nwsSDkT{?x?E(DgLC~Nh8HKQGv`~2jMYrz9PwS^8qs3@nz4ZBCP5}%i z=w}jr2*$X-f(zDhu%D8(hWCpix>TQpi{e`-{p^y?x4?9%)^wWc?L}UMcfp~lL|;g) zmtkcXGi9#?cFOQQi_!Z8b;4R%4y{$SN~fkFedDJ&3eBfHg|DRSx09!tjoDHgD510Z z_aJLHdS&7;Dl;X|WBVyl_+d+2_MK07^X1JEi_)v$Z*ny-()VrD6VWx|Un{)gO0*FQ zX{8Ss3JMrV15zXyfCTsVO@hs49m&mN(QMdL3&x@uQqOyh2gnGJYocz0G=?BX7qxA{ zXe0bn4ij^;wfZfnRlIYkWS^usYI@goI9PccI>}Ih*B!%zv6P$DoXsS%?G)|HHevkG z>`b#vtP=Lx$Ee(t??%_+jh(nuc0Q&mCU{E3U z1NqNK!XOE#H2Pybjg0_tYz^bzX`^RR{F2ML^+<8Q{a;t(#&af8@c6K2y2m zP|parK=qf`I`#YxwL=NTP>tMiLR(d|<#gEu=L-c!r&(+CpSMB5ChYW1pUmTVdCWw|!Ao?j&-*~50S`=) z9#Knf7GPA19g%Y7wip@`nj$aJcV|SakXZ*Q2k$_SZlNMx!eY8exF;navr&R)?NO9k z#V&~KLZ0c9m|Mf4Gic}+<=w9YPlY@|Pw*z?70dwOtb<9-(0GOg>{sZaMkZc9DVk0r zKt%g5B1-8xj$Z)>tWK-Gl4{%XF55_Ra3}pSY<@Y&9mw`1jW8|&Zm{BmHt^g=FlE{` z9Lu7fI2v3_0u~apyA;wa|S4NaaG>eHEw&3lNFVd_R9E=Y? zgpVQxc9{drFt2pP#ZiN~(PL%9daP4pWd*5ABZYK{a@e&Vb`TYiLt$1S>KceK36Ehz z;;MI%V;I`#VoSVAgK3I%-c>ViA>nt=5EZ zjr$Jv~$_vg<$q<@CpZ1gdqP_3v^)uaqZ`?RS_>f(pWx3(H;gWpjR?W8L++YPW;)Vw3)~tozdySrB3A2;O<%1F8?Il4G|rO0mEZYHDz!?ke!$^bEiWRC1B%j~ws0+hHS;B8l5Wh)e+Ms7f4M4CbL%Q_*i~cP}5-B(UkE&f7*pW6OtYk5okQCEoN4v|7;(+~~nyViqo5 z(bMGQi$)KN6EmfVHv4pf2zZMJbcAKyYy>jY@>LB5eId|2Vsp{>NMlsee-tmh({;@b z@g;wiv8@a1qrDf-@7$(MR^M^*dKYBewhIDFX%;*8s zR#u?E;DJO;VnTY6IfbO=dQ61V0DisUAs4~t|9`9ZE(jG}ax#-xikDhsO_4^RaK ziZ?9AJQP_{9WuzVk^s_U+3V8gOvVl5(#1>}a|RL>};+uJB%nQM-J>M4~yK)cioytFXtnmOaJZSiE+3g}C`Im~6H z*+-vjI>ng5w>>Y!L(+DwX2gs0!&-BFEaDie4i5ln*NGP$te7$F9iUlJl4`XpkAsPm z0l?GQ17uN^=g~u1*$)S`30xL%!`LW*flwT*#svAtY(kHXFfvA`dj*pDfr0pBZ`!La zWmX$Z@qyv|{nNsRS|+CzN-Pvb>47HEDeUGFhpp5C_NL0Vp~{Wc{bsm_5J!#tuqW@? z)Be zb&Gj&(l*bHQDq7w-b`F9MHEH*{Dh~0`Gn8t`pz}!R+q~4u$T@cVaUu`E^%0f-q*hM z1To6V31UGJN7a-QW5;nhk#C26vmHyjTVZkdV zqYMI9jQY)3oZt=V0L7JZQ=^c2k){Y_lHp&V_LIi*iX^Ih3vZ_K<@Di(hY<&g^f?c$wwF-wX1VLj>ZC4{0#e`XhbL_$a9uXS zKph*4LupSV2TQBCJ4AfOXD8fs2;bAGz-qU4=Qj$^1ZJX z2TtaVdq>OjaWGvv9)agwV)QW9eTZ-xv`us2!yXSARnD5DwX_Vg*@g4w!-zT|5<}-7 zsnllGRQz>k!LwdU`|i&!Bw^W7CTUU3x`Zg8>XgHj=bo!cd<#pI8*pa*1N`gg~I0ace!wzZoJ)oGScm~D_Sc;#wFed zUo;-*0LaWVCC2yqr6IbeW3`hvXyMfAH94qP2|cN``Z%dSuz8HcQ!WT0k38!X34<6l zHtMV%4fH5<6z-lYcK;CTvzzT6-^xSP>~a*8LfbByHyp$|X*#I6HCAi){gCu1nvN%& zvlSbNFJRCc&8>f`$2Qa`fb@w!C11v1KCn)P9<}ei0}g*cl~9A9h=7(}FO!=cVllq3 z7nD)E%gt;&AYdo{Ljb2~Fm5jy{I><%i*GUlU8crR4k(zwQf#nima@xb%O71M#t-4< z(yjX(m^mp_Y;5()naqt2-VibylPS)Oof9uBp$3Gj`>7@gjKwnwRCc>rx%$esn);gI z5B9;~uz57n7Rpm8K^o=_sFPyU?>liHM&8&#O%f)}C5F7gvj#n#TLp@!M~Q?iW~lS}(gy%d&G3p?iBP z(PZQUv07@7!o3~1_l|m5m;Xr)^QK_JaVAY3v1UREC*6>v;AT$BO`nA~KZa1x3kV2F z%iwG7SaaAcT8kalCa^Hg&|eINWmBQA_d8$}B+-Q_@6j_{>a- zwT3CMWG!A}Ef$EvQsjK>o)lJ;q!~#F%wo`k-_mT=+yo%6+`iGe9(XeUl;*-4(`G;M zc@+ep^Xv&<3e7l4wt48iwaLIC1RhSsYrf6>7zXfVD zNNJ1#zM;CjKgfqCabzacX7#oEN{koCnq1-stV+-CMQ=ZX7Fpd*n9`+AEg9=p&q7mTAKXvcbo?$AVvOOp{F>#a;S?joYZl_f}BECS%u&0x!95DR;|QkR9i}`FEAsPb=)I z8nb=4iwjiLRgAF}8WTwAb^eA>QjL4Srqb#n zTwx^-*Z38Uzh@bX$_1tq>m{o8PBX*t3Lqaf$EBqiOU*2NFp{LJX#3}p9{|v{^Hg4f zlhllKI>F+>*%mu6i9V7TT*Wx-zdK z(p8faUOwGOm5mBC%UGA1jO0@IKkG;i&+6Ur8XR2ZuRb$*a}R^-H6eKxcYodlXsF`& z{NkO+;_Yh-Ni@vV9iyzM43Yibn;oC7hPAzC24zs&+RYdY&r`3&&fg2hs62ysV^G`N zHMfBEFo8E3S$0C_m({bL8QCe$B@M{n1dLsaJYIU;(!n*V?0I1OvBB=iYh&`?u8 z&~n-$nbVIhO3mMhCQRlq%XRr1;Hvl=9E_F0sc9!VLnM>@mY~=Cx3K5}wxHKEZF9pC zIdyu1qucM!gEiomw7bW0-RwbX7?o=FE#K0l4`U2KhC8*kMWaEWJyVNZVu_tY2e&4F zb54Lh=Oz>(3?V$!ArXFXh8Cb3i;%KQGCrW$W#;kvx$YA2gofNeu?@nt>Yq8?2uJQp zUTo14hS%&dHF3Uhm~Z1>W)yb%&HoM!3z?%a%dmKT#>}}kKy2B=V3{Nu=bae%V%wU$ zb4%^m?&qn==QeHo`nAs3H}wtiK~!!&i|iBLfazh6!y9F)ToKNyE0B385!zq{p)5vB zvu`R#ULIS|2{3w52c*c$4}Pe>9Fw&U^>Bb_LUWn!xPx3X-uQsv(b1XFvFzn#voq0* z5~o`V_G805QXdgAOwOjoqmZ?uzwBVYSNP0Ie8FL`P0VK1J4CzV@t&%0duHB{;yIL$FZ9 zz#s#%ZG6ya&AwE;0_~^$1K

Hnj76Oym1QVh(3qRgs)GmgnEt-KxP|nCFY3uezZn zmtR0CZ$Z_-+f07?lu_tr~IC{&U6+QOth>ZgYk4V2FI$B2V3`M`Jk zsr>>lupymPeK129PfpDt9?GA2;I>03Ktz8NxwvTroqu8oaRB&bXT}G=^2UyOW}(4H z;9sG^YwV8K7pC&&viM^X_pfeFoN!cIhrE>OPQ5E<4KKDyPhRV^BGb_^Y6GO6#w}c= zu`0fC-@F4qXQtnB^nPmfI7Uw0bLhY^09TCO+H2(nvg8jdPjMAi4oSX%GP3oeo0`ks z%DoV|waU-Q7_libJCwnnOL9~LoapKqFPpZx?5FygX zsA~*ZR7X=@i{smf?fgxbcY6Y`JvD50P=R;Xv^sANPRp-Hc8n~Wb*gLIaoZJ2Q^CFe z_=G}y&{_NXT|Ob??}$cF7)$oPQMaeN_va1f%>C>V2E01uDU=h~<_fQKjtnl_aho2i zmI|R9jrNdhtl+q*X@}>l08Izz&UJygYkbsqu?4OOclV{GI5h98vfszu2QPiF?{Tvh19u_-C^+NjdAq!tq&Rd`ejXw#` z@U15c$Nmylco)Yj4kctX{L+lz$&CqTT5~}Q>0r-Xe!m5+?du6R&XY|YD5r5C-k*`s zOq-NOg%}RJr5ZWV4)?EO%XzZg&e8qVFQ?40r=8BI-~L%9T7@_{1X@<7RjboXqMzsV z8FiSINMjV*vC^FCv_;`jdJ-{U1<_xjZg4g?ek z4FtsapW_vFGqiGcGHP%?8US~Dfqi8^ZqtHx!}0%dqZFg%nQB)8`mE$~;1)Fb76nFk z@rK#&>2@@)4vO&gb{9&~R8-_{8qz6Rmw`4zeckD(L9xq}{r(fUO0Zh-R(d#x{<0j| z?6xZ2sp3mWnC}40B~g2QinHs1CZqZH&`+x2yBLT8hF7oWNIs_#YK2cyHO6AoGRG|RM>Hyn(ddpXFPAOGh~^0zcat`%&WoEQf9)!@l*3Tt@m>Lb z6$+$c!zsy_=%L9!_;jfd`?VXDd*^Vn%G>n~V9Vr6+_D@#E+dWB#&zAE+6xJeDMr1j zV+Tp~ht!M%^6f?)LBf8U1O4G#CutR07SB>8C&_&;g3TdIR#~e~qRtwd>&)|-ztJJ#4y0|UMjhJZlS8gA zAA260zUh+!$+xMfWKs|Lr23bcy#)JNnY|?WOka&wTS7_u%*N7PrMl1Lp9gxJY%CF? zz4IA@VVxX{knZPlNF+$9)>YIj#+(|$aflt=Wnforgn6`^3T+vaMmbshBjDi&tR(a7 zky~xCa77poRXPPam)@_UCwPdha^X~Aum=c0I@yTyD&Z!3pkA7LKr%Y6g%;~0<`{2& zS7W$AY$Kd}3Tg9CJgx=_gKR59zTMROsos?PU6&ocyCwCs8Qx1R%2#!&5c%~B+APu( z<1EXfahbm{XtOBK%@2a3&!cJ6R^g|2iLIN1)C2|l=;uj%tgSHoq2ojec6_4@6b<8BYG1h-Pm_V6dkRB!{T?jwVIIj&;~b7#%5Ew=0Fx zc(p7D1TT&e=hVt4spli}{J6tJ^}WL>sb`k}&gz+6It`Yz6dZdI53%$TR6!kSK2CfT*Q$`P30 z;$+G$D*C$U(^kkeY!OWn$j@IUu0_a{bZQ=TCbHD1EtmZ0-IBR<_3=tT%cz$>EE!V}pvfn7EMWs^971+XK}~kxSc_ATJJD$?)1Gz^Jq!>Hz#KkdCJ~jb-Y*Xv01_}}=T_V-A1<3O!V9Ezf z%Lnjihb3>=ZV}jSeqNu5AAdVbe|`;|p<%W#-<$s1oDYrB;C({psqV>ENkhadsC{cfEx=teVSB`?FOs+}d#pssxP z(ihudAVu3%%!*vOIWY11fn1M0&W|(|<2lEShz|#%W|wV2qM%#+P9NOy1x8jytHpfU zh;_L^uiL<<$L@~NpRXSrkJgdC>9R=>FmVu3^#C?3H>P{ue=mcv7lBmnfA?mB|L)EF zHv%Nl|D}0Tb~JVnv$ZysvbD8zw)>|5NpW3foe!QHipV9>Zy`|<5?O+rsBr*nZ4OE} zUytv%Rw7>^moSMsSU?@&a9+OdVgzWZnD>QXcUd{dd7vad+=0Hy)4|0A`}rpCx6cu!Ee5AM=iJ?|6=pG^>q(ExotyZP3(2PGhgg6-FkkQHS?nHX(yU0NG;4foCV|&)7 z1YK!bnv%#5n<25|CZ>4r1nK=D39qMzLAja*^#CN(aBbMx${?Iur3t=g2EMK|KwOF?I@W~0y`al&TGqJ zwf#~(?!>@#|JbDjQV9ct%+51l%q|lcY&f{FV&ACRVW*%VY6G5DzTpC!e%=T30mvav zRk$JOTntNoxRv>PDlJG1X=uep&???K00ep|l_#7=YZPuRHYoM46Z$O=ZZuGy_njgC z>P@gd+zKH5SjpWQ!h_r*!ol1s{9DS@sD4}xgFxaw>|av!xrKzg?rGnhZ#uZeU~iod z3-i*Hl@7cge0);y{DCVU(Ni1zg{yE&CxYT7)@zJ%ZZABj-Fh}0au^)*aw`vpmym;( z5|JZ!EACYenKNXH%=Md{my$sI3!8^FgtqkMcUR%w_)EBdP5DZ64aCIR%K99tId6SU ziT8Ef)K%7{XuIpPi}N+&FCm$elE>oKY;3c$x+*mXy?~wt6~?ss$HGqCm=YL2xzVTQ zr>*2_F;7j{5}NUPQ(aY0+h~rOKN|IA28L7^4XjX!L0C^vFB+3R5*1+s@k7;4d#U=5 zXTy8JN^_BCx1a4O3HMa9rf@?Fz>>dq}uvkY7!c?oksgs~xrpCo1{}^PD?w}Ug z3MbfBtRi z$ze~eRSLW^6bDJJeAt^5El{T*i1*v9wX{T7`a2wAVA z%j>3m*g^lc*~GOHFNy?h7>f7mPU*)3J>yPosaGkok}2#?wX5d$9moM~{NTzLznVhX zKa}bFQt#De`atoWzj4Lb@ZCud_T9rA@6VcmvW(+X?oIaH-FDbEg#0Slwf|7f!zUO( z7EUzpBOODL&w~(tNt0z|<9}Filev&4y;SQPp+?kIvJgnpc!^eYmsWz1)^n`LmP&Ui z-Oi1J2&O|$I<^V@g2Z91l3OArSbCkYAD0Tuw-O(INJJ>t%`DfIj}6%zmO+=-L{b!P zLRKvZHBT=^`60YuZon~D$;8UDlb-5l8J=1erf$H(r~ryWFN)+yY@a;=CjeUGNmexR zN)@)xaHmyp$SJcl>9)buKst5_+XomJu34&QMyS zQR(N@C$@%EmfWB8dFN(@Z%xmRma@>QU}!{3=E`wrRCQ~W=Dwb}*CW8KxAJ;v@TAs3 zW}Pq5JPc)(C8Rths1LR}Bgcf6dPOX<#X08^QHkznM-S>6YF(siF;pf~!@)O{KR4q1_c`T9gxSEf`_;a-=bg6=8W zQ&t`BK^gsK-E0Jp{^gW&8F9k?L4<#}Y0icYT2r+Dvg!bnY;lNNCj_3=N=yd9cM9kY zLFg|R0X;NRMY%zD*DbAmFV`(V@IANtz4^_32CH*)XCc$A>P-v49$k@!o$8%Ug>3-- z$#Fpo9J>eUMKg>Cn+T0H!n0Hf#avZX4pp54cv}YcutP+CmKC~a745-zhZp`KNms;J zS3S49WEyS8gCRAY|B~6yDh*cehY52jOSA#MZmk2dzu`_XpBXx9jDf!H3~!`n zaGe=)1VkfIz?*$T3t>-Pwhrw447idZxrsi;ks;(NF>uVl12}zI(N~2Gxi)8yDv-TLgbZ;L&{ax&TBv;m@z6RcbakF^el{!&)<___n#_|XR%jedxzfXG!a2Eyi)4g zYAWkYK{bQzhm|=>4+*SLTG2<#7g-{oB48b05=?PeW;Jo3ebWlo5y5|cl?p8)~PVZqiT^A~w-V*st8kV%%Et1(}x(mE0br-#hyPspVehofF`{gjFXla1lrqXJqQKE9M)8Xe0ZO&s$}Q zBTPjH>N!UU%bRFqaX(O9KMoG$Zy|xt-kCDjz(E*VDaI={%q? zURR{qi>G^wNteX|?&ZfhK-93KZlPXmGMsPd1o?*f_ej~TkoQ#no}~&#{O=>RadgtR zvig@~IZMsm3)vOr`>TGKD&fbRoB*0xhK7|R?Jh-NzkmR}H6lJiAZTIM1#AXE1LOGx zm7j;4b(Lu6d6GwtnsCvImB8%KJD+8z?W{_bDEB$ulcKP*v;c z*Ymsd)aP+t$dAfC-XnbwDx3HXKrB{91~O}OBx)fsb{s-qXkY<@QK7p-q-aaX&F?GS z2};`CqoNJ$<0DuM2!NCbtIpJ9*1a8?PH#bnF#xf~AYOIc4dx1Bw@K=)9bRX;ehYs; z$_=Ro(1!iIM=kZDlHFB>Ef46#rUwLM%)(#oAG(gYp>0tc##V{#aBl!q``!iIe1GBn z+6^G^5)(nr z8h#bm1ZzI450T?!EL)>RWX8VwT1X`2f;dW!{b~S>#$Pa~D6#Hp!;85XzluH%v5325 z730-aW?rY1!EAt;j7d23qfbMEyRZqxP};uID8xmG@mGw~3#2T^B~~14K5?&dP&H@r zL|aXJsEcAAXEXfu2d-!otZTV=if~^EQD*!NkUFQaheV&b-?-zH6JfjKO)aYN=Do*5 zYZ-@m#)5U0c&sUqu_%-Editr5#%Ne&bs)DxOj2_}`f;I_ReEY9U&Cf3rb>A3LK(ZD zid0_-3RfsS*t&g!zw}C_9u(_ze-vc1L59CdBl(IS^yrvsksfvjXfm>(lcol%L3))Q z@ZT;aumO3Q#8R!-)U697NBM@11jQ>lWBPs#?M4_(w=V_73rsiZh8awEm>q1phn1Ks ze@D|zskeome3uilE8-dgG(EojlI(@Yhfm}Xh_AgueHV`SL##I@?VR+bEHH=sh21A_ zhs&pIN7YTLcmJiyf4lZ;`?pN0`8@QbzDpmT`$m0CTrTMiCq%dE&Cd_{-h`I~f8Kps zAuZt4z)}@T>w$9V@iLi=mh({yiCl}}d>JN)z;*G<6&mgl(CYhJHCAPl=PYK2D>*F zy;YK=xS@1JW7i=C)T04(2P#|fowalY=`Y`G8?eRMAKt|ddG9UF^0M5 zW=ZGZ5qb-z@}iS`4RKXvuPIfzUHT)rv<8a|b?bgB3n=ziCiX4m2~CdVBKHWxw2+Hz zLvqoAij9(0moKoo2$`dqS0?5-(?^RXfcsQB6hU2SAgq8wyeasuyFGcK+@An?8ZzVw zW8wwbZB@i=<<4fA7JKPkki6y>>qO3_bW>-uQ*>9g+g7M0U^`RV)YTrGu2Q=2K>fiI zY0dFs>+}xuOZE^efLK2K6&X@>+y10Oqejnnq^NjfXt9JpK4K_E=cl29 z(t2P;kl4AK_Jg9v{1(z)ESpyo_(Z`74D&J1A#J?l5&J^Ad1sm5;Po@s9v7wOs(=_T zkutjt`BaxT09G{-r>yzyKLlM(k`GZl5m+Tgvq=IN|VjtJ*Zu66@#Rw;qdfZqi15A@fr^vz?071F5!T`s>Lx5!TszI%UK|7dDU;rUCwrRcLh!TZZ9$UMfo z@Qzjw>tKS3&-pyWS^p4mMtx`AvwxVc?g?#8aj@jQ#YKDG0aCx{pU+36?ctAiz=f$k z05S(b&VPQgA(Sm`oP&M^eiHvBe&PcTb+j$!!Yx(j3iI5zcQLOn(QqfX5OElbSsQBUw7);5C92onieJyx`p{V!iwXk)+1v zA6vStRZo0hc>m5yz-pkby#9`iG5+qJ{x>6I@qeAK zSBFylj8{FU*0YbFd2FZ6zdt^2p?V;3F~kap`UQgf@}c33+6xP)hK)fmDo@mm=`47* z9S6rnwCSL&aqgZs959!lhEZZp`*>V8ifNmL;cqajMuaJ~t`;jLPB?X~Ylk_Z#Q;%} zV+sAJ=4505-DdnIR=@D_a`Gy#RxtSX+i-zInO@LVDOd*p>M-|X(qRrZ3S(>(=Oj>} z89d75&n?m^j>;SOXM=)vNoum|3YmzxjYx%^AU*V|5v@SjBYtESp^yz?eQ#>5pnCj} zJ_WCw23wGd2AA-iBve8Hq8`%B3K4@9q@a}sf$49IA^IPsX@QK)36mrzqOv?R_n9K@ zw3=^_m#j{gNR0;&+F~wlS(i8IQN8mIvIO)mkx|e)u*y+xDie}%mkZ*m)BQM^$R@-g z1FrP0{8A?EcxtxxxX&J;393ljwwG?2A2?y-1M0-tw$?5ssoEsbPi?sd2!s~TrwPLF zYo-5XYV7AU-c|Vb-v;>pVi^CwX(Rpt<9{Ic?@<9SrNu>F(gwij%?dC9^!Xo90o1-| z&_aPKo%+xyw64e&v<}F^-7sO0Cz-VOF@7**i@v&(Oy4Q8PbV+4&rKwmYyokM z48OZ|^%*mC_Q)RJ31D#b4o4Jzr{~BX4D#swW<31;qCil2qlim;e=9ymJAEXfv-|h3 z)>uqQ5~S+8IgiWW28Fqbq+@ukCLy+k7eGa1i5#G_tAUquw$FjFvQt6~kWa69KXvAj z-knF`5yWMEJvCbTX!K{L)VeNF?(+s?eNjtE5ivg^-#937-l()2nKr#cHShB&Pl^l8 zVYws26D^7nXPlm<_DYU{iDS>6Bq0@QsN%6n>XHVvP<^rDWscC!c+LFrK#)T@$%_0{ zob%f&oaq>1_Z8Ata@Y2K6n?GYg|l8SgUr(}hi4D!@KL~hjRv<}ZZ`tCD^ev=H&^0pP%6q2e+t=Ua`ag8xqWvNnIvCU|6ZA^L5v{DD)!mcQ@n6{=; z#Z)PrAz>*+h-|IV!&J*f@{xb!L7h3{?FEs*ifw5z2U9$&OkYseI68yb=V4xv*VK3- zVxGhtmedujX32y-kC{5ej-Wy#JvB~4oxTb{|1H825_B(A0#?CjUTc=PrGh6jAgK9h zoLAe`+NBdStZE@Y8UH^Rd*|R-|7Ke}wr$(CZQHhO+upHlCp)%n+fH_}S8%^%xqhu%20_1p=x#Dl9ia`c3iM+9Vh5?gyY8M9c$tJ5>}V_sidHN zoMl%rSgSK!7+Y8tQkYq|;Vh`4by2uMsUfnxkk2{S@a>V#d}fv}Yud*>paVi_~T zU!GoYwWbnG%92!Cte(zhZX-i9#KJ;b{$(aZs|{MerP#6||UUx$=y)4XOb zihyKn`_QhJ#~@_peJ*8yD4>I7wQyKkZG%#FTKZfb(@G+9x7-3@hG}+ZC&$7DwbaB$ zC)jLj7yituY&WpOWlG7Z4Tuxzdwo6k!3lgwhh7BYMyB? zO9Q5nvn77~g~c623b`Pe5efNzYD#2Sfmg>aMB5s?4NC|-0pIXy%%`J;+E{(irb!Szc8M8A@!}0zqJLoG4SJ5$~1*yRo0^Z`uObA+= zV?1sYNvzvWbP%AsMzoIo3Cwx~y%i8rHF(BgLS>tH5Ab|1wp$X_3o2_VB(pFxgQ5QQ zk@)Vy95$b%HVf4@ppX(wrv^Jwfrsu+9N_OUm}nD7Ch_7STj66EYsZR#`9k|Tf^@p& ziHwnO$p{TB#R(Q{Os>Un~0!r$JO zLZ&F%SP|%$TuG)mFeOhKr1?S!aa0jTV$2XIeZb_fgO&n{8HTe9s`L&(tKoy?OaS^$ zLHNrgYgq920EI~M>LyU7gK70$7*`nFKD^d>MoEAhsBU0%@*RW@%T(J z?+wVbz=mcN%4#7qlCpl_^Ay7VB%?+uW1WSNnQOj^tALyqTpV zkEN2C;qO_W)MYl^Ow5I;t3;z#iG82F(qe}#QeE;AjA=wM==dB(Gu+ez*5|RVxO4}l zt`o?*B;);-0`vR(#+Q^L4WH_9wklh-S-L-_zd%Q0LZ%|H5=>Z)-x#Z+m%p&6$2ScV zEBneIGo)r0oT)xjze*Q~AIqhB%lOM5Id}^eKwS!?b_;B&TouZsemyL&y`)#FX}ZKp zp)ZnB*^)1P@2bCoe+Z|#KhTBNrT)UN@WIuudw})fwHl)re1|b~E1F=xpH?7L77p>5 zei$aD@KO0<+zo1<&7OuZatNsPq24Whu%0jD_ z$ZZy6MzayYgTJulNEy8D$F%JDYgx|d6{6kpDg#s170<15bM#4tzvrDU$6bvu-hH@6 zgcjq&3aR3k(23$FaUA|iuoy*bO{2F6W0<+ZdsYvXjc?d@ZT8kM!GD}r@qr;TF@0Hb z2Dz-A!HZ$-qJ?F%w6_`t`8xk$f$MNBfjqwvJiVdD+pf7NVFGh?O=qp2vh%UcYvc{rFldib~rkIlo`seU%pO_6hmBWGMcUhsBSWiQYYPMX<-Cjp49@7U==iS57bG zw3T9Nbm`)m9<<4e$U74`t~zRo0JSfi}=GdQXGLLPyW zlT^I}y=t$j{Vx!wN^z8X4l0|@RNrC#)G>bK)7IT7Qop>YdS^NnI3gfP>vtp)pXkr2WSVcAAv8uN>@ z`6)kICvNYU$DA8pnkl4sQopDC6<_M8zGJ^@ANXJL(yd#n1XFj9pH;rld*gwY8om_I zdB55w@FUQ_2k}d%HtQsmUx_7Mzftky&o2X2yDQrgGcehmrDDDtUJj5``AX$gzEbMc zUj2Qzp)Lo>y-O*@HJ|g9$GR2-jgjKfB68J6OlIg;4F2@2?FlW zqj|lO7A2Ts-Kd!SO|r9XLbPt_B~pBpF40xcr0h=a&$bg(cwjp>v%d~Uk-7GUWom?1 z92p+C0~)Og*-N~daT#gQdG{&dPRZso(#{jGeDb1G`N)^nFSB`{2-UQ&!fkPyK`m03 z_Di94`{-(%3nE4}7;4MZ)Pmawf#{}lyTSs5f(r;r1Dp4<;27K=F}Oga^VsUs3*NIn zOsYstpqpRF&rq^9>m50LRORj>=;{CV2&#C$-{M5{oY9biBSoQyXvugVcwyT-19S;pf!`GSNqb4**TI%Y z*zyV)XN3Fdp3RNNr9FU+cV*tt?4L8>D@kJp^rkf_rJ~DPYL}oJngd1^l!4ITQN`0RTT^iq4xMg|S6;d}lznE$Ip^8pW-CHu zP*^!U>Lcd3*shqa)pswq;y<|ISM1g1RG#`|MSPNAsw*XH1IAD(e(Kgqp6aDHgv>fI z!P67$z{#()Pdo3;4dUoy*Xor(O?+YTRPe=g*FfRj*9q9!8p%1l>g3e^rQ_nm{(@4t z?^nMDC2J8@my5q0QyCljCSp_@)No+6bZ*y)lSdrkLFcR6YOHu*vZ-q(C);5$MmM_z z1WT>Gc8g%`Rt~6*!}JhWi0=Rc_z5c8GR9YXW+cdoK~Ea(@wyXf|89HagNuFAO-V7k zUb|9zaCCWH3^Fz(m7$8K$|0ZOP!SNpgP!ql<)!z8w$Z$?9gq2f<~koe3|zD=imLfD z>IV5?SkRZ;7JlOG%z%Tlze$GXr0A}ResyF63ZGZVDLv2k4HWtoqoCaq+Z&GaVKuLA z>@zhNjYYc=sexH?;DTe4&2vnQE}C@UFo&|qcLddvH0FwswdRUc(p*X&IT^Zu>xLpG zn(@C%3ig(l2ZPm#Fc){+0b+%O7nt4zbOt+3@GQVm|1t70=-U(>yo3VY2`FnXFHUyi zwiqf(akt0kEE5_Pa-a*VCS}Pi6?`~P%bvX6UT~r-tUAY%I4XF3^nC+tf3alyL{M`w zv?aVQ#usdwpZmkrfv19O39}tQPQM+oY**a{X?@3Qe>r$+G!>r#?Id&U&m^HU(f= zjVpSi9M||1FyNQA&PO`*94&(qTTMQv3-z`bpCXs-3bX}#Ovqec<>omYhB*VrwxqjY zF3#OXFsj`h#G?F}UAilxTQ|78-edHc-Uc-LHaH*Y(K%R#dVw>_gz}kRD4s#+U&Pq= zps)kMf_t9`GHR7CO4zI8WVj0%qiSqy50N{e_5o#GrvNhMpJf5_sCPrEa%a@ltFnss ziaWh26vEW4fQp}qa4oP(l4xIMpA)~VHD9!lP%;Tm`(HD$jYMM-5Ag>S(gC35J35$%?^gk(r|`4Ewi-W z;f&;B*fO=kC@N=r<-#nGW|yXE;`zb0Y3TJOAkw1a$SQgoTawHZTck+V%T=spmP`^BHihc(jc+S1ObX%6AYQ6LVVc+BfM*P{2s0T2z zVIs*5{ql%#CKAzv0?@S+%||z;`dpfj0Y(VtA51n$j%sG5I%A|h98VU}PkVZFrk1*G zaw75v3(N50lanvr&ND4=7Db;HS4fpi)2vTME7aD2-8N5+kcOXmYCrLE?*5&dWhvB` zbD5)ADuIwwpS*Ms;1qyns(8&tZ*)0*&_lNa`_(phwqkL}h#WdX_ zyKg%+7vP>*&Fus9E4SqIN*Ms`QLB(YOnJ|md%U|X`r#tVN$#q6nEH1|blQ?9e(3|3 z`i#;GUl~v?I6&I6%YvkvmR?*l%&z)Pv8irzVQsWrZSr%aoYuPJa#EjK|4NmiuswK= zlKP2v&;yXv3>LQ$P){aYWrb)5GICwbj;ygw>*amKP;Z{xb^cF}O@IeQ^hB-OjEK{l z>#PNyLuVkeDroL9SK2*ChHmJJSkv@YRn7)E49fy!3tqhq`HtHs_(DK|2Lyv(%9L&f zSy+H}Uk{nE2^5h7zN7;{tP3)$1GK9Xcv^L48Sodg0}ZST@}x607yJo2O*XCfs7*wT@d?G^Q6QQRb!kVn?}iZLUVoyh8M4A^ElaHD*Nn2= zkfCS=(Bg9-Mck6K{ z%ZM59Rs4(j1tSG1B#wS=$kQfXSvw6V>A(IC@>F;5RrCos`N{>Oyg|o*qR2EJ>5Gpe ze~a4CB{mmDXC7C>uS@VL&t%X#&4k<`nDx;Zjmo%?A4fV3KOhBr;VuO!cvM8s2;pG5 zcAs!j?nshFQhNA`G3HMS z?8bfRyy1LwSYktu+I7Hurb-AIU9r|rl5nMd!S&!()6xYNJ1EqJd9BkjgDH@F*! zzjtj4ezywvlkV7X@dG^oOB}T76eK=y!YZB#53LhYsZuP&HdmVL>6kH8&xwa zxv8;t-AE>D5K<{`-({E0O4%fGiLVI8#GfZ0aXR6SfYiPUJKnujMoTI5El<1ZO9w|u zS3lJFx<7XUoUD(@)$pDcs3taMb*(v2yj#G)=Mz-1M1q@Tf4o{s9}Uj9Yo?8refJwV zJ;b+7kf0M}fluzHHHS!Ph8MGJxJNks7C$58^EmlaJcp`5nx+O7?J)4}1!Y>-GHf9o zk}oTyPa>+YC$)(Qm8|MhEWbj?XEq}R=0NFH@F3ymW>&KS!e&k5*05>V@O*~my_Th; zlP05~S5@q+XG>0EuSH!~gZe_@5Dbj}oNIiPJpEOip+3l!gyze@%qOkmjmx=?FWJLF zj?b}f8Vet*yYd16KmM43rVfZo?rz3u|L6Foi*GQe4+{REUv9*}d?%a{%=8|i;I!aT z7Wxm}QJC`?cEt9+$@kSkB!@`TKZz1|yrA1^*7geq zD5Kx-zf|pvWA+8s$egLrb=kY385v2WCGL{y4I15NCz5NMnyXP_^@rsP#LN$%`2+AL zJaUyV<5;B^7f+pLzTN50Z~6KC0WI<|#bMfv+JiP3RTN^2!a7*oi+@v3w*sm5#|7zz zosF*{&;fHBXn2@uguQ1IDsh(oJzH#i4%pk;Qh^T zfQLyOW;E*NqU!Fki*f-T4j(?C$lY2CT{e!uW}8E(evb3!S%>v^NtNy@BTYAD;DkVo zn9ehVGaO7s?PQBP{p%b#orGi6Y&~<;D%XLWdUi}`Nu-(U$wBBTt*|N4##sm2JSuWc)TRoYg57cM*VDGj~ka<=&JF zo8=4>Z8F`wA?AUHtoi$_hHoK!3v?l*P0$g^yipOWlcex4?N2?Ewb1U=lu}0`QICA4 zef61j-^1p}hkA*0_(esa!p%dX6%-1e-eMfQsIp6wRgtE=6=hDe`&jel{y=6x5;78s z?5^{J|t!#x1aS8<3C`v%E%u{*wZwSXr$0Owl5_ zmXh>D>C_SjOCL^CyGZpBpM5`eymt{*rf~9`%F&&o7*S!H%3X)7~QFgn^J>6 zD+yV}u{HN-x9*_$R;a+k?4k*1f)rE~K|QvcC3dlr>!nftB?gE-cfcPMj&9mRl>|Lg zQyCe|&SuZopU0>IfRmcV3^_mhueN5oQ=J+H4%UsSIum4r4!`^DJqZr?1j3BU)Ttzg z6LwM)W&UEMIe*H2T6|{rQ;x9qGbp7ca#-!Egm4|ECNTMN);`>2Q&%|BpOdIJ4l|fp zk!qEhl;n(Y7~R1YNt7FnY10bQZXRna2X`E_D1f*}v1bW^lJorDD0_p2Rkr32n}hY! zCDB(t$)4YOd)97R60gfg3|wrlsVs#4=poh4JS7Ykg$H)vE#B|YFrxU-$Ae^~62e;! zK9mwxK?dV4(|0_sv(zY&mzkf{x@!T8@}Z6Bf)#sfGy#XyRS1{$Bl(6&+db=>uy-@y z$Eq~9fYX$06>PSKAs#|7RqJ3GFb;@(^e`jpo-14%^{|%}&|6h{CD(w@8(bu-m=dVl zoWmYtxTjwKlI!^nwJ}^+ql`&fE#pcj*3I|_Z>#y##e@AvnlSN4po#4N#}WT)V5oNP zkG+h_Yb=fB$)i`e2Fd28kS$;$*_sI;o0Xoj#uVAtsB6CjX&|;Bk}HzQ*hJ!HDQ&qZ z^qf{}c`l^h5sg-i(pEg#_9aW(yTi?#WH=48?2Hfl_X+(SfW)_c48bG5Bf+MDNp>Y#Mpil%{IzCXD&azAq4&1U10=$#ETJzev$)C*S;Pr9papU3OabRQk_toRZ!Ge(4-=Ki8Db?eSBq~ZT#ufL6SKaXZ+9rA~ zQwyTQTI7*NXOhn?^$QOU>Y6PyCFP|pg;wi8VZ5Z$)7+(I_9cy--(;T#c9SO;Hk~|_ z0tEQ)?geu8C(E$>e1wy%f@o;Ar2e#3HZP$I#+9ar9bDa(RUOA+y!oB;NEBQ`VMb@_ zLFj{syU4mN%9GF;zCwNbx@^)jkv$|vFtbtbi7_odG)9s=q(-PtOnIVcwy(FxnEZm&O^y`vwRfhB z7Urcums9SQS6(swAgl?S|WDGUTFQu51yG$8069U zviuZ=@J&7tQ8DZG<(a->RzV+sUrmH$WG+QvZmUJhT*IoR3#3{ugW%XG0s?_ycS6V6 zS)019<_Rl@DN~8K4#w3g_lvRm4mK3&jmI$mwROr0>D`mX+228Dw4r;mvx7df zy~$zP8NjVX?xkGFaV>|BLuXMQ+BN+MMrIB4S6X)p&5l$;6=S8oI9qi&1iQbs?TroDMfCmIeJ}pbVVtVqHhS(zutEy6#UjTk29-+3@W0`KfehW`@np zhhu#)O&g%r)hTj4b$CY41NYp_)7!bYyG;v(rts z^}YDJt2W88H^H;e$LSm3dh=~yi@)mzJtEfW8=4avbeOE&;Oc>-6OHO+MW`XBZ4rO6 zS;nAi**w3Yso4&Ty+8f$uvT?Z)eaLe$KW1I~9YM2zeTIT}C%_G6FPH-s5Wi3r`=I&juGTfl zZ;4qFZV|6V0c&>t!Y>mvGx#1WWL0N5evV=u28K9**dv`}U3tJ$W?>3InXiwyc)SA% zcnH}(zb0@&wmE>J07n#DOs7~lw>5qUY0(JDQszC~KAAM}Bmd-2tGIzUpO@|yGBrJyXGJk3d+7 zJBN0$?Se(rEb0-z2m%CBd;~_4aH04%9UnSc4KP!FDAM5F_EFujJZ!KDR-fn181GX` z8A?8BUYV}D9bCE0eV~M>9SPag%iVCLWOYQJDzC4~B~Ct0{H7x|kOmVcTQ;esvyHJC zi$H0R73Z8+Z!9^3|2tNut#&MVKbm`8?65s)UM8rg6uE(|e^DYqvoc15-f;u8c=>3;Viz*T# zN%!T+Hex0>>_gUKs%+lgY9jo6CnxL6qnQ>C*RseLWRpipqI;AQE7;LUwL`zM%b`Vu z%Sa-+?a#+=)HaD|k2%_(b;pHRF96(c;QyPl6XHL8IqGQKC$M8R=US-c8;hUe?LKo&l!{V)8d&55sUXEu z5uITcO~`ipddh+Nr{7ibp^Wd{bU)^3##<5`lkuqfckxEU*9{pgNpTB2=ku1c-|3dK z|LIQF=ld@I7swq^4|G1VA}BK85&>2p#*P95W`I1FF(8G9vfNJ6MoN$+C^M89u!X=< zJSS%l?Qj>$J%9?0#0&S6#*h*(-9Z$}q*G#hP?cX7cAvM0eiVFhJJ~$`iZM!N5NhDb zi<1u_m#?jzpIaOe7h|Kiap#mHA`L|)ATnPJ7du{^ybuNx@1jA+V1l8ux#{LJ#teM(6=%gZcMq24J$2p z`wcC!qRssmwUv4H6Psw{(YdDNOv$!sq&O1SvIS}fCKZa+`T=Ayt@uZjQqEC{@Uj+| z!;i3W+p~=@fqEEhW@gT^JtCR<`m`i|Htg<TSJ&v`p;55ed zt@a|)70mq;#RP@=%76*iz>fAr7FKd|X8*@?9sWOFf$gbH$XFG zcUNu#=_+ovUd>FW*twO`+NSo*bcea=nbQ_gu^C7iR*dZtYbMkXL5mB@4a3@0wnwH! z(fZKLy+yfQRd%}-!aPC z4GB%OvPHXl(^H(BwVr6u6s=I;`SHQ1um7GPCdP-BjO%OQUH!_UKbEGvHCY}{OL`8FU$GZ;Y$SlS$-0VjK%lCP?U0shcadt4x7lN4%V}wBrLEbiEcK-OHl+pcBNSqN#mftpRj2A4Q z+av@-<#t_Dj_FN^O2~wq(ij1O*+=RVl+6gNV^~CI1UED- zn^zN@UOq8?q58b^4RA>lV}x;jA2OE=SqMYV9P#RsUlI+pp!y*jpwHgp-w3i$V)%?L z>irn1pnRc|P@r|Z0pCeMZ*k$}$`1GVGCT&QtJ`V%Mq!TXoge?8Fjn$bz}NqDn*2ZQ z$p3@F_^(}IVS76>OLNzs`O5!pF=LZ$<&gyuM$HQzHx8ww^FVxnP%Yv2i=m*1ASF~~ zP=!H}b`xl`k0pL5byku2QOS~!_1po!6vQyQL#LQ#rIRr?G5^W?yuNvw-PP{}%m35i$i+I?DJ%RGRcqekT#X~CxOjkV1UQrd&m_bbJ+gsSGbPwKS{F& zU-`QNw!*yq#Co#{)2JvP-6>lY$J$2u+e=r0&kEc#j#jh@4Tp;l*s<28wU%r= zezVPG^r*a?&Fn_(M|A7^xTPD998E-)-A4agNwT?=>FbrHz8w~w?hWBeHVYM()|buJ zvGv4j<%!U_Rh^ZKi~2(h1vk-?o9;`*Zc}m5#o@a1ncp)}rO2SDD9y!nT$_Eb%h`>% zDmssJ8Dl=gDn<-7Ug$~nTaRzd?CJh;?}nCco$7Pz<#J8;YL40#VFbAG|4nA$co;l^byBOT2Ki@gAO!{xU7-TY|rujdYTaWV(Rr{Jwu?(_TA zDR1|~ExJBfJ?MAReMF47u!oEw>JHVREmROknZUs2>yaboEyVs$Pg1f6vs06gCQp$b z?##4PWI#BxjCAVl>46V_dm4?uw=Y@h#}ER4|ACU{lddiweg`vq>gmB25`XuhNai1- zjt{?&%;TRFE+2Y_Gn;p^&&|bU44M=`9!Mc%NbHv|2E4!2+dUL z>6be$Kh|Duz}+)(R7WXsh!m`+#t^Its($x`pqDaN-^E z?*a=0Ck^rZBLQV~jY-SBliN&7%-y3s@FB;X)z(t&D=~@U0vT%xfcu`Lix=W#WVE{{ z2=C~L$>`~@JCIg8RAyk= zYG`(@w4H95n0@Fqv16~nlDU!+QZw&#w@K)hv!V>zA!ZOL$1Iykd&Su3rEln@(gxO| zxWc++T-rQEIL+j7i`TeatMfp4z7Ir31(TE4+_Ds@M|-+cwQg(z>s=S}gsSz{X*Wm+ ziKJWgOd`5^o|5a#i%?Gvw~8e?Rpi7C>nQ5dvPHVTO$PI^mnJ*7?gd3RD{|c_a>WrXT#Es3d}(k z$wpmA#$Q^zFclx{-GUL_M$i0&mRQMd4J#xq-5es)yD{kYCP1s!An(~K5JDRkv6DUSKgo^s@lVM5|V4mWjNZp zsuw^##l%rbRDKglQyj?YT!nk$lNUzh%kH705HWhiMuv(5a<~yoRDM&oCqm+1#S~|8 zA$g2Xr=}p_FX%Eaq{tUO9i*Q1i!>$+1JYZCL}flWRvF0y1=#D#y-JQTwx6uP-(bC} z_uP7)c;Xd`C6k#JVW?#Id7-|`uW+hN0>OM=C2Ta^4?G zr;EvxJ{%l|8D-heRYRM%f*LBC)krHZJ@%&CL0)FADWh14&7KV<9km6gE=o9(7keg~^rIQtthK^_8%Jk&aZLY_bc6SbY>IcwDK9{sV*t1GfKwf8aCo8t za)yALEi^-WXb!k6n>W-62Z^n8hO|eRYr&uZiW5d_URi??nl*aGu?ioQ+9RF9u8kwD z6UZ6HVd(G%l9>y7E)uyn?gAJMKeki0@tG*jdcE-}K?8(D-&n=Ld1i=A1AI<1z>u5p=B z<1}|q3@2jNxW-}Q4z~s|j&^Qc;nXIdS3K8caP_07#ig} z#KAD&ue2jXc&K#Q`Hy#x+LeT4HHUCzi1e?*3w{tK+5Tij(#2l2%p#YGI-b~{5{aS8 z!jABC*n6y~W|h;P!kn(a4$Ri2G118!?0WHDNn((QDJP^I{{wPf<^efQWW?zS>VS?X zfIUgCS{7oV$|7z2hJBt+pp1CPx4L{B_yC3oWdE)d)20WG6m5qknl}8@;kjPJE@!xP zV(Nkv^-Vz>DuwBXmKT(z>57*D<$u=Blt)IS-RK0j89omD{5Ya*ULWkoO)qeM_*)jF zIn87l{kXPp=}4ufM1h7t(lAL?-kEq>_DE-in8-!@+>E1+gCV9Fq)5V3SY?**;AKq0 zIpQ(1u*3MVh#tHRu5E5=B{W-QOI34plm`#uH(mk*;9&Re%?|v-=fvb;?qvVL@gc|l z8^L?2_0ZrVFS-stRY(E>UiQeG_sMrw5UiO znGFLOP-GO{JtBM@!)Q37k3G_p&JhdwPwtJS6@R4_($Ut^b!8HP{52-tkue8MG=Zwr z7u6WaFranJq4oNadY)>_6d~?pKVxg$2Uz`zZPnZVHOh-;M|H7qbV0OF8}z;ZPoI+| z(`e}bn6u*kJpRLC>OZ}gX#eHCMEk#d8y$XzSU;QZ|An$pQ%uZC$=Ki!h@&m8$5(xCtGaY3X1FsU?l5w^Fr{Q-?+EbUBxx+b?D z80o*@qg0juG;aZhj=tO=YHjfo=1+-NqLME~Kw7Y1A*?}M7#cOyT(vd$1tVPKKd@U! z&oV!RzZcK6gPWj`*8FIAy2I&x``h_sXPe*O{|ih(Y+V3|o68MWq~2Iy^iQ8RqK76f zC$1+hXqd^jsz`U{+EFo^VQNrLZt#R`qE*>2-Ip&(@6FmtAngx@+YnG}b5B9Y)^wg#oc z24KlT2s!H_4ZR^1_nDX#UH4(UTgl603&Q3g{G4!?6Sl9Om=Sy|8CjWO>d@e9?Q%s- z-OS3*W_H7*LW|Ne{b+^#LqQ}UKDmiZDma@no2!ydO^jcm>+z379K%=Ifs{20mT|xh zP$e7P=?N(tW4PMHJOQ`a8?n}>^&@<`1Rgo`aRevPp^1n7ibeS6sc8^GPe>c&{Kc+R z^2_F~K=HVI45Pf|<3)^;I{?H}vU7-QK3L1nHpcn3!1_)<$V;e0d_b8^d1T==rVpky zZTn~UvKrjdr11k}UO@o>aR2wn{jX5`KQQM1J1A?^wAFvi&A#NA#`_qKksu`sQ0tdM ziif17TO<{wDq_Q;OM}+1xMji^5X=syK=$QdZnS#dwe$;JYC7JozV8KpwfV}?As|^! zFlln0UitprIpuzLd$`<{_XoUV>rrHgc{cUQH-Px#(_Ul%=#ENrfJe@MRP_$E@FLMa zI`(J)Imw$o427@Oc^3(U&vz}<3Lfmy7diVpJJJ@gA>e;q-&gj zcGcBC_luF%_;**EB?o--G?AkaruJ%-b*8aX$4E+-?V@RWMnjHJ;hx27Vd7l0nUUY( z6OQb&8g8cvN3LZ%^xvIav*X|Epqm@yrTZk9U{GSZXAUJt8Lh(%7?Eaf&AzmXOVvU| zmz<@l1oMe#^POR38KT6q3@c`{%eYNu4ccurv`q?b5DzLxENjSfYOJHAI$MbSNgB*D zJsP>i*BgrFlIn?x&DH9x~UbPBtMFj{_vJ#CaAF>1$oE&k`EF&L@HCa@mN>Q7~!RU>7 zW%fv84aCKSgBacmuvg}r@)YKqO$U{D5|!`vG-Gp%An}raz2gESWm0Exhux4C)zE}} z_@kn z3t}bvm?L+@@az@<*jG>(Xopq&c*;^mttlJ!mv;5k6o%Ac<_`o`4G3qzzo(GO{!&F8 zW+~bF?S;7gO1dQ@>gwZ?iIHjE#^@;Ix!Z`R6{RYLlGB&v4A)ha(2hc`RGV-8`LcvSf+Y@lhT%(Z7$tWEF;cZs2{B|9k#&C}sPyr; zd-g~${TqY7E$9X+h4_(yMxQ%q;tm(h(lKzK)2FQ%k#b2}aMy+a=LHYgk?1|1VQ=&e z9)olOA5H}UD{%nu+!3^HsrBoX^D9Iy0pw!xNGXB6bPSpKDAaun{!fT~Z~`xp&Ii~k zdac?&*lkM+k_&+4oc6=KJ6RwIkB|st@DiQ!4`sI;@40>%zAG^!oG2@ z@eBM$2PJ@F&_3_}oc8A*7mp-0bWng^he9UYX#Ph*JL+<>y+moP^xvQF!MD_)h@b}c2GVX8Ez`x!kjAIV>y9h;2EgwMhDc~tn<2~`lf9j8-Q~yL zM=!Ahm|3JL3?@Tt(OuDDfljlbbN@nIgn#k+7VC+Ko;@iKi>~ovA)(M6rz5KP(yiH| z#iwJqOB7VmFZ#6qI~93C`&qTxT(*Q@om-Xb%ntm_?E;|58Ipd1F!r>^vEjy}*M^E(WslbfLE z<+71#sY~m$gZvoRX@=^FY}X?5qoU|Vg8(o`Om5RM6I(baU^6HmB<+n9rBl@N$CmP41^s?s1ey}wu3r3 z4~1dkyi%kA#*pLQy0phlXa-u(oK2Dwzhuex$YZv=*t*Tg5=n~H=}fJA!p2L78y3D2 zimkqC1gTU(0q||k9QM#><$b-Ilw#Ut2>JF=T^qN34^qcBEd={! zB)rxUbM2IwvMo?S;Id^aglw}-t9et}@TP;!QlFoqqcs(-HfNt9VqGFJ4*Ko*Kk#*B zGpJ>tA9(=t|4#M!kBaf%{$Kfj3-uf|ZFgiU`Bo>%k_OuAp~vnE^_Tg8*% z*?)4JdzyMTzvNDy{r$c``zBw=Vr)6c4}CBIv#mw()3h7`?V-;LF?J&N5a>kjpy;9n zQyXvuu`n?+W84QV=(i`JEJY=}Ak+u4>!Lyt2P!$nBl}T=^|pG*z@)_l!)OKB{tIV&&E@hj=OIhSBHgPV~X=R3NrTMh?VzDm?1yW^IJ&zzAn2{8rE~MRX5EE)a(-T&oE)1J4pGXBYi+nexX-?5! z{EZ4Ju=Y8MQ87=uNc2t^7@X)?85KeSoc`?BmCD;Uv_cwQaLyc}vvnJKHV zuK)H_d)xhGKB!_pRXv{$XgfZ_(8G%N3o$ZI#_ zixQj~so0*m^iuA!bT>&8R@>b%#B~zbIlwt4Ba0v&>B(`*Z;~?6!>-aQ zal+Qt4^dCcjZZMd4b4Khg~(GP#8$3BeB8j!-6l?*##)H?J$PeUy)cA_I26#0aggao zaM5PweS_Sb@{OZ@Uw*(!DNV)KTQU+BTRi?AUAv0Vowth`7mr9)ZVC+TI?@; zWGL&zydnsuE3+D7#U~P%PrxpD3nTc9#mm621iX*?ZMS_Q#n9SzOJ~Hg@`rX{d?qJ; zt}`76!H)MX#=VKifJZP$3<8@}0-llthFpq3FV;(UP$-k63MkHHq~J&}d?C<+c~*Zk z<#G&>AD7EoiAVO38TO2TOBKN>6N|JS*{+`}V-)T0j(bAzGlEUWEvWLrMOIItYexh) z?he>SJk*#bywgDF6+*&%>n%0`-3tOY72+n&Q1NJ`A-bX*2tJV(@;%b6&RxMcUd7+# z@UzOmc9DolSHc-D$5(GouinaE%&uOVMyD&CTdKaEB{Qap4_wU7_=23CULKQ;jmZuV;+Y$(`#Gh0@}s7-!qk-^&#IG>7B{yft?UoA)H5 z|B0u3Tu0TF{AB0jpT|E&RsYB$3WiQU^5p*|f)^Si_#^j+Ao^|5(gNjn+!0|NtXDt* z5fwxpajl@e0FrdEuj2s#Pg>gUvJdko9RBwEe_4@?aEM?SiA2nvm^tsLML{-AvBWM7 z_bm7%tu*MaJkUWd#?GWVrqaQ0>B%Azkxj+Yidvc$XdG1{@$U~uF|1oovneldx`h;9 zB1>H;;n1_5(h`2ECl?bu-sSY@d!QTa`3DrNj_F@vUIdW5{R7$|K{fN11_l7={h7@D z4}I;wCCq>QR6(;JbVbb4$=OBO)#zVu|0iK~SnW~{SrOq&j*_>YRzU&bHUhPPwiy($ zK0qin8U;#F@@}_P_flw`bW_v^G;ct?Pb65%=%egDBgS#YF3?E36$9xzdvYqjAZoK#hcjctJu~MF^S*$q3`o2;!L|jPnM1x*Q~qF%BH(5UDFYglsJwO zEdEuB7NihnTXK6$)F~``nmSQNFP7x7hE{WuOjTAhEjGw#XxvL@S;aZYuyu9)!yZ~X zo35D6Cwb8`shRXCCR;xlR`n`cs4aie!SSM`0)x3ykwM*k zK~w^4x2u#=jEEi`3Q9AU!wE)Zpn#)0!*~)(T^SEjIJveav(d1$RaSMC0|}<)?}nSG zRC2xEBN_YAsuKyl_3yDt%W^F`J-TyeGrcfboC_0Ta=KcW_?~RLb>xbqIVI6`%iWz; zM8Kq9QzwO8w!TntqcB;gNuV$gd+N|(4?6A9GEzYs z5f4(*N5}&ObeYA~I28r;?pKUj4N6}iloE=ok%1|X()Ahdwir?xf6QJfY7owe>pPj)Me*}c^%W-pP6`dnX1&6 z`b#*_P0PeM+1FR)t)Rnr22f!@UFBW!TxgjV)u0%_C~gIbb_D3aPhZ~Wmex0)Lj`VoZKjoW)dUoKY6*| z0|V)|XyjiKgZ}s5(SN?te*muif87vD_(wYOiOjOKNI4L*aK||2$~;s25HS#iY6r=)WW8a^dkd0Y|pPc1-9jmy&wqoCbL84`C94At6$lm_o!8m*did^?o$m?ozIp{RmZ*M%YMX_i$KYkz_Q)QK?Fdm)REqf*f=@>C-SnW{Lb;yYfk&2nAC~b}&B@@^fY7g;n(FVh_hy zW}ifIO9T7nSBHBQP5%-&GF8@A-!%wJAjDn{gAg=lV6IJv!|-QEXT+O>3yoZNCSD3V zG$B?5Xl20xQT?c%cCh?mParFHBsMGB=_5hl#!$W@JHM-vKkiwYqr8kZJ06n%w|-bS zE?p&12hR2B+YB$0GQd;40fJd6#37-qd1}xc1mNCeC%PDxb zlK=X|WE*qn2fROb4{oXtJZSyjOFleI3i8RBZ?2u?EEL1W-~L%7<`H6Vp0;cz5vv`7jlTXf-7XGwp}3|Xl6tNaII3GC z9y1w*@jFLl2iFA!<5AQ~e@S|uK4WL9<$R^??V^aM?Bgy=#|wl$D2P$o;06>{f)P+X z91};NrzVV+)b}k2#rYLF0X0-A+eRul=opDju)g0+vd79B%i!Y}*&a^L$_|C&jQN^j z9q#4<(4)3qNst^+ZYpyVF2hP;DN|OMxM9w(+)%kFQRcYVI zO-frej9x6a%-D%Xuwedcw9#3VSVkOjNF!BYRoY1KD3wFJ%?ML*3QwcarMK)@v`o%s z$w=NLrO>og`nRJpZZ(%~*hNJU#Y~k;_Ci3~gc=4UQO!Ydje^?=W^DgCKyO;Zz4LgQ zKtm($MdY;UZ((U_g5*pMY+dYGyyT1ERkaj`U#S-2yyJ47wMonCpV+2rI8zPNHDfo& zc59dFz*2#^A-R?P6Np}jhDLi4&vP%$NW#8J>=CLj1mlf$XzmQezH*F1jNOiPgXl2j zzD07AKLT*h$CA*OsOba2etPLU%|p?=XhplXo?vOu@q0{QBo++)@6U?YKv_)GFK(^Y zm&uFBbrQyzJm;c49O00PIt;|{&ei%VSS%Y3m3#~L#(3%Gso^a4#9AaB$w@vnAvdr6 z%!2#)YS0HFt%o)q6~BelT;?%oUjX%9qQCn#-~+TM(a^s%Y>&aBkL(UY{+?a9@&Q+a;t%c_6u^6_r@>MEAN9ir5q=Yo|R8z4lKYd1sv^LyTozFn$KqaJ>? zoH&+`AX>E03Gv=71+NZK2>!-NasKeCfMp;@5rZ z*m<}q2!$AgKUwWRXTVHs!E>`FcMT|fzJo30W551|6RoE#Q0WPD$fdA>IRD-C=ae&$=Fuzc6q1CNF>b3z_c<9!;))OViz@ zP58XOt`WOQS)r@tD0IiEIo4Umc(5f%J1p{y4F(1&3AzeAP%V)e#}>2%8W9~x^l}S4 zUOc9^;@m{eUDGL={35TN0+kQbN$X~)P>~L?3FD>s;=PIq9f{Xsl)b7D@8JW{!WVi=s?aqGVKrSJB zO-V&R>_|3@u=MEV1AF%!V*;mZS=ZK9u5OVbETOE$9JhOs!YRxgwRS9XMQ0TArkAi< zu1EC{6!O{djvwxWk_cF`2JgB zE{oo?Cyjy5@Et}<6+>vsYWY3T7S-EcO?8lrm&3!318GR}f~VZMy+(GQ#X9yLEXnnX z7)UaEJSIHQtj5?O(ZJQ{0W{^JrD=EqH_h`gxh^HS!~)?S)s<7ox3eeb7lS!XiKNiWDj5!S1ZVr8m*Vm(LX=PFO>N%y7l+73j-eS1>v0g}5&G zp?qu*PR0C>)@9!mP#acrxNj`*gh}21yrvqyhpQQK)U6|hk1wt3`@h^0-$GQCE z^f#SJiU zb@27$QZ^SVuNSI7qoRcwiH6H(ax|Xx!@g__4i%NN5wu0;mM`CSTZjJw96htSu%C7? z#pPQ9o4xEOJ#DT#KRu9mzu!GH0jb{vhP$nkD}v`n1`tnnNls#^_AN-c~PD;MVeGMBhLT0Ce2O2nwYOlg39xtI24v>pzQ zanl2Vr$77%weA<>>iVZQ&*K9_hfmv=tXiu#PVzNA;M@2}l&vaQsh84GX_+hrIfZC= z0Se*ilv-%zoXRHyvAQW9nOI2C$%DlFH1%zP-4r8bEfHjB3;8{WH`gOYt zg+fX)HIleuMKewYtjg+cSVRUIxAD9xCn+MT zs`DA7)Wx;B`ycL8Q&dR8+8mfhK;a^Rw9 zh9tC~qa>%5T{^8THrj^VEl5Do4j4h@nkrBG6+k8CDD~KB=57m@BL-)vXGkKIuVO9v z7t_L5rpY^0y=uu5iNw0v&Ca-zWk>v;fLJ=+SaV&V#C-o^}8 zp&Xp$v?~ccnfR=&5Df)32^d6QJLg*iuF#s|0M4zJF@Hza1p`q|f}~K)q;HC*I1_9t zQ&1jr9-kdUi8)DGxiwdqU|rPxYWDQPWY&SI&Rxkhxobp~C=Y*`d?HD4JW?WjU7dBPeuIE`ABLq95b#lfKS52IB^6KoHmm60$R}TESplQt59#mboJj+Na!P)V{ic@$yQ-&Z za^JU0T+n0Lf2VdusoNr0?g~1DMsY)zdY-63yH!Ii#aWe|;0TO>L7#YlaDrH}xvYXn zh-NYa>O>f_NTTBG=|k0qWH+X?d5@+INsQ}WcI_3z1Z4-%Gj#_{P$0A~cAye`?j0cW z8)hd(V}7rattLUSMvgZ4g96P7n` z^{55A&&29;-P992{yhkGWa3v_Z6iB4a&~NmL)IpC&dsSwe$9jS(4RVJGt=Y!b-O~1 zSCl@wlaba_cA*yt(QvulMcLUuK z>(ys_!{vqKy{%%~d#4ibQ5$yKn6|4Ky0_ngH>x-}h3pHzRt;iqs}KzajS!i!Pqs8c zCP%xI*d=F=6za_0g`{ZO^mAwRk0iwkzKB7D)SaLR0h|ovGF2w9C9g8;f#EtDN*vBP9yl;n=;B2a7#E8(%Bw()z(M$_pu zQ+9uFnlJ!5&$kk^S_+kJ>r9y8MFPpSf9;o8v;ZxsMA!p>eaAIwt5xNiQ|2_ydGkbi zkggG;Xp&I7C8R{>ten^j@MsN#V5JPs1Ezc!74->Nh0a}U){OK@j=OIoY}C7IYYd8-V9 zQ6s?v=Y7(?Y$7=P#Wwub-*0DLqli?I%kT-D^jqK?c2~HEx<2(poRWAUoC}!~6$1=I z*M(IfPmdID8i+5l@=1(+`?i`G_ew=1Y!gF?tFbdgtW2etKLOFoNozkH(i!Qa7(h^| zF`9!VeqQQwM+yO6J`;oWUWq@9l6hP~FiG8-{Pj*T`XI3~s@FfjW2Tl(llpa901$&y`F}K1uZuHEo;=mr+_8d(o z2Be#yWHEN@euC$=VUSB+3A}khJdF$)0r#<5(f3n`kx>ZT8ifaKyX*OhffeHH1?6OM z*-19$j5tMNYQoB)>cGpz@11>J%q4KW`GLNj?uB>LcNg$0G@}XN#Tqf2F5@jv<`|~p zqB^l!%v!g{R_+0GX5z0>3Q~O``%T$NFc==dsPsTj-;{b$XUS0TGoJs2BUA*H;4S?w z|Nigt|F@9hf7QLSo}JPEK#CPgYgTjrdCSChx0yJeRdbXipF(OwV)ZvghYba)5NZxS zm=L8k_7Lb?f8`=vpv(@m%gzsCs9^E$D5Jn+sf}1lep*zz&5V?~qi_@B?-$Vd1ti(rCi*I0}c}slKv@H_+g?#yarVzpYZN zIk21Bz9Z#WOF`JG&TC&C%a*3*`)GJx9I!U8+!#J4}@5rm8*jK%Xg2VLjP-a;H zFydWO;nxOZ&|{yOW;ta$ZU^6*4vFP)idD6M*M0+9buB#hK4z%YTGBdSva?Pvxim2` zF-?QVGuRQ2-1eYzd1Y%}w^`t1S7|{{8=Es#ApC0<;pc$|NJ)IU%WVK+4gnTWA7-t1 z0K{DCESXb}!y_tzrycr^%%|G4T4)`$BC8+qm|n1lS?CO=`V`1T#ykY#5g5$dc$lGt zqGHyw-*Av%C;33nEiU(rU?w^3F46!dEz#cHd3IF<(XCq)>JG?Bi)4v26MQr1A-g5RqhFoPy%^TD3sa|D^9aS>>_2-X2i#? ztVp@ZkyMB;Uo#9s!R!@G#CCaFVaxx*8YYu$kGFk4g3|9t!1nKqOaDBAe;w!(6#w)0 z?{&F2BgctT1=Z;TvjOGL_!}Vlt=kaLA7#W`mv1h%hUg983!wA*K@_r6_cd6o z6LHiCE6qwlt2H&|Ica~%b9C?Z@$dreBNR_!NKcfL)%8kGr7!IVq|^&6PKYK%EhcKu z6+uR*%EOw=rF6Q42Mx|a> z$2XrM*NV2x9ci6|X^eh1UAbJ9Ky!#*Q5w7)#o#%}d!#-^k8To=n8{UU*LmFsS-wRj zi6-p76V6g?If3S&Bj~GW&QI_WtyPY0@u3hjKtqf9`8S!wn{@P&Tc8uu8cf)YmrX7+ zrC+O3V{9}JG6ihA&^2Q7@)Kq)j(Y_oTzsoBUYQDG!}`Ame`bbcr>J-6E%gaBPEDCU zflX#1-)Ih^HJV*lew*N_SdG-4!b2}G8%U&9_V0~Qt?ZS z@H3L&5ybV8X}A@KQADl93H`}0qkNm!jGHkCJUM%r8`mP1nV?Oo%^l;yDnU6IJtbuY z`X2Sf8|r00mB_f)Q0;S{FqS1Yq?otd-BVbw`#@SDd5}n5X4lqdDi1*vtVv8-Zi10q zexCj0eyngrp`UxjEOrdzUt`?%jRlj7zSU-V-%R?y+_w7P7f1ge%t1ozmN+&)%3xQW zT3u@)))(_a<6`lTJd`DIYw>(pkb=PMKvCNEG~zza+LVNqkY^}QoGMVdS0K;gS*A3f z;6Ua!^sSV-try(M^pB6D9dsX}c>$Da#NHucp9vr(fg4pbBR*uPhYq+N>q1X4RSOCl znIQj4=A+y+8{?LQ$3L@(!Yy~~Cu4Sx72*%@dW>eP%Br7=uaynV6Mqa-49A9) z|L&5r=4K5SClwc`!2J|>(#n$4y1>lmR~2Om8q6HkcpK>d(Fk!T^NO?hM4Fc+(5J{` z&K|vrBz;;zWlNO%=a~JkMxMiZa%wYz#G901lw#+2SUaMMHrebb&|1L8tKoGJK*QhJ zU9|WkDy^-4F6U&VYSc3ScHDk@kV^0801#I|-pSK%az5=DwI}gMm)@s2O+-ESTk?QY z;y9gyucaXO(Cc+cd{B>2)euMHFT71$a6DssWU>>oLw4E-7>FC-YgZH1QAbRwmdahD zO4KAeuA^0q&yWS|zLTx%(P4VOqZv-^BO`0OFAXdBNt9>LAXmPALi3b|gt{b?e-$z0 z4n7H$eg6y_zs(c>*4FT!kN*$H`43~1p!g;IZ8-mYbUPTejaLW#BZnAPFES?ApM{TQ zE*TC%O8)apqcX|PrNjIZE-z{q`I(LwIE0kf=PLjExEX>)oIu><<@lt>-Ng9i$Lrk( znGXl|i4dP;Mt^-IbEp7K0e#*c7By@gCo@VQIW$93ujLL`)lMbA9R?C_5u~7^KopaAMj#6&>n-SOWlup_@{4 zcJ?w_!9JKPM=&Bd#IQ37F*x39y!azm$;~IRlkm>bHdABcNwW-TdDKD$pkD{j6A8d* z{vP~|<}bj_Oz#83K$ieRtsA4a@4a5cRjJ}A01{PgxXn3;fx)5ElMEPwDX_mW9)9oB z*;scve~v#HHqUj3KdC$tdV3&0)Whkp-=hKKz{SzD7g0@N!wyv;ZAime7AjB7&)!)5 zp_iVblaf)%agwJqOG2e7WTCM1&khq`{b>fN4n8hOJbvO?Y;60>LIwagLXWC@@0RSR zo%lPo1cUU=g$ahJ8D=;`v~ORUSl(1-&a@yTAC5Y8E892@{P@MM=GXUGpBSXSbSs!N z;L~0D_s7{+^F6c!WW+^yz5~o7eWtsOE}8{hKaFlHgnyBeUJ8Zz2$k7Lrh?NuMU|No zVvsq@57)8zin;&ckR1;*Z%(xH2lBw z`x%N;|H1En8au588bPDxP^$kfpO!bIzz>K=5Jiq9Rg(NGde0g!rKagLa+&yC)jg7y zq}~2IH)N*FJC31qrIH-2;%3^F?=bDD^U2Y;%ftN(v71oY;od+vh!!2z^}GHR$43rg z0In@ki}TglIsMU^O1(SiLK#oiuyw zB>-@z?&uW`ILoPupw0_cs?C|2YoX&87~us+ny%eo{A!3M<-7O7mHUBCgA~{yR!Dc^ zb= z8}s4Ly!GdxEQj7HHr<}iu@%Lu+-bV>EZ6MnB~{v7U59;q<9$h}&0WT;SKRpf2IId ztAjig0@{@!ab z{yVt$e@uJ{3R~8*vfrL03KVF2pS5`oR75rm?1c`@a8e{G$zfx^mA*~d>1x`8#dRm) zFESmEnSSsupfB>h7MipTeE!t>BayDVjH~pu&(FI%bRUpZ*H615?2(_6vNmYwbc^KX4HqSi!&mY9$w zpf%C6vy@O30&3N5#0s_!jDk|6qjb-7wE3YT3DA7q3D`Q&Y*y>XbgE7=g#rPx1hnf8 zTWd{IC!Iysq*vZup5VGrO)UM<3)6raR`rOwk(!ikf3XPp!n|gz0hS*P=VDXAyMW(s zL??-`&IusEuOMrz>m(A1W5Q~>9xJwCExAcMkOBD` zD5BJSadd{0u}%z4r!9qA`FW4;Ka_Qk>FcHxiucGw4L9qhtoge|ag8jbr`7LHSbVQz z6|xUo*^LV1SLxS>?D`m=g{8IC&1YF$e}VRGD#ZOc_15QW%J@FbEj8tE-nGxo4?X02 z@|q#k*G4xMW>q84Xc09pRj@>Hz8t^fMm3n&G;Al6KU*;=W`7Q{$^|=bnZiJ7?(s)@ zB`vW>#zJ{}!8=*|?p(~fcXSanO^j8+q7V!q16*ic!HLRdz0TzNI6}m+=OKd2b8KX< zAcDTj*%~vQlcO+%@H01gjv-1zZaOXVoM*t-+KXTR#NoTf-#{dQAm?GqK6q8Ta zu3xW?t=NE$EfYa#=0HofLn5~c#m-U#Ct_r6~X-pg6k*F zYIP7De52BBwcAnK?O(j?YEs1;q60!-!hTuKzw3T;XcA_w5HvU;tO~}byLA^cggu8i z-IP@pxFjTy&ie28m}j66dm@g78xK7aG{QSR^bAcY+W*xWu;G~I08sf(GK4>K-cbfJ z-%v9DGR77He<291M~=fg>>9&NFQlboP)pC6fT;{>_!lM`A&&HWIMd)Y6e@IL;nvRdBE*Tn({&3{-XJ9helJa{G51Ck}-_Y=5C|fEo z)7fZlsHxN&SY&ZLTdYuBBZnwIh0#VTzmyK>U0|r&SXb&GP0m)1dGV8z(^x6s5yQ-z zEyniK${#U@Y7p@Yxx}E+jA?1@{=|e6UM;iyai=0=aItVvqieogZUq@sio2#9NLW~L z{w@^H!HEGU;>;T0lu{Ad20Hr6u;?-9YHKvkjEc)}wsb4Y-ArRK8`24uBT8N)8m%Ee zYJX21)|e{peL26}VUUKYQ3L@NSe8rEbN#AIo$tjJm-$B|IJU?mu(h$Sq`XNY0@NhY z0?WeMtPwP)sUdk}dWA4qBUV^x>P|is-kPgVe)*WV>dKDL>gOq1 zUYw(nU|N#dw>97A_(c3?VA_zDfF{^A1eE#8Bucd^ON(sv-{tc@&i)Y)3V~o7U~+AA zOwnXB5`WN^z$z<9^@(?LY%7?y5X_C(j1ip-Ug^f7Tt6suI3&a=&~#EJegG4r2^tKz zJoEXCVOc1QdOSNHp2d;t&smxL%CfK@mSl)Ky}`!6kCsi#7s5&G2Q!sM9S6o)&mdx% zz|2M~pav2;Th=DTN5yB@6HFAO!pl-y+tEJsh}(? z!tIyg01O*w@mWxsFhHMi7%Gqz!v(Osc5WxK+^1PGfsozw)FE}VIxk9GexmAohPNAF*SAjxG3Al#(xQoYXdI}TR zoCHAFS6+LDqsP8L1SZH{RxJjFK_=vy4nNH^?M!OsQWe^qC~$c1r&y`H9n5;D z2F$t-Htc%2@K(>opJHE{NytI2<_J<6Kz*p$wtKUTEH}zITx?H0L%!5%i@!rLphSBrkFs>jscP6?HVQovX8!~b~ZY|0h%&souT7e5nD@OxuSgC zVW*eo0B|1POwg7;6fJSUC`g+`1%XQvwpRc*&|AtV*h!#5nQM(@m!K)-Qop!Rt3F`a z9HUO zF3w{uI_==EpjFQWV4boF^A?wc@@@U+KrKPjn6sK{OLu-~1UloSqt-aHYo*^@kQy2+ zH(9*-mFz?YV4cL7EW)9hsdmG{5jaYXLvm*&3PZ4y?8z`$9z6`q9fgsJm@*W$-QSzu zut}57hroSbTd=&RJpuy#?K?A6!-;_MowpK8eb~5T-^eye%3O-T^ktSMbd%PT0j-B?#yAKr37u%gB z*2)WJMw6Y)6BvY$JjD`(06ci7u;u$hv}gN5oS&Q^*y$J6L)0#BD<>XL|;pZgtZaxp3~$0zxA(;6Qr_AP$?8l@S)C^Hoaz#rQFK^lA}3&)Gr}Fsca? zK>9BkVcl;c*E2P9UMppEIB&38dL9R?Xg9N{Nl~4*w!qsZJElz}Xc9gz#}cwnP4u{+ z6VNTEx*>u67?3bn{sWk*P`1_$YfsB+)Ax0+jt|)0p&VS?N0k8IAp2KH_#eY3I#{Hw zB$vObUDtXyZX)*wVh*@BefnUej#jv@%uiA=>ngX0kQXaz>8(WM)fX~v__@I}7|!Il z@J%r#I!JqqFwGd4JPhmDmL>1Bh}nn_BE;hgKUesNOf9zQhiuhn%4B}O8jnxEwJiQFDaiiuXw2sb?*8a}Lr;_#7+IPfIjhVDhazSpbQZECL+4)p8lO;)!y>Rt=0X*;O# zX{s(p-*d{#{Y3gVhL;A{4a(Z5sIfpk;WMCqdFA&Mb7mp;YMXhBF@p`}$ShAug+bo`;<9fm!~F z-;1yCj$GQ^mzucrfuatilXrYLr)`izjn_m(f~);txN?D7d?Kg4wDuPXilVyeVwjzf z=4Kewf=u}X_H*viVfPWZW?Sqa3G#h3|;b!Q7>BRc7-Wox0}&>}Lqo=0v;T_i~% zqB&h;14|~nK{W0N=$obGP@O%(c8SraYS^qiu%Q`B zBHdA!`Vk7#Bz*@_3eE#bizLzjBV;F0vfSA~+7@8+F{$7Y?fwI~Pp_X`2ORgqW6g@2 z{cQV!niSsMEVr1IaeRAj8~|*4yW~X5$6o`crw4uTHhgPs^qAk?9UPu;xy5wh2^jZ; z)@27Q=QKa?8w7_C0|u`@k=%b9Ce$D7x42CdLsckF2<$wLuV2kpik8PXex2^Co$n2o z)l#H*;#>?yrPw0x6LI@x(X$nezCBa0Obi%|I5ZV|4bJSPtNHjDkS|3S?fiv(i_(n* zFbve0g!B0!MMmakRsgg_if8nwImb=kk%|s+08xGQ)J?vpkdaya3UD|RJK+LQ72|g> zc4LnwInx!2pN-5Yvp7rvRF#B=(ZO8gyVB^0Dh#ZdHA2BjjppfV<=2Nm#w_t{%6O$W z`-?7N?LwL0DWgK0Y7L#ChSHfa{=DOpJpl8L@V70cd%ei)n%SQO;Z+Xw#li#%LUfbs z&hP%UzN(qM3cw#bWQS6_B@>1^ea-AqNA12xoiQeb_Zdtf>yHljqeIHqlyC^gzH)h1 zstXTFEb0r=l9;><<$a}YWlscH7VW_xeKVZ#*#v#HiuUOs7PPj8ml4#!BiGEK)kDpO zX=2mU0ZuIDDnhfV7v_Rs)0R#ff6I6_|MrzV(R$3Nt#S7D?GQy6?a^WRvA@r2~?7f~s99*9;fuqJ(843U`hRl2O|sk>J@WMsR2O zwyZt$@J)DnSUNkF@B3MPNz|<@`72{M*S5d<1Vkg+G=q~u{8OP84Yh6VCE5pNC*#m> z*jzHy5Tc82sBVw+6W7DoR5@LXZ|+>;)Q%czg%8pyMyeE2-)R^oHg~SrO~#I8MxNc> z6pWT&F&H1mX7#2@mBY>#rRoFKszT z(gvV#j3x|7sF|Dt0*CgsJTdH1R!>inYZWp*2RDbjjQCP98L_ds!$x&{t85NRYk4ii ztJ3HyC8h2A2&`kq^Cfci>N*r&btHg_|v6=s|v=(-MQ zK4kjqoI^~y`j9poC2r{Izdlehm8!AcMP^+SwDUce1Zon(%YvxK)x|rXsJRlO?-K91 zMsmHgI&PmqT_W}C0mdA_6L!EEjgJzidRvTN;vQRJ-uBl#{dEeN?24PRwx)7c5kF^ut=M0)e@zr?z_vpYf=%;;@UYF9>9-->Qf2FW*# z5*#VFB$$-k(zphh4sAElMiLbp`$+SKm*{l6qX;Q8GZ7b|J>OhC!yg$}8dt$dx3E8b z$FlaM*K@6mSsYCoe#*QjLEB3|_Vs4GbZI#!>Ya}dzh%uMn}sw0gFQQ{+V+e|_`q)M3nK27)nAqQ-viJoPHUKdr9HN`v0 z+tZo0ORLuv_d)x}gO|~s(H!12RM(aMfqLG>KSH#kGxC{sUUj>FUC(6;ds1cOjeDYu zOrd>q@bNFq5?0s&@5nbF3-rw{{V&YYf3o_9|K-X4k861UwZ&C2bH+A7^%7nizU>b? zC2@*VlrqprJiv$rx{+^+Op9i3RM;IHq@a;34=Gn%B+rXMZi=UsHC@TEFk4{*fs96p z)wNUY?AhVkdLGQmPESuh@-!iqSZrnxIT~Mon)J+i+B~9VdL8QE`^4=2@lNaKluUVx z_^i7~5E4dN4&gVMi%;7ast@WIY21Q`+^iTC*Gx@IMVYB`BLFHzPh{Fpc6LKZTk@>P zquo2E*Pgq(0MX>h>4)YaJYbIK&V?-W}JfL@&R0I2)TOA!Teg zNa4DBO&)`Nn0$Inb|d8ea|)qqOLYVbQIBRC4T4E<5#Nzc2 z57|Bq7mYsW8y?uLA$XMj%OeK+1|DAKcLYB98-vDP<3*+SKYcPcOkm&}H|!{9l*9%L zbiYJYJ^)Cql-&wPwABGD>Ai7SUXe15m zIr^wNEU$9)D6@atm z(w(1~GuLpHi?JGgIBj`Ovy;j4M`XjrCNs?JsGh1zKsZ{8 z@%G?i>LaU7#uSQLpypocm*onI)$8zFgVWc7_8PVuuw>u`j-<@R$Of}T`glJ!@v*N^ zc(T~+N+M!ZczPSXN&?Ww(<@B=+*jZ+KmcpB8* zDY_1bZ3fwTw|urH{LLWB;DCGzz$jD|VX#Af@HC%BktA8F7VJSy&!5iTt};#U^e0_q zh6j7KCTInKqriZ1`BiF3iq2LWk;gyt0ORIFc4Mi3Bx`7WEuFq{u^C49-SYVjnv!_40m1>7x*+<8~Xkq?056 z!RBfE@osP%SxzOw>cLAQ$bioAOC0V!OzIXIc};)8HjfPtc~8tnah$PtoAz`4k)7$FDUc2O@D)g_uAo&nXMymK$##V?gYUPt^l zj{6NFDL(l-Rh(xkAHP%bBa=($r%3Y~jB!eQ1Smuq2iuQ|>n%Y=p(26SE5gFu11*Q< zaPN5G^d;Iovf`VY&Gh58z~%JpGzaeUz6QoBL^J%+U4|30w7Q&g9i}}@l61eKEfCgo zST6qMxF_Eaj7;0OC)TSU{4_m}%FOa6B{AxS$QIcmmG~IVjjf;7Uk!HBtHfm{%LsLb zu8~5VQFyOZk&!VY(wxL__haJ;>Bj?g&n`+i&=X{unJmv&0whCitWfGlOr6+Tc-lMZ z(ZRXqC-=O+GAvTXKViA9vdwu{aifhk$tYh~-9BScg!Yr*M2zw&9`pHMxHGh`dUH-1;~^6lF@ep;X9PjQ!rqmXNWJ?#P-qb%*TB%xe&3 zX*5V>xuW7)$3!Yc$y>cwBqd8+p+u>WS7p7~O80ipG{(a*#=NJ`^Ld6k-`|;Y&htFy zIi2(Sm)4eD=o+CGo~M3%qF|O9P0+ahmc%EklI?NgX05W3+OdS`_Rd#wg-}hd1&txU5wXy zy`x)05?WVZvELw`XWetIAg6$|(^4ntaE;=f$Wcpwbxm7?bLDnPs-1!bRoMcy!EeOh zpIv8ewDzcIU}mv1NxV!&(Wf7~_kqGAk=2=j&O5FA)z2!APCcDQPnIaiqMkVT4fUyX z))R|WvOJyzcU6d=z0q8JDt42*`js4g+_t{YP7lVguX+vhEejJ3TAIo*Z6jizHm#S- zZT_}-STQAa-0Gn8+RmR7V}{Ns1@jJ{^Sb!9&RSXXP;^ep)r6;&PW++~XYXC9a=zSF z?sp(JQo&MROb~b1Y*Xw4!P)>PHT>Z<)*U=Ax_75^OUw97pNudbxS1XPtNrIg zQ5YB77E@i7$2Ia}(^JcCi@OX`9a|m}PY%-th2m~y+)eCl>fTVjCP^lDOBLyhg1DZ+ z)~G{&OkDc$!;t~`gq(wz@qW3lh9B^ic$>-h#nV!H8d#l+>C(M%g}u2g=I#&W|L!VD zqHYoQkBW;`r|fW02u{7X!X;}T7X4iAaWzkeOh}7&o!F1qt4#$1|BDF;(2VlgEqJ$F zy8Ba-y(%fs`MzpvyXlQLEhS^ed$7Va2hO%?$-D>^*f$b)2Hx;}Ao$UqFt7l26<7eP z!{!C7PVrq>=794Zqmc z%LKkzIBZq@%Ja8EkH}?>c5ILG(EAMS*JHu?#9_7TsELw)8LZzN>f2Y6YN{AJC?34> zh42sPa1%2JpCeS9&E1URm+Pb}B>A1M`R{+O+2~}c(@^1Rf&J9p(4QqHl;E^4w5;I5 zM{?(A^eg*6DY_kI*-9!?If^HaNBfuh*u==X1_a?8$EQ3z!&;v2iJ``O7mZh%G)(O8 ze<4wX?N94(Ozf9`j+=TZpCbH>KVjWyLUe*SCiYO=rFZ4}S~Tq|ln75Jz7$AcKl$=hub=-0RM1s(0WMmE`(OPtAj>7_2I5&76hu2KPIA0y;9{+8yKa;9-m??hIE5t`5DrZ8DzRsQ+{p1jk-VFL9U z2NK_oIeqvyze>1K%b|V?-t;Wv`nY~?-t;tMC4ozyk8CR(hoZTno3!*8ZTc15`?MFf zDI892&g&3lshOEv4E@w-*_%)8C_<&HhV`0D5lN$WT4Q^UWHNSAE+RZe(o z%bqR^hp1IsDr47e^AajFtlppT)2F6yPcrWO9{Kw{o=P6y^HOW$Wqd_)_fwzn`ikZl zOGVc0+S(*=xZ_KbL0Nr`Sx$$CWEbw$52udl1f=X6CZEcFMA*nl>`0gn4&tc5^`!!)tGw<}^Q>P7E}$ zialDUofH*XcB3r9@tA@lnS}dA(@nK_xuw0b;FPUnNGD0;MIySCw=cSzB#=3>F37V-nni3UNB)-;;Gkk;3l9fh6FIjSZU zk=Eo2a`6i7@i*4>ym5`R?i-uZFv6+iX*Gi^I}ZU1OrLAX8aGiT@`*YnjeF>}$U}ORP`+EY5`eqVC_&4yG z;Tp>+2QbZ?lt1GB+D}q14W3dWP8lWnN zf(nlT6+XW&(zme{FbyDpP^NakA<~TK=Y}H^eS%2rt0v8Lr)B}@B!cTvC=9FM;7q4@ zf*;vb4HG>RFpY5?vFCp27VEnVIGx~-na6biU4{+UoYe=}^R#_My6wT$5d&r*=kpAA zu;=-c0|~yqi(N8&*H;aNfhyey+HHQ7J_qae*_CgG2V8j=Tq936S0DC8r3BXBql3Gz z0pLo_`|4Q+oY3rPBNaLmL{QM};9dke>ujP^j@z-N;fNlKb|edn>)YaafDaJ>GWKP$ z5}l&#$QFhN!CMT;WH&z-5E)kvM|36lV!^#3z{@2FF>HsgUO4PMqO#U$X%+U>K!xJ@ zBFs|+woG_9HZQs_Tw*vnCPGhlXG@>y|6pJT$I67!aP&b0o$AF2JwFy9OoapQAk>k7 z**+$_5L;5fKof<;NBX%_;vP@eyD=Z0(QW)5AF7 zp|=tk3p?5)*e~Inuydz-U?%Kuj4%zToS5I|lolPT!B)ZuRVkVa>f*-2aPeV3R79xh zB)3A$>X~szg#}>uNkpLPG#3IKyeMHM*pUuV5=-Jji7S6PSQ9oCLo{oXxzOZfF$PP) zrYwlmSQ-~n94uO3CD{K0QTmj@g%Yzn7_xQ4fTduU0Yqvln`e_`CdXH5iQ5qRr1 zBC;}%YZ2!4I>*=sR)O~jBPx6sxmIEBnq)s-fHz_y0z8-gPl2Us4BiBXNR5CIF!YR@ zb9B305SilU*@4|+ x6JBtc8JSt5M0pkooaq!^FqtuD_KdXXTo>Mw54>`rP&>h&58!3a6l6r9{sG7g--!SK literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..b7c8c5dbf5 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000000..2fe81a7d95 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..62bd9b9cce --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh old mode 100644 new mode 100755 From ed6d4d25bd4e34461919ffe785a6f10f4c087552 Mon Sep 17 00:00:00 2001 From: lzq Date: Sat, 5 Aug 2023 15:24:02 +0800 Subject: [PATCH 02/57] Bump gradle and lib version --- build.gradle | 9 +- gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 63375 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 281 ++++++++++++++--------- gradlew.bat | 195 ++++++++-------- 5 files changed, 273 insertions(+), 216 deletions(-) diff --git a/build.gradle b/build.gradle index 885198fcfa..a388517ae1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'application' - id 'com.github.johnrengelman.shadow' version '5.1.0' + id 'com.github.johnrengelman.shadow' version '7.1.2' } repositories { @@ -9,8 +9,8 @@ repositories { } dependencies { - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.5.0' - testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.5.0' + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' + testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' } test { @@ -28,12 +28,13 @@ test { } application { - mainClassName = "seedu.duke.Duke" + mainClass.set("seedu.duke.Duke") } shadowJar { archiveBaseName = "duke" archiveClassifier = null + dependsOn("distZip", "distTar") } run{ diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index f3d88b1c2faf2fc91d853cd5d4242b5547257070..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 43723 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 delta 38942 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b7c8c5dbf5..66c01cfeba 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 2fe81a7d95..fcb6fca147 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ -#!/usr/bin/env sh +#!/bin/sh # -# Copyright 2015 the original author or authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,78 +17,110 @@ # ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -97,87 +129,120 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=`expr $i + 1` + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 62bd9b9cce..6689b85bee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,103 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 4b12bd630068eddc46a497eb0bacd4eb5b6cd30c Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 13:50:52 +0800 Subject: [PATCH 03/57] rename --- src/main/java/{Duke.java => Dude.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/{Duke.java => Dude.java} (94%) diff --git a/src/main/java/Duke.java b/src/main/java/Dude.java similarity index 94% rename from src/main/java/Duke.java rename to src/main/java/Dude.java index 5d313334cc..84ffc8d3af 100644 --- a/src/main/java/Duke.java +++ b/src/main/java/Dude.java @@ -1,4 +1,4 @@ -public class Duke { +public class Dude { public static void main(String[] args) { String logo = " ____ _ \n" + "| _ \\ _ _| | _____ \n" From a6f13d3c9e8d57d81c0b91954d960e55bd88cbf8 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 13:54:26 +0800 Subject: [PATCH 04/57] greet & exit --- src/main/java/Dude.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 84ffc8d3af..3692c1eb80 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,10 +1,14 @@ public class Dude { public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); +// String logo = " ____ _ \n" +// + "| _ \\ _ _| | _____ \n" +// + "| | | | | | | |/ / _ \\\n" +// + "| |_| | |_| | < __/\n" +// + "|____/ \\__,_|_|\\_\\___|\n"; + String greeting = "Hello, I'm Dude! \n" + + "What can I do for you?"; + String exit = "Bye. Hope to see you again soon!"; + System.out.println(greeting); + System.out.println(exit); } } From 6ae3cc1187cea177e5bf90f51a98e7ee5945d898 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 15:19:21 +0800 Subject: [PATCH 05/57] echo --- src/main/java/Dude.java | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 3692c1eb80..85d7838ad0 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,14 +1,29 @@ +import java.util.Scanner; + public class Dude { + + public static void bye() { + String greeting = "Bye. Hope to see you again soon!"; + System.out.println(greeting); + } + public static void main(String[] args) { -// String logo = " ____ _ \n" -// + "| _ \\ _ _| | _____ \n" -// + "| | | | | | | |/ / _ \\\n" -// + "| |_| | |_| | < __/\n" -// + "|____/ \\__,_|_|\\_\\___|\n"; String greeting = "Hello, I'm Dude! \n" + "What can I do for you?"; - String exit = "Bye. Hope to see you again soon!"; System.out.println(greeting); - System.out.println(exit); +// System.out.print( "Type some data for the program: " ); + + while (true) { + Scanner scanner = new Scanner(System.in); + String input = scanner.nextLine(); + + if (input.equals("bye")) { + greeting = "Bye. Hope to see you again soon!"; + System.out.println(greeting); + break; + } + + System.out.println(input); + } } -} +} \ No newline at end of file From cfc7c19c6049d628d97d7c73e21026ff47873e5a Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 15:44:46 +0800 Subject: [PATCH 06/57] store & list --- src/main/java/Dude.java | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 85d7838ad0..0466931b60 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -2,6 +2,20 @@ public class Dude { + static String[] taskList = new String[100]; + static int nTasks = 0; + + public static void addTask(String task) { + taskList[nTasks] = task; + nTasks += 1; + System.out.printf("added %s \n", task); + } + + public static void list() { + for (int i = 0; i < nTasks; i++) { + System.out.printf("%d. %s \n", i + 1, taskList[i]); + } + } public static void bye() { String greeting = "Bye. Hope to see you again soon!"; System.out.println(greeting); @@ -11,19 +25,21 @@ public static void main(String[] args) { String greeting = "Hello, I'm Dude! \n" + "What can I do for you?"; System.out.println(greeting); -// System.out.print( "Type some data for the program: " ); while (true) { Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); - if (input.equals("bye")) { - greeting = "Bye. Hope to see you again soon!"; - System.out.println(greeting); + if (input.equals("list")) { + list(); + } else if (input.equals("bye")) { + bye(); break; + } else { + addTask(input); } - System.out.println(input); + } } } \ No newline at end of file From ae180ceec8b3da7a6e309aa679bb29ac05a25aeb Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 16:37:17 +0800 Subject: [PATCH 07/57] task class --- src/main/java/Dude.java | 21 +++++++++++++++------ src/main/java/Task.java | 21 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 src/main/java/Task.java diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 0466931b60..b7eed66881 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -2,20 +2,28 @@ public class Dude { - static String[] taskList = new String[100]; + static Task[] taskList = new Task[100]; static int nTasks = 0; public static void addTask(String task) { - taskList[nTasks] = task; + Task newTask = new Task(task); + taskList[nTasks] = newTask; nTasks += 1; - System.out.printf("added %s \n", task); + System.out.printf("added %s \n", newTask.getDescription()); } public static void list() { + String doneStatus = "[ ]"; for (int i = 0; i < nTasks; i++) { - System.out.printf("%d. %s \n", i + 1, taskList[i]); + Task task = taskList[i]; + if (task.isDone()) { + doneStatus = "[x]"; + } + System.out.printf("%d. %s %s \n", i + 1, doneStatus, task.getDescription()); + doneStatus = "[ ]"; } } + public static void bye() { String greeting = "Bye. Hope to see you again soon!"; System.out.println(greeting); @@ -29,10 +37,11 @@ public static void main(String[] args) { while (true) { Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); + String[] words = input.split(" "); - if (input.equals("list")) { + if (words[0].equals("list")) { list(); - } else if (input.equals("bye")) { + } else if (words[0].equals("bye")) { bye(); break; } else { diff --git a/src/main/java/Task.java b/src/main/java/Task.java new file mode 100644 index 0000000000..be719d15bf --- /dev/null +++ b/src/main/java/Task.java @@ -0,0 +1,21 @@ +public class Task { + private String description; + private boolean done; + + Task(String description) { + this.description = description; + this.done = false; + } + + public boolean isDone() { + return this.done; + } + + public String getDescription() { + return this.description; + } + + public void setDone(boolean done) { + this.done = done; + } +} From 07d666a77604d993ac2f24556ce7e55f17f31b97 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 16:37:50 +0800 Subject: [PATCH 08/57] mark & unmark --- src/main/java/Dude.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index b7eed66881..37ac846167 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -24,6 +24,18 @@ public static void list() { } } + public static void mark(int n) { + taskList[n-1].setDone(true); + System.out.println("Nice! I've marked this task as done:"); + System.out.printf("%d. [x] %s \n", n, taskList[n-1].getDescription()); + } + + public static void unmark(int n) { + taskList[n-1].setDone(false); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.printf("%d. [ ] %s \n", n, taskList[n-1].getDescription()); + } + public static void bye() { String greeting = "Bye. Hope to see you again soon!"; System.out.println(greeting); @@ -44,6 +56,10 @@ public static void main(String[] args) { } else if (words[0].equals("bye")) { bye(); break; + } else if (words[0].equals("mark")) { + mark(Integer.valueOf(words[1])); + } else if (words[0].equals("unmark")) { + unmark(Integer.valueOf(words[1])); } else { addTask(input); } From 4cec3c5b487cf68908036ea47d2395c546f4f6fc Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 16:47:01 +0800 Subject: [PATCH 09/57] lvl4 todo, event & deadline classes --- src/main/java/Deadline.java | 5 +++++ src/main/java/Dude.java | 2 +- src/main/java/Event.java | 5 +++++ src/main/java/ToDo.java | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/main/java/Deadline.java create mode 100644 src/main/java/Event.java create mode 100644 src/main/java/ToDo.java diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java new file mode 100644 index 0000000000..f3c2628a9d --- /dev/null +++ b/src/main/java/Deadline.java @@ -0,0 +1,5 @@ +public class Deadline extends Task { + Deadline(String description) { + super(description); + } +} diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 37ac846167..085ef1d6f8 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -60,7 +60,7 @@ public static void main(String[] args) { mark(Integer.valueOf(words[1])); } else if (words[0].equals("unmark")) { unmark(Integer.valueOf(words[1])); - } else { + } else if (words[0].equals("todo")) { addTask(input); } diff --git a/src/main/java/Event.java b/src/main/java/Event.java new file mode 100644 index 0000000000..41a7f2935f --- /dev/null +++ b/src/main/java/Event.java @@ -0,0 +1,5 @@ +public class Event extends Task { + Event(String description) { + super(description); + } +} diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java new file mode 100644 index 0000000000..84f97da107 --- /dev/null +++ b/src/main/java/ToDo.java @@ -0,0 +1,5 @@ +public class ToDo extends Task { + ToDo(String description) { + super(description); + } +} From a056e50c7a0d56c8be62157b349a313442e1d75a Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 23 Aug 2023 17:32:06 +0800 Subject: [PATCH 10/57] lvl4 todo --- src/main/java/Deadline.java | 6 ++++++ src/main/java/Dude.java | 26 +++++++++++++++----------- src/main/java/Event.java | 6 ++++++ src/main/java/Task.java | 4 ++++ src/main/java/ToDo.java | 6 ++++++ 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index f3c2628a9d..42e0adca04 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,5 +1,11 @@ public class Deadline extends Task { + private String type; Deadline(String description) { super(description); + this.type = "D"; + } + + public String getType() { + return this.type; } } diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 085ef1d6f8..b2968f7a4f 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -5,35 +5,39 @@ public class Dude { static Task[] taskList = new Task[100]; static int nTasks = 0; - public static void addTask(String task) { - Task newTask = new Task(task); - taskList[nTasks] = newTask; + public static void addTask(String taskType, String task) { + if (taskType.equals("todo")) { + ToDo newTask = new ToDo(task); + taskList[nTasks] = newTask; + System.out.printf("Got it. I've added this task:\n [T][ ] %s\n", task); + } + nTasks += 1; - System.out.printf("added %s \n", newTask.getDescription()); + System.out.printf("Now you have %d tasks in the list. \n", nTasks); } public static void list() { - String doneStatus = "[ ]"; + String doneStatus = " "; for (int i = 0; i < nTasks; i++) { Task task = taskList[i]; if (task.isDone()) { - doneStatus = "[x]"; + doneStatus = "X"; } - System.out.printf("%d. %s %s \n", i + 1, doneStatus, task.getDescription()); - doneStatus = "[ ]"; + System.out.printf("%d. [%s][%s] %s \n", i + 1, task.getType(), doneStatus, task.getDescription()); + doneStatus = " "; } } public static void mark(int n) { taskList[n-1].setDone(true); System.out.println("Nice! I've marked this task as done:"); - System.out.printf("%d. [x] %s \n", n, taskList[n-1].getDescription()); + System.out.printf("%d. [%s][X] %s \n", n, taskList[n-1].getType(), taskList[n-1].getDescription()); } public static void unmark(int n) { taskList[n-1].setDone(false); System.out.println("OK, I've marked this task as not done yet:"); - System.out.printf("%d. [ ] %s \n", n, taskList[n-1].getDescription()); + System.out.printf("%d. [%s][ ] %s \n", n, taskList[n-1].getType(), taskList[n-1].getDescription()); } public static void bye() { @@ -61,7 +65,7 @@ public static void main(String[] args) { } else if (words[0].equals("unmark")) { unmark(Integer.valueOf(words[1])); } else if (words[0].equals("todo")) { - addTask(input); + addTask("todo", input.substring(5)); } diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 41a7f2935f..7e675656f1 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,5 +1,11 @@ public class Event extends Task { + private String type; Event(String description) { super(description); + this.type = "E"; + } + + public String getType() { + return this.type; } } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index be719d15bf..42c002c97d 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -18,4 +18,8 @@ public String getDescription() { public void setDone(boolean done) { this.done = done; } + + public String getType() { + return "task"; + } } diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java index 84f97da107..3dc0122125 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/ToDo.java @@ -1,5 +1,11 @@ public class ToDo extends Task { + private String type; ToDo(String description) { super(description); + this.type = "T"; + } + + public String getType() { + return this.type; } } From acbfead0bb0ded72b36cd925e8ca94f37d751145 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Thu, 24 Aug 2023 00:20:42 +0800 Subject: [PATCH 11/57] lvl4 create todos, events, deadlines --- src/main/java/Deadline.java | 13 ++++++---- src/main/java/Dude.java | 48 ++++++++++++++++++++++++------------- src/main/java/Event.java | 15 ++++++++---- src/main/java/Task.java | 9 +++++++ src/main/java/ToDo.java | 9 +++---- 5 files changed, 64 insertions(+), 30 deletions(-) diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 42e0adca04..174f3c32e1 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,11 +1,14 @@ public class Deadline extends Task { - private String type; - Deadline(String description) { + private String by; + Deadline(String description, String by) { super(description); - this.type = "D"; + this.by = by; } - public String getType() { - return this.type; + return "deadline"; + } + @Override + public String toString() { + return "[D]" + super.toString() + " (by: " + by + ")"; } } diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index b2968f7a4f..dc6b875524 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -5,39 +5,45 @@ public class Dude { static Task[] taskList = new Task[100]; static int nTasks = 0; - public static void addTask(String taskType, String task) { - if (taskType.equals("todo")) { - ToDo newTask = new ToDo(task); - taskList[nTasks] = newTask; - System.out.printf("Got it. I've added this task:\n [T][ ] %s\n", task); - } - + public static void addTodo(String task) { + ToDo newTask = new ToDo(task); + taskList[nTasks] = newTask; + System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); + nTasks += 1; + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + public static void addDeadline(String task, String by) { + Deadline newTask = new Deadline(task, by); + taskList[nTasks] = newTask; + System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); + nTasks += 1; + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + public static void addEvent(String task, String from, String to) { + Event newTask = new Event(task, from, to); + taskList[nTasks] = newTask; + System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); nTasks += 1; System.out.printf("Now you have %d tasks in the list. \n", nTasks); } public static void list() { - String doneStatus = " "; for (int i = 0; i < nTasks; i++) { Task task = taskList[i]; - if (task.isDone()) { - doneStatus = "X"; - } - System.out.printf("%d. [%s][%s] %s \n", i + 1, task.getType(), doneStatus, task.getDescription()); - doneStatus = " "; + System.out.printf("%d %s\n", i+1, task.toString()); } } public static void mark(int n) { taskList[n-1].setDone(true); System.out.println("Nice! I've marked this task as done:"); - System.out.printf("%d. [%s][X] %s \n", n, taskList[n-1].getType(), taskList[n-1].getDescription()); + System.out.printf("%d. %s\n", n, taskList[n-1].toString()); } public static void unmark(int n) { taskList[n-1].setDone(false); System.out.println("OK, I've marked this task as not done yet:"); - System.out.printf("%d. [%s][ ] %s \n", n, taskList[n-1].getType(), taskList[n-1].getDescription()); + System.out.printf("%d. %s\n", n, taskList[n-1].toString()); } public static void bye() { @@ -65,10 +71,20 @@ public static void main(String[] args) { } else if (words[0].equals("unmark")) { unmark(Integer.valueOf(words[1])); } else if (words[0].equals("todo")) { - addTask("todo", input.substring(5)); + addTodo(input.substring(5)); + } else if (words[0].equals("deadline")) { + String[] taskWords = input.substring(9).split(" /"); + String by = taskWords[1].substring(3); + addDeadline(taskWords[0], by); + } else if (words[0].equals("event")) { + String[] taskWords = input.substring(6).split(" /"); + String from = taskWords[1].substring(5); + String to = taskWords[2].substring(3); + addEvent(taskWords[0], from, to); } + } } } \ No newline at end of file diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 7e675656f1..214efc96f6 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,11 +1,16 @@ public class Event extends Task { - private String type; - Event(String description) { + private String from; + private String to; + Event(String description, String from, String to) { super(description); - this.type = "E"; + this.from = from; + this.to = to; } - public String getType() { - return this.type; + return "event"; + } + @Override + public String toString() { + return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; } } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index 42c002c97d..bdd7da6aae 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -22,4 +22,13 @@ public void setDone(boolean done) { public String getType() { return "task"; } + + @Override + public String toString() { + String doneStatus = "[ ]"; + if (this.isDone()) { + doneStatus = "[X]"; + } + return doneStatus + " " + this.description; + } } diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java index 3dc0122125..1c50b56327 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/ToDo.java @@ -1,11 +1,12 @@ public class ToDo extends Task { - private String type; ToDo(String description) { super(description); - this.type = "T"; } - public String getType() { - return this.type; + return "todo"; + } + @Override + public String toString() { + return "[T]" + super.toString(); } } From 0dadc7273a4bfb1555d278ea33b42381a8a57de6 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Fri, 1 Sep 2023 12:07:56 +0800 Subject: [PATCH 12/57] lvl 5 handle errors --- src/main/java/Dude.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index dc6b875524..19bba17fd9 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -30,7 +30,7 @@ public static void addEvent(String task, String from, String to) { public static void list() { for (int i = 0; i < nTasks; i++) { Task task = taskList[i]; - System.out.printf("%d %s\n", i+1, task.toString()); + System.out.printf("%d. %s\n", i+1, task.toString()); } } @@ -71,16 +71,28 @@ public static void main(String[] args) { } else if (words[0].equals("unmark")) { unmark(Integer.valueOf(words[1])); } else if (words[0].equals("todo")) { - addTodo(input.substring(5)); + if (words.length > 1) { + addTodo(input.substring(5)); + } else { + System.out.println("OOPS!!! The description of a todo cannot be empty."); + } } else if (words[0].equals("deadline")) { + if (words.length == 1) { + System.out.println("OOPS!!! The description of a deadline cannot be empty."); + } String[] taskWords = input.substring(9).split(" /"); String by = taskWords[1].substring(3); addDeadline(taskWords[0], by); } else if (words[0].equals("event")) { + if (words.length == 1) { + System.out.println("OOPS!!! The description of an event cannot be empty."); + } String[] taskWords = input.substring(6).split(" /"); String from = taskWords[1].substring(5); String to = taskWords[2].substring(3); addEvent(taskWords[0], from, to); + } else { + System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); } From 91b96cfd20270856a02d67b1730a00b36be33621 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Fri, 1 Sep 2023 12:21:09 +0800 Subject: [PATCH 13/57] lvl 6 delete --- src/main/java/Dude.java | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 19bba17fd9..f3ffbf3d1f 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,49 +1,67 @@ import java.util.Scanner; +import java.util.ArrayList; public class Dude { - static Task[] taskList = new Task[100]; +// static Task[] taskList = new Task[100]; + static ArrayList taskList = new ArrayList(); static int nTasks = 0; public static void addTodo(String task) { ToDo newTask = new ToDo(task); - taskList[nTasks] = newTask; +// taskList[nTasks] = newTask; + taskList.add(newTask); System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); nTasks += 1; System.out.printf("Now you have %d tasks in the list. \n", nTasks); } public static void addDeadline(String task, String by) { Deadline newTask = new Deadline(task, by); - taskList[nTasks] = newTask; +// taskList[nTasks] = newTask; + taskList.add(newTask); System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); nTasks += 1; System.out.printf("Now you have %d tasks in the list. \n", nTasks); } public static void addEvent(String task, String from, String to) { Event newTask = new Event(task, from, to); - taskList[nTasks] = newTask; +// taskList[nTasks] = newTask; + taskList.add(newTask); System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); nTasks += 1; System.out.printf("Now you have %d tasks in the list. \n", nTasks); } + public static void delete(int n) { + Task removedTask = taskList.get(n-1); + taskList.remove(n-1); + nTasks -= 1; + System.out.println("Noted. I've removed this task:"); + System.out.println(removedTask.toString()); + System.out.printf("Now you have %d tasks in the list.\n", nTasks); + + } + public static void list() { for (int i = 0; i < nTasks; i++) { - Task task = taskList[i]; + Task task = taskList.get(i); +// Task task = taskList[i]; System.out.printf("%d. %s\n", i+1, task.toString()); } } public static void mark(int n) { - taskList[n-1].setDone(true); +// taskList[n-1].setDone(true); + taskList.get(n-1).setDone(true); System.out.println("Nice! I've marked this task as done:"); - System.out.printf("%d. %s\n", n, taskList[n-1].toString()); + System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); } public static void unmark(int n) { - taskList[n-1].setDone(false); +// taskList[n-1].setDone(false); + taskList.get(n-1).setDone(false); System.out.println("OK, I've marked this task as not done yet:"); - System.out.printf("%d. %s\n", n, taskList[n-1].toString()); + System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); } public static void bye() { @@ -91,6 +109,8 @@ public static void main(String[] args) { String from = taskWords[1].substring(5); String to = taskWords[2].substring(3); addEvent(taskWords[0], from, to); + } else if (words[0].equals("delete")) { + delete(Integer.valueOf(words[1])); } else { System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); } From 2445b298feeb5a282cbfc6d022d12a8f14c17cd8 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 6 Sep 2023 20:07:50 +0800 Subject: [PATCH 14/57] add text ui testing --- src/main/java/Dude.java | 2 +- text-ui-test/EXPECTED.TXT | 9 ++------- text-ui-test/runtest.sh | 2 +- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index f3ffbf3d1f..58e76349d7 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -70,7 +70,7 @@ public static void bye() { } public static void main(String[] args) { - String greeting = "Hello, I'm Dude! \n" + + String greeting = "Hello, I'm Dude!\n" + "What can I do for you?"; System.out.println(greeting); diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 657e74f6e7..9324a30ad9 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,7 +1,2 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - +Hello, I'm Dude! +What can I do for you? diff --git a/text-ui-test/runtest.sh b/text-ui-test/runtest.sh index c9ec870033..93cffedca9 100644 --- a/text-ui-test/runtest.sh +++ b/text-ui-test/runtest.sh @@ -20,7 +20,7 @@ then fi # run the program, feed commands from input.txt file and redirect the output to the ACTUAL.TXT -java -classpath ../bin Duke < input.txt > ACTUAL.TXT +java -classpath ../bin Dude < input.txt > ACTUAL.TXT # convert to UNIX format cp EXPECTED.TXT EXPECTED-UNIX.TXT From 8f55d5e326d3e92c1f344ff93ffcea85c138b60f Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 6 Sep 2023 23:09:12 +0800 Subject: [PATCH 15/57] add save tasks and load task --- data/dude.txt | 3 ++ src/main/java/Deadline.java | 13 ++++++ src/main/java/Dude.java | 91 +++++++++++++++++++++++++++++++++++-- src/main/java/Event.java | 13 ++++++ src/main/java/Task.java | 1 + src/main/java/ToDo.java | 12 +++++ 6 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 data/dude.txt diff --git a/data/dude.txt b/data/dude.txt new file mode 100644 index 0000000000..6089c4283b --- /dev/null +++ b/data/dude.txt @@ -0,0 +1,3 @@ +T | 0 | borrow book +D | 0 | return book | Sunday +E | 0 | project meeting | Mon 2pm | 4pm diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 174f3c32e1..8236ba967f 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -4,10 +4,23 @@ public class Deadline extends Task { super(description); this.by = by; } + @Override public String getType() { return "deadline"; } @Override + public String saveTask() { + String data = "D | "; + if (this.isDone()) { + data += "1 | "; + } else { + data += "0 | "; + } + data += this.getDescription(); + data = data + " | " + this.by + "\n"; + return data; + } + @Override public String toString() { return "[D]" + super.toString() + " (by: " + by + ")"; } diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 58e76349d7..89cbb45485 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,12 +1,14 @@ +import java.io.*; import java.util.Scanner; import java.util.ArrayList; public class Dude { -// static Task[] taskList = new Task[100]; static ArrayList taskList = new ArrayList(); static int nTasks = 0; + private static final String FILE_PATH = "./data/dude.txt"; + public static void addTodo(String task) { ToDo newTask = new ToDo(task); // taskList[nTasks] = newTask; @@ -51,14 +53,12 @@ public static void list() { } public static void mark(int n) { -// taskList[n-1].setDone(true); taskList.get(n-1).setDone(true); System.out.println("Nice! I've marked this task as done:"); System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); } - public static void unmark(int n) { -// taskList[n-1].setDone(false); + public static void unmark(int n) throws IOException { taskList.get(n-1).setDone(false); System.out.println("OK, I've marked this task as not done yet:"); System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); @@ -69,11 +69,87 @@ public static void bye() { System.out.println(greeting); } - public static void main(String[] args) { + public static void saveTasksToDisk() throws IOException { + String directoryPath = "./data"; + String filePath = "./data/dude.txt"; + + File directory = new File(directoryPath); + if (!directory.exists()) { + if (directory.mkdirs()) { + System.out.println("Directory created at: " + directoryPath); + } else { + System.err.println("Failed to create directory."); + return; + } + } + + File file = new File(filePath); + if (!file.exists()) { + try { + if (file.createNewFile()) { + System.out.println("File created at: " + filePath); + } else { + System.err.println("Failed to create the file."); + } + } catch (IOException e) { + System.err.println("An error occurred while creating the file: " + e.getMessage()); + } + } + + String data = ""; + for (int i = 0; i < nTasks; i++) { + Task task = taskList.get(i); + data += task.saveTask(); + } + try { + FileWriter fw = new FileWriter(file); + fw.write(data); + fw.close(); + } catch (IOException e) { + System.out.println(e.toString()); + } + } + + public static void loadTasksFromDisk() throws FileNotFoundException { + String filePath = "./data/dude.txt"; + + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + String line; + while ((line = reader.readLine()) != null) { + String[] taskInfo = line.split("\\s+\\|\\s+"); + + Task task; + + if (taskInfo[0].equals("T")) { + task = new ToDo(taskInfo[2]); + task.setDone(taskInfo[1] == "1"); + taskList.add(task); + nTasks += 1; + } else if (taskInfo[0].equals("D")) { + task = new Deadline(taskInfo[2], taskInfo[3]); + task.setDone(taskInfo[1] == "1"); + taskList.add(task); + nTasks += 1; + } else if (taskInfo[0].equals("E")) { + task = new Event(taskInfo[2], taskInfo[3], taskInfo[4]); + task.setDone(taskInfo[1] == "1"); + taskList.add(task); + nTasks += 1; + } + } + } catch (IOException e) { + System.err.println("An error occurred while reading the file: " + e.getMessage()); + } + } + + public static void main(String[] args) throws IOException { String greeting = "Hello, I'm Dude!\n" + "What can I do for you?"; System.out.println(greeting); + loadTasksFromDisk(); + System.out.printf("You have %d saved tasks:\n", nTasks); + list(); while (true) { Scanner scanner = new Scanner(System.in); String input = scanner.nextLine(); @@ -86,11 +162,14 @@ public static void main(String[] args) { break; } else if (words[0].equals("mark")) { mark(Integer.valueOf(words[1])); + saveTasksToDisk(); } else if (words[0].equals("unmark")) { unmark(Integer.valueOf(words[1])); + saveTasksToDisk(); } else if (words[0].equals("todo")) { if (words.length > 1) { addTodo(input.substring(5)); + saveTasksToDisk(); } else { System.out.println("OOPS!!! The description of a todo cannot be empty."); } @@ -101,6 +180,7 @@ public static void main(String[] args) { String[] taskWords = input.substring(9).split(" /"); String by = taskWords[1].substring(3); addDeadline(taskWords[0], by); + saveTasksToDisk(); } else if (words[0].equals("event")) { if (words.length == 1) { System.out.println("OOPS!!! The description of an event cannot be empty."); @@ -109,6 +189,7 @@ public static void main(String[] args) { String from = taskWords[1].substring(5); String to = taskWords[2].substring(3); addEvent(taskWords[0], from, to); + saveTasksToDisk(); } else if (words[0].equals("delete")) { delete(Integer.valueOf(words[1])); } else { diff --git a/src/main/java/Event.java b/src/main/java/Event.java index 214efc96f6..d425335b24 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -6,10 +6,23 @@ public class Event extends Task { this.from = from; this.to = to; } + @Override public String getType() { return "event"; } @Override + public String saveTask() { + String data = "E | "; + if (this.isDone()) { + data += "1 | "; + } else { + data += "0 | "; + } + data += this.getDescription(); + data = data + " | " + this.from + " | " + this.to + "\n"; + return data; + } + @Override public String toString() { return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; } diff --git a/src/main/java/Task.java b/src/main/java/Task.java index bdd7da6aae..c818de6a8c 100644 --- a/src/main/java/Task.java +++ b/src/main/java/Task.java @@ -22,6 +22,7 @@ public void setDone(boolean done) { public String getType() { return "task"; } + public String saveTask () {return this.description; } @Override public String toString() { diff --git a/src/main/java/ToDo.java b/src/main/java/ToDo.java index 1c50b56327..d039f05bdf 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/ToDo.java @@ -2,10 +2,22 @@ public class ToDo extends Task { ToDo(String description) { super(description); } + @Override public String getType() { return "todo"; } @Override + public String saveTask() { + String data = "T | "; + if (this.isDone()) { + data += "1 | "; + } else { + data += "0 | "; + } + data = data + this.getDescription() + "\n"; + return data; + } + @Override public String toString() { return "[T]" + super.toString(); } From 4fc7fc4ae0c27ebf48548f3eebb6ab064584e03f Mon Sep 17 00:00:00 2001 From: vivienherq Date: Thu, 7 Sep 2023 00:31:43 +0800 Subject: [PATCH 16/57] implement datetime recognition for deadline --- data/dude.txt | 2 +- src/main/java/Deadline.java | 14 ++++++++++---- src/main/java/Dude.java | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/data/dude.txt b/data/dude.txt index 6089c4283b..5ffac6797b 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -1,3 +1,3 @@ T | 0 | borrow book -D | 0 | return book | Sunday +D | 0 | return book | 2023-09-06T14:30 E | 0 | project meeting | Mon 2pm | 4pm diff --git a/src/main/java/Deadline.java b/src/main/java/Deadline.java index 8236ba967f..6c49e21afe 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/Deadline.java @@ -1,6 +1,10 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + public class Deadline extends Task { - private String by; - Deadline(String description, String by) { + LocalDateTime by; + Deadline(String description, LocalDateTime by) { super(description); this.by = by; } @@ -17,11 +21,13 @@ public String saveTask() { data += "0 | "; } data += this.getDescription(); - data = data + " | " + this.by + "\n"; + data = data + " | " + this.by + "\n"; // ISO-8601 e.g. 2023-09-06T14:30 return data; } @Override public String toString() { - return "[D]" + super.toString() + " (by: " + by + ")"; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); + String formattedDateTime = by.format(formatter); + return "[D]" + super.toString() + " (by: " + formattedDateTime + ")"; } } diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 89cbb45485..988e8dda2d 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,6 +1,8 @@ import java.io.*; import java.util.Scanner; import java.util.ArrayList; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; public class Dude { @@ -17,7 +19,7 @@ public static void addTodo(String task) { nTasks += 1; System.out.printf("Now you have %d tasks in the list. \n", nTasks); } - public static void addDeadline(String task, String by) { + public static void addDeadline(String task, LocalDateTime by) { Deadline newTask = new Deadline(task, by); // taskList[nTasks] = newTask; taskList.add(newTask); @@ -116,6 +118,7 @@ public static void loadTasksFromDisk() throws FileNotFoundException { try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { String line; while ((line = reader.readLine()) != null) { + //System.out.println(line); String[] taskInfo = line.split("\\s+\\|\\s+"); Task task; @@ -126,7 +129,11 @@ public static void loadTasksFromDisk() throws FileNotFoundException { taskList.add(task); nTasks += 1; } else if (taskInfo[0].equals("D")) { - task = new Deadline(taskInfo[2], taskInfo[3]); + String byInput = taskInfo[3]; // ISO-8601 e.g. 2023-09-06T14:30 + LocalDateTime by = LocalDateTime.parse(byInput); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + // LocalDateTime by = LocalDateTime.parse(byInput, formatter); + task = new Deadline(taskInfo[2], by); task.setDone(taskInfo[1] == "1"); taskList.add(task); nTasks += 1; @@ -177,8 +184,11 @@ public static void main(String[] args) throws IOException { if (words.length == 1) { System.out.println("OOPS!!! The description of a deadline cannot be empty."); } - String[] taskWords = input.substring(9).split(" /"); - String by = taskWords[1].substring(3); + + String[] taskWords = input.substring(9).split(" /by "); + String byInput = taskWords[1]; //dd/mm/yyyy hh:mm format + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + LocalDateTime by = LocalDateTime.parse(byInput, formatter); addDeadline(taskWords[0], by); saveTasksToDisk(); } else if (words[0].equals("event")) { From 725c47eabe9067141a11afbeb97a2d0e7551115d Mon Sep 17 00:00:00 2001 From: vivienherq Date: Tue, 12 Sep 2023 01:57:28 +0800 Subject: [PATCH 17/57] Refactor code into Ui, Storage, Parser, TaskList, Command classes --- data/dude.txt | 8 +- src/main/java/AddDeadlineCommand.java | 24 +++ src/main/java/AddEventCommand.java | 26 +++ src/main/java/AddToDoCommand.java | 21 +++ src/main/java/Command.java | 14 ++ src/main/java/DeleteCommand.java | 20 +++ src/main/java/Dude.java | 222 ++++---------------------- src/main/java/DudeException.java | 10 ++ src/main/java/Event.java | 15 +- src/main/java/ExitCommand.java | 10 ++ src/main/java/ListCommand.java | 7 + src/main/java/MarkCommand.java | 19 +++ src/main/java/Parser.java | 52 ++++++ src/main/java/Storage.java | 122 ++++++++++++++ src/main/java/TaskList.java | 69 ++++++++ src/main/java/Ui.java | 65 ++++++++ src/main/java/UnknownCommand.java | 6 + src/main/java/UnmarkCommand.java | 18 +++ 18 files changed, 528 insertions(+), 200 deletions(-) create mode 100644 src/main/java/AddDeadlineCommand.java create mode 100644 src/main/java/AddEventCommand.java create mode 100644 src/main/java/AddToDoCommand.java create mode 100644 src/main/java/Command.java create mode 100644 src/main/java/DeleteCommand.java create mode 100644 src/main/java/DudeException.java create mode 100644 src/main/java/ExitCommand.java create mode 100644 src/main/java/ListCommand.java create mode 100644 src/main/java/MarkCommand.java create mode 100644 src/main/java/Parser.java create mode 100644 src/main/java/Storage.java create mode 100644 src/main/java/TaskList.java create mode 100644 src/main/java/Ui.java create mode 100644 src/main/java/UnknownCommand.java create mode 100644 src/main/java/UnmarkCommand.java diff --git a/data/dude.txt b/data/dude.txt index 5ffac6797b..6c6cfb03be 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -1,3 +1,5 @@ -T | 0 | borrow book -D | 0 | return book | 2023-09-06T14:30 -E | 0 | project meeting | Mon 2pm | 4pm +T | 0 | eat +T | 0 | sleep +D | 0 | ip | 2023-09-22T23:59 +E | 0 | ifg closing ceremony | 2023-09-22T18:00 | 2023-09-22T21:00 +E | 0 | gen meeting | 2023-09-12T20:00 | 2023-09-12T22:00 diff --git a/src/main/java/AddDeadlineCommand.java b/src/main/java/AddDeadlineCommand.java new file mode 100644 index 0000000000..645c1922ba --- /dev/null +++ b/src/main/java/AddDeadlineCommand.java @@ -0,0 +1,24 @@ +import java.io.IOException; +import java.time.LocalDateTime; + +public class AddDeadlineCommand extends Command { + private String taskDescription; + private LocalDateTime byDateTime; + public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { + this.taskDescription = taskDescription; + this.byDateTime = byDateTime; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Add Deadline Command"); + Deadline newTask = new Deadline(taskDescription, byDateTime); + taskList.addTask(newTask); + int nTasks = taskList.getSize(); + ui.showAddedTask(newTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Add Deadline Command"); + } + } +} diff --git a/src/main/java/AddEventCommand.java b/src/main/java/AddEventCommand.java new file mode 100644 index 0000000000..cc596cae66 --- /dev/null +++ b/src/main/java/AddEventCommand.java @@ -0,0 +1,26 @@ +import java.io.IOException; +import java.time.LocalDateTime; + +public class AddEventCommand extends Command { + private String taskDescription; + private LocalDateTime fromDateTime; + private LocalDateTime toDateTime; + public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, LocalDateTime toDateTime) { + this.taskDescription = taskDescription; + this.fromDateTime = fromDateTime; + this.toDateTime = toDateTime; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Add Event Command"); + Event newTask = new Event(taskDescription, fromDateTime, toDateTime); + taskList.addTask(newTask); + int nTasks = taskList.getSize(); + ui.showAddedTask(newTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Add Event Command"); + } + } +} diff --git a/src/main/java/AddToDoCommand.java b/src/main/java/AddToDoCommand.java new file mode 100644 index 0000000000..b2668d01b0 --- /dev/null +++ b/src/main/java/AddToDoCommand.java @@ -0,0 +1,21 @@ +import java.io.IOException; + +public class AddToDoCommand extends Command { + private String taskDescription; + public AddToDoCommand(String taskDescription) { + this.taskDescription = taskDescription; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Add ToDo Command"); + ToDo newTask = new ToDo(taskDescription); + taskList.addTask(newTask); + int nTasks = taskList.getSize(); + ui.showAddedTask(newTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Add ToDo Command"); + } + } +} diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 0000000000..8899d2a857 --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,14 @@ +public abstract class Command { + + protected boolean isExit; + + public Command() { + this.isExit = false; + } + + public abstract void execute(TaskList tasks, Ui ui, Storage storage); + + public boolean isExit() { + return this.isExit; + } +} diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 0000000000..7b58749612 --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,20 @@ +import java.io.IOException; + +public class DeleteCommand extends Command { + private int taskIndex; + public DeleteCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Delete Command"); + Task deletedTask = taskList.deleteTask(taskIndex); + int nTasks = taskList.getSize(); + ui.showDeletedTask(deletedTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Delete Command"); + } + } +} diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 988e8dda2d..148883461d 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,4 +1,9 @@ -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; import java.util.Scanner; import java.util.ArrayList; import java.time.LocalDateTime; @@ -6,208 +11,39 @@ public class Dude { - static ArrayList taskList = new ArrayList(); + private TaskList taskList; + private Storage storage; + private Ui ui; static int nTasks = 0; - private static final String FILE_PATH = "./data/dude.txt"; - - public static void addTodo(String task) { - ToDo newTask = new ToDo(task); -// taskList[nTasks] = newTask; - taskList.add(newTask); - System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); - nTasks += 1; - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - public static void addDeadline(String task, LocalDateTime by) { - Deadline newTask = new Deadline(task, by); -// taskList[nTasks] = newTask; - taskList.add(newTask); - System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); - nTasks += 1; - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - public static void addEvent(String task, String from, String to) { - Event newTask = new Event(task, from, to); -// taskList[nTasks] = newTask; - taskList.add(newTask); - System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); - nTasks += 1; - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - - public static void delete(int n) { - Task removedTask = taskList.get(n-1); - taskList.remove(n-1); - nTasks -= 1; - System.out.println("Noted. I've removed this task:"); - System.out.println(removedTask.toString()); - System.out.printf("Now you have %d tasks in the list.\n", nTasks); - - } - - public static void list() { - for (int i = 0; i < nTasks; i++) { - Task task = taskList.get(i); -// Task task = taskList[i]; - System.out.printf("%d. %s\n", i+1, task.toString()); - } - } - - public static void mark(int n) { - taskList.get(n-1).setDone(true); - System.out.println("Nice! I've marked this task as done:"); - System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); - } - - public static void unmark(int n) throws IOException { - taskList.get(n-1).setDone(false); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); - } - - public static void bye() { - String greeting = "Bye. Hope to see you again soon!"; - System.out.println(greeting); - } - - public static void saveTasksToDisk() throws IOException { - String directoryPath = "./data"; - String filePath = "./data/dude.txt"; - - File directory = new File(directoryPath); - if (!directory.exists()) { - if (directory.mkdirs()) { - System.out.println("Directory created at: " + directoryPath); - } else { - System.err.println("Failed to create directory."); - return; - } - } - - File file = new File(filePath); - if (!file.exists()) { - try { - if (file.createNewFile()) { - System.out.println("File created at: " + filePath); - } else { - System.err.println("Failed to create the file."); - } - } catch (IOException e) { - System.err.println("An error occurred while creating the file: " + e.getMessage()); - } - } - - String data = ""; - for (int i = 0; i < nTasks; i++) { - Task task = taskList.get(i); - data += task.saveTask(); - } + public Dude(String filePath) { + this.ui = new Ui(); + this.storage = new Storage(filePath); try { - FileWriter fw = new FileWriter(file); - fw.write(data); - fw.close(); - } catch (IOException e) { - System.out.println(e.toString()); + taskList = new TaskList(storage.loadTasksFromDisk()); + } catch (FileNotFoundException e) { // DudeException + ui.showLoadingError(); + taskList = new TaskList(); } } + public void run() { + ui.showWelcome(); + boolean isExit = false; - public static void loadTasksFromDisk() throws FileNotFoundException { - String filePath = "./data/dude.txt"; - - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - String line; - while ((line = reader.readLine()) != null) { - //System.out.println(line); - String[] taskInfo = line.split("\\s+\\|\\s+"); - - Task task; - - if (taskInfo[0].equals("T")) { - task = new ToDo(taskInfo[2]); - task.setDone(taskInfo[1] == "1"); - taskList.add(task); - nTasks += 1; - } else if (taskInfo[0].equals("D")) { - String byInput = taskInfo[3]; // ISO-8601 e.g. 2023-09-06T14:30 - LocalDateTime by = LocalDateTime.parse(byInput); - // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); - // LocalDateTime by = LocalDateTime.parse(byInput, formatter); - task = new Deadline(taskInfo[2], by); - task.setDone(taskInfo[1] == "1"); - taskList.add(task); - nTasks += 1; - } else if (taskInfo[0].equals("E")) { - task = new Event(taskInfo[2], taskInfo[3], taskInfo[4]); - task.setDone(taskInfo[1] == "1"); - taskList.add(task); - nTasks += 1; - } + while (!isExit) { + try { + String fullCommand = ui.readCommand(); + ui.showLine(); + Command c = Parser.parse(fullCommand); + c.execute(taskList, ui, storage); + isExit = c.isExit(); + } finally { + ui.showLine(); } - } catch (IOException e) { - System.err.println("An error occurred while reading the file: " + e.getMessage()); } } public static void main(String[] args) throws IOException { - String greeting = "Hello, I'm Dude!\n" + - "What can I do for you?"; - System.out.println(greeting); - - loadTasksFromDisk(); - System.out.printf("You have %d saved tasks:\n", nTasks); - list(); - while (true) { - Scanner scanner = new Scanner(System.in); - String input = scanner.nextLine(); - String[] words = input.split(" "); - - if (words[0].equals("list")) { - list(); - } else if (words[0].equals("bye")) { - bye(); - break; - } else if (words[0].equals("mark")) { - mark(Integer.valueOf(words[1])); - saveTasksToDisk(); - } else if (words[0].equals("unmark")) { - unmark(Integer.valueOf(words[1])); - saveTasksToDisk(); - } else if (words[0].equals("todo")) { - if (words.length > 1) { - addTodo(input.substring(5)); - saveTasksToDisk(); - } else { - System.out.println("OOPS!!! The description of a todo cannot be empty."); - } - } else if (words[0].equals("deadline")) { - if (words.length == 1) { - System.out.println("OOPS!!! The description of a deadline cannot be empty."); - } - - String[] taskWords = input.substring(9).split(" /by "); - String byInput = taskWords[1]; //dd/mm/yyyy hh:mm format - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); - LocalDateTime by = LocalDateTime.parse(byInput, formatter); - addDeadline(taskWords[0], by); - saveTasksToDisk(); - } else if (words[0].equals("event")) { - if (words.length == 1) { - System.out.println("OOPS!!! The description of an event cannot be empty."); - } - String[] taskWords = input.substring(6).split(" /"); - String from = taskWords[1].substring(5); - String to = taskWords[2].substring(3); - addEvent(taskWords[0], from, to); - saveTasksToDisk(); - } else if (words[0].equals("delete")) { - delete(Integer.valueOf(words[1])); - } else { - System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); - } - - - - } + new Dude("data/dude.txt").run(); } } \ No newline at end of file diff --git a/src/main/java/DudeException.java b/src/main/java/DudeException.java new file mode 100644 index 0000000000..4e670080e5 --- /dev/null +++ b/src/main/java/DudeException.java @@ -0,0 +1,10 @@ +public class DudeException extends Exception { + DudeException(String message) { + super(message); + } + + @Override + public String toString() { + return this.getMessage(); + } +} diff --git a/src/main/java/Event.java b/src/main/java/Event.java index d425335b24..bcb6f8fb3a 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,7 +1,11 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + public class Event extends Task { - private String from; - private String to; - Event(String description, String from, String to) { + private LocalDateTime from; + private LocalDateTime to; + Event(String description, LocalDateTime from, LocalDateTime to) { super(description); this.from = from; this.to = to; @@ -24,6 +28,9 @@ public String saveTask() { } @Override public String toString() { - return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); + String fromFormatted = from.format(formatter); + String toFormatted = to.format(formatter); + return "[E]" + super.toString() + " (from: " + fromFormatted + " to: " + toFormatted + ")"; } } diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java new file mode 100644 index 0000000000..9488b933ba --- /dev/null +++ b/src/main/java/ExitCommand.java @@ -0,0 +1,10 @@ +public class ExitCommand extends Command { + public ExitCommand() { + super.isExit = true; + } + + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) { + ui.showFarewell(); + } +} diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 0000000000..b6af2c7d79 --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,7 @@ +public class ListCommand extends Command { + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + System.out.println("Listing..."); + ui.showTaskList(taskList); + } +} diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java new file mode 100644 index 0000000000..19606585bb --- /dev/null +++ b/src/main/java/MarkCommand.java @@ -0,0 +1,19 @@ +import java.io.IOException; + +public class MarkCommand extends Command { + private int taskIndex; + public MarkCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Mark Command");; + Task markedTask = taskList.markTask(taskIndex); + ui.showMarkedTask(markedTask); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Mark Command"); + } + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000000..b3b0e73bdd --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,52 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +// deals with making sense of the user command +public class Parser { + + private static DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + public static Command parse(String fullCommand) { + String[] commandDetails = fullCommand.split(" ", 2); + String commandType = commandDetails[0]; + Command c; + + if (commandType.equals("bye")){ + c = new ExitCommand(); + } else if (commandType.equals("list")) { + c = new ListCommand(); + } else if (commandType.equals("mark")) { + int taskIndex = Integer.parseInt(commandDetails[1]) - 1; + c = new MarkCommand(taskIndex); + } else if (commandType.equals("unmark")) { + int taskIndex = Integer.parseInt(commandDetails[1]) - 1; + c = new UnmarkCommand(taskIndex); + } else if (commandType.equals("delete")) { + int taskIndex = Integer.parseInt(commandDetails[1]) - 1; + c = new DeleteCommand(taskIndex); + } else if (commandType.equals("todo")) { + String taskDescription = commandDetails[1].trim(); + c = new AddToDoCommand(taskDescription); + // if (userInputDetails.length > 1) + // System.out.println("OOPS!!! The description of a todo cannot be empty."); + } else if (commandType.equals("deadline")) { + String[] taskDetails = commandDetails[1].split("\\s/by\\s"); + String taskDescription = taskDetails[0].trim(); + LocalDateTime byDateTime = LocalDateTime.parse(taskDetails[1].trim(), DATETIME_FORMATTER); + c = new AddDeadlineCommand(taskDescription, byDateTime); + // if (userInputDetails.length == 1) { + // System.out.println("OOPS!!! The description of a deadline cannot be empty."); + } else if (commandType.equals("event")) { + String[] taskDetails = commandDetails[1].split("\\s/from\\s|\\s/to\\s"); + String taskDescription = taskDetails[0].trim(); + LocalDateTime fromDateTime = LocalDateTime.parse(taskDetails[1].trim(), DATETIME_FORMATTER); + LocalDateTime toDateTime = LocalDateTime.parse(taskDetails[2].trim(), DATETIME_FORMATTER); + c = new AddEventCommand(taskDescription, fromDateTime, toDateTime); + // if (userInputDetails.length == 1) { + // System.out.println("OOPS!!! The description of an event cannot be empty."); + } else { + c = new UnknownCommand(); + } + return c; + } + +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..140992833c --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,122 @@ +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Scanner; + +// deals with loading tasks from the file and saving tasks in the file +public class Storage { + private String filepath; + public Storage(String filepath) { + this.filepath = filepath; + } + + public void saveTasksToDisk(TaskList taskList) throws IOException { + File file = new File(this.filepath); + if (!file.exists()) { + try { + if (file.createNewFile()) { + System.out.println("File created at: " + this.filepath); + } else { + System.err.println("Failed to create the file."); + } + } catch (IOException e) { + System.err.println("An error occurred while creating the file: " + e.getMessage()); + } + } + + String data = ""; + for (int i = 0; i < taskList.getSize(); i++) { + Task task = taskList.getTask(i); + data += task.saveTask(); + } + + try { + FileWriter fw = new FileWriter(file); + fw.write(data); + fw.close(); + } catch (IOException e) { + System.out.println(e.toString()); + } + } + + public ArrayList loadTasksFromDisk() throws FileNotFoundException { + ArrayList taskList = new ArrayList(); + + File file = new File(this.filepath); + if (file.exists()) { + try { + Scanner sc = new Scanner(file); + while (sc.hasNext()) { + String storedTaskDetails = sc.nextLine(); + String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); + String taskType = taskDetails[0]; + Task task; + if (taskType.equals("T")) { + task = new ToDo(taskDetails[2]); + task.setDone(taskDetails[1] == "1"); + taskList.add(task); + } else if (taskType.equals("D")) { + String byInput = taskDetails[3]; // ISO-8601 e.g. 2023-09-06T14:30 + LocalDateTime by = LocalDateTime.parse(byInput); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + // LocalDateTime by = LocalDateTime.parse(byInput, formatter); + task = new Deadline(taskDetails[2], by); + task.setDone(taskDetails[1] == "1"); + taskList.add(task); + } else if (taskType.equals("E")) { + LocalDateTime from = LocalDateTime.parse(taskDetails[3]); + LocalDateTime to = LocalDateTime.parse(taskDetails[4]); + task = new Event(taskDetails[2], from, to); + task.setDone(taskDetails[1] == "1"); + taskList.add(task); + } + } + } catch (IOException e) { + System.err.println("An error occurred while reading the file: " + e.getMessage()); + } + } else { + try { + file.createNewFile(); + System.out.println("File created at: " + this.filepath); + } catch (IOException e) { + System.out.println("File creating error"); + System.out.println(e.getMessage()); + } + } + System.out.printf("You have %d saved tasks.\n", taskList.size()); + // TaskList tasks = new TaskList(taskList); + return taskList; + } + + + /* to be fixed + public Task processTaskDetails(String storedTaskDetails) { + String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); + + Task storedTask; + + if (taskDetails[0].equals("T")) { + storedTask = new ToDo(taskDetails[2]); + storedTask.setDone(taskDetails[1] == "1"); + } else if (taskDetails[0].equals("D")) { + String byInput = taskDetails[3]; // ISO-8601 e.g. 2023-09-06T14:30 + LocalDateTime by = LocalDateTime.parse(byInput); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + // LocalDateTime by = LocalDateTime.parse(byInput, formatter); + storedTask = new Deadline(taskDetails[2], by); + storedTask.setDone(taskDetails[1] == "1"); + } else if (taskDetails[0].equals("E")) { + storedTask = new Event(taskDetails[2], taskDetails[3], taskDetails[4]); + storedTask.setDone(taskDetails[1] == "1"); + } + return storedTask; + } + + */ + +} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 0000000000..e861ba659f --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,69 @@ +// contains the task list e.g., it has operations to add/delete tasks in the list +import java.time.LocalDateTime; +import java.util.ArrayList; +public class TaskList { + private ArrayList taskList; + + public TaskList() { + this.taskList = new ArrayList(); + } + public TaskList(ArrayList taskList) { + this.taskList = taskList; + } + + // getters + public int getSize() { + return this.taskList.size(); + } + + public Task getTask(int index) { + return this.taskList.get(index); + } + + private ArrayList getAllTasks() { + return this.taskList; + } + + // setters + public Task markTask(int index) { + Task task = taskList.get(index); + task.setDone(true); + return task; + } + public Task unmarkTask(int index) { + Task task = taskList.get(index); + task.setDone(false); + return task; + } + + // add + + public void addTask(Task task) { + taskList.add(task); + } + + public void addTodo(String task) { + ToDo newTask = new ToDo(task); + this.addTask(newTask); + + } +// public void addDeadline(String task, LocalDateTime by) { +// Deadline newTask = new Deadline(task, by); +// taskList.add(newTask); +// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); +// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); +// } +// public void addEvent(String task, LocalDateTime from, LocalDateTime to) { +// Event newTask = new Event(task, from, to); +// taskList.add(newTask); +// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); +// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); +// } + + public Task deleteTask(int index) { + Task removedTask = taskList.get(index); + taskList.remove(index); + return removedTask; + } + +} diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 0000000000..1b0f8b5e73 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,65 @@ +// deals with interactions with the user +import java.util.Scanner; +public class Ui { + Scanner sc; + public Ui() { + this.sc = new Scanner(System.in); + } + public String readCommand() { + return this.sc.nextLine(); + } + public void showWelcome() { + String greeting = "Hello, I'm Dude!\n" + + "What can I do for you?"; + System.out.println(greeting); + } + public void showFarewell() { + String greeting = "Bye. Hope to see you again soon!"; + System.out.println(greeting); + } + public void showLine() { + System.out.println("__________________________________________________"); + } + public void showTaskList(TaskList taskList) { + int nTasks = taskList.getSize(); + if (nTasks == 0) { + System.out.println("You have no saved tasks."); + } else { + for (int i = 0; i < nTasks; i++) { + Task task = taskList.getTask(i); + System.out.printf("%d. %s\n", i+1, task.toString()); + } + } + } + public void showMarkedTask(Task task) { + System.out.println("Nice! I've marked this task as done:"); + System.out.printf(task.toString()); + // task is already done? + } + public void showUnmarkedTask(Task task) { + System.out.println("Nice! I've marked this task as as not done yet:"); + System.out.printf(task.toString()); + // task is already undone? + } + public void showDeletedTask(Task task, int nTasks) { + System.out.println("Noted. I've removed this task:"); + System.out.println(task.toString()); + System.out.printf("Now you have %d tasks in the list.\n", nTasks); + } + public void showAddedTask(Task task, int nTasks) { + System.out.printf("Got it. I've added this task:\n%s\n", task.toString()); + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + public void showUnknownCommand() { + System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); + } + public void showError(String message) { + + } + + + + + public void showLoadingError() { + } +} diff --git a/src/main/java/UnknownCommand.java b/src/main/java/UnknownCommand.java new file mode 100644 index 0000000000..f1d3391846 --- /dev/null +++ b/src/main/java/UnknownCommand.java @@ -0,0 +1,6 @@ +public class UnknownCommand extends Command { + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + ui.showUnknownCommand(); + } +} diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java new file mode 100644 index 0000000000..7d49411aa2 --- /dev/null +++ b/src/main/java/UnmarkCommand.java @@ -0,0 +1,18 @@ +import java.io.IOException; + +public class UnmarkCommand extends Command { + private int taskIndex; + public UnmarkCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Unmark Command");; + Task unmarkedTask = taskList.unmarkTask(taskIndex); + ui.showUnmarkedTask(unmarkedTask); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Unmark Command"); + } + } +} From 34281a2f89e3fecff460a3d7ce670a58a2df8e3d Mon Sep 17 00:00:00 2001 From: vivienherq Date: Tue, 12 Sep 2023 02:05:08 +0800 Subject: [PATCH 18/57] Revert latest commit to push to A-MoreOOP Branch --- data/dude.txt | 8 +- src/main/java/AddDeadlineCommand.java | 24 --- src/main/java/AddEventCommand.java | 26 --- src/main/java/AddToDoCommand.java | 21 --- src/main/java/Command.java | 14 -- src/main/java/DeleteCommand.java | 20 --- src/main/java/Dude.java | 222 ++++++++++++++++++++++---- src/main/java/DudeException.java | 10 -- src/main/java/Event.java | 15 +- src/main/java/ExitCommand.java | 10 -- src/main/java/ListCommand.java | 7 - src/main/java/MarkCommand.java | 19 --- src/main/java/Parser.java | 52 ------ src/main/java/Storage.java | 122 -------------- src/main/java/TaskList.java | 69 -------- src/main/java/Ui.java | 65 -------- src/main/java/UnknownCommand.java | 6 - src/main/java/UnmarkCommand.java | 18 --- 18 files changed, 200 insertions(+), 528 deletions(-) delete mode 100644 src/main/java/AddDeadlineCommand.java delete mode 100644 src/main/java/AddEventCommand.java delete mode 100644 src/main/java/AddToDoCommand.java delete mode 100644 src/main/java/Command.java delete mode 100644 src/main/java/DeleteCommand.java delete mode 100644 src/main/java/DudeException.java delete mode 100644 src/main/java/ExitCommand.java delete mode 100644 src/main/java/ListCommand.java delete mode 100644 src/main/java/MarkCommand.java delete mode 100644 src/main/java/Parser.java delete mode 100644 src/main/java/Storage.java delete mode 100644 src/main/java/TaskList.java delete mode 100644 src/main/java/Ui.java delete mode 100644 src/main/java/UnknownCommand.java delete mode 100644 src/main/java/UnmarkCommand.java diff --git a/data/dude.txt b/data/dude.txt index 6c6cfb03be..5ffac6797b 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -1,5 +1,3 @@ -T | 0 | eat -T | 0 | sleep -D | 0 | ip | 2023-09-22T23:59 -E | 0 | ifg closing ceremony | 2023-09-22T18:00 | 2023-09-22T21:00 -E | 0 | gen meeting | 2023-09-12T20:00 | 2023-09-12T22:00 +T | 0 | borrow book +D | 0 | return book | 2023-09-06T14:30 +E | 0 | project meeting | Mon 2pm | 4pm diff --git a/src/main/java/AddDeadlineCommand.java b/src/main/java/AddDeadlineCommand.java deleted file mode 100644 index 645c1922ba..0000000000 --- a/src/main/java/AddDeadlineCommand.java +++ /dev/null @@ -1,24 +0,0 @@ -import java.io.IOException; -import java.time.LocalDateTime; - -public class AddDeadlineCommand extends Command { - private String taskDescription; - private LocalDateTime byDateTime; - public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { - this.taskDescription = taskDescription; - this.byDateTime = byDateTime; - } - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - try { - System.out.println("Executing Add Deadline Command"); - Deadline newTask = new Deadline(taskDescription, byDateTime); - taskList.addTask(newTask); - int nTasks = taskList.getSize(); - ui.showAddedTask(newTask, nTasks); - storage.saveTasksToDisk(taskList); - } catch (IOException e) { - System.out.println("Error in Add Deadline Command"); - } - } -} diff --git a/src/main/java/AddEventCommand.java b/src/main/java/AddEventCommand.java deleted file mode 100644 index cc596cae66..0000000000 --- a/src/main/java/AddEventCommand.java +++ /dev/null @@ -1,26 +0,0 @@ -import java.io.IOException; -import java.time.LocalDateTime; - -public class AddEventCommand extends Command { - private String taskDescription; - private LocalDateTime fromDateTime; - private LocalDateTime toDateTime; - public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, LocalDateTime toDateTime) { - this.taskDescription = taskDescription; - this.fromDateTime = fromDateTime; - this.toDateTime = toDateTime; - } - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - try { - System.out.println("Executing Add Event Command"); - Event newTask = new Event(taskDescription, fromDateTime, toDateTime); - taskList.addTask(newTask); - int nTasks = taskList.getSize(); - ui.showAddedTask(newTask, nTasks); - storage.saveTasksToDisk(taskList); - } catch (IOException e) { - System.out.println("Error in Add Event Command"); - } - } -} diff --git a/src/main/java/AddToDoCommand.java b/src/main/java/AddToDoCommand.java deleted file mode 100644 index b2668d01b0..0000000000 --- a/src/main/java/AddToDoCommand.java +++ /dev/null @@ -1,21 +0,0 @@ -import java.io.IOException; - -public class AddToDoCommand extends Command { - private String taskDescription; - public AddToDoCommand(String taskDescription) { - this.taskDescription = taskDescription; - } - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - try { - System.out.println("Executing Add ToDo Command"); - ToDo newTask = new ToDo(taskDescription); - taskList.addTask(newTask); - int nTasks = taskList.getSize(); - ui.showAddedTask(newTask, nTasks); - storage.saveTasksToDisk(taskList); - } catch (IOException e) { - System.out.println("Error in Add ToDo Command"); - } - } -} diff --git a/src/main/java/Command.java b/src/main/java/Command.java deleted file mode 100644 index 8899d2a857..0000000000 --- a/src/main/java/Command.java +++ /dev/null @@ -1,14 +0,0 @@ -public abstract class Command { - - protected boolean isExit; - - public Command() { - this.isExit = false; - } - - public abstract void execute(TaskList tasks, Ui ui, Storage storage); - - public boolean isExit() { - return this.isExit; - } -} diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java deleted file mode 100644 index 7b58749612..0000000000 --- a/src/main/java/DeleteCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -import java.io.IOException; - -public class DeleteCommand extends Command { - private int taskIndex; - public DeleteCommand(int taskIndex) { - this.taskIndex = taskIndex; - } - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - try { - System.out.println("Executing Delete Command"); - Task deletedTask = taskList.deleteTask(taskIndex); - int nTasks = taskList.getSize(); - ui.showDeletedTask(deletedTask, nTasks); - storage.saveTasksToDisk(taskList); - } catch (IOException e) { - System.out.println("Error in Delete Command"); - } - } -} diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 148883461d..988e8dda2d 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,9 +1,4 @@ -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.Scanner; import java.util.ArrayList; import java.time.LocalDateTime; @@ -11,39 +6,208 @@ public class Dude { - private TaskList taskList; - private Storage storage; - private Ui ui; + static ArrayList taskList = new ArrayList(); static int nTasks = 0; - public Dude(String filePath) { - this.ui = new Ui(); - this.storage = new Storage(filePath); - try { - taskList = new TaskList(storage.loadTasksFromDisk()); - } catch (FileNotFoundException e) { // DudeException - ui.showLoadingError(); - taskList = new TaskList(); + private static final String FILE_PATH = "./data/dude.txt"; + + public static void addTodo(String task) { + ToDo newTask = new ToDo(task); +// taskList[nTasks] = newTask; + taskList.add(newTask); + System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); + nTasks += 1; + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + public static void addDeadline(String task, LocalDateTime by) { + Deadline newTask = new Deadline(task, by); +// taskList[nTasks] = newTask; + taskList.add(newTask); + System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); + nTasks += 1; + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + public static void addEvent(String task, String from, String to) { + Event newTask = new Event(task, from, to); +// taskList[nTasks] = newTask; + taskList.add(newTask); + System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); + nTasks += 1; + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + + public static void delete(int n) { + Task removedTask = taskList.get(n-1); + taskList.remove(n-1); + nTasks -= 1; + System.out.println("Noted. I've removed this task:"); + System.out.println(removedTask.toString()); + System.out.printf("Now you have %d tasks in the list.\n", nTasks); + + } + + public static void list() { + for (int i = 0; i < nTasks; i++) { + Task task = taskList.get(i); +// Task task = taskList[i]; + System.out.printf("%d. %s\n", i+1, task.toString()); } } - public void run() { - ui.showWelcome(); - boolean isExit = false; - while (!isExit) { + public static void mark(int n) { + taskList.get(n-1).setDone(true); + System.out.println("Nice! I've marked this task as done:"); + System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); + } + + public static void unmark(int n) throws IOException { + taskList.get(n-1).setDone(false); + System.out.println("OK, I've marked this task as not done yet:"); + System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); + } + + public static void bye() { + String greeting = "Bye. Hope to see you again soon!"; + System.out.println(greeting); + } + + public static void saveTasksToDisk() throws IOException { + String directoryPath = "./data"; + String filePath = "./data/dude.txt"; + + File directory = new File(directoryPath); + if (!directory.exists()) { + if (directory.mkdirs()) { + System.out.println("Directory created at: " + directoryPath); + } else { + System.err.println("Failed to create directory."); + return; + } + } + + File file = new File(filePath); + if (!file.exists()) { try { - String fullCommand = ui.readCommand(); - ui.showLine(); - Command c = Parser.parse(fullCommand); - c.execute(taskList, ui, storage); - isExit = c.isExit(); - } finally { - ui.showLine(); + if (file.createNewFile()) { + System.out.println("File created at: " + filePath); + } else { + System.err.println("Failed to create the file."); + } + } catch (IOException e) { + System.err.println("An error occurred while creating the file: " + e.getMessage()); } } + + String data = ""; + for (int i = 0; i < nTasks; i++) { + Task task = taskList.get(i); + data += task.saveTask(); + } + try { + FileWriter fw = new FileWriter(file); + fw.write(data); + fw.close(); + } catch (IOException e) { + System.out.println(e.toString()); + } + } + + public static void loadTasksFromDisk() throws FileNotFoundException { + String filePath = "./data/dude.txt"; + + try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { + String line; + while ((line = reader.readLine()) != null) { + //System.out.println(line); + String[] taskInfo = line.split("\\s+\\|\\s+"); + + Task task; + + if (taskInfo[0].equals("T")) { + task = new ToDo(taskInfo[2]); + task.setDone(taskInfo[1] == "1"); + taskList.add(task); + nTasks += 1; + } else if (taskInfo[0].equals("D")) { + String byInput = taskInfo[3]; // ISO-8601 e.g. 2023-09-06T14:30 + LocalDateTime by = LocalDateTime.parse(byInput); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + // LocalDateTime by = LocalDateTime.parse(byInput, formatter); + task = new Deadline(taskInfo[2], by); + task.setDone(taskInfo[1] == "1"); + taskList.add(task); + nTasks += 1; + } else if (taskInfo[0].equals("E")) { + task = new Event(taskInfo[2], taskInfo[3], taskInfo[4]); + task.setDone(taskInfo[1] == "1"); + taskList.add(task); + nTasks += 1; + } + } + } catch (IOException e) { + System.err.println("An error occurred while reading the file: " + e.getMessage()); + } } public static void main(String[] args) throws IOException { - new Dude("data/dude.txt").run(); + String greeting = "Hello, I'm Dude!\n" + + "What can I do for you?"; + System.out.println(greeting); + + loadTasksFromDisk(); + System.out.printf("You have %d saved tasks:\n", nTasks); + list(); + while (true) { + Scanner scanner = new Scanner(System.in); + String input = scanner.nextLine(); + String[] words = input.split(" "); + + if (words[0].equals("list")) { + list(); + } else if (words[0].equals("bye")) { + bye(); + break; + } else if (words[0].equals("mark")) { + mark(Integer.valueOf(words[1])); + saveTasksToDisk(); + } else if (words[0].equals("unmark")) { + unmark(Integer.valueOf(words[1])); + saveTasksToDisk(); + } else if (words[0].equals("todo")) { + if (words.length > 1) { + addTodo(input.substring(5)); + saveTasksToDisk(); + } else { + System.out.println("OOPS!!! The description of a todo cannot be empty."); + } + } else if (words[0].equals("deadline")) { + if (words.length == 1) { + System.out.println("OOPS!!! The description of a deadline cannot be empty."); + } + + String[] taskWords = input.substring(9).split(" /by "); + String byInput = taskWords[1]; //dd/mm/yyyy hh:mm format + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + LocalDateTime by = LocalDateTime.parse(byInput, formatter); + addDeadline(taskWords[0], by); + saveTasksToDisk(); + } else if (words[0].equals("event")) { + if (words.length == 1) { + System.out.println("OOPS!!! The description of an event cannot be empty."); + } + String[] taskWords = input.substring(6).split(" /"); + String from = taskWords[1].substring(5); + String to = taskWords[2].substring(3); + addEvent(taskWords[0], from, to); + saveTasksToDisk(); + } else if (words[0].equals("delete")) { + delete(Integer.valueOf(words[1])); + } else { + System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); + } + + + + } } } \ No newline at end of file diff --git a/src/main/java/DudeException.java b/src/main/java/DudeException.java deleted file mode 100644 index 4e670080e5..0000000000 --- a/src/main/java/DudeException.java +++ /dev/null @@ -1,10 +0,0 @@ -public class DudeException extends Exception { - DudeException(String message) { - super(message); - } - - @Override - public String toString() { - return this.getMessage(); - } -} diff --git a/src/main/java/Event.java b/src/main/java/Event.java index bcb6f8fb3a..d425335b24 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,11 +1,7 @@ -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Locale; - public class Event extends Task { - private LocalDateTime from; - private LocalDateTime to; - Event(String description, LocalDateTime from, LocalDateTime to) { + private String from; + private String to; + Event(String description, String from, String to) { super(description); this.from = from; this.to = to; @@ -28,9 +24,6 @@ public String saveTask() { } @Override public String toString() { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); - String fromFormatted = from.format(formatter); - String toFormatted = to.format(formatter); - return "[E]" + super.toString() + " (from: " + fromFormatted + " to: " + toFormatted + ")"; + return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; } } diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java deleted file mode 100644 index 9488b933ba..0000000000 --- a/src/main/java/ExitCommand.java +++ /dev/null @@ -1,10 +0,0 @@ -public class ExitCommand extends Command { - public ExitCommand() { - super.isExit = true; - } - - @Override - public void execute(TaskList tasks, Ui ui, Storage storage) { - ui.showFarewell(); - } -} diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java deleted file mode 100644 index b6af2c7d79..0000000000 --- a/src/main/java/ListCommand.java +++ /dev/null @@ -1,7 +0,0 @@ -public class ListCommand extends Command { - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - System.out.println("Listing..."); - ui.showTaskList(taskList); - } -} diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java deleted file mode 100644 index 19606585bb..0000000000 --- a/src/main/java/MarkCommand.java +++ /dev/null @@ -1,19 +0,0 @@ -import java.io.IOException; - -public class MarkCommand extends Command { - private int taskIndex; - public MarkCommand(int taskIndex) { - this.taskIndex = taskIndex; - } - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - try { - System.out.println("Executing Mark Command");; - Task markedTask = taskList.markTask(taskIndex); - ui.showMarkedTask(markedTask); - storage.saveTasksToDisk(taskList); - } catch (IOException e) { - System.out.println("Error in Mark Command"); - } - } -} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java deleted file mode 100644 index b3b0e73bdd..0000000000 --- a/src/main/java/Parser.java +++ /dev/null @@ -1,52 +0,0 @@ -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -// deals with making sense of the user command -public class Parser { - - private static DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); - public static Command parse(String fullCommand) { - String[] commandDetails = fullCommand.split(" ", 2); - String commandType = commandDetails[0]; - Command c; - - if (commandType.equals("bye")){ - c = new ExitCommand(); - } else if (commandType.equals("list")) { - c = new ListCommand(); - } else if (commandType.equals("mark")) { - int taskIndex = Integer.parseInt(commandDetails[1]) - 1; - c = new MarkCommand(taskIndex); - } else if (commandType.equals("unmark")) { - int taskIndex = Integer.parseInt(commandDetails[1]) - 1; - c = new UnmarkCommand(taskIndex); - } else if (commandType.equals("delete")) { - int taskIndex = Integer.parseInt(commandDetails[1]) - 1; - c = new DeleteCommand(taskIndex); - } else if (commandType.equals("todo")) { - String taskDescription = commandDetails[1].trim(); - c = new AddToDoCommand(taskDescription); - // if (userInputDetails.length > 1) - // System.out.println("OOPS!!! The description of a todo cannot be empty."); - } else if (commandType.equals("deadline")) { - String[] taskDetails = commandDetails[1].split("\\s/by\\s"); - String taskDescription = taskDetails[0].trim(); - LocalDateTime byDateTime = LocalDateTime.parse(taskDetails[1].trim(), DATETIME_FORMATTER); - c = new AddDeadlineCommand(taskDescription, byDateTime); - // if (userInputDetails.length == 1) { - // System.out.println("OOPS!!! The description of a deadline cannot be empty."); - } else if (commandType.equals("event")) { - String[] taskDetails = commandDetails[1].split("\\s/from\\s|\\s/to\\s"); - String taskDescription = taskDetails[0].trim(); - LocalDateTime fromDateTime = LocalDateTime.parse(taskDetails[1].trim(), DATETIME_FORMATTER); - LocalDateTime toDateTime = LocalDateTime.parse(taskDetails[2].trim(), DATETIME_FORMATTER); - c = new AddEventCommand(taskDescription, fromDateTime, toDateTime); - // if (userInputDetails.length == 1) { - // System.out.println("OOPS!!! The description of an event cannot be empty."); - } else { - c = new UnknownCommand(); - } - return c; - } - -} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java deleted file mode 100644 index 140992833c..0000000000 --- a/src/main/java/Storage.java +++ /dev/null @@ -1,122 +0,0 @@ -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.Scanner; - -// deals with loading tasks from the file and saving tasks in the file -public class Storage { - private String filepath; - public Storage(String filepath) { - this.filepath = filepath; - } - - public void saveTasksToDisk(TaskList taskList) throws IOException { - File file = new File(this.filepath); - if (!file.exists()) { - try { - if (file.createNewFile()) { - System.out.println("File created at: " + this.filepath); - } else { - System.err.println("Failed to create the file."); - } - } catch (IOException e) { - System.err.println("An error occurred while creating the file: " + e.getMessage()); - } - } - - String data = ""; - for (int i = 0; i < taskList.getSize(); i++) { - Task task = taskList.getTask(i); - data += task.saveTask(); - } - - try { - FileWriter fw = new FileWriter(file); - fw.write(data); - fw.close(); - } catch (IOException e) { - System.out.println(e.toString()); - } - } - - public ArrayList loadTasksFromDisk() throws FileNotFoundException { - ArrayList taskList = new ArrayList(); - - File file = new File(this.filepath); - if (file.exists()) { - try { - Scanner sc = new Scanner(file); - while (sc.hasNext()) { - String storedTaskDetails = sc.nextLine(); - String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); - String taskType = taskDetails[0]; - Task task; - if (taskType.equals("T")) { - task = new ToDo(taskDetails[2]); - task.setDone(taskDetails[1] == "1"); - taskList.add(task); - } else if (taskType.equals("D")) { - String byInput = taskDetails[3]; // ISO-8601 e.g. 2023-09-06T14:30 - LocalDateTime by = LocalDateTime.parse(byInput); - // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); - // LocalDateTime by = LocalDateTime.parse(byInput, formatter); - task = new Deadline(taskDetails[2], by); - task.setDone(taskDetails[1] == "1"); - taskList.add(task); - } else if (taskType.equals("E")) { - LocalDateTime from = LocalDateTime.parse(taskDetails[3]); - LocalDateTime to = LocalDateTime.parse(taskDetails[4]); - task = new Event(taskDetails[2], from, to); - task.setDone(taskDetails[1] == "1"); - taskList.add(task); - } - } - } catch (IOException e) { - System.err.println("An error occurred while reading the file: " + e.getMessage()); - } - } else { - try { - file.createNewFile(); - System.out.println("File created at: " + this.filepath); - } catch (IOException e) { - System.out.println("File creating error"); - System.out.println(e.getMessage()); - } - } - System.out.printf("You have %d saved tasks.\n", taskList.size()); - // TaskList tasks = new TaskList(taskList); - return taskList; - } - - - /* to be fixed - public Task processTaskDetails(String storedTaskDetails) { - String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); - - Task storedTask; - - if (taskDetails[0].equals("T")) { - storedTask = new ToDo(taskDetails[2]); - storedTask.setDone(taskDetails[1] == "1"); - } else if (taskDetails[0].equals("D")) { - String byInput = taskDetails[3]; // ISO-8601 e.g. 2023-09-06T14:30 - LocalDateTime by = LocalDateTime.parse(byInput); - // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); - // LocalDateTime by = LocalDateTime.parse(byInput, formatter); - storedTask = new Deadline(taskDetails[2], by); - storedTask.setDone(taskDetails[1] == "1"); - } else if (taskDetails[0].equals("E")) { - storedTask = new Event(taskDetails[2], taskDetails[3], taskDetails[4]); - storedTask.setDone(taskDetails[1] == "1"); - } - return storedTask; - } - - */ - -} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java deleted file mode 100644 index e861ba659f..0000000000 --- a/src/main/java/TaskList.java +++ /dev/null @@ -1,69 +0,0 @@ -// contains the task list e.g., it has operations to add/delete tasks in the list -import java.time.LocalDateTime; -import java.util.ArrayList; -public class TaskList { - private ArrayList taskList; - - public TaskList() { - this.taskList = new ArrayList(); - } - public TaskList(ArrayList taskList) { - this.taskList = taskList; - } - - // getters - public int getSize() { - return this.taskList.size(); - } - - public Task getTask(int index) { - return this.taskList.get(index); - } - - private ArrayList getAllTasks() { - return this.taskList; - } - - // setters - public Task markTask(int index) { - Task task = taskList.get(index); - task.setDone(true); - return task; - } - public Task unmarkTask(int index) { - Task task = taskList.get(index); - task.setDone(false); - return task; - } - - // add - - public void addTask(Task task) { - taskList.add(task); - } - - public void addTodo(String task) { - ToDo newTask = new ToDo(task); - this.addTask(newTask); - - } -// public void addDeadline(String task, LocalDateTime by) { -// Deadline newTask = new Deadline(task, by); -// taskList.add(newTask); -// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); -// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); -// } -// public void addEvent(String task, LocalDateTime from, LocalDateTime to) { -// Event newTask = new Event(task, from, to); -// taskList.add(newTask); -// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); -// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); -// } - - public Task deleteTask(int index) { - Task removedTask = taskList.get(index); - taskList.remove(index); - return removedTask; - } - -} diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java deleted file mode 100644 index 1b0f8b5e73..0000000000 --- a/src/main/java/Ui.java +++ /dev/null @@ -1,65 +0,0 @@ -// deals with interactions with the user -import java.util.Scanner; -public class Ui { - Scanner sc; - public Ui() { - this.sc = new Scanner(System.in); - } - public String readCommand() { - return this.sc.nextLine(); - } - public void showWelcome() { - String greeting = "Hello, I'm Dude!\n" + - "What can I do for you?"; - System.out.println(greeting); - } - public void showFarewell() { - String greeting = "Bye. Hope to see you again soon!"; - System.out.println(greeting); - } - public void showLine() { - System.out.println("__________________________________________________"); - } - public void showTaskList(TaskList taskList) { - int nTasks = taskList.getSize(); - if (nTasks == 0) { - System.out.println("You have no saved tasks."); - } else { - for (int i = 0; i < nTasks; i++) { - Task task = taskList.getTask(i); - System.out.printf("%d. %s\n", i+1, task.toString()); - } - } - } - public void showMarkedTask(Task task) { - System.out.println("Nice! I've marked this task as done:"); - System.out.printf(task.toString()); - // task is already done? - } - public void showUnmarkedTask(Task task) { - System.out.println("Nice! I've marked this task as as not done yet:"); - System.out.printf(task.toString()); - // task is already undone? - } - public void showDeletedTask(Task task, int nTasks) { - System.out.println("Noted. I've removed this task:"); - System.out.println(task.toString()); - System.out.printf("Now you have %d tasks in the list.\n", nTasks); - } - public void showAddedTask(Task task, int nTasks) { - System.out.printf("Got it. I've added this task:\n%s\n", task.toString()); - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - public void showUnknownCommand() { - System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); - } - public void showError(String message) { - - } - - - - - public void showLoadingError() { - } -} diff --git a/src/main/java/UnknownCommand.java b/src/main/java/UnknownCommand.java deleted file mode 100644 index f1d3391846..0000000000 --- a/src/main/java/UnknownCommand.java +++ /dev/null @@ -1,6 +0,0 @@ -public class UnknownCommand extends Command { - @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - ui.showUnknownCommand(); - } -} diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java deleted file mode 100644 index 7d49411aa2..0000000000 --- a/src/main/java/UnmarkCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -import java.io.IOException; - -public class UnmarkCommand extends Command { - private int taskIndex; - public UnmarkCommand(int taskIndex) { - this.taskIndex = taskIndex; - } - public void execute(TaskList taskList, Ui ui, Storage storage) { - try { - System.out.println("Executing Unmark Command");; - Task unmarkedTask = taskList.unmarkTask(taskIndex); - ui.showUnmarkedTask(unmarkedTask); - storage.saveTasksToDisk(taskList); - } catch (IOException e) { - System.out.println("Error in Unmark Command"); - } - } -} From 6bcc6ec1f9f2c6d03db1863f96a93577219eb94c Mon Sep 17 00:00:00 2001 From: vivienherq Date: Tue, 12 Sep 2023 01:57:28 +0800 Subject: [PATCH 19/57] Refactor code into Ui, Storage, Parser, TaskList, Command classes --- data/dude.txt | 8 +- src/main/java/AddDeadlineCommand.java | 24 +++ src/main/java/AddEventCommand.java | 26 +++ src/main/java/AddToDoCommand.java | 21 +++ src/main/java/Command.java | 14 ++ src/main/java/DeleteCommand.java | 20 +++ src/main/java/Dude.java | 222 ++++---------------------- src/main/java/DudeException.java | 10 ++ src/main/java/Event.java | 15 +- src/main/java/ExitCommand.java | 10 ++ src/main/java/ListCommand.java | 7 + src/main/java/MarkCommand.java | 19 +++ src/main/java/Parser.java | 52 ++++++ src/main/java/Storage.java | 122 ++++++++++++++ src/main/java/TaskList.java | 69 ++++++++ src/main/java/Ui.java | 65 ++++++++ src/main/java/UnknownCommand.java | 6 + src/main/java/UnmarkCommand.java | 18 +++ 18 files changed, 528 insertions(+), 200 deletions(-) create mode 100644 src/main/java/AddDeadlineCommand.java create mode 100644 src/main/java/AddEventCommand.java create mode 100644 src/main/java/AddToDoCommand.java create mode 100644 src/main/java/Command.java create mode 100644 src/main/java/DeleteCommand.java create mode 100644 src/main/java/DudeException.java create mode 100644 src/main/java/ExitCommand.java create mode 100644 src/main/java/ListCommand.java create mode 100644 src/main/java/MarkCommand.java create mode 100644 src/main/java/Parser.java create mode 100644 src/main/java/Storage.java create mode 100644 src/main/java/TaskList.java create mode 100644 src/main/java/Ui.java create mode 100644 src/main/java/UnknownCommand.java create mode 100644 src/main/java/UnmarkCommand.java diff --git a/data/dude.txt b/data/dude.txt index 5ffac6797b..6c6cfb03be 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -1,3 +1,5 @@ -T | 0 | borrow book -D | 0 | return book | 2023-09-06T14:30 -E | 0 | project meeting | Mon 2pm | 4pm +T | 0 | eat +T | 0 | sleep +D | 0 | ip | 2023-09-22T23:59 +E | 0 | ifg closing ceremony | 2023-09-22T18:00 | 2023-09-22T21:00 +E | 0 | gen meeting | 2023-09-12T20:00 | 2023-09-12T22:00 diff --git a/src/main/java/AddDeadlineCommand.java b/src/main/java/AddDeadlineCommand.java new file mode 100644 index 0000000000..645c1922ba --- /dev/null +++ b/src/main/java/AddDeadlineCommand.java @@ -0,0 +1,24 @@ +import java.io.IOException; +import java.time.LocalDateTime; + +public class AddDeadlineCommand extends Command { + private String taskDescription; + private LocalDateTime byDateTime; + public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { + this.taskDescription = taskDescription; + this.byDateTime = byDateTime; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Add Deadline Command"); + Deadline newTask = new Deadline(taskDescription, byDateTime); + taskList.addTask(newTask); + int nTasks = taskList.getSize(); + ui.showAddedTask(newTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Add Deadline Command"); + } + } +} diff --git a/src/main/java/AddEventCommand.java b/src/main/java/AddEventCommand.java new file mode 100644 index 0000000000..cc596cae66 --- /dev/null +++ b/src/main/java/AddEventCommand.java @@ -0,0 +1,26 @@ +import java.io.IOException; +import java.time.LocalDateTime; + +public class AddEventCommand extends Command { + private String taskDescription; + private LocalDateTime fromDateTime; + private LocalDateTime toDateTime; + public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, LocalDateTime toDateTime) { + this.taskDescription = taskDescription; + this.fromDateTime = fromDateTime; + this.toDateTime = toDateTime; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Add Event Command"); + Event newTask = new Event(taskDescription, fromDateTime, toDateTime); + taskList.addTask(newTask); + int nTasks = taskList.getSize(); + ui.showAddedTask(newTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Add Event Command"); + } + } +} diff --git a/src/main/java/AddToDoCommand.java b/src/main/java/AddToDoCommand.java new file mode 100644 index 0000000000..b2668d01b0 --- /dev/null +++ b/src/main/java/AddToDoCommand.java @@ -0,0 +1,21 @@ +import java.io.IOException; + +public class AddToDoCommand extends Command { + private String taskDescription; + public AddToDoCommand(String taskDescription) { + this.taskDescription = taskDescription; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Add ToDo Command"); + ToDo newTask = new ToDo(taskDescription); + taskList.addTask(newTask); + int nTasks = taskList.getSize(); + ui.showAddedTask(newTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Add ToDo Command"); + } + } +} diff --git a/src/main/java/Command.java b/src/main/java/Command.java new file mode 100644 index 0000000000..8899d2a857 --- /dev/null +++ b/src/main/java/Command.java @@ -0,0 +1,14 @@ +public abstract class Command { + + protected boolean isExit; + + public Command() { + this.isExit = false; + } + + public abstract void execute(TaskList tasks, Ui ui, Storage storage); + + public boolean isExit() { + return this.isExit; + } +} diff --git a/src/main/java/DeleteCommand.java b/src/main/java/DeleteCommand.java new file mode 100644 index 0000000000..7b58749612 --- /dev/null +++ b/src/main/java/DeleteCommand.java @@ -0,0 +1,20 @@ +import java.io.IOException; + +public class DeleteCommand extends Command { + private int taskIndex; + public DeleteCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Delete Command"); + Task deletedTask = taskList.deleteTask(taskIndex); + int nTasks = taskList.getSize(); + ui.showDeletedTask(deletedTask, nTasks); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Delete Command"); + } + } +} diff --git a/src/main/java/Dude.java b/src/main/java/Dude.java index 988e8dda2d..148883461d 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/Dude.java @@ -1,4 +1,9 @@ -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; import java.util.Scanner; import java.util.ArrayList; import java.time.LocalDateTime; @@ -6,208 +11,39 @@ public class Dude { - static ArrayList taskList = new ArrayList(); + private TaskList taskList; + private Storage storage; + private Ui ui; static int nTasks = 0; - private static final String FILE_PATH = "./data/dude.txt"; - - public static void addTodo(String task) { - ToDo newTask = new ToDo(task); -// taskList[nTasks] = newTask; - taskList.add(newTask); - System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); - nTasks += 1; - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - public static void addDeadline(String task, LocalDateTime by) { - Deadline newTask = new Deadline(task, by); -// taskList[nTasks] = newTask; - taskList.add(newTask); - System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); - nTasks += 1; - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - public static void addEvent(String task, String from, String to) { - Event newTask = new Event(task, from, to); -// taskList[nTasks] = newTask; - taskList.add(newTask); - System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); - nTasks += 1; - System.out.printf("Now you have %d tasks in the list. \n", nTasks); - } - - public static void delete(int n) { - Task removedTask = taskList.get(n-1); - taskList.remove(n-1); - nTasks -= 1; - System.out.println("Noted. I've removed this task:"); - System.out.println(removedTask.toString()); - System.out.printf("Now you have %d tasks in the list.\n", nTasks); - - } - - public static void list() { - for (int i = 0; i < nTasks; i++) { - Task task = taskList.get(i); -// Task task = taskList[i]; - System.out.printf("%d. %s\n", i+1, task.toString()); - } - } - - public static void mark(int n) { - taskList.get(n-1).setDone(true); - System.out.println("Nice! I've marked this task as done:"); - System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); - } - - public static void unmark(int n) throws IOException { - taskList.get(n-1).setDone(false); - System.out.println("OK, I've marked this task as not done yet:"); - System.out.printf("%d. %s\n", n, taskList.get(n-1).toString()); - } - - public static void bye() { - String greeting = "Bye. Hope to see you again soon!"; - System.out.println(greeting); - } - - public static void saveTasksToDisk() throws IOException { - String directoryPath = "./data"; - String filePath = "./data/dude.txt"; - - File directory = new File(directoryPath); - if (!directory.exists()) { - if (directory.mkdirs()) { - System.out.println("Directory created at: " + directoryPath); - } else { - System.err.println("Failed to create directory."); - return; - } - } - - File file = new File(filePath); - if (!file.exists()) { - try { - if (file.createNewFile()) { - System.out.println("File created at: " + filePath); - } else { - System.err.println("Failed to create the file."); - } - } catch (IOException e) { - System.err.println("An error occurred while creating the file: " + e.getMessage()); - } - } - - String data = ""; - for (int i = 0; i < nTasks; i++) { - Task task = taskList.get(i); - data += task.saveTask(); - } + public Dude(String filePath) { + this.ui = new Ui(); + this.storage = new Storage(filePath); try { - FileWriter fw = new FileWriter(file); - fw.write(data); - fw.close(); - } catch (IOException e) { - System.out.println(e.toString()); + taskList = new TaskList(storage.loadTasksFromDisk()); + } catch (FileNotFoundException e) { // DudeException + ui.showLoadingError(); + taskList = new TaskList(); } } + public void run() { + ui.showWelcome(); + boolean isExit = false; - public static void loadTasksFromDisk() throws FileNotFoundException { - String filePath = "./data/dude.txt"; - - try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) { - String line; - while ((line = reader.readLine()) != null) { - //System.out.println(line); - String[] taskInfo = line.split("\\s+\\|\\s+"); - - Task task; - - if (taskInfo[0].equals("T")) { - task = new ToDo(taskInfo[2]); - task.setDone(taskInfo[1] == "1"); - taskList.add(task); - nTasks += 1; - } else if (taskInfo[0].equals("D")) { - String byInput = taskInfo[3]; // ISO-8601 e.g. 2023-09-06T14:30 - LocalDateTime by = LocalDateTime.parse(byInput); - // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); - // LocalDateTime by = LocalDateTime.parse(byInput, formatter); - task = new Deadline(taskInfo[2], by); - task.setDone(taskInfo[1] == "1"); - taskList.add(task); - nTasks += 1; - } else if (taskInfo[0].equals("E")) { - task = new Event(taskInfo[2], taskInfo[3], taskInfo[4]); - task.setDone(taskInfo[1] == "1"); - taskList.add(task); - nTasks += 1; - } + while (!isExit) { + try { + String fullCommand = ui.readCommand(); + ui.showLine(); + Command c = Parser.parse(fullCommand); + c.execute(taskList, ui, storage); + isExit = c.isExit(); + } finally { + ui.showLine(); } - } catch (IOException e) { - System.err.println("An error occurred while reading the file: " + e.getMessage()); } } public static void main(String[] args) throws IOException { - String greeting = "Hello, I'm Dude!\n" + - "What can I do for you?"; - System.out.println(greeting); - - loadTasksFromDisk(); - System.out.printf("You have %d saved tasks:\n", nTasks); - list(); - while (true) { - Scanner scanner = new Scanner(System.in); - String input = scanner.nextLine(); - String[] words = input.split(" "); - - if (words[0].equals("list")) { - list(); - } else if (words[0].equals("bye")) { - bye(); - break; - } else if (words[0].equals("mark")) { - mark(Integer.valueOf(words[1])); - saveTasksToDisk(); - } else if (words[0].equals("unmark")) { - unmark(Integer.valueOf(words[1])); - saveTasksToDisk(); - } else if (words[0].equals("todo")) { - if (words.length > 1) { - addTodo(input.substring(5)); - saveTasksToDisk(); - } else { - System.out.println("OOPS!!! The description of a todo cannot be empty."); - } - } else if (words[0].equals("deadline")) { - if (words.length == 1) { - System.out.println("OOPS!!! The description of a deadline cannot be empty."); - } - - String[] taskWords = input.substring(9).split(" /by "); - String byInput = taskWords[1]; //dd/mm/yyyy hh:mm format - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); - LocalDateTime by = LocalDateTime.parse(byInput, formatter); - addDeadline(taskWords[0], by); - saveTasksToDisk(); - } else if (words[0].equals("event")) { - if (words.length == 1) { - System.out.println("OOPS!!! The description of an event cannot be empty."); - } - String[] taskWords = input.substring(6).split(" /"); - String from = taskWords[1].substring(5); - String to = taskWords[2].substring(3); - addEvent(taskWords[0], from, to); - saveTasksToDisk(); - } else if (words[0].equals("delete")) { - delete(Integer.valueOf(words[1])); - } else { - System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); - } - - - - } + new Dude("data/dude.txt").run(); } } \ No newline at end of file diff --git a/src/main/java/DudeException.java b/src/main/java/DudeException.java new file mode 100644 index 0000000000..4e670080e5 --- /dev/null +++ b/src/main/java/DudeException.java @@ -0,0 +1,10 @@ +public class DudeException extends Exception { + DudeException(String message) { + super(message); + } + + @Override + public String toString() { + return this.getMessage(); + } +} diff --git a/src/main/java/Event.java b/src/main/java/Event.java index d425335b24..bcb6f8fb3a 100644 --- a/src/main/java/Event.java +++ b/src/main/java/Event.java @@ -1,7 +1,11 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Locale; + public class Event extends Task { - private String from; - private String to; - Event(String description, String from, String to) { + private LocalDateTime from; + private LocalDateTime to; + Event(String description, LocalDateTime from, LocalDateTime to) { super(description); this.from = from; this.to = to; @@ -24,6 +28,9 @@ public String saveTask() { } @Override public String toString() { - return "[E]" + super.toString() + " (from: " + from + " to: " + to + ")"; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); + String fromFormatted = from.format(formatter); + String toFormatted = to.format(formatter); + return "[E]" + super.toString() + " (from: " + fromFormatted + " to: " + toFormatted + ")"; } } diff --git a/src/main/java/ExitCommand.java b/src/main/java/ExitCommand.java new file mode 100644 index 0000000000..9488b933ba --- /dev/null +++ b/src/main/java/ExitCommand.java @@ -0,0 +1,10 @@ +public class ExitCommand extends Command { + public ExitCommand() { + super.isExit = true; + } + + @Override + public void execute(TaskList tasks, Ui ui, Storage storage) { + ui.showFarewell(); + } +} diff --git a/src/main/java/ListCommand.java b/src/main/java/ListCommand.java new file mode 100644 index 0000000000..b6af2c7d79 --- /dev/null +++ b/src/main/java/ListCommand.java @@ -0,0 +1,7 @@ +public class ListCommand extends Command { + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + System.out.println("Listing..."); + ui.showTaskList(taskList); + } +} diff --git a/src/main/java/MarkCommand.java b/src/main/java/MarkCommand.java new file mode 100644 index 0000000000..19606585bb --- /dev/null +++ b/src/main/java/MarkCommand.java @@ -0,0 +1,19 @@ +import java.io.IOException; + +public class MarkCommand extends Command { + private int taskIndex; + public MarkCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Mark Command");; + Task markedTask = taskList.markTask(taskIndex); + ui.showMarkedTask(markedTask); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Mark Command"); + } + } +} diff --git a/src/main/java/Parser.java b/src/main/java/Parser.java new file mode 100644 index 0000000000..b3b0e73bdd --- /dev/null +++ b/src/main/java/Parser.java @@ -0,0 +1,52 @@ +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +// deals with making sense of the user command +public class Parser { + + private static DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + public static Command parse(String fullCommand) { + String[] commandDetails = fullCommand.split(" ", 2); + String commandType = commandDetails[0]; + Command c; + + if (commandType.equals("bye")){ + c = new ExitCommand(); + } else if (commandType.equals("list")) { + c = new ListCommand(); + } else if (commandType.equals("mark")) { + int taskIndex = Integer.parseInt(commandDetails[1]) - 1; + c = new MarkCommand(taskIndex); + } else if (commandType.equals("unmark")) { + int taskIndex = Integer.parseInt(commandDetails[1]) - 1; + c = new UnmarkCommand(taskIndex); + } else if (commandType.equals("delete")) { + int taskIndex = Integer.parseInt(commandDetails[1]) - 1; + c = new DeleteCommand(taskIndex); + } else if (commandType.equals("todo")) { + String taskDescription = commandDetails[1].trim(); + c = new AddToDoCommand(taskDescription); + // if (userInputDetails.length > 1) + // System.out.println("OOPS!!! The description of a todo cannot be empty."); + } else if (commandType.equals("deadline")) { + String[] taskDetails = commandDetails[1].split("\\s/by\\s"); + String taskDescription = taskDetails[0].trim(); + LocalDateTime byDateTime = LocalDateTime.parse(taskDetails[1].trim(), DATETIME_FORMATTER); + c = new AddDeadlineCommand(taskDescription, byDateTime); + // if (userInputDetails.length == 1) { + // System.out.println("OOPS!!! The description of a deadline cannot be empty."); + } else if (commandType.equals("event")) { + String[] taskDetails = commandDetails[1].split("\\s/from\\s|\\s/to\\s"); + String taskDescription = taskDetails[0].trim(); + LocalDateTime fromDateTime = LocalDateTime.parse(taskDetails[1].trim(), DATETIME_FORMATTER); + LocalDateTime toDateTime = LocalDateTime.parse(taskDetails[2].trim(), DATETIME_FORMATTER); + c = new AddEventCommand(taskDescription, fromDateTime, toDateTime); + // if (userInputDetails.length == 1) { + // System.out.println("OOPS!!! The description of an event cannot be empty."); + } else { + c = new UnknownCommand(); + } + return c; + } + +} diff --git a/src/main/java/Storage.java b/src/main/java/Storage.java new file mode 100644 index 0000000000..140992833c --- /dev/null +++ b/src/main/java/Storage.java @@ -0,0 +1,122 @@ +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Scanner; + +// deals with loading tasks from the file and saving tasks in the file +public class Storage { + private String filepath; + public Storage(String filepath) { + this.filepath = filepath; + } + + public void saveTasksToDisk(TaskList taskList) throws IOException { + File file = new File(this.filepath); + if (!file.exists()) { + try { + if (file.createNewFile()) { + System.out.println("File created at: " + this.filepath); + } else { + System.err.println("Failed to create the file."); + } + } catch (IOException e) { + System.err.println("An error occurred while creating the file: " + e.getMessage()); + } + } + + String data = ""; + for (int i = 0; i < taskList.getSize(); i++) { + Task task = taskList.getTask(i); + data += task.saveTask(); + } + + try { + FileWriter fw = new FileWriter(file); + fw.write(data); + fw.close(); + } catch (IOException e) { + System.out.println(e.toString()); + } + } + + public ArrayList loadTasksFromDisk() throws FileNotFoundException { + ArrayList taskList = new ArrayList(); + + File file = new File(this.filepath); + if (file.exists()) { + try { + Scanner sc = new Scanner(file); + while (sc.hasNext()) { + String storedTaskDetails = sc.nextLine(); + String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); + String taskType = taskDetails[0]; + Task task; + if (taskType.equals("T")) { + task = new ToDo(taskDetails[2]); + task.setDone(taskDetails[1] == "1"); + taskList.add(task); + } else if (taskType.equals("D")) { + String byInput = taskDetails[3]; // ISO-8601 e.g. 2023-09-06T14:30 + LocalDateTime by = LocalDateTime.parse(byInput); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + // LocalDateTime by = LocalDateTime.parse(byInput, formatter); + task = new Deadline(taskDetails[2], by); + task.setDone(taskDetails[1] == "1"); + taskList.add(task); + } else if (taskType.equals("E")) { + LocalDateTime from = LocalDateTime.parse(taskDetails[3]); + LocalDateTime to = LocalDateTime.parse(taskDetails[4]); + task = new Event(taskDetails[2], from, to); + task.setDone(taskDetails[1] == "1"); + taskList.add(task); + } + } + } catch (IOException e) { + System.err.println("An error occurred while reading the file: " + e.getMessage()); + } + } else { + try { + file.createNewFile(); + System.out.println("File created at: " + this.filepath); + } catch (IOException e) { + System.out.println("File creating error"); + System.out.println(e.getMessage()); + } + } + System.out.printf("You have %d saved tasks.\n", taskList.size()); + // TaskList tasks = new TaskList(taskList); + return taskList; + } + + + /* to be fixed + public Task processTaskDetails(String storedTaskDetails) { + String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); + + Task storedTask; + + if (taskDetails[0].equals("T")) { + storedTask = new ToDo(taskDetails[2]); + storedTask.setDone(taskDetails[1] == "1"); + } else if (taskDetails[0].equals("D")) { + String byInput = taskDetails[3]; // ISO-8601 e.g. 2023-09-06T14:30 + LocalDateTime by = LocalDateTime.parse(byInput); + // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + // LocalDateTime by = LocalDateTime.parse(byInput, formatter); + storedTask = new Deadline(taskDetails[2], by); + storedTask.setDone(taskDetails[1] == "1"); + } else if (taskDetails[0].equals("E")) { + storedTask = new Event(taskDetails[2], taskDetails[3], taskDetails[4]); + storedTask.setDone(taskDetails[1] == "1"); + } + return storedTask; + } + + */ + +} diff --git a/src/main/java/TaskList.java b/src/main/java/TaskList.java new file mode 100644 index 0000000000..e861ba659f --- /dev/null +++ b/src/main/java/TaskList.java @@ -0,0 +1,69 @@ +// contains the task list e.g., it has operations to add/delete tasks in the list +import java.time.LocalDateTime; +import java.util.ArrayList; +public class TaskList { + private ArrayList taskList; + + public TaskList() { + this.taskList = new ArrayList(); + } + public TaskList(ArrayList taskList) { + this.taskList = taskList; + } + + // getters + public int getSize() { + return this.taskList.size(); + } + + public Task getTask(int index) { + return this.taskList.get(index); + } + + private ArrayList getAllTasks() { + return this.taskList; + } + + // setters + public Task markTask(int index) { + Task task = taskList.get(index); + task.setDone(true); + return task; + } + public Task unmarkTask(int index) { + Task task = taskList.get(index); + task.setDone(false); + return task; + } + + // add + + public void addTask(Task task) { + taskList.add(task); + } + + public void addTodo(String task) { + ToDo newTask = new ToDo(task); + this.addTask(newTask); + + } +// public void addDeadline(String task, LocalDateTime by) { +// Deadline newTask = new Deadline(task, by); +// taskList.add(newTask); +// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); +// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); +// } +// public void addEvent(String task, LocalDateTime from, LocalDateTime to) { +// Event newTask = new Event(task, from, to); +// taskList.add(newTask); +// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); +// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); +// } + + public Task deleteTask(int index) { + Task removedTask = taskList.get(index); + taskList.remove(index); + return removedTask; + } + +} diff --git a/src/main/java/Ui.java b/src/main/java/Ui.java new file mode 100644 index 0000000000..1b0f8b5e73 --- /dev/null +++ b/src/main/java/Ui.java @@ -0,0 +1,65 @@ +// deals with interactions with the user +import java.util.Scanner; +public class Ui { + Scanner sc; + public Ui() { + this.sc = new Scanner(System.in); + } + public String readCommand() { + return this.sc.nextLine(); + } + public void showWelcome() { + String greeting = "Hello, I'm Dude!\n" + + "What can I do for you?"; + System.out.println(greeting); + } + public void showFarewell() { + String greeting = "Bye. Hope to see you again soon!"; + System.out.println(greeting); + } + public void showLine() { + System.out.println("__________________________________________________"); + } + public void showTaskList(TaskList taskList) { + int nTasks = taskList.getSize(); + if (nTasks == 0) { + System.out.println("You have no saved tasks."); + } else { + for (int i = 0; i < nTasks; i++) { + Task task = taskList.getTask(i); + System.out.printf("%d. %s\n", i+1, task.toString()); + } + } + } + public void showMarkedTask(Task task) { + System.out.println("Nice! I've marked this task as done:"); + System.out.printf(task.toString()); + // task is already done? + } + public void showUnmarkedTask(Task task) { + System.out.println("Nice! I've marked this task as as not done yet:"); + System.out.printf(task.toString()); + // task is already undone? + } + public void showDeletedTask(Task task, int nTasks) { + System.out.println("Noted. I've removed this task:"); + System.out.println(task.toString()); + System.out.printf("Now you have %d tasks in the list.\n", nTasks); + } + public void showAddedTask(Task task, int nTasks) { + System.out.printf("Got it. I've added this task:\n%s\n", task.toString()); + System.out.printf("Now you have %d tasks in the list. \n", nTasks); + } + public void showUnknownCommand() { + System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); + } + public void showError(String message) { + + } + + + + + public void showLoadingError() { + } +} diff --git a/src/main/java/UnknownCommand.java b/src/main/java/UnknownCommand.java new file mode 100644 index 0000000000..f1d3391846 --- /dev/null +++ b/src/main/java/UnknownCommand.java @@ -0,0 +1,6 @@ +public class UnknownCommand extends Command { + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + ui.showUnknownCommand(); + } +} diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/UnmarkCommand.java new file mode 100644 index 0000000000..7d49411aa2 --- /dev/null +++ b/src/main/java/UnmarkCommand.java @@ -0,0 +1,18 @@ +import java.io.IOException; + +public class UnmarkCommand extends Command { + private int taskIndex; + public UnmarkCommand(int taskIndex) { + this.taskIndex = taskIndex; + } + public void execute(TaskList taskList, Ui ui, Storage storage) { + try { + System.out.println("Executing Unmark Command");; + Task unmarkedTask = taskList.unmarkTask(taskIndex); + ui.showUnmarkedTask(unmarkedTask); + storage.saveTasksToDisk(taskList); + } catch (IOException e) { + System.out.println("Error in Unmark Command"); + } + } +} From 85e358c1d3ce876c1136c53928839253b603b281 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Tue, 12 Sep 2023 03:15:21 +0800 Subject: [PATCH 20/57] Organise classes into packages --- src/main/java/{ => dude}/Dude.java | 12 ++++-------- src/main/java/{ => dude}/DudeException.java | 1 + src/main/java/{ => dude}/Parser.java | 4 ++++ src/main/java/{ => dude}/Storage.java | 9 +++++++-- src/main/java/{ => dude}/TaskList.java | 15 +++++++++------ src/main/java/{ => dude}/Ui.java | 8 ++++---- .../{ => dude/command}/AddDeadlineCommand.java | 7 +++++++ .../java/{ => dude/command}/AddEventCommand.java | 7 +++++++ .../java/{ => dude/command}/AddToDoCommand.java | 7 +++++++ src/main/java/{ => dude/command}/Command.java | 8 +++++++- .../java/{ => dude/command}/DeleteCommand.java | 7 +++++++ src/main/java/{ => dude/command}/ExitCommand.java | 8 +++++++- src/main/java/{ => dude/command}/ListCommand.java | 6 ++++++ src/main/java/{ => dude/command}/MarkCommand.java | 7 +++++++ .../java/{ => dude/command}/UnknownCommand.java | 6 ++++++ .../java/{ => dude/command}/UnmarkCommand.java | 7 +++++++ src/main/java/{ => dude/task}/Deadline.java | 4 +++- src/main/java/{ => dude/task}/Event.java | 4 +++- src/main/java/{ => dude/task}/Task.java | 2 ++ src/main/java/{ => dude/task}/ToDo.java | 4 +++- 20 files changed, 108 insertions(+), 25 deletions(-) rename src/main/java/{ => dude}/Dude.java (82%) rename src/main/java/{ => dude}/DudeException.java (93%) rename src/main/java/{ => dude}/Parser.java (98%) rename src/main/java/{ => dude}/Storage.java (97%) rename src/main/java/{ => dude}/TaskList.java (91%) rename src/main/java/{ => dude}/Ui.java (98%) rename src/main/java/{ => dude/command}/AddDeadlineCommand.java (89%) rename src/main/java/{ => dude/command}/AddEventCommand.java (90%) rename src/main/java/{ => dude/command}/AddToDoCommand.java (87%) rename src/main/java/{ => dude/command}/Command.java (54%) rename src/main/java/{ => dude/command}/DeleteCommand.java (86%) rename src/main/java/{ => dude/command}/ExitCommand.java (50%) rename src/main/java/{ => dude/command}/ListCommand.java (71%) rename src/main/java/{ => dude/command}/MarkCommand.java (84%) rename src/main/java/{ => dude/command}/UnknownCommand.java (67%) rename src/main/java/{ => dude/command}/UnmarkCommand.java (84%) rename src/main/java/{ => dude/task}/Deadline.java (92%) rename src/main/java/{ => dude/task}/Event.java (91%) rename src/main/java/{ => dude/task}/Task.java (97%) rename src/main/java/{ => dude/task}/ToDo.java (89%) diff --git a/src/main/java/Dude.java b/src/main/java/dude/Dude.java similarity index 82% rename from src/main/java/Dude.java rename to src/main/java/dude/Dude.java index 148883461d..7734393a06 100644 --- a/src/main/java/Dude.java +++ b/src/main/java/dude/Dude.java @@ -1,13 +1,9 @@ -import java.io.BufferedReader; -import java.io.File; +package dude; + +import dude.command.Command; + import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; -import java.util.Scanner; -import java.util.ArrayList; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; public class Dude { diff --git a/src/main/java/DudeException.java b/src/main/java/dude/DudeException.java similarity index 93% rename from src/main/java/DudeException.java rename to src/main/java/dude/DudeException.java index 4e670080e5..64e0f0d108 100644 --- a/src/main/java/DudeException.java +++ b/src/main/java/dude/DudeException.java @@ -1,3 +1,4 @@ +package dude; public class DudeException extends Exception { DudeException(String message) { super(message); diff --git a/src/main/java/Parser.java b/src/main/java/dude/Parser.java similarity index 98% rename from src/main/java/Parser.java rename to src/main/java/dude/Parser.java index b3b0e73bdd..7f14f44900 100644 --- a/src/main/java/Parser.java +++ b/src/main/java/dude/Parser.java @@ -1,3 +1,7 @@ +package dude; + +import dude.command.*; + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; diff --git a/src/main/java/Storage.java b/src/main/java/dude/Storage.java similarity index 97% rename from src/main/java/Storage.java rename to src/main/java/dude/Storage.java index 140992833c..62beced335 100644 --- a/src/main/java/Storage.java +++ b/src/main/java/dude/Storage.java @@ -1,7 +1,12 @@ -import java.io.BufferedReader; +package dude; + +import dude.task.Deadline; +import dude.task.Event; +import dude.task.Task; +import dude.task.ToDo; + import java.io.File; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.time.LocalDateTime; diff --git a/src/main/java/TaskList.java b/src/main/java/dude/TaskList.java similarity index 91% rename from src/main/java/TaskList.java rename to src/main/java/dude/TaskList.java index e861ba659f..b8ed277548 100644 --- a/src/main/java/TaskList.java +++ b/src/main/java/dude/TaskList.java @@ -1,5 +1,8 @@ +package dude; + // contains the task list e.g., it has operations to add/delete tasks in the list -import java.time.LocalDateTime; +import dude.task.Task; + import java.util.ArrayList; public class TaskList { private ArrayList taskList; @@ -42,11 +45,11 @@ public void addTask(Task task) { taskList.add(task); } - public void addTodo(String task) { - ToDo newTask = new ToDo(task); - this.addTask(newTask); - - } +// public void addTodo(String task) { +// ToDo newTask = new ToDo(task); +// this.addTask(newTask); +// +// } // public void addDeadline(String task, LocalDateTime by) { // Deadline newTask = new Deadline(task, by); // taskList.add(newTask); diff --git a/src/main/java/Ui.java b/src/main/java/dude/Ui.java similarity index 98% rename from src/main/java/Ui.java rename to src/main/java/dude/Ui.java index 1b0f8b5e73..92f34061de 100644 --- a/src/main/java/Ui.java +++ b/src/main/java/dude/Ui.java @@ -1,4 +1,8 @@ +package dude; + // deals with interactions with the user +import dude.task.Task; + import java.util.Scanner; public class Ui { Scanner sc; @@ -54,12 +58,8 @@ public void showUnknownCommand() { System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); } public void showError(String message) { - } - - - public void showLoadingError() { } } diff --git a/src/main/java/AddDeadlineCommand.java b/src/main/java/dude/command/AddDeadlineCommand.java similarity index 89% rename from src/main/java/AddDeadlineCommand.java rename to src/main/java/dude/command/AddDeadlineCommand.java index 645c1922ba..30de7dabfc 100644 --- a/src/main/java/AddDeadlineCommand.java +++ b/src/main/java/dude/command/AddDeadlineCommand.java @@ -1,3 +1,10 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.Deadline; + import java.io.IOException; import java.time.LocalDateTime; diff --git a/src/main/java/AddEventCommand.java b/src/main/java/dude/command/AddEventCommand.java similarity index 90% rename from src/main/java/AddEventCommand.java rename to src/main/java/dude/command/AddEventCommand.java index cc596cae66..0d32ab571f 100644 --- a/src/main/java/AddEventCommand.java +++ b/src/main/java/dude/command/AddEventCommand.java @@ -1,3 +1,10 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.Event; + import java.io.IOException; import java.time.LocalDateTime; diff --git a/src/main/java/AddToDoCommand.java b/src/main/java/dude/command/AddToDoCommand.java similarity index 87% rename from src/main/java/AddToDoCommand.java rename to src/main/java/dude/command/AddToDoCommand.java index b2668d01b0..eab8c57223 100644 --- a/src/main/java/AddToDoCommand.java +++ b/src/main/java/dude/command/AddToDoCommand.java @@ -1,3 +1,10 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.ToDo; + import java.io.IOException; public class AddToDoCommand extends Command { diff --git a/src/main/java/Command.java b/src/main/java/dude/command/Command.java similarity index 54% rename from src/main/java/Command.java rename to src/main/java/dude/command/Command.java index 8899d2a857..793ddc683a 100644 --- a/src/main/java/Command.java +++ b/src/main/java/dude/command/Command.java @@ -1,3 +1,9 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; + public abstract class Command { protected boolean isExit; @@ -6,7 +12,7 @@ public Command() { this.isExit = false; } - public abstract void execute(TaskList tasks, Ui ui, Storage storage); + public abstract void execute(TaskList taskList, Ui ui, Storage storage); public boolean isExit() { return this.isExit; diff --git a/src/main/java/DeleteCommand.java b/src/main/java/dude/command/DeleteCommand.java similarity index 86% rename from src/main/java/DeleteCommand.java rename to src/main/java/dude/command/DeleteCommand.java index 7b58749612..caabaf2af4 100644 --- a/src/main/java/DeleteCommand.java +++ b/src/main/java/dude/command/DeleteCommand.java @@ -1,3 +1,10 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.Task; + import java.io.IOException; public class DeleteCommand extends Command { diff --git a/src/main/java/ExitCommand.java b/src/main/java/dude/command/ExitCommand.java similarity index 50% rename from src/main/java/ExitCommand.java rename to src/main/java/dude/command/ExitCommand.java index 9488b933ba..16077c6f97 100644 --- a/src/main/java/ExitCommand.java +++ b/src/main/java/dude/command/ExitCommand.java @@ -1,10 +1,16 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; + public class ExitCommand extends Command { public ExitCommand() { super.isExit = true; } @Override - public void execute(TaskList tasks, Ui ui, Storage storage) { + public void execute(TaskList taskList, Ui ui, Storage storage) { ui.showFarewell(); } } diff --git a/src/main/java/ListCommand.java b/src/main/java/dude/command/ListCommand.java similarity index 71% rename from src/main/java/ListCommand.java rename to src/main/java/dude/command/ListCommand.java index b6af2c7d79..a3a449f9b7 100644 --- a/src/main/java/ListCommand.java +++ b/src/main/java/dude/command/ListCommand.java @@ -1,3 +1,9 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; + public class ListCommand extends Command { @Override public void execute(TaskList taskList, Ui ui, Storage storage) { diff --git a/src/main/java/MarkCommand.java b/src/main/java/dude/command/MarkCommand.java similarity index 84% rename from src/main/java/MarkCommand.java rename to src/main/java/dude/command/MarkCommand.java index 19606585bb..4170d47673 100644 --- a/src/main/java/MarkCommand.java +++ b/src/main/java/dude/command/MarkCommand.java @@ -1,3 +1,10 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.Task; + import java.io.IOException; public class MarkCommand extends Command { diff --git a/src/main/java/UnknownCommand.java b/src/main/java/dude/command/UnknownCommand.java similarity index 67% rename from src/main/java/UnknownCommand.java rename to src/main/java/dude/command/UnknownCommand.java index f1d3391846..f9d8b180c8 100644 --- a/src/main/java/UnknownCommand.java +++ b/src/main/java/dude/command/UnknownCommand.java @@ -1,3 +1,9 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; + public class UnknownCommand extends Command { @Override public void execute(TaskList taskList, Ui ui, Storage storage) { diff --git a/src/main/java/UnmarkCommand.java b/src/main/java/dude/command/UnmarkCommand.java similarity index 84% rename from src/main/java/UnmarkCommand.java rename to src/main/java/dude/command/UnmarkCommand.java index 7d49411aa2..524c6efc01 100644 --- a/src/main/java/UnmarkCommand.java +++ b/src/main/java/dude/command/UnmarkCommand.java @@ -1,3 +1,10 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.Task; + import java.io.IOException; public class UnmarkCommand extends Command { diff --git a/src/main/java/Deadline.java b/src/main/java/dude/task/Deadline.java similarity index 92% rename from src/main/java/Deadline.java rename to src/main/java/dude/task/Deadline.java index 6c49e21afe..80a0c6cb86 100644 --- a/src/main/java/Deadline.java +++ b/src/main/java/dude/task/Deadline.java @@ -1,10 +1,12 @@ +package dude.task; + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; public class Deadline extends Task { LocalDateTime by; - Deadline(String description, LocalDateTime by) { + public Deadline(String description, LocalDateTime by) { super(description); this.by = by; } diff --git a/src/main/java/Event.java b/src/main/java/dude/task/Event.java similarity index 91% rename from src/main/java/Event.java rename to src/main/java/dude/task/Event.java index bcb6f8fb3a..9619c6f97b 100644 --- a/src/main/java/Event.java +++ b/src/main/java/dude/task/Event.java @@ -1,3 +1,5 @@ +package dude.task; + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Locale; @@ -5,7 +7,7 @@ public class Event extends Task { private LocalDateTime from; private LocalDateTime to; - Event(String description, LocalDateTime from, LocalDateTime to) { + public Event(String description, LocalDateTime from, LocalDateTime to) { super(description); this.from = from; this.to = to; diff --git a/src/main/java/Task.java b/src/main/java/dude/task/Task.java similarity index 97% rename from src/main/java/Task.java rename to src/main/java/dude/task/Task.java index c818de6a8c..9e3e7a116d 100644 --- a/src/main/java/Task.java +++ b/src/main/java/dude/task/Task.java @@ -1,3 +1,5 @@ +package dude.task; + public class Task { private String description; private boolean done; diff --git a/src/main/java/ToDo.java b/src/main/java/dude/task/ToDo.java similarity index 89% rename from src/main/java/ToDo.java rename to src/main/java/dude/task/ToDo.java index d039f05bdf..dc49c8bba4 100644 --- a/src/main/java/ToDo.java +++ b/src/main/java/dude/task/ToDo.java @@ -1,5 +1,7 @@ +package dude.task; + public class ToDo extends Task { - ToDo(String description) { + public ToDo(String description) { super(description); } @Override From 23714e199d5e3ab36f67fa3282897524943e3873 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 13 Sep 2023 11:17:18 +0800 Subject: [PATCH 21/57] Add Gradle support --- build.gradle | 4 ++-- data/dude.txt | 3 ++- gradle/wrapper/gradle-wrapper.jar | Bin 63375 -> 61624 bytes gradle/wrapper/gradle-wrapper.properties | 1 - gradlew | 16 ++++++---------- src/main/java/dude/Ui.java | 2 ++ 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/build.gradle b/build.gradle index a388517ae1..4c6df08211 100644 --- a/build.gradle +++ b/build.gradle @@ -28,11 +28,11 @@ test { } application { - mainClass.set("seedu.duke.Duke") + mainClass.set("dude.Dude") } shadowJar { - archiveBaseName = "duke" + archiveBaseName = "dude" archiveClassifier = null dependsOn("distZip", "distTar") } diff --git a/data/dude.txt b/data/dude.txt index 6c6cfb03be..fd0e578b0e 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -1,5 +1,6 @@ T | 0 | eat -T | 0 | sleep +T | 1 | sleep D | 0 | ip | 2023-09-22T23:59 E | 0 | ifg closing ceremony | 2023-09-22T18:00 | 2023-09-22T21:00 E | 0 | gen meeting | 2023-09-12T20:00 | 2023-09-12T22:00 +T | 0 | go to school diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4cdf41af1ab109bc7f253b2b887023340..afba109285af78dbd2a1d187e33ac4f87c76e392 100644 GIT binary patch delta 24872 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 HzpnldrMqp; delta 26705 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 66c01cfeba..4e86b92707 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,6 +2,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip networkTimeout=10000 -validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fcb6fca147..65dcd68d65 100755 --- a/gradlew +++ b/gradlew @@ -85,6 +85,9 @@ done APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -130,13 +133,10 @@ location of your Java installation." fi else JAVACMD=java - if ! command -v java >/dev/null 2>&1 - then - die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." - fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,10 +197,6 @@ if "$cygwin" || "$msys" ; then done fi - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/src/main/java/dude/Ui.java b/src/main/java/dude/Ui.java index 92f34061de..4149812abd 100644 --- a/src/main/java/dude/Ui.java +++ b/src/main/java/dude/Ui.java @@ -38,11 +38,13 @@ public void showTaskList(TaskList taskList) { public void showMarkedTask(Task task) { System.out.println("Nice! I've marked this task as done:"); System.out.printf(task.toString()); + System.out.println(); // task is already done? } public void showUnmarkedTask(Task task) { System.out.println("Nice! I've marked this task as as not done yet:"); System.out.printf(task.toString()); + System.out.println(); // task is already undone? } public void showDeletedTask(Task task, int nTasks) { From 88e778abadb9c5b20ac86a39931ec5b05094e955 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 13 Sep 2023 13:02:03 +0800 Subject: [PATCH 22/57] Add JUnit tests --- src/test/java/dude/TaskListTest.java | 8 ++++++++ src/test/java/dude/task/DeadlineTest.java | 17 +++++++++++++++++ src/test/java/dude/task/EventTest.java | 18 ++++++++++++++++++ src/test/java/dude/task/ToDoTest.java | 14 ++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 src/test/java/dude/TaskListTest.java create mode 100644 src/test/java/dude/task/DeadlineTest.java create mode 100644 src/test/java/dude/task/EventTest.java create mode 100644 src/test/java/dude/task/ToDoTest.java diff --git a/src/test/java/dude/TaskListTest.java b/src/test/java/dude/TaskListTest.java new file mode 100644 index 0000000000..c3cdb0d8c6 --- /dev/null +++ b/src/test/java/dude/TaskListTest.java @@ -0,0 +1,8 @@ +package dude; //same package as the class being tested + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class TaskListTest { + +} diff --git a/src/test/java/dude/task/DeadlineTest.java b/src/test/java/dude/task/DeadlineTest.java new file mode 100644 index 0000000000..32162bb46e --- /dev/null +++ b/src/test/java/dude/task/DeadlineTest.java @@ -0,0 +1,17 @@ +package dude.task; + +import java.time.LocalDateTime; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class DeadlineTest { + @Test + public void createDeadlineTest(){ + String description = "Assignment"; + LocalDateTime by = LocalDateTime.of(2023, 9, 11, 23, 59); + Deadline deadline = new Deadline(description, by); + String expected = "[D][ ] Assignment (by: 11 Sep 2023 11:59 PM)"; + assertEquals(expected, deadline.toString()); + } + +} diff --git a/src/test/java/dude/task/EventTest.java b/src/test/java/dude/task/EventTest.java new file mode 100644 index 0000000000..deb5ff242d --- /dev/null +++ b/src/test/java/dude/task/EventTest.java @@ -0,0 +1,18 @@ +package dude.task; + +import java.time.LocalDateTime; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class EventTest { + @Test + public void createDeadlineTest(){ + String description = "Tutorial"; + LocalDateTime from = LocalDateTime.of(2023, 9, 11, 14, 0); + LocalDateTime to = LocalDateTime.of(2023, 9, 11, 15, 0); + Event event = new Event(description, from, to); + String expected = "[E][ ] Tutorial (from: 11 Sep 2023 02:00 PM to: 11 Sep 2023 03:00 PM)"; + assertEquals(expected, event.toString()); + } + +} \ No newline at end of file diff --git a/src/test/java/dude/task/ToDoTest.java b/src/test/java/dude/task/ToDoTest.java new file mode 100644 index 0000000000..56f27468ce --- /dev/null +++ b/src/test/java/dude/task/ToDoTest.java @@ -0,0 +1,14 @@ +package dude.task; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ToDoTest { + @Test + public void createDeadlineTest(){ + String description = "Homework"; + ToDo todo = new ToDo(description); + String expected = "[T][ ] Homework"; + assertEquals(expected, todo.toString()); + } +} From 1fef7f762185caf9e7a2b8495bff21f4a4d8a169 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 13 Sep 2023 13:26:49 +0800 Subject: [PATCH 23/57] Modify build.gradle for JAR creation --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 4c6df08211..35984658d8 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,7 @@ application { shadowJar { archiveBaseName = "dude" + archiveFileName = "dude.jar" archiveClassifier = null dependsOn("distZip", "distTar") } From 0314cf6d37544e065797f130b35aea042ff5bbc2 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 13 Sep 2023 16:59:10 +0800 Subject: [PATCH 24/57] Implement find feature to search for tasks --- data/dude.txt | 4 +++- src/main/java/dude/Parser.java | 3 +++ src/main/java/dude/TaskList.java | 10 +++++++++ src/main/java/dude/command/FindCommand.java | 25 +++++++++++++++++++++ src/main/java/dude/task/Task.java | 6 ++++- 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/main/java/dude/command/FindCommand.java diff --git a/data/dude.txt b/data/dude.txt index fd0e578b0e..95fdf0093a 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -1,6 +1,8 @@ T | 0 | eat -T | 1 | sleep +T | 0 | sleep D | 0 | ip | 2023-09-22T23:59 E | 0 | ifg closing ceremony | 2023-09-22T18:00 | 2023-09-22T21:00 E | 0 | gen meeting | 2023-09-12T20:00 | 2023-09-12T22:00 T | 0 | go to school +T | 0 | sleep again +T | 0 | sleep tomorrow diff --git a/src/main/java/dude/Parser.java b/src/main/java/dude/Parser.java index 7f14f44900..f04436d261 100644 --- a/src/main/java/dude/Parser.java +++ b/src/main/java/dude/Parser.java @@ -47,6 +47,9 @@ public static Command parse(String fullCommand) { c = new AddEventCommand(taskDescription, fromDateTime, toDateTime); // if (userInputDetails.length == 1) { // System.out.println("OOPS!!! The description of an event cannot be empty."); + } else if (commandType.equals("find")) { + String searchKeywords = commandDetails[1].trim(); + c = new FindCommand(searchKeywords); } else { c = new UnknownCommand(); } diff --git a/src/main/java/dude/TaskList.java b/src/main/java/dude/TaskList.java index b8ed277548..2389130acf 100644 --- a/src/main/java/dude/TaskList.java +++ b/src/main/java/dude/TaskList.java @@ -69,4 +69,14 @@ public Task deleteTask(int index) { return removedTask; } + public TaskList findTasks(String taskKeywords) { + TaskList searchResults = new TaskList(); + for (int i = 0; i < this.getSize(); i++) { + Task task = this.getTask(i); + if (task.containKeywords(taskKeywords)) { + searchResults.addTask(task); + } + } + return searchResults; + } } diff --git a/src/main/java/dude/command/FindCommand.java b/src/main/java/dude/command/FindCommand.java new file mode 100644 index 0000000000..ad6a5057cb --- /dev/null +++ b/src/main/java/dude/command/FindCommand.java @@ -0,0 +1,25 @@ +package dude.command; + +import dude.Storage; +import dude.TaskList; +import dude.Ui; +import dude.task.ToDo; + +import java.io.IOException; + +public class FindCommand extends Command { + + private String searchKeywords; + + public FindCommand(String searchKeywords) { + this.searchKeywords = searchKeywords; + } + + @Override + public void execute(TaskList taskList, Ui ui, Storage storage) { + System.out.println("Executing Find Command"); + TaskList searchResults = taskList.findTasks(searchKeywords); + ui.showTaskList(searchResults); + } + +} diff --git a/src/main/java/dude/task/Task.java b/src/main/java/dude/task/Task.java index 9e3e7a116d..6b93781fd3 100644 --- a/src/main/java/dude/task/Task.java +++ b/src/main/java/dude/task/Task.java @@ -24,7 +24,11 @@ public void setDone(boolean done) { public String getType() { return "task"; } - public String saveTask () {return this.description; } + public String saveTask() {return this.description; } + + public boolean containKeywords(String keywords){ + return this.description.contains(keywords); + } @Override public String toString() { From 1e5aa08168c2535e4c557ed28040b2a850232ce1 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 13 Sep 2023 22:13:58 +0800 Subject: [PATCH 25/57] Add JavaDocs to methods and classes --- src/main/java/dude/Dude.java | 1 + src/main/java/dude/Parser.java | 23 +++++++-- src/main/java/dude/Storage.java | 23 ++++++++- src/main/java/dude/TaskList.java | 47 ++++++++++--------- src/main/java/dude/Ui.java | 5 +- .../java/dude/command/AddDeadlineCommand.java | 11 +++++ .../java/dude/command/AddEventCommand.java | 12 +++++ .../java/dude/command/AddToDoCommand.java | 11 +++++ src/main/java/dude/command/DeleteCommand.java | 11 +++++ src/main/java/dude/command/ExitCommand.java | 10 ++++ src/main/java/dude/command/ListCommand.java | 11 +++++ src/main/java/dude/command/MarkCommand.java | 12 +++++ .../java/dude/command/UnknownCommand.java | 11 +++++ src/main/java/dude/command/UnmarkCommand.java | 12 +++++ src/main/java/dude/task/Deadline.java | 20 ++++++++ src/main/java/dude/task/Event.java | 21 +++++++++ src/main/java/dude/task/Task.java | 19 +++++++- src/main/java/dude/task/ToDo.java | 18 +++++++ 18 files changed, 250 insertions(+), 28 deletions(-) diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index 7734393a06..2d0b2d281e 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -22,6 +22,7 @@ public Dude(String filePath) { taskList = new TaskList(); } } + public void run() { ui.showWelcome(); boolean isExit = false; diff --git a/src/main/java/dude/Parser.java b/src/main/java/dude/Parser.java index 7f14f44900..132974b158 100644 --- a/src/main/java/dude/Parser.java +++ b/src/main/java/dude/Parser.java @@ -1,14 +1,31 @@ package dude; -import dude.command.*; +import dude.command.AddDeadlineCommand; +import dude.command.AddEventCommand; +import dude.command.AddToDoCommand; +import dude.command.Command; +import dude.command.DeleteCommand; +import dude.command.ExitCommand; +import dude.command.ListCommand; +import dude.command.MarkCommand; +import dude.command.UnknownCommand; +import dude.command.UnmarkCommand; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -// deals with making sense of the user command +/** + * Represents a parser that parses user input and deals with making sense of the user command. + */ public class Parser { - private static DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + + /** + * Parses the user's input and returns the corresponding command. + * + * @param fullCommand The full user command input. + * @return A command object representing the user's intent. + */ public static Command parse(String fullCommand) { String[] commandDetails = fullCommand.split(" ", 2); String commandType = commandDetails[0]; diff --git a/src/main/java/dude/Storage.java b/src/main/java/dude/Storage.java index 62beced335..fc9b44c492 100644 --- a/src/main/java/dude/Storage.java +++ b/src/main/java/dude/Storage.java @@ -13,13 +13,27 @@ import java.util.ArrayList; import java.util.Scanner; -// deals with loading tasks from the file and saving tasks in the file +/** + * Represents the Storage system of Dude and deals with loading tasks from + * the file and saving tasks in the file. + */ public class Storage { private String filepath; + + /** + * Constructs a new Storage object with the specified filepath. + * + * @param filepath Path to the file. + */ public Storage(String filepath) { this.filepath = filepath; } + /** + * Saves the task list to the file specified by filepath. + * + * @param taskList List of tasks to be saved. + */ public void saveTasksToDisk(TaskList taskList) throws IOException { File file = new File(this.filepath); if (!file.exists()) { @@ -49,6 +63,12 @@ public void saveTasksToDisk(TaskList taskList) throws IOException { } } + /** + * Loads the saved tasks from the file specified by filepath. + * + * @return List of tasks from the file. + * @throws FileNotFoundException If no file is not found in the filepath. + */ public ArrayList loadTasksFromDisk() throws FileNotFoundException { ArrayList taskList = new ArrayList(); @@ -98,7 +118,6 @@ public ArrayList loadTasksFromDisk() throws FileNotFoundException { return taskList; } - /* to be fixed public Task processTaskDetails(String storedTaskDetails) { String[] taskDetails = storedTaskDetails.split("\\s+\\|\\s+"); diff --git a/src/main/java/dude/TaskList.java b/src/main/java/dude/TaskList.java index b8ed277548..b9f408ce7e 100644 --- a/src/main/java/dude/TaskList.java +++ b/src/main/java/dude/TaskList.java @@ -4,12 +4,17 @@ import dude.task.Task; import java.util.ArrayList; + +/** + * Represents a list of tasks. + */ public class TaskList { private ArrayList taskList; public TaskList() { this.taskList = new ArrayList(); } + public TaskList(ArrayList taskList) { this.taskList = taskList; } @@ -27,42 +32,42 @@ private ArrayList getAllTasks() { return this.taskList; } - // setters + /** + * Marks a task as done. + * + * @param index Index of the task to be marked as done. + */ public Task markTask(int index) { Task task = taskList.get(index); task.setDone(true); return task; } + + /** + * Marks a task as undone. + * + * @param index Index of the task to be marked as undone. + */ public Task unmarkTask(int index) { Task task = taskList.get(index); task.setDone(false); return task; } - // add - + /** + * Adds a task to the list. + * + * @param task Task to be added to the list. + */ public void addTask(Task task) { taskList.add(task); } -// public void addTodo(String task) { -// ToDo newTask = new ToDo(task); -// this.addTask(newTask); -// -// } -// public void addDeadline(String task, LocalDateTime by) { -// Deadline newTask = new Deadline(task, by); -// taskList.add(newTask); -// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); -// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); -// } -// public void addEvent(String task, LocalDateTime from, LocalDateTime to) { -// Event newTask = new Event(task, from, to); -// taskList.add(newTask); -// System.out.printf("Got it. I've added this task:\n%s\n", newTask.toString()); -// System.out.printf("Now you have %d tasks in the list. \n", taskList.size()); -// } - + /** + * Removes a task from the list. + * + * @param index Index of the task to be removed from the list. + */ public Task deleteTask(int index) { Task removedTask = taskList.get(index); taskList.remove(index); diff --git a/src/main/java/dude/Ui.java b/src/main/java/dude/Ui.java index 4149812abd..b1b3ef36e3 100644 --- a/src/main/java/dude/Ui.java +++ b/src/main/java/dude/Ui.java @@ -1,9 +1,12 @@ package dude; -// deals with interactions with the user import dude.task.Task; import java.util.Scanner; + +/** + * Represents the UI of Dude and deals with interactions with the user. + */ public class Ui { Scanner sc; public Ui() { diff --git a/src/main/java/dude/command/AddDeadlineCommand.java b/src/main/java/dude/command/AddDeadlineCommand.java index 30de7dabfc..fcdcad63d6 100644 --- a/src/main/java/dude/command/AddDeadlineCommand.java +++ b/src/main/java/dude/command/AddDeadlineCommand.java @@ -8,6 +8,9 @@ import java.io.IOException; import java.time.LocalDateTime; +/** + * Represents a command that adds a Deadline task. + */ public class AddDeadlineCommand extends Command { private String taskDescription; private LocalDateTime byDateTime; @@ -15,6 +18,14 @@ public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { this.taskDescription = taskDescription; this.byDateTime = byDateTime; } + + /** + * Executes the command to add a Deadline task. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/AddEventCommand.java b/src/main/java/dude/command/AddEventCommand.java index 0d32ab571f..5ac3fe2269 100644 --- a/src/main/java/dude/command/AddEventCommand.java +++ b/src/main/java/dude/command/AddEventCommand.java @@ -8,15 +8,27 @@ import java.io.IOException; import java.time.LocalDateTime; +/** + * Represents a command that adds an Event task. + */ public class AddEventCommand extends Command { private String taskDescription; private LocalDateTime fromDateTime; private LocalDateTime toDateTime; + public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, LocalDateTime toDateTime) { this.taskDescription = taskDescription; this.fromDateTime = fromDateTime; this.toDateTime = toDateTime; } + + /** + * Executes the command to add an Event task. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/AddToDoCommand.java b/src/main/java/dude/command/AddToDoCommand.java index eab8c57223..08c8719c0f 100644 --- a/src/main/java/dude/command/AddToDoCommand.java +++ b/src/main/java/dude/command/AddToDoCommand.java @@ -7,11 +7,22 @@ import java.io.IOException; +/** + * Represents a command that adds a ToDo task. + */ public class AddToDoCommand extends Command { private String taskDescription; public AddToDoCommand(String taskDescription) { this.taskDescription = taskDescription; } + + /** + * Executes the command to add a ToDo task. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/DeleteCommand.java b/src/main/java/dude/command/DeleteCommand.java index caabaf2af4..338f4da998 100644 --- a/src/main/java/dude/command/DeleteCommand.java +++ b/src/main/java/dude/command/DeleteCommand.java @@ -7,11 +7,22 @@ import java.io.IOException; +/** + * Represents a command that deletes task. + */ public class DeleteCommand extends Command { private int taskIndex; public DeleteCommand(int taskIndex) { this.taskIndex = taskIndex; } + + /** + * Executes the command to delete a task. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/ExitCommand.java b/src/main/java/dude/command/ExitCommand.java index 16077c6f97..b142605370 100644 --- a/src/main/java/dude/command/ExitCommand.java +++ b/src/main/java/dude/command/ExitCommand.java @@ -4,11 +4,21 @@ import dude.TaskList; import dude.Ui; +/** + * Represents a command that exits the programme. + */ public class ExitCommand extends Command { public ExitCommand() { super.isExit = true; } + /** + * Executes the command to exit the programme. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { ui.showFarewell(); diff --git a/src/main/java/dude/command/ListCommand.java b/src/main/java/dude/command/ListCommand.java index a3a449f9b7..60d1858542 100644 --- a/src/main/java/dude/command/ListCommand.java +++ b/src/main/java/dude/command/ListCommand.java @@ -4,7 +4,18 @@ import dude.TaskList; import dude.Ui; +/** + * Represents a command that lists all the tasks. + */ public class ListCommand extends Command { + + /** + * Executes the command to list all tasks. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { System.out.println("Listing..."); diff --git a/src/main/java/dude/command/MarkCommand.java b/src/main/java/dude/command/MarkCommand.java index 4170d47673..ff73d6a20a 100644 --- a/src/main/java/dude/command/MarkCommand.java +++ b/src/main/java/dude/command/MarkCommand.java @@ -7,11 +7,23 @@ import java.io.IOException; +/** + * Represents a command that marks a task as done. + */ public class MarkCommand extends Command { private int taskIndex; + public MarkCommand(int taskIndex) { this.taskIndex = taskIndex; } + + /** + * Executes the command to mark a task as done. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/UnknownCommand.java b/src/main/java/dude/command/UnknownCommand.java index f9d8b180c8..b3a6b12606 100644 --- a/src/main/java/dude/command/UnknownCommand.java +++ b/src/main/java/dude/command/UnknownCommand.java @@ -4,7 +4,18 @@ import dude.TaskList; import dude.Ui; +/** + * Represents a command that is not defined in Dude. + */ public class UnknownCommand extends Command { + + /** + * Executes the command to tell users the command is unknown. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ @Override public void execute(TaskList taskList, Ui ui, Storage storage) { ui.showUnknownCommand(); diff --git a/src/main/java/dude/command/UnmarkCommand.java b/src/main/java/dude/command/UnmarkCommand.java index 524c6efc01..2e34610fff 100644 --- a/src/main/java/dude/command/UnmarkCommand.java +++ b/src/main/java/dude/command/UnmarkCommand.java @@ -7,11 +7,23 @@ import java.io.IOException; +/** + * Represents a command that marks a task as undone. + */ public class UnmarkCommand extends Command { private int taskIndex; + public UnmarkCommand(int taskIndex) { this.taskIndex = taskIndex; } + + /** + * Executes the command to mark a task as undone. + * + * @param taskList List of tasks. + * @param storage Storage containing saved tasks, and saves and loads tasks. + * @param ui User interface of Dude. + */ public void execute(TaskList taskList, Ui ui, Storage storage) { try { System.out.println("Executing Unmark Command");; diff --git a/src/main/java/dude/task/Deadline.java b/src/main/java/dude/task/Deadline.java index 80a0c6cb86..d5ccd47aeb 100644 --- a/src/main/java/dude/task/Deadline.java +++ b/src/main/java/dude/task/Deadline.java @@ -4,16 +4,30 @@ import java.time.format.DateTimeFormatter; import java.util.Locale; +/** + * Represents a deadline that extends a task. + * A Deadline object has a String description, + * and LocalDateTime due time. + */ public class Deadline extends Task { LocalDateTime by; + + /** + * Constructs a new Deadline object with the specified description and due time. + * + * @param description A short description of the event. + * @param by The time when the task is due. + */ public Deadline(String description, LocalDateTime by) { super(description); this.by = by; } + @Override public String getType() { return "deadline"; } + @Override public String saveTask() { String data = "D | "; @@ -26,6 +40,12 @@ public String saveTask() { data = data + " | " + this.by + "\n"; // ISO-8601 e.g. 2023-09-06T14:30 return data; } + + /** + * Returns a formatted string representation of the deadline. + * + * @return A formatted string describing the deadline. + */ @Override public String toString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); diff --git a/src/main/java/dude/task/Event.java b/src/main/java/dude/task/Event.java index 9619c6f97b..f164fd220e 100644 --- a/src/main/java/dude/task/Event.java +++ b/src/main/java/dude/task/Event.java @@ -4,18 +4,33 @@ import java.time.format.DateTimeFormatter; import java.util.Locale; +/** + * Represents a scheduled event that extends a task. + * An Event object has a String description, + * LocalDateTime start time, and a LocalDateTime end time. + */ public class Event extends Task { private LocalDateTime from; private LocalDateTime to; + + /** + * Constructs a new Event object with the specified description and event date and time. + * + * @param description A short description of the event. + * @param from The time when the event is scheduled to start. + * @param to The time when the event is scheduled to end. + */ public Event(String description, LocalDateTime from, LocalDateTime to) { super(description); this.from = from; this.to = to; } + @Override public String getType() { return "event"; } + @Override public String saveTask() { String data = "E | "; @@ -28,6 +43,12 @@ public String saveTask() { data = data + " | " + this.from + " | " + this.to + "\n"; return data; } + + /** + * Returns a formatted string representation of the event. + * + * @return A formatted string describing the event. + */ @Override public String toString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); diff --git a/src/main/java/dude/task/Task.java b/src/main/java/dude/task/Task.java index 9e3e7a116d..9906695896 100644 --- a/src/main/java/dude/task/Task.java +++ b/src/main/java/dude/task/Task.java @@ -1,9 +1,18 @@ package dude.task; +/** + * Represents a task. + * A Task object has a String description. + */ public class Task { private String description; private boolean done; + /** + * Constructs a new Task object with the specified description. + * + * @param description A short description of the event. + */ Task(String description) { this.description = description; this.done = false; @@ -24,8 +33,16 @@ public void setDone(boolean done) { public String getType() { return "task"; } - public String saveTask () {return this.description; } + public String saveTask () { + return this.description; + } + + /** + * Returns a formatted string representation of the task. + * + * @return A formatted string describing the task. + */ @Override public String toString() { String doneStatus = "[ ]"; diff --git a/src/main/java/dude/task/ToDo.java b/src/main/java/dude/task/ToDo.java index dc49c8bba4..da95318b4d 100644 --- a/src/main/java/dude/task/ToDo.java +++ b/src/main/java/dude/task/ToDo.java @@ -1,13 +1,25 @@ package dude.task; +/** + * Represents a todo that extends a task. + * A ToDo object has a String description. + */ public class ToDo extends Task { + + /** + * Constructs a new ToDo object with the specified description. + * + * @param description A short description of the event. + */ public ToDo(String description) { super(description); } + @Override public String getType() { return "todo"; } + @Override public String saveTask() { String data = "T | "; @@ -19,6 +31,12 @@ public String saveTask() { data = data + this.getDescription() + "\n"; return data; } + + /** + * Returns a formatted string representation of the todo. + * + * @return A formatted string describing the todo. + */ @Override public String toString() { return "[T]" + super.toString(); From 9dcbe6971102a209e798fda7f340d3c41124ab62 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Wed, 13 Sep 2023 22:24:41 +0800 Subject: [PATCH 26/57] Modify code to apply coding standards --- src/main/java/dude/Dude.java | 2 ++ src/main/java/dude/Parser.java | 3 +-- src/main/java/dude/Storage.java | 5 ++++- src/main/java/dude/TaskList.java | 2 +- src/main/java/dude/Ui.java | 12 +++++++++++- src/main/java/dude/command/AddDeadlineCommand.java | 2 ++ src/main/java/dude/command/AddEventCommand.java | 2 ++ src/main/java/dude/command/AddToDoCommand.java | 2 ++ src/main/java/dude/command/DeleteCommand.java | 2 ++ src/main/java/dude/command/MarkCommand.java | 2 ++ src/main/java/dude/task/Deadline.java | 4 ++++ src/main/java/dude/task/Event.java | 3 +++ src/main/java/dude/task/Task.java | 8 ++++---- src/main/java/dude/task/ToDo.java | 3 +++ 14 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index 7734393a06..8e7ece6b2b 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -15,6 +15,7 @@ public class Dude { public Dude(String filePath) { this.ui = new Ui(); this.storage = new Storage(filePath); + try { taskList = new TaskList(storage.loadTasksFromDisk()); } catch (FileNotFoundException e) { // DudeException @@ -22,6 +23,7 @@ public Dude(String filePath) { taskList = new TaskList(); } } + public void run() { ui.showWelcome(); boolean isExit = false; diff --git a/src/main/java/dude/Parser.java b/src/main/java/dude/Parser.java index 7f14f44900..ed0854c1f6 100644 --- a/src/main/java/dude/Parser.java +++ b/src/main/java/dude/Parser.java @@ -7,8 +7,8 @@ // deals with making sense of the user command public class Parser { - private static DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + public static Command parse(String fullCommand) { String[] commandDetails = fullCommand.split(" ", 2); String commandType = commandDetails[0]; @@ -52,5 +52,4 @@ public static Command parse(String fullCommand) { } return c; } - } diff --git a/src/main/java/dude/Storage.java b/src/main/java/dude/Storage.java index 62beced335..f28aa6bace 100644 --- a/src/main/java/dude/Storage.java +++ b/src/main/java/dude/Storage.java @@ -22,6 +22,7 @@ public Storage(String filepath) { public void saveTasksToDisk(TaskList taskList) throws IOException { File file = new File(this.filepath); + if (!file.exists()) { try { if (file.createNewFile()) { @@ -35,6 +36,7 @@ public void saveTasksToDisk(TaskList taskList) throws IOException { } String data = ""; + for (int i = 0; i < taskList.getSize(); i++) { Task task = taskList.getTask(i); data += task.saveTask(); @@ -51,8 +53,8 @@ public void saveTasksToDisk(TaskList taskList) throws IOException { public ArrayList loadTasksFromDisk() throws FileNotFoundException { ArrayList taskList = new ArrayList(); - File file = new File(this.filepath); + if (file.exists()) { try { Scanner sc = new Scanner(file); @@ -93,6 +95,7 @@ public ArrayList loadTasksFromDisk() throws FileNotFoundException { System.out.println(e.getMessage()); } } + System.out.printf("You have %d saved tasks.\n", taskList.size()); // TaskList tasks = new TaskList(taskList); return taskList; diff --git a/src/main/java/dude/TaskList.java b/src/main/java/dude/TaskList.java index b8ed277548..5cccd4dc7d 100644 --- a/src/main/java/dude/TaskList.java +++ b/src/main/java/dude/TaskList.java @@ -33,6 +33,7 @@ public Task markTask(int index) { task.setDone(true); return task; } + public Task unmarkTask(int index) { Task task = taskList.get(index); task.setDone(false); @@ -40,7 +41,6 @@ public Task unmarkTask(int index) { } // add - public void addTask(Task task) { taskList.add(task); } diff --git a/src/main/java/dude/Ui.java b/src/main/java/dude/Ui.java index 4149812abd..51a114d31b 100644 --- a/src/main/java/dude/Ui.java +++ b/src/main/java/dude/Ui.java @@ -5,25 +5,29 @@ import java.util.Scanner; public class Ui { - Scanner sc; + private Scanner sc; public Ui() { this.sc = new Scanner(System.in); } public String readCommand() { return this.sc.nextLine(); } + public void showWelcome() { String greeting = "Hello, I'm Dude!\n" + "What can I do for you?"; System.out.println(greeting); } + public void showFarewell() { String greeting = "Bye. Hope to see you again soon!"; System.out.println(greeting); } + public void showLine() { System.out.println("__________________________________________________"); } + public void showTaskList(TaskList taskList) { int nTasks = taskList.getSize(); if (nTasks == 0) { @@ -35,30 +39,36 @@ public void showTaskList(TaskList taskList) { } } } + public void showMarkedTask(Task task) { System.out.println("Nice! I've marked this task as done:"); System.out.printf(task.toString()); System.out.println(); // task is already done? } + public void showUnmarkedTask(Task task) { System.out.println("Nice! I've marked this task as as not done yet:"); System.out.printf(task.toString()); System.out.println(); // task is already undone? } + public void showDeletedTask(Task task, int nTasks) { System.out.println("Noted. I've removed this task:"); System.out.println(task.toString()); System.out.printf("Now you have %d tasks in the list.\n", nTasks); } + public void showAddedTask(Task task, int nTasks) { System.out.printf("Got it. I've added this task:\n%s\n", task.toString()); System.out.printf("Now you have %d tasks in the list. \n", nTasks); } + public void showUnknownCommand() { System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); } + public void showError(String message) { } diff --git a/src/main/java/dude/command/AddDeadlineCommand.java b/src/main/java/dude/command/AddDeadlineCommand.java index 30de7dabfc..d82830cf31 100644 --- a/src/main/java/dude/command/AddDeadlineCommand.java +++ b/src/main/java/dude/command/AddDeadlineCommand.java @@ -11,10 +11,12 @@ public class AddDeadlineCommand extends Command { private String taskDescription; private LocalDateTime byDateTime; + public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { this.taskDescription = taskDescription; this.byDateTime = byDateTime; } + @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/AddEventCommand.java b/src/main/java/dude/command/AddEventCommand.java index 0d32ab571f..9fdbbe9003 100644 --- a/src/main/java/dude/command/AddEventCommand.java +++ b/src/main/java/dude/command/AddEventCommand.java @@ -12,11 +12,13 @@ public class AddEventCommand extends Command { private String taskDescription; private LocalDateTime fromDateTime; private LocalDateTime toDateTime; + public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, LocalDateTime toDateTime) { this.taskDescription = taskDescription; this.fromDateTime = fromDateTime; this.toDateTime = toDateTime; } + @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/AddToDoCommand.java b/src/main/java/dude/command/AddToDoCommand.java index eab8c57223..de78711291 100644 --- a/src/main/java/dude/command/AddToDoCommand.java +++ b/src/main/java/dude/command/AddToDoCommand.java @@ -9,9 +9,11 @@ public class AddToDoCommand extends Command { private String taskDescription; + public AddToDoCommand(String taskDescription) { this.taskDescription = taskDescription; } + @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/DeleteCommand.java b/src/main/java/dude/command/DeleteCommand.java index caabaf2af4..26821f6d7c 100644 --- a/src/main/java/dude/command/DeleteCommand.java +++ b/src/main/java/dude/command/DeleteCommand.java @@ -9,9 +9,11 @@ public class DeleteCommand extends Command { private int taskIndex; + public DeleteCommand(int taskIndex) { this.taskIndex = taskIndex; } + @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/command/MarkCommand.java b/src/main/java/dude/command/MarkCommand.java index 4170d47673..a19eb439b6 100644 --- a/src/main/java/dude/command/MarkCommand.java +++ b/src/main/java/dude/command/MarkCommand.java @@ -9,9 +9,11 @@ public class MarkCommand extends Command { private int taskIndex; + public MarkCommand(int taskIndex) { this.taskIndex = taskIndex; } + @Override public void execute(TaskList taskList, Ui ui, Storage storage) { try { diff --git a/src/main/java/dude/task/Deadline.java b/src/main/java/dude/task/Deadline.java index 80a0c6cb86..0baf8fa4d2 100644 --- a/src/main/java/dude/task/Deadline.java +++ b/src/main/java/dude/task/Deadline.java @@ -6,14 +6,17 @@ public class Deadline extends Task { LocalDateTime by; + public Deadline(String description, LocalDateTime by) { super(description); this.by = by; } + @Override public String getType() { return "deadline"; } + @Override public String saveTask() { String data = "D | "; @@ -26,6 +29,7 @@ public String saveTask() { data = data + " | " + this.by + "\n"; // ISO-8601 e.g. 2023-09-06T14:30 return data; } + @Override public String toString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); diff --git a/src/main/java/dude/task/Event.java b/src/main/java/dude/task/Event.java index 9619c6f97b..57849cd4fd 100644 --- a/src/main/java/dude/task/Event.java +++ b/src/main/java/dude/task/Event.java @@ -12,10 +12,12 @@ public Event(String description, LocalDateTime from, LocalDateTime to) { this.from = from; this.to = to; } + @Override public String getType() { return "event"; } + @Override public String saveTask() { String data = "E | "; @@ -28,6 +30,7 @@ public String saveTask() { data = data + " | " + this.from + " | " + this.to + "\n"; return data; } + @Override public String toString() { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MMM yyyy hh:mm a", Locale.ENGLISH); diff --git a/src/main/java/dude/task/Task.java b/src/main/java/dude/task/Task.java index 9e3e7a116d..6d35a5ed3b 100644 --- a/src/main/java/dude/task/Task.java +++ b/src/main/java/dude/task/Task.java @@ -2,15 +2,15 @@ public class Task { private String description; - private boolean done; + private boolean isDone; Task(String description) { this.description = description; - this.done = false; + this.isDone = false; } public boolean isDone() { - return this.done; + return this.isDone; } public String getDescription() { @@ -18,7 +18,7 @@ public String getDescription() { } public void setDone(boolean done) { - this.done = done; + this.isDone = done; } public String getType() { diff --git a/src/main/java/dude/task/ToDo.java b/src/main/java/dude/task/ToDo.java index dc49c8bba4..1dce18282d 100644 --- a/src/main/java/dude/task/ToDo.java +++ b/src/main/java/dude/task/ToDo.java @@ -4,13 +4,16 @@ public class ToDo extends Task { public ToDo(String description) { super(description); } + @Override public String getType() { return "todo"; } + @Override public String saveTask() { String data = "T | "; + if (this.isDone()) { data += "1 | "; } else { From c6507ac5838da1c5e2589f592adcdfcb4d70fc95 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Thu, 14 Sep 2023 00:56:37 +0800 Subject: [PATCH 27/57] Fix coding style violations --- build.gradle | 5 + config/checkstyle/checkstyle.xml | 434 ++++++++++++++++++ config/checkstyle/suppressions.xml | 10 + src/main/java/dude/Dude.java | 25 +- src/main/java/dude/DudeException.java | 4 + src/main/java/dude/Parser.java | 11 +- src/main/java/dude/Storage.java | 10 +- src/main/java/dude/TaskList.java | 9 +- src/main/java/dude/Ui.java | 37 +- .../java/dude/command/AddDeadlineCommand.java | 11 +- .../java/dude/command/AddEventCommand.java | 12 +- .../java/dude/command/AddToDoCommand.java | 4 +- src/main/java/dude/command/Command.java | 3 + src/main/java/dude/command/DeleteCommand.java | 4 +- src/main/java/dude/command/FindCommand.java | 10 +- src/main/java/dude/command/MarkCommand.java | 4 +- src/main/java/dude/command/UnmarkCommand.java | 4 +- src/main/java/dude/task/Deadline.java | 2 +- src/main/java/dude/task/Task.java | 8 +- src/test/java/dude/TaskListTest.java | 5 +- src/test/java/dude/task/DeadlineTest.java | 8 +- src/test/java/dude/task/EventTest.java | 13 +- src/test/java/dude/task/ToDoTest.java | 5 +- 23 files changed, 579 insertions(+), 59 deletions(-) create mode 100644 config/checkstyle/checkstyle.xml create mode 100644 config/checkstyle/suppressions.xml diff --git a/build.gradle b/build.gradle index 35984658d8..f15561e8da 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,14 @@ plugins { + id 'checkstyle' id 'java' id 'application' id 'com.github.johnrengelman.shadow' version '7.1.2' } +checkstyle { + toolVersion = '10.2' +} + repositories { mavenCentral() } diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml new file mode 100644 index 0000000000..eb761a9b9a --- /dev/null +++ b/config/checkstyle/checkstyle.xml @@ -0,0 +1,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/config/checkstyle/suppressions.xml b/config/checkstyle/suppressions.xml new file mode 100644 index 0000000000..39efb6e4ac --- /dev/null +++ b/config/checkstyle/suppressions.xml @@ -0,0 +1,10 @@ + + + + + + + + diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index 8e7ece6b2b..7515c1f939 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -1,16 +1,23 @@ package dude; +import java.io.FileNotFoundException; + import dude.command.Command; -import java.io.FileNotFoundException; -import java.io.IOException; +/** + * Dude is a programme that allows users to manage their tasks. + */ public class Dude { private TaskList taskList; private Storage storage; private Ui ui; - static int nTasks = 0; + + /** + * Constructor for Dude that takes in a file path to storage file. + * @param filePath Path to storage file. + */ public Dude(String filePath) { this.ui = new Ui(); @@ -24,6 +31,9 @@ public Dude(String filePath) { } } + /** + * Method that runs the Dude programme. + */ public void run() { ui.showWelcome(); boolean isExit = false; @@ -41,7 +51,12 @@ public void run() { } } - public static void main(String[] args) throws IOException { + /** + * Main method for Dude. Start the programme here. + * @param args + */ + + public static void main(String[] args) { new Dude("data/dude.txt").run(); } -} \ No newline at end of file +} diff --git a/src/main/java/dude/DudeException.java b/src/main/java/dude/DudeException.java index 64e0f0d108..54419db76f 100644 --- a/src/main/java/dude/DudeException.java +++ b/src/main/java/dude/DudeException.java @@ -1,4 +1,8 @@ package dude; + +/** + * Class of Exceptions that might be found in the Dude programme. + */ public class DudeException extends Exception { DudeException(String message) { super(message); diff --git a/src/main/java/dude/Parser.java b/src/main/java/dude/Parser.java index aa827244bb..9881490542 100644 --- a/src/main/java/dude/Parser.java +++ b/src/main/java/dude/Parser.java @@ -1,24 +1,25 @@ package dude; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + import dude.command.AddDeadlineCommand; import dude.command.AddEventCommand; import dude.command.AddToDoCommand; import dude.command.Command; import dude.command.DeleteCommand; import dude.command.ExitCommand; +import dude.command.FindCommand; import dude.command.ListCommand; import dude.command.MarkCommand; import dude.command.UnknownCommand; import dude.command.UnmarkCommand; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - /** * Represents a parser that parses user input and deals with making sense of the user command. */ public class Parser { - private static DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); + private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm"); /** * Parses the user's input and returns the corresponding command. @@ -31,7 +32,7 @@ public static Command parse(String fullCommand) { String commandType = commandDetails[0]; Command c; - if (commandType.equals("bye")){ + if (commandType.equals("bye")) { c = new ExitCommand(); } else if (commandType.equals("list")) { c = new ListCommand(); diff --git a/src/main/java/dude/Storage.java b/src/main/java/dude/Storage.java index 78ce53e7c8..0e366c2980 100644 --- a/src/main/java/dude/Storage.java +++ b/src/main/java/dude/Storage.java @@ -1,10 +1,5 @@ package dude; -import dude.task.Deadline; -import dude.task.Event; -import dude.task.Task; -import dude.task.ToDo; - import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; @@ -13,6 +8,11 @@ import java.util.ArrayList; import java.util.Scanner; +import dude.task.Deadline; +import dude.task.Event; +import dude.task.Task; +import dude.task.ToDo; + /** * Represents the Storage system of Dude and deals with loading tasks from * the file and saving tasks in the file. diff --git a/src/main/java/dude/TaskList.java b/src/main/java/dude/TaskList.java index 6343746a67..47cdec1617 100644 --- a/src/main/java/dude/TaskList.java +++ b/src/main/java/dude/TaskList.java @@ -1,9 +1,9 @@ package dude; -import dude.task.Task; - import java.util.ArrayList; +import dude.task.Task; + /** * Represents a list of tasks. */ @@ -73,6 +73,11 @@ public Task deleteTask(int index) { return removedTask; } + /** + * Finds tasks in list that contain specified keyword(s). + * + * @param taskKeywords Keywords used to search for tasks. + */ public TaskList findTasks(String taskKeywords) { TaskList searchResults = new TaskList(); for (int i = 0; i < this.getSize(); i++) { diff --git a/src/main/java/dude/Ui.java b/src/main/java/dude/Ui.java index 3f3cfd13a5..635f9d4728 100644 --- a/src/main/java/dude/Ui.java +++ b/src/main/java/dude/Ui.java @@ -1,9 +1,9 @@ package dude; -import dude.task.Task; - import java.util.Scanner; +import dude.task.Task; + /** * Represents the UI of Dude and deals with interactions with the user. */ @@ -16,21 +16,33 @@ public String readCommand() { return this.sc.nextLine(); } + /** + * Prints a welcome message for users. + */ public void showWelcome() { - String greeting = "Hello, I'm Dude!\n" + - "What can I do for you?"; + String greeting = "Hello, I'm Dude!\n" + + "What can I do for you?"; System.out.println(greeting); } + /** + * Prints a farewell message for users. + */ public void showFarewell() { String greeting = "Bye. Hope to see you again soon!"; System.out.println(greeting); } + /** + * Prints a line. + */ public void showLine() { System.out.println("__________________________________________________"); } + /** + * Prints the list of tasks.. + */ public void showTaskList(TaskList taskList) { int nTasks = taskList.getSize(); if (nTasks == 0) { @@ -38,11 +50,14 @@ public void showTaskList(TaskList taskList) { } else { for (int i = 0; i < nTasks; i++) { Task task = taskList.getTask(i); - System.out.printf("%d. %s\n", i+1, task.toString()); + System.out.printf("%d. %s\n", i + 1, task.toString()); } } } + /** + * Prints a statement to show the task that has been successfully marked. + */ public void showMarkedTask(Task task) { System.out.println("Nice! I've marked this task as done:"); System.out.printf(task.toString()); @@ -50,6 +65,9 @@ public void showMarkedTask(Task task) { // task is already done? } + /** + * Prints a statement to show the task that has been successfully unmarked. + */ public void showUnmarkedTask(Task task) { System.out.println("Nice! I've marked this task as as not done yet:"); System.out.printf(task.toString()); @@ -57,17 +75,26 @@ public void showUnmarkedTask(Task task) { // task is already undone? } + /** + * Prints a statement to show the task that has been successfully deleted. + */ public void showDeletedTask(Task task, int nTasks) { System.out.println("Noted. I've removed this task:"); System.out.println(task.toString()); System.out.printf("Now you have %d tasks in the list.\n", nTasks); } + /** + * Prints a statement to show the task that has been successfully added. + */ public void showAddedTask(Task task, int nTasks) { System.out.printf("Got it. I've added this task:\n%s\n", task.toString()); System.out.printf("Now you have %d tasks in the list. \n", nTasks); } + /** + * Prints a statement to show the command is unknown. + */ public void showUnknownCommand() { System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); } diff --git a/src/main/java/dude/command/AddDeadlineCommand.java b/src/main/java/dude/command/AddDeadlineCommand.java index 51298324a6..69a9ee164a 100644 --- a/src/main/java/dude/command/AddDeadlineCommand.java +++ b/src/main/java/dude/command/AddDeadlineCommand.java @@ -1,13 +1,13 @@ package dude.command; +import java.io.IOException; +import java.time.LocalDateTime; + import dude.Storage; import dude.TaskList; import dude.Ui; import dude.task.Deadline; -import java.io.IOException; -import java.time.LocalDateTime; - /** * Represents a command that adds a Deadline task. */ @@ -15,6 +15,11 @@ public class AddDeadlineCommand extends Command { private String taskDescription; private LocalDateTime byDateTime; + /** + * Creates an Add Deadline Command to add a deadline to the list. + * @param taskDescription Short description of deadline to be added. + * @param byDateTime Time that task needs to be completed. + */ public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { this.taskDescription = taskDescription; this.byDateTime = byDateTime; diff --git a/src/main/java/dude/command/AddEventCommand.java b/src/main/java/dude/command/AddEventCommand.java index 5ac3fe2269..2007f86d24 100644 --- a/src/main/java/dude/command/AddEventCommand.java +++ b/src/main/java/dude/command/AddEventCommand.java @@ -1,13 +1,13 @@ package dude.command; +import java.io.IOException; +import java.time.LocalDateTime; + import dude.Storage; import dude.TaskList; import dude.Ui; import dude.task.Event; -import java.io.IOException; -import java.time.LocalDateTime; - /** * Represents a command that adds an Event task. */ @@ -16,6 +16,12 @@ public class AddEventCommand extends Command { private LocalDateTime fromDateTime; private LocalDateTime toDateTime; + /** + * Creates an Add Event Command to add an event to the list. + * @param taskDescription Short description of event to be added. + * @param fromDateTime Starting time of event. + * @param toDateTime Ending time of event. + */ public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, LocalDateTime toDateTime) { this.taskDescription = taskDescription; this.fromDateTime = fromDateTime; diff --git a/src/main/java/dude/command/AddToDoCommand.java b/src/main/java/dude/command/AddToDoCommand.java index aeaa4507e0..09548e1f55 100644 --- a/src/main/java/dude/command/AddToDoCommand.java +++ b/src/main/java/dude/command/AddToDoCommand.java @@ -1,12 +1,12 @@ package dude.command; +import java.io.IOException; + import dude.Storage; import dude.TaskList; import dude.Ui; import dude.task.ToDo; -import java.io.IOException; - /** * Represents a command that adds a ToDo task. */ diff --git a/src/main/java/dude/command/Command.java b/src/main/java/dude/command/Command.java index 793ddc683a..3db1daa8ec 100644 --- a/src/main/java/dude/command/Command.java +++ b/src/main/java/dude/command/Command.java @@ -4,6 +4,9 @@ import dude.TaskList; import dude.Ui; +/** + * Abstract parents class of Commands that can be created by users. + */ public abstract class Command { protected boolean isExit; diff --git a/src/main/java/dude/command/DeleteCommand.java b/src/main/java/dude/command/DeleteCommand.java index 59f95d85eb..e2fd623faf 100644 --- a/src/main/java/dude/command/DeleteCommand.java +++ b/src/main/java/dude/command/DeleteCommand.java @@ -1,12 +1,12 @@ package dude.command; +import java.io.IOException; + import dude.Storage; import dude.TaskList; import dude.Ui; import dude.task.Task; -import java.io.IOException; - /** * Represents a command that deletes task. */ diff --git a/src/main/java/dude/command/FindCommand.java b/src/main/java/dude/command/FindCommand.java index ad6a5057cb..b84bd90df3 100644 --- a/src/main/java/dude/command/FindCommand.java +++ b/src/main/java/dude/command/FindCommand.java @@ -3,14 +3,18 @@ import dude.Storage; import dude.TaskList; import dude.Ui; -import dude.task.ToDo; - -import java.io.IOException; +/** + * Represents a command that finds tasks by keywords. + */ public class FindCommand extends Command { private String searchKeywords; + /** + * Creates a Find Command that finds tasks by specified keywords. + * @param searchKeywords Keywords used in search for tasks. + */ public FindCommand(String searchKeywords) { this.searchKeywords = searchKeywords; } diff --git a/src/main/java/dude/command/MarkCommand.java b/src/main/java/dude/command/MarkCommand.java index ff73d6a20a..c530ab838d 100644 --- a/src/main/java/dude/command/MarkCommand.java +++ b/src/main/java/dude/command/MarkCommand.java @@ -1,12 +1,12 @@ package dude.command; +import java.io.IOException; + import dude.Storage; import dude.TaskList; import dude.Ui; import dude.task.Task; -import java.io.IOException; - /** * Represents a command that marks a task as done. */ diff --git a/src/main/java/dude/command/UnmarkCommand.java b/src/main/java/dude/command/UnmarkCommand.java index 2e34610fff..601ee8e1e9 100644 --- a/src/main/java/dude/command/UnmarkCommand.java +++ b/src/main/java/dude/command/UnmarkCommand.java @@ -1,12 +1,12 @@ package dude.command; +import java.io.IOException; + import dude.Storage; import dude.TaskList; import dude.Ui; import dude.task.Task; -import java.io.IOException; - /** * Represents a command that marks a task as undone. */ diff --git a/src/main/java/dude/task/Deadline.java b/src/main/java/dude/task/Deadline.java index d5ccd47aeb..c48eea5dd0 100644 --- a/src/main/java/dude/task/Deadline.java +++ b/src/main/java/dude/task/Deadline.java @@ -10,7 +10,7 @@ * and LocalDateTime due time. */ public class Deadline extends Task { - LocalDateTime by; + private LocalDateTime by; /** * Constructs a new Deadline object with the specified description and due time. diff --git a/src/main/java/dude/task/Task.java b/src/main/java/dude/task/Task.java index f619c36073..d023c98c9d 100644 --- a/src/main/java/dude/task/Task.java +++ b/src/main/java/dude/task/Task.java @@ -34,14 +34,14 @@ public String getType() { return "task"; } - public String saveTask () { + public String saveTask() { return this.description; } - - public boolean containKeywords(String keywords){ + + public boolean containKeywords(String keywords) { return this.description.contains(keywords); } - + /** * Returns a formatted string representation of the task. * diff --git a/src/test/java/dude/TaskListTest.java b/src/test/java/dude/TaskListTest.java index c3cdb0d8c6..67a7a5fe2c 100644 --- a/src/test/java/dude/TaskListTest.java +++ b/src/test/java/dude/TaskListTest.java @@ -1,7 +1,4 @@ -package dude; //same package as the class being tested - -import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; +package dude; public class TaskListTest { diff --git a/src/test/java/dude/task/DeadlineTest.java b/src/test/java/dude/task/DeadlineTest.java index 32162bb46e..e99dc188bd 100644 --- a/src/test/java/dude/task/DeadlineTest.java +++ b/src/test/java/dude/task/DeadlineTest.java @@ -1,14 +1,16 @@ package dude.task; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.time.LocalDateTime; + import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; public class DeadlineTest { @Test - public void createDeadlineTest(){ + public void createDeadlineTest() { String description = "Assignment"; - LocalDateTime by = LocalDateTime.of(2023, 9, 11, 23, 59); + LocalDateTime by = LocalDateTime.of(2023, 9, 11, 23, 59); Deadline deadline = new Deadline(description, by); String expected = "[D][ ] Assignment (by: 11 Sep 2023 11:59 PM)"; assertEquals(expected, deadline.toString()); diff --git a/src/test/java/dude/task/EventTest.java b/src/test/java/dude/task/EventTest.java index deb5ff242d..99796ba950 100644 --- a/src/test/java/dude/task/EventTest.java +++ b/src/test/java/dude/task/EventTest.java @@ -1,18 +1,19 @@ package dude.task; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.time.LocalDateTime; + import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertEquals; public class EventTest { @Test - public void createDeadlineTest(){ + public void createDeadlineTest() { String description = "Tutorial"; - LocalDateTime from = LocalDateTime.of(2023, 9, 11, 14, 0); - LocalDateTime to = LocalDateTime.of(2023, 9, 11, 15, 0); + LocalDateTime from = LocalDateTime.of(2023, 9, 11, 14, 0); + LocalDateTime to = LocalDateTime.of(2023, 9, 11, 15, 0); Event event = new Event(description, from, to); String expected = "[E][ ] Tutorial (from: 11 Sep 2023 02:00 PM to: 11 Sep 2023 03:00 PM)"; assertEquals(expected, event.toString()); } - -} \ No newline at end of file +} diff --git a/src/test/java/dude/task/ToDoTest.java b/src/test/java/dude/task/ToDoTest.java index 56f27468ce..2b714f20cc 100644 --- a/src/test/java/dude/task/ToDoTest.java +++ b/src/test/java/dude/task/ToDoTest.java @@ -1,11 +1,12 @@ package dude.task; -import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + public class ToDoTest { @Test - public void createDeadlineTest(){ + public void createDeadlineTest() { String description = "Homework"; ToDo todo = new ToDo(description); String expected = "[T][ ] Homework"; From 6fbf6bde87b2ade2a76f0d6b9e28cc8ffcb52fa5 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Thu, 14 Sep 2023 11:19:48 +0800 Subject: [PATCH 28/57] Create GUI for Dude --- build.gradle | 15 +++++++ src/main/java/dude/Dude.java | 71 +++++++++++++++++++++++++++++++- src/main/java/dude/Launcher.java | 12 ++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 src/main/java/dude/Launcher.java diff --git a/build.gradle b/build.gradle index f15561e8da..6e6061b4d8 100644 --- a/build.gradle +++ b/build.gradle @@ -16,6 +16,21 @@ repositories { dependencies { testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' + + String javaFxVersion = '17.0.7' + + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-base', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-controls', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-fxml', version: javaFxVersion, classifier: 'linux' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'win' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'mac' + implementation group: 'org.openjfx', name: 'javafx-graphics', version: javaFxVersion, classifier: 'linux' } test { diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index 7515c1f939..c579ef74cb 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -2,23 +2,39 @@ import java.io.FileNotFoundException; +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.TextField; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.Label; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; + import dude.command.Command; /** * Dude is a programme that allows users to manage their tasks. */ -public class Dude { +public class Dude extends Application { + private ScrollPane scrollPane; + private VBox dialogContainer; + private TextField userInput; + private Button sendButton; private TaskList taskList; private Storage storage; private Ui ui; + public Dude() { } + /** * Constructor for Dude that takes in a file path to storage file. * @param filePath Path to storage file. */ - public Dude(String filePath) { this.ui = new Ui(); this.storage = new Storage(filePath); @@ -31,6 +47,57 @@ public Dude(String filePath) { } } + @Override + public void start(Stage stage) { + //Step 1: Setting up required components + + //Container for the content of the chat to scroll + scrollPane = new ScrollPane(); + dialogContainer = new VBox(); + scrollPane.setContent(dialogContainer); + + userInput = new TextField(); + sendButton = new Button("Send"); + + AnchorPane mainLayout = new AnchorPane(); + mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); + + Scene scene = new Scene(mainLayout); // Setting the scene to be mainLayout + + stage.setScene(scene); // Setting the stage to show our screen + stage.show(); // Render the stage. + + //Step 2: Formatting the window to look as expected + stage.setTitle("Dude"); + stage.setResizable(false); + stage.setMinHeight(600.0); + stage.setMinWidth(400.0); + + mainLayout.setPrefSize(400.0, 600.0); + + scrollPane.setPrefSize(385.0, 535.0); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); + + scrollPane.setVvalue(1.0); + scrollPane.setFitToWidth(true); + + dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); + + userInput.setPrefWidth(342.0); + + sendButton.setPrefWidth(55.0); + + AnchorPane.setTopAnchor(scrollPane, 1.0); + + AnchorPane.setBottomAnchor(sendButton, 1.0); + AnchorPane.setRightAnchor(sendButton, 1.0); + + AnchorPane.setLeftAnchor(userInput, 1.0); + AnchorPane.setBottomAnchor(userInput, 1.0); + + } + /** * Method that runs the Dude programme. */ diff --git a/src/main/java/dude/Launcher.java b/src/main/java/dude/Launcher.java new file mode 100644 index 0000000000..4960f600e2 --- /dev/null +++ b/src/main/java/dude/Launcher.java @@ -0,0 +1,12 @@ +package dude; + +import javafx.application.Application; + +/** + * A launcher class to workaround classpath issues. + */ +public class Launcher { + public static void main(String[] args) { + Application.launch(Dude.class, args); + } +} From 1f859050ef2b91abd84f94f74043547be7128c88 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Thu, 14 Sep 2023 12:11:42 +0800 Subject: [PATCH 29/57] Add functionality to GUI for dude --- src/main/java/dude/DialogBox.java | 47 +++++++++++ src/main/java/dude/Dude.java | 69 +--------------- src/main/java/dude/Launcher.java | 2 +- src/main/java/dude/Main.java | 121 +++++++++++++++++++++++++++++ src/main/resources/images/Dude.png | Bin 0 -> 58618 bytes src/main/resources/images/User.png | Bin 0 -> 108991 bytes 6 files changed, 170 insertions(+), 69 deletions(-) create mode 100644 src/main/java/dude/DialogBox.java create mode 100644 src/main/java/dude/Main.java create mode 100644 src/main/resources/images/Dude.png create mode 100644 src/main/resources/images/User.png diff --git a/src/main/java/dude/DialogBox.java b/src/main/java/dude/DialogBox.java new file mode 100644 index 0000000000..c0e450c52f --- /dev/null +++ b/src/main/java/dude/DialogBox.java @@ -0,0 +1,47 @@ +package dude; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.geometry.Pos; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.image.ImageView; +import javafx.scene.layout.HBox; + +public class DialogBox extends HBox { + + private Label text; + private ImageView displayPicture; + + public DialogBox(Label l, ImageView iv) { + text = l; + displayPicture = iv; + + text.setWrapText(true); + displayPicture.setFitWidth(100.0); + displayPicture.setFitHeight(100.0); + + this.setAlignment(Pos.TOP_RIGHT); + this.getChildren().addAll(text, displayPicture); + } + + /** + * Flips the dialog box such that the ImageView is on the left and text on the right. + */ + private void flip() { + this.setAlignment(Pos.TOP_LEFT); + ObservableList tmp = FXCollections.observableArrayList(this.getChildren()); + FXCollections.reverse(tmp); + this.getChildren().setAll(tmp); + } + + public static DialogBox getUserDialog(Label l, ImageView iv) { + return new DialogBox(l, iv); + } + + public static DialogBox getDudeDialog(Label l, ImageView iv) { + var db = new DialogBox(l, iv); + db.flip(); + return db; + } +} diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index c579ef74cb..245fa54e8a 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -2,29 +2,13 @@ import java.io.FileNotFoundException; -import javafx.application.Application; -import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.TextField; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.Label; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.Region; -import javafx.scene.layout.VBox; -import javafx.stage.Stage; - import dude.command.Command; /** * Dude is a programme that allows users to manage their tasks. */ -public class Dude extends Application { - private ScrollPane scrollPane; - private VBox dialogContainer; - private TextField userInput; - private Button sendButton; - +public class Dude { private TaskList taskList; private Storage storage; private Ui ui; @@ -47,57 +31,6 @@ public Dude(String filePath) { } } - @Override - public void start(Stage stage) { - //Step 1: Setting up required components - - //Container for the content of the chat to scroll - scrollPane = new ScrollPane(); - dialogContainer = new VBox(); - scrollPane.setContent(dialogContainer); - - userInput = new TextField(); - sendButton = new Button("Send"); - - AnchorPane mainLayout = new AnchorPane(); - mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); - - Scene scene = new Scene(mainLayout); // Setting the scene to be mainLayout - - stage.setScene(scene); // Setting the stage to show our screen - stage.show(); // Render the stage. - - //Step 2: Formatting the window to look as expected - stage.setTitle("Dude"); - stage.setResizable(false); - stage.setMinHeight(600.0); - stage.setMinWidth(400.0); - - mainLayout.setPrefSize(400.0, 600.0); - - scrollPane.setPrefSize(385.0, 535.0); - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); - - scrollPane.setVvalue(1.0); - scrollPane.setFitToWidth(true); - - dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); - - userInput.setPrefWidth(342.0); - - sendButton.setPrefWidth(55.0); - - AnchorPane.setTopAnchor(scrollPane, 1.0); - - AnchorPane.setBottomAnchor(sendButton, 1.0); - AnchorPane.setRightAnchor(sendButton, 1.0); - - AnchorPane.setLeftAnchor(userInput, 1.0); - AnchorPane.setBottomAnchor(userInput, 1.0); - - } - /** * Method that runs the Dude programme. */ diff --git a/src/main/java/dude/Launcher.java b/src/main/java/dude/Launcher.java index 4960f600e2..c97b4240eb 100644 --- a/src/main/java/dude/Launcher.java +++ b/src/main/java/dude/Launcher.java @@ -7,6 +7,6 @@ */ public class Launcher { public static void main(String[] args) { - Application.launch(Dude.class, args); + Application.launch(Main.class, args); } } diff --git a/src/main/java/dude/Main.java b/src/main/java/dude/Main.java new file mode 100644 index 0000000000..320d5d4a09 --- /dev/null +++ b/src/main/java/dude/Main.java @@ -0,0 +1,121 @@ +package dude; + +import javafx.application.Application; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.Region; +import javafx.scene.layout.VBox; +import javafx.stage.Stage; + +public class Main extends Application { + private ScrollPane scrollPane; + private VBox dialogContainer; + private TextField userInput; + private Button sendButton; + private Image user = new Image(this.getClass().getResourceAsStream("/images/User.png")); + private Image dude = new Image(this.getClass().getResourceAsStream("/images/Dude.png")); + + @Override + public void start(Stage stage) { + //Step 1: Setting up required components + + //Container for the content of the chat to scroll + scrollPane = new ScrollPane(); + dialogContainer = new VBox(); + scrollPane.setContent(dialogContainer); + + userInput = new TextField(); + sendButton = new Button("Send"); + + AnchorPane mainLayout = new AnchorPane(); + mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); + + Scene scene = new Scene(mainLayout); // Setting the scene to be mainLayout + + stage.setScene(scene); // Setting the stage to show our screen + stage.show(); // Render the stage. + + //Step 2: Formatting the window to look as expected + stage.setTitle("Dude"); + stage.setResizable(false); + stage.setMinHeight(600.0); + stage.setMinWidth(400.0); + + mainLayout.setPrefSize(400.0, 600.0); + + scrollPane.setPrefSize(385.0, 535.0); + scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); + scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); + + scrollPane.setVvalue(1.0); + scrollPane.setFitToWidth(true); + + dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); + + userInput.setPrefWidth(342.0); + + sendButton.setPrefWidth(55.0); + + AnchorPane.setTopAnchor(scrollPane, 1.0); + + AnchorPane.setBottomAnchor(sendButton, 1.0); + AnchorPane.setRightAnchor(sendButton, 1.0); + + AnchorPane.setLeftAnchor(userInput, 1.0); + AnchorPane.setBottomAnchor(userInput, 1.0); + + //Step 3: Add functionality to handle user input + sendButton.setOnMouseClicked(((event) -> { + handleUserInput(); + })); + + userInput.setOnAction(((event) -> { + handleUserInput(); + })); + + //Scroll down to the end every time dialogContainer's height changes + dialogContainer.heightProperty().addListener((observable) -> scrollPane.setVvalue(1.0)); + } + + /** + * Iteration 1: + * Creates a label with the specified text and adds it to the dialog container. + * @param text String containing text to add. + * @return a label with the specified text that has word wrap enabled. + */ + private Label getDialogLabel(String text) { + Label textToAdd = new Label(text); + textToAdd.setWrapText(true); + + return textToAdd; + } + + /** + * Iteration 2: + * Creates two dialog boxes, one echoing user input and the other containing Dude's reply + * and then appends them to the dialog container. Clears the user input after processing. + */ + private void handleUserInput() { + Label userText = new Label(userInput.getText()); + Label dudeText = new Label(getResponse(userInput.getText())); + dialogContainer.getChildren().addAll( + DialogBox.getUserDialog(userText, new ImageView(user)), + DialogBox.getDudeDialog(dudeText, new ImageView(dude)) + ); + userInput.clear(); + } + + /** + * Method to generate a response to user input. + * Replace with completed method. + */ + private String getResponse(String input) { + return "Dude heard: " + input; + } +} diff --git a/src/main/resources/images/Dude.png b/src/main/resources/images/Dude.png new file mode 100644 index 0000000000000000000000000000000000000000..9ce5a19eef04a5ab1eb453d8f7a12a819cb131b8 GIT binary patch literal 58618 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ⅇJ(KlpX|dtnq*ZAHA#llz9xI#HWusm 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/images/User.png b/src/main/resources/images/User.png new file mode 100644 index 0000000000000000000000000000000000000000..29d02d74c82574510dc3d4f8c04d3cdbff9773c2 GIT binary patch literal 108991 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 QZvX%Q07*qoM6N<$f+?trmH+?% literal 0 HcmV?d00001 From 0e725575c3c28c148e6bca81a9dc0e66afbb9862 Mon Sep 17 00:00:00 2001 From: vivienherq Date: Thu, 14 Sep 2023 15:24:39 +0800 Subject: [PATCH 30/57] Add user interaction functionality to GUI for Dude --- data/dude.txt | 1 + src/main/java/dude/DialogBox.java | 52 ++++--- src/main/java/dude/Dude.java | 11 ++ src/main/java/dude/Main.java | 128 +++--------------- src/main/java/dude/MainWindow.java | 54 ++++++++ src/main/java/dude/Ui.java | 59 ++++---- .../java/dude/command/AddDeadlineCommand.java | 10 +- .../java/dude/command/AddEventCommand.java | 8 +- .../java/dude/command/AddToDoCommand.java | 8 +- src/main/java/dude/command/Command.java | 2 +- src/main/java/dude/command/DeleteCommand.java | 10 +- src/main/java/dude/command/ExitCommand.java | 5 +- src/main/java/dude/command/FindCommand.java | 8 +- src/main/java/dude/command/ListCommand.java | 7 +- src/main/java/dude/command/MarkCommand.java | 10 +- .../java/dude/command/UnknownCommand.java | 5 +- src/main/java/dude/command/UnmarkCommand.java | 10 +- src/main/resources/view/DialogBox.fxml | 16 +++ src/main/resources/view/MainWindow.fxml | 19 +++ 19 files changed, 236 insertions(+), 187 deletions(-) create mode 100644 src/main/java/dude/MainWindow.java create mode 100644 src/main/resources/view/DialogBox.fxml create mode 100644 src/main/resources/view/MainWindow.fxml diff --git a/data/dude.txt b/data/dude.txt index 95fdf0093a..7f78c8b120 100644 --- a/data/dude.txt +++ b/data/dude.txt @@ -6,3 +6,4 @@ E | 0 | gen meeting | 2023-09-12T20:00 | 2023-09-12T22:00 T | 0 | go to school T | 0 | sleep again T | 0 | sleep tomorrow +T | 0 | sleeepppppp diff --git a/src/main/java/dude/DialogBox.java b/src/main/java/dude/DialogBox.java index c0e450c52f..4b47280311 100644 --- a/src/main/java/dude/DialogBox.java +++ b/src/main/java/dude/DialogBox.java @@ -1,46 +1,60 @@ package dude; +import java.io.IOException; +import java.util.Collections; + import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; import javafx.geometry.Pos; import javafx.scene.Node; import javafx.scene.control.Label; +import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.HBox; +/** + * An example of a custom control using FXML. + * This control represents a dialog box consisting of an ImageView to represent the speaker's face and a label + * containing text from the speaker. + */ public class DialogBox extends HBox { - - private Label text; + @FXML + private Label dialog; + @FXML private ImageView displayPicture; - public DialogBox(Label l, ImageView iv) { - text = l; - displayPicture = iv; - - text.setWrapText(true); - displayPicture.setFitWidth(100.0); - displayPicture.setFitHeight(100.0); - - this.setAlignment(Pos.TOP_RIGHT); - this.getChildren().addAll(text, displayPicture); + private DialogBox(String text, Image img) { + try { + FXMLLoader fxmlLoader = new FXMLLoader(MainWindow.class.getResource("/view/DialogBox.fxml")); + fxmlLoader.setController(this); + fxmlLoader.setRoot(this); + fxmlLoader.load(); + } catch (IOException e) { + e.printStackTrace(); + } + + dialog.setText(text); + displayPicture.setImage(img); } /** * Flips the dialog box such that the ImageView is on the left and text on the right. */ private void flip() { - this.setAlignment(Pos.TOP_LEFT); ObservableList tmp = FXCollections.observableArrayList(this.getChildren()); - FXCollections.reverse(tmp); - this.getChildren().setAll(tmp); + Collections.reverse(tmp); + getChildren().setAll(tmp); + setAlignment(Pos.TOP_LEFT); } - public static DialogBox getUserDialog(Label l, ImageView iv) { - return new DialogBox(l, iv); + public static DialogBox getUserDialog(String text, Image img) { + return new DialogBox(text, img); } - public static DialogBox getDudeDialog(Label l, ImageView iv) { - var db = new DialogBox(l, iv); + public static DialogBox getDudeDialog(String text, Image img) { + var db = new DialogBox(text, img); db.flip(); return db; } diff --git a/src/main/java/dude/Dude.java b/src/main/java/dude/Dude.java index 245fa54e8a..175c70e8ac 100644 --- a/src/main/java/dude/Dude.java +++ b/src/main/java/dude/Dude.java @@ -31,6 +31,17 @@ public Dude(String filePath) { } } + /** + * Method to generate a response to user input. + * Replace with completed method. + */ + public String getResponse(String input) { + System.out.println(input); + Command c = Parser.parse(input); + String output = c.execute(taskList, ui, storage); + return output; + } + /** * Method that runs the Dude programme. */ diff --git a/src/main/java/dude/Main.java b/src/main/java/dude/Main.java index 320d5d4a09..b891d5d0cf 100644 --- a/src/main/java/dude/Main.java +++ b/src/main/java/dude/Main.java @@ -1,121 +1,33 @@ package dude; +import java.io.IOException; + import javafx.application.Application; +import javafx.fxml.FXMLLoader; import javafx.scene.Scene; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.TextField; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.Region; -import javafx.scene.layout.VBox; import javafx.stage.Stage; +/** + * A GUI for Duke using FXML. + */ public class Main extends Application { - private ScrollPane scrollPane; - private VBox dialogContainer; - private TextField userInput; - private Button sendButton; - private Image user = new Image(this.getClass().getResourceAsStream("/images/User.png")); - private Image dude = new Image(this.getClass().getResourceAsStream("/images/Dude.png")); + + private Dude dude = new Dude("./data/dude.txt"); @Override public void start(Stage stage) { - //Step 1: Setting up required components - - //Container for the content of the chat to scroll - scrollPane = new ScrollPane(); - dialogContainer = new VBox(); - scrollPane.setContent(dialogContainer); - - userInput = new TextField(); - sendButton = new Button("Send"); - - AnchorPane mainLayout = new AnchorPane(); - mainLayout.getChildren().addAll(scrollPane, userInput, sendButton); - - Scene scene = new Scene(mainLayout); // Setting the scene to be mainLayout - - stage.setScene(scene); // Setting the stage to show our screen - stage.show(); // Render the stage. - - //Step 2: Formatting the window to look as expected - stage.setTitle("Dude"); - stage.setResizable(false); - stage.setMinHeight(600.0); - stage.setMinWidth(400.0); - - mainLayout.setPrefSize(400.0, 600.0); - - scrollPane.setPrefSize(385.0, 535.0); - scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER); - scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS); - - scrollPane.setVvalue(1.0); - scrollPane.setFitToWidth(true); - - dialogContainer.setPrefHeight(Region.USE_COMPUTED_SIZE); - - userInput.setPrefWidth(342.0); - - sendButton.setPrefWidth(55.0); - - AnchorPane.setTopAnchor(scrollPane, 1.0); - - AnchorPane.setBottomAnchor(sendButton, 1.0); - AnchorPane.setRightAnchor(sendButton, 1.0); - - AnchorPane.setLeftAnchor(userInput, 1.0); - AnchorPane.setBottomAnchor(userInput, 1.0); - - //Step 3: Add functionality to handle user input - sendButton.setOnMouseClicked(((event) -> { - handleUserInput(); - })); - - userInput.setOnAction(((event) -> { - handleUserInput(); - })); - - //Scroll down to the end every time dialogContainer's height changes - dialogContainer.heightProperty().addListener((observable) -> scrollPane.setVvalue(1.0)); - } - - /** - * Iteration 1: - * Creates a label with the specified text and adds it to the dialog container. - * @param text String containing text to add. - * @return a label with the specified text that has word wrap enabled. - */ - private Label getDialogLabel(String text) { - Label textToAdd = new Label(text); - textToAdd.setWrapText(true); - - return textToAdd; - } - - /** - * Iteration 2: - * Creates two dialog boxes, one echoing user input and the other containing Dude's reply - * and then appends them to the dialog container. Clears the user input after processing. - */ - private void handleUserInput() { - Label userText = new Label(userInput.getText()); - Label dudeText = new Label(getResponse(userInput.getText())); - dialogContainer.getChildren().addAll( - DialogBox.getUserDialog(userText, new ImageView(user)), - DialogBox.getDudeDialog(dudeText, new ImageView(dude)) - ); - userInput.clear(); - } - - /** - * Method to generate a response to user input. - * Replace with completed method. - */ - private String getResponse(String input) { - return "Dude heard: " + input; + try { + FXMLLoader fxmlLoader = new FXMLLoader(Main.class.getResource("/view/MainWindow.fxml")); + AnchorPane ap = fxmlLoader.load(); + Scene scene = new Scene(ap); + stage.setScene(scene); + MainWindow mainWindow = fxmlLoader.getController(); + mainWindow.setDude(dude); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + } } } + diff --git a/src/main/java/dude/MainWindow.java b/src/main/java/dude/MainWindow.java new file mode 100644 index 0000000000..0eb127262b --- /dev/null +++ b/src/main/java/dude/MainWindow.java @@ -0,0 +1,54 @@ +package dude; + +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.image.Image; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.VBox; +/** + * Controller for MainWindow. Provides the layout for the other controls. + */ +public class MainWindow extends AnchorPane { + @FXML + private ScrollPane scrollPane; + @FXML + private VBox dialogContainer; + @FXML + private TextField userInput; + @FXML + private Button sendButton; + + private Dude dude; + + private Image userImage = new Image(this.getClass().getResourceAsStream("/images/User.png")); + private Image dudeImage = new Image(this.getClass().getResourceAsStream("/images/Dude.png")); + + @FXML + public void initialize() { + scrollPane.vvalueProperty().bind(dialogContainer.heightProperty()); + dialogContainer.getChildren().addAll( + DialogBox.getDudeDialog(Ui.showWelcome(), dudeImage) + ); + } + + public void setDude(Dude d) { + dude = d; + } + + /** + * Creates two dialog boxes, one echoing user input and the other containing Duke's reply and then appends them to + * the dialog container. Clears the user input after processing. + */ + @FXML + private void handleUserInput() { + String input = userInput.getText(); + String response = dude.getResponse(input); + dialogContainer.getChildren().addAll( + DialogBox.getUserDialog(input, userImage), + DialogBox.getDudeDialog(response, dudeImage) + ); + userInput.clear(); + } +} \ No newline at end of file diff --git a/src/main/java/dude/Ui.java b/src/main/java/dude/Ui.java index 635f9d4728..bbaac5d41f 100644 --- a/src/main/java/dude/Ui.java +++ b/src/main/java/dude/Ui.java @@ -19,84 +19,91 @@ public String readCommand() { /** * Prints a welcome message for users. */ - public void showWelcome() { + public static String showWelcome() { String greeting = "Hello, I'm Dude!\n" + "What can I do for you?"; - System.out.println(greeting); + return greeting; } /** * Prints a farewell message for users. */ - public void showFarewell() { + public static String showFarewell() { String greeting = "Bye. Hope to see you again soon!"; - System.out.println(greeting); + return greeting; } /** * Prints a line. */ - public void showLine() { - System.out.println("__________________________________________________"); + public String showLine() { + String line = "__________________________________________________"; + return line; } /** * Prints the list of tasks.. */ - public void showTaskList(TaskList taskList) { + public String showTaskList(TaskList taskList) { int nTasks = taskList.getSize(); + String taskListString = ""; if (nTasks == 0) { - System.out.println("You have no saved tasks."); + taskListString = "You have no saved tasks.\n"; } else { for (int i = 0; i < nTasks; i++) { Task task = taskList.getTask(i); - System.out.printf("%d. %s\n", i + 1, task.toString()); + taskListString = taskListString + String.format("%d. %s\n", i + 1, task.toString()); } } + return taskListString; } /** * Prints a statement to show the task that has been successfully marked. */ - public void showMarkedTask(Task task) { - System.out.println("Nice! I've marked this task as done:"); - System.out.printf(task.toString()); - System.out.println(); + public String showMarkedTask(Task task) { + String confirmation = "Nice! I've marked this task as done:\n" + + task.toString() + "\n"; + return confirmation; // task is already done? } /** * Prints a statement to show the task that has been successfully unmarked. */ - public void showUnmarkedTask(Task task) { - System.out.println("Nice! I've marked this task as as not done yet:"); - System.out.printf(task.toString()); - System.out.println(); + public String showUnmarkedTask(Task task) { + String confirmation = "Nice! I've marked this task as as not done yet:\n" + + task.toString() + "\n"; + return confirmation; // task is already undone? } /** * Prints a statement to show the task that has been successfully deleted. */ - public void showDeletedTask(Task task, int nTasks) { - System.out.println("Noted. I've removed this task:"); - System.out.println(task.toString()); - System.out.printf("Now you have %d tasks in the list.\n", nTasks); + public String showDeletedTask(Task task, int nTasks) { + String confirmation = "Noted. I've removed this task:\n" + + task.toString() + "\n" + + String.format("Now you have %d tasks in the list.\n", nTasks); + return confirmation; } /** * Prints a statement to show the task that has been successfully added. */ - public void showAddedTask(Task task, int nTasks) { - System.out.printf("Got it. I've added this task:\n%s\n", task.toString()); - System.out.printf("Now you have %d tasks in the list. \n", nTasks); + public String showAddedTask(Task task, int nTasks) { + String confirmation = "Got it. I've added this task:\n" + + task.toString() + "\n" + + String.format("Now you have %d tasks in the list.\n", nTasks); + return confirmation; } /** * Prints a statement to show the command is unknown. */ - public void showUnknownCommand() { - System.out.println(" OOPS!!! I'm sorry, but I don't know what that means :-("); + public String showUnknownCommand() { + String reply = " OOPS!!! I'm sorry, but I don't know what that means :-(\n"; + return reply; } public void showError(String message) { diff --git a/src/main/java/dude/command/AddDeadlineCommand.java b/src/main/java/dude/command/AddDeadlineCommand.java index 69a9ee164a..bdf5947b74 100644 --- a/src/main/java/dude/command/AddDeadlineCommand.java +++ b/src/main/java/dude/command/AddDeadlineCommand.java @@ -33,16 +33,18 @@ public AddDeadlineCommand(String taskDescription, LocalDateTime byDateTime) { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ""; try { - System.out.println("Executing Add Deadline Command"); + output = "Executing Add Deadline Command\n"; Deadline newTask = new Deadline(taskDescription, byDateTime); taskList.addTask(newTask); int nTasks = taskList.getSize(); - ui.showAddedTask(newTask, nTasks); + output = output + ui.showAddedTask(newTask, nTasks) +"\n"; storage.saveTasksToDisk(taskList); } catch (IOException e) { - System.out.println("Error in Add Deadline Command"); + output = "Error in Add Deadline Command"; } + return output; } } diff --git a/src/main/java/dude/command/AddEventCommand.java b/src/main/java/dude/command/AddEventCommand.java index 2007f86d24..3de881408a 100644 --- a/src/main/java/dude/command/AddEventCommand.java +++ b/src/main/java/dude/command/AddEventCommand.java @@ -36,16 +36,18 @@ public AddEventCommand(String taskDescription, LocalDateTime fromDateTime, Local * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ""; try { - System.out.println("Executing Add Event Command"); + output = "Executing Add Event Command\n"; Event newTask = new Event(taskDescription, fromDateTime, toDateTime); taskList.addTask(newTask); int nTasks = taskList.getSize(); - ui.showAddedTask(newTask, nTasks); + output = output + ui.showAddedTask(newTask, nTasks) + "\n"; storage.saveTasksToDisk(taskList); } catch (IOException e) { System.out.println("Error in Add Event Command"); } + return output; } } diff --git a/src/main/java/dude/command/AddToDoCommand.java b/src/main/java/dude/command/AddToDoCommand.java index 09548e1f55..d532fa21cf 100644 --- a/src/main/java/dude/command/AddToDoCommand.java +++ b/src/main/java/dude/command/AddToDoCommand.java @@ -25,16 +25,18 @@ public AddToDoCommand(String taskDescription) { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ""; try { - System.out.println("Executing Add ToDo Command"); + output = "Executing Add ToDo Command\n"; ToDo newTask = new ToDo(taskDescription); taskList.addTask(newTask); int nTasks = taskList.getSize(); - ui.showAddedTask(newTask, nTasks); + output = output + ui.showAddedTask(newTask, nTasks) + "\n"; storage.saveTasksToDisk(taskList); } catch (IOException e) { System.out.println("Error in Add ToDo Command"); } + return output; } } diff --git a/src/main/java/dude/command/Command.java b/src/main/java/dude/command/Command.java index 3db1daa8ec..8acdc907a8 100644 --- a/src/main/java/dude/command/Command.java +++ b/src/main/java/dude/command/Command.java @@ -15,7 +15,7 @@ public Command() { this.isExit = false; } - public abstract void execute(TaskList taskList, Ui ui, Storage storage); + public abstract String execute(TaskList taskList, Ui ui, Storage storage); public boolean isExit() { return this.isExit; diff --git a/src/main/java/dude/command/DeleteCommand.java b/src/main/java/dude/command/DeleteCommand.java index e2fd623faf..255b41339d 100644 --- a/src/main/java/dude/command/DeleteCommand.java +++ b/src/main/java/dude/command/DeleteCommand.java @@ -25,15 +25,17 @@ public DeleteCommand(int taskIndex) { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ""; try { - System.out.println("Executing Delete Command"); + output = "Executing Delete Command"; Task deletedTask = taskList.deleteTask(taskIndex); int nTasks = taskList.getSize(); - ui.showDeletedTask(deletedTask, nTasks); + output = output + ui.showDeletedTask(deletedTask, nTasks) + "\n"; storage.saveTasksToDisk(taskList); } catch (IOException e) { - System.out.println("Error in Delete Command"); + output = "Error in Delete Command"; } + return output; } } diff --git a/src/main/java/dude/command/ExitCommand.java b/src/main/java/dude/command/ExitCommand.java index b142605370..c2c9b294d8 100644 --- a/src/main/java/dude/command/ExitCommand.java +++ b/src/main/java/dude/command/ExitCommand.java @@ -20,7 +20,8 @@ public ExitCommand() { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - ui.showFarewell(); + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ui.showFarewell(); + return output; } } diff --git a/src/main/java/dude/command/FindCommand.java b/src/main/java/dude/command/FindCommand.java index b84bd90df3..39e96e98bd 100644 --- a/src/main/java/dude/command/FindCommand.java +++ b/src/main/java/dude/command/FindCommand.java @@ -20,10 +20,10 @@ public FindCommand(String searchKeywords) { } @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - System.out.println("Executing Find Command"); + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = "Executing Find Command\n"; TaskList searchResults = taskList.findTasks(searchKeywords); - ui.showTaskList(searchResults); + output = output + ui.showTaskList(searchResults); + return output; } - } diff --git a/src/main/java/dude/command/ListCommand.java b/src/main/java/dude/command/ListCommand.java index 60d1858542..2d791f8f6d 100644 --- a/src/main/java/dude/command/ListCommand.java +++ b/src/main/java/dude/command/ListCommand.java @@ -17,8 +17,9 @@ public class ListCommand extends Command { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - System.out.println("Listing..."); - ui.showTaskList(taskList); + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = "Listing...\n"; + output = output + ui.showTaskList(taskList); + return output; } } diff --git a/src/main/java/dude/command/MarkCommand.java b/src/main/java/dude/command/MarkCommand.java index c530ab838d..afb4bc0526 100644 --- a/src/main/java/dude/command/MarkCommand.java +++ b/src/main/java/dude/command/MarkCommand.java @@ -25,14 +25,16 @@ public MarkCommand(int taskIndex) { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ""; try { - System.out.println("Executing Mark Command");; + output = "Executing Mark Command\n"; Task markedTask = taskList.markTask(taskIndex); - ui.showMarkedTask(markedTask); + output = output + ui.showMarkedTask(markedTask); storage.saveTasksToDisk(taskList); } catch (IOException e) { - System.out.println("Error in Mark Command"); + output = "Error in Mark Command\n"; } + return output; } } diff --git a/src/main/java/dude/command/UnknownCommand.java b/src/main/java/dude/command/UnknownCommand.java index b3a6b12606..4f852dc709 100644 --- a/src/main/java/dude/command/UnknownCommand.java +++ b/src/main/java/dude/command/UnknownCommand.java @@ -17,7 +17,8 @@ public class UnknownCommand extends Command { * @param ui User interface of Dude. */ @Override - public void execute(TaskList taskList, Ui ui, Storage storage) { - ui.showUnknownCommand(); + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ui.showUnknownCommand(); + return output; } } diff --git a/src/main/java/dude/command/UnmarkCommand.java b/src/main/java/dude/command/UnmarkCommand.java index 601ee8e1e9..506d4619aa 100644 --- a/src/main/java/dude/command/UnmarkCommand.java +++ b/src/main/java/dude/command/UnmarkCommand.java @@ -24,14 +24,16 @@ public UnmarkCommand(int taskIndex) { * @param storage Storage containing saved tasks, and saves and loads tasks. * @param ui User interface of Dude. */ - public void execute(TaskList taskList, Ui ui, Storage storage) { + public String execute(TaskList taskList, Ui ui, Storage storage) { + String output = ""; try { - System.out.println("Executing Unmark Command");; + output = "Executing Unmark Command\n"; Task unmarkedTask = taskList.unmarkTask(taskIndex); - ui.showUnmarkedTask(unmarkedTask); + output = output + ui.showUnmarkedTask(unmarkedTask); storage.saveTasksToDisk(taskList); } catch (IOException e) { - System.out.println("Error in Unmark Command"); + output = "Error in Unmark Command"; } + return output; } } diff --git a/src/main/resources/view/DialogBox.fxml b/src/main/resources/view/DialogBox.fxml new file mode 100644 index 0000000000..d3e6e9db86 --- /dev/null +++ b/src/main/resources/view/DialogBox.fxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml new file mode 100644 index 0000000000..b4be105aee --- /dev/null +++ b/src/main/resources/view/MainWindow.fxml @@ -0,0 +1,19 @@ + + + + + + + + + + + +