Project

General

Profile

Download (7 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 CdmPermanentCacheBase
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
    //NOTE AM: this is currently not used
61
    @Autowired
62
    private ConfigFileUtil configFileUtil = null;
63

    
64
    public CdmServiceCachingProxy() {
65
        super();
66
    }
67

    
68
    @Override
69
    protected void setup() {
70

    
71
        setUpCacheManager();
72

    
73
        DefinedTermBase.setCacher(this);
74
        CdmTransientEntityCacher.setPermanentCacher(this);
75
        RemoteInvocationTermCacher.setDefaultCacher(this);
76

    
77
        cacheLoader = new CacheLoader(this);
78
    }
79

    
80
    private void setUpCacheManager() {
81

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

    
95
        // FIXME use subfolder per taxeditor version to allow running multiple
96
        //   installations in parallel
97
        // String taxEditorVersion = ..;
98
        // File ehcacheFolder = new File(ehcacheFolder, taxEditorVersion);
99
        diskStoreConfiguration.setPath(ehcacheFolder.getAbsolutePath());
100

    
101
        EhCacheConfiguration cacheConfig = new EhCacheConfiguration();
102
        cacheConfig.setDiskStoreConfiguration(diskStoreConfiguration);
103

    
104
        CacheManager cacheManager = cacheConfig.cacheManager();
105
        setCacheManager(cacheManager);
106
    }
107

    
108
    @Override
109
    protected CacheConfiguration getPermanentCacheConfiguration() {
110
        // For a better understanding on how to size caches, refer to
111
        // http://ehcache.org/documentation/configuration/cache-size
112

    
113
        SizeOfPolicyConfiguration sizeOfConfig = new SizeOfPolicyConfiguration();
114
        sizeOfConfig.setMaxDepth(100);
115
        sizeOfConfig.setMaxDepthExceededBehavior("abort");
116

    
117
        return new CacheConfiguration(PERMANENT_CACHE_NAME, 0)
118
        	.eternal(true)
119
        	.sizeOfPolicy(sizeOfConfig)
120
        	.overflowToOffHeap(false);
121
    }
122

    
123
    @Override
124
    protected CdmBase findByUuid(UUID uuid) {
125
        CdmBase term = CdmApplicationState.getCurrentAppConfig().getTermService().findWithoutFlush(uuid);
126
        return load(term);
127
    }
128

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

    
143
    public void setCdmEntitySessionManager(ICdmEntitySessionManager cdmEntitySessionManager) {
144
        this.cdmEntitySessionManager = cdmEntitySessionManager;
145
        if(cdmEntitySessionManager != null) {
146
            cdmEntitySessionManager.addSessionObserver(this);
147
        }
148
    }
149

    
150
    public CdmTransientEntityCacher getCurrentCacher() {
151
        ICdmEntitySession cdmEntitySession = cdmEntitySessionManager.getActiveSession();
152
        if(cdmEntitySession != null && cdmEntitySession instanceof CdmEntitySession) {
153
            return ((CdmEntitySession) cdmEntitySession).getCacher();
154
        }
155
        return null;
156
    }
157

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

    
176
    @Override
177
    public <T extends CdmBase> T load(T cdmEntity) {
178
        @SuppressWarnings("unchecked")
179
        T cachedCdmEntity = (T)getFromCache(cdmEntity.getUuid());
180

    
181
        if(isCachable(cdmEntity) && cachedCdmEntity == null) {
182
            cachedCdmEntity = cacheLoader.load(cdmEntity, false, true);
183
        }
184
        return cachedCdmEntity;
185
    }
186

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