001/**
002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com).
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.jboot.components.cache.ehcache;
017
018import com.jfinal.kit.PathKit;
019import com.jfinal.plugin.ehcache.IDataLoader;
020import io.jboot.Jboot;
021import io.jboot.components.cache.JbootCacheBase;
022import io.jboot.components.cache.JbootCacheConfig;
023import io.jboot.utils.StrUtil;
024import net.sf.ehcache.Cache;
025import net.sf.ehcache.CacheManager;
026import net.sf.ehcache.Element;
027import net.sf.ehcache.event.CacheEventListener;
028
029import java.util.Arrays;
030import java.util.List;
031
032
033public class JbootEhcacheImpl extends JbootCacheBase {
034
035    private CacheManager cacheManager;
036    private static Object locker = new Object();
037
038    private CacheEventListener cacheEventListener;
039
040    public JbootEhcacheImpl(JbootCacheConfig config) {
041        super(config);
042        JbootEhCacheConfig ehconfig = Jboot.config(JbootEhCacheConfig.class);
043        if (StrUtil.isBlank(ehconfig.getConfigFileName())) {
044            cacheManager = CacheManager.create();
045        } else {
046            String configPath = ehconfig.getConfigFileName();
047            if (!configPath.startsWith("/")) {
048                configPath = PathKit.getRootClassPath() + "/" + configPath;
049            }
050            cacheManager = CacheManager.create(configPath);
051        }
052    }
053
054
055    public CacheEventListener getCacheEventListener() {
056        return cacheEventListener;
057    }
058
059    public void setCacheEventListener(CacheEventListener cacheEventListener) {
060        this.cacheEventListener = cacheEventListener;
061    }
062
063    public Cache getOrAddCache(String cacheName) {
064        cacheName = buildCacheName(cacheName);
065        Cache cache = cacheManager.getCache(cacheName);
066        if (cache == null) {
067            synchronized (locker) {
068                cache = cacheManager.getCache(cacheName);
069                if (cache == null) {
070                    cacheManager.addCacheIfAbsent(cacheName);
071                    cache = cacheManager.getCache(cacheName);
072                    if (cacheEventListener != null) {
073                        cache.getCacheEventNotificationService().registerListener(cacheEventListener);
074                    }
075                }
076            }
077        }
078        return cache;
079    }
080
081
082    @Override
083    public <T> T get(String cacheName, Object key) {
084        Element element = getOrAddCache(cacheName).get(key);
085        if (element == null) {
086            return null;
087        }
088
089        Object objectValue = element.getObjectValue();
090        if (config.isDevMode()) {
091            println("Ehcache GET: cacheName[" + buildCacheName(cacheName) + "] cacheKey[" + key + "] value:" + objectValue);
092        }
093        return (T) objectValue;
094
095    }
096
097    @Override
098    public void put(String cacheName, Object key, Object value) {
099        getOrAddCache(cacheName).put(new Element(key, value));
100
101        if (config.isDevMode()) {
102            println("Ehcache PUT: cacheName[" +buildCacheName(cacheName)+ "] cacheKey["+key+"] value:" + value);
103        }
104    }
105
106    @Override
107    public void put(String cacheName, Object key, Object value, int liveSeconds) {
108        if (liveSeconds <= 0) {
109            put(cacheName, key, value);
110            return;
111        }
112        Element element = new Element(key, value);
113        element.setTimeToLive(liveSeconds);
114        getOrAddCache(cacheName).put(element);
115
116        if (config.isDevMode()) {
117            println("Ehcache PUT: cacheName[" +buildCacheName(cacheName)+ "] cacheKey["+key+"] value:" + value);
118        }
119    }
120
121    @Override
122    public void remove(String cacheName, Object key) {
123        getOrAddCache(cacheName).remove(key);
124
125        if (config.isDevMode()) {
126            println("Ehcache REMOVE: cacheName[" +buildCacheName(cacheName)+ "] cacheKey["+key+"]");
127        }
128    }
129
130    @Override
131    public void removeAll(String cacheName) {
132        getOrAddCache(cacheName).removeAll();
133        cacheManager.removeCache(cacheName);
134
135        if (config.isDevMode()) {
136            println("Ehcache REMOVEALL: cacheName[" +buildCacheName(cacheName)+ "]");
137        }
138    }
139
140    @Override
141    public <T> T get(String cacheName, Object key, IDataLoader dataLoader) {
142        Object data = get(cacheName, key);
143        if (data == null) {
144            data = dataLoader.load();
145            put(cacheName, key, data);
146        }
147
148        if (config.isDevMode()) {
149            println("Ehcache GET: cacheName[" +buildCacheName(cacheName)+ "] cacheKey["+key+"] value:" + data);
150        }
151        return (T) data;
152    }
153
154    @Override
155    public <T> T get(String cacheName, Object key, IDataLoader dataLoader, int liveSeconds) {
156        if (liveSeconds <= 0) {
157            return get(cacheName, key, dataLoader);
158        }
159        Object data = get(cacheName, key);
160        if (data == null) {
161            data = dataLoader.load();
162            put(cacheName, key, data, liveSeconds);
163        }
164
165        if (config.isDevMode()) {
166            println("Ehcache GET: cacheName[" +buildCacheName(cacheName)+ "] cacheKey["+key+"] value:" + data);
167        }
168
169        return (T) data;
170    }
171
172    @Override
173    public Integer getTtl(String cacheName, Object key) {
174        Element element = getOrAddCache(cacheName).get(key);
175        return element != null ? element.getTimeToLive() : null;
176    }
177
178
179    @Override
180    public void setTtl(String cacheName, Object key, int seconds) {
181        Element element = getOrAddCache(cacheName).get(key);
182        if (element == null) {
183            return;
184        }
185
186        element.setTimeToLive(seconds);
187        getOrAddCache(cacheName).put(element);
188
189        if (config.isDevMode()) {
190            println("Ehcache SETTTL: cacheName[" +buildCacheName(cacheName)+ "] cacheKey["+key+"] seconds:" + seconds);
191        }
192    }
193
194    @Override
195    public List getNames() {
196        return Arrays.asList(cacheManager.getCacheNames());
197    }
198
199    @Override
200    public List getKeys(String cacheName) {
201        return getOrAddCache(cacheName).getKeys();
202    }
203
204
205    public CacheManager getCacheManager() {
206        return cacheManager;
207    }
208
209}