/* Ċ Ġ* ĠUtils . kt Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 0 - 2 0 2 1 , ĠE rik ĠC . ĠTh au vin Ġ( erik @ th au vin . net ) Ċ Ġ* ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠRedistribution Ġand Ġuse Ġin Ġsource Ġand Ġbinary Ġforms , Ġwith Ġor Ġwithout Ċ Ġ* Ġmodification , Ġare Ġpermitted Ġprovided Ġthat Ġthe Ġfollowing Ġconditions Ġare Ġmet : Ċ Ġ* Ċ Ġ* ĠĠ ĠRedistributions Ġof Ġsource Ġcode Ġmust Ġretain Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer . Ċ Ġ* Ċ Ġ* ĠĠ ĠRedistributions Ġin Ġbinary Ġform Ġmust Ġreproduce Ġthe Ġabove Ġcopyright Ġnotice , Ċ Ġ* ĠĠ Ġthis Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer Ġin Ġthe Ġdocumentation Ċ Ġ* ĠĠ Ġand / or Ġother Ġmaterials Ġprovided Ġwith Ġthe Ġdistribution . Ċ Ġ* Ċ Ġ* ĠĠ ĠNeither Ġthe Ġname Ġof Ġthis Ġproject Ġnor Ġthe Ġnames Ġof Ġits Ġcontributors Ġmay Ġbe Ċ Ġ* ĠĠ Ġused Ġto Ġendorse Ġor Ġpromote Ġproducts Ġderived Ġfrom Ġthis Ġsoftware Ġwithout Ċ Ġ* ĠĠ Ġspecific Ġprior Ġwritten Ġpermission . Ċ Ġ* Ċ Ġ* ĠTHIS ĠSOFTWARE ĠIS ĠPROVIDED ĠBY ĠTHE ĠCOPYRIGHT ĠHOLDERS ĠAND ĠCONTRIBUTORS Ġ" AS ĠIS " Ċ Ġ* ĠAND ĠANY ĠEXPRESS ĠOR ĠIMPLIED ĠWARRANTIES , ĠINCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠTHE Ċ Ġ* ĠIMPLIED ĠWARRANTIES ĠOF ĠMERCHANTABILITY ĠAND ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠARE Ċ Ġ* ĠDISCLAIMED . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠCOPYRIGHT ĠHOLDER ĠOR ĠCONTRIBUTORS ĠBE ĠLIABLE Ċ Ġ* ĠFOR ĠANY ĠDIRECT , ĠINDIRECT , ĠINCIDENTAL , ĠSPECIAL , ĠEXEMPLARY , ĠOR ĠCONSEQUENTIAL Ċ Ġ* ĠDAMAGES Ġ( INCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠPROCUREMENT ĠOF ĠSUBSTITUTE ĠGOODS ĠOR Ċ Ġ* ĠSERVICES ; ĠLOSS ĠOF ĠUSE , ĠDATA , ĠOR ĠPROFITS ; ĠOR ĠBUSINESS ĠINTERRUPTION ) ĠHOWEVER Ċ Ġ* ĠCAUSED ĠAND ĠON ĠANY ĠTHEORY ĠOF ĠLIABILITY , ĠWHETHER ĠIN ĠCONTRACT , ĠSTRICT ĠLIABILITY , Ċ Ġ* ĠOR ĠTORT Ġ( INCLUDING ĠNEGLIGENCE ĠOR ĠOTHERWISE ) ĠARISING ĠIN ĠANY ĠWAY ĠOUT ĠOF ĠTHE ĠUSE Ċ Ġ* ĠOF ĠTHIS ĠSOFTWARE , ĠEVEN ĠIF ĠADVISED ĠOF ĠTHE ĠPOSSIBILITY ĠOF ĠSUCH ĠDAMAGE . Ċ Ġ*/ Ċ Ċ package Ġnet . th au vin . erik . bit ly Ċ Ċ import Ġokhttp 3 . Http Url . Companion . to Http Url OrNull Ċ import Ġokhttp 3 . MediaType . Companion . to MediaType OrNull Ċ import Ġokhttp 3 . Ok HttpClient Ċ import Ġokhttp 3 . Request Ċ import Ġokhttp 3 . RequestBody . Companion . to RequestBody Ċ import Ġokhttp 3 . Response Ċ import Ġokhttp 3 . logging . Http Logging Interceptor Ċ import Ġorg . json . JSONException Ċ import Ġorg . json . JSONObject Ċ import Ġjava . net . Malformed URLException Ċ import Ġjava . net . URL Ċ import Ġjava . util . logging . Level Ċ import Ġjava . util . logging . Logger Ċ Ċ /** ĠProvides Ġuseful Ġgeneric Ġfunctions . Ġ*/ Ċ open Ġclass ĠUtils Ġprivate Ġconstructor () Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĠThe Ġlogger Ġinstance . Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġlogger : ĠLogger Ġby Ġlazy Ġ{ ĠLogger . getLogger ( Bit ly :: class . java . simple Name ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠExec utes Ġan ĠAPI Ġcall . ĊĠĠĠĠĠĠĠĠ Ġ* ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param ĠaccessToken ĠThe ĠAPI Ġaccess Ġtoken . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġend Point ĠThe ĠREST Ġendpoint . Ġ( eg . Ġ` https :// api - ssl . bit ly . com / v 4 / short en `) ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġparams ĠThe Ġrequest Ġparameters Ġkey / value Ġmap . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġmethod ĠThe Ġsubmission Ġ[ Method ][ Methods ]. ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠThe Ġresponse Ġ( JSON ) Ġfrom Ġthe ĠAPI . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠĠĠĠĠ Ġfun Ġcall ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠaccessToken : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend Point : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparams : ĠMap < String , ĠAny > Ġ= Ġempty Map (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmethod : ĠMethods Ġ= ĠMethods . POST ĊĠĠĠĠĠĠĠ Ġ): ĠCall Response Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= ĠCall Response () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( validate Call ( accessToken , Ġend Point )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġapi Url Ġ= Ġend Point . to Http Url OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( api Url Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbuilder Ġ= Ġwhen Ġ( method ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMethods . POST , ĠMethods . PATCH Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġform Body Ġ= ĠJSONObject ( params ). toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. to RequestBody (" application / json ; Ġcharset = utf - 8 ". to MediaType OrNull ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRequest . Builder (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurl ( api Url . newBuilder (). build ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method Ġ== ĠMethods . POST ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpost ( form Body ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpatch ( form Body ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMethods . DELETE Ġ-> ĠRequest . Builder (). url ( api Url . newBuilder (). build ()). delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ Ġ// ĠMethods . GET ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhttp Url Ġ= Ġapi Url . newBuilder (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . value Ġis ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter ( it . key , Ġit . value . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. build () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠRequest . Builder (). url ( http Url ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. add Header (" Authorization ", Ġ" Bearer Ġ$ accessToken ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġcreate HttpClient (). new Call ( builder . build ()). execute () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . body Ġ= Ġparse Body ( end Point , Ġresult ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresponse . result Code Ġ= Ġresult . code ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresponse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġcreate HttpClient (): ĠOk HttpClient Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠOk HttpClient . Builder (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( logger . is Log gable ( Level . F INE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd Interceptor ( Http Logging Interceptor (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlevel Ġ= ĠHttp Logging Interceptor . Level . BODY ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġred act Header (" Authorization ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. build () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġparse Body ( end Point : ĠString , Ġresult : ĠResponse ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbody Ġ= Ġresult . body ?. string () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( body Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! result . is Successful Ġ&& Ġbody . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwith ( JSONObject ( body )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has (" message ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . se vere ( getString (" message ") Ġ+ Ġ" Ġ(${ result . code }) ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( has (" description ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . se vere ( getString (" description ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( j se : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . log ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLevel . SEVERE , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" An Ġerror Ġoccurred Ġparsing Ġthe Ġerror Ġresponse Ġfrom ĠBit ly . Ġ[$ end Point ]", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġj se ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġbody ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠConstants . EMPTY ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠValid ates Ġa ĠURL . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun ĠString . isValid Url (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( this . isNotBlank ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠURL ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠMal formed URLException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . log ( Level . F INE , Ġ" Invalid ĠURL : Ġ$ this ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠRemoves Ġhttp ( s ) Ġscheme Ġfrom Ġstring . ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun ĠString . remove Http (): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . replace First ( Regex ("^ [ Hh ][ Tt ]{ 2 }[ Pp ][ Ss ]? :// "), Ġ"") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠBuilds Ġthe Ġfull ĠAPI Ġendpoint ĠURL Ġusing Ġthe Ġ[ Constants . API _ BASE _ URL ]. ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun ĠString . to EndPoint (): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( this . startsWith ('/ ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Constants . API _ BASE _ URL }$ this " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Constants . API _ BASE _ URL }/ $ this " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġvalidate Call ( accessToken : ĠString , Ġend Point : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġend Point . isBlank () Ġ-> Ġlogger . se vere (" Please Ġspecify Ġa Ġvalid ĠAPI Ġendpoint .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠaccessToken . isBlank () Ġ-> Ġlogger . se vere (" Please Ġspecify Ġa Ġvalid ĠAPI Ġaccess Ġtoken .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ