/* Ċ Ġ* ĠSession . kt Ċ Ġ* ĠCopyright ĠÂ© Ġ 1 9 9 3 - 2 0 2 0 , ĠThe ĠAv ail ĠFoundation , ĠLLC . Ċ Ġ* ĠAll Ġrights Ġreserved . Ċ Ġ* Ċ Ġ* ĠRedistribution Ġand Ġuse Ġin Ġsource Ġand Ġbinary Ġforms , Ġwith Ġor Ġwithout Ċ Ġ* Ġmodification , Ġare Ġpermitted Ġprovided Ġthat Ġthe Ġfollowing Ġconditions Ġare Ġmet : Ċ Ġ* Ċ Ġ* Ġ Ġ* ĠRedistributions Ġof Ġsource Ġcode Ġmust Ġretain Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer . Ċ Ġ* Ċ Ġ* Ġ Ġ* ĠRedistributions Ġin Ġbinary Ġform Ġmust Ġreproduce Ġthe Ġabove Ġcopyright Ġnotice , Ġthis Ċ Ġ* ĠĠĠĠ Ġlist Ġof Ġconditions Ġand Ġthe Ġfollowing Ġdisclaimer Ġin Ġthe Ġdocumentation Ċ Ġ* ĠĠĠĠ Ġand / or Ġother Ġmaterials Ġprovided Ġwith Ġthe Ġdistribution . Ċ Ġ* Ċ Ġ* Ġ Ġ* ĠNeither Ġthe Ġname Ġof Ġthe Ġcopyright Ġholder Ġnor Ġthe Ġnames Ġof Ġthe Ġcontributors Ċ Ġ* ĠĠĠ Ġmay Ġbe Ġused Ġto Ġendorse Ġor Ġpromote Ġproducts Ġderived Ġfrom Ġthis Ġsoftware Ċ Ġ* ĠĠĠ Ġwithout Ġspecific Ġprior Ġwritten Ġpermission . Ċ Ġ* Ċ Ġ* ĠTHIS ĠSOFTWARE ĠIS ĠPROVIDED ĠBY ĠTHE ĠCOPYRIGHT ĠHOLDERS ĠAND ĠCONTRIBUTORS Ġ" AS ĠIS " Ċ Ġ* ĠAND ĠANY ĠEXPRESS ĠOR ĠIMPLIED ĠWARRANTIES , ĠINCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠTHE Ċ Ġ* ĠIMPLIED ĠWARRANTIES ĠOF ĠMERCHANTABILITY ĠAND ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE Ċ Ġ* ĠARE ĠDISCLAIMED . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE ĠCOPYRIGHT ĠHOLDER ĠOR ĠCONTRIBUTORS ĠBE Ċ Ġ* ĠLIABLE ĠFOR ĠANY ĠDIRECT , ĠINDIRECT , ĠINCIDENTAL , ĠSPECIAL , ĠEXEMPLARY , ĠOR Ċ Ġ* ĠCONSEQUENTIAL ĠDAMAGES Ġ( INCLUDING , ĠBUT ĠNOT ĠLIMITED ĠTO , ĠPROCUREMENT ĠOF Ċ Ġ* ĠSUBSTITUTE ĠGOODS ĠOR ĠSERVICES ; ĠLOSS ĠOF ĠUSE , ĠDATA , ĠOR ĠPROFITS ; ĠOR ĠBUSINESS Ċ Ġ* ĠINTERRUPTION ) ĠHOWEVER ĠCAUSED ĠAND ĠON ĠANY ĠTHEORY ĠOF ĠLIABILITY , ĠWHETHER ĠIN Ċ Ġ* ĠCONTRACT , ĠSTRICT ĠLIABILITY , ĠOR ĠTORT Ġ( INCLUDING ĠNEGLIGENCE ĠOR ĠOTHERWISE ) Ċ Ġ* ĠARISING ĠIN ĠANY ĠWAY ĠOUT ĠOF ĠTHE ĠUSE ĠOF ĠTHIS ĠSOFTWARE , ĠEVEN ĠIF ĠADVISED ĠOF ĠTHE Ċ Ġ* ĠPOSSIBILITY ĠOF ĠSUCH ĠDAMAGE . Ċ Ġ*/ Ċ Ċ package Ġcom . avail . server . session Ċ Ċ import Ġcom . avail . server . Avail Server Ċ import Ġcom . avail . server . io . Avail Server Channel Ċ import Ġcom . avail . server . io . Disconnect Reason Ċ import Ġcom . avail . server . io . Parent Channel Disconnect Ċ import Ġcom . avail . server . io . files . FileManager Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . logging . Level Ċ Ċ /** Ċ Ġ* Ġ` Session ` Ġis Ġa Ġcontext Ġof Ġdata Ġfor Ġa Ġsingular Ġuser - controlled Ġinstance Ġof Ċ Ġ* Ġan Ġ[ Avail Server ] Ġ` connection `. ĠA Ġ_ connection _ Ġbeing Ġa Ġsingle Ċ Ġ* Ġ[ Avail Server Channel ] Ġthat Ġis Ġa Ċ Ġ* Ġ[ command Ġchannel ][ Avail Server Channel . Protocol State . COMMAND ] Ġand Ġall Ġof Ġits Ċ Ġ* Ġspawn ed Ġ[ child Ġchannels ][ Avail Server Channel ]. ĠA Ġ_ child Ġchannel _ Ġbeing Ġany Ċ Ġ* Ġ` Avail Server Channel ` Ġthat Ġhas Ġbeen Ċ Ġ* Ġ[ up graded ][ Avail Server Channel . Protocol State . EL IG IBLE _ FOR _ UP GR ADE ] Ġinto Ġa Ċ Ġ* Ġ[ non - command Ġchannel ][ Avail Server Channel . Protocol State . COMMAND ]. Ċ Ġ* Ċ Ġ* Ġ@ author ĠRichard ĠAr ri aga Ġ& lt ; rich @ avail lang . org & gt ; Ċ Ġ* Ċ Ġ* Ġ@ property Ġcommand Channel Ċ Ġ* ĠĠ ĠA Ġ[ Avail Server Channel ] Ġthat Ġhas Ġa Ġ[ Avail Server Channel . state ] Ġset Ġto Ċ Ġ* ĠĠ Ġ[ Avail Server Channel . Protocol State . COMMAND ] Ġand Ġis Ġel igible Ġto Ġcreate Ġchild Ċ Ġ* ĠĠ Ġ` Avail Server Channel ` s . Ċ Ġ* Ċ Ġ* Ġ@ constructor Ċ Ġ* ĠConstruct Ġa Ġnew Ġ[ Session ]. Ċ Ġ* Ċ Ġ* Ġ@ param Ġcommand Channel Ċ Ġ* ĠĠ ĠA Ġ[ Avail Server Channel ] Ġthat Ġhas Ġa Ġ[ Avail Server Channel . state ] Ġset Ġto Ċ Ġ* ĠĠ Ġ[ Avail Server Channel . Protocol State . COMMAND ] Ġand Ġis Ġel igible Ġto Ġcreate Ġchild Ċ Ġ* ĠĠ Ġ` Avail Server Channel ` s . Ċ Ġ*/ Ċ class ĠSession Ġconstructor ( val Ġcommand Channel : ĠAv ail Server Channel ) Ċ { Ċ ĉ // ĠTODO Ċ ĉ // Ġ Ġ- ĠMaint ain Ġspace Ġfor Ġuser Ġdata , Ġthis Ġincludes Ċ ĉ // Ġ Ġ- ĠMake Ġspace Ġfor Ġsubscriptions Ġfor Ġupdates / notifications Ċ ĉ // Ġ Ġ- ĠUser Ġcapability Ġmatrix Ġby ĠChannel Type Ġand Ġ" organization ?" ĊĊ ĉ /** Ċĉ Ġ* ĠThe Ġ[ UUID ] Ġthat Ġuniquely Ġidentifies Ġthis Ġ[ Session ]. ĠThis Ġis Ġalso Ġthe Ċĉ Ġ* Ġ[ command Channel ]' s Ġ[ Avail Server Channel . id ]. Ċĉ Ġ*/ Ċ ĉ val Ġid : ĠUUID Ġ= Ġcommand Channel . id ĊĊ ĉ /** Ċĉ Ġ* ĠThe Ġ[ Map ] Ġfrom Ġ[ Avail Server Channel . id ] Ġto Ġ[ Avail Server Channel ] Ġfor Ġall Ċĉ Ġ* Ġthe Ġ` Avail Server Channel ` s Ġcreated Ġby Ġthe Ġ[ command Channel ]. Ċĉ Ġ*/ Ċ ĉ val Ġchild Channels Ġ= ĠConcurrent HashMap < UUID , ĠAv ail Server Channel >() ĊĊ ĉ /** Ċĉ Ġ* ĠThe Ġ[ Disconnect Reason ] Ġindicating Ġwhy Ġthis Ġ[ Session ] Ġwas Ġ[ closed ][ close ]. Ċĉ Ġ*/ Ċ ĉ var Ġdisconnect Reason : ĠDis connect Reason ? Ġ= Ġnull ĊĊ ĉ /** Ċĉ Ġ* Ġ` true ` Ġindicates Ġthis Ġ[ Session ] Ġis Ġactive ; Ġ` false ` Ġindicates Ġthis Ċĉ Ġ* Ġ` Session ` Ġis Ġdisconnected Ġor Ġin Ġthe Ġprocess Ġof Ġdisconnect ing . Ċĉ Ġ*/ Ċ ĉ val ĠisActive Ġ= Ġdisconnect Reason Ġ== Ġnull ĊĊ ĉ /** Ċĉ Ġ* ĠAdd Ġthe Ġchild Ġ[ Avail Server Channel ] Ġto Ġthis Ġ[ Session ] Ġif Ġthis Ġ` Session ` Ċĉ Ġ* Ġ[ is Ġactive ][ isActive ]. ĠIf Ġthe Ġsession Ġis Ġinactive , Ċĉ Ġ* Ġ[ close ][ Avail Server Channel . schedule Close ] Ġthe Ġchild . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġchild Ċĉ Ġ* ĠĠ ĠThe Ġ` Avail Server Channel ` Ġto Ġadd . Ċĉ Ġ*/ Ċ ĉ @ Synchron ized Ċ ĉ fun Ġadd Child Channel Ġ( child : ĠAv ail Server Channel ) Ċ ĉ { Ċĉ ĉ if ( isActive ) Ċĉ ĉ { Ċĉĉ ĉ child Channels [ child . id ] Ġ= Ġchild Ċĉ ĉ } Ċĉ ĉ else Ċĉ ĉ { Ċĉĉ ĉ child . schedule Close ( Parent Channel Disconnect ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠRemove Ġthe Ġchild Ġ[ Avail Server Channel ] Ġto Ġthis Ġ[ Session ] Ġif Ġthis Ġ` Session ` Ċĉ Ġ* Ġ[ is Ġactive ][ isActive ]. Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġchild Ċĉ Ġ* ĠĠ ĠThe Ġ` Avail Server Channel ` Ġto Ġadd . Ċĉ Ġ*/ Ċ ĉ @ Synchron ized Ċ ĉ fun Ġremove Child Channel Ġ( child : ĠAv ail Server Channel ) Ċ ĉ { Ċĉ ĉ if ( isActive ) Ċĉ ĉ { Ċĉĉ ĉ child Channels . remove ( child . id ) Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠThe Ġ[ Free List ] Ġthat Ġcontains Ġ[ FileManager ] Ġcache Ġids Ġfor Ġopened Ġfiles . Ċĉ Ġ*/ Ċ ĉ private Ġval Ġsession File Cache Ġ= ĠFree List < UUID >() ĊĊ ĉ /** Ċĉ Ġ* ĠThe Ġ[ Map ] Ġfrom Ġ[ FileManager ] Ġcache Ġids Ġfor Ġopened Ġfiles Ġto Ġits Ċĉ Ġ* Ġ[ session File Cache ] Ġid . Ċĉ Ġ*/ Ċ ĉ private Ġval Ġfile Cache Id SessionId Ġ= Ġmutable Map Of < UUID , ĠInt >() ĊĊ ĉ /** Ċĉ Ġ* ĠClose Ġthis Ġ[ Session ] Ġand Ġall Ġof Ġits Ġ[ child Channels ]. Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġreason Ċĉ Ġ* ĠĠ ĠThe Ġ[ Disconnect Reason ] Ġfor Ġthe Ġclose . Ċĉ Ġ*/ Ċ ĉ @ Synchron ized Ċ ĉ fun Ġclose Ġ( reason : ĠDis connect Reason ) Ċ ĉ { Ċĉ ĉ disconnect Reason Ġ= Ġreason Ċĉ ĉ child Channels . values . forEach Ġ{ Ċĉĉ ĉ it . schedule Close ( Parent Channel Disconnect ) Ċĉ ĉ } Ċĉ ĉ command Channel . server . sessions . remove ( id ) Ċĉ ĉ file Cache Id SessionId . keys . forEach Ġ{ Ċĉĉ ĉ command Channel . server . file Manager . dere gister Interest ( it ) Ċĉ ĉ } Ċĉ ĉ Avail Server . logger . log ( Level . INFO , Ġ" Session Ġ$ id Ġclosed ") Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠAdd Ġthe Ġ[ FileManager ] Ġcache Ġid Ġto Ġthis Ġ[ Session ] Ġand Ġanswer Ġa Ċĉ Ġ* Ġ` Session `- specific Ġcache Ġkey Ġfor Ġthe Ġfile . Ċĉ Ġ* Ċĉ Ġ* ĠIf Ġthere Ġis Ġalready Ġan Ġid Ġfor Ġthis , Ġthe Ġexisting Ġid Ġis Ġreturned . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġuuid Ċĉ Ġ* ĠĠ ĠThe Ġ` FileManager ` Ġcache Ġid Ġto Ġadd . Ċĉ Ġ* Ġ@ return Ċĉ Ġ* ĠĠ ĠThe Ġsession Ġid Ġfor Ġthe Ġfile Ġthat Ġcan Ġbe Ġused Ġto Ġrefer Ġto Ġthe Ġfile . Ċĉ Ġ*/ Ċ ĉ fun Ġadd File Cache Id Ġ( uuid : ĠUUID ): ĠInt Ġ= Ċĉ ĉ file Cache Id SessionId [ uuid ]?. let Ġ{ Ċĉĉ ĉ // ĠIf Ġwe Ġgot Ġhere , Ġwhich Ġwe Ġshouldn 't Ġunless Ġthe Ġclient Ġ" forgot " Ċĉĉ ĉ // Ġit Ġhad Ġa Ġfile Ġopen Ġand Ġre - requested Ġit , Ġthen Ġthis ĠSession Ġwould Ċĉĉ ĉ // Ġhave Ġbeen Ġdouble - count ed Ġin Ġthe ĠServer File Wrapper 's Ċĉĉ ĉ // Ġinterest Count , Ġwhich Ġneeds Ġto Ġbe Ġadjusted . Ċĉĉ ĉ command Channel . server . file Manager . dere gister Interest ( uuid ) Ċĉĉ ĉ it Ċĉ ĉ } Ġ?: Ġsession File Cache . add ( uuid ). apply Ġ{ Ċĉĉĉ ĉ file Cache Id SessionId [ uuid ] Ġ= Ġthis Ċĉĉ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠRemove Ġthe Ġfile Ġassociated Ġwith Ġthe Ġsession Ġfile Ġid Ġfrom Ġthis Ġ[ Session ] Ċĉ Ġ* Ġand Ġanswer Ġthe Ġ` Session `- specific Ġcache Ġkey Ġfor Ġthe Ġfile Ġif Ġremoved . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġid Ċĉ Ġ* ĠĠ ĠThe Ġsession Ġid Ġfor Ġthe Ġfile Ġto Ġremove . Ċĉ Ġ* Ġ@ return Ċĉ Ġ* ĠĠ ĠThe Ġprovided Ġ` id ` Ġif Ġthere Ġwere Ġsomething Ġat Ġthat Ġlocation Ġto Ġremove Ċĉ Ġ* ĠĠ Ġor Ġ` null ` Ġif Ġthat Ġlocation Ġwas Ġinvalid Ġor Ġempty . Ċĉ Ġ*/ Ċ ĉ fun Ġremove File Cache Id Ġ( id : ĠInt ) Ġ= Ċĉ ĉ session File Cache . remove ( id )?. let Ġ{ Ċĉĉ ĉ command Channel . server . file Manager . dere gister Interest ( it ) Ċĉĉ ĉ file Cache Id SessionId . remove ( it ) Ċĉ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠRemove Ġthe Ġfile Ġassociated Ġwith Ġthe Ġ[ FileManager ] Ġid Ġfrom Ġthis Ġ[ Session ] Ċĉ Ġ* Ġand Ġanswer Ġthe Ġ` Session `- specific Ġcache Ġkey Ġfor Ġthe Ġfile Ġif Ġremoved . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġfile Manager Id Ċĉ Ġ* ĠĠ ĠThe Ġ` FileManager ` Ġid Ġfor Ġthe Ġfile Ġto Ġremove . Ċĉ Ġ* Ġ@ return Ċĉ Ġ* ĠĠ ĠThe Ġprovided Ġ` id ` Ġif Ġthere Ġwere Ġsomething Ġat Ġthat Ġlocation Ġto Ġremove Ċĉ Ġ* ĠĠ Ġor Ġ` null ` Ġif Ġthat Ġlocation Ġwas Ġinvalid Ġor Ġempty . Ċĉ Ġ*/ Ċ ĉ fun Ġremove File Ġ( file Manager Id : ĠUUID ) Ġ= Ċĉ ĉ file Cache Id SessionId [ file Manager Id ]?. let Ġ{ Ċĉĉ ĉ remove File Cache Id ( it ) Ċĉ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠAnswer Ġthe Ġ[ FileManager ] Ġid Ġlinked Ġto Ġthe Ġprovided Ġ[ Free List ] Ġindex Ġid . Ċĉ Ġ* Ċĉ Ġ* Ġ@ param Ġid Ċĉ Ġ* ĠĠ ĠThe Ġlocation Ġin Ġthe Ġ[ session File Cache ] Ġto Ġretrieve Ġthe Ġfile Ġ[ UUID ] Ċĉ Ġ* ĠĠ Ġfrom . Ċĉ Ġ* Ġ@ return Ċĉ Ġ* ĠĠ ĠA Ġ` UUID ` Ġif Ġone Ġis Ġavailable Ġor Ġ` null ` Ġif Ġeither Ġid Ġis Ġinvalid Ġor Ġthe Ċĉ Ġ* ĠĠ Ġid Ġpoints Ġto Ġa Ġlocation Ġwith Ġno Ġstored Ġ[ value ][ Link . value ]. Ċĉ Ġ*/ Ċ ĉ fun ĠgetFile Ġ( id : ĠInt ): ĠUUID ? Ġ= Ġsession File Cache [ id ] Ċ }