1 /* 2 * Copyright (c) 2007 Mockito contributors 3 * This program is made available under the terms of the MIT License. 4 */ 5 package org.mockito.internal.configuration.injection.filter; 6 7 import static org.mockito.internal.util.MockUtil.getMockName; 8 9 import java.lang.reflect.Field; 10 import java.util.ArrayList; 11 import java.util.Collection; 12 import java.util.List; 13 14 public class NameBasedCandidateFilter implements MockCandidateFilter { 15 private final MockCandidateFilter next; 16 17 public NameBasedCandidateFilter(MockCandidateFilter next) { 18 this.next = next; 19 } 20 21 public OngoingInjector filterCandidate(final Collection<Object> mocks, 22 final Field candidateFieldToBeInjected, 23 final List<Field> allRemainingCandidateFields, 24 final Object injectee) { 25 if (mocks.size() == 1 26 && anotherCandidateMatchesMockName(mocks, candidateFieldToBeInjected, allRemainingCandidateFields)) { 27 return OngoingInjector.nop; 28 } 29 30 return next.filterCandidate(tooMany(mocks) ? selectMatchingName(mocks, candidateFieldToBeInjected) : mocks, 31 candidateFieldToBeInjected, 32 allRemainingCandidateFields, 33 injectee); 34 } 35 36 private boolean tooMany(Collection<Object> mocks) { 37 return mocks.size() > 1; 38 } 39 40 private List<Object> selectMatchingName(Collection<Object> mocks, Field candidateFieldToBeInjected) { 41 List<Object> mockNameMatches = new ArrayList<Object>(); 42 for (Object mock : mocks) { 43 if (candidateFieldToBeInjected.getName().equals(getMockName(mock).toString())) { 44 mockNameMatches.add(mock); 45 } 46 } 47 return mockNameMatches; 48 } 49 50 /* 51 * In this case we have to check whether we have conflicting naming 52 * fields. E.g. 2 fields of the same type, but we have to make sure 53 * we match on the correct name. 54 * 55 * Therefore we have to go through all other fields and make sure 56 * whenever we find a field that does match its name with the mock 57 * name, we should take that field instead. 58 */ 59 private boolean anotherCandidateMatchesMockName(final Collection<Object> mocks, 60 final Field candidateFieldToBeInjected, 61 final List<Field> allRemainingCandidateFields) { 62 String mockName = getMockName(mocks.iterator().next()).toString(); 63 64 for (Field otherCandidateField : allRemainingCandidateFields) { 65 if (!otherCandidateField.equals(candidateFieldToBeInjected) 66 && otherCandidateField.getType().equals(candidateFieldToBeInjected.getType()) 67 && otherCandidateField.getName().equals(mockName)) { 68 return true; 69 } 70 } 71 return false; 72 } 73 } 74