1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.reflection;
17
18 import java.lang.annotation.Annotation;
19 import java.lang.reflect.Method;
20 import java.util.Collections;
21 import java.util.Map;
22 import java.util.SortedMap;
23 import java.util.TreeMap;
24
25 import org.apache.ibatis.annotations.Param;
26 import org.apache.ibatis.binding.MapperMethod.ParamMap;
27 import org.apache.ibatis.session.Configuration;
28 import org.apache.ibatis.session.ResultHandler;
29 import org.apache.ibatis.session.RowBounds;
30
31 public class ParamNameResolver {
32
33 public static final String GENERIC_NAME_PREFIX = "param";
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 private final SortedMap<Integer, String> names;
49
50 private boolean hasParamAnnotation;
51
52 public ParamNameResolver(Configuration config, Method method) {
53 final Class<?>[] paramTypes = method.getParameterTypes();
54 final Annotation[][] paramAnnotations = method.getParameterAnnotations();
55 final SortedMap<Integer, String> map = new TreeMap<>();
56 int paramCount = paramAnnotations.length;
57
58 for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
59 if (isSpecialParameter(paramTypes[paramIndex])) {
60
61 continue;
62 }
63 String name = null;
64 for (Annotation annotation : paramAnnotations[paramIndex]) {
65 if (annotation instanceof Param) {
66 hasParamAnnotation = true;
67 name = ((Param) annotation).value();
68 break;
69 }
70 }
71 if (name == null) {
72
73 if (config.isUseActualParamName()) {
74 name = getActualParamName(method, paramIndex);
75 }
76 if (name == null) {
77
78
79 name = String.valueOf(map.size());
80 }
81 }
82 map.put(paramIndex, name);
83 }
84 names = Collections.unmodifiableSortedMap(map);
85 }
86
87 private String getActualParamName(Method method, int paramIndex) {
88 return ParamNameUtil.getParamNames(method).get(paramIndex);
89 }
90
91 private static boolean isSpecialParameter(Class<?> clazz) {
92 return RowBounds.class.isAssignableFrom(clazz) || ResultHandler.class.isAssignableFrom(clazz);
93 }
94
95
96
97
98 public String[] getNames() {
99 return names.values().toArray(new String[0]);
100 }
101
102
103
104
105
106
107
108
109
110 public Object getNamedParams(Object[] args) {
111 final int paramCount = names.size();
112 if (args == null || paramCount == 0) {
113 return null;
114 } else if (!hasParamAnnotation && paramCount == 1) {
115 return args[names.firstKey()];
116 } else {
117 final Map<String, Object> param = new ParamMap<>();
118 int i = 0;
119 for (Map.Entry<Integer, String> entry : names.entrySet()) {
120 param.put(entry.getValue(), args[entry.getKey()]);
121
122 final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
123
124 if (!names.containsValue(genericParamName)) {
125 param.put(genericParamName, args[entry.getKey()]);
126 }
127 i++;
128 }
129 return param;
130 }
131 }
132 }