1 package com.addthis.codec.reflection;
2
3 import javax.annotation.Nonnull;
4 import javax.annotation.Nullable;
5
6 import java.lang.reflect.GenericArrayType;
7 import java.lang.reflect.ParameterizedType;
8 import java.lang.reflect.Type;
9
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.List;
13 import java.util.concurrent.ConcurrentHashMap;
14 import java.util.concurrent.ConcurrentMap;
15 import java.util.concurrent.atomic.AtomicBoolean;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public final class Fields {
31 private Fields() {}
32
33 private static final ConcurrentMap<Class<?>, CodableClassInfo> fieldMaps =
34 new ConcurrentHashMap<>();
35
36 public static CodableClassInfo getClassFieldMap(Class<?> clazz) {
37 CodableClassInfo fieldMap = fieldMaps.get(clazz);
38 if (fieldMap == null) {
39 fieldMap = new CodableClassInfo(clazz);
40 fieldMaps.put(clazz, fieldMap);
41 }
42 return fieldMap;
43 }
44
45 public static void flushClassFieldMaps() {
46 fieldMaps.clear();
47 }
48
49 public static boolean isNative(@Nonnull Class<?> type) {
50 return (type == String.class) || (type == AtomicBoolean.class) ||
51 (type == Boolean.class) || type.isPrimitive() || Number.class.isAssignableFrom(type);
52 }
53
54 @Nullable static Type[] collectTypes(Class<?> type, Type node) {
55 List<Type> l = new ArrayList<>();
56 collectTypes(l, type, node);
57 while (!l.isEmpty()) {
58 int ni = l.lastIndexOf(null);
59 if (ni < 0) {
60 break;
61 }
62 if (ni >= (l.size() - 1)) {
63 l.remove(ni);
64 } else {
65 l.set(ni, l.get(l.size() - 1));
66 l.remove(l.size() - 1);
67 }
68 }
69 if (l.isEmpty()) {
70 return null;
71 } else {
72 Type[] t = new Type[l.size()];
73 l.toArray(t);
74 return t;
75 }
76 }
77
78 private static void collectTypes(@Nonnull List<Type> list, @Nullable Class<?> type, @Nullable Type node) {
79 if ((type == null) && (node == null)) {
80 return;
81 }
82 if (node instanceof Class) {
83 if (type != null) {
84 collectTypes(list, ((Class<?>) node).getSuperclass(), type.getGenericSuperclass());
85 } else {
86 collectTypes(list, ((Class<?>) node).getSuperclass(), null);
87 }
88 } else {
89 if (type != null) {
90 collectTypes(list, null, type.getGenericSuperclass());
91 } else {
92 collectTypes(list, null, null);
93 }
94 }
95 if (node instanceof ParameterizedType) {
96 List<Type> tl = Arrays.asList(((ParameterizedType) node).getActualTypeArguments());
97 for (Type t : tl) {
98 if ((t instanceof Class) || (t instanceof GenericArrayType)) {
99 list.add(t);
100 } else if (t instanceof ParameterizedType) {
101 list.add(((ParameterizedType) t).getRawType());
102 } else {
103 list.add(null);
104 }
105 }
106 }
107 }
108 }