/* * Copyright (c) 2006 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit.internal.expectations; import java.lang.reflect.*; import java.util.*; import javax.annotation.*; final class SequenceOfReturnValues { @Nonnull private final Expectation expectation; @Nonnull private final Class<?> returnType; @Nullable private final Object firstValue; @Nonnull private final Object[] remainingValues; SequenceOfReturnValues( @Nonnull Expectation expectation, @Nullable Object firstValue, @Nonnull Object[] remainingValues) { this.expectation = expectation; returnType = expectation.getReturnType(); this.firstValue = firstValue; this.remainingValues = remainingValues; } boolean addResultWithSequenceOfValues() { boolean added = false; if (returnType != void.class) { if (returnType.isArray()) { added = addValuesInArrayIfApplicable(); } else if (Iterator.class.isAssignableFrom(returnType)) { added = addValuesInIteratorIfApplicable(); } else if (Iterable.class.isAssignableFrom(returnType)) { added = addValuesInIterableIfApplicable(); } } return added; } private boolean addValuesInArrayIfApplicable() { if (firstValue == null || !firstValue.getClass().isArray()) { addArrayAsReturnValue(); return true; } return false; } private void addArrayAsReturnValue() { Class<?> elementType = returnType.getComponentType(); int n = 1 + remainingValues.length; Object values = Array.newInstance(elementType, n); setArrayElement(elementType, values, 0, firstValue); for (int i = 1; i < n; i++) { setArrayElement(elementType, values, i, remainingValues[i - 1]); } expectation.getResults().addReturnValue(values); } private static void setArrayElement(Class<?> elementType, Object array, int index, @Nullable Object value) { Object arrayValue = value; if (value != null) { if (elementType == byte.class || elementType == Byte.class) { arrayValue = ((Number) value).byteValue(); } else if (elementType == short.class || elementType == Short.class) { arrayValue = ((Number) value).shortValue(); } } Array.set(array, index, arrayValue); } private boolean addValuesInIteratorIfApplicable() { if (firstValue == null || !Iterator.class.isAssignableFrom(firstValue.getClass())) { List<Object> values = new ArrayList<Object>(1 + remainingValues.length); addAllValues(values); expectation.getResults().addReturnValue(values.iterator()); return true; } return false; } private void addAllValues(@Nonnull Collection<Object> values) { values.add(firstValue); Collections.addAll(values, remainingValues); } private boolean addValuesInIterableIfApplicable() { if (firstValue == null || !Iterable.class.isAssignableFrom(firstValue.getClass())) { if (returnType.isAssignableFrom(List.class)) { List<Object> values = new ArrayList<Object>(1 + remainingValues.length); addReturnValues(values); return true; } else if (returnType.isAssignableFrom(Set.class)) { Set<Object> values = new LinkedHashSet<Object>(1 + remainingValues.length); addReturnValues(values); return true; } else if (returnType.isAssignableFrom(SortedSet.class)) { addReturnValues(new TreeSet<Object>()); return true; } } return false; } private void addReturnValues(@Nonnull Collection<Object> values) { addAllValues(values); expectation.getResults().addReturnValue(values); } }