1e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson/*
2e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * Copyright (c) 2007 Mockito contributors
3e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * This program is made available under the terms of the MIT License.
4e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson */
5e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonpackage org.mockito.internal.configuration;
6e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
7e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport org.mockito.configuration.IMockitoConfiguration;
8e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport org.mockito.exceptions.misusing.MockitoConfigurationException;
9e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonimport org.mockito.plugins.MockMaker;
10e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
11e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
12e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson/**
13e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * Loads configuration or extension points available in the classpath.
14e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *
15e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * <p>
16e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * <ul>
17e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     <li>
18e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         Can load the mockito configuration. The user who want to provide his own mockito configuration
19e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         should write the class <code>org.mockito.configuration.MockitoConfiguration</code> that implements
20e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         {@link IMockitoConfiguration}. For example :
21e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         <pre class="code"><code class="java">
22e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * package org.mockito.configuration;
23e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *
24e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * //...
25e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *
26e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * public class MockitoConfiguration implements IMockitoConfiguration {
27e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     boolean enableClassCache() { return false; }
28e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *
29e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     // ...
30e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * }
31e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     </code></pre>
32e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     </li>
33e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     <li>
34e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         Can load available mockito extensions. Currently Mockito only have one extension point the
35e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         {@link MockMaker}. This extension point allows a user to provide his own bytecode engine to build mocks.
36e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         <br>Suppose you wrote an extension to create mocks with some <em>Awesome</em> library, in order to tell
37e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         Mockito to use it you need to put in your classpath
38e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         <ol style="list-style-type: lower-alpha">
39e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *             <li>The implementation itself, for example <code>org.awesome.mockito.AwesomeMockMaker</code>.</li>
40e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *             <li>A file named <code>org.mockito.plugins.MockMaker</code> in a folder named
41e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *             <code>mockito-extensions</code>, the content of this file need to have <strong>one</strong> line with
42e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *             the qualified name <code>org.awesome.mockito.AwesomeMockMaker</code>.</li>
43e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *         </ol>
44e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson *     </li>
45e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * </ul>
46e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson * </p>
47e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson */
48e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinsonpublic class ClassPathLoader {
49e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
50e03a0f42b85425bffd40bcf790819671a7848c1aPaul Duffin    public static final String MOCKITO_CONFIGURATION_CLASS_NAME = "org.mockito.configuration.MockitoConfiguration";
51e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
52e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    /**
53e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson     * @return configuration loaded from classpath or null
54e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson     */
55e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    @SuppressWarnings({"unchecked"})
56e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    public IMockitoConfiguration loadConfiguration() {
572637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        // Trying to get config from classpath
582637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin        Class<?> configClass;
59e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        try {
602637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin            configClass = Class.forName(MOCKITO_CONFIGURATION_CLASS_NAME);
61e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        } catch (ClassNotFoundException e) {
62e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            //that's ok, it means there is no global config, using default one.
63e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return null;
64e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        }
65e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson
66e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        try {
67e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            return (IMockitoConfiguration) configClass.newInstance();
68e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        } catch (ClassCastException e) {
69e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            throw new MockitoConfigurationException("MockitoConfiguration class must implement " + IMockitoConfiguration.class.getName() + " interface.", e);
70e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        } catch (Exception e) {
71e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson            throw new MockitoConfigurationException("Unable to instantiate " + MOCKITO_CONFIGURATION_CLASS_NAME +" class. Does it have a safe, no-arg constructor?", e);
72e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson        }
73e0ae5d7e87b1dd6e789803c1b9615a84bd7488b7Ian Parkinson    }
742637d96c202372854a7c71466ddcc6e90fc4fc53Paul Duffin}
75