package Ġcom . never mind software . url parser Ċ Ċ import Ġcom . never mind software . url parser . t ld . TL D Source Ċ Ċ /** Ċ Ġ* ĠCore ĠUrl ĠParser Ġinstance . ĠUses Ġa ĠT LD Ġsource Ġto Ġload ĠT LD Ġsuffix es Ġto Ġparse Ġraw Ġstring Ġdomains Ċ Ġ* Ġ@ property Ġt ld Source Ġt ld Ġsource Ġto Ġuse . ĠThe Ġresults Ġof Ġthis Ġcall Ġare Ġnot Ġcached Ġand Ġthe Ġt ld Ġsource Ġwill Ġbe Ġqueried Ġeach Ġtime Ċ Ġ*/ Ċ open Ġclass ĠUrl Parser ( private Ġval Ġt ld Source : ĠT LD Source ) Ġ{ ĊĠĠĠ Ġprivate Ġclass ĠMutable Url ( ĊĠĠĠĠĠĠĠ Ġval Ġraw : ĠString , ĊĠĠĠĠĠĠĠ Ġvar Ġscheme : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġvar Ġhost : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġvar Ġt ld : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġvar Ġpath : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġvar Ġquery Str : ĠString ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġvar Ġsub Domains : ĠList < String > Ġ= Ġempty List () ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcurrent : ĠString Ġ= Ġraw ĊĊĠĠĠĠĠĠĠ Ġfun Ġto Url () Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠUrl ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġraw Ġ= Ġraw , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscheme Ġ= Ġscheme , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhost Ġ= Ġhost , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġt ld Ġ= Ġt ld , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath Ġ= Ġpath , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġquery Str Ġ= Ġquery Str , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsub Domains Ġ= Ġsub Domains ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠParses Ġa Ġraw Ġurl Ġstring Ġinto Ġa ĠUrl Ġobject ĊĠĠĠĠ Ġ* Ġ@ param Ġurl ĠThe Ġurl Ġto Ġparse Ġ( e . g . Ġhttp :// www . example . com / path ? qp 1 = 2 & qp 2 = b ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġparse ( url : ĠString ): ĠUrl Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġm Url Ġ= ĠMutable Url ( raw Ġ= Ġurl ) ĊĠĠĠĠĠĠĠ Ġconsume Scheme ( m Url ) ĊĠĠĠĠĠĠĠ Ġconsume Query Str ( m Url ) ĊĠĠĠĠĠĠĠ Ġconsume Path ( m Url ) ĊĠĠĠĠĠĠĠ Ġconsume TL D ( m Url ) ĊĠĠĠĠĠĠĠ Ġconsume Host ( m Url ) ĊĠĠĠĠĠĠĠ Ġconsume Sub Domains ( m Url ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġm Url . to Url () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġthe Ġt ld Ġfrom Ġa Ġurl Ġhost . ĠNote Ġthat Ġthis Ġmethod Ġdoes Ġnot Ġexpect Ġa Ġfull Ġurl , Ġonly Ġthe Ġhost Ġpart Ġ( e . g . Ġexample . co . uk ) ĊĠĠĠĠ Ġ* Ġ@ param Ġhost Ġthe Ġhost Ġto Ġparse Ġthe ĠT LD Ġfrom ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget TL D ( host : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhost Parts Ġ= Ġhost ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. split (".") Ġ// ĠGet Ġindividual Ġparts ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . toLowerCase () Ġ} Ġ// ĠStandard ise Ġto Ġlowercase Ġfor Ġrule Ġmatching ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. reversed () Ġ// ĠRules Ġare Ġmatched Ġfrom Ġthe Ġend Ġof Ġthe Ġstring Ġbackwards ĊĊĠĠĠĠĠĠĠ Ġreturn Ġget Best T ld Rule ( host Parts ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. match ( host Parts ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. reversed () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. join ToString ( separator Ġ= Ġ". ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconsume Scheme ( m Url : ĠMutable Url ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Url . current ĊĠĠĠĠĠĠĠ Ġval Ġboundary Marker Ġ= Ġ" ://" ĊĠĠĠĠĠĠĠ Ġval Ġboundary Ġ= Ġurl . indexOf ( boundary Marker ) ĊĠĠĠĠĠĠĠ Ġif Ġ( boundary Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . scheme Ġ= Ġurl . substring ( 0 , Ġboundary ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġurl . substring ( boundary Ġ+ Ġboundary Marker . length , Ġurl . length ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconsume Query Str ( m Url : ĠMutable Url ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Url . current ĊĠĠĠĠĠĠĠ Ġval Ġboundary Marker Ġ= Ġ" ?" ĊĠĠĠĠĠĠĠ Ġval Ġboundary Ġ= Ġurl . lastIndexOf ( boundary Marker ) ĊĠĠĠĠĠĠĠ Ġif Ġ( boundary Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . query Str Ġ= Ġnull If Empty ( url . substring ( boundary Ġ+ Ġ 1 ), Ġprefix Ġ= Ġ"? ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġurl . substring ( 0 , Ġboundary ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconsume Path ( m Url : ĠMutable Url ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Url . current ĊĠĠĠĠĠĠĠ Ġval Ġboundary Marker Ġ= Ġ"/" ĊĠĠĠĠĠĠĠ Ġval Ġboundary Ġ= Ġurl . indexOf ( boundary Marker ) ĊĠĠĠĠĠĠĠ Ġif Ġ( boundary Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . path Ġ= Ġnull If Empty ( url . substring ( boundary Ġ+ Ġ 1 ), Ġprefix Ġ= Ġ"/") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġurl . substring ( 0 , Ġboundary ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconsume TL D ( m Url : ĠMutable Url ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Url . current ĊĠĠĠĠĠĠĠ Ġval Ġt ld Ġ= Ġget TL D ( url ) ĊĠĠĠĠĠĠĠ Ġval Ġboundary Ġ= Ġurl . lastIndexOf ( t ld ) ĊĠĠĠĠĠĠĠ Ġm Url . t ld Ġ= Ġt ld ĊĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġurl . substring ( 0 , Ġboundary Ġ- Ġ 1 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconsume Host ( m Url : ĠMutable Url ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Url . current ĊĠĠĠĠĠĠĠ Ġval Ġboundary Marker Ġ= Ġ"." ĊĠĠĠĠĠĠĠ Ġval Ġboundary Ġ= Ġurl . lastIndexOf ( boundary Marker ) ĊĠĠĠĠĠĠĠ Ġif Ġ( boundary Ġ>= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . host Ġ= Ġnull If Empty ( url . substring ( boundary Ġ+ Ġ 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġurl . substring ( 0 , Ġboundary ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . host Ġ= Ġurl ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġconsume Sub Domains ( m Url : ĠMutable Url ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġm Url . current ĊĠĠĠĠĠĠĠ Ġif Ġ(! url . isBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . sub Domains Ġ= Ġurl . split (".") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Url . current Ġ= Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Best T ld Rule ( host Parts : ĠList < String >): ĠS uffix Rule Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrules Ġ= Ġt ld Source . get () ĊĊĠĠĠĠĠĠĠ Ġval Ġmatches Ġ= Ġrules ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . match able Labels . size Ġ<= Ġhost Parts . size Ġ} Ġ// ĠHost Ġmust Ġhave Ġat Ġleast Ġas Ġmany Ġparts Ġas Ġthe Ġrule ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġrule Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrule . match able Labels . with Index () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . value Ġ== Ġhost Parts [ it . index ] Ġ|| Ġit . value Ġ== Ġ"*" Ġ} Ġ// ĠPart Ġmust Ġeither Ġmatch Ġor Ġbe Ġa Ġwildcard ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. reduce Ġ{ Ġacc , Ġv Ġ-> Ġacc Ġ&& Ġv Ġ} Ġ// ĠRule Ġmatches Ġif Ġeach Ġpart Ġmatches ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠĠĠĠĠ Ġif Ġ( matches . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠS uffix Rule ("* ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( matches . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmatches . first () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġthere Ġis Ġan Ġexception Ġrule , Ġit Ġwins ĊĠĠĠĠĠĠĠ Ġval Ġexception Ġ= Ġget Exception Rule ( matches ) ĊĠĠĠĠĠĠĠ Ġif Ġ( exception Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġexception ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠL on gest Ġmatch Ġwins ĊĠĠĠĠĠĠĠ Ġreturn Ġmatches . sorted By Ġ{ Ġit . labels . size Ġ}. last () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Exception Rule ( rules : ĠList < Suffix Rule >): ĠS uffix Rule ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexceptions Ġ= Ġrules . filter Ġ{ Ġit . is Exception Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( exceptions . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠ 0 Ġ-> Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠ 1 Ġ-> Ġexceptions . first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Rules Ġlist Ġcontained Ġmultiple Ġexception Ġrules Ġfor Ġpattern : Ġ${ exceptions . map Ġ{ Ġit . raw Ġ}} ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnull If Empty ( v : ĠString ?, Ġprefix : ĠString ? Ġ= Ġnull ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( v Ġ!= Ġnull Ġ&& Ġ! v . trim (). isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġr Ġ= Ġv . trim () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( prefix Ġ!= Ġnull ) Ġ"$ prefix $ r " Ġelse Ġr ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĠĠĠ Ġ} Ċ }