1 /* 2 * Copyright (C) 2018 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 android.host.test.composer; 17 18 import java.lang.AssertionError; 19 import java.util.Collection; 20 import java.util.Collections; 21 import java.util.List; 22 import java.util.stream.Collectors; 23 24 /** 25 * A {@link Compose} function base class for repeating objects a configurable number of times. 26 */ 27 public abstract class IterateBase<T, U> implements Compose<T, U> { 28 protected static final String ITERATIONS_OPTION_NAME = "iterations"; 29 protected static final int ITERATIONS_DEFAULT_VALUE = 1; 30 31 /** Iteration ordering, i.e. cyclical (ABCABC) or sequential (AABBCC). */ 32 protected enum OrderOptions { CYCLIC, SEQUENTIAL }; 33 protected static final String ORDER_OPTION_NAME = "order"; 34 protected static final OrderOptions ORDER_DEFAULT_VALUE = OrderOptions.CYCLIC; 35 36 protected final int mDefaultValue; 37 protected String mOptionName = ITERATIONS_OPTION_NAME; 38 IterateBase()39 public IterateBase() { 40 this(ITERATIONS_DEFAULT_VALUE); 41 } 42 IterateBase(int defaultIterations)43 public IterateBase(int defaultIterations) { 44 mDefaultValue = defaultIterations; 45 } 46 47 @Override apply(T args, List<U> input)48 public List<U> apply(T args, List<U> input) { 49 int iterations = getIterationsArgument(args); 50 OrderOptions order = getOrdersArgument(args); 51 switch (order) { 52 case CYCLIC: 53 return Collections.nCopies(iterations, input) 54 .stream() 55 .flatMap(Collection::stream) 56 .collect(Collectors.toList()); 57 case SEQUENTIAL: 58 return input.stream() 59 .map(u -> Collections.nCopies(iterations, u)) 60 .flatMap(Collection::stream) 61 .collect(Collectors.toList()); 62 } 63 // We should never get here as the switch statement should exhaust the order options. 64 throw new AssertionError( 65 String.format("Order option \"%s\" is not supported", order)); 66 } 67 68 /** Returns the number of iterations to run from {@code args}. */ getIterationsArgument(T args)69 protected abstract int getIterationsArgument(T args); 70 71 /** Returns the order that the iteration should happen in from {@code args}. */ getOrdersArgument(T args)72 protected abstract OrderOptions getOrdersArgument(T args); 73 74 /** Returns the option name to supply values to this iterator. */ getOptionName()75 protected String getOptionName() { 76 return mOptionName; 77 } 78 79 /** Sets the option name for supply values to this iterator. */ setOptionName(String name)80 public void setOptionName(String name) { 81 mOptionName = name; 82 } 83 } 84