// ĠCopyright Ġ 2 0 0 0 - 2 0 2 0 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ package Ġcom . intellij . configuration Store . scheme Manager Ċ Ċ import Ġcom . intellij . configuration Store . Lazy Scheme Processor Ċ import Ġcom . intellij . configuration Store . Scheme Content Changed Handler Ċ import Ġcom . intellij . openapi . util . io . File Util Rt Ċ import Ġcom . intellij . openapi . vfs . Virtual File Ċ import Ġcom . intellij . util . containers . Collection Factory Ċ import Ġjava . util . function . Function Ċ Ċ internal Ġinterface ĠScheme ChangeEvent Ġ{ ĊĠ Ġfun Ġexecute ( schema Loader : ĠLazy < Scheme Loader < Any , ĠAny >>, Ġscheme Manager : ĠScheme ManagerImpl < Any , ĠAny >) Ċ } Ċ Ċ internal Ġinterface ĠScheme Add OrUpdate Event Ġ{ ĊĠ Ġval Ġfile : ĠVirtual File Ċ } Ċ Ċ private Ġfun Ġfind External izable Scheme By FileName ( fileName : ĠString , Ġscheme Manager : ĠScheme ManagerImpl < Any , ĠAny >): ĠAny ? Ġ{ ĊĠ Ġreturn Ġscheme Manager . sche mes . first OrNull Ġ{ ĊĠĠĠ ĠfileName Ġ== Ġget Scheme FileName ( scheme Manager , Ġit ) ĊĠ Ġ} Ċ } Ċ Ċ internal Ġfun Ġ< T Ġ: ĠAny > Ġget Scheme FileName ( scheme Manager : ĠScheme ManagerImpl < T , ĠT >, Ġscheme : ĠT ): ĠString Ġ{ ĊĠ Ġreturn Ġ"${ scheme Manager . get FileName ( scheme )} ${ scheme Manager . scheme Extension }" Ċ } Ċ Ċ internal Ġfun Ġ< T Ġ: ĠAny > Ġread Scheme FromFile ( file : ĠVirtual File , Ġscheme Loader : ĠScheme Loader < T , ĠT >, Ġscheme Manager : ĠScheme ManagerImpl < T , ĠT >): ĠT ? Ġ{ ĊĠ Ġval ĠfileName Ġ= Ġfile . name ĊĠ Ġif Ġ( file . isDirectory Ġ|| Ġ! scheme Manager . can Read ( fileName )) Ġ{ ĊĠĠĠ Ġreturn Ġnull ĊĠ Ġ} ĊĊĠ Ġreturn Ġcatch And Log ({ Ġfile . path Ġ}) Ġ{ ĊĠĠĠ Ġscheme Loader . load Scheme ( fileName , Ġnull , Ġfile . contents To ByteArray ()) ĊĠ Ġ} Ċ } Ċ Ċ internal Ġclass ĠScheme Change Applic ator ( private Ġval Ġscheme Manager : ĠScheme ManagerImpl < Any , ĠAny >) Ġ{ ĊĠ Ġfun Ġreload ( events : ĠCollection < Scheme ChangeEvent >) Ġ{ ĊĠĠĠ Ġval Ġlazy Scheme Loader Ġ= Ġlazy Ġ{ Ġscheme Manager . create Scheme Loader () Ġ} ĊĠĠĠ Ġdo Reload ( events , Ġlazy Scheme Loader ) ĊĠĠĠ Ġif Ġ( lazy Scheme Loader . isInitialized ()) Ġ{ ĊĠĠĠĠĠ Ġlazy Scheme Loader . value . apply () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġdo Reload ( events : ĠCollection < Scheme ChangeEvent >, Ġlazy Schema Loader : ĠLazy < Scheme Loader < Any , ĠAny >>) Ġ{ ĊĠĠĠ Ġval Ġold Active Scheme Ġ= Ġscheme Manager . active Scheme ĊĠĠĠ Ġvar Ġnew Active Scheme : ĠAny ? Ġ= Ġnull ĊĊĠĠĠ Ġval Ġprocessor Ġ= Ġscheme Manager . processor ĊĠĠĠ Ġfor Ġ( event Ġin Ġsort Scheme Change Events ( events )) Ġ{ ĊĠĠĠĠĠ Ġevent . execute ( lazy Schema Loader , Ġscheme Manager ) ĊĊĠĠĠĠĠ Ġif Ġ( event Ġ! is ĠUpdate Scheme ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġval Ġfile Ġ= Ġevent . file ĊĠĠĠĠĠ Ġif Ġ(! file . isValid ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġval ĠfileName Ġ= Ġfile . name ĊĠĠĠĠĠ Ġval Ġchanged Scheme Ġ= Ġfind External izable Scheme By FileName ( fileName , Ġscheme Manager ) ĊĠĠĠĠĠ Ġif Ġ( call Scheme Content Changed If Supported ( changed Scheme , ĠfileName , Ġfile , Ġscheme Manager )) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġif Ġ( changed Scheme Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlazy Schema Loader . value . remove Updated Scheme ( changed Scheme ) ĊĠĠĠĠĠĠĠ Ġprocessor . on Scheme Deleted ( changed Scheme ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġval Ġnew Scheme Ġ= Ġread Scheme FromFile ( file , Ġlazy Schema Loader . value , Ġscheme Manager ) ĊĊĠĠĠĠĠ Ġfun Ġis New Active Scheme (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( new Active Scheme Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( old Active Scheme Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġreturn Ġnew Scheme Ġ!= Ġnull Ġ&& Ġscheme Manager . current Pending Scheme Name Ġ== Ġprocessor . get Scheme Key ( new Scheme ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġdo Ġnot Ġset Ġactive Ġscheme Ġif Ġcurrently Ġno Ġactive Ġscheme ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġmust Ġbe Ġequals Ġby Ġreference ĊĠĠĠĠĠĠĠĠĠ Ġreturn Ġchanged Scheme Ġ=== Ġold Active Scheme ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġif Ġ( isNew Active Scheme ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġcall Ġon Current Scheme Sw itched Ġonly Ġwhen Ġall Ġschemes Ġre loaded ĊĠĠĠĠĠĠĠ Ġnew Active Scheme Ġ= Ġnew Scheme ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( new Active Scheme Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġscheme Manager . active Scheme Ġ= Ġnew Active Scheme ĊĠĠĠĠĠ Ġprocessor . on Current Scheme Sw itched ( old Active Scheme , Ġnew Active Scheme , Ġfalse ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ // Ġexposed Ġfor Ġtest Ġonly Ċ internal Ġfun Ġsort Scheme Change Events ( input Events : ĠCollection < Scheme ChangeEvent >): ĠCollection < Scheme ChangeEvent > Ġ{ ĊĠ Ġif Ġ( input Events . size Ġ< Ġ 2 ) Ġ{ ĊĠĠĠ Ġreturn Ġinput Events ĊĠ Ġ} ĊĊĠ Ġvar Ġis There Some Remove Event Ġ= Ġfalse ĊĊĊĠ Ġval Ġexisting Add OrUpdate Ġ= ĠCollection Factory . create Small Memory Footprint Set < String >() ĊĠ Ġval Ġremoved File Names Ġ= ĠCollection Factory . create Small Memory Footprint Set < String >() ĊĠ Ġval Ġresult Ġ= ĠArrayList ( input Events ) ĊĠ Ġ// Ġfirst , Ġremove Ġany Ġevent Ġbefore ĠRemove All Schemes Ġand Ġremove ĠRemove Scheme Ġevent Ġif Ġthere Ġis Ġany Ġsubsequent Ġadd / update ĊĠ Ġfor Ġ( i Ġin Ġ( result . size Ġ- Ġ 1 ) Ġdown To Ġ 0 ) Ġ{ ĊĠĠĠ Ġval Ġevent Ġ= Ġresult . get ( i ) ĊĠĠĠ Ġif Ġ( event Ġis ĠRemove All Schemes ) Ġ{ ĊĠĠĠĠĠ Ġfor Ġ( j Ġin Ġ( i Ġ- Ġ 1 ) Ġdown To Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . remove At ( j ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġbreak ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġif Ġ( event Ġis ĠScheme Add OrUpdate Event ) Ġ{ ĊĠĠĠĠĠ Ġval ĠfileName Ġ= Ġevent . file . name ĊĠĠĠĠĠ Ġif Ġ( removed File Names . contains ( fileName )) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . remove At ( i ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġexisting Add OrUpdate . add ( fileName ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġif Ġ( event Ġis ĠRemove Scheme ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( existing Add OrUpdate . contains ( event . fileName )) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . remove At ( i ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġis There Some Remove Event Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġremoved File Names . add ( event . fileName ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġweight ( event : ĠScheme ChangeEvent ): ĠInt Ġ{ ĊĠĠĠ Ġreturn Ġwhen Ġ( event ) Ġ{ ĊĠĠĠĠĠ Ġis ĠScheme Add OrUpdate Event Ġ-> Ġ 1 ĊĠĠĠĠĠ Ġelse Ġ-> Ġ 0 ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġif Ġ( is There Some Remove Event ) Ġ{ ĊĠĠĠ Ġ// Ġsecond , Ġmove Ġall ĠRemove Scheme Ġto Ġfirst Ġplace , Ġto Ġensure Ġthat ĠScheme Loader Ġwill Ġbe Ġnot Ġcreated Ġduring Ġprocessing Ġof ĠRemove Scheme Ġevent ĊĠĠĠ Ġ// Ġ( because ĠRemove Scheme Ġremoves Ġschemes Ġfrom Ġscheme Ġmanager Ġdirectly ) ĊĠĠĠ Ġresult . sort With ( Comparator Ġ{ Ġo 1 , Ġo 2 Ġ-> ĊĠĠĠĠĠ Ġweight ( o 1 ) Ġ- Ġweight ( o 2 ) ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġreturn Ġresult Ċ } Ċ Ċ private Ġfun Ġcall Scheme Content Changed If Supported ( changed Scheme : ĠAny ?, ĠfileName : ĠString , Ġfile : ĠVirtual File , Ġscheme Manager : ĠScheme ManagerImpl < Any , ĠAny >): ĠBoolean Ġ{ ĊĠ Ġif Ġ( changed Scheme Ġ== Ġnull Ġ|| Ġscheme Manager . processor Ġ! is ĠScheme Content Changed Handler < *> Ġ|| Ġscheme Manager . processor Ġ! is ĠLazy Scheme Processor ) Ġ{ ĊĠĠĠ Ġreturn Ġfalse ĊĠ Ġ} ĊĊĠ Ġ// Ġun real istic Ġcase , Ġbut Ġwho Ġknows ĊĠ Ġval Ġexternal Info Ġ= Ġscheme Manager . scheme To Info . get ( changed Scheme ) Ġ?: Ġreturn Ġfalse ĊĠ Ġcatch And Log ({ Ġfile . path Ġ}) Ġ{ ĊĠĠĠ Ġval Ġbytes Ġ= Ġfile . contents To ByteArray () ĊĠĠĠ Ġlazy Pre load Scheme ( bytes , Ġscheme Manager . is Old Scheme Naming ) Ġ{ Ġname , Ġparser Ġ-> ĊĠĠĠĠĠ Ġval Ġattribute Provider Ġ= ĠFunction < String , ĠString ?> Ġ{ Ġparser . getAttribute Value ( null , Ġit ) Ġ} ĊĠĠĠĠĠ Ġval Ġscheme Name Ġ= Ġname ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġscheme Manager . processor . get Scheme Key ( attribute Provider , ĠFile Util Rt . getName Without Extension ( fileName )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow Ġname Is Mis sed ( bytes ) ĊĊĠĠĠĠĠ Ġval Ġdata Holder Ġ= ĠScheme Data Holder Impl ( scheme Manager . processor , Ġbytes , Ġexternal Info ) ĊĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠ Ġ( scheme Manager . processor Ġas ĠScheme Content Changed Handler < Any >). scheme Content Changed ( changed Scheme , Ġscheme Name , Ġdata Holder ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġtrue ĊĠ Ġ} ĊĠ Ġreturn Ġfalse Ċ }