1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5package org.mockito.internal.configuration.injection.scanner;
6
7import org.mockito.Captor;
8import org.mockito.InjectMocks;
9import org.mockito.Mock;
10import org.mockito.MockitoAnnotations;
11import org.mockito.exceptions.Reporter;
12
13import java.lang.reflect.Field;
14import java.util.HashSet;
15import java.util.Set;
16
17/**
18 * Scan field for injection.
19 */
20@SuppressWarnings("deprecation")
21public class InjectMocksScanner {
22    private final Class<?> clazz;
23
24    /**
25     * Create a new InjectMocksScanner for the given clazz on the given instance
26     *
27     * @param clazz    Current class in the hierarchy of the test
28     */
29    public InjectMocksScanner(Class<?> clazz) {
30        this.clazz = clazz;
31    }
32
33
34    /**
35     * Add the fields annotated by @{@link InjectMocks}
36     *
37     * @param mockDependentFields Set of fields annotated by  @{@link InjectMocks}
38     */
39    public void addTo(Set<Field> mockDependentFields) {
40        mockDependentFields.addAll(scan());
41    }
42
43    /**
44     * Scan fields annotated by &#064;InjectMocks
45     *
46     * @return Fields that depends on Mock
47     */
48    private Set<Field> scan() {
49        Set<Field> mockDependentFields = new HashSet<Field>();
50        Field[] fields = clazz.getDeclaredFields();
51        for (Field field : fields) {
52            if (null != field.getAnnotation(InjectMocks.class)) {
53                assertNoAnnotations(field, Mock.class, MockitoAnnotations.Mock.class, Captor.class);
54                mockDependentFields.add(field);
55            }
56        }
57
58        return mockDependentFields;
59    }
60
61    void assertNoAnnotations(final Field field, final Class... annotations) {
62        for (Class annotation : annotations) {
63            if (field.isAnnotationPresent(annotation)) {
64                new Reporter().unsupportedCombinationOfAnnotations(annotation.getSimpleName(), InjectMocks.class.getSimpleName());
65            }
66        }
67    }
68}
69