package Ġcom . shop app . domain . validator Ċ Ċ import Ġcom . shop app . gateway . entity . Card Ċ import Ġjava . util .* Ċ Ċ class ĠCard Validator Ġ{ ĊĊĠĠĠ Ġfun Ġsplit Holder Name ( holder Name : ĠString ): ĠPair < String , ĠString >? Ġ= ĊĠĠĠĠĠĠĠ Ġsplit ( holder Name , Ġ"\\ s ". to Regex ()) ĊĊĠĠĠ Ġfun Ġsplit Expire Date ( expire Date : ĠString ): ĠPair < String , ĠString >? Ġ= ĊĠĠĠĠĠĠĠ Ġsplit ( expire Date , Ġ"/ ". to Regex ()) ĊĊĠĠĠ Ġfun Ġis Card Valid ( card : ĠCard ): ĠCard Validation Result Ġ{ ĊĊĠĠĠĠĠĠĠ Ġwith ( card ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( firstName . isBlank () Ġ|| ĠlastName . isBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCard Validation Result . INVALID _ NAME ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(! is Date Valid ( expire Month , Ġexpire Year )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCard Validation Result . INVALID _ DATE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( verification Code . isBlank () Ġ|| Ġverification Code . length Ġ! in Ġ 3 .. 4 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCard Validation Result . INVALID _ CV V ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ(! isNumber Valid ( card Number )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCard Validation Result . INVALID _ NUMBER ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠCard Validation Result . VALID ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsplit ( original String : ĠString , Ġregex : ĠRegex ): ĠPair < String , ĠString >? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġoriginal String . split ( regex , Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( result . size Ġ== Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPair ( result [ 0 ], Ġresult [ 1 ]) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Date Valid ( expire Month : ĠString , Ġexpire Year : ĠString ): ĠBoolean Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġcalendar Ġ= ĠCalendar . getInstance () ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Month Ġ= Ġcalendar . get ( Calendar . MONTH ) ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Year Ġ= Ġcalendar . get ( Calendar . YEAR ) ĊĊĠĠĠĠĠĠĠ Ġval Ġincorrect Month Ġ= Ġexpire Month . toInt OrNull () Ġ?: Ġ- 1 ĊĠĠĠĠĠĠĠ Ġval Ġselected Month Ġ= Ġincorrect Month Ġ- Ġ 1 ĊĠĠĠĠĠĠĠ Ġval Ġselected Year Ġ= Ġexpire Year . toInt OrNull () Ġ?: Ġ- 1 ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġselected Month Ġ> ĠCalendar . DE CE MBER Ġ|| Ġselected Month Ġ< Ġ 0 Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Year Ġ> Ġselected Year Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ!( current Month Ġ> Ġselected Month Ġ&& Ġcurrent Year Ġ== Ġselected Year ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Number Valid ( number : ĠString ): ĠBoolean Ġ{ ĊĊĠĠĠĠĠĠĠ Ġif Ġ( number . isNotBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġsum Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġalternate Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġnumber . length Ġ- Ġ 1 Ġdown To Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġn Ġ= ĠInteger . parseInt ( number . substring ( i , Ġi Ġ+ Ġ 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( alternate ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn Ġ*= Ġ 2 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( n Ġ> Ġ 9 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġn Ġ= Ġn Ġ% Ġ 1 0 Ġ+ Ġ 1 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsum Ġ+= Ġn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġalternate Ġ= Ġ! alternate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsum Ġ% Ġ 1 0 Ġ== Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġenum Ġclass ĠCard Validation Result Ġ{ ĊĠĠĠĠĠĠĠ ĠVALID , ĊĠĠĠĠĠĠĠ ĠINVALID _ DATE , ĊĠĠĠĠĠĠĠ ĠINVALID _ NAME , ĊĠĠĠĠĠĠĠ ĠINVALID _ NUMBER , ĊĠĠĠĠĠĠĠ ĠINVALID _ CV V ĊĠĠĠ Ġ} Ċ }