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.creation.cglib;
6
7import java.io.Serializable;
8import java.lang.reflect.Field;
9
10import org.mockito.internal.creation.MockitoMethodProxy;
11import org.mockito.cglib.proxy.MethodProxy;
12
13public class CGLIBHacker implements Serializable {
14
15    private static final long serialVersionUID = -4389233991416356668L;
16
17    public void setMockitoNamingPolicy(MockitoMethodProxy mockitoMethodProxy) {
18        try {
19            MethodProxy methodProxy = mockitoMethodProxy.getMethodProxy();
20            Field createInfoField = reflectOnCreateInfo(methodProxy);
21            createInfoField.setAccessible(true);
22            Object createInfo = createInfoField.get(methodProxy);
23            Field namingPolicyField = createInfo.getClass().getDeclaredField("namingPolicy");
24            namingPolicyField.setAccessible(true);
25            if (namingPolicyField.get(createInfo) == null) {
26                namingPolicyField.set(createInfo, MockitoNamingPolicy.INSTANCE);
27            }
28        } catch (Exception e) {
29            throw new RuntimeException(
30                            "Unable to set MockitoNamingPolicy on cglib generator which creates FastClasses", e);
31        }
32    }
33
34    @SuppressWarnings("unchecked")
35    private Field reflectOnCreateInfo(MethodProxy methodProxy) throws SecurityException, NoSuchFieldException {
36
37        Class cglibMethodProxyClass = methodProxy.getClass();
38        // in case methodProxy was extended by user, let's traverse the object
39        // graph to find the cglib methodProxy
40        // with all the fields we would like to change
41        while (cglibMethodProxyClass != MethodProxy.class) {
42            cglibMethodProxyClass = methodProxy.getClass().getSuperclass();
43        }
44        return cglibMethodProxyClass.getDeclaredField("createInfo");
45    }
46}