1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
| public Class<?> checkAutoType(String typeName, Class<?> expectClass, int features) {
if (typeName == null) {
return null;
} else {
if (this.autoTypeCheckHandlers != null) {
for(AutoTypeCheckHandler h : this.autoTypeCheckHandlers) {
Class<?> type = h.handler(typeName, expectClass, features);
if (type != null) {
return type;
}
}
}
int safeModeMask = Feature.SafeMode.mask;
boolean safeMode = this.safeMode || (features & safeModeMask) != 0 || (JSON.DEFAULT_PARSER_FEATURE & safeModeMask) != 0;
if (safeMode) {
throw new JSONException("safeMode not support autoType : " + typeName);
} else if (typeName.length() < 192 && typeName.length() >= 3) {
boolean expectClassFlag;
if (expectClass == null) {
expectClassFlag = false;
} else {
long expectHash = TypeUtils.fnv1a_64(expectClass.getName());
if (expectHash != -8024746738719829346L && expectHash != 3247277300971823414L && expectHash != -5811778396720452501L && expectHash != -1368967840069965882L && expectHash != 2980334044947851925L && expectHash != 5183404141909004468L && expectHash != 7222019943667248779L && expectHash != -2027296626235911549L && expectHash != -2114196234051346931L && expectHash != -2939497380989775398L) {
expectClassFlag = true;
} else {
expectClassFlag = false;
}
}
String className = typeName.replace('$', '.');
long h1 = (-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L;
if (h1 == -5808493101479473382L) {
throw new JSONException("autoType is not support. " + typeName);
} else if ((h1 ^ (long)className.charAt(className.length() - 1)) * 1099511628211L == 655701488918567152L) {
throw new JSONException("autoType is not support. " + typeName);
} else {
long h3 = (((-3750763034362895579L ^ (long)className.charAt(0)) * 1099511628211L ^ (long)className.charAt(1)) * 1099511628211L ^ (long)className.charAt(2)) * 1099511628211L;
long fullHash = TypeUtils.fnv1a_64(className);
boolean internalWhite = Arrays.binarySearch(INTERNAL_WHITELIST_HASHCODES, fullHash) >= 0;
if (this.internalDenyHashCodes != null) {
long hash = h3;
for(int i = 3; i < className.length(); ++i) {
hash ^= (long)className.charAt(i);
hash *= 1099511628211L;
if (Arrays.binarySearch(this.internalDenyHashCodes, hash) >= 0) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}
if (!internalWhite && (this.autoTypeSupport || expectClassFlag)) {
long hash = h3;
for(int i = 3; i < className.length(); ++i) {
hash ^= (long)className.charAt(i);
hash *= 1099511628211L;
if (Arrays.binarySearch(this.acceptHashCodes, hash) >= 0) {
Class<?> clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader, true);
if (clazz != null) {
return clazz;
}
}
if (Arrays.binarySearch(this.denyHashCodes, hash) >= 0 && TypeUtils.getClassFromMapping(typeName) == null && Arrays.binarySearch(this.acceptHashCodes, fullHash) < 0) {
throw new JSONException("autoType is not support. " + typeName);
}
}
}
Class<?> clazz = TypeUtils.getClassFromMapping(typeName);
if (clazz == null) {
clazz = this.deserializers.findClass(typeName);
}
if (clazz == null) {
clazz = (Class)this.typeMapping.get(typeName);
}
if (internalWhite) {
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader, true);
}
if (clazz != null) {
if (expectClass != null && clazz != HashMap.class && clazz != LinkedHashMap.class && !expectClass.isAssignableFrom(clazz)) {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
} else {
return clazz;
}
} else {
if (!this.autoTypeSupport) {
long hash = h3;
for(int i = 3; i < className.length(); ++i) {
char c = className.charAt(i);
hash ^= (long)c;
hash *= 1099511628211L;
if (Arrays.binarySearch(this.denyHashCodes, hash) >= 0) {
throw new JSONException("autoType is not support. " + typeName);
}
if (Arrays.binarySearch(this.acceptHashCodes, hash) >= 0) {
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader, true);
if (clazz == null) {
return expectClass;
}
if (expectClass != null && expectClass.isAssignableFrom(clazz)) {
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}
return clazz;
}
}
}
boolean jsonType = false;
InputStream is = null;
try {
String resource = typeName.replace('.', '/') + ".class";
if (this.defaultClassLoader != null) {
is = this.defaultClassLoader.getResourceAsStream(resource);
} else {
is = ParserConfig.class.getClassLoader().getResourceAsStream(resource);
}
if (is != null) {
ClassReader classReader = new ClassReader(is, true);
TypeCollector visitor = new TypeCollector("<clinit>", new Class[0]);
classReader.accept(visitor);
jsonType = visitor.hasJsonType();
}
} catch (Exception var24) {
} finally {
IOUtils.close(is);
}
int mask = Feature.SupportAutoType.mask;
boolean autoTypeSupport = this.autoTypeSupport || (features & mask) != 0 || (JSON.DEFAULT_PARSER_FEATURE & mask) != 0;
if (autoTypeSupport || jsonType || expectClassFlag) {
boolean cacheClass = autoTypeSupport || jsonType;
clazz = TypeUtils.loadClass(typeName, this.defaultClassLoader, cacheClass);
}
if (clazz != null) {
if (jsonType) {
TypeUtils.addMapping(typeName, clazz);
return clazz;
}
if (ClassLoader.class.isAssignableFrom(clazz) || DataSource.class.isAssignableFrom(clazz) || RowSet.class.isAssignableFrom(clazz)) {
throw new JSONException("autoType is not support. " + typeName);
}
if (expectClass != null) {
if (expectClass.isAssignableFrom(clazz)) {
TypeUtils.addMapping(typeName, clazz);
return clazz;
}
throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName());
}
JavaBeanInfo beanInfo = JavaBeanInfo.build(clazz, clazz, this.propertyNamingStrategy);
if (beanInfo.creatorConstructor != null && autoTypeSupport) {
throw new JSONException("autoType is not support. " + typeName);
}
}
if (!autoTypeSupport) {
throw new JSONException("autoType is not support. " + typeName);
} else {
if (clazz != null) {
TypeUtils.addMapping(typeName, clazz);
}
return clazz;
}
}
}
} else {
throw new JSONException("autoType is not support. " + typeName);
}
}
}
|