11package com .aerospike .mapper .tools ;
22
3- import java .util .HashMap ;
4- import java .util .Map ;
5-
6- import javax .validation .constraints .NotNull ;
7-
83import com .aerospike .client .AerospikeException ;
94import com .aerospike .client .IAerospikeClient ;
105import com .aerospike .client .policy .BatchPolicy ;
1813import com .aerospike .mapper .tools .configuration .Configuration ;
1914import com .aerospike .mapper .tools .utils .TypeUtils ;
2015
16+ import javax .validation .constraints .NotNull ;
17+ import java .util .HashMap ;
18+ import java .util .Map ;
19+
2120public class ClassCache {
2221 private static final ClassCache instance = new ClassCache ();
2322
@@ -33,49 +32,61 @@ enum PolicyType {
3332 QUERY
3433 }
3534
36- private final Map <Class <?>, ClassCacheEntry > cacheMap = new HashMap <>();
35+ private final Map <Class <?>, ClassCacheEntry <?> > cacheMap = new HashMap <>();
3736 private final Map <String , ClassConfig > classesConfig = new HashMap <>();
3837 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 <>();
4039 private final Map <PolicyType , Map <Class <?>, Policy >> childrenPolicies = new HashMap <>();
4140 private final Map <PolicyType , Map <Class <?>, Policy >> specificPolicies = new HashMap <>();
4241
42+ private final Object lock = new Object ();
43+
4344 private ClassCache () {
4445 for (PolicyType thisType : PolicyType .values ()) {
4546 this .childrenPolicies .put (thisType , new HashMap <>());
4647 this .specificPolicies .put (thisType , new HashMap <>());
4748 }
4849 }
4950
51+ @ SuppressWarnings ("unchecked" )
5052 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 )) {
5255 return null ;
5356 }
54- ClassCacheEntry <T > entry = cacheMap .get (clazz );
57+
58+ ClassCacheEntry <T > entry = (ClassCacheEntry <T >) cacheMap .get (clazz );
5559 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+ }
7990 }
8091 }
8192 return entry ;
0 commit comments