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.support.redis;
017
018import com.jfinal.log.Log;
019import io.jboot.Jboot;
020import io.jboot.components.serializer.JbootSerializer;
021import io.jboot.components.serializer.JbootSerializerManager;
022import io.jboot.utils.StrUtil;
023import redis.clients.jedis.util.SafeEncoder;
024
025import java.util.ArrayList;
026import java.util.Collection;
027import java.util.List;
028import java.util.Set;
029
030/**
031 * 参考: com.jfinal.plugin.redis
032 * JbootRedis 命令文档: http://redisdoc.com/
033 */
034public abstract class JbootRedisBase implements JbootRedis {
035
036    private final JbootSerializer serializer;
037    private boolean close = false;
038
039    public JbootRedisBase(JbootRedisConfig config) {
040        if (config == null || StrUtil.isBlank(config.getSerializer())) {
041            serializer = Jboot.getSerializer();
042        } else {
043            serializer = JbootSerializerManager.me().getSerializer(config.getSerializer());
044        }
045
046        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
047            close = true;
048            System.err.println("JbootApplication exited, redis disconnection.");
049        }, "jboot-redis-hook"));
050    }
051
052
053    public boolean isClose() {
054        return close;
055    }
056
057
058    @Override
059    public byte[] keyToBytes(Object key) {
060        return SafeEncoder.encode(key.toString());
061    }
062
063    public Object keyFromBytes(byte[] bytes) {
064        return SafeEncoder.encode(bytes);
065    }
066
067    @Override
068    public String bytesToKey(byte[] bytes) {
069        return new String(bytes);
070    }
071
072    @Override
073    public byte[][] keysToBytesArray(Object... keys) {
074        byte[][] result = new byte[keys.length][];
075        for (int i = 0; i < result.length; i++)
076            result[i] = keyToBytes(keys[i]);
077        return result;
078    }
079
080
081    @Override
082    public void fieldSetFromBytesSet(Set<byte[]> data, Set<Object> result) {
083        for (byte[] fieldBytes : data) {
084            result.add(valueFromBytes(fieldBytes));
085        }
086    }
087
088    @Override
089    public byte[] valueToBytes(Object value) {
090        return serializer.serialize(value);
091    }
092
093    @Override
094    public Object valueFromBytes(byte[] bytes) {
095        if (bytes == null || bytes.length == 0) {
096            return null;
097        }
098        return serializer.deserialize(bytes);
099    }
100
101    @Override
102    public byte[][] valuesToBytesArray(Object... valuesArray) {
103        byte[][] data = new byte[valuesArray.length][];
104        for (int i = 0; i < data.length; i++)
105            data[i] = valueToBytes(valuesArray[i]);
106        return data;
107    }
108
109    @Override
110    public void valueSetFromBytesSet(Set<byte[]> data, Set<Object> result) {
111        for (byte[] valueBytes : data) {
112            result.add(valueFromBytes(valueBytes));
113        }
114    }
115
116    @Override
117    @SuppressWarnings("rawtypes")
118    public List valueListFromBytesList(Collection<byte[]> data) {
119        List<Object> result = new ArrayList<Object>();
120        for (byte[] d : data) {
121            Object object = null;
122            try {
123                object = valueFromBytes(d);
124            } catch (Throwable ex) {
125                /**
126                 *  有可能出现错误的情况
127                 *  在类似blpop等命令,会出现把key也返回,key并不是通过序列化转成byte,而是  key.toString().getBytes()
128                 */
129                object = new String(d);
130            }
131            result.add(object);
132        }
133        return result;
134    }
135
136    public List keyValueListFromBytesList(List<byte[]> data) {
137        List<Object> result = new ArrayList<Object>();
138        result.add(keyFromBytes(data.get(0)));
139        result.add(valueFromBytes(data.get(1)));
140        return result;
141    }
142
143
144}
145
146
147
148
149
150