/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 7 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ġtech . asc end io . mv vm . data . repository Ċ Ċ import Ġandroid . arch . lifecycle . LiveData Ċ import Ġandroid . arch . lifecycle . Mediator LiveData Ċ import Ġandroid . support . annotation . MainThread Ċ import Ġandroid . support . annotation . Worker Thread Ċ import Ġtech . asc end io . mv vm . data . api . Api Empty Response Ċ import Ġtech . asc end io . mv vm . data . api . Api ErrorResponse Ċ import Ġtech . asc end io . mv vm . data . api . ApiResponse Ċ import Ġtech . asc end io . mv vm . data . api . Api Success Response Ċ import Ġtech . asc end io . mv vm . data . vo . Resource Ċ import Ġtech . asc end io . mv vm . util . App Executors Ċ Ċ /** Ċ Ġ* ĠA Ġgeneric Ġclass Ġthat Ġcan Ġprovide Ġa Ġresource Ġbacked Ġby Ġboth Ġthe Ġsqlite Ġdatabase Ġand Ġthe Ġnetwork . Ċ Ġ* Ċ Ġ* Ċ Ġ* ĠYou Ġcan Ġread Ġmore Ġabout Ġit Ġin Ġthe Ġ[ Architecture Ċ Ġ* ĠGuide ]( https :// developer . android . com / arch ). Ċ Ġ* Ġ@ param Ġ< Result Type > Ċ Ġ* Ġ@ param Ġ< RequestType > Ċ </ RequestType ></ Result Type > Ġ*/ Ċ abstract Ġclass ĠNetwork Bound Resource < Result Type , ĠRequest Type > Ċ @ MainThread Ġconstructor ( private Ġval Ġapp Executors : ĠApp Executors ) Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġresult Ġ= ĠMed iator LiveData < Resource < Result Type >>() ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . value Ġ= ĠResource . loading ( null ) ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" Le aking This ") ĊĠĠĠĠĠĠĠ Ġval Ġdb Source Ġ= Ġload From Db () ĊĠĠĠĠĠĠĠ Ġresult . add Source ( db Source ) Ġ{ Ġdata Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . remove Source ( db Source ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( should Fetch ( data )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfetch From Network ( db Source ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Source ( db Source ) Ġ{ ĠnewData Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( Resource . success ( new Data )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprivate Ġfun ĠsetValue ( newValue : ĠResource < Result Type >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( result . value Ġ!= ĠnewValue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . value Ġ= ĠnewValue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch From Network ( db Source : ĠLive Data < Result Type >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġapi Response Ġ= Ġcreate Call () ĊĠĠĠĠĠĠĠ Ġ// Ġwe Ġre - attach Ġdb Source Ġas Ġa Ġnew Ġsource , Ġit Ġwill Ġdispatch Ġits Ġlatest Ġvalue Ġquickly ĊĠĠĠĠĠĠĠ Ġresult . add Source ( db Source ) Ġ{ ĠnewData Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( Resource . loading ( new Data )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġresult . add Source ( api Response ) Ġ{ Ġresponse Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . remove Source ( api Response ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . remove Source ( db Source ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( response ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠApi Success Response Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Executors . disk IO (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsave Call Result ( process Response ( response )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Executors . main Thread (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġspec ially Ġrequest Ġa Ġnew Ġlive Ġdata , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġotherwise Ġwe Ġwill Ġget Ġimmediately Ġlast Ġcached Ġvalue , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwhich Ġmay Ġnot Ġbe Ġupdated Ġwith Ġlatest Ġresults Ġreceived Ġfrom Ġnetwork . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Source ( load From Db ()) Ġ{ ĠnewData Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( Resource . success ( new Data )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠApi Empty Response Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Executors . main Thread (). execute Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġreload Ġfrom Ġdisk Ġwhatever Ġwe Ġhad ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Source ( load From Db ()) Ġ{ ĠnewData Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( Resource . success ( new Data )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠApi ErrorResponse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġon Fetch Failed () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Source ( db Source ) Ġ{ ĠnewData Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠsetValue ( Resource . error ( response . errorMessage , ĠnewData )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprotected Ġopen Ġfun Ġon Fetch Failed () Ġ{} ĊĊĠĠĠ Ġfun Ġas LiveData () Ġ= Ġresult Ġas ĠLive Data < Resource < Result Type >> ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprotected Ġopen Ġfun Ġprocess Response ( response : ĠApi Success Response < RequestType >) Ġ= Ġresponse . body ĊĊĠĠĠ Ġ@ Worker Thread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġsave Call Result ( items : ĠRequest Type ) ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġshould Fetch ( data : ĠResult Type ?): ĠBoolean ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġload From Db (): ĠLive Data < Result Type > ĊĊĠĠĠ Ġ@ MainThread ĊĠĠĠ Ġprotected Ġabstract Ġfun Ġcreate Call (): ĠLive Data < ApiResponse < RequestType >> Ċ } Ċ