12637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin/*
22637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * Copyright (c) 2007 Mockito contributors
32637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin * This program is made available under the terms of the MIT License.
42637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin */
52637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpackage org.mockito.internal.creation;
62637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
72637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.MockSettings;
82637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
92637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.internal.exceptions.Reporter.*;
102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.creation.settings.CreationSettings;
112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.debugging.VerboseMockInvocationLogger;
122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.util.MockCreationValidator;
132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.internal.util.MockNameImpl;
142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.listeners.InvocationListener;
152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.mock.MockCreationSettings;
162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.mock.MockName;
172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.mock.SerializableMode;
182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport org.mockito.stubbing.Answer;
192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.io.Serializable;
212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.util.HashSet;
222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.util.List;
232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport java.util.Set;
242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinimport static org.mockito.internal.util.collections.Sets.newSet;
262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin@SuppressWarnings("unchecked")
282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffinpublic class MockSettingsImpl<T> extends CreationSettings<T> implements MockSettings, MockCreationSettings<T> {
292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private static final long serialVersionUID = 4475297236197939569L;
312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private boolean useConstructor;
322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private Object outerClassInstance;
332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings serializable() {
352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return serializable(SerializableMode.BASIC);
362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings serializable(SerializableMode mode) {
392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.serializableMode = mode;
402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings extraInterfaces(Class<?>... extraInterfaces) {
442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        if (extraInterfaces == null || extraInterfaces.length == 0) {
452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            throw extraInterfacesRequiresAtLeastOneInterface();
462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        for (Class<?> i : extraInterfaces) {
492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (i == null) {
502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                throw extraInterfacesDoesNotAcceptNullParameters();
512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            } else if (!i.isInterface()) {
522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                throw extraInterfacesAcceptsOnlyInterfaces(i);
532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.extraInterfaces = newSet(extraInterfaces);
562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockName getMockName() {
602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return mockName;
612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public Set<Class<?>> getExtraInterfaces() {
642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return extraInterfaces;
652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public Object getSpiedInstance() {
682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return spiedInstance;
692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings name(String name) {
722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.name = name;
732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings spiedInstance(Object spiedInstance) {
772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.spiedInstance = spiedInstance;
782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings defaultAnswer(Answer defaultAnswer) {
822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.defaultAnswer = defaultAnswer;
832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        if (defaultAnswer == null) {
842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            throw defaultAnswerDoesNotAcceptNullParameter();
852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
862637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
872637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
882637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
892637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public Answer<Object> getDefaultAnswer() {
902637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return defaultAnswer;
912637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
922637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
932637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettingsImpl<T> stubOnly() {
942637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.stubOnly = true;
952637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
962637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
972637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
982637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings useConstructor() {
992637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.useConstructor = true;
1002637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
1012637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1022637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1032637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings outerInstance(Object outerClassInstance) {
1042637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        this.outerClassInstance = outerClassInstance;
1052637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
1062637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1072637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1082637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public boolean isUsingConstructor() {
1092637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return useConstructor;
1102637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1112637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1122637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public Object getOuterClassInstance() {
1132637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return outerClassInstance;
1142637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1152637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1162637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public boolean isStubOnly() {
1172637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this.stubOnly;
1182637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1192637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1202637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings verboseLogging() {
1212637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        if (!invocationListenersContainsType(VerboseMockInvocationLogger.class)) {
1222637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            invocationListeners(new VerboseMockInvocationLogger());
1232637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1242637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
1252637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1262637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1272637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockSettings invocationListeners(InvocationListener... listeners) {
1282637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        if (listeners == null || listeners.length == 0) {
1292637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            throw invocationListenersRequiresAtLeastOneListener();
1302637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1312637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        for (InvocationListener listener : listeners) {
1322637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (listener == null) {
1332637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                throw invocationListenerDoesNotAcceptNullParameters();
1342637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
1352637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            this.invocationListeners.add(listener);
1362637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1372637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this;
1382637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1392637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1402637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private boolean invocationListenersContainsType(Class<?> clazz) {
1412637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        for (InvocationListener listener : invocationListeners) {
1422637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            if (listener.getClass().equals(clazz)) {
1432637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin                return true;
1442637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            }
1452637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1462637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return false;
1472637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1482637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1492637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public List<InvocationListener> getInvocationListeners() {
1502637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return this.invocationListeners;
1512637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1522637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1532637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public boolean hasInvocationListeners() {
1542637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return !invocationListeners.isEmpty();
1552637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1562637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public Class<T> getTypeToMock() {
1582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return typeToMock;
1592637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1612637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    public MockCreationSettings<T> confirm(Class<T> typeToMock) {
1622637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return validatedSettings(typeToMock, this);
1632637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1642637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1652637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private static <T> CreationSettings<T> validatedSettings(Class<T> typeToMock, CreationSettings<T> source) {
1662637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        MockCreationValidator validator = new MockCreationValidator();
1672637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1682637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        validator.validateType(typeToMock);
1692637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        validator.validateExtraInterfaces(typeToMock, source.getExtraInterfaces());
1702637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        validator.validateMockedType(typeToMock, source.getSpiedInstance());
1712637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1722637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //TODO SF - add this validation and also add missing coverage
1732637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin//        validator.validateDelegatedInstance(classToMock, settings.getDelegatedInstance());
1742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1752637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        validator.validateConstructorUse(source.isUsingConstructor(), source.getSerializableMode());
1762637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1772637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        //TODO SF - I don't think we really need CreationSettings type
1782637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        CreationSettings<T> settings = new CreationSettings<T>(source);
1792637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        settings.setMockName(new MockNameImpl(source.getName(), typeToMock));
1802637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        settings.setTypeToMock(typeToMock);
1812637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        settings.setExtraInterfaces(prepareExtraInterfaces(source));
1822637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return settings;
1832637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1842637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1852637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    private static Set<Class<?>> prepareExtraInterfaces(CreationSettings settings) {
1862637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Set<Class<?>> interfaces = new HashSet<Class<?>>(settings.getExtraInterfaces());
1872637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        if(settings.isSerializable()) {
1882637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            interfaces.add(Serializable.class);
1892637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        }
1902637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        return interfaces;
1912637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin    }
1922637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
1932637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin}
1942637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin
195