package edu.uw.zookeeper.netty;
import java.util.Collection;
import java.util.Collections;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import io.netty.channel.Channel;
import edu.uw.zookeeper.common.Factory;
import edu.uw.zookeeper.common.ParameterizedFactory;
import edu.uw.zookeeper.net.Codec;
import edu.uw.zookeeper.net.CodecConnection;
import edu.uw.zookeeper.net.Connection;
public class ChannelCodecConnection<I,O,T extends Codec<I,? extends O,? extends I,?>> extends AbstractChannelConnection<I,O,ChannelCodecConnection<I,O,T>> implements CodecConnection<I,O,T,ChannelCodecConnection<I,O,T>> {
public static <I,O,T extends Codec<I,O,? extends I,? extends O>, C extends Connection<?,?,?>> ParameterizedFactory<Channel, C> factory(
final Factory<? extends T> codecFactory,
final ParameterizedFactory<CodecConnection<I,O,T,?>, C> connectionFactory) {
return new ParameterizedFactory<Channel, C>() {
@Override
public C get(Channel channel) {
T codec = codecFactory.get();
ChannelCodecConnection<I,O,T> connection = ChannelCodecConnection.defaults(codec, channel);
return connectionFactory.get(connection);
}
};
}
public static <I,O,T extends Codec<I,O,? extends I,? extends O>> ChannelCodecConnection<I,O,T> defaults(
T codec,
Channel channel) {
Collection<Connection.Listener<? super O>> listeners = Collections.emptySet();
return withListeners(codec, channel, listeners);
}
public static <I,O,T extends Codec<I,O,? extends I,? extends O>> ChannelCodecConnection<I,O,T> withListeners(
T codec,
Channel channel,
Collection<? extends Connection.Listener<? super O>> listeners) {
Logger logger = LogManager.getLogger(ChannelCodecConnection.class);
EventfulHandler<? extends O> eventful = EventfulHandler.withLogger(codec.decodeType(), logger);
ConnectionStateHandler state = ConnectionStateHandler.withLogger(logger);
return newInstance(codec, channel, eventful, state, listeners, logger);
}
public static <I,O,T extends Codec<I,O,? extends I,? extends O>> ChannelCodecConnection<I,O,T> newInstance(
T codec,
Channel channel,
EventfulHandler<? extends O> eventful,
ConnectionStateHandler state,
Collection<? extends Connection.Listener<? super O>> listeners,
Logger logger) {
return new ChannelCodecConnection<I,O,T>(codec, channel, eventful, state, listeners, logger);
}
protected final T codec;
protected ChannelCodecConnection(
T codec,
Channel channel,
EventfulHandler<? extends O> eventful,
ConnectionStateHandler state,
Collection<? extends Connection.Listener<? super O>> listeners,
Logger logger) {
super(channel, eventful, state, listeners, logger);
this.codec = codec;
DecoderHandler.toPipeline(
DecoderHandler.withDecoder(codec, logger),
EncoderHandler.toPipeline(
EncoderHandler.withEncoder(codec, logger),
channel.pipeline()));
}
@Override
public T codec() {
return codec;
}
@Override
protected ChannelCodecConnection<I,O,T> self() {
return this;
}
}