/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 ĠJ Lang Ċ Ġ* Ċ Ġ* Ġ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 Ġorg . j lang . kt _ config Ċ Ċ import Ġorg . j lang . kt _ config . impl .* Ċ import Ġorg . j lang . kt _ config . impl . TokenType .* Ċ import Ġjava . net . URL Ċ import Ġjava . io . Reader Ċ import Ġjava . io . BufferedReader Ċ import Ġjava . io . InputStream Ċ import Ġjava . io . InputStream Reader Ċ import Ġjava . nio . charset . Charset ĊĊ Ċ /** Ċ Ġ* ĠCreates Ġa Ġconfiguration Ġreader Ġfrom Ġa Ġstring Ġwith Ġoptional Ġuser Ġdefinitions . Ċ Ġ* ĠThe Ġcompanion Ġobjects Ġoffers Ġcreating Ġa Ġconfiguration Ġreader Ġfrom Ġan Ċ Ġ* ĠInputStream Ċ Ġ* Ċ Ġ* ĠThe Ġreader Ġthrows Ġa ĠConfiguration Exception Ġif Ġthe Ġpassed Ġconfiguration Ċ Ġ* Ġdoes Ġnot Ġmeet Ġthe Ġgrammar Ġor Ġif Ġnot Ġall Ġreferenced Ġdefinitions Ġcould Ċ Ġ* Ġbe Ġresolved . Ċ Ġ* Ċ Ġ* Ġ### Configuration ĠE BN F Ċ Ġ* Ġ``` Ċ Ġ* ĠĠĠ ĠConfig Ġ::= ĠDef Statement Ġ{ ĠSection Ġ| ĠConfig Item Ġ} Ċ Ġ* ĠĠĠ ĠDef Statement Ġ::= Ġ' def ' ĠIdentifier Ġ'=' ĠValue Ċ Ġ* ĠĠĠ ĠSection Ġ::= Ġ( Identifier Ġ| ĠPath ) Ġ'{ ' Ġ{ Ġ( Section Ġ| ĠConfig Item ) Ġ} Ġ' }' Ċ Ġ* ĠĠĠ ĠConfig Item Ġ::= Ġ( Identifier Ġ| ĠPath ) Ġ'=' Ġ( Value Ġ| ĠMulti Value ) Ċ Ġ* ĠĠĠ ĠIdentifier Ġ::= Ġ( a .. z Ġ| ĠA .. Z ) Ġ Ġ{ Ġ( a .. z Ġ| ĠA .. Z | Ġ 0 .. 9 Ġ| Ġ'_ ') Ġ} Ċ Ġ* ĠĠĠ ĠPath Ġ::= ĠIdentifier Ġ{ Ġ'.' ĠIdentifier Ġ} Ċ Ġ* ĠĠĠ ĠMulti Value Ġ::= Ġ'[' ĠValue Ġ{ Ġ',' ĠValue Ġ} Ġ' ]' Ċ Ġ* ĠĠĠ ĠValue Ġ::= Ġ(' "' Ġ< any - char > Ġ'"' Ġ| Ġ''' Ġ< any - char > Ġ''' Ċ Ġ* Ġ`` Ċ Ġ*/ Ċ class ĠConfig Reader ( ĊĠĠĠĠĠĠĠ Ġconfig : ĠString , ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġuser Definitions : ĠMap < String , String > Ġ= ĠHashMap () Ċ ) Ġ{ ĊĠĠĠ Ġ// ĠActually Ġa ĠLL ( 2 ) Ġparser Ġis Ġsufficient Ġbut ĠLL ( 4 ) Ġsimpl ifies Ġcode ĊĠĠĠ Ġprivate Ġval ĠLO OK A HEAD _ SIZE Ġ= Ġ 4 ĊĊĠĠĠ Ġprivate Ġval Ġlexer Ġ= ĠLex er ( String Reader ( config )) ĊĠĠĠ Ġprivate Ġval Ġbuilder Ġ= ĠConfig Builder () ĊĠĠĠ Ġprivate Ġval Ġdefinitions Ġ= ĠLinkedHashMap < String , String >() ĊĊĠĠĠ Ġ// Ġlook ahead Ġbuffer Ġwith Ġtokens Ġand Ġprime Ġit ĊĠĠĠ Ġprivate Ġvar Ġlook ahead : ĠLook ahead < Token > Ġ= ĠLook ahead ( LOOK A HEAD _ SIZE , Ġlexer ) ĊĊĠĠĠ Ġcompanion Ġobject ĠFactory Ġ{ ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġurl : ĠURL , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Definitions : ĠMap < String , ĠString > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġ): ĠConfig Reader Ġ= ĠConfig Reader ( sl ur p ( url . open Stream ()), Ġuser Definitions ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġin Stream : ĠInputStream , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcharset : ĠCharset Ġ= ĠChar sets . UTF _ 8 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Definitions : ĠMap < String , ĠString > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġ): ĠConfig Reader Ġ= ĠConfig Reader ( sl ur p ( in Stream , Ġcharset ), Ġuser Definitions ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreader : ĠReader , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Definitions : ĠMap < String , ĠString > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġ): ĠConfig Reader Ġ= ĠConfig Reader ( sl ur p ( reader ), Ġuser Definitions ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Path Resource : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Definitions : ĠMap < String , ĠString > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġ): ĠConfig Reader Ġ= ĠConfig Reader ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsl ur p ( class Path Resource , Ġthis . java Class . class Loader ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Definitions ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclass Path Resource : ĠString , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġloader : ĠClassLoader , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuser Definitions : ĠMap < String , ĠString > Ġ= ĠHashMap () ĊĠĠĠĠĠĠĠ Ġ): ĠConfig Reader Ġ= ĠConfig Reader ( sl ur p ( class Path Resource , Ġloader ), Ġuser Definitions ) ĊĊĠĠĠĠĠĠĠ Ġfun Ġempty (): ĠConfig Ġ= ĠConfig Impl ( Config Object ()) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġsl ur p ( in Stream : ĠInputStream , Ġcharset : ĠCharset Ġ= ĠChar sets . UTF _ 8 ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBufferedReader ( InputStream Reader ( in Stream , Ġcharset )). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . read Lines (). reduce ({ Ġs 1 , s 2 Ġ-> Ġs 1 Ġ+ Ġ"\ n " Ġ+ Ġs 2 Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġsl ur p ( reader : ĠReader ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBufferedReader ( reader ). use Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . read Lines (). reduce ({ Ġs 1 , s 2 Ġ-> Ġs 1 Ġ+ Ġ"\ n " Ġ+ Ġs 2 Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġsl ur p ( class Path Resource : ĠString , Ġloader : ĠClassLoader ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsl ur p ( loader . getResource AsStream ( class Path Resource ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" The Ġclasspath Ġresource Ġconfig Ġ'$ class Path Resource ' Ġdoes Ġnot Ġexist .")) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġvalidate User Definitions ( user Definitions ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġread (): ĠConfig Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefinitions . put All ( get Prefix ed Environment Variables (" env ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefinitions . put All ( get Prefix ed System Properties (" system ")) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefinitions . put All ( user Definitions ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( parse Def Statement ()) Ġ{ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġa Ġconfig Ġis Ġbuilt Ġfrom Ġany Ġnumber Ġof Ġconfig Ġitems Ġand Ġsections ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( parse Config Item Or Section ()) Ġ{ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! look ahead [ 0 ]. eof ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception (" Expected ĠEOF Ġat Ġposition Ġ${ look ahead [ 0 ]. pos }. ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠConfig Impl ( Config Object ( builder . get ())) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch ( ex : ĠConfig Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} Ġcatch ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception (" Internal Ġerror .", Ġex ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Def Statement (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 0 ]. is Type ( IDENTIFIER ) Ġ&& Ġ" def " Ġ== Ġlook ahead [ 0 ]. data ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 1 ]. isNot Type ( IDENTIFIER )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid Ġvariable Ġdefinition Ġat Ġposition Ġ${ look ahead [ 1 ]. pos }. Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġ" Expected Ġa Ġvariable Ġname .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 2 ]. isNot Type ( EQUAL S )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid Ġvariable Ġdefinition Ġat Ġposition Ġ${ look ahead [ 2 ]. pos }. Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġ" Expected Ġ'=' .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 3 ]. isNot Type ( STRING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid Ġvariable Ġdefinition Ġat Ġposition Ġ${ look ahead [ 3 ]. pos }. Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġ" Expected Ġa Ġvariable Ġvalue Ġstring .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdefinitions . put ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead [ 1 ]. data , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapply Definitions ( look ahead [ 3 ]. data , Ġlook ahead [ 3 ]. pos )) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 4 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Config Item Or Section (): ĠBoolean Ġ= Ġparse Config Item () Ġ|| Ġparse Section () ĊĊĠĠĠ Ġprivate Ġfun Ġparse Config Item (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 0 ]. is Type ( IDENTIFIER , ĠPATH ) Ġ&& Ġlook ahead [ 1 ]. is Type ( EQUAL S )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 2 ]. is Type ( STRING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsingle Ġvalue : Ġname Ġ= Ġ" value " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . add ( Config Value . single ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead [ 0 ]. data , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapply Definitions ( look ahead [ 2 ]. data , Ġlook ahead [ 2 ]. pos ))) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 3 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( look ahead [ 2 ]. is Type ( L BRACK )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġmulti Ġvalue : Ġname Ġ= Ġ[ Ġ" value 1 ", Ġ" value 2 ", Ġ... Ġ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġlook ahead [ 0 ]. data ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 3 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparse Config Item _ Multi Values ( name ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 0 ]. isNot Type ( R BRACK )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Expected Ġarray Ġclose Ġ' ]' Ġat Ġposition Ġ${ look ahead [ 0 ]. pos }. ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Invalid Ġconfig Ġitem Ġat Ġposition Ġ${ look ahead [ 2 ]. pos }. Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġ" Expected Ġa Ġdouble Ġquoted Ġvalue .") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Config Item _ Multi Values ( name : ĠString ): ĠUnit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠArrayList < String >() ĊĊĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 0 ]. is Type ( STRING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . add ( apply Definitions ( look ahead [ 0 ]. data , Ġlook ahead [ 0 ]. pos )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( look ahead [ 0 ]. is Type ( COMMA ) Ġ&& Ġlook ahead [ 1 ]. is Type ( STRING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . add ( apply Definitions ( look ahead [ 1 ]. data , Ġlook ahead [ 1 ]. pos )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġbuilder . add ( Config Value . multi ( name , Ġvalues )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Section (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 0 ]. is Type ( IDENTIFIER , ĠPATH ) Ġ&& Ġlook ahead [ 1 ]. is Type ( L BRACE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . push Path ( look ahead [ 0 ]. data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 2 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġa Ġsection Ġis Ġbuilt Ġfrom Ġany Ġnumber Ġof Ġconfig Ġitems Ġand Ġsub Ġsections ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( parse Config Item Or Section ()) Ġ{} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( look ahead [ 0 ]. isNot Type ( R BRACE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Expected Ġsection Ġclose Ġ' }' Ġat Ġposition Ġ${ look ahead [ 0 ]. pos }. ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlook ahead . consume ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġbuilder . pop Path () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġapply Definitions ( text : ĠString , Ġtoken Pos : ĠPosition ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġtmp Ġ= Ġapply Definitions ( text , Ġdefinitions ) ĊĠĠĠĠĠĠĠ Ġif Ġ( has Definitions ( tmp )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Un resolved Ġdefinition Ġin Ġvalue Ġat Ġposition Ġ$ token Pos .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtmp ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġapply Definitions ( text : ĠString , Ġdefs : ĠMap < String , String >): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtmp : ĠString Ġ= Ġtext ĊĠĠĠĠĠĠĠ Ġdefs . forEach Ġ{ Ġk , Ġv Ġ-> Ġtmp Ġ= Ġtmp . replace ("${ '$ ' }{$ k }", Ġv ) Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġtmp ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhas Definitions ( text : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtext . matches (" .* [$ ][ { ][ ^ } ]+ [ } ]. * ". to Regex ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalidate User Definitions ( definitions : ĠMap < String , String >): ĠUnit Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġis Reserved Key ( key : ĠString ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey . startsWith (" env .", Ġtrue ) Ġ|| Ġkey . startsWith (" system .", Ġtrue ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( definitions . keys . filter Ġ{ Ġis Reserved Key ( it ) Ġ}. any ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠConfig Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" User Ġsupplied Ġdefinitions Ġmay Ġnot Ġhave Ġkeys Ġstarting Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġ" with Ġ' env .' Ġor Ġ' system .' Ġthus Ġcover ing Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ+ Ġ" environment Ġvariables Ġor Ġsystem Ġproperties .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }