/* Ċ Ġ* ĠCopyright Ġ 2 0 1 7 - 2 0 1 8 Ġthe Ġoriginal Ġauthor Ġor Ġauthors . Ċ Ġ* Ċ Ġ* Ġ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 . k oin . core . instance Ċ Ċ import Ġorg . k oin . core . K oin Ċ import Ġorg . k oin . core . bean . Bean Registry Ċ import Ġorg . k oin . core . fullname Ċ import Ġorg . k oin . core . parameter . Parameter Definition Ċ import Ġorg . k oin . core . path . Path Registry Ċ import Ġorg . k oin . core . scope . Scope Ċ import Ġorg . k oin . core . scope . Scope Registry Ċ import Ġorg . k oin . core . scope . get Scope Ċ import Ġorg . k oin . core . stack . Resolution Stack Ċ import Ġorg . k oin . core . time . measure Duration Ċ import Ġorg . k oin . dsl . definition . Bean Definition Ċ import Ġkotlin . reflect . K Class Ċ Ċ /** Ċ Ġ* ĠInstance ĠResolver Ċ Ġ* Ċ Ġ* Ġ@ author ĠAr na ud ĠG i ul ian i Ċ Ġ*/ Ċ class ĠInstance Registry ( ĊĠĠĠ Ġval Ġbean Registry : ĠBean Registry , ĊĠĠĠ Ġval Ġinstance Factory : ĠInstance Factory , ĊĠĠĠ Ġval Ġpath Registry : ĠPath Registry , ĊĠĠĠ Ġprivate Ġval Ġscope Registry : ĠScope Registry Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġresolution Stack Ġ= ĠResolution Stack () ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġresolve Ġinstance Ġfrom ĠInstance Request ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< T Ġ: ĠAny > Ġresolve ( request : ĠInstance Request , Ġfilter Function : ĠDefinition Filter ? Ġ= Ġnull ): ĠT Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġdefinitions Ġ= Ġ( if Ġ( filter Function Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbean Registry . definitions HashMap . keys . filter ( filter Function ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġbean Registry . definitions HashMap . keys ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġrequest . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsearch Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname . isNotEmpty () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġbean Registry . search ByName And Class ( definitions , Ġname , Ġclazz ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ{ Ġbean Registry . search By Class ( definitions , Ġclazz ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġproceed Resolution ( clazz , Ġscope , parameters , Ġsearch ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠResolve Ġa Ġdependency Ġfor Ġits Ġbean Ġdefinition ĊĠĠĠĠ Ġ* Ġ@ param Ġscope Ġ- Ġassociated Ġscope ĊĠĠĠĠ Ġ* Ġ@ param Ġclazz Ġ- ĠClass ĊĠĠĠĠ Ġ* Ġ@ param Ġparameters Ġ- ĠParameters ĊĠĠĠĠ Ġ* Ġ@ param Ġdefinition Resolver Ġ- Ġfunction Ġto Ġfind Ġbean Ġdefinitions ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġ< T Ġ: ĠAny > Ġproceed Resolution ( ĊĠĠĠĠĠĠĠ Ġclazz : ĠK Class <* >, ĊĠĠĠĠĠĠĠ Ġscope Ġ: ĠScope ?, ĊĠĠĠĠĠĠĠ Ġparameters : ĠParameter Definition , ĊĠĠĠĠĠĠĠ Ġdefinition Resolver : Ġ() Ġ-> ĠList < Bean Definition <* >> ĊĠĠĠ Ġ): ĠT Ġ= Ġsynchronized ( this ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġvar Ġresult Instance : ĠT ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġclazz Name Ġ= Ġclazz . fullname () ĊĠĠĠĠĠĠĠ Ġval Ġlog Indent : ĠString Ġ= Ġresolution Stack . indent () ĊĠĠĠĠĠĠĠ Ġval Ġduration Ġ= Ġmeasure Duration Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġbean Definition : ĠBean Definition < T > Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbean Registry . retrieve Definition ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclazz , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscope , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdefinition Resolver , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresolution Stack . last () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRetrieve Ġscope Ġfrom ĠDSL ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġassociated Scope Id Ġ= Ġbean Definition . get Scope () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtarget Scope Ġ: ĠScope ? Ġ= Ġscope Ġ?: Ġif Ġ( associated Scope Id . isNotEmpty ()) Ġscope Registry . get Scope ( associated Scope Id ) Ġelse Ġnull ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlog Path Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(" ${ bean Definition . path }". isEmpty ()) Ġ"" Ġelse Ġ"@ Ġ${ bean Definition . path }" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Char Ġ= Ġif Ġ( resolution Stack . isEmpty ()) Ġ" +" Ġelse Ġ" +" ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK oin . logger . info ("$ log Indent $ start Char -- Ġ'$ clazz Name ' Ġ$ log Path ") Ġ// Ġ@ Ġ[$ bean Definition ]") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK oin . logger . debug ("$ log Indent |-- Ġ[$ bean Definition ]") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresolution Stack . resolve ( bean Definition ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( instance , Ġcreated ) Ġ= Ġinstance Factory . retrieve Instance ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbean Definition , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparameters , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtarget Scope ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK oin . logger . debug ("$ log Indent |-- Ġ$ instance ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLog Ġcreation ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( created ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK oin . logger . info ("$ log Indent \\ -- Ġ(* ) ĠCreated ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Instance Ġ= Ġinstance ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresolution Stack . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠK oin . logger . err (" Error Ġwhile Ġresolving Ġinstance Ġfor Ġclass Ġ'$ clazz Name ' Ġ- Ġerror : Ġ$ e Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ ĠK oin . logger . debug ("$ log Indent !-- Ġ[$ clazz Name ] Ġresolved Ġin Ġ$ duration Ġms ") ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( result Instance Ġ!= Ġnull ) Ġresult Instance !! Ġelse Ġerror (" Could Ġnot Ġcreate Ġinstance Ġfor Ġ$ clazz Name ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġinstances Ġat Ġstart Ġ- Ġtagged Ġeager ĊĠĠĠĠ Ġ* Ġ@ param Ġdefault Parameters ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġcreate E ager Instances ( default Parameters : ĠParameter Definition ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdefinitions Ġ= Ġbean Registry . definitions HashMap . keys . filter Ġ{ Ġit . is E ager Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( definitions . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK oin . logger . info (" Creating Ġinstances Ġ... ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcreate Instances ( definitions , Ġdefault Parameters ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCreate Ġinstances Ġfor Ġgiven Ġdefinition Ġlist Ġ& Ġparams ĊĠĠĠĠ Ġ* Ġ@ param Ġdefinitions ĊĠĠĠĠ Ġ* Ġ@ param Ġparams ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġcreate Instances ( ĊĠĠĠĠĠĠĠ Ġdefinitions : ĠList < Bean Definition <* >>, ĊĠĠĠĠĠĠĠ Ġparams : ĠParameter Definition ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdefinitions . forEach Ġ{ Ġdef Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġproceed Resolution ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdef . clazz , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparams ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĠlistOf ( def ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠD ry ĠRun Ġ- Ġrun Ġeach Ġdefinition ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġdry Run ( default Parameters : ĠParameter Definition ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcreate Instances ( bean Registry . definitions HashMap . keys . distinct (), Ġdefault Parameters ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠClose Ġres ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġclose () Ġ{ ĊĠĠĠĠĠĠĠ ĠK oin . logger . debug ("[ Close ] ĠClosing Ġinstance Ġresolver ") ĊĠĠĠĠĠĠĠ Ġresolution Stack . clear () ĊĠĠĠĠĠĠĠ Ġinstance Factory . clear () ĊĠĠĠĠĠĠĠ Ġbean Registry . clear () ĊĊĠĠĠ Ġ} Ċ } Ċ Ċ type alias ĠDefinition Filter Ġ= Ġ( Bean Definition <* >) Ġ-> ĠBoolean