/* Ċ Ġ* ĠCopyright ĠC - Dot ĠConsult ants Ġ 2 0 2 0 Ġ- ĠMIT Ġlicense Ċ Ġ*/ Ċ package Ġcom . cdot . lists Ċ Ċ import Ġandroid . app . Application Ċ import Ġandroid . content . Content Resolver Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . SharedPreferences Ċ import Ġandroid . net . Uri Ċ import Ġandroid . util . Log Ċ import Ġcom . cdot . lists . model . Check lists Ċ import Ġorg . json . JSONException Ċ import Ġjava . io .* Ċ import Ġjava . util .* Ċ Ċ /** Ċ Ġ* ĠApplication Ġsingleton Ġthat Ġhandles Ġdata Ġthat Ġis Ġnot Ġspecific Ġto Ġactivities . Ċ Ġ*/ Ċ class ĠList er Ġ: ĠApplication () Ġ{ ĊĠĠĠ Ġ// ĠAlways Ġneed Ġa Ġcheck lists Ġinstance , Ġas Ġa Ġplace Ġto Ġattach Ġlisteners ĊĠĠĠ Ġval Ġlists Ġ= ĠCheck lists () ĊĊĠĠĠ Ġprivate Ġvar Ġlists Are Loaded Ġ= Ġfalse ĊĠĠĠ Ġvar ĠisLoading Ġ= Ġfalse ĊĠĠĠ Ġprivate Ġvar Ġshared Prefs : ĠSharedPreferences ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġload Thread : ĠThread ? Ġ= Ġnull ĊĊĠĠĠ Ġval Ġprefs : ĠSharedPreferences ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( shared Prefs Ġ== Ġnull ) Ġshared Prefs Ġ= Ġget SharedPreferences ( null , ĠContext . MODE _ PRIVATE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġshared Prefs !! ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLoad Ġlists Ġif Ġ( and Ġonly Ġif ) Ġthey Ġhaven 't Ġalready Ġbeen Ġloaded Ġand Ġare Ġres iding Ġin Ġmemory . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġc xt ĠĠĠ Ġui Ġwe Ġare Ġloading Ġfrom ĊĠĠĠĠ Ġ* Ġ@ param Ġon OK ĠĠ Ġcallback ĊĠĠĠĠ Ġ* Ġ@ param Ġon Fail Ġcallback ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġload Lists ( c xt : ĠContext , Ġon OK : ĠSuccess Callback , Ġon Fail : ĠFail Callback ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" load Lists Ġloaded =$ lists Are Loaded Ġloading =$ isLoading ") ĊĠĠĠĠĠĠĠ Ġif Ġ( lists Are Loaded Ġ|| ĠisLoading ) Ġreturn ĊĠĠĠĠĠĠĠ ĠisLoading Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġ// ĠAs ynchronously Ġload Ġthe ĠURI . ĠIf Ġthe Ġload Ġfails , Ġtry Ġthe Ġcache ĊĠĠĠĠĠĠĠ Ġload Thread Ġ= ĠThread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġth red Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuri Ġ= Ġget Uri ( PRE F _ FILE _ URI ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Starting Ġload Ġthread Ġ$ th red Ġto Ġload Ġfrom Ġ$ uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( uri Ġ== Ġnull ) Ġthrow ĠException (" Null ĠURI Ġ( this Ġis ĠOK )") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( get Bool ( PRE F _ DEBUG ) Ġ&& Ġget Bool ( PRE F _ DISABLE _ FILE )) Ġthrow ĠException (" DEBUG ĠFile Ġload Ġdisabled ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstream : ĠInputStream Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( uri . scheme ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContent Resolver . SCHEME _ FILE Ġ-> ĠFileInputStream ( File ( uri . path !! )) Ġ// Ġfor Ġtests ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContent Resolver . SCHEME _ CONTENT Ġ-> Ġc xt . content Resolver . open InputStream ( uri ) !! Ġ// Ġnormal Ġusage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIOException (" Failed Ġto Ġload Ġlists . ĠUnknown Ġuri Ġscheme : Ġ" Ġ+ Ġuri . scheme ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists . from Stream ( stream ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists . for Uri Ġ= Ġuri . toString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġagainst Ġthe Ġcache ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Cache ( Check lists (), Ġc xt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠSuccess Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġsucceeded ( data : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcached Lists Ġ= Ġdata Ġas ĠCheck lists ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Cache Ġre members ĠURI Ġ" Ġ+ Ġcached Lists . for Uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cached Lists . is More Recent Version Of ( lists )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Cache Ġis Ġmore Ġrecent ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġun load Lists () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġcached Lists . clone Children ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists . addChild ( i ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists Are Loaded Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon OK . succeeded ( lists ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Load Ġthread Ġ" Ġ+ Ġth red Ġ+ Ġ" finished ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠFail Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfailed ( code : ĠInt , Ġvar arg Ġargs : ĠAny ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( code , Ġ* args ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠBack ing Ġstore Ġloaded ĠOK Ġbut Ġcache Ġfailed . ĠThat 's ĠOK . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists Are Loaded Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon OK . succeeded ( lists ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Load Ġthread Ġ" Ġ+ Ġth red Ġ+ Ġ" finished ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( se : ĠSecurity Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġopen InputStream Ġdenied , Ġpass Ġback Ġuri _ access _ den ied Ġto Ġrer oute Ġthrough Ġpicker ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġto Ġre - est ablish Ġpermissions ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Security ĠException Ġ" Ġ+ Ġstringify Exception ( se )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ access _ den ied ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Load Ġthread Ġ" Ġ+ Ġth red Ġ+ Ġ" finished ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( uri Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ no _ file ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Exception Ġloading Ġ" Ġ+ Ġstringify Exception ( e )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ file _ load ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Loading Ġ$ lists Ġfrom Ġcache ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġload Cache ( lists , Ġc xt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠSuccess Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġsucceeded ( data : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( uri Ġ!= Ġnull Ġ&& Ġlists . for Uri Ġ!= Ġuri . toString ()) Ġlists . clear () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġlists . size (). toString () Ġ+ Ġ" Ġlists Ġloaded Ġto Ġ" Ġ+ Ġlists Ġ+ Ġ" Ġfrom Ġcache ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists Are Loaded Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon OK . succeeded ( lists ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Load Ġthread Ġ" Ġ+ Ġth red Ġ+ Ġ" finished ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠFail Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġfailed ( code : ĠInt , Ġvar arg Ġargs : ĠAny ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Load Ġthread Ġ" Ġ+ Ġth red Ġ+ Ġ" finished ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġon Fail . failed ( code , Ġ* args ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠisLoading Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Load Ġthread Ġ$ th red Ġfinished Ġloaded =$ lists Are Loaded ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġload Thread !!. start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠLoad Ġfrom Ġthe Ġcache Ġfile Ġinto Ġa ĠCheck lists Ġobject ĊĠĠĠ Ġprivate Ġfun Ġload Cache ( cache Lists : ĠCheck lists , Ġc xt : ĠContext , Ġon OK : ĠSuccess Callback , Ġon Fail : ĠFail Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( get Bool ( PRE F _ DEBUG ) Ġ&& Ġget Bool ( PRE F _ DISABLE _ CACHE )) Ġthrow ĠException (" DEBUG ĠCache Ġload Ġdisabled ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache Lists . from Stream ( c xt . open File Input ( CACHE _ FILE )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon OK . succeeded ( cache Lists ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ce : ĠFileNotFoundException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" FileNotFoundException Ġloading Ġcache Ġ$ CACHE _ FILE : Ġ$ ce ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . sn ack _ no _ cache ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ce : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Failed Ġcache Ġload Ġ" Ġ+ ĠCACHE _ FILE Ġ+ Ġ": Ġ" Ġ+ Ġstringify Exception ( ce )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ cache _ load ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSave Ġa Ġnew Ġcache Ġof Ġthe Ġlists Ġcurrently Ġloaded Ġinto Ġthe Ġapp ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsave Cache ( c xt : ĠContext ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( get Bool ( PRE F _ DEBUG ) Ġ&& Ġget Bool ( PRE F _ DISABLE _ CACHE )) Ġthrow ĠException (" DEBUG ĠCache Ġsave Ġdisabled ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjson String Ġ= Ġlists . toJSON (). toString ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstream Ġ= Ġc xt . open File Output ( CACHE _ FILE , ĠContext . MODE _ PRIVATE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstream . write ( json String . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstream . close () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Saved Ġ" Ġ+ Ġlists . size () Ġ+ Ġ" Ġlists Ġto Ġcache ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Exception Ġsaving Ġto Ġcache : Ġ" Ġ+ Ġstringify Exception ( e )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSave Ġchanges Ġto Ġthe Ġcache Ġand Ġbacking Ġstore ĊĠĠĠĠ Ġ* ĠIf Ġthere 's Ġa Ġfailure Ġsaving Ġto Ġthe Ġbacking Ġstore , Ġwe Ġset Ġlast Store Save Failed Ġin Ġthe Ġpreferences . ĊĠĠĠĠ Ġ* ĠIf Ġthere 's Ġa Ġfailure Ġsaving Ġto Ġthe Ġcache , Ġthis Ġis Ġa Ġmajor Ġproblem Ġthat Ġmay Ġnot Ġbe Ġrecover able . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠonSuccess Ġsucceeded Ġwill Ġbe Ġcalled Ġwith Ġnull Ġparameter ĊĠĠĠĠ Ġ* Ġ@ param Ġon Fail ĠĠĠ Ġfailed Ġwill Ġbe Ġcalled Ġwith Ġa Ġresource Ġid Ġindicating Ġthe Ġtype Ġof Ġfailure ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġsave Lists ( c xt : ĠContext , ĠonSuccess : ĠSuccess Callback , Ġon Fail : ĠFail Callback ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠAlways Ġsave Ġto Ġthe Ġcache . ĊĠĠĠĠĠĠĠ Ġval Ġcache OK Ġ= Ġsave Cache ( c xt ) ĊĠĠĠĠĠĠĠ Ġif Ġ(! cache OK ) Ġon Fail . failed ( R . string . failed _ save _ to _ cache ) ĊĠĠĠĠĠĠĠ Ġval Ġuri Ġ= Ġget Uri ( PRE F _ FILE _ URI ) ĊĠĠĠĠĠĠĠ Ġif Ġ( uri Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cache OK ) ĠonSuccess . succeeded ( null ) Ġelse Ġon Fail . failed ( R . string . failed _ save _ to _ cache _ and _ file ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠLaunch Ġa Ġthread Ġto Ġdo Ġthis Ġsave , Ġso Ġwe Ġdon 't Ġblock Ġthe Ġui Ġthread ĊĠĠĠĠĠĠĠ ĠThread Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdata : ĠByteArray ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġjson String Ġ= Ġlists . toJSON (). toString ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata Ġ= Ġjson String . toByteArray () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠJSON Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Should Ġnever Ġhappen Ġ" Ġ+ Ġstringify Exception ( e )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ save _ to _ uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ Thread ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( get Bool ( PRE F _ DEBUG ) Ġ&& Ġget Bool ( PRE F _ DISABLE _ FILE )) Ġthrow ĠIOException (" DEBUG ĠFile Ġsave Ġdisabled ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstream : ĠOutputStream Ġ= Ġwhen Ġ( uri . scheme ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContent Resolver . SCHEME _ FILE Ġ-> ĠFileOutputStream ( File ( uri . path !! )) Ġ// Ġfor Ġtests ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContent Resolver . SCHEME _ CONTENT Ġ-> Ġc xt . content Resolver . open OutputStream ( uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIOException (" Unknown Ġuri Ġscheme : Ġ" Ġ+ Ġuri . scheme ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġthrow ĠIOException (" Stream Ġopen Ġfailed ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstream . write ( data ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstream . close () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Bool ( PRE F _ LAST _ STORE _ FAILED , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Saved Ġ" Ġ+ Ġlists . size () Ġ+ Ġ" Ġlists Ġto Ġ" Ġ+ Ġuri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonSuccess . succeeded ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( io e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" Exception Ġwhile Ġsaving Ġ" Ġ+ Ġstringify Exception ( io e )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Bool ( PRE F _ LAST _ STORE _ FAILED , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ save _ to _ uri ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cache OK ) ĠonSuccess . succeeded ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. start () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠImport Ġlists Ġfrom Ġthe Ġgiven Ġuri Ġinto Ġthe Ġset Ġof Ġlists Ġmanaged Ġby Ġthe Ġapp ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġimport List ( uri : ĠUri , Ġc xt : ĠContext , Ġon OK : ĠSuccess Callback , Ġon Fail : ĠFail Callback ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Import ing Ġfrom Ġ$ uri ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstream : ĠInputStream Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( uri . scheme ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContent Resolver . SCHEME _ FILE Ġ-> ĠFileInputStream ( File ( uri . path !! )) Ġ// Ġfor Ġtests ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠContent Resolver . SCHEME _ CONTENT Ġ-> Ġc xt . content Resolver . open InputStream ( uri ) !! Ġ// Ġnormal Ġusage ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIOException (" Failed Ġto Ġload Ġlists . ĠUnknown Ġuri Ġscheme : Ġ" Ġ+ Ġuri . scheme ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimport edList s Ġ= ĠCheck lists () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimport edList s . from Stream ( stream ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġret Ġ= Ġimport edList s . clone Children () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ret . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġduplicates : ĠList < String >? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġadded : ĠList < String >? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( eli Ġin Ġret ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( get Bool ( PRE F _ WARN _ DUPLIC ATE ) Ġ&& Ġlists . findBy Text ( eli . text , Ġfalse ) Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġduplicates Ġ= Ġduplicates ?. plus ( eli . text ) Ġ?: Ġarray ListOf ( eli . text ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadded Ġ= Ġadded ?. plus ( eli . text ) Ġ?: Ġarray ListOf ( eli . text ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlists . addChild ( eli ) Ġ// Ġde pop ulates Ġimport edList s , Ġbut Ġnot Ġret ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( duplicates Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ duplicate _ list , Ġduplicates . join ToString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( added Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Lists ( c xt , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠSuccess Callback Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġsucceeded ( data : ĠAny ?) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" Saved Ġimported Ġlists ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon OK . succeeded ( added ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, Ġon Fail ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ( TAG , Ġ" import Ġfailed Ġ" Ġ+ Ġstringify Exception ( e )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġon Fail . failed ( R . string . failed _ import , Ġe . toString ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠEmpty Ġthe Ġobject ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġun load Lists () Ġ{ ĊĠĠĠĠĠĠĠ Ġlists Are Loaded Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġlists . clear () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġa Ġvalue Ġfrom ĠShared ĠPreferences , Ġapplying Ġthe Ġappropriate Ġdefault ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Int ( name : ĠString ): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdef lt Ġ= Ġs Defaults [ name ] Ġas ĠInt ? ĊĠĠĠĠĠĠĠ Ġreturn Ġprefs . getInt ( name , Ġdef lt Ġ?: Ġ 0 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSet Ġa Ġvalue Ġfrom ĠShared ĠPreferences ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġset Int ( name : ĠString , Ġvalue : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġe Ġ= Ġprefs . edit () ĊĠĠĠĠĠĠĠ Ġe . put Int ( name , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġe . apply () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġa Ġvalue Ġfrom ĠShared ĠPreferences , Ġapplying Ġthe Ġappropriate Ġdefault ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Bool ( name : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdef lt Ġ= Ġs Defaults [ name ] Ġas ĠBoolean ? ĊĠĠĠĠĠĠĠ Ġreturn Ġprefs . getBoolean ( name , Ġdef lt Ġ?: Ġfalse ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSet Ġa Ġvalue Ġfrom ĠShared ĠPreferences ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġset Bool ( name : ĠString , Ġvalue : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġe Ġ= Ġprefs . edit () ĊĠĠĠĠĠĠĠ Ġe . put Boolean ( name , Ġvalue ) ĊĠĠĠĠĠĠĠ Ġe . apply () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGet Ġa Ġvalue Ġfrom ĠShared ĠPreferences , Ġapplying Ġthe Ġappropriate Ġdefault ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġget Uri ( name : ĠString ): ĠUri ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdef lt Ġ= Ġs Defaults [ name ] Ġas ĠString ? ĊĠĠĠĠĠĠĠ Ġval Ġur is Ġ= Ġprefs . getString ( name , Ġdef lt ) ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( uris Ġ== Ġnull ) Ġnull Ġelse ĠUri . parse ( uris ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠSet Ġa Ġvalue Ġin ĠShared ĠPreferences ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġset Uri ( name : ĠString , Ġvalue : ĠUri ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġe Ġ= Ġprefs . edit () ĊĠĠĠĠĠĠĠ Ġe . putString ( name , Ġvalue ?. toString ()) ĊĠĠĠĠĠĠĠ Ġe . apply () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCallback Ġused Ġto Ġreport Ġfailures ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinterface ĠFail Callback Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠReturn Ġfalse Ġif Ġit 's Ġunsafe Ġto Ġcontinue Ġwith Ġthe Ġoperation Ġafter Ġrecording Ġthe Ġfailure . ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġcallback Ġmay Ġbe Ġinvoked Ġseveral Ġtimes Ġduring Ġan Ġoperation , Ġbut Ġthe Ġoperation Ġshould ĊĠĠĠĠĠĠĠĠ Ġ* Ġstop Ġif Ġfailed () Ġreturns Ġfalse . ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġcode Ġstring Ġresource Ġ( error ) Ġcode ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġargs Ġto Ġthe Ġresource Ġtemplate ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġthe Ġoperation Ġis Ġsafe Ġto Ġcontinue , Ġfalse Ġotherwise ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġfailed ( code : ĠInt , Ġvar arg Ġargs : ĠAny ): ĠBoolean ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠCallback Ġon Ġsuccess ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinterface ĠSuccess Callback Ġ{ ĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* ĠThe Ġcontract Ġis Ġthat Ġthis Ġwill Ġbe Ġthe Ġlast Ġcall Ġin Ġany Ġsuccessful Ġoperation ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ param Ġdata Ġis Ġarbitrary Ġand Ġdefined Ġby Ġthe Ġoperation ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġfun Ġsucceeded ( data : ĠAny ?) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠShared ĠPreferences ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ GRE Y _ CHECK ED Ġ= Ġ" grey Checked Items " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ ENT I RE _ ROW _ TO GG LES Ġ= Ġ" ent ire Row Toggle s Item " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ LAST _ STORE _ FAILED Ġ= Ġ" last Store Save Failed " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ LEFT _ H AN DED Ġ= Ġ" checkBox On Left Side " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ STRI KE _ CHECK ED Ġ= Ġ" strike Through Checked Items " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ TEXT _ SIZE _ INDEX Ġ= Ġ" text Size Index " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ FILE _ URI Ġ= Ġ" back ing Store " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ WARN _ DUPLIC ATE Ġ= Ġ" warn Duplicates " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ DISABLE _ FILE Ġ= Ġ" disable File " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ DISABLE _ CACHE Ġ= Ġ" disable Cache " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠP REF _ DEBUG Ġ= Ġ" debug " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠCACHE _ FILE Ġ= Ġ" check lists . json " ĊĊĠĠĠĠĠĠĠ Ġ// ĠMust Ġmatch Ġres / values / strings . xml / text _ size _ list ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTEXT _ SIZE _ DEFAULT Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTEXT _ SIZE _ SMALL Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTEXT _ SIZE _ MEDIUM Ġ= Ġ 2 ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTEXT _ SIZE _ LARGE Ġ= Ġ 3 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTAG Ġ= ĠList er :: class . simple Name ĊĊĠĠĠĠĠĠĠ Ġ// ĠInteger Ġpreference Ġdefaults ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġs Defaults : ĠMap < String , ĠAny ?> Ġ= Ġobject Ġ: ĠHashMap < String , ĠAny ?> () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ TEXT _ SIZE _ INDEX , ĠTEXT _ SIZE _ DEFAULT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ FILE _ URI , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ GRE Y _ CHECK ED , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ WARN _ DUPLIC ATE , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ ENT I RE _ ROW _ TO GG LES , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ LAST _ STORE _ FAILED , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ LEFT _ H AN DED , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ STRI KE _ CHECK ED , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ DISABLE _ FILE , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ DISABLE _ CACHE , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġput ( PRE F _ DEBUG , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠUseful Ġfor Ġdebug ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġstringify Exception ( e : ĠException ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsw Ġ= ĠString Writer () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġe . printStackTrace ( PrintWriter ( sw )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsw . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }