1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package androidx.room.integration.testapp.database;
17 
18 import androidx.annotation.NonNull;
19 import androidx.paging.DataSource;
20 import androidx.paging.ItemKeyedDataSource;
21 import androidx.room.InvalidationTracker;
22 
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Set;
26 
27 /**
28  * Sample Room keyed data source.
29  */
30 public class LastNameAscCustomerDataSource extends ItemKeyedDataSource<String, Customer> {
31     private final CustomerDao mCustomerDao;
32     @SuppressWarnings("FieldCanBeLocal")
33     private final InvalidationTracker.Observer mObserver;
34     private SampleDatabase mDb;
35 
factory(final SampleDatabase db)36     public static Factory<String, Customer> factory(final SampleDatabase db) {
37         return new Factory<String, Customer>() {
38             @Override
39             public DataSource<String, Customer> create() {
40                 return new LastNameAscCustomerDataSource(db);
41             }
42         };
43     }
44 
45     /**
46      * Create a DataSource from the customer table of the given database
47      */
48     private LastNameAscCustomerDataSource(SampleDatabase db) {
49         mDb = db;
50         mCustomerDao = db.getCustomerDao();
51         mObserver = new InvalidationTracker.Observer("customer") {
52             @Override
53             public void onInvalidated(@NonNull Set<String> tables) {
54                 invalidate();
55             }
56         };
57         db.getInvalidationTracker().addWeakObserver(mObserver);
58     }
59 
60     @Override
61     public boolean isInvalid() {
62         mDb.getInvalidationTracker().refreshVersionsSync();
63         return super.isInvalid();
64     }
65 
66     @NonNull
67     public static String getKeyStatic(@NonNull Customer customer) {
68         return customer.getLastName();
69     }
70 
71     @NonNull
72     @Override
73     public String getKey(@NonNull Customer customer) {
74         return getKeyStatic(customer);
75     }
76 
77     @Override
78     public void loadInitial(@NonNull LoadInitialParams<String> params,
79             @NonNull LoadInitialCallback<Customer> callback) {
80         String customerName = params.requestedInitialKey;
81         List<Customer> list;
82         if (customerName != null) {
83             // initial keyed load - load before 'customerName',
84             // and load after last item in before list
85             int pageSize = params.requestedLoadSize / 2;
86             String key = customerName;
87             list = mCustomerDao.customerNameLoadBefore(key, pageSize);
88             Collections.reverse(list);
89             if (!list.isEmpty()) {
90                 key = getKey(list.get(list.size() - 1));
91             }
92             list.addAll(mCustomerDao.customerNameLoadAfter(key, pageSize));
93         } else {
94             list = mCustomerDao.customerNameInitial(params.requestedLoadSize);
95         }
96 
97         if (params.placeholdersEnabled && !list.isEmpty()) {
98             String firstKey = getKey(list.get(0));
99             String lastKey = getKey(list.get(list.size() - 1));
100 
101             // only bother counting if placeholders are desired
102             final int position = mCustomerDao.customerNameCountBefore(firstKey);
103             final int count = position + list.size() + mCustomerDao.customerNameCountAfter(lastKey);
104             callback.onResult(list, position, count);
105         } else {
106             callback.onResult(list);
107         }
108     }
109 
110     @Override
111     public void loadAfter(@NonNull LoadParams<String> params,
112             @NonNull LoadCallback<Customer> callback) {
113         callback.onResult(mCustomerDao.customerNameLoadAfter(params.key, params.requestedLoadSize));
114     }
115 
116     @Override
117     public void loadBefore(@NonNull LoadParams<String> params,
118             @NonNull LoadCallback<Customer> callback) {
119         List<Customer> list = mCustomerDao.customerNameLoadBefore(
120                 params.key, params.requestedLoadSize);
121         Collections.reverse(list);
122         callback.onResult(list);
123     }
124 }
125 
126