Project

General

Profile

« Previous | Next » 

Revision 348d552a

Added by Cherian Mathew about 9 years ago

AbstractPersistentCollection : fixed loading of collection
MockCdmEntitySessionManager, MockCdmEntitySession, ICdmEntitySessionManager, ICdmEntitySession, CdmEntitySessionManager,
CdmEntitySession : added new load method with choice to update client object graph
TermServiceRequestExecutor : using cacher instead of cache
ICachedCommonService, CachedCommonServiceImpl, ProxyUtils : moved utility methods to utility class
CdmServiceRequestExecutor : updating client object graph when calling merge
EntityCacherDebugResult : corrections for output string
CdmTransientEntityCacher : corrected cache configuration, added load methods with update choice, added service cacher check before put
CacheLoader : checking in recursive call if collection and maps are already visited
CdmRemotingException : added constructor with exception as argument
CdmServiceCacher : corrected cache configuration and loading of entities from default cache

View differences:

eu.etaxonomy.taxeditor.cdmlib/src/main/java/eu/etaxonomy/taxeditor/remoting/cache/CacheLoader.java
44 44

  
45 45
    private final Cache cdmlibModelCache;
46 46

  
47
    private final ICdmCacher cdmServiceCacher;
48

  
47 49

  
48 50
    public CacheLoader(ICdmCacher cdmCacher) {
51
        this(cdmCacher, null);
52
    }
53

  
54
    public CacheLoader(ICdmCacher cdmCacher, ICdmCacher cdmServiceCacher) {
49 55
        this.cdmCacher = cdmCacher;
50 56
        this.cdmlibModelCache = CdmRemoteCacheManager.getInstance().getCdmModelGetMethodsCache();
57
        this.cdmServiceCacher = cdmServiceCacher;
51 58
    }
52 59

  
53 60

  
......
61 68
    }
62 69

  
63 70
    @SuppressWarnings("unchecked")
64
    public <T extends Object> T load(T obj, boolean recursive) {
71
    public <T extends Object> T load(T obj, boolean recursive, boolean update) {
65 72
        if(obj == null) {
66 73
            return null;
67 74
        }
68 75
        if(obj instanceof CdmBase) {
69
            return (T) load((CdmBase)obj, recursive);
76
            return (T) load((CdmBase)obj, recursive, update);
70 77
        } else if (obj instanceof Map) {
71
            return (T) load((Map<T,T>)obj, recursive);
78
            return (T) load((Map<T,T>)obj, recursive, update);
72 79
        } else if (obj instanceof Collection) {
73
            return (T) load((Collection<T>)obj, recursive);
80
            return (T) load((Collection<T>)obj, recursive, update);
74 81
        }
75 82

  
76 83
        return obj;
77 84
    }
78 85

  
79 86
    @SuppressWarnings("unchecked")
80
    private <T extends Object> T loadRecursive(T obj, Set<CdmBase> alreadyVisitedEntities) {
87
    private <T extends Object> T loadRecursive(T obj, Set<Object> alreadyVisitedEntities, boolean update) {
81 88
        if(obj == null) {
82 89
            return null;
83 90
        }
84 91
        if(obj instanceof CdmBase) {
85
            return (T) loadRecursive((CdmBase)obj, alreadyVisitedEntities);
92
            return (T) loadRecursive((CdmBase)obj, alreadyVisitedEntities, update);
86 93
        } else if (obj instanceof Map) {
87
            return (T) load((Map<T,T>)obj, alreadyVisitedEntities);
94
            return (T) load((Map<T,T>)obj, alreadyVisitedEntities, update);
88 95
        } else if (obj instanceof Collection) {
89
            return (T) load((Collection<T>)obj, alreadyVisitedEntities);
96
            return (T) load((Collection<T>)obj, alreadyVisitedEntities, update);
90 97
        }
91 98

  
92 99

  
......
95 102
        return obj;
96 103
    }
97 104

  
98
    public <T extends Object> Map<T,T> load(Map<T,T> map, boolean recursive){
99
        if(map == null) {
100
            return null;
101
        }
105
    public <T extends Object> Map<T,T> load(Map<T,T> map, boolean recursive, boolean update){
106

  
102 107

  
103 108
        if(isRecursiveEnabled && recursive) {
104 109
            logger.info("---- starting recursive load for cdm entity map");
105
            Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
106
            Map<T,T> cachedMap = load(map, alreadyVisitedEntities);
110
            Set<Object> alreadyVisitedEntities = new HashSet<Object>();
111
            Map<T,T> cachedMap = load(map, alreadyVisitedEntities, update);
107 112
            alreadyVisitedEntities.clear();
108 113
            logger.info("---- ending recursive load for cdm entity map \n");
109 114
            return cachedMap;
110 115
        } else {
111
            return load(map, null);
116
            return load(map, null, update);
112 117
        }
113 118
    }
114 119

  
115 120

  
116
    private <T extends Object> Map<T,T> load(Map<T,T> map, Set<CdmBase> alreadyVisitedEntities){
121
    private <T extends Object> Map<T,T> load(Map<T,T> map, Set<Object> alreadyVisitedEntities, boolean update){
122
        //map = (Map<T,T>)deproxy(map);
123

  
117 124
        if(map == null || map.isEmpty()) {
118 125
            return map;
119 126
        }
......
122 129
        Object[] result = new Object[ map.size() * 2 ];
123 130
        Iterator<Map.Entry<T,T>> iter = map.entrySet().iterator();
124 131
        int i=0;
132
        // to avoid ConcurrentModificationException
133
        alreadyVisitedEntities.add(map);
125 134
        while ( iter.hasNext() ) {
126 135
            Map.Entry<T,T> e = iter.next();
127 136
            result[i++] = e.getKey();
......
130 139

  
131 140
        for(i=0; i<result.length;i++) {
132 141
            if(alreadyVisitedEntities == null) {
133
                result[i] = load(result[i], false);
142
                result[i] = load(result[i], false, update);
134 143
            } else {
135
                result[i] = loadRecursive(result[i], alreadyVisitedEntities);
144
                result[i] = loadRecursive(result[i], alreadyVisitedEntities, update);
136 145
            }
137 146
        }
138 147
        map.clear();
......
145 154
        return map;
146 155
    }
147 156

  
148
    public <T extends Object> Collection<T> load(Collection<T> collection, boolean recursive){
149
        if(collection == null) {
150
            return null;
151
        }
157
    public <T extends Object> Collection<T> load(Collection<T> collection, boolean recursive, boolean update){
152 158

  
153 159
        Collection<T> loadedCollection;
154 160
        if(isRecursiveEnabled && recursive) {
155 161
            logger.info("---- starting recursive load for cdm entity collection");
156
            Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
157
            Collection<T> cachedCollection = load(collection, alreadyVisitedEntities);
162
            Set<Object> alreadyVisitedEntities = new HashSet<Object>();
163
            Collection<T> cachedCollection = load(collection, alreadyVisitedEntities, update);
158 164
            alreadyVisitedEntities.clear();
159 165
            logger.info("---- ending recursive load for cdm entity collection \n");
160 166
            loadedCollection = cachedCollection;
161 167
        } else {
162
            loadedCollection = load(collection, null);
168
            loadedCollection = load(collection, null, update);
163 169
        }
164 170
        return loadedCollection;
165 171
    }
166 172

  
167 173
    @SuppressWarnings("unchecked")
168
    private <T extends Object> Collection<T> load(Collection<T> collection, Set<CdmBase> alreadyVisitedEntities){
174
    private <T extends Object> Collection<T> load(Collection<T> collection, Set<Object> alreadyVisitedEntities, boolean update) {
175

  
176

  
177

  
178
        if(collection == null || collection.isEmpty()) {
179
            return collection;
180
        }
169 181
        int length = collection.size();
170 182
        Object[] result = new Object[length];
171 183
        Iterator<T> collectionItr = collection.iterator();
172 184
        int count = 0;
185
        // to avoid ConcurrentModificationException
186
        alreadyVisitedEntities.add(collection);
173 187
        while(collectionItr.hasNext()) {
174 188
            Object obj = collectionItr.next();
175 189
            if(alreadyVisitedEntities == null) {
176
                result[count] = load(obj, false);
190
                result[count] = load(obj, false, update);
177 191
            } else {
178
                result[count] = loadRecursive(obj, alreadyVisitedEntities);
192
                result[count] = loadRecursive(obj, alreadyVisitedEntities, update);
179 193
            }
180 194

  
181 195
            count++;
......
199 213
     * @param uuid
200 214
     * @param cdmEntity
201 215
     */
202
    public CdmBase load(CdmBase cdmEntity, boolean recursive) {
216
    public CdmBase load(CdmBase cdmEntity, boolean recursive, boolean update) {
203 217
        if(cdmEntity == null) {
204 218
            return null;
205 219
        }
......
215 229
            if(cachedCdmEntity == cdmEntity) {
216 230
                return cachedCdmEntity;
217 231
            }
218
            return cachedCdmEntity;
232

  
219 233
        }
220 234

  
221 235
        CdmBase loadedCdmBase;
222 236
        if(isRecursiveEnabled && recursive) {
223 237
            logger.info("---- starting recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
224
            Set<CdmBase> alreadyVisitedEntities = new HashSet<CdmBase>();
225
            CdmBase cb =  loadRecursive(cdmEntity, alreadyVisitedEntities);
238
            Set<Object> alreadyVisitedEntities = new HashSet<Object>();
239
            CdmBase cb =  loadRecursive(cdmEntity, alreadyVisitedEntities, update);
226 240
            alreadyVisitedEntities.clear();
227 241
            logger.info("---- ending recursive load for cdm entity " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId() + "\n");
228 242
            loadedCdmBase =  cb;
......
237 251
    private CdmBase load(CdmBase cdmEntity) {
238 252
        logger.info("loading object of type " + cdmEntity.getClass().getName() + " with id " + cdmEntity.getId());
239 253

  
254
        cdmEntity = (CdmBase)ProxyUtils.deproxy(cdmEntity);
255

  
240 256
        // start by looking up the cdm entity in the cache
241 257
        CdmBase cachedCdmEntity = cdmCacher.getFromCache(cdmEntity);
242 258

  
......
252 268
        }
253 269
    }
254 270

  
255
    private CdmBase loadRecursive(CdmBase cdmEntity,  Set<CdmBase> alreadyVisitedEntities) {
271
    private CdmBase loadRecursive(CdmBase cdmEntity,  Set<Object> alreadyVisitedEntities, boolean update) {
256 272

  
257 273
        CdmBase cachedCdmEntity = load(cdmEntity);
258

  
274
        if(cdmServiceCacher != null && cdmServiceCacher.exists(cachedCdmEntity)) {
275
            return cachedCdmEntity;
276
        }
259 277

  
260 278
        // we want to recursive through the cdmEntity (and not the cachedCdmEntity)
261 279
        // since there could be new or deleted objects in the cdmEntity sub-graph
......
271 289
                // this object will be either a CdmBase or a Collection / Map
272 290
                // with CdmBase as the generic type
273 291

  
274
                CdmBase cdmEntityInSubGraph = getCdmBaseTypeFieldValue(cdmEntity, cachedCdmEntity, field, alreadyVisitedEntities);
292
                CdmBase cdmEntityInSubGraph = getCdmBaseTypeFieldValue(cdmEntity, cachedCdmEntity, field, alreadyVisitedEntities, update);
275 293
                if(cdmEntityInSubGraph != null) {
276 294
                    //checkForIdenticalCdmEntity(alreadyVisitedEntities, cdmEntityInSubGraph);
277 295
                    if(!alreadyVisitedEntities.contains(cdmEntityInSubGraph)) {
278 296
                        logger.info("recursive loading object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId());
279
                        loadRecursive(cdmEntityInSubGraph, alreadyVisitedEntities);
297
                        loadRecursive(cdmEntityInSubGraph, alreadyVisitedEntities, update);
280 298
                    } else {
281 299
                        logger.info("object of type " + cdmEntityInSubGraph.getClass().getName() + " with id " + cdmEntityInSubGraph.getId() + " already visited");
282 300
                    }
......
294 312
    private CdmBase getCdmBaseTypeFieldValue(CdmBase cdmEntity,
295 313
            CdmBase cachedCdmEntity,
296 314
            String fieldName,
297
            Set<CdmBase> alreadyVisitedEntities) {
315
            Set<Object> alreadyVisitedEntities,
316
            boolean update) {
298 317

  
299 318
        // this method attempts to make sure that for any two objects found in
300 319
        // the object graph, if they are equal then they should also be the same,
......
334 353

  
335 354

  
336 355
            CdmBase cdmEntityInSubGraph = null;
356
            if(update) {
357
                // making sure that the field in cached cdm entity is always
358
                // up-to-date by setting to the value of the cdm entity being loaded
359
                // the only exception to this is found below
360
                field.set(cachedCdmEntity, o);
361
            }
337 362
            if(o != null
338 363
                    && !ProxyFactory.isProxyClass(o.getClass())
339 364
                    && !(o instanceof PersistentCollection) ) {
340 365

  
366

  
341 367
                if(CdmBase.class.isAssignableFrom(o.getClass())) {
342 368
                    logger.info("found initialised cdm entity '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId());
343 369
                    cdmEntityInSubGraph  = (CdmBase)o;
344

  
345

  
346 370
                    CdmBase cachedCdmEntityInSubGraph = cdmCacher.getFromCache(cdmEntityInSubGraph);
347
                    // making sure that the field in cached cdm entity is always
348
                    // up-to-date by setting to the value of the cdm entity being loaded
349
                    // the only execption to this is found below
350
                    field.set(cachedCdmEntity, o);
351

  
352 371

  
353 372
                    // the only exception to updating the field to the latest value
354 373
                    // is the case where the field has been already initialised, cached and
......
359 378
                            logger.info("setting cached + real value to '" + fieldName + "' in object of type " + clazz.getName() + " with id " + cdmEntity.getId());
360 379
                            field.set(cachedCdmEntity, cachedCdmEntityInSubGraph);
361 380
                            field.set(cdmEntity, cachedCdmEntityInSubGraph);
381
                        } else {
382
                            // hack to stop the recursion, since the field value object in cdmEntity
383
                            // is the same as the field value object in cachedCdmEntity
384
                            cdmEntityInSubGraph = null;
362 385
                        }
363
                        cdmEntityInSubGraph = null;
364 386
                    }
365 387

  
366
                } else if(o instanceof Map) {
367
                    loadRecursive((Map)o, alreadyVisitedEntities);
368
                } else if(o instanceof Collection) {
369
                    loadRecursive((Collection)o, alreadyVisitedEntities);
388
                } else if(o instanceof Map && !alreadyVisitedEntities.contains(o)) {
389
                    loadRecursive((Map)o, alreadyVisitedEntities, update);
390
                } else if(o instanceof Collection && !alreadyVisitedEntities.contains(o)) {
391
                    loadRecursive((Collection)o, alreadyVisitedEntities, update);
370 392
                }
371 393
            }
372 394
            // we return the original cdm entity in the sub graph because we
......
398 420
        return false;
399 421
    }
400 422

  
423

  
401 424
    public static boolean isRecursiveEnabled() {
402 425
        return isRecursiveEnabled;
403 426
    }

Also available in: Unified diff