All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yixan.tools.common.cache.BaseCache Maven / Gradle / Ivy

There is a newer version: 3.7.1
Show newest version
package com.yixan.tools.common.cache;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yixan.tools.common.cache.ICacheKeys.FieldList;
import com.yixan.tools.common.cache.ICacheKeys.FieldValue;
import com.yixan.tools.common.cache.ICacheKeys.KeyList;
import com.yixan.tools.common.cache.ICacheKeys.KeyValue;
import com.yixan.tools.common.model.Duration;
import com.yixan.tools.common.util.ConvertUtil;
import com.yixan.tools.common.util.VerifyUtil;

/**
 * 基础缓存类
 *
 * @author zhaohuihua
 * @version V1.0 2017年6月6日
 */
public abstract class BaseCache implements ICacheService {

    private static final Logger log = LoggerFactory.getLogger(BaseCache.class);

    private Map> keys;

    public BaseCache() {
        this.keys = new ConcurrentHashMap<>();
    }

    /**
     * 保存对象
     *
     * @param key 关键字
     * @param value 值
     */
    @Override
    public  void set(ICacheKeys.KeyValue key, T value) {
        set(topath(key), null, value, totime(key));
    }

    /**
     * 保存对象
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param value 值
     */
    @Override
    public  void set(ICacheKeys.FieldValue key, String subkey, T value) {
        set(topath(key), subkey, value, totime(key));
    }

    /**
     * 保存列表
     *
     * @param key 关键字
     * @param value 值
     */
    @Override
    public  void set(ICacheKeys.KeyList key, List value) {
        set(topath(key), null, value, totime(key));
    }

    /**
     * 保存列表
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param value 值
     */
    @Override
    public  void set(ICacheKeys.FieldList key, String subkey, List value) {
        set(topath(key), subkey, value, totime(key));
    }

    /**
     * 保存对象
     *
     * @param key 关键字
     * @param value 值
     * @param duration 过期时间
     */
    @Override
    public  void set(ICacheKeys.KeyValue key, T value, Duration expire) {
        set(topath(key), null, value, totime(expire));
    }

    /**
     * 保存对象
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param value 值
     * @param expire 过期时间
     */
    @Override
    public  void set(ICacheKeys.FieldValue key, String subkey, T value, Duration expire) {
        set(topath(key), subkey, value, totime(expire));
    }

    /**
     * 保存列表
     *
     * @param key 关键字
     * @param value 值
     * @param expire 过期时间
     */
    @Override
    public  void set(ICacheKeys.KeyList key, List value, Duration expire) {
        set(topath(key), null, value, totime(expire));
    }

    /**
     * 保存列表
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param value 值
     * @param expire 过期时间
     */
    @Override
    public  void set(ICacheKeys.FieldList key, String subkey, List value, Duration expire) {
        set(topath(key), subkey, value, totime(expire));
    }

    /**
     * 从缓存中取出对象
     *
     * @param key 关键字
     * @return 缓存对象
     */
    @Override
    public  T get(ICacheKeys.KeyValue key) {
        return get(topath(key), null, key.type());
    }

    /**
     * 从缓存中取出对象
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @return 缓存对象
     */
    @Override
    public  T get(ICacheKeys.FieldValue key, String subkey) {
        return get(topath(key), subkey, key.type());
    }

    /**
     * 从缓存中取出对象
     *
     * @param key 关键字
     * @return 缓存对象
     */
    @Override
    public  List get(ICacheKeys.KeyList key) {
        return list(topath(key), null, key.type());
    }

    /**
     * 从缓存中取出对象
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @return 缓存对象
     */
    @Override
    public  List get(ICacheKeys.FieldList key, String subkey) {
        return list(topath(key), subkey, key.type());
    }

    /**
     * 判断缓存是否存在key
     *
     * @param key 关键字
     * @return 是否存在
     */
    @Override
    public boolean exist(ICacheKeys.KeyValue key) {
        return exist(topath(key), null);
    }

    /**
     * 判断缓存是否存在key
     *
     * @param key 关键字
     * @return 是否存在
     */
    @Override
    public boolean exist(ICacheKeys.KeyList key) {
        return exist(topath(key), null);
    }

    /**
     * 判断缓存是否存在key
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @return 是否存在
     */
    @Override
    public boolean exist(ICacheKeys.FieldValue key, String subkey) {
        return exist(topath(key), subkey);
    }

    /**
     * 判断缓存是否存在key
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @return 是否存在
     */
    @Override
    public boolean exist(ICacheKeys.FieldList key, String subkey) {
        return exist(topath(key), subkey);
    }

    /**
     * 删除缓存中的指定key的值
     *
     * @param key 关键字
     */
    @Override
    public void del(ICacheKeys.KeyValue key) {
        del(topath(key), null);
    }

    /**
     * 删除缓存中的指定key的值
     *
     * @param key 关键字
     */
    @Override
    public void del(ICacheKeys.KeyList key) {
        del(topath(key), null);
    }

    /**
     * 删除缓存中的指定key的值
     *
     * @param key 关键字
     * @param subkey 子关键字
     */
    @Override
    public void del(ICacheKeys.FieldValue key, String subkey) {
        del(topath(key), subkey);
    }

    /**
     * 删除缓存中的指定key的值
     *
     * @param key 关键字
     * @param subkey 子关键字
     */
    @Override
    public void del(ICacheKeys.FieldList key, String subkey) {
        del(topath(key), subkey);
    }

    /**
     * 设置过期时间
     *
     * @param key 关键字
     * @param time 过期时间
     */
    @Override
    public void expire(ICacheKeys.KeyValue key, Duration time) {
        expire(topath(key), null, totime(time));
    }

    /**
     * 设置过期时间
     *
     * @param key 关键字
     * @param time 过期时间
     */
    @Override
    public void expire(ICacheKeys.KeyList key, Duration time) {
        expire(topath(key), null, totime(time));
    }

    /**
     * 设置过期时间
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param time 过期时间
     */
    @Override
    public void expire(ICacheKeys.FieldValue key, String subkey, Duration time) {
        expire(topath(key), subkey, totime(time));
    }

    /**
     * 设置过期时间
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param time 过期时间
     */
    @Override
    public void expire(ICacheKeys.FieldList key, String subkey, Duration time) {
        expire(topath(key), subkey, totime(time));
    }

    /**
     * 移除过期时间
     *
     * @param key 关键字
     */
    @Override
    public void persist(KeyValue key) {
        this.persist(topath(key), null);
    }

    /**
     * 移除过期时间
     *
     * @param key 关键字
     */
    @Override
    public void persist(KeyList key) {
        this.persist(topath(key), null);
    }

    /**
     * 移除过期时间
     *
     * @param key 关键字
     */
    @Override
    public void persist(FieldValue key, String subkey) {
        this.persist(topath(key), subkey);
    }

    /**
     * 移除过期时间
     *
     * @param key 关键字
     */
    @Override
    public void persist(FieldList key, String subkey) {
        this.persist(topath(key), subkey);
    }

    /**
     * 设置过期时间
     *
     * @param key 关键字
     * @param subkey 子关键字
     * @param time 过期时间
     */
    public void expire(String key, String subkey, Duration time) {
        this.expire(key, subkey, totime(time));
    }

    protected void set(String key, Object value, Long expire) {
        set(key, null, value, expire);
    }

    protected  T get(String key, Class clazz) {
        return get(key, null, clazz);
    }

    protected  List list(String key, Class clazz) {
        return list(key, null, clazz);
    }

    public void expire(String key, Duration time) {
        this.expire(key, null, totime(time));
    }

    protected void expire(String key, Long expire) {
        expire(key, null, expire);
    }

    public void persist(String key) {
        this.persist(key, null);
    }

    public boolean exist(String key) {
        return exist(key, null);
    }

    public void del(String key) {
        del(key, null);
    }

    @Override
    public  void hset(String key, String field, T value) {
        this.hset(key, null, field, value);
    }

    @Override
    public  T hget(String key, String field, Class clazz) {
        return this.hget(key, null, field, clazz);
    }

    @Override
    public  List hlist(String key, String field, Class clazz) {
        return this.hlist(key, null, field, clazz);
    }

    @Override
    public boolean hexist(String key, String field) {
        return this.hexist(key, null, field);
    }

    @Override
    public void hdel(String key, String field) {
        this.hdel(key, null, field);
    }

    @Override
    public  void hmset(String key, Map map) {
        this.hmset(key, null, map);
    }

    @Override
    public Map hmget(String key, List fields) {
        return this.hmget(key, null, fields);
    }

    @Override
    public  Map hmget(String key, List fields, Class clazz) {
        return this.hmget(key, null, fields, clazz);
    }

    @Override
    public long hmdel(String key, List fields) {
        return this.hmdel(key, null, fields);
    }

    @Override
    public  void hoset(String key, T object) {
        this.hoset(key, null, object);
    }

    @Override
    public  T hoget(String key, Class clazz) {
        return this.hoget(key, null, clazz);
    }

    @Override
    public  Map haget(String key, Class clazz) {
        return this.haget(key, null, clazz);
    }

    @Override
    public Map haget(String key) {
        return this.haget(key, (String) null);
    }

    @Override
    public Set hkeys(String key) {
        return this.hkeys(key, null);
    }

    @Override
    public int hlen(String key) {
        return this.hlen(key, null);
    }

    protected abstract void set(String key, String subkey, Object value, Long expire);

    protected abstract  T get(String key, String subkey, Class clazz);

    protected abstract  List list(String key, String subkey, Class clazz);

    protected abstract void expire(String key, String subkey, Long expire);

    public abstract void persist(String key, String subkey);

    public abstract boolean exist(String key, String subkey);

    public abstract void del(String key, String subkey);

    @Override
    public  void hset(String key, String subkey, String field, T value) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  T hget(String key, String subkey, String field, Class clazz) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  List hlist(String key, String subkey, String field, Class clazz) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean hexist(String key, String subkey, String field) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void hdel(String key, String subkey, String field) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  void hmset(String key, String subkey, Map map) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Map hmget(String key, String subkey, List fields) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  Map hmget(String key, String subkey, List fields, Class clazz) {
        throw new UnsupportedOperationException();
    }

    @Override
    public long hmdel(String key, String subkey, List fields) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  void hoset(String key, String subkey, T object) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  T hoget(String key, String subkey, Class clazz) {
        throw new UnsupportedOperationException();
    }

    @Override
    public  Map haget(String key, String subkey, Class clazz) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Map haget(String key, String subkey) {
        throw new UnsupportedOperationException();
    }

    @Override
    public Set hkeys(String key, String subkey) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int hlen(String key, String subkey) {
        throw new UnsupportedOperationException();
    }

    protected Long totime(Duration duration) {
        return duration == null ? null : duration.toMillis();
    }

    protected Long totime(ICacheKeys key) {
        if (key instanceof ICacheKeys.ExpireFixed) {
            return ((ICacheKeys.ExpireFixed) key).time();
        } else {
            return null;
        }
    }

    private String topath(ICacheKeys key) {
        checkKeyTypeDuplicate(key);
        return key.name();
    }

    protected String concat(String key, String... fields) {
        if (fields == null || fields.length == 0) return key;

        StringBuilder buffer = new StringBuilder();
        buffer.append(key);
        for (String field : fields) {
            if (VerifyUtil.isNotBlank(field)) {
                buffer.append(":").append(field);
            }
        }
        return buffer.toString();
    }

    protected String[] toArray(List strings) {
        return ConvertUtil.toArray(strings, String.class);
    }

    protected  Map serializeFields(T value) {
        Object object = JSON.toJSON(value);
        if (object instanceof JSONObject) {
            JSONObject json = (JSONObject) object;
            Map map = new HashMap<>();
            for (Map.Entry entry : json.entrySet()) {
                if (VerifyUtil.isNotBlank(entry.getValue())) {
                    map.put(entry.getKey(), serializeValue(entry.getValue()));
                }
            }
            return map;
        } else {
            throw new IllegalArgumentException("value must be a plain object");
        }
    }

    protected  T deserializeFeilds(Map map, Class clazz) {
        // JSONObject json = new JSONObject();
        // json.putAll(map);
        // return JSON.toJavaObject(json, clazz);
        StringBuilder buffer = new StringBuilder();
        for (Entry entry : map.entrySet()) {
            if (VerifyUtil.isAnyBlank(entry.getKey(), entry.getValue())) continue;
            if (buffer.length() > 0) buffer.append(",");
            buffer.append('"').append(entry.getKey()).append('"').append(':');
            String value = entry.getValue();
            if (value.startsWith("\"") && value.endsWith("\"")) { // 兼容历史错误数据
                buffer.append(value);
            } else if (value.startsWith("{") && value.endsWith("}")) { // 对象
                buffer.append(value);
            } else if (value.startsWith("[") && value.endsWith("]")) { // 数组
                buffer.append(value);
            } else { // 普通字符串
                buffer.append(JSON.toJSONString(value)); // 替换字符串中的引号反斜杠
            }
        }
        String string = "{" + buffer.toString() + "}";

        try {
            return JSON.parseObject(string, clazz);
        } catch (Exception e) {
            log.error("JsonParseError:{}, class={}, text={}", e.toString(), clazz.getSimpleName(), string);
            throw e;
        }
    }

    protected  String serializeValue(T value) {
        if (value == null) {
            return null;
        } else if (value instanceof CharSequence) {
            return value.toString();
        } else if (value instanceof Enum) {
            return ((Enum) value).name();
        } else {
            String string = JSON.toJSONString(value);
            if (string.startsWith("\"") && string.startsWith("\"")) {
                return string.substring(1, string.length() - 1);
            } else if (string.startsWith("'") && string.startsWith("'")) {
                return string.substring(1, string.length() - 1);
            } else {
                return string;
            }
        }
    }

    @SuppressWarnings("unchecked")
    protected  T deserializeValue(String string, Class clazz) {
        if (string == null) {
            return null;
        } else if (clazz.isAssignableFrom(string.getClass())) {
            return (T) string;
        } else {
            try {
                return JSON.parseObject(string, clazz);
            } catch (Exception e) {
                log.error("JsonParseError:{}, class={}, text={}", e.toString(), clazz.getSimpleName(), string);
                throw e;
            }
        }
    }

    protected  List deserializeList(String string, Class clazz) {
        if (string == null) {
            return null;
        } else {
            try {
                return JSON.parseArray(string, clazz);
            } catch (Exception e) {
                log.error("JsonParseError:{}, class={}, text={}", e.toString(), clazz.getSimpleName(), string);
                throw e;
            }
        }
    }

    /** 检查KEY类型是否冲突 **/
    private void checkKeyTypeDuplicate(ICacheKeys key) throws IllegalArgumentException {
        String path = key.name();
        if (!keys.containsKey(path)) {
            keys.put(path, key);
        } else {
            ICacheKeys old = keys.get(path);
            if (key.type() == String.class || old.type() == String.class) {
                return; // String类型的不作判断
            }
            if (key.type() == Object.class || old.type() == Object.class) {
                return; // Object类型的不作判断
            }
            if (!key.equals(old) && key.getClass() != old.getClass() && key.type() != old.type()) {
                String k = key.name();
                String o = old.getClass().getName();
                String n = key.getClass().getName();
                throw new IllegalArgumentException("Key duplicate, " + k + " in " + o + " and " + n + ".");
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy