package Ġdev . al pas . routing Ċ Ċ import Ġdev . al pas . AppConfig Ċ import Ġdev . al pas . filter NotNull Values Ċ import Ġdev . al pas . toDate Ċ import Ġorg . sage b ion etwork s . url . HttpMethod Ċ import Ġorg . sage b ion etwork s . url . Url Signer Utils Ċ import Ġu y . kl utter . core . uri . build Uri Ċ import Ġjava . net . URI Ċ import Ġjava . net . URL Ċ import Ġjava . time . Duration Ċ import Ġjava . time . Z onedDateTime Ċ Ċ class ĠUrl Generator ( private Ġval Ġroot : ĠURI , Ġprivate Ġval Ġrouter : ĠRouter , Ġprivate Ġval Ġapp Config : ĠApp Config ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġparam Match Regex Ġby Ġlazy Ġ{ Ġ""" < ([^ >] *) > """. to Regex () Ġ} ĊĊĠĠĠ Ġfun Ġroute ( ĊĠĠĠĠĠĠĠ Ġname : ĠString , ĊĠĠĠĠĠĠĠ Ġparams : ĠMap < String , ĠAny ?> ? Ġ= Ġnull , ĊĠĠĠĠĠĠĠ Ġabsolute : ĠBoolean Ġ= Ġtrue , ĊĠĠĠĠĠĠĠ Ġdefault Path : ĠString ? Ġ= Ġnull ĊĠĠĠ Ġ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmutable Params Map Ġ= Ġparams ?. filter NotNull Values ()?. to Mutable Map () Ġ?: Ġmutable Map Of () ĊĠĠĠĠĠĠĠ Ġval Ġroute Ġ= Ġrouter . find Named Route ( name ) ĊĠĠĠĠĠĠĠ Ġif Ġ( route Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġrequire Ġthat Ġthe Ġroute Ġis Ġfound Ġor Ġthat Ġthere Ġis Ġa Ġdefault Ġpath , Ġotherwise Ġwe Ġthrow Ġan Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire NotNull ( default Path ) Ġ{ Ġ" Route Ġ$ name Ġisn 't Ġdefined ." Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġdefault Path ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠbasePath Ġ= Ġroute . path . replace ( param Match Regex ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatch Ġ= Ġit . group Values [ 1 ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġmutable Params Map . remove ( match ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalArgumentException (" No Ġvalue Ġprovided Ġfor Ġrequired Ġparameter Ġ'$ match '") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalue . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġuri Ġ= Ġbuild Uri ( root ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. encoded Path ( basePath ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add QueryParams (* mutable Params Map . map Ġ{ Ġit . key Ġto Ġit . value . toString () Ġ}. to Typed Array ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. to URI () ĊĠĠĠĠĠĠĠ Ġreturn Ġ( if Ġ( absolute ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuri ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġroot . rel ativ ize ( uri ) ĊĠĠĠĠĠĠĠ Ġ}). toString () ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġfun Ġurl ( path : ĠString , Ġparams : ĠMap < String , ĠAny > Ġ= Ġempty Map (), Ġforce Secure : ĠBoolean Ġ= Ġfalse ): ĠURI Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġurl ( root , Ġpath , Ġparams , Ġforce Secure ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsigned Route ( name : ĠString , Ġparams : ĠMap < String , ĠAny >? Ġ= Ġnull , Ġexpiration : ĠDuration ): ĠURL Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġroute ( name , Ġparams Ġ= Ġparams , Ġabsolute Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġreturn Ġsign ( url , Ġexpiration ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsign ( url : ĠString , Ġexpiration : ĠDuration ): ĠURL Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġtodo : Ġcleanup ĠUrl Signer Utils ĊĠĠĠĠĠĠĠ Ġval Ġexpiration DateTime Ġ= ĠZ onedDateTime . now ( app Config . timezone ). plus Minutes ( expiration . to Minutes ()) ĊĠĠĠĠĠĠĠ Ġreturn ĠUrl Signer Utils . generate Pre Signed URL ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHttpMethod . GET , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġurl , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpiration DateTime . toDate (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Config . encryption Key ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcheck Signature ( url : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsignature Ġ= ĠUrl Signer Utils . validate Pres ign ed URL ( HttpMethod . GET , Ġurl , Ġapp Config . encryption Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsignature Ġ!= Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhas Route ( name : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġrouter . find Named Route ( name ) Ġ!= Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġurl ( root : ĠURI , Ġpath : ĠString Ġ= Ġ"", Ġparams : ĠMap < String , ĠAny > Ġ= Ġempty Map (), Ġforce Secure : ĠBoolean Ġ= Ġfalse ): ĠURI Ġ{ ĊĠĠĠ Ġval Ġbuilder Ġ= Ġbuild Uri ( root ) ĊĠĠĠĠĠĠĠ Ġ. encoded Path ( path ) ĊĠĠĠĠĠĠĠ Ġ. add QueryParams (* params . map Ġ{ Ġit . key Ġto Ġit . value . toString () Ġ}. to Typed Array ()) ĊĠĠĠ Ġif Ġ( force Secure ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbuilder . scheme (" https :// ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġbuilder . build (). to URI () Ċ } Ċ