1 /* 2 * Copyright (C) 2015 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 17 package com.android.ahat; 18 19 import java.util.List; 20 21 /** 22 * The SubsetSelector is that can be added to a page that lets the 23 * user select a limited number of elements to show. 24 * This is used to limit the number of elements shown on a page by default, 25 * requiring the user to explicitly request more, so users not interested in 26 * more don't have to wait for everything to render. 27 */ 28 class SubsetSelector<T> { 29 private static final int kIncrAmount = 1000; 30 private static final int kDefaultShown = 1000; 31 32 private Query mQuery; 33 private String mId; 34 private int mLimit; 35 private List<T> mElements; 36 37 /** 38 * @param id - the name of the query parameter key that should hold 39 * the limit selectors selected value. 40 * @param query - The query for the current page. This is required so the 41 * LimitSelector can add a link to the same page with modified limit 42 * selection. 43 * @param elements - the elements to select from. The collection of elements 44 * should not be modified during the lifetime of the SubsetSelector object. 45 */ 46 public SubsetSelector(Query query, String id, List<T> elements) { 47 mQuery = query; 48 mId = id; 49 mLimit = getSelectedLimit(query, id, elements.size()); 50 mElements = elements; 51 } 52 53 // Return the list of elements included in the selected subset. 54 public List<T> selected() { 55 return mElements.subList(0, mLimit); 56 } 57 58 // Return the list of remaining elements not included in the selected subset. 59 public List<T> remaining() { 60 return mElements.subList(mLimit, mElements.size()); 61 } 62 63 /** 64 * Returns the currently selected limit. 65 * @param query the current page query 66 * @param size the total number of elements to select from 67 * @return the number of selected elements 68 */ 69 private static int getSelectedLimit(Query query, String id, int size) { 70 String value = query.get(id, null); 71 try { 72 int ivalue = Math.min(size, Integer.parseInt(value)); 73 return Math.max(0, ivalue); 74 } catch (NumberFormatException e) { 75 // We can't parse the value as a number. Ignore it. 76 } 77 return Math.min(kDefaultShown, size); 78 } 79 80 // Render the limit selector to the given doc. 81 // It has the form: 82 // (showing X of Y - show none - show less - show more - show all) 83 public void render(Doc doc) { 84 int all = mElements.size(); 85 if (all > kDefaultShown) { 86 DocString menu = new DocString(); 87 menu.appendFormat("(%d of %d elements shown - ", mLimit, all); 88 if (mLimit > 0) { 89 int less = Math.max(0, mLimit - kIncrAmount); 90 menu.appendLink(mQuery.with(mId, 0), DocString.text("show none")); 91 menu.append(" - "); 92 menu.appendLink(mQuery.with(mId, less), DocString.text("show less")); 93 menu.append(" - "); 94 } else { 95 menu.append("show none - show less - "); 96 } 97 if (mLimit < all) { 98 int more = Math.min(mLimit + kIncrAmount, all); 99 menu.appendLink(mQuery.with(mId, more), DocString.text("show more")); 100 menu.append(" - "); 101 menu.appendLink(mQuery.with(mId, all), DocString.text("show all")); 102 menu.append(")"); 103 } else { 104 menu.append("show more - show all)"); 105 } 106 doc.println(menu); 107 } 108 } 109 } 110