1/* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 6package org.mockito.internal.progress; 7 8import org.mockito.ArgumentMatcher; 9import org.mockito.internal.matchers.And; 10import org.mockito.internal.matchers.LocalizedMatcher; 11import org.mockito.internal.matchers.Not; 12import org.mockito.internal.matchers.Or; 13 14import static java.util.Collections.emptyList; 15import static org.mockito.internal.exceptions.Reporter.incorrectUseOfAdditionalMatchers; 16import static org.mockito.internal.exceptions.Reporter.misplacedArgumentMatcher; 17import static org.mockito.internal.exceptions.Reporter.reportNoSubMatchersFound; 18 19import java.util.*; 20 21public class ArgumentMatcherStorageImpl implements ArgumentMatcherStorage { 22 23 private static final int TWO_SUB_MATCHERS = 2; 24 private static final int ONE_SUB_MATCHER = 1; 25 private final Stack<LocalizedMatcher> matcherStack = new Stack<LocalizedMatcher>(); 26 27 public void reportMatcher(ArgumentMatcher<?> matcher) { 28 matcherStack.push(new LocalizedMatcher(matcher)); 29 } 30 31 public List<LocalizedMatcher> pullLocalizedMatchers() { 32 if (matcherStack.isEmpty()) { 33 return emptyList(); 34 } 35 36 List<LocalizedMatcher> lastMatchers = resetStack(); 37 return lastMatchers; 38 } 39 40 public void reportAnd() { 41 assertStateFor("And(?)", TWO_SUB_MATCHERS); 42 43 ArgumentMatcher<?> m1 = popMatcher(); 44 ArgumentMatcher<?> m2 = popMatcher(); 45 46 reportMatcher(new And(m1, m2)); 47 } 48 49 public void reportOr() { 50 assertStateFor("Or(?)", TWO_SUB_MATCHERS); 51 52 ArgumentMatcher<?> m1 = popMatcher(); 53 ArgumentMatcher<?> m2 = popMatcher(); 54 55 reportMatcher(new Or(m1, m2)); 56 } 57 58 public void reportNot() { 59 assertStateFor("Not(?)", ONE_SUB_MATCHER); 60 61 ArgumentMatcher<?> m = popMatcher(); 62 63 reportMatcher(new Not(m)); 64 } 65 66 public void validateState() { 67 if (!matcherStack.isEmpty()) { 68 List<LocalizedMatcher> lastMatchers = resetStack(); 69 throw misplacedArgumentMatcher(lastMatchers); 70 } 71 } 72 73 public void reset() { 74 matcherStack.clear(); 75 } 76 77 private void assertStateFor(String additionalMatcherName, int subMatchersCount) { 78 if (matcherStack.isEmpty()) { 79 throw reportNoSubMatchersFound(additionalMatcherName); 80 } 81 if (matcherStack.size() < subMatchersCount) { 82 List<LocalizedMatcher> lastMatchers = resetStack(); 83 throw incorrectUseOfAdditionalMatchers(additionalMatcherName, subMatchersCount, lastMatchers); 84 } 85 } 86 87 private ArgumentMatcher<?> popMatcher() { 88 return matcherStack.pop().getMatcher(); 89 } 90 91 private List<LocalizedMatcher> resetStack() { 92 ArrayList<LocalizedMatcher> lastMatchers = new ArrayList<LocalizedMatcher>(matcherStack); 93 reset(); 94 return lastMatchers; 95 } 96 97} 98