/* ĊĠĠ ĠCopyright Ġ 2 0 1 7 - 2 0 2 0 ĠChar les ĠK orn . ĊĊĠĠ ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); ĊĠĠ Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . ĊĠĠ ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat ĊĊĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 ĊĊĠĠ ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware ĊĠĠ Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , ĊĠĠ ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . ĊĠĠ ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand ĊĠĠ Ġlimitations Ġunder Ġthe ĠLicense . Ċ */ Ċ Ċ package Ġb ate ct . config Ċ Ċ import Ġb ate ct . config . io . ConfigurationException Ċ import Ġcom . char les k orn . k aml . Yaml Input Ċ import Ġkotlinx . serialization . Decoder Ċ import Ġkotlinx . serialization . Encoder Ċ import Ġkotlinx . serialization . K Serializer Ċ import Ġkotlinx . serialization . Serial Descriptor Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . Serializer Ċ import Ġkotlinx . serialization . internal . String Descriptor Ċ import Ġkotlinx . serialization . with Name Ċ Ċ @ Serializable ( with Ġ= ĠVariable Expression . Companion :: class ) Ċ sealed Ġclass ĠVariable Expression Ġ{ ĊĠĠĠ Ġabstract Ġfun Ġevaluate ( host Environment Variables : ĠMap < String , ĠString >, Ġconfig Variables : ĠMap < String , ĠString ?> ): ĠString ĊĊĠĠĠ Ġ@ Serializer ( for Class Ġ= ĠVariable Expression :: class ) ĊĠĠĠ Ġcompanion Ġobject Ġ: ĠK Serializer < Variable Expression > Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġpatterns Ġ= ĠlistOf ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("") Ġto Ġ{ Ġ_: ĠMatch Result Ġ-> ĠLiteral Value ("") Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("\\ $ \\ { (. + ): -( .* )} ") Ġto Ġ{ Ġmatch : ĠMatch Result Ġ-> ĠEnvironment Variable Reference ( match . group Values [ 1 ], Ġmatch . group Values [ 2 ]) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("\\ $ \\ { ([^ : ]+ )} ") Ġto Ġ{ Ġmatch : ĠMatch Result Ġ-> ĠEnvironment Variable Reference ( match . group Values [ 1 ]) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("\\ $ ([ ^{ ]( .* [^ } ]) ?) ") Ġto Ġ{ Ġmatch : ĠMatch Result Ġ-> ĠEnvironment Variable Reference ( match . group Values [ 1 ]) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("< \\ { (. + )} ") Ġto Ġ{ Ġmatch : ĠMatch Result Ġ-> ĠConfig Variable Reference ( match . group Values [ 1 ]) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("< ([ ^{ ]( .* [^ } ]) ?) ") Ġto Ġ{ Ġmatch : ĠMatch Result Ġ-> ĠConfig Variable Reference ( match . group Values [ 1 ]) Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ ĠRegex ("[ ^ $ < ]. * ") Ġto Ġ{ Ġmatch : ĠMatch Result Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( match . value . startsWith ("\\ $ ") Ġ|| Ġmatch . value . startsWith ("\\ < ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLiteral Value ( match . value . drop ( 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLiteral Value ( match . value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġparse ( source : ĠString ): ĠVariable Expression Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpatterns . forEach Ġ{ Ġ( pattern , Ġgenerator ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġpattern . match Ent ire ( source ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġgenerator ( result ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Invalid Ġexpression Ġ'$ source '") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġdescriptor : ĠSerial Descriptor Ġ= ĠString Descriptor . with Name (" expression ") ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġdeserialize ( decoder : ĠDecoder ): ĠVariable Expression Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġparse ( decoder . decode String ()) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( decoder Ġis ĠYaml Input ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfiguration Exception ( e . message Ġ?: Ġ"", Ġdecoder . node . location . line , Ġdecoder . node . location . column , Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġserialize ( encoder : ĠEncoder , Ġobj : ĠVariable Expression ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrepresentation Ġ= Ġwhen Ġ( obj ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠLiteral Value Ġ-> Ġobj . value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠEnvironment Variable Reference Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( obj . default Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'$ ' Ġ+ Ġobj . reference To ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ'$ ' Ġ+ Ġ"{ ${ obj . reference To } :- ${ obj . default }}" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠConfig Variable Reference Ġ-> Ġ"< ${ obj . reference To }" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġencoder . encode String ( representation ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠLiteral Value ( val Ġvalue : ĠString ) Ġ: ĠVariable Expression () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġevaluate ( host Environment Variables : ĠMap < String , ĠString >, Ġconfig Variables : ĠMap < String , ĠString ?> ) Ġ= Ġvalue ĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ"${ this :: class . simple Name }( value : Ġ'$ value ')" Ċ } Ċ Ċ data Ġclass ĠEnvironment Variable Reference ( val Ġreference To : ĠString , Ġval Ġdefault : ĠString ? Ġ= Ġnull ) Ġ: ĠVariable Expression () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġevaluate ( host Environment Variables : ĠMap < String , ĠString >, Ġconfig Variables : ĠMap < String , ĠString ?> ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġhost Value Ġ= Ġhost Environment Variables . get ( reference To ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhost Value Ġ!= Ġnull Ġ-> Ġhost Value ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefault Ġ!= Ġnull Ġ-> Ġdefault ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠVariable Expression Evaluation Exception (" The Ġhost Ġenvironment Ġvariable Ġ'$ reference To ' Ġis Ġnot Ġset , Ġand Ġno Ġdefault Ġvalue Ġhas Ġbeen Ġprovided .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ"${ this :: class . simple Name }( reference Ġto : Ġ'$ reference To ', Ġdefault : Ġ${ defaultValue ToString () })" ĊĊĠĠĠ Ġprivate Ġfun ĠdefaultValue ToString () Ġ= Ġif Ġ( default Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" null " ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġ"' $ default '" ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠConfig Variable Reference ( val Ġreference To : ĠString ) Ġ: ĠVariable Expression () Ġ{ ĊĠĠĠ Ġoverride Ġfun Ġevaluate ( host Environment Variables : ĠMap < String , ĠString >, Ġconfig Variables : ĠMap < String , ĠString ?> ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! config Variables . containsKey ( reference To )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠVariable Expression Evaluation Exception (" The Ġconfig Ġvariable Ġ'$ reference To ' Ġhas Ġnot Ġbeen Ġdefined .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġconfig Variables . getValue ( reference To ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( value Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠVariable Expression Evaluation Exception (" The Ġconfig Ġvariable Ġ'$ reference To ' Ġis Ġnot Ġset Ġand Ġhas Ġno Ġdefault Ġvalue .") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġvalue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString () Ġ= Ġ"${ this :: class . simple Name }( reference Ġto : Ġ'$ reference To ')" Ċ } Ċ Ċ class ĠVariable Expression Evaluation Exception ( message : ĠString ) Ġ: ĠRuntimeException ( message ) Ċ