18a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk/* 28a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * Copyright 2017 The Android Open Source Project 38a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * 48a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * Licensed under the Apache License, Version 2.0 (the "License"); 58a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * you may not use this file except in compliance with the License. 68a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * You may obtain a copy of the License at 78a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * 88a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * http://www.apache.org/licenses/LICENSE-2.0 98a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * 108a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * Unless required by applicable law or agreed to in writing, software 118a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * distributed under the License is distributed on an "AS IS" BASIS, 128a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * See the License for the specific language governing permissions and 148a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * limitations under the License. 158a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 168a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1785ef1446b82c8783a50af92c4cb1389fe0d0e907Aurimas Liutikaspackage androidx.slice.core; 188a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 190c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monkimport static android.app.slice.SliceItem.FORMAT_ACTION; 200c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monkimport static android.app.slice.SliceItem.FORMAT_SLICE; 210c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk 228a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monkimport android.text.TextUtils; 238a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 24f68dde011de8fb4d616a09292524869f56d94110Jason Monkimport androidx.annotation.RestrictTo; 2585ef1446b82c8783a50af92c4cb1389fe0d0e907Aurimas Liutikasimport androidx.slice.Slice; 2685ef1446b82c8783a50af92c4cb1389fe0d0e907Aurimas Liutikasimport androidx.slice.SliceItem; 27dcb5e2f13fa8471f62a7f4625b4dc6e449358cbdJason Monk 28f68dde011de8fb4d616a09292524869f56d94110Jason Monkimport java.util.ArrayList; 29f68dde011de8fb4d616a09292524869f56d94110Jason Monkimport java.util.Iterator; 30f68dde011de8fb4d616a09292524869f56d94110Jason Monkimport java.util.List; 31f68dde011de8fb4d616a09292524869f56d94110Jason Monk 328a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk/** 338a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * Utilities for finding content within a Slice. 348a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk * @hide 358a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 368a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 378a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monkpublic class SliceQuery { 388a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 398a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 408a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 418a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk public static boolean hasAnyHints(SliceItem item, String... hints) { 428a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (hints == null) return false; 438a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk List<String> itemHints = item.getHints(); 448a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk for (String hint : hints) { 458a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (itemHints.contains(hint)) { 468a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return true; 478a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 488a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 498a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return false; 508a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 518a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 528a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 538a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 548a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk public static boolean hasHints(SliceItem item, String... hints) { 558a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (hints == null) return true; 568a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk List<String> itemHints = item.getHints(); 578a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk for (String hint : hints) { 588a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (!TextUtils.isEmpty(hint) && !itemHints.contains(hint)) { 598a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return false; 608a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 618a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 628a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return true; 638a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 648a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 658a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 668a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 678a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk public static boolean hasHints(Slice item, String... hints) { 688a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (hints == null) return true; 698a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk List<String> itemHints = item.getHints(); 708a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk for (String hint : hints) { 718a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (!TextUtils.isEmpty(hint) && !itemHints.contains(hint)) { 728a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return false; 738a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 748a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 758a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return true; 768a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 778a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 788a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 798a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 808a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk public static SliceItem findNotContaining(SliceItem container, List<SliceItem> list) { 818a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk SliceItem ret = null; 828a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk while (ret == null && list.size() != 0) { 838a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk SliceItem remove = list.remove(0); 848a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (!contains(container, remove)) { 858a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk ret = remove; 868a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 878a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 888a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return ret; 898a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 908a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 918a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 928a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 932a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk private static boolean contains(SliceItem container, final SliceItem item) { 948a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk if (container == null || item == null) return false; 95f68dde011de8fb4d616a09292524869f56d94110Jason Monk return findFirst(filter(stream(container), new Filter<SliceItem>() { 962a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk @Override 97f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem s) { 982a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk return s == item; 992a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk } 100f68dde011de8fb4d616a09292524869f56d94110Jason Monk }), null) != null; 1018a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1028a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1038a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1048a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1050c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static List<SliceItem> findAll(SliceItem s, String format) { 1060c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return findAll(s, format, (String[]) null, null); 1078a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1088a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1098a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1108a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1110c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static List<SliceItem> findAll(Slice s, String format, String hints, String nonHints) { 1120c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return findAll(s, format, new String[]{ hints }, new String[]{ nonHints }); 1138a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1148a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1158a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1168a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1170c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static List<SliceItem> findAll(SliceItem s, String format, String hints, 1180c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk String nonHints) { 1190c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return findAll(s, format, new String[]{ hints }, new String[]{ nonHints }); 1208a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1218a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1228a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1238a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1242a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk public static List<SliceItem> findAll(Slice s, final String format, final String[] hints, 1252a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk final String[] nonHints) { 126f68dde011de8fb4d616a09292524869f56d94110Jason Monk return collect(filter(stream(s), new Filter<SliceItem>() { 1272a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk @Override 128f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem item) { 1292a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk return checkFormat(item, format) 1302a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk && (hasHints(item, hints) && !hasAnyHints(item, nonHints)); 1312a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk } 132f68dde011de8fb4d616a09292524869f56d94110Jason Monk })); 1338a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1348a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1358a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1368a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1372a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk public static List<SliceItem> findAll(SliceItem s, final String format, final String[] hints, 1382a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk final String[] nonHints) { 139f68dde011de8fb4d616a09292524869f56d94110Jason Monk return collect(filter(stream(s), new Filter<SliceItem>() { 1402a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk @Override 141f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem item) { 1422a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk return checkFormat(item, format) 1432a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk && (hasHints(item, hints) && !hasAnyHints(item, nonHints)); 1442a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk } 145f68dde011de8fb4d616a09292524869f56d94110Jason Monk })); 1468a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1478a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1488a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1498a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1500c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static SliceItem find(Slice s, String format, String hints, String nonHints) { 1510c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return find(s, format, new String[]{ hints }, new String[]{ nonHints }); 1528a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1538a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1548a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1558a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1560c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static SliceItem find(Slice s, String format) { 1570c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return find(s, format, (String[]) null, null); 1588a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1598a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1608a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1618a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1620c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static SliceItem find(SliceItem s, String format) { 1630c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return find(s, format, (String[]) null, null); 1648a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1658a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1668a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1678a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1680c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk public static SliceItem find(SliceItem s, String format, String hints, String nonHints) { 1690c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return find(s, format, new String[]{ hints }, new String[]{ nonHints }); 1708a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1718a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1728a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1738a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 1742a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk public static SliceItem find(Slice s, final String format, final String[] hints, 1752a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk final String[] nonHints) { 176f68dde011de8fb4d616a09292524869f56d94110Jason Monk return findFirst(filter(stream(s), new Filter<SliceItem>() { 1772a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk @Override 178f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem item) { 1792a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk return checkFormat(item, format) 1802a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk && (hasHints(item, hints) && !hasAnyHints(item, nonHints)); 1812a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk } 182f68dde011de8fb4d616a09292524869f56d94110Jason Monk }), null); 1838a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 1848a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 1858a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 1868a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 18798ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk public static SliceItem findSubtype(Slice s, final String format, final String subtype) { 188f68dde011de8fb4d616a09292524869f56d94110Jason Monk return findFirst(filter(stream(s), new Filter<SliceItem>() { 18998ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk @Override 190f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem item) { 19198ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk return checkFormat(item, format) && checkSubtype(item, subtype); 19298ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk } 193f68dde011de8fb4d616a09292524869f56d94110Jason Monk }), null); 19498ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk } 19598ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk 19698ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk /** 19798ae4f80b7244070c20d5c3a16245df5cd0c5df8Jason Monk */ 1982a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk public static SliceItem findSubtype(SliceItem s, final String format, final String subtype) { 199f68dde011de8fb4d616a09292524869f56d94110Jason Monk return findFirst(filter(stream(s), new Filter<SliceItem>() { 2002a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk @Override 201f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem item) { 2022a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk return checkFormat(item, format) && checkSubtype(item, subtype); 2032a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk } 204f68dde011de8fb4d616a09292524869f56d94110Jason Monk }), null); 2050c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk } 2060c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk 2075b2c0ce4135a0531d1b8ddb4bd35698859678b83Mady Mellor /** 2085b2c0ce4135a0531d1b8ddb4bd35698859678b83Mady Mellor */ 2092a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk public static SliceItem find(SliceItem s, final String format, final String[] hints, 2102a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk final String[] nonHints) { 211f68dde011de8fb4d616a09292524869f56d94110Jason Monk return findFirst(filter(stream(s), new Filter<SliceItem>() { 2122a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk @Override 213f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean filter(SliceItem item) { 2142a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk return checkFormat(item, format) 2152a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk && (hasHints(item, hints) && !hasAnyHints(item, nonHints)); 2162a7d0fcd09ed39bbeda29e024c47fca617050094Jason Monk } 217f68dde011de8fb4d616a09292524869f56d94110Jason Monk }), null); 2188a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 2198a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 2200c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk private static boolean checkFormat(SliceItem item, String format) { 2210c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return format == null || format.equals(item.getFormat()); 2220c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk } 2230c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk 2240c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk private static boolean checkSubtype(SliceItem item, String subtype) { 2250c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk return subtype == null || subtype.equals(item.getSubType()); 2260c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk } 2270c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk 2288a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 2298a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 230f68dde011de8fb4d616a09292524869f56d94110Jason Monk public static Iterator<SliceItem> stream(SliceItem slice) { 231f68dde011de8fb4d616a09292524869f56d94110Jason Monk ArrayList<SliceItem> items = new ArrayList<>(); 2328a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk items.add(slice); 2338a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return getSliceItemStream(items); 2348a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 2358a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 2368a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 2378a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 238f68dde011de8fb4d616a09292524869f56d94110Jason Monk public static Iterator<SliceItem> stream(Slice slice) { 239f68dde011de8fb4d616a09292524869f56d94110Jason Monk ArrayList<SliceItem> items = new ArrayList<>(); 2408a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk items.addAll(slice.getItems()); 2418a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return getSliceItemStream(items); 2428a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 2438a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 2448a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk /** 2458a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk */ 246f68dde011de8fb4d616a09292524869f56d94110Jason Monk private static Iterator<SliceItem> getSliceItemStream(final ArrayList<SliceItem> items) { 247f68dde011de8fb4d616a09292524869f56d94110Jason Monk return new Iterator<SliceItem>() { 2488a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk @Override 2498a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk public boolean hasNext() { 2508a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return items.size() != 0; 2518a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 2528a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk 2538a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk @Override 2548a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk public SliceItem next() { 255f68dde011de8fb4d616a09292524869f56d94110Jason Monk SliceItem item = items.remove(0); 2560c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk if (FORMAT_SLICE.equals(item.getFormat()) 2570c76d3038c814e26f15b16ce2e09e28bcbcedcc6Jason Monk || FORMAT_ACTION.equals(item.getFormat())) { 2588a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk items.addAll(item.getSlice().getItems()); 2598a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 2608a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk return item; 2618a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 2628a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk }; 263f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 264f68dde011de8fb4d616a09292524869f56d94110Jason Monk 265f68dde011de8fb4d616a09292524869f56d94110Jason Monk private static <T> List<T> collect(Iterator<T> iter) { 266f68dde011de8fb4d616a09292524869f56d94110Jason Monk List<T> list = new ArrayList<>(); 267f68dde011de8fb4d616a09292524869f56d94110Jason Monk while (iter.hasNext()) list.add(iter.next()); 268f68dde011de8fb4d616a09292524869f56d94110Jason Monk return list; 269f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 270f68dde011de8fb4d616a09292524869f56d94110Jason Monk 271f68dde011de8fb4d616a09292524869f56d94110Jason Monk private static <T> Iterator<T> filter(final Iterator<T> input, final Filter<T> f) { 272f68dde011de8fb4d616a09292524869f56d94110Jason Monk return new Iterator<T>() { 273f68dde011de8fb4d616a09292524869f56d94110Jason Monk T mNext = findNext(); 274f68dde011de8fb4d616a09292524869f56d94110Jason Monk 275f68dde011de8fb4d616a09292524869f56d94110Jason Monk private T findNext() { 276f68dde011de8fb4d616a09292524869f56d94110Jason Monk while (input.hasNext()) { 277f68dde011de8fb4d616a09292524869f56d94110Jason Monk T i = input.next(); 278f68dde011de8fb4d616a09292524869f56d94110Jason Monk if (f.filter(i)) { 279f68dde011de8fb4d616a09292524869f56d94110Jason Monk return i; 280f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 281f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 282f68dde011de8fb4d616a09292524869f56d94110Jason Monk return null; 283f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 284f68dde011de8fb4d616a09292524869f56d94110Jason Monk 285f68dde011de8fb4d616a09292524869f56d94110Jason Monk @Override 286f68dde011de8fb4d616a09292524869f56d94110Jason Monk public boolean hasNext() { 287f68dde011de8fb4d616a09292524869f56d94110Jason Monk return mNext != null; 288f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 289f68dde011de8fb4d616a09292524869f56d94110Jason Monk 290f68dde011de8fb4d616a09292524869f56d94110Jason Monk @Override 291f68dde011de8fb4d616a09292524869f56d94110Jason Monk public T next() { 292f68dde011de8fb4d616a09292524869f56d94110Jason Monk T ret = mNext; 293f68dde011de8fb4d616a09292524869f56d94110Jason Monk mNext = findNext(); 294f68dde011de8fb4d616a09292524869f56d94110Jason Monk return ret; 295f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 296f68dde011de8fb4d616a09292524869f56d94110Jason Monk }; 297f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 298f68dde011de8fb4d616a09292524869f56d94110Jason Monk 299f68dde011de8fb4d616a09292524869f56d94110Jason Monk private static <T> T findFirst(Iterator<T> filter, T def) { 300f68dde011de8fb4d616a09292524869f56d94110Jason Monk while (filter.hasNext()) { 301f68dde011de8fb4d616a09292524869f56d94110Jason Monk T r = filter.next(); 302f68dde011de8fb4d616a09292524869f56d94110Jason Monk if (r != null) return r; 303f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 304f68dde011de8fb4d616a09292524869f56d94110Jason Monk return def; 305f68dde011de8fb4d616a09292524869f56d94110Jason Monk } 306f68dde011de8fb4d616a09292524869f56d94110Jason Monk 307f68dde011de8fb4d616a09292524869f56d94110Jason Monk private interface Filter<T> { 308f68dde011de8fb4d616a09292524869f56d94110Jason Monk boolean filter(T input); 3098a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk } 3100f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton 3110f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton private SliceQuery() { 3120f4ca634bbc43ddff900c35f7d2a43b55d8c830dJake Wharton } 3138a452e96e2308fe9515aa91b8e5b369eeefc25e7Jason Monk} 314