From ca59792916b76441583edb0c6b3b317146ac7d08 Mon Sep 17 00:00:00 2001 From: Ilkka Seppala Date: Fri, 13 Mar 2015 21:59:24 +0200 Subject: [PATCH] Added event aggregator pattern. --- event-aggregator/etc/classes.png | Bin 0 -> 45639 bytes event-aggregator/etc/classes.ucls | 124 ++++++++++++++++++ event-aggregator/pom.xml | 17 +++ .../src/main/java/com/iluwatar/App.java | 35 +++++ .../src/main/java/com/iluwatar/Event.java | 21 +++ .../main/java/com/iluwatar/EventEmitter.java | 35 +++++ .../main/java/com/iluwatar/EventObserver.java | 12 ++ .../main/java/com/iluwatar/KingJoffrey.java | 14 ++ .../src/main/java/com/iluwatar/KingsHand.java | 28 ++++ .../main/java/com/iluwatar/LordBaelish.java | 24 ++++ .../src/main/java/com/iluwatar/LordVarys.java | 24 ++++ .../src/main/java/com/iluwatar/Scout.java | 24 ++++ .../src/main/java/com/iluwatar/Weekday.java | 16 +++ .../src/test/java/com/iluwatar/AppTest.java | 13 ++ pom.xml | 3 +- 15 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 event-aggregator/etc/classes.png create mode 100644 event-aggregator/etc/classes.ucls create mode 100644 event-aggregator/pom.xml create mode 100644 event-aggregator/src/main/java/com/iluwatar/App.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/Event.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/EventEmitter.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/EventObserver.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/KingJoffrey.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/KingsHand.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/LordBaelish.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/LordVarys.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/Scout.java create mode 100644 event-aggregator/src/main/java/com/iluwatar/Weekday.java create mode 100644 event-aggregator/src/test/java/com/iluwatar/AppTest.java diff --git a/event-aggregator/etc/classes.png b/event-aggregator/etc/classes.png new file mode 100644 index 0000000000000000000000000000000000000000..295719ea37125d8b49bb8967e2269355d6901c6b GIT binary patch literal 45639 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 z z6=q}ko7l7Axh_L6Z`|!(Ws`MgU(h;Uik-hwsMD+>GT5if^>*4$Sx^&40V6o^{BSuzUFZCN0gvTOT ze8Hl^14vJfjhzHXyZM7l-pXWN*S!SO-+fRIvA&{OS4*;7R4T8!lfpt0np9iSw-%*C z)E0|-osw!9~|XGK{<)b7Um*F&G)n%xidV1(MvWT!r4?JU6_zk z@pNA8wIqK88QSQ_gpM6_S}U9~rlQ!1cPbAFsTKD4U-Txhz1r2e#6M~Q&pbNIlq*~F zNO@h?bnmW;`H?&)e8*(2@^YYp+V^|Q{^MI`#|;R#65~E`|nn?yD-~LsJoWC>P}mG zpz)?GQI{GR+lW;R%-iU!-noKZ^2|qw_3w?9*?t@gzU)=L5|=ub&jMRAyplv!4cx{0 z*(Z9ZKL?41H)`m7sn-2IF#;fqg}Wa8MS1@R4ib*4QH5~(1`+k(IJD_s;4HZdyy2AO zQ2d3Byfe7b{caB!q%a0#h>TD6+3ra7W9d8z;mBi}>Ah5<=|8|7%j0Lo$v&PLqmL(e zEv6A|T9B~%F3h|?@S9tu0Wa%55T5;Y_p;Gc0^5q>bQMI4s{YrDNSH(;2D2F^}G=8Pna) ziUaX@6y9v8W~DSx1zwcPoSYSrW*FumCc_FDyZ+ZDAlMpB?>GkfJp=*9nKuA1RzuVIL`?D$hJ z$bo1oRS;LLLN(DPwZb~lAKEe|FL+azEjI$D*H)Ybzxt;1_gLr@nEIm0q6)0@>r$&d z1@*8=r_LDd#OgPAxhU@CUylyJM4fj6kFIops41`!*uJF)P+ZhZvr*8NV(x@Tq2E2D3AU^HCrIEu&bm=iFp=tadU4gDIy(i z!PcsY`wzM#lW&H1?DVB{$8V77x?O7IOrUB=iP4);Gx0*fb!Wsb!_!qwYvlpo<%jqA zlXdVqKd7HpM#KnilKIr}3l7uAkgveZ0x~=H2VB#Aiws_IwtYpMYfxsHep9rV?W+y1 z`gZYrgMZ@%E6r4K@)|wPsYeb|i($%kho@M|M^HYlH&0*a^CoHC&u)W50%w zI6Cq9l4sz!qE|v}$_X;YQ zXTiNtngk`6O;D)j-r1p2cYhGUp=DJ?7p zDF=vP>7+V6BKy=$!8No?%rZr4%&UL{YXT4Hb5RxDy0^`jghW(j%{j25nm`xJm*Dt8 zE%KV4cyVm8PenD&DmTv}pvU0I}wIfV_?GBbG`w$k0`#;OyFWTp9p}*=)jni6g z2z-6O9l%-vAjG+sq}Kapi2DQ1=jWG38ze*Ms7pEViyjH%at_1aQGz%OyP4gR4`A1T z0NDw_kUPW{;zq|+@)b-c(%Q`bWA@z&Yx+8>*Yd~TB**yX&Thk_KtP<)sSppchzKQ5MGgjlmbj`aa}ECD0vY~8W6h1c5@K(kqd$Yc#Pfmoo5XH>B+aQF zu_w43sQ!G;63(9(d3E8}4bqP~dfhGit!}&IFn?ne=C>3VVeKE|WBRe_@2lW=;W<5N zm(m3r(AeK#;Qv4&y`6gaLU6KqfLDGs#Cd?*Kml zh3?-6-7=wS*apg**`1q`;SE@h{?b%I8 zWcADKqBMGvcKCV?CWh8m1JW%B=)+2Q-HUoeE<_|@t@FC`)OMANmz_JYB3-(eGCqWc z(Q6w<6HG(cz|0sC)cltUT8gOmFuJquhbSZX1qB&GvCOI`;mxOQAwHzAgH&3I7{ZF2TLIv&@ zPxGa##mSZf{6%cQ)gN~rCmJ`1ZyVx_)k7&(!|_!_sDFdT&>Pcb^*t@66r+J48mBaU zvd8OWg5+0$BU+xX8IOCGn7vs0_IlChPtcg|vpQ4@DxG}je zj}iwqnNOe}Fnjn!Bb;9Iaz*DFgA)Wz>P+(6q^qP%W5Sl*Yx(?cSNzY}jsR89 zs^sNauc=a|U2HR!zZfd$Zhh`tf#WJ4859{Jei<26*6CB+M?>{dc*Vj(xa|9`-2B+K z*=BV62chY)WdEmEnV+(+1oKuCt$b-{M(HamFd)p~P;{HNgRBK@2mI)Y%AVog-h+6? zEri4ijo4bNih0Sb|Bh44sbEgxCA|l+%$i8TEqbGrCmp zA;xfnB^YIHUv3qW71fO=cuNq0c*6D~jBuzGFfx3(IP!@y7|AsfTT^6!!gU~hvhHoy zBNzujQ;#}vle}KpmO~!MwE<=D&ieX;?#wao%)hLP8js55d9u_SimP5!EgD@!1pXYM zr*TVb;$FiA>dsWu{v_W9rc?k*rnTBMGn955Xh-oKLBRw33_gTgzl@BTE`rTPf0w}* zAF99dgWeQ!=WHE$l^B;hRy_8VdS=ahRG>H?3BY}dLc!~fuk_}@%DJ?(TNxPUADF7h zrL^%^eF%k%w}L`pVU7T$5-{-b!UqOE-B{*b-i8Hk3#G~mfd`xgi20C0c&86GY@P*I zft*}o1^eZu@ZyyE^+ikPp^W>Ir-kv?o2_y__zI5|WASszd_FRWeqr+QFO@QJ1Stpx z`+Whi`Viuu(pz=8X$K<%7bo7v7Vp!|PX0Tau`r%lu`7#EvBm=q0pfSr9M@7I)^-B* z-yxAPuZbD(-*9BUKsL@H$xXAzUW-a&L)rSFHD2KfRwmBus4o}k?(T^&^-e$ag8CEi zs`5XiyIhjc5s*k%i?nlZziK{VZ;KPXo^!?KYK83$#?t|eJ2qoYa-JQ zNin_8PJ&+P!zH!H6Fe|;7q!gOy^_IN)xNUaKloABXrUy_Z!cCtCnB1AoU9{xv?REq z$sL(|)SHxCzJgYo)q;-zfcV1t>?bam~6V7(21ozhCJ?i0wS(hd0>YEj`5S7aP$ zwnR04^YdFd5HkSf(PyO1a&g$+0)<8#bmE@#9q(70^pt=cp{bYG^4_83l_SHd%*stE zm2ct=X1-s|lp5eSz6*4Ibz00*`=MpQfUl;k>3c`?k3We%2GSLnd?U-aYQU%Qi1k+L z3lU}W!R~)9R^g+4cYJ@hFjzbrchJOtaq6Qzpe#9f%a-+w)yrSN+Jv_te#;|aUXE~; z(wSG$>+R0XPVQ-xs_y>G0X+Ws`(;nUrS2efLEayw-Vb%tbji()@R;fMd`S({t=Ot7 zO@>jP}d1=KstM?tr#H;}kbj(?S| zBSd9c%d{Z0%^Gq7fq7d43>Y~Mo11+z%w@c4EPwCDDM={U7||zI2_6RksQ_Ujo9wKP zXa3q@@4c|s_eGI<(d2N3Z+P!wIK_*&hXjd2w>vyoY?HOPI4c^D=%#(_gPdP&B4DA7 zB@^m{U{ZOeVp`+vb#&DKMo!Y>(@7yskva1Tz>V?6@C=irYXU#xiWhs%F8vxb?6L=j&9QzMNn~j)J z0Kq#WFE57G$SAntUU~C}n-tDLa6|$M&KK&3$B_fz&sH_ zz;7)SfLyq@@yX3&gF$|yktR&Im{0q!Py8G907tYW0=r7)Ieo4y_y}eUiK3&DBbP_2 z1_Ofi#&-aRerto9!EidK!=k7BoMC|q==KcyBSOgq%L0% zN}v@n=>p`kJoo407~hR|l3-SMa0szdw5`isDGVlKy+?%D8j%GM0Q?Y;W4P{?j;rl9IbmH_)zVMv41#L{&6be(kQmM8WG`jzX6lDkiNT2Ih4;c@`dSl?lyPhcz5JG5PqSgeL zn5d}FhM)`oD%T){++3t}w*H`-Np%HU_vj1n07(zhQaWy$Jk3vCE!W$Jv!t!a zS@N7%lcH&wtC1Rp#_aJy>f9=t(~+_;iny#~2mm!Q`1Kbxg2LQBZI}Q{8`2xrEemiD z({nNZqHv+b2m}&dFgC+r;2}e?elchY9?^jzh_HlBshq`wKfYt1aa04 zpC=_oRGrl+zASJ8A%g=1O<)q*2w6FB-`aTOUUn=?JC1|9E-`6I)H6*3SF-;5K*!%k zs(~;*Z4qAx?H7T;o!FVuJw?e$&ts+Vat++QC_u>n`*7c41xQe4(OH zp#}r#QYC9&SS_=KYQQ+Q?H!tYI*J61sP>=%5r-$KQ6Zx8-X$3F zPkE1J%SBQ>X%#w}Ru!oFY*rJrL>{gfK(!27{nQ%Cy5R5?tJ z-ZB4RS18gUgV)*uh(K<;xK~1vGt|qkq-3!8#gdRfzj%!0B5b?Hp$kLgPE=6!k381L z!tJk-Gh7|)$U@&pGwBiQwHNXHqJ_72v>ef!HgSQCwoH)i-kgr=OI{+cmsSRu3h8rAU3;~5b5w%AG-;PVv` zBe%Ntc5gx8Jh-lQRB>|OIdGm*E~&;a?g#8r=&}`0nen`0`}TtqI7@xXkG^f4z38A= zHKi}v@vWzXSeUpiF91y=KwAHs@I$Hm)~{y4x3|ys=#gn8CPBw;i%29T_KZR4C~J4x zR@rf@Dern*BK^2{^;EN3mlIfVOzFH?^i6c1wr#aePxrFmz>7c^%*8!-7nikiM7!SE z{8v|rEnZIY^*`D<4}C&bJT2K`>lr=}m^=(yEeO%2^gt0Sbl2`ROybMcnr*NExshvA zHwTyXE^a?kB{tS@Tn&w?owFpo9(xb;oi!iekCYd{HtPfQu6EQ{Tq3q^M#~EG_lS9? z-h$8T6~rIM6_sqv^)bC8rxr%^d3t^L3$N4FLo9Kh2k#c;bxON&0H8d7bec_;-}-pq zNVVwoi^G>dtFI?Lk0RS~WI1pm2FDGJ!EcS}!)nbp(3C#eUvBocNoq69L9U32FgZF7 zrZ7*@#YH%;pl6}#iJ(V`h(M@xPfGQ2hT?yY>s5<}7hyH{q@@%=bSl6=wgu9(pN!Rpe_DI7wA4g`5M^0dOG&HBPv;EuJ z2SfdZzD=n)kg;&CQA`uLJt+rH8=wJD_IDE<_hy|3p>QplCl>53^@qyflY;r#eX*~#<){sHXNE?04hk#Z@u)G=UcpU?+J{sqm zza2N-zc^AGlp)N_NQ!8V)urj@XA>J}zTnd9N_(BHl#>#kc4c7AObw_?k_H-gS`y41 zA(wrMB&hbdx0$ZFaycEob~hiiHe|4#gD+_Z@WRaETg%|*lI z>kg`S$kNR~&X7T$>mFAPY>b3!NcEFmuwq(M@N)uSP??)hZ+}sUmItgZKI0^0qf4Pp?0G9@nX=35H3=fEt+885} z`H*RlqET2Ak@r}M{JeRM(6eK5J%VTmpdTRIelpFu-nMHDx^C}W>I7rXRJ)jlAzzxb z&TfY-4+O79RE;0kZYg3!kzY|TIk3mRQ>OvTs4L<_EaGZ);nv^*f*DF$cYviIv!cW} zrxes;K4r8nIvm@7u>F)Pj)H%{li(=rlZP2c-(T;M$wY0GT(--kfj1+-2F44)H?ns7 z9XFE!Kl7+_oSiZ@^*mW5YukbrTP!q&ms<>-1BoE1F&W~Y>SwfTARp}P?99w|YqyKo z{>ykv!sgqf3D|j8<r#A#l*Uh#L{A8NVo1^&HJk@jTiAn)aZBU`d{& z(Hn-ao`~#XLdyFW-PO3OuY9Ceskg>m#POq3WT-YLIJ$@6f0`hA!EM1^EBJ=C{d!4l z^Z1_W^JQz@0N<-n5OFo;@BF;~3d z;n_OB#?oP6WE|-08=9;5xm#0H1HHe6-g|*B;EpA?9u!7O*sb4wq&0S-w7#f}8zW!s zbaCrjXxMvvzeq}_ny9W$BXveIhUNJFN5wrwUD)DEytazrlf z`FSW5efws|h~IItZoZ(|Wi-yidX>+LNqEvuVTmU%Q-h`@D3y+d}ZgixsSHDR-2)54Os`hcN-pj8v4uIt&p?_Z?EtLSZ>ps?L{VLqZoXzfr{ z8Wf^KKtCF9=ef~?d+F8ChK05FX=#iQ9|&sJg~qR_I&2Hv zBC-C7U7w)TH7+iVkct%`qxsYK0(zw7sLJ+=4hdwCy{nepX^xTicE(VFcSk`i6$8^7 zxq?ERw;*XcE+bHRy{YxEJs-sOOu_TJ;To>xqmu<3F7lb{#ghE zQ>AlXp?lCw)5m>0rlrdk2C(Y(pfX6nWYb$rGy4hA44;Y+ei94#!Ed3kyH`CYB8 z*%vy)_V@M%`uo+*=Im27QVA~G!8h%bjb{~?gKJ{d6-`aD>8IVYE+e)=NA8bjR2#OG zPmINiK2^cNXu91_dbhyxo;C;JCW8o60QP(G0w+)}g!>?r=h5?f`}$B1p%GkNG|*F3 z5=7#ru;D<@Zq4-JxQOR0_Y!F6OBZCux*@>py97F}Kz>b2`F*DtKY5p~FwQjhX7Q9| znv={nwgO*G6UpW+b>50Me0)?fwc{qG%j`>*D_HhJBHWapUzIdA%AA*#mmlXhUFDx} ztxs=sWM>2a-$oy!ii*noNfsAA{P`pth2bRF^-VW+dnwi`a)t*?v+R_s8Q$xXU&`o= zVCMN$*HNff_Xgtp+_S{w?k^zs10jN{r`_(C zOc9vv=n8)bnSQZmIk`%v>vb#dibBafri`hTXr|I+f5=vqh$z2$^r}SLq^_Ys8ttm1 z!@J(p(lTt;?#QxOyWzb<9n~XHu{G05yduWwr0ebEq^6bhomh7mBiiG+nUl}_uu*5ehQ>Z7+!km-F&d)RH) zjb7di{fAf^RoKhAbXYb=E+=CUE^!Ocu$Ukjd)dhUEV*`HLY|{`qNAQH!D-Zq6&D^b zeeJeSa(_s&PV#k81{Yxt*NgDG<)oHfVPWC)XBq7RIN$rZxjD0{pA`P6zF9CjtbqGh zdfA?-*81{K(c>0~c^eaCH4=r#_1LD1LlldOcnaPA0}%Y zyR}q@1?SNWy;u#Iy)rl_fZn&Z@4uEJIAKzC+qBjrrk_N}Op+7eww!kGKKiTeM&k@I2}uO6jLiJqUE^*g)>rNbI>yV(L06e! zrMo(->;R8F%MTyCI9)EOc+xX3B*oiaW5IStsj4Qau<0v1rH&zyKSdMw9!6p3F3Ei#Jn(XJr+;Efy4KZfaoy)H)e zB&^UU14en)6Lz#nJZ`Sj9$e6~m7}<9z843KSCaP%WU4_n6ChkoeqGC*#_d+@T`8nC zGZ&LbhTb3e3K?Im&=gWu+O%l!cU~JIYqyRKiY2(S=ndCXx^>E@C z%Hzlvn;yhj1bzQaaPyq&3}TQdM^>Iuyrj-w_mSzzi}Y%Ogjgy8Jx_|sO%U!dCF zH!Z`^+`M>nbEUrL=%@^W!$hC@Gc7?+vJ2O|8I}XuKAx{S-L4ChIt@JWdfT-K(mK}a z@fKM4FVjVG8FH$S)ghUj)TGk>oef#O=#22_sc3EU&ET0WZ=SIiK;33zWAkQ2Ll%QD zb}lO6BD~>ssDxU4R@acGL-wvq74uj^mC}K`_`}!9qeRfm7qM`6e*;7j{i{Q2+axHam~$*jD!=**ySpo|H2sYmA4UNPE;0w5|4Dy^>l8yLzmCU?^oq5hS6*K7E&X>O zn9PccizBFGTo=tc0gz~Odpe1t&*`a)j@g{c80^+KDxx-%o)x;k^k&~-kRE&~Vdvrs zlLLR&@CLM!szd%;)J`+C5K?)+1!o0-g;9fu)E~L_ih%q*k1`eRz0%Kyh6dZZhO)9H zzs|FXs>ah8*UOmc8Wn)c6?hiF%Z4~=RlgQ*8VS9QlGGSOYt@pw_+NCrWk6NIw?2FT zX`~U51_h);x=Rp{lJ0H<4j~=VjnW8G(k%)|ceiw>bV`^1IsEdz_r72F!alQS*34S# zd7fD_yRx=6S%eD{VvT&W_=RdcGfn=x6C@HS~%GtA60L9X}iu@-#%fuzH;$M2^ez(`$m& zz68eg7_=IB5vifhHoe_d%8~YTjt_d&6?rIe-Rpi=I}^pH@nl+eWRSjKZ+li3rfwbb zLtKiVURJSzq>g62DU(Q8tDumWx~+8yusnwUSrEPkNiV|BTru`v^iMo$eQl zU<)Z$o(l*FP{`-x;hFNYis))PK6ZTlE5B~ClPZUJjptjyhnATcEqOh}%YTgUzm&{J zj5&?}L4%wNPvL)wN8cZ5uI;7KK<_;oj;f70MvVA?rm6KQMN7db9$8VEea-mlY$z`f zlURxh4_aZR-CE6?W2sB@JPXxbx3i4tAo_3>Qz6|W>?)2NQj3MVrZN#ISdoxG0IhHA z`--NlpV%CrN6O)a&WF@$`2-EIai;^}HqhJNUiR;3Qd{Id%eyFdVvFr)-~O#?f_n7e zTrP<}N&Md;C$}(a&Ih+VWmlTIi1j*omc+_f5>x7u&rcHn>|@pZ)KS=H69apNqCcl+ zW~_c_@9ysU@EdKsq1*5w?4}ImR!rwNt0z#)A(l{wv|v1}ZQlRJc3TavDy8!(NsmZ$n2}; zc(}O}lal&*tK5z0^OrZ}vWO#MA%1Y@1asKXc~EUdPmXPx&H|1F1-FGcg?xN-p#MzhJEQ+q)J2`RjKmd=N+hT6cH%x^>N*T}J+6 zW-f-zr9|qwPYU`>4c;#RQ~vf=8&0&{(4Z1fFd`RS&lOs`hAd4Srh9W%@7WlU+dq}9 z6((6pMwhkx!A30XuL#9P>c=byU&hMDTf8+8cj@ob$1H2zJH&gapaSK$5LHBIm3HYQ zKzaMY(;Wc54GhS?ZVwH*awY5Ln$lgf;F;>}MHQmO>Sl%e($Z98fyu{lc`*NtXm9Fn zrNvSh%lZ`6z+rxd&*=dJoV1g*Yv%L}W#j)-+9YWSN}E=5mFLwa zQXhs(xp#ONm(f^TyOke7oYU~4NPN5?B7jXuXn&5>jJ?f_!sfK%A7SN6JbKzQx4S~_%FQZTcf49ehR1` z;z$=z!@#7p@Yveg#_DK|HOT*vaDS^BRG>kK>`(eGBjgmLLKAsJY5L+E8(Q14le88Z z2DXcDTkr3M-CO$m`yKMd<9VdiLetaJudc36h76Ffp$|WieE5kbtw4My5?E<|SiJoF z)JyNp&GYmP=H;Yj@TNYs^9u>-)jM*Wel|oogG9JMq5{0_v8X~eL179cs{8udqj+L= zW~OohJ49&*UyZ8oK>P)2G9x$AlU+#aqnkx?am-;@Z-C6(tk~Ms*N4VYs2MLLHIZ2j zMht5Dk8B`-i~py|M||~8PEJ)-RUjQ#&#gY``;yHd`KF#1W!!d{(8|cali#lkEPxOo z_<-6DzhM8guV-gx+uPd<3wm>QjyPtD%3K9bgx!!CNnDs&FdoL}rT|vi$g{ou{h$=p zWLxPlYkrEIxlVS`o-BCK)2ASy={r(|nEz-J9B9&(YTea-W^<0Xi<9@pz{XxJ>J~QI zLCBRvI>aH;dF$e4oj1`tAt#3>{CY>g&D_Su#>%SKl`#zgw6%i?0>Ce-kmu6AwU!>Z z<|ydlQ(WIiaHxrVy#80HP2?eih;8&+b; zh^A=RCSxLSxkgt$ABA5ljGH3=;5f3DS|TB$jl#++Cc>}{jzhFohD9{b?WP@^t=iay zBY$fZ{l-|QR8cb}K$ht0QNJ>Avtas}>Q`y2N>lc{!eG!Rllo%klhO1#Ftxq)wpcoPn zBmTmq*E3lW%_N=^?QKIlD+T8G5T(73_#7W!t^SY;%4sE7IX^1M;$aOY?p+*RX{V&) z+oXqtqQ8lhpcOukg(opv%SA_R#udkeK%gs^m&s}5rYdHVW=5h2b-YL@d>ok{UJpYu z9l(sMNJQ7>QLoEPM7Q_&C{++?UvcqpN|5p% zRm_GGC>o)^mxYDDWKzKL@oh`W%je$72q|qCZXr24VtjBM+jpIFWz>~6yEBI<;RBTM z?^+Ley5Qxds@SU1bzy9(_1GJh+W%SZL5z%B_lF+gi{yZW+rU@;C?yJ{gdW?LH)GR?LzyUA$*#-T20WBc1Ahr6hT8;35;_oA! zL_mH;fcT~H3JdG&>%Xg+yScfko>L)F_nFt-& z*?|J!-at}7mQV`HoV_K)Z=&_1LacxmzL z9=Jp);1kR6(b3VrH#aRTEZFydcN74=jSVD+p~91Jg3JkPHSUw9*Dc0me*M5nsn(Cu zV9}f(kh|XAIauh7eVVfha?aj^nxy95X+6@zTLf=diP>WIpWtPP1GpbplO-jTaSU`N zUWQ<@qfS|Ipz;{N{NO^m#l^z6tSRt|ZHjVi^F`bV$!17PM12 zps;Idr8c$#+y8)6>nMAIj0VKsxp#<=NW-N$61sJw2G@&V11<0Nevx~drTgyYZwHJ4 zLD(R6#z)1)#U&&ps22yJzC;h~obi8pC`-LgkEZ^L7|stDtiJzwLUYpF3`Q#;ekzsq z^#VddjX(sKFETc=3FQ=$_Q+JPQ)fV!9Am*IiooK92gU8@27OGiIe$7*s+e{Y))t^5j+qxB!7tbpBrXwc6oQ2p z`BNTd82mEbpB$W=RkgL#m*vaVhK}Jy{ybnlL3Vdc-&cS673x zDO1StE9X2PH&$?ezzCZ#?e-`i!m~!6ROp zZd1BZsia?vUf>ww0KazXIkp$M?0AE9J0n1GS(U_k7xoR_{VMAZ*~PO8l8;Uqk8oj# z-+@S>gT)hf8p9^KkLPNdX8N}WL-yOS1wzNP_HJ_9AC%!T;)T!F4J9%wzKvA#uFLF~ zIR*hwrlhN`uFlKPXD2Y9sSx-xJUWUaWTq&rOhHQeU7LBX)RI=PcMyRT_{1w zXnw0x@TEF1lJTJXa7p#gvd3r&c*REP`eYXP${NW7p=B&WmefGx6J_~js$kMlwc1z- zhIkL?DjN-E7bzVGQ^`ai<^xm!BB#tK3&|7U>MIlQ=o;nvxtD#ej8D>cuH)5 zKzjk(f%fYz`{WR{4*x(RsLWiEc$1y(Ft{cFV#x+#-xET@7mK2_YKRrQQfesW581d6 z8GxZ8;2Fc%(A#32=F5zO#i*-t!Wy-S47~t!Lu|VB1u}R*YOu{fm^#A& zl;HC5xp+7^mfF1<$U&eOYMF|gn;Wo$^YiNcU^h5Iqy>*lt*7O|DzMbBV`Px)LeIbldw0lcvQc<1{lJwl8CR|8t+mnWU~w0et+m}@oHx#nOMYu-8~%$j zYai9G@zLhKhQjfOWYpo+cS!;H$`E6U%t4xC#Y$?K$56Zx6GxUFZy_qi z*D1E;%nuS?_+Pvwz|eaa zd5||MmPglAVNRM(fx6p|J=@kJp!7;cM5{ zt}&oR^otJNozjHTp+3zb0s=Pm1o{Zd6iQ5>z2MljE>_?5NxJ%_%X>l=pG_lB!uAs_ z$K~P!IOn8xys+3e?l=pz}|m)WX&EvUFH1Z#0bB!=BY`yyLLv*`&_KLYB!s59UuS)OpV$oD7!4%^ zx0J-+p4IvqR*`g*-vzyB(q;GhAjEyNkW%~H^_1qXFrN`L!C~f5IjzOz?VdHf--(W~ zfDf$5n_nqeZ1GuR^T*<4On|#I)YWZksNw2(jddG6Ts%BxT^S)vvGDjvfVr`(yR9^) zI}NATA70(O+FO$TtCGdNj@^zW91(VQxq*YVz{CE58~1DfdT* z>n#w`Af}{bWFIMJww>9|zP@!BY|hvGK4JZ{0xb(2sM9DiOt0UJu%oX7_X2}!_}^73 zBv1#I+OiCP$0e7QaA>I1ccDGS*mCN}i!$hZvNmD+mp~wdplBKx&<*!)axKh13i1V^ zUtzGfs`Fgw*9-EVzI2}y^xTh%K>`T@^z;y4*9K|l{u zIHQY=Rk92xM$}y1U&fTtqTg|lHS?QoZ4xF4j%ohim$`%t@~Xsapdi_C>S4d$^yAQZ zF)^Cq#U%Zlxspr-6dU`A#lGee5mB_aG*$VD>hZFyH0T2hCNbE}du+`19){%8V9b`T z_wMLz1`1to?qju}(N&LY;^N>vx}56#K+|VZ1F@@HRevOzC23v-5=roxsBtkDQUE;l z7~v|qRK36Obu8q``phrRZwqLcTdPVReDJ)~-=pCdyyqu#o`a8T1yt4Mg=oLLcm&2S zRCWB*Ea2)RL_iY)`qzo&G1Z8ct(_e+GxN;5AQWdudUj4u37Fmo33(7y+`+E1H7YfG;V1yG)>!C;rJ=;1t(a|f~J_Ig~TiPnDpoyJmz`p=fxwfgN@dPXD;eniga$QedfZUQ^*I7)Ups>=MTOm2T;|fi z3(q9J$-$qF2{KyOhku9AaU6UTfW*Oo*Hfq9hkRJ22}9rjmj^il(D{NDTOuqN#rUV1 zQ$SW-Qv=wPU}s&+%(#=YV{+w_7T`n7GJY?1T1t#XUxD5L<+c}pnOz2A+fNBG?F5?M z-rnBoYIcAGJmmR5M0ML5@yFoD{$UOC$SIQH{IObSrv7)piy$rDBLXgFX1NpAMri3z zTg`k?^hgUqT}$54B1kRxwR||F%ajk_V)$zK{(aJi$6phs(DALl&)Hd238#_iuVU&R zWWj4LzlPI-c_ldbM}QV$Thrz;vX&EKSx+EJONovtg9y_W zAc&yEU~+P@hqXg8)+KPQ{TY2I*o6JDfHvjdQljsmyA9ceMHL9;hqg%dV!(lL<99>B zG=Zs@D;wo$Jhwp(=jlnSgD&|}dL6a^xFN_Kaip1y2Kn!>@qdV3q=fMe(nvzl*ZQ`4gL57LXb{!E$DKfir5 zt|xe5Su+>?zO5EXMbQhr;Kjco112moL4=KceKQ(}p(>*{OOWyGi_9lc&W~AG%izDZ z9sgYO3x8;~*}>WQdu=T*Cucx;{vZU$7CZ&#CDCW@>aC(4~N{-m&U5gulLkG{g78l9+p07tzi`32(Oj&z?HS{bo zwl@tls2Xbx&T3n^m&4r5ukOSAM+L}w*-P?&Y^HLh?&h)B1lPtCzTjmTd{p=cz(l<+ zGq@|bH%O37A220aIyyE#v@d0TBlK`t)y&}=&AyXS&y2_s1qNV~DSWY0@X;E<9RhpY zJd-VeR0)l5dCVOiD!aoai>ybAxSDEHCdOkP0I0w%OtgVmBb*2VtMR7~wYK{2S3?N0 zTn_~5c*7Czk}uH~ZBK8!zwIccbb(Xq5Xf1}^)){qMSXpJH3__G$iF<82%gdPy@1}|eqjOxX zTv|*Ertqg*9>EOlR}Vz>)Qk+e41^TbrWK%ufQ0=+ZZ+fcX9;QD%7W3=7*Pc#W@bA( zyP0>0N>3ivJpBXVdD8G03jjy)<5&CU!(Wj=a0YDhX@z;31^~^;Ar*xW?K@2`EzwQc zxw{kpO1=zB^_hM}C{3)XrKM$H0PuJw_4uh1LM-A#*HJ)_XJ%eWSmU%#9gAX#{!{@A z+kQL1A0^8n@^2>vVT-4Q0Hix01<@o;S^Ptjnt9jxOq5Xi_4M?#roMhPXjO%jlvHWl zU;iNZ!R^l-K{)kjg*8sL#<{a=0cKF}Us4I864wr|5t$*3EkbNR-1cv5m_eu5&YCtU zUsJLdSaBo%AT9KJp4CKVAgZuD%7X#xYeg`C#sH(c{PGh^PcrZ`QDu-}km0tifv-UL zI>Ckd@QhzT00NW-kWZVMBX}hw>qcXqI$l}CPm_YurBMhi4~sWp_43l~A(Kp;#&Ik0 zf@qSMm}pyLEDri;`|mgn`P?#(G5Fx;MF@@D^wTX&H=>bsSh&C$XMijt?6MON!U4C~ zxqr!{uA2!mSO*H=!7@)*uz2?l6P)vm1g-<(^ti^ekxp=}V%~D`Wwf>;D_o$=ctHx$2q!wpVU zzPw-q9F_n~Xx}0-xeQ{mY?YTv@~HI>`gM95C!`b9yl;XxTIWU6*!FDbD^z|gaS1@b z;-bVr+v0FJad&neM^)0-;9bX)H+y~l=V6g1@jpUbeQZu8_-Mq8dcA zeJEsV_j&iAi9PYrhWl49@TjB*Q3BxW1~i3Z9+XjmbOm<=YpRUpTBdoQPiZyUrE6haeBupUfgx;ERM`m?;FRX2)B79ZK6D?V&kHZE zZu31uI`u-o7FBs9H#UqQtFx!Qq{n8iLAhE-y>gB~?Az?^eO)|JWXsMG$|Dh4lUUIr zNR|Drau2jquNWlaoCrNP!Z4A{Qw;Z1_*jeLvYw%TVfmO47d_<_1G==g#aNK@MyF6k z_)4;vzva)%+(#!V)FH8o#Y{@VfTaMg62Y&-K)HxYwdm0XFC7?KN1y%HEQmD6Q(agi zmlOpnpo6-I^S0FLbC_)5EL&vUu8g7{;eHCsGlFP^Y^F%QJTJoI7KUI(B*bjBXiG6+ zs*Kp-$Xe)zZ2bbux+*c;aj=`lixq6;P|KMUE#021T|U`;WfcvgyZMmDUq+NNB)SxGrw;@|sl zn0x5f@lH|@Nk~Y5rgt^W`Gj&2`>^jBDK#2Ssi-h>)CM+%XayP84`MZPyNmjK&%2`; zn_U!*6$(YwPp(<`qekfLiS3wF+GQ5ju#Qz{eCWA_`N2!DjoCVu2v50)W|Sy*`{WRg zsX_(cWdnP(Ps_CjXH3va^u#u}QDX(q%xBUk>EmZZjKKmEIgOB&qrlhhY>Hac?5&l3 zaTVFv8cI)$yBPWdEq_XZ&Q{Hw0I~-%HQLANN(iu~1r<|;EIw6s8CXj+QN4y<@3j4} z(-&!JUOuBPbaAHBDC^4Rdwu>IVGlOzUtzN@)wAgq=%wDDcJi~Tic>_yAig6SF|_7> z9oVs=WetZ~n>ios8MF+*Jdk!B&pE|?{mqXX<<;V0>T|yJgjH`#}j;&UI&MV!vh2OjFl#EFi&J++v321jz_Z5XZ8nr zePD6ofCVa$mqDBhLbr1jZD?f*L`2e~6^~BEK|*v+iB%jiQ=rYTfeU{!ef)pF#NP`* zO%O762v@QH|DG5c8altZ!+qo`_^&sZ|D@`E-(2&ziS^4>sUmCBvHwpJ@}{8b!j5a9 zsZ=(4e(`Bt%JsPCrej>uj2WO_56GX-U+-x;NH$Q7MdLl;6`@++sO*Sco1YSSgJruN zhPC8v_57J#^Zk63>d=&Gi5x{qClO&VLAZ8hpdmq0({1@3SlPPV^d@LJ%HN)4 zs6W?h&-LxAErT;fd|IqI4?%qJPbFHOZ97>+)-`h>@ zv~=8R8?tXgtT7dM#^j)2{^SJbW+A&{7(I~yI2^H&3h#t?%m~44#(5iTOFaUx9&B4~03%eeEGndE>GgaZ-k0c6w#OM9b`13DX?hm4 zAw}lQ9P!0Mnd$lZCHUOK3;Ejsx%VP}YnGk_p3MBc(DA(-X9$XvmnQf-OVW7Mr!(%| z5KH6J_0K-!iKWO)_jwTp!_R98tv@Ohba#!29roWvihVAQ$^1YC6h_7Q`S!wVoXpi< z)ESiwO)rvevgY^@1R{P(HbJ{G6GLe)kK*eXZduUpM*YhvB8SSi_~&ZlLgc)4|86+Q z;^rLdoZS7swcPh_@%Ou&we~ZMgZxH{%dv%`?z~83)g|&*hf-N5Tdj|R_?;;Aji1r$ z20qQ8V*+63Wl}q3m(H_!cP6By+}&Tg5U!gaU*%$5=xJ62Iw=uu6?Qc zE`V+uVY{^zjEe^;THZZ4&H5ABjNE>XYp0E*v}a*|tjq>oG}=DXWnb~-#dgDI?#>u4 z$dq2bK4FzhT8>V{8B^^pHHo@w*fe%?PlB1cHa$f>&Ol`4|%{)$HLA1i*|kpuSlUa z6Q9y{=Y7^IBGbaS5(um9{9DXLwf6iBUJG&W<8`6jmYxs+D-X(yxIWVqBqc_{***My z|DYM8{0%2}cXtz$98-TXEZ5FCAOCyQ*gs z9QFW36<6>AWY8HKY%bQ4}W=U7ke$YqPNrLYZ&swq8 zTIN=7Vg5L~|A}n2jmKMyy^WE<-Q~c7c6h}B_8{FS4IR!lZ?}GJP*8PW-nJwiG#%W| zGdE)0ovvFrS6lcVZ8q0eT^DW!SFR~4_*^$FhP<2AZTQptC2A)o@&qC)M2+;L z??o7Vug-GjizeP3pguMPK2!ZoB3d~Jd_nAEN<1lnR9QYfn@cGF!xC~w8le=lqLL0D ziC)5(lTR3qii+CU*kD+9k)I~8zZfWij^q6)n+hx2ep9OPGVYpk-9cRPkCQxAQjcT< z3ZHWt1Ivc*5K1KE4+Q+TFo=$F9Qzd8bfIsj1UE zZu(R)Z)_+p)q@xJ6TgR!316I3)Maj;414E4QK=&JT8rrievG*~Q!aFy8q>IMmvOz{ z*?r&N-Q>D-H!LXQYjsmY(RerYcZ=+MQelZ46AqG9E+|eE)-|^ z`#;itCr-^$d2F#!^$T3ow68{6Y0_HfCSY!UX2SQOYFldRD33dOLn#f7Dny4`yEN7& zP)Q&n*u9Us>N}@2pU9VA1BIW&qmNb^&%e|xe0QH4%&5QnEp4CQ{Qb@I)b2d5{ocDb z=FcrenE%vk7PnrwTG29*2&`iVg(XF1|F#W=S^F6yj?nu*dr_$cqMUe^8NEfTodJOP zSm!1_4{F)k^l}b~9e!>0O&o!DNE0(>WG7X*|26de1CK5SU}X7&TfM0{7gb0tIEv73+SdN)okB>PijG8wC#ITR8Ip%@>ci{9(q zj_d_p@pzvIonACHa^8wFn2kkk)8KZ+H@4x)(U2 z07wTA;KGBr1xRrY^HOHIaQ=xB=3{eI7=j}pzc4vg@w4+7gkLJx z3m_U$uDtWymFeH0rb-+W3&xA&d+4?}%>IL|)C0K%C>IT%w800k{EIvN^BG-qLkYuf zgbtDcaZSVjFgDbyM=&x5a2cpc8Vurn^sjgP4`_yV!Y3dwcX+{!y65KS7NCWKj!_4; z@wsSV{E#Xmv)^>X=^w>wiM7$_FtS(ClG!iWqs-Zs>BoY1g8EMe2lTh&<4R^nGC~-` zGx8Tpn#qhc;br!&I8cLq-)MmnBOLLXN;?Sq#L7Q*cp!4a$;ZdX!lFB|L;(`Y(;)zU z!;DRxn(`Qp&zSqVusw6yG)D@?9qe#VQo59Yi@|mtnZ?pEu0LoTo41gc~CIQg;FEbS?afbUE zoYP^#54LM6O~<}mBws5;&N8Am61(M(r#k-*HJMg_?a6p}^#R5W#GXpDxLD_TMD6y<->wl&$7FM_ja;px`UpKKA>9) zux^FL4m*nr?|;+=pFAMYp-x5qr;+pVsI6n}&!CSK%jR_UJE(rs&tnYt($1mMu^;|8 z0{lB215L6YmnvgB&`W#u`Z|QE&qCq9dr-%oNOQgaa@#ph*d!IzEP7$T!%S0*O|VZkEkUrOuzB)Tdu77!=cYBm>^HJmXvrX= zaOtCshAk>w0$zv>4a7eiC50NIoY{Kbd>7{}VE_L2;DBdURecqwy}1a5m)HQNg@w6= z&mYf2fy2g>MnVk@5vNouF9np9sMS!6NZTigG#1oZl%J)%sOQGF8|rJ_&ezw^UnC+B z=$RUtR#lMl;h`eVFskY++=sP1X$F*o9a z(&D0h)9Rr6CcSX5kehphiRHUI)C$csj`*K%_5A+xDlnEGx!*sWnS+0@a9ZdA?Jee^iWS7cF%p$jpi^vKf))&p zSO{9cQf3A3E)Lq-gy`sM-k_TjW#EasY{dANt!ZmW^P6YAj*?ja&UXJ@o?5!Qx#0LK6r`bmi>Az;LoKXK zyW@J8*nfdOh0{1~tBKj>=_-ZvirYq|zw&mH&}_u^?|w~(fmpCZDKzt+k6<`Lx#^t%&j7K?XSK(*v1UNUzN1n>6tf+Ki0 z)cPGbO3KXA9@`pKMWf|Oy-eK$uRKXNxDY~eEcplfA1PKpoq>8C2n-9IzuNB>@!kJ@ z!_yIXSrC|375V;ygqlP%yXDKFUZj_-@bj3z9Yxanq{Tu1aKq7>;qz67lofS{6?!;5T7?Mxo#=$mC3^Ix?Gn`{ z)qiC;p6ML?tQNv3QM+H`%qk(kEVAs+daSqq`=v(5Ua-xN>yd+lKR-imVo3pZ-WCV%m#I|1fFD7tim1v*3W{RBwFIH0E3k z-^e9ruq&4yfcW9+JF&B{R)1R{hpg(OCL8{Q19q&y4oZQ`R4!-l9S?Lj*YC~T`@~pY za(E=%!Tvw`+`VWMe#navbm@f&JBQdQ=%A-1IM~&^PfQX?NxDqK))^~jiA46%BN;_2L?@x3^Y2i}gxxaHf6){N9ffi2gb zwm@6~263}5$Ev}76K}(KM)loowTYRdP?`|tk z3uOv~ps_LUkPwj`IWL7!=4}m%t`(im*^R-CAIG0Y_28=r_m2~%Fi0`TJKZcJF1Kp= zxyFf5zm#yLZq#1b#0cJZU02nx@YT`ZhsPM_*;g)mn>{C%x>h)RBBMxkQON2nQHs~~ zrofFX(@frT;YPgGPDfHZS;<&hs$d{OIH5HbML0wHi@*}cB{B2Y5uCEK5_8~KuUMd{~kP`YtUSSGH8@icqf|2COg`U$<;XJl>kmXc2^*XWdA zGG39@AIK{^x@+sIfIJ=RGqQf;^gKf^)AuU)w-%ZciURD3221r`n30J#d7UM!kSD754)UJ+Rv7k&!AWLysWDz1#XEn`=`Y< zq${)=p&M^tu-KviHfzBq%oG(y#!R@+LBco*Lr_b4W zUNSaCK>wCUe<1?(Tz(!U%0>A3@OFsaZ6)c!J4?^;({WE(ZTrkC%1jpldo>Labi6)I zWh$-`fjldw?&Wb+hRs_V!W#o;{W0T`sGuP?%h1p>Bg4{g+>AKW(qysRL&j_@y|v%w z&P*XkBp^F_b#4YufAWziJ_$FsBeFp^xRYFeZt|V9Gv@qb{1gV$+cIP3Q#D~$1?N$c z$Y~`@96>D`(|)ScfzqUn_MwhIb2#tbo%kgQ@BBHGU15rL&+wpc3gxBT_^-P<*12b| z?d=72HH=xXKTHaZvBFw-umb-pjD*GbU#b_R@$7thhyF#wZ zw{k$?`zC!G9h$QAek!iIb$>9fi?U+L)AaQDSn%H0Yy?&Z%$K5OI0ua@$;uU*aj7Uy%lL=<^q~ZVLbZQqs>1kTU%D5OKk2Wav*_g>E-&0?Pt=P|G^Lzo@5Ky9prNGsgc0TWECg=2bH;pswIc z(FG;Lh?4Sh)(fi#2;$wAV92Lb2}29${U13~aAosti|UdE?FRhDrw_(;7@L!O%+Lzuw;|Pv2$_s-7ZHk9i6g z)pKa^H;QK{c;cg>s^F#Wqmz?wNl0R7zZK0?lJ;p-i3HGd!9ZKzIMh;~;bj{_ka3?U zf2(TE^GS-`(c-+dOmD7|-*CJ+wDE(3gPayapfc`F@|#!TXm7;BF1RCQdJ(c4o@gr{ z5{R2n{I#X&j)2?mtMU}u(WFYBf*(F&5WSmw)-BSRrvVpDXAn+rT}w{JMMya8TK_)e zP$kkKUAh0G=JiD4Y>r65;ANM7yD=33*R1sPbBXVpTnJdv`O;&E{H>fX-Bgrb*z~hU z;gPy+yG4#Cc2s}z>2l&oTpK6;?YJYTP@~JzFTI-=r{p!5hnnb~T0?QV`0n%R#Ap5W zM+TvbHQ9(MVXSz5W><^9DKAPcqq-6&Jp+R>+D<>qQR2CQ*f(b=zV zEIA}$z2Obd`_&+SB>6}Y?f--@mb?e|v>Kc8FOd!ho_lZEv-z&l)k<4(ebIk*k_X`~10hYWMYXd_C1#459n19Oa)% z#Tb}P2Y!$0l+R+S>ni4$ic3m=|4qDj3O&@>Aq)LZEnV+($WmYRdlqpiC}+u{eey=c zAceTGW~Y^+k;BNspGVd!7^AcqPlhe5kX^TaFM)am58saOdsgv6+V60B^V<8Z^>dJP z>FDZFgKdIAGD8iz=-Aen>s$Ff;Xw3R!TD05YWoxM0EKQsXXLr2Ckf3gXXHP@&)bEk z>It8I5l^Bz5edF1c=>6=?YvZjd`9Q*N-Ga?-3#IHl>5$jj=9FWy)=wm{jEWau?W7- zzhwP9k{(WipDlGQ=*x2}n3t|52e-@TogF?*kZmS(y_KhbClSI%4kk11S-hrlR&zsC zR(37#0^Bi|O+hKe4!r)b$szt0tHOrP;OK5{{DSc3nu9XB--`_F zf+y)j=;#f~t8X>-u8O3y-V$SsZe^n3F+gs!1Z~+&hGmp>g$K;NXm%29A+DMTU(HNpk z`Gil!H+IsCr+lEL<>y=vnD2N0J8K);9^F*kJSeg@@fPPb|3vuq_nM8K`UT;WKIEGC z2BJ6HY**v0NP8 z|5H&K(@+x}8=V-0sK0k9s8M*T!{8+{^L|o1pMxlS@l9S29zKrt$B#LU)Zs*BOU;*x zau4s;5BPjYbcKcBcMB^1GHM0-RujxG z_%Hu&OvS$BukMK_6)evC<=XX)r^Rzux1XLI`*tZq#)caok)^jc^E<+?0-wv(%%y|n ztX>Sp1g22vzFqwJs$XqV%3<=&PD47XZyKvzNL zohV^&z~lFd9-w2<6yh-8(4Nu@wWP4H9~}KMg;63DFobo{Z8X0%*rbr$zWiDY2G#NG zea>zNyUUuLHm>J1^gV9ElX(rw!&9woAy~sGP9?`G=vYGIR z3=YLq*Zhu+jtxRwBs$)9rU^^ZIV~kUR*1D9{Fp_OPK`!b26DtZJ0Y$p2j(vuG6Huy z%+i+%)*UD9JCL=rxL&*OF;z9cEr)H8CIu199o+D20iL7|phNsWk(xw* za^_ZD2ho%jx!lV}J7Q|4?@*mCsHBsFgHoaD`daCyFtnVt7>tAhgfW5Hgg(CVU-_S^ zJO<;S90pF@zeM>yf{&j0CYJ=#h zs(%8;Dn`gYQKJ!*HLEoF`ZlxYIt;Q2)0wUwowNH~PdrLK ztbWH9nWLCi_j60Giy|s0%=PcVbL@TMSC^7hI|ZermInR7(Co%PxY3KP-Wg&Y=K6F4 zT1Q_qVfat_x6_;;T=i?z++W+Em@GXlE%Xi05`vqNrlC?xb42tLJ(cP?A>V%> z>NE5)#Sqf!?w-ln*kHw6oe{010?8>9am6kI4R0T>7kj@d-9IE^dHY2|Uy(Xu4Jp+h z9;w_v;@!4*vbieyx`Ln2_|j$icuOsF3Hc_A3hXHqRj%`nPSpY(g!q0kkICi#IdC)B z++X9&p_aS}>^qz5<|Js1tEq|ElzWjfYhvcs@-o3)9A^UlxMreGxm5V&*56pXGZK}x zyw6(AWE|=;7UUV*{dRp*m`$=yJSXI3jEtKA9d_M%G&poZ@g)#L&%;ck&xr?Ga>AEi z=YK0wJ7$({HGM6^5 zxdS&uJD&h)h^cXd*XcJ+U4DqzdFb0XDGtX~6HRfPGKq1LbG{7oj^^Ea0U&pvahe;>5O%j+hTK4|oB z%nIj7%#}q-elJQC^LF!Cy=hVXcrnr_{`X^HttO1Di*xF;!uqBQzjJ(D!`k2`V&~Hf zkZ>RwdWI^?jAU5#$(N*3@iC8=NW|{{^k-8;LOf?SevYkzEnt~VM5-1pA1d& zQH=QLk2*@#=NM|tN6BIW0QH~TAm7tbU;S&1tW0_OCeJB{YrfpSZikDUDhbjN8Da^<9aMKYG2Dq3;z5_e^A#9*c3|X_R%no|C0xkO$=(EG%E%R3ZP4)Q*0H5O!+g zcr7$&k3=get?3jkf!`137^Xl^sKX=dwNaIE`ASVb`CE&?LOsCUFy&79xkTLOV157I ze$VO}dtcK;WdrV)U7aEcfuBy%rJcLuM}0WJCvblBQ(w@ z4)xhsdFS@U%Vy$aY%-$_K1^jML1LY4EJ9Dxx7{1RgcsFT#(+_<@WoW-li#=`^a2RXEn|gNl zgz3(lWF?TEieKe1Rryb%vDSE{FW$Qe(&v-DZbyUu?|`mhPM?3t(N+w^R;Jt4lg8ZE zv){TJ(7GBw4E4jY6K%S)!93_t^k3PyU-v1CzuP!nKL27N-btq}cfaTg=4Y?{@`EuZ zZQBO(d@S)#oy~$`+^_5FE#x{Kn!Yrj|5w|WheO@H|4*rqO12_nOQ3B_y>~Uru_Pc{w6-5srJtuz7}6^WbEU??>7N;S@_9F=i54O|l4(J(H66 z9shlohHU%1z()qZVO(SU95KH^F4xlWn%55HRzNgLg+1r)hr7S>j z^}>uqKA!3_uEfrK`_q`@a=`X$>GL~>X`ek^{U{PpF4RTTH@eSsue|bG#ZJ@o*0hz#$gY-mbcn^_ci6tS{a+g`NQ~k&J?*;W#FGo zOBa(V&FZNygsxrqK-7Ay9Ngb5fkfGo#q0B-_h}`URomfQT_iwXLgvuC>3CbbUwZwY z1U}HfMPS2=3~q10lSzzMwQvJBWchAWt&W5i{q^atkTf3DTGLkioB;w6M8704`+z6% z-r)S%`c?Ao^m=b^R0UDrc@}lMYC0t1INYV`?dgvh4o*^@in@rb4M%o5JUq+v-qcfL z$$-{X7txbz@4EMh-|=R(S>!{k{&_3 z{a#W2(lj`OGcjoCfoLSZ#^b|kmKGz!3O@Vk&TJI{9{|sT<5vnI~xe=^qflY)I$a{w4e5oYLgzSVRO{c zy+>TOd(VeMsdOs#r4Qyvb99EIa7wz9i_@ZeDGL4Z%2=Kd2r&v4xnaAPM=g}d{y9gw zm}X?^8ANO8gw*LfB5dhiw$_KA>Y#s|$xKx1)6zOgzo@N~~{V6&T~6AF!FtoF&3m1n!q#i`of9xX3! zy<9be-@+N|UO8TI;e*-J6c)Azf9AWsDHa=sCI+r%o#p61$CP-^0yr4y3m+UQjv$A= zvxC3-J2t_rP@32mt;J1X$O@tnfMvF?{lcu;PNfrCM6z#wcK{oG86 z7SutC1y~2Jpg?M>g>s}cv0BY2Cp!)y4R1!tsWmCTNv{&a=zB&W7vN`ENH=h7kd^RF*tZHV0e`7i?{^gvt{L-yCbgpKrBWpHj3r(sDHXT7Gh@-g_3 zE~x6y&H_*$TNk+C_K@p+xX2?~4QqpSyxqO=f|2;Q@539Ylah1qXI>rwsJp!DCRiM83;f& z)$5;7gv%FKW->z{CXMy?r2a%`L<2YxNX3EKwIbe#;C-d}-StK(ZK(-+I-?#x;0B*O z`#mcpfXGZCxY8IVp+?=)!TXCoj@_JgO!#s-+o>LM1)5&57O)w-&f zf6NyXF@vlg?X>r6p(^jx4MTst`c;Z2rtfb2${j)N`-3d9nqb1+T*3Js&=<$$(IROu z6r0?4n>Vxg-5&xF!5|x&@}LRG#v!f9akVSDUx}se z^Fn=Fws00eOLU}~0iQm(B*6V*J(tpgJ|1IRh;!hR)hUO~zx&k0fr1u_yREt4mEE4b z#R*hg$1dSXf|5@~VX)G@;1u*m^IZg|XD&%&I{SXf$z*awqU+UuOP@)A5@AJ3w45)% zB$?$JWa+_rq050y$l>jxo80I}y935iP*YZPJ@D0h1g3&B9kr?`_|i2dH^p-8lLxMu zgZ=F2HKu4<7k0F!Tkvkf=i)xqG0tSOoJir6FyYEiujQdq%+>^^-}F=4rhkn8;<*?` zo%Af2RIC822dDTYa-xGEWhUT4(3LlWr`d( zbl_<3c|()K;vJ)gFX4=Op84D1;VYRIj!|q$fNED-)(G*TS=C(|bo-u}jZ60-p<{%O z*o@yoIY1=+yi88CCmH3m{rItR?mNn&0IK@gQDOII*4S`AQlj^jg~6%8JJ99oR)%8RM`E|jw7x&Xr9 z-QYRR-Os7Jl|EsWUmsT8)aBszo%D#Hqc#8vf|Rm<3A3M`eo?+!+|0lfsWu&Be1#A& z5kx<7So;azJWE!h2%h$Kn&1e{hZDxmv+eR_c*AqJp}_9bzx^GCU$6=q^29?Es-;4gQ9O|w&#d4NIEDq_dP3o0uWL0beYHfk-@ zi(4cBzSrPAqqz~XyL+R>4->Gmj#(YTuhoF2TK!;6yg_QT5}-HCkR$dRk!#U=lFndG z$8NfxXa-(=3@LKLk>8U}anUxoXlWV(;1VbAS(>^;GZ3(fESd{vRU@rZKp_Jd;kx+; zn2f(@V5fGe0ZrCG#yi{fNFFrC=J6!z+vbC*a;BSqjqQFAeo@E3PyM#A_0C{Mh6j0nKN@ zBvb>npz@vRhD>cvuxxJM9LEB{uTC(D(5hU8a&rd_Mx)TMq!x?YbZB`QnW&y#(5Rd+ ziPSfyg?R0}o`h(y-@jyHXqc{h`5~E(HC#K5Kh8lg_Kdga&M}`T04_ZN7N+xu^m9N^ zPLAln>Y;Eu^$Q4ld#lQ`5J5>;=~22Ho?KcfY53uUl}taqZ&RSD;I!KEU*GSVok)JY^NS= zWQf-m+NEfNj#XM^NPxzqer)xYT8rCGYil%L5KudEUK=z~>>5s_)8?iC8s7s;lII83 zS6T`qdO!r#?WJN{yQTZ)Ux4ltk}p-xKp?CqL}oXx1b}FOzcXN zbJBy%A{OJ3u`x^A-34D#xY}E=ZGyCfL*@V}b(1&*I`|WZh6wJiyh`-OpXhtC|&WnM50H4+u?%NV5nb?F(c;B{1a zXI2*>hNPtMoZDb>FgkE@cR$STxVyBf2*3b$?jYbC3z#@kEWg@O2!sPjQKJAL`b7b_ zP&+!He}>nX?(lo#udY^|Y#6xr)g$0#Dpswus#{@ByG-t|-3^#OiWtj`~>k z@@8cv5DRt^6GPygdXsAqNQ)dG6ZOo^&F~<%$1904O&<<&bNagShlEfEoYLYexoLa_ zywngr-hL&Q)SUNuai$Z!fe#LDW9eK3@kRIrFu+(|e*XO&{gy)^C4RTo5w2wB)dKVB(D$%O#*=1 zvCl+sFB!pJ7r9|CsmiwvE3XJMiu95)45Wm6ujCHgzOdc8ztPdD$RrQsL0lS4fB1aM zjZzacL&Iv9&Ht61oDOSZS4K>j>N`>^{nouN)ckQiBG!z;2I4b2ln8|cO-;0 zPCHE}w{LQrz%g~m;uIqzK>oxX%WwB_-8Idg2JN*D6fv6GM+ab8jdS#SI)c4*$FQ2$L%BSrHt1foSRLR)RmH=A8hi%G8sK%pm<@?UQDdjUHz zdIaGAALk0qr~oLXm85U9h7~A4lmmT@&;zjeXrOW}7Zb&d#iBUijzXQ*(R)Mo(g4mT zND31FTvMjOa2zm65v=rE+uq*Z&Q66BFVJc?01^Vw&@Qy!U5(^`p4r(9_5C(Vxd>6S4;SO=K1<bwwO!QCsB z8r-`h#y~JvumqUGdkru}{BVt1U{EfqLNBeW$=&sMs9c;{e+BRdOYUl=ND& z*XsKM7^Z4E;4d4Jf2#!JSMLQp1Hk#P-38XZvJ$mFeCGgM_jDS0aZx-W9!P*VP*kra z=U935kTc{6*#)Q2&%3{$Jd$yaJN3I6n48(z*^I7|{KCRImaM-hxm1G$ZQ&%UQ0E#) zp?4M6x-Za(`*yj_7xe+qZCF^C%`jNqDs_L}**iK0ofBp3xpUlE!LDeql0uZf#s6+m z^z;7CuPdfy>f^^C5G!B?A7Ph-&B_`1VA3JwL3Y1hDiW z@ETq=e3zRO%M={?@(Z8C>9f`2K4yG!2R4iWusixZvTmiL<9?|Lu#&M2g6ci%tE)6t z32{0=5Wwzv>4FkClJ)x=wbynHNJC*D84!(&j1XSEKO0ZfkrFh&e*N0O;o&uzr%!dv z;rF;9Dud6Vb#YE|-lZPNy{)?PI5(++Jr1->^ z6$dP>Qy#o=Wd8ooSv-8_qGMx+`um-fLBvLwaRkjW^!YzA%exSqQKb*c+KZ76^B-5N z(wis8vqz2sra;brQGh^%0j?VWjk-CWik)bfno8Xwfe-++cG%p>g7_6clN{{Q^yT_w z+lWTglK}6zW*SIdFoo!W@bpyL(ao~{_E0RUb_HJqZM~7AYln|UkiTVkHg(&DZP`EEAD{E+E#EkBVNiq)QN|S$3@~T=Ko-+_^RHEsChtKf1VXChR ze*UQ?b?(>1Ys`(V7|9JY;}L=H=E9aS;0jwxvgL5PwO^TwyQcq%w>C=Db=>e?24@u2 zQ&5>*%EUyniC7lHTXWbJ+tZwk_K)FSllSDVu4Qgm8rd+<#CQ|%A0M9=2^g2!(sWn4 zFm0i&EPJL+U0PO_v|RjjIKQfhPBg>#SHJZMaLR)$Q8^TRk2W+GM4~m3z%moUoJ9jN zI6K=HZfzaiD%vrtAF`lsLqDevYExnJA1PD+$Jw14#mfeCrG!QoPDm;1Z+ z8!jR2{w`ZuN2w8cxWWfoh&dC8M*uj0a0*C7?D6?St_#BvSC;xmMqd5&roE8|T@voS zq5RX6P(Debmf=#C#Kk1PPPU)=8i;*VYYeN=_oW^<#o2&pR-Xrb)J*I;?4|Vx`Poju zz^$3>vKNh7+|6D-rs~#ubRjT!k3ph)lqKOlhxcPJ_=3R>&GqwDDWs?7A^~w3#zJ?q z4@0~zsl9|iHmywv5?VybFR1ZS0Zc>an4$Wl=k(PjaD{0uK}dh50pVN4Has0Jq~`on7;Za>VK2+CJ##5 zYk ziz-nQTn8L8BHYLA?XBF!nq}{nw)5=veQp*YZLd6n-JG5!Wo;%Hc%1q3JjjT34D?elXX`fed zTRn3xrel31*vnkj^_dHxoknhRj8guMCv7P0&SyWR+{a$+tU4Ljl8lp>9=J{22d4ve z>U2H~#T%@9QofP4I(k9gpj4R-na_D0iN)L^rp)WgHRFsTs z^PI0Bo#xx0Bpb42FVKnvn6%)EzvGEGEqE9XaclR69B6^-b?9FlTN;i+=;0Q@3u)6s zIGq7Du!_yf&%rh}Fi*;Ngr5=YEx&*j_WZ;ANbJrlN4~&8vC;Kw4`fEMQ2s)so5w}h zB&;U5?uT;-ETWE0-Hqu3IZP^ohRowo%h;;@jb=(F+-H?pG_yh>9$+9b!C=>Di|oBJ(~MxNE1)wr`T;oRGZEzg&7aUbDma6k4)| z?rwIcOLph)G)eSE)zO@q5*!m%-P8_v4d_)ZhwslsaqlcN;I@|t`!hnBpY}$SUyhBE zgZKS2+fqF?JsE%IS_A~>GnQ$b#6p{EBuIpW?c7wh8rk1NI7I3T%zZRJ)e`%wP!%)P z%5%G9ku6MVbtL%i&Op78-8X1i+N7=RL_-uM#$EVj4sAYBNoj|#)EaB< z#*3N4zFp@$FiuAfc8PlI&n51cBkU_FtA0Gx?HVJuMp5eH0w?dk{@X0vDV$W{0EyWD zMGImM%Vwi4@B*;F;RvJ+EcA-O#9Zyj8!H35fWM8w+Uu~L|$WmoB4T$-dT+N+;gGy?OP4|35LY&W$ZHA?#vHXYm{)S=x^D{)4czpy=}Ld4-z6E)q-TP ztZ_Nz6H~KzLMxDBD$x~Bx7#<6vX=|OP>4#@n>xtm@#;EU~rEXNlfdvP`YVkRKqvOCKPy^bkOC8M?S+@(R z4v&Vqg#Q`$muy89SE(@X%69GN!aznaH=fN7G0)}BYdJw{JPLG#JN5!cIODDTD1|Vo!ydgi%OD z@Kgpk3j0&n7t-|K_xNobW!Q%|$gL+vx@BBn%<7fIcl0;^BzN@9^v>w?_hxjKNVGM_ z$5efN_?#LMT|AK3Xc2rR++$)%ruTEDOH;@7B?A2eo7~Xc`$wsIQu|kUakpZ#XGMmme6I~Nhk(DFnHRPkLsee3 zZm^qVuSc$Cl7F3ZcnFsffjy5;ow2beSiutYwS@t*-u}6#furO9mAy@PoERWnR|G}! zu6;R1=3$kviZ8Pm0Ac+Ut!t3CkV%w`Yc1z zt2w1Dv%4}V!gsSDwASi^8=6yZ^wP>OjLNbC_(YRb3>boX$nZk3IKYq>$d%Ab7e^_` z>3<(=CSq$0L+`EBv;I3v`e&eb$6Ms4(Mc}6&!I7$Gk@FNAS>8$L8=5CoU2IxshIz% zb5Gh(>J;^djoi+*1))H4^A1zL13y|IPx*iS60y%%amT|WDW(zV00eUDy0-dPRrA;X E2VMR^U;qFB literal 0 HcmV?d00001 diff --git a/event-aggregator/etc/classes.ucls b/event-aggregator/etc/classes.ucls new file mode 100644 index 000000000..4a869b9d2 --- /dev/null +++ b/event-aggregator/etc/classes.ucls @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/event-aggregator/pom.xml b/event-aggregator/pom.xml new file mode 100644 index 000000000..9392bd996 --- /dev/null +++ b/event-aggregator/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.0-SNAPSHOT + + event-aggregator + + + junit + junit + test + + + diff --git a/event-aggregator/src/main/java/com/iluwatar/App.java b/event-aggregator/src/main/java/com/iluwatar/App.java new file mode 100644 index 000000000..6a917c3b9 --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/App.java @@ -0,0 +1,35 @@ +package com.iluwatar; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * The Event Aggregator pattern channels events from multiple objects + * into a single object to simplify registration for clients. + * + * In the example LordBaelish, LordVarys and Scout deliver events to + * KingsHand. KingsHand, the event aggregator, then delivers the events + * to KingJoffrey. + * + */ +public class App { + + public static void main(String[] args) { + + KingJoffrey kingJoffrey = new KingJoffrey(); + KingsHand kingsHand = new KingsHand(kingJoffrey); + + List emitters = new ArrayList<>(); + emitters.add(kingsHand); + emitters.add(new LordBaelish(kingsHand)); + emitters.add(new LordVarys(kingsHand)); + emitters.add(new Scout(kingsHand)); + + for (Weekday day: Weekday.values()) { + for (EventEmitter emitter: emitters) { + emitter.timePasses(day); + } + } + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/Event.java b/event-aggregator/src/main/java/com/iluwatar/Event.java new file mode 100644 index 000000000..8f62af015 --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/Event.java @@ -0,0 +1,21 @@ +package com.iluwatar; + +/** + * + * Event enumeration. + * + */ +public enum Event { + + STARK_SIGHTED("Stark sighted"), WARSHIPS_APPROACHING("Warships approaching"), TRAITOR_DETECTED("Traitor detected"); + + private String description; + + Event(String description) { + this.description = description; + } + + public String toString() { + return description; + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/EventEmitter.java b/event-aggregator/src/main/java/com/iluwatar/EventEmitter.java new file mode 100644 index 000000000..b698dca38 --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/EventEmitter.java @@ -0,0 +1,35 @@ +package com.iluwatar; + +import java.util.LinkedList; +import java.util.List; + +/** + * + * EventEmitter is the base class for event producers that can be observed. + * + */ +public abstract class EventEmitter { + + private List observers; + + public EventEmitter() { + observers = new LinkedList<>(); + } + + public EventEmitter(EventObserver obs) { + this(); + registerObserver(obs); + } + + public void registerObserver(EventObserver obs) { + observers.add(obs); + } + + protected void notifyObservers(Event e) { + for (EventObserver obs: observers) { + obs.onEvent(e); + } + } + + public abstract void timePasses(Weekday day); +} diff --git a/event-aggregator/src/main/java/com/iluwatar/EventObserver.java b/event-aggregator/src/main/java/com/iluwatar/EventObserver.java new file mode 100644 index 000000000..a642754ca --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/EventObserver.java @@ -0,0 +1,12 @@ +package com.iluwatar; + +/** + * + * Observers of events implement this interface. + * + */ +public interface EventObserver { + + void onEvent(Event e); + +} diff --git a/event-aggregator/src/main/java/com/iluwatar/KingJoffrey.java b/event-aggregator/src/main/java/com/iluwatar/KingJoffrey.java new file mode 100644 index 000000000..b37cd5e20 --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/KingJoffrey.java @@ -0,0 +1,14 @@ +package com.iluwatar; + +/** + * + * KingJoffrey observes events from KingsHand. + * + */ +public class KingJoffrey implements EventObserver { + + @Override + public void onEvent(Event e) { + System.out.println("Received event from the King's Hand: " + e.toString()); + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/KingsHand.java b/event-aggregator/src/main/java/com/iluwatar/KingsHand.java new file mode 100644 index 000000000..09bec7502 --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/KingsHand.java @@ -0,0 +1,28 @@ +package com.iluwatar; + +/** + * + * KingsHand observes events from multiple sources and delivers them + * to listeners. + * + */ +public class KingsHand extends EventEmitter implements EventObserver { + + public KingsHand() { + super(); + } + + public KingsHand(EventObserver obs) { + super(obs); + } + + @Override + public void onEvent(Event e) { + notifyObservers(e); + } + + @Override + public void timePasses(Weekday day) { + // NOP + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/LordBaelish.java b/event-aggregator/src/main/java/com/iluwatar/LordBaelish.java new file mode 100644 index 000000000..38022546c --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/LordBaelish.java @@ -0,0 +1,24 @@ +package com.iluwatar; + +/** + * + * LordBaelish produces events. + * + */ +public class LordBaelish extends EventEmitter { + + public LordBaelish() { + super(); + } + + public LordBaelish(EventObserver obs) { + super(obs); + } + + @Override + public void timePasses(Weekday day) { + if (day.equals(Weekday.FRIDAY)) { + notifyObservers(Event.STARK_SIGHTED); + } + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/LordVarys.java b/event-aggregator/src/main/java/com/iluwatar/LordVarys.java new file mode 100644 index 000000000..5d5a25fe8 --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/LordVarys.java @@ -0,0 +1,24 @@ +package com.iluwatar; + +/** + * + * LordVarys produces events. + * + */ +public class LordVarys extends EventEmitter { + + public LordVarys() { + super(); + } + + public LordVarys(EventObserver obs) { + super(obs); + } + + @Override + public void timePasses(Weekday day) { + if (day.equals(Weekday.SATURDAY)) { + notifyObservers(Event.TRAITOR_DETECTED); + } + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/Scout.java b/event-aggregator/src/main/java/com/iluwatar/Scout.java new file mode 100644 index 000000000..cdb43742a --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/Scout.java @@ -0,0 +1,24 @@ +package com.iluwatar; + +/** + * + * Scout produces events. + * + */ +public class Scout extends EventEmitter { + + public Scout() { + super(); + } + + public Scout(EventObserver obs) { + super(obs); + } + + @Override + public void timePasses(Weekday day) { + if (day.equals(Weekday.TUESDAY)) { + notifyObservers(Event.WARSHIPS_APPROACHING); + } + } +} diff --git a/event-aggregator/src/main/java/com/iluwatar/Weekday.java b/event-aggregator/src/main/java/com/iluwatar/Weekday.java new file mode 100644 index 000000000..f7552867f --- /dev/null +++ b/event-aggregator/src/main/java/com/iluwatar/Weekday.java @@ -0,0 +1,16 @@ +package com.iluwatar; + +public enum Weekday { + + MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY("Saturday"), SUNDAY("Sunday"); + + private String description; + + Weekday(String description) { + this.description = description; + } + + public String toString() { + return description; + } +} diff --git a/event-aggregator/src/test/java/com/iluwatar/AppTest.java b/event-aggregator/src/test/java/com/iluwatar/AppTest.java new file mode 100644 index 000000000..58c74fe79 --- /dev/null +++ b/event-aggregator/src/test/java/com/iluwatar/AppTest.java @@ -0,0 +1,13 @@ +package com.iluwatar; +import org.junit.Test; + +import com.iluwatar.App; + +public class AppTest { + + @Test + public void test() { + String[] args = {}; + App.main(args); + } +} diff --git a/pom.xml b/pom.xml index 92d10e951..7316f65f2 100644 --- a/pom.xml +++ b/pom.xml @@ -38,7 +38,8 @@ double-checked-locking servant service-locator - null-object + null-object + event-aggregator