1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.type;
17
18 import java.math.BigDecimal;
19 import java.math.BigInteger;
20 import java.sql.ResultSet;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.Set;
31
32 import org.apache.ibatis.io.ResolverUtil;
33 import org.apache.ibatis.io.Resources;
34
35
36
37
38 public class TypeAliasRegistry {
39
40 private final Map<String, Class<?>> typeAliases = new HashMap<>();
41
42 public TypeAliasRegistry() {
43 registerAlias("string", String.class);
44
45 registerAlias("byte", Byte.class);
46 registerAlias("char", Character.class);
47 registerAlias("character", Character.class);
48 registerAlias("long", Long.class);
49 registerAlias("short", Short.class);
50 registerAlias("int", Integer.class);
51 registerAlias("integer", Integer.class);
52 registerAlias("double", Double.class);
53 registerAlias("float", Float.class);
54 registerAlias("boolean", Boolean.class);
55
56 registerAlias("byte[]", Byte[].class);
57 registerAlias("char[]", Character[].class);
58 registerAlias("character[]", Character[].class);
59 registerAlias("long[]", Long[].class);
60 registerAlias("short[]", Short[].class);
61 registerAlias("int[]", Integer[].class);
62 registerAlias("integer[]", Integer[].class);
63 registerAlias("double[]", Double[].class);
64 registerAlias("float[]", Float[].class);
65 registerAlias("boolean[]", Boolean[].class);
66
67 registerAlias("_byte", byte.class);
68 registerAlias("_char", char.class);
69 registerAlias("_character", char.class);
70 registerAlias("_long", long.class);
71 registerAlias("_short", short.class);
72 registerAlias("_int", int.class);
73 registerAlias("_integer", int.class);
74 registerAlias("_double", double.class);
75 registerAlias("_float", float.class);
76 registerAlias("_boolean", boolean.class);
77
78 registerAlias("_byte[]", byte[].class);
79 registerAlias("_char[]", char[].class);
80 registerAlias("_character[]", char[].class);
81 registerAlias("_long[]", long[].class);
82 registerAlias("_short[]", short[].class);
83 registerAlias("_int[]", int[].class);
84 registerAlias("_integer[]", int[].class);
85 registerAlias("_double[]", double[].class);
86 registerAlias("_float[]", float[].class);
87 registerAlias("_boolean[]", boolean[].class);
88
89 registerAlias("date", Date.class);
90 registerAlias("decimal", BigDecimal.class);
91 registerAlias("bigdecimal", BigDecimal.class);
92 registerAlias("biginteger", BigInteger.class);
93 registerAlias("object", Object.class);
94
95 registerAlias("date[]", Date[].class);
96 registerAlias("decimal[]", BigDecimal[].class);
97 registerAlias("bigdecimal[]", BigDecimal[].class);
98 registerAlias("biginteger[]", BigInteger[].class);
99 registerAlias("object[]", Object[].class);
100
101 registerAlias("map", Map.class);
102 registerAlias("hashmap", HashMap.class);
103 registerAlias("list", List.class);
104 registerAlias("arraylist", ArrayList.class);
105 registerAlias("collection", Collection.class);
106 registerAlias("iterator", Iterator.class);
107
108 registerAlias("ResultSet", ResultSet.class);
109 }
110
111 @SuppressWarnings("unchecked")
112
113 public <T> Class<T> resolveAlias(String string) {
114 try {
115 if (string == null) {
116 return null;
117 }
118
119 String key = string.toLowerCase(Locale.ENGLISH);
120 Class<T> value;
121 if (typeAliases.containsKey(key)) {
122 value = (Class<T>) typeAliases.get(key);
123 } else {
124 value = (Class<T>) Resources.classForName(string);
125 }
126 return value;
127 } catch (ClassNotFoundException e) {
128 throw new TypeException("Could not resolve type alias '" + string + "'. Cause: " + e, e);
129 }
130 }
131
132 public void registerAliases(String packageName) {
133 registerAliases(packageName, Object.class);
134 }
135
136 public void registerAliases(String packageName, Class<?> superType) {
137 ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
138 resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
139 Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();
140 for (Class<?> type : typeSet) {
141
142
143 if (!type.isAnonymousClass() && !type.isInterface() && !type.isMemberClass()) {
144 registerAlias(type);
145 }
146 }
147 }
148
149 public void registerAlias(Class<?> type) {
150 String alias = type.getSimpleName();
151 Alias aliasAnnotation = type.getAnnotation(Alias.class);
152 if (aliasAnnotation != null) {
153 alias = aliasAnnotation.value();
154 }
155 registerAlias(alias, type);
156 }
157
158 public void registerAlias(String alias, Class<?> value) {
159 if (alias == null) {
160 throw new TypeException("The parameter alias cannot be null");
161 }
162
163 String key = alias.toLowerCase(Locale.ENGLISH);
164 if (typeAliases.containsKey(key) && typeAliases.get(key) != null && !typeAliases.get(key).equals(value)) {
165 throw new TypeException(
166 "The alias '" + alias + "' is already mapped to the value '" + typeAliases.get(key).getName() + "'.");
167 }
168 typeAliases.put(key, value);
169 }
170
171 public void registerAlias(String alias, String value) {
172 try {
173 registerAlias(alias, Resources.classForName(value));
174 } catch (ClassNotFoundException e) {
175 throw new TypeException("Error registering type alias " + alias + " for " + value + ". Cause: " + e, e);
176 }
177 }
178
179
180
181
182
183
184
185
186 public Map<String, Class<?>> getTypeAliases() {
187 return Collections.unmodifiableMap(typeAliases);
188 }
189
190 }