View Javadoc
1   /*
2    * Copyright 2007 Kasper B. Graversen
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.supercsv.util;
17  
18  import java.lang.reflect.Method;
19  
20  import org.supercsv.exception.SuperCsvReflectionException;
21  
22  /**
23   * This class cache's method lookups. Hence first time it introspects the instance's class, while subsequent method
24   * lookups are super fast.
25   */
26  public class MethodCache {
27  	
28  	/**
29  	 * A cache of setter methods. The three keys are the class the setter is being invoked on, the parameter type of the
30  	 * setter, and the variable name. The value is the setter method.
31  	 */
32  	private final ThreeDHashMap<Class<?>, Class<?>, String, Method> setMethodsCache = new ThreeDHashMap<Class<?>, Class<?>, String, Method>();
33  	
34  	/**
35  	 * A cache of getter methods. The two keys are the name of the class the getter is being invoked on, and the
36  	 * variable name. The value is the getter method.
37  	 */
38  	private final TwoDHashMap<String, String, Method> getCache = new TwoDHashMap<String, String, Method>();
39  	
40  	/**
41  	 * Returns the getter method for field on an object.
42  	 * 
43  	 * @param object
44  	 *            the object
45  	 * @param fieldName
46  	 *            the field name
47  	 * @return the getter associated with the field on the object
48  	 * @throws NullPointerException
49  	 *             if object or fieldName is null
50  	 * @throws SuperCsvReflectionException
51  	 *             if the getter doesn't exist or is not visible
52  	 */
53  	public Method getGetMethod(final Object object, final String fieldName) {
54  		if( object == null ) {
55  			throw new NullPointerException("object should not be null");
56  		} else if( fieldName == null ) {
57  			throw new NullPointerException("fieldName should not be null");
58  		}
59  		
60  		Method method = getCache.get(object.getClass().getName(), fieldName);
61  		if( method == null ) {
62  			method = ReflectionUtils.findGetter(object, fieldName);
63  			getCache.set(object.getClass().getName(), fieldName, method);
64  		}
65  		return method;
66  	}
67  	
68  	/**
69  	 * Returns the setter method for the field on an object.
70  	 * 
71  	 * @param object
72  	 *            the object
73  	 * @param fieldName
74  	 *            the field name
75  	 * @param argumentType
76  	 *            the type to be passed to the setter
77  	 * @param <T>
78  	 *            the object type
79  	 * @return the setter method associated with the field on the object
80  	 * @throws NullPointerException
81  	 *             if object, fieldName or fieldType is null
82  	 * @throws SuperCsvReflectionException
83  	 *             if the setter doesn't exist or is not visible
84  	 */
85  	public <T> Method getSetMethod(final Object object, final String fieldName, final Class<?> argumentType) {
86  		if( object == null ) {
87  			throw new NullPointerException("object should not be null");
88  		} else if( fieldName == null ) {
89  			throw new NullPointerException("fieldName should not be null");
90  		} else if( argumentType == null ) {
91  			throw new NullPointerException("argumentType should not be null");
92  		}
93  		
94  		Method method = setMethodsCache.get(object.getClass(), argumentType, fieldName);
95  		if( method == null ) {
96  			method = ReflectionUtils.findSetter(object, fieldName, argumentType);
97  			setMethodsCache.set(object.getClass(), argumentType, fieldName, method);
98  		}
99  		return method;
100 	}
101 	
102 }