package Ġcom . xm art labs . fo unt ain . feature Ċ Ċ import Ġandroid . arch . lifecycle . LiveData Ċ import Ġandroid . arch . lifecycle . Mutable LiveData Ċ import Ġandroid . arch . paging . Paged List Ċ import Ġandroid . arch . paging . Paging Request Helper Ċ import Ġcom . xm art labs . fo unt ain . ListResponse Ċ import Ġcom . xm art labs . fo unt ain . Network State Ċ import Ġcom . xm art labs . fo unt ain . adapter . Base Network DataSource Adapter Ċ import Ġcom . xm art labs . fo unt ain . adapter . Network Result Listener Ċ import Ġjava . util . concurrent . Executor Ċ Ċ internal Ġclass ĠP ager Manager < Network Value , ĠNetwork Response Ġ: ĠList Response < out ĠNetwork Value >>( ĊĠĠĠ Ġprivate Ġval Ġnetwork DataSource Adapter : ĠBase Network DataSource Adapter < Network Response >, ĊĠĠĠ Ġprivate Ġval Ġpage d List Config : ĠP aged List . Config , ĊĠĠĠ Ġprivate Ġval Ġio Service Executor : ĠExecutor , ĊĠĠĠ Ġprivate Ġval Ġfirst Page : ĠInt Ċ ) Ġ{ ĊĠ Ġprivate Ġvar ĠisLoading Initial Data Ġ= Ġfalse ĊĠ Ġinternal Ġvar Ġpage Ġ= Ġfirst Page ĊĠ Ġvar Ġhelper Ġ= ĠP aging Request Helper ( io Service Executor ) ĊĠ Ġval Ġnetwork State Ġ= ĠMutable LiveData < Network State >() ĊĊĠ Ġinternal Ġfun Ġon Initial Data Pre loaded () Ġ{ ĊĠĠĠ Ġpage Ġ= Ġ 1 Ġ+ Ġfirst Page Ġ+ Ġpage d List Config . initial Load Size Hint Ġ/ Ġpage d List Config . pageSize ĊĠĠĠ Ġval Ġis Last Page Ġ= Ġ! network DataSource Adapter . can Fetch ( page Ġ= Ġpage Ġ+ Ġ 1 , ĠpageSize Ġ= Ġpage d List Config . pageSize ) ĊĠĠĠ Ġval Ġsuccess Ġ= ĠNetwork State . Loaded ( first Page , Ġpage d List Config . initial Load Size Hint , Ġtrue , Ġis Last Page ) ĊĠĠĠ Ġnetwork State . post Value ( success ) ĊĠ Ġ} ĊĊĠ Ġfun Ġload Initial Data ( process Response : Ġ( request : ĠRequest , Ġresponse : ĠNetwork Response , Ġcallback : ĠCallback ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠ ĠisLoading Initial Data Ġ= Ġtrue ĊĠĠĠĠĠ Ġhelper . run IfNot Running ( Paging Request Helper . RequestType . INITIAL ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcallback Ġ= ĠCallback . from Callback ( it ) ĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest ( first Page , Ġtrue , Ġpage d List Config ) ĊĠĠĠĠĠĠĠ Ġperform Request ( process Response , Ġnetwork State , Ġcallback , Ġrequest ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġload Next Page ( process Response : Ġ( request : ĠRequest , Ġresponse : ĠNetwork Response , Ġcallback : ĠCallback ) Ġ-> ĠUnit ) Ġ{ ĊĠĠĠ Ġval Ġrequest Ġ= ĠRequest ( page , Ġfalse , Ġpage d List Config ) ĊĠĠĠ Ġif Ġ( network DataSource Adapter . can Fetch ( page Ġ= Ġrequest . page , ĠpageSize Ġ= Ġpage d List Config . pageSize )) Ġ{ ĊĠĠĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! isLoading Initial Data ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġhelper . run IfNot Running ( Paging Request Helper . RequestType . AFTER ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcallback Ġ= ĠCallback . from Callback ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġperform Request ( process Response , Ġnetwork State , Ġcallback , Ġrequest ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġreset Data ( ĊĠĠĠĠĠ Ġprocess Response : Ġ( request : ĠRequest , Ġresponse : ĠNetwork Response , Ġcallback : ĠCallback ) Ġ-> ĠUnit ĊĠ Ġ): ĠLive Data < Network State > Ġ{ ĊĠĠĠ Ġval Ġreset Network State Ġ= ĠMutable LiveData < Network State >() ĊĠĠĠ Ġval Ġcallback Ġ= Ġobject Ġ: ĠCallback () Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun ĠonSuccess () Ġ{ ĊĠĠĠĠĠĠĠ Ġhelper Ġ= ĠP aging Request Helper ( io Service Executor ) ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun ĠonError ( throwable : ĠThrowable ) Ġ{} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! isLoading Initial Data ) Ġ{ ĊĠĠĠĠĠĠĠ ĠisLoading Initial Data Ġ= Ġtrue ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Ġ= ĠRequest ( first Page , Ġtrue , Ġpage d List Config ) ĊĠĠĠĠĠĠĠ Ġperform Request ( process Response , Ġreset Network State , Ġcallback , Ġrequest ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġreset Network State . post Value ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNetwork State . Error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIllegalStateException (" The Ġfirst Ġpage Ġcannot Ġbe Ġfetched "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfirst Page , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpage d List Config . initial Load Size Hint , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis Last Page ( page Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġreset Network State ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġcreate Loading State ( page : ĠInt , Ġnext Page : ĠInt , ĠpageSize : ĠInt ): ĠNetwork State . Loading Ġ= ĊĠĠĠĠĠ ĠNetwork State . Loading ( page , ĠpageSize , Ġpage Ġ== Ġfirst Page , Ġis Last Page ( next Page )) ĊĊĠ Ġinternal Ġfun Ġon Initial Data Loaded () Ġ{ ĊĠĠĠ Ġsynchronized ( this ) Ġ{ ĊĠĠĠĠĠ ĠisLoading Initial Data Ġ= Ġfalse ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġperform Request ( ĊĠĠĠĠĠ Ġprocess Response : Ġ( request : ĠRequest , Ġresponse : ĠNetwork Response , Ġcallback : ĠCallback ) Ġ-> ĠUnit , ĊĠĠĠĠĠ Ġnetwork State : ĠMutable LiveData < Network State >, ĊĠĠĠĠĠ Ġcallback : ĠCallback , ĊĠĠĠĠĠ Ġrequest : ĠRequest ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġio Service Executor . execute Ġ{ ĊĠĠĠĠĠ Ġval Ġloading State Ġ= Ġif Ġ( request . is First Page ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġnext Page Ġ= Ġfirst Page Ġ+ Ġ 1 Ġ+ Ġpage d List Config . initial Load Size Hint Ġ/ Ġpage d List Config . pageSize ĊĠĠĠĠĠĠĠ Ġcreate Loading State ( first Page , Ġnext Page , Ġpage d List Config . initial Load Size Hint ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġcreate Loading State ( request . page , Ġrequest . page Ġ+ Ġ 1 , Ġpage d List Config . pageSize ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġnetwork State . post Value ( loading State ) ĊĊĠĠĠĠĠ Ġnetwork DataSource Adapter . page Fetcher . fetch Page ( request . page , Ġrequest . pageSize , ĊĠĠĠĠĠĠĠĠĠ Ġobject Ġ: ĠNetwork Result Listener < Network Response > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonSuccess ( response : ĠNetwork Response ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave In Database IfNeeded ( process Response , Ġnetwork State , Ġrequest , Ġresponse , Ġcallback ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonError ( t : ĠThrowable ) Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonError H app ened ( network State , Ġrequest , Ġt , Ġcallback ) ĊĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġinternal Ġfun ĠonError H app ened ( ĊĠĠĠĠĠ Ġnetwork State : ĠMutable LiveData < Network State >, ĊĠĠĠĠĠ Ġrequest : ĠRequest , ĊĠĠĠĠĠ Ġthrowable : ĠThrowable , ĊĠĠĠĠĠ Ġcallback : ĠCallback ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġif Ġ( request . is First Page ) Ġ{ ĊĠĠĠĠĠ Ġon Initial Data Loaded () ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġis Last Page Ġ= Ġis Last Page ( request . requested Page Count Ġ+ Ġrequest . page Ġ+ Ġ 1 ) ĊĠĠĠ Ġnetwork State . post Value ( ĊĠĠĠĠĠĠĠ ĠNetwork State . Error ( throwable , Ġrequest . page , Ġrequest . pageSize , Ġrequest . is First Page , Ġis Last Page ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġcallback . onError ( throwable ) ĊĠ Ġ} ĊĊĠ Ġinternal Ġfun Ġsave In Database IfNeeded ( ĊĠĠĠĠĠ Ġprocess Response : Ġ( request : ĠRequest , Ġresponse : ĠNetwork Response , Ġcallback : ĠCallback ) Ġ-> ĠUnit , ĊĠĠĠĠĠ Ġnetwork State : ĠMutable LiveData < Network State >, ĊĠĠĠĠĠ Ġrequest : ĠRequest , ĊĠĠĠĠĠ Ġresponse : ĠNetwork Response , ĊĠĠĠĠĠ Ġcallback : ĠCallback ĊĠ Ġ) Ġ{ ĊĠĠĠ Ġprocess Response . invoke ( request , Ġresponse , Ġobject Ġ: ĠCallback () Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun ĠonSuccess () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġis Last Page Ġ= Ġis Last Page ( request . page Ġ+ Ġrequest . pageSize Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġnetwork State . post Value ( Network State . Loaded ( request . page , Ġrequest . pageSize , Ġrequest . is First Page , Ġis Last Page )) ĊĠĠĠĠĠĠĠ Ġpage Ġ= Ġrequest . page Ġ+ Ġrequest . requested Page Count ĊĠĠĠĠĠĠĠ Ġif Ġ( request . is First Page ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġon Initial Data Loaded () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcallback . on Success () ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġoverride Ġfun ĠonError ( throwable : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠ ĠonError H app ened ( network State , Ġrequest , Ġthrowable , Ġcallback ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠ Ġ} ĊĊĠ Ġinternal Ġfun Ġis Last Page ( next Page : ĠInt ) Ġ= ĊĠĠĠĠĠ Ġ! network DataSource Adapter . can Fetch ( page Ġ= Ġnext Page , ĠpageSize Ġ= Ġpage d List Config . pageSize ) ĊĊĠ Ġinternal Ġdata Ġclass ĠRequest ( val Ġpage : ĠInt , Ġval ĠpageSize : ĠInt , Ġval Ġrequested Page Count : ĠInt , Ġval Ġis First Page : ĠBoolean ) Ġ{ ĊĠĠĠ Ġconstructor ( page : ĠInt , Ġis First Page : ĠBoolean , Ġconfig : ĠP aged List . Config ) Ġ: Ġthis ( ĊĠĠĠĠĠĠĠ Ġpage Ġ= Ġpage , ĊĠĠĠĠĠĠĠ ĠpageSize Ġ= Ġif Ġ( is First Page ) Ġconfig . initial Load Size Hint Ġelse Ġconfig . pageSize , ĊĠĠĠĠĠĠĠ Ġrequested Page Count Ġ= Ġif Ġ( is First Page ) Ġconfig . initial Load Size Hint Ġ/ Ġconfig . pageSize Ġelse Ġ 1 , ĊĠĠĠĠĠĠĠ Ġis First Page Ġ= Ġis First Page ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġinternal Ġabstract Ġclass ĠCallback Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠ Ġfun Ġfrom Callback ( callback : ĠP aging Request Helper . Request . Callback ): ĠCallback Ġ= Ġobject Ġ: ĠCallback () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonSuccess () Ġ= Ġcallback . record Success () ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonError ( throwable : ĠThrowable ) Ġ= Ġcallback . record Failure ( throwable ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġabstract Ġfun ĠonSuccess () ĊĠĠĠ Ġabstract Ġfun ĠonError ( throwable : ĠThrowable ) ĊĠ Ġ} Ċ } Ċ