124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik/* 224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * Copyright (C) 2017 The Android Open Source Project 324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * 424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * you may not use this file except in compliance with the License. 624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * You may obtain a copy of the License at 724418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * 824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * http://www.apache.org/licenses/LICENSE-2.0 924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * 1024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * Unless required by applicable law or agreed to in writing, software 1124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 1224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * See the License for the specific language governing permissions and 1424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * limitations under the License. 1524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik */ 1624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik 17ef346ae131affbba6345e00d833103acc5743c8aChris Craikpackage android.arch.paging; 1824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik 1924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport android.support.annotation.Nullable; 2024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport android.support.annotation.RestrictTo; 21d1b3338562ddc451d50cbca91ce8ec6ef7d8bfe5Chris Craikimport android.support.annotation.WorkerThread; 2224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik 2324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport java.util.ArrayList; 2424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport java.util.Collections; 2524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport java.util.List; 2624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik 2724418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik/** 2824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * Simplest data source form that provides all of its data through a single loadRange() method. 2924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * <p> 3024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * Requires that your data resides in positions <code>0</code> through <code>N</code>, where 31f0d13608aae3b4700d84c1c4532abbea56ea7a28Chris Craik * <code>N</code> is the value returned from {@link #countItems()}. You must return the exact number 3224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * requested, so that the data as returned can be safely prepended/appended to what has already 3324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * been loaded. 3424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * <p> 3524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * For more flexibility in how many items to load, or to avoid counting your data source, override 3624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * {@link PositionalDataSource} directly. 3724418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * 382e9d5136685b07ef5bfabcd3936b1eedb5d24e91Chris Craik * @paramValue type returned by the data source. 3924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * 4024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * @hide 4124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik */ 4224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 432e9d5136685b07ef5bfabcd3936b1eedb5d24e91Chris Craikpublic abstract class BoundedDataSource<Value> extends PositionalDataSource<Value> { 4424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik /** 4524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * Called to load items at from the specified position range. 4624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * 4724418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * @param startPosition Index of first item to load. 4824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * @param loadCount Exact number of items to load. Returning a different number will cause 4924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * an exception to be thrown. 5024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * @return List of loaded items. Null if the BoundedDataSource is no longer valid, and should 5124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik * not be queried again. 5224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik */ 53d1b3338562ddc451d50cbca91ce8ec6ef7d8bfe5Chris Craik @WorkerThread 5424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik @Nullable 552e9d5136685b07ef5bfabcd3936b1eedb5d24e91Chris Craik public abstract List<Value> loadRange(int startPosition, int loadCount); 5624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik 57d1b3338562ddc451d50cbca91ce8ec6ef7d8bfe5Chris Craik @WorkerThread 5824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik @Nullable 5924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik @Override 602e9d5136685b07ef5bfabcd3936b1eedb5d24e91Chris Craik public List<Value> loadAfter(int startIndex, int pageSize) { 61ef346ae131affbba6345e00d833103acc5743c8aChris Craik return loadRange(startIndex, pageSize); 6224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik } 6324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik 64d1b3338562ddc451d50cbca91ce8ec6ef7d8bfe5Chris Craik @WorkerThread 6524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik @Nullable 6624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik @Override 672e9d5136685b07ef5bfabcd3936b1eedb5d24e91Chris Craik public List<Value> loadBefore(int startIndex, int pageSize) { 6824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik if (startIndex < 0) { 6924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik return new ArrayList<>(); 7024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik } 7124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik int loadSize = Math.min(pageSize, startIndex + 1); 7224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik startIndex = startIndex - loadSize + 1; 732e9d5136685b07ef5bfabcd3936b1eedb5d24e91Chris Craik List<Value> result = loadRange(startIndex, loadSize); 7424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik if (result != null) { 7524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik if (result.size() != loadSize) { 7624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik throw new IllegalStateException("invalid number of items returned."); 7724418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik } 7824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik Collections.reverse(result); 7924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik } 8024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik return result; 8124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik } 8224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik} 83