Project

General

Profile

Download (6.97 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
 * Copyright (C) 2015 EDIT
3
 * European Distributed Institute of Taxonomy
4
 * http://www.e-taxonomy.eu
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version 1.1
7
 * See LICENSE.TXT at the top of this package for the full license terms.
8
 */
9
package eu.etaxonomy.cdm.api.cache;
10

    
11
import java.io.File;
12
import java.util.UUID;
13

    
14
import org.apache.logging.log4j.LogManager;
15
import org.apache.logging.log4j.Logger;
16
import org.springframework.beans.factory.annotation.Autowired;
17

    
18
import eu.etaxonomy.cdm.api.application.CdmApplicationState;
19
import eu.etaxonomy.cdm.api.config.EhCacheConfiguration;
20
import eu.etaxonomy.cdm.cache.CacheLoader;
21
import eu.etaxonomy.cdm.cache.CdmEntityCacheKey;
22
import eu.etaxonomy.cdm.cache.CdmTransientEntityCacher;
23
import eu.etaxonomy.cdm.config.ConfigFileUtil;
24
import eu.etaxonomy.cdm.model.common.CdmBase;
25
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
26
import eu.etaxonomy.cdm.model.term.Representation;
27
import eu.etaxonomy.cdm.model.term.TermBase;
28
import eu.etaxonomy.taxeditor.service.RemoteInvocationTermCacher;
29
import eu.etaxonomy.taxeditor.session.CdmEntitySession;
30
import eu.etaxonomy.taxeditor.session.ICdmEntitySession;
31
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManager;
32
import eu.etaxonomy.taxeditor.session.ICdmEntitySessionManagerObserver;
33
import net.sf.ehcache.CacheManager;
34
import net.sf.ehcache.config.CacheConfiguration;
35
import net.sf.ehcache.config.DiskStoreConfiguration;
36
import net.sf.ehcache.config.SizeOfPolicyConfiguration;
37

    
38
/**
39
 * Class which uses CDM services to cache cdm entities
40
 *
41
 * FIXME: Currently only handles term entities. It would be
42
 *        interesting to have a generic method which finds the
43
 *        correct service to load / cache the entity.
44
 * TODO by AM: compare with {@link CdmTermCacher} and merge if possible
45
 *
46
 * @author cmathew
47
 */
48
public class CdmServiceCachingProxy
49
        extends CdmCacherBase
50
        implements ICdmEntitySessionManagerObserver {
51

    
52
    private static final Logger logger = LogManager.getLogger();
53

    
54
    private ICdmEntitySessionManager cdmEntitySessionManager;
55

    
56
    private CdmTransientEntityCacher cdmTransientEntityCacher;
57

    
58
    private CacheLoader cacheLoader;
59

    
60
    @Autowired
61
    private ConfigFileUtil configFileUtil = null;
62

    
63
    @Override
64
    protected void setup() {
65

    
66
        setUpCacheManager();
67

    
68
        DefinedTermBase.setCacher(this);
69
        CdmTransientEntityCacher.setPermanentCacher(this);
70
        //TermServiceRequestExecutor.setDefaultCacher(this);
71
        RemoteInvocationTermCacher.setDefaultCacher(this);
72

    
73
        cacheLoader = new CacheLoader(this);
74
    }
75

    
76
    private void setUpCacheManager() {
77

    
78
        DiskStoreConfiguration diskStoreConfiguration = new DiskStoreConfiguration();
79
        File ehcacheFolder = null;
80
        if(configFileUtil != null){
81
            try {
82
                ehcacheFolder = configFileUtil.getCdmHomeSubDir("taxeditor-ehcache");
83
            } catch (Exception e){
84
                logger.warn("Cannot determine CdmHomeSubDir for ./taxeditor-ehcache, will use fallback method.", e);
85
            }
86
        }
87
        if(ehcacheFolder == null){
88
            ehcacheFolder = ConfigFileUtil.getCdmHomeSubDirFallback("taxeditor-ehcache");
89
        }
90

    
91
        // FIXME use subfolder per taxeditor version to allow running multiple
92
        //   installations in parallel
93
        // String taxEditorVersion = ..;
94
        // File ehcacheFolder = new File(ehcacheFolder, taxEditorVersion);
95
        diskStoreConfiguration.setPath(ehcacheFolder.getAbsolutePath());
96

    
97
        EhCacheConfiguration cacheConfig = new EhCacheConfiguration();
98
        cacheConfig.setDiskStoreConfiguration(diskStoreConfiguration);
99
        CacheManager cacheManager = cacheConfig.cacheManager();
100
        setCacheManager(cacheManager);
101
    }
102

    
103
    @Override
104
    protected CacheConfiguration getDefaultCacheConfiguration() {
105
        // For a better understanding on how to size caches, refer to
106
        // http://ehcache.org/documentation/configuration/cache-size
107

    
108
        SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration();
109
        sizeOfConfig.setMaxDepth(100);
110
        sizeOfConfig.setMaxDepthExceededBehavior("abort");
111

    
112
        return new CacheConfiguration(DEFAULT_CACHE_NAME, 0)
113
        	.eternal(true)
114
        	.statistics(true)
115
        	.sizeOfPolicy(sizeOfConfig)
116
        	.overflowToOffHeap(false);
117
    }
118

    
119
    @Override
120
    protected CdmBase findByUuid(UUID uuid) {
121
        CdmBase term = CdmApplicationState.getCurrentAppConfig().getTermService().findWithoutFlush(uuid);
122
        return load(term);
123
    }
124

    
125
    /**
126
     * <code>true</code> if the parameter is a term or a representation
127
     */
128
    @Override
129
    public boolean isCachable(CdmBase cdmEntity) {
130
     	if(cdmEntity == null){
131
     	    return false;
132
     	}else if (cdmEntity instanceof TermBase || cdmEntity instanceof Representation){
133
            return true;
134
        }else{
135
            return false;
136
        }
137
    }
138

    
139
    public void setCdmEntitySessionManager(ICdmEntitySessionManager cdmEntitySessionManager) {
140
        this.cdmEntitySessionManager = cdmEntitySessionManager;
141
        if(cdmEntitySessionManager != null) {
142
            cdmEntitySessionManager.addSessionObserver(this);
143
        }
144
    }
145

    
146
    public CdmTransientEntityCacher getCurrentCacher() {
147
        ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
148
        if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
149
            return ((CdmEntitySession) cdmEntitySession).getCacher();
150
        }
151
        return null;
152
    }
153

    
154
    @Override
155
    public <T extends CdmBase> T  getFromCache(T cdmBase) {
156
        T cachedCdmEntity = null;
157
        // first we check in the active session cache if the
158
        // entity has been loaded there
159
        // FIXME:Remoting do we really need the cdmTransientEntityCacher
160
        // here. Is it not guaranteed that every entity which 'isCachable'
161
        // by this cacher is cached only in this cacher ?
162
        if(!isCachable(cdmBase) && cdmTransientEntityCacher != null) {
163
            CdmEntityCacheKey<T> key = CdmTransientEntityCacher.generateKey(cdmBase);
164
            cachedCdmEntity = cdmTransientEntityCacher.getFromCache(key);
165
        }
166
        if(cachedCdmEntity == null) {
167
            cachedCdmEntity = super.getFromCache(cdmBase);
168
        }
169
        return cachedCdmEntity;
170
    }
171

    
172
    @Override
173
    public <T extends CdmBase> T load(T cdmEntity) {
174
        @SuppressWarnings("unchecked")
175
        T cachedCdmEntity = (T)getFromCache(cdmEntity.getUuid());
176

    
177
        if(isCachable(cdmEntity) && cachedCdmEntity == null) {
178
            cachedCdmEntity = cacheLoader.load(cdmEntity, false, true);
179
        }
180
        return cachedCdmEntity;
181
    }
182

    
183
    @Override
184
    public void changed() {
185
        ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
186
        if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
187
            this.cdmTransientEntityCacher = ((CdmEntitySession) cdmEntitySession).getCacher();
188
        } else {
189
            this.cdmTransientEntityCacher = null;
190
        }
191
    }
192
}
    (1-1/1)