1
1
package com .aerospike .mapper .tools ;
2
2
3
- import java .util .HashMap ;
4
- import java .util .Map ;
5
-
6
- import javax .validation .constraints .NotNull ;
7
-
8
3
import com .aerospike .client .AerospikeException ;
9
4
import com .aerospike .client .IAerospikeClient ;
10
5
import com .aerospike .client .policy .BatchPolicy ;
18
13
import com .aerospike .mapper .tools .configuration .Configuration ;
19
14
import com .aerospike .mapper .tools .utils .TypeUtils ;
20
15
16
+ import javax .validation .constraints .NotNull ;
17
+ import java .util .HashMap ;
18
+ import java .util .Map ;
19
+
21
20
public class ClassCache {
22
21
private static final ClassCache instance = new ClassCache ();
23
22
@@ -33,49 +32,61 @@ enum PolicyType {
33
32
QUERY
34
33
}
35
34
36
- private final Map <Class <?>, ClassCacheEntry > cacheMap = new HashMap <>();
35
+ private final Map <Class <?>, ClassCacheEntry <?> > cacheMap = new HashMap <>();
37
36
private final Map <String , ClassConfig > classesConfig = new HashMap <>();
38
37
private final Map <PolicyType , Policy > defaultPolicies = new HashMap <>();
39
- private final Map <String , ClassCacheEntry > storedNameToCacheEntry = new HashMap <>();
38
+ private final Map <String , ClassCacheEntry <?> > storedNameToCacheEntry = new HashMap <>();
40
39
private final Map <PolicyType , Map <Class <?>, Policy >> childrenPolicies = new HashMap <>();
41
40
private final Map <PolicyType , Map <Class <?>, Policy >> specificPolicies = new HashMap <>();
42
41
42
+ private final Object lock = new Object ();
43
+
43
44
private ClassCache () {
44
45
for (PolicyType thisType : PolicyType .values ()) {
45
46
this .childrenPolicies .put (thisType , new HashMap <>());
46
47
this .specificPolicies .put (thisType , new HashMap <>());
47
48
}
48
49
}
49
50
51
+ @ SuppressWarnings ("unchecked" )
50
52
public <T > ClassCacheEntry <T > loadClass (@ NotNull Class <T > clazz , IBaseAeroMapper mapper ) {
51
- if (clazz .isPrimitive () || clazz .equals (Object .class ) || clazz .equals (String .class ) || clazz .equals (Character .class ) || Number .class .isAssignableFrom (clazz )) {
53
+ if (clazz .isPrimitive () || clazz .equals (Object .class ) || clazz .equals (String .class )
54
+ || clazz .equals (Character .class ) || Number .class .isAssignableFrom (clazz )) {
52
55
return null ;
53
56
}
54
- ClassCacheEntry <T > entry = cacheMap .get (clazz );
57
+
58
+ ClassCacheEntry <T > entry = (ClassCacheEntry <T >) cacheMap .get (clazz );
55
59
if (entry == null ) {
56
- try {
57
- // Construct a class cache entry. This must be done in 2 steps, one creating the entry and the other finalizing construction of
58
- // it. This is to cater for classes which recursively refer to themselves, such as
59
- // public static class A {
60
- // @AerospikeKey
61
- // public int id;
62
- // public A a;
63
- // }
64
- entry = new ClassCacheEntry <>(clazz , mapper , getClassConfig (clazz ),
65
- determinePolicy (clazz , PolicyType .READ ),
66
- (WritePolicy ) determinePolicy (clazz , PolicyType .WRITE ),
67
- (BatchPolicy ) determinePolicy (clazz , PolicyType .BATCH ),
68
- (QueryPolicy ) determinePolicy (clazz , PolicyType .QUERY ),
69
- (ScanPolicy ) determinePolicy (clazz , PolicyType .SCAN ));
70
- } catch (NotAnnotatedClass nae ) {
71
- return null ;
72
- }
73
- cacheMap .put (clazz , entry );
74
- try {
75
- entry .construct ();
76
- } catch (IllegalArgumentException iae ) {
77
- cacheMap .remove (clazz );
78
- return null ;
60
+ synchronized (lock ) {
61
+ entry = (ClassCacheEntry <T >) cacheMap .get (clazz );
62
+ if (entry == null ) {
63
+ try {
64
+ // Construct a class cache entry. This must be done in 2 steps, one creating the entry
65
+ // and the other finalizing construction of it.
66
+ // This is to cater for classes which recursively refer to themselves, such as
67
+ // public static class A {
68
+ // @AerospikeKey
69
+ // public int id;
70
+ // public A a;
71
+ // }
72
+ entry = new ClassCacheEntry <>(clazz , mapper , getClassConfig (clazz ),
73
+ determinePolicy (clazz , PolicyType .READ ),
74
+ (WritePolicy ) determinePolicy (clazz , PolicyType .WRITE ),
75
+ (BatchPolicy ) determinePolicy (clazz , PolicyType .BATCH ),
76
+ (QueryPolicy ) determinePolicy (clazz , PolicyType .QUERY ),
77
+ (ScanPolicy ) determinePolicy (clazz , PolicyType .SCAN ));
78
+
79
+ } catch (NotAnnotatedClass nae ) {
80
+ return null ;
81
+ }
82
+ cacheMap .put (clazz , entry );
83
+ try {
84
+ entry .construct ();
85
+ } catch (IllegalArgumentException iae ) {
86
+ cacheMap .remove (clazz );
87
+ return null ;
88
+ }
89
+ }
79
90
}
80
91
}
81
92
return entry ;
0 commit comments