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

io.lettuce.core.output.PushOutput Maven / Gradle / Ivy

Go to download

Advanced and thread-safe Java Redis client for synchronous, asynchronous, and reactive usage. Supports Cluster, Sentinel, Pipelining, Auto-Reconnect, Codecs and much more.

The newest version!
package io.lettuce.core.output;

import java.nio.ByteBuffer;
import java.util.*;
import java.util.function.Function;

import io.lettuce.core.api.push.PushMessage;
import io.lettuce.core.codec.RedisCodec;
import io.lettuce.core.codec.StringCodec;
import io.lettuce.core.internal.LettuceAssert;

/**
 * Output for push notifications. The response output is always {@code List<Object>} as push notifications may contain
 * arbitrary values. The first response element which denotes the push message type is available through {@link #type()}.
 *
 * @author Mark Paluch
 * @since 6.0
 */
public class PushOutput extends NestedMultiOutput implements PushMessage {

    private String type;

    public PushOutput(RedisCodec codec) {
        super(codec);
    }

    @Override
    public void set(ByteBuffer bytes) {

        if (type == null) {
            bytes.mark();
            type = StringCodec.ASCII.decodeKey(bytes);
            bytes.reset();
        }

        super.set(bytes);
    }

    @Override
    public void setSingle(ByteBuffer bytes) {
        if (type == null) {
            set(bytes);
        }
        super.setSingle(bytes);
    }

    public String type() {
        return type;
    }

    @Override
    public String getType() {
        return type();
    }

    @Override
    public List getContent() {

        List copy = new ArrayList<>();

        for (Object o : get()) {
            if (o instanceof ByteBuffer) {
                copy.add(((ByteBuffer) o).asReadOnlyBuffer());
            } else {
                copy.add(o);
            }
        }

        return Collections.unmodifiableList(copy);
    }

    @Override
    public List getContent(Function decodeFunction) {

        LettuceAssert.notNull(decodeFunction, "Decode function must not be null");

        List copy = new ArrayList<>();

        for (Object o : get()) {
            copy.add(decode(o, decodeFunction));
        }

        return Collections.unmodifiableList(copy);
    }

    private Object decode(Object toDecode, Function decodeFunction) {

        if (toDecode instanceof List) {

            List copy = new ArrayList<>(((List) toDecode).size());

            for (Object o : (List) toDecode) {
                copy.add(decode(o, decodeFunction));
            }

            return copy;
        }

        if (toDecode instanceof Set) {

            Set copy = new LinkedHashSet<>(((Set) toDecode).size());

            for (Object o : (Set) toDecode) {
                copy.add(decode(o, decodeFunction));
            }

            return copy;

        }

        if (toDecode instanceof Map) {

            Map copy = new LinkedHashMap<>(((Map) toDecode).size());

            ((Map) toDecode).forEach((k, v) -> {
                copy.put(decode(k, decodeFunction), decode(v, decodeFunction));
            });

            return copy;
        }

        if (toDecode instanceof ByteBuffer) {

            ByteBuffer buffer = (ByteBuffer) toDecode;
            try {
                buffer.mark();
                return decodeFunction.apply(buffer);
            } finally {
                buffer.reset();
            }
        }

        return toDecode;
    }

}