package edu.uw.zookeeper.protocol.server;
import static com.google.common.base.Preconditions.checkState;
import java.net.SocketAddress;
import edu.uw.zookeeper.ServerInetAddressView;
import edu.uw.zookeeper.ZooKeeperApplication;
import edu.uw.zookeeper.common.*;
import edu.uw.zookeeper.net.CodecConnection;
import edu.uw.zookeeper.net.NetServerModule;
import edu.uw.zookeeper.net.ServerConnectionFactory;
import edu.uw.zookeeper.netty.server.NettyServerModule;
import edu.uw.zookeeper.protocol.Message;
import edu.uw.zookeeper.protocol.ProtocolCodec;
import edu.uw.zookeeper.server.ClientAddressConfiguration;
public class ServerConnectionFactoryBuilder implements ZooKeeperApplication.RuntimeBuilder<ServerConnectionFactory<? extends ServerProtocolConnection<?,?>>, ServerConnectionFactoryBuilder> {
public static ServerConnectionFactoryBuilder defaults() {
return new ServerConnectionFactoryBuilder(null, null, null, null, null);
}
protected final RuntimeModule runtime;
protected final NetServerModule serverModule;
protected final Factory<? extends ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>> codecFactory;
protected final ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ? extends ServerProtocolConnection<?,?>> connectionFactory;
protected final ServerInetAddressView address;
public ServerConnectionFactoryBuilder(
RuntimeModule runtime,
NetServerModule serverModule,
Factory<? extends ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>> codecFactory,
ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ? extends ServerProtocolConnection<?,?>> connectionFactory,
ServerInetAddressView address) {
this.runtime = runtime;
this.serverModule = serverModule;
this.codecFactory = codecFactory;
this.connectionFactory = connectionFactory;
this.address = address;
}
@Override
public RuntimeModule getRuntimeModule() {
return runtime;
}
@Override
public ServerConnectionFactoryBuilder setRuntimeModule(RuntimeModule runtime) {
if (this.runtime == runtime) {
return this;
} else {
return newInstance(runtime, serverModule, codecFactory, connectionFactory, address);
}
}
public NetServerModule getServerModule() {
return serverModule;
}
public ServerConnectionFactoryBuilder setServerModule(NetServerModule serverModule) {
if (this.serverModule == serverModule) {
return this;
} else {
return newInstance(runtime, serverModule, codecFactory, connectionFactory, address);
}
}
public Factory<? extends ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>> getCodecFactory() {
return codecFactory;
}
public ServerConnectionFactoryBuilder setCodecFactory(
Factory<? extends ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>> codecFactory) {
if (this.codecFactory == codecFactory) {
return this;
} else {
return newInstance(runtime, serverModule, codecFactory, connectionFactory, address);
}
}
public ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ? extends ServerProtocolConnection<?,?>> getConnectionFactory() {
return connectionFactory;
}
public ServerConnectionFactoryBuilder setConnectionFactory(
ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ? extends ServerProtocolConnection<?,?>> connectionFactory) {
return newInstance(runtime, serverModule, codecFactory, connectionFactory, address);
}
public ServerInetAddressView getAddress() {
return address;
}
public ServerConnectionFactoryBuilder setAddress(ServerInetAddressView address) {
if (this.address == address) {
return this;
} else {
return newInstance(runtime, serverModule, codecFactory, connectionFactory, address);
}
}
@Override
public ServerConnectionFactoryBuilder setDefaults() {
checkState(runtime != null);
if (serverModule == null) {
return setServerModule(getDefaultServerModule()).setDefaults();
}
if (codecFactory == null) {
return setCodecFactory(getDefaultCodecFactory()).setDefaults();
}
if (connectionFactory == null) {
return setConnectionFactory(getDefaultConnectionFactory()).setDefaults();
}
if (address == null) {
return setAddress(getDefaultAddress()).setDefaults();
}
return this;
}
@Override
public ServerConnectionFactory<? extends ServerProtocolConnection<?,?>> build() {
return setDefaults().getDefaultServerConnectionFactory();
}
protected ServerConnectionFactoryBuilder newInstance(
RuntimeModule runtime,
NetServerModule serverModule,
Factory<? extends ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>> codecFactory,
ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ? extends ServerProtocolConnection<?,?>> connectionFactory,
ServerInetAddressView address) {
return new ServerConnectionFactoryBuilder(runtime, serverModule, codecFactory, connectionFactory, address);
}
protected NetServerModule getDefaultServerModule() {
return NettyServerModule.newInstance(runtime);
}
protected Factory<? extends ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>> getDefaultCodecFactory() {
return new Factory<ServerProtocolCodec>() {
@Override
public ServerProtocolCodec get() {
return ServerProtocolCodec.defaults();
}
};
}
protected ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ? extends ServerProtocolConnection<?,?>> getDefaultConnectionFactory() {
return new ParameterizedFactory<CodecConnection<Message.Server,Message.Client,ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>,?>, ServerProtocolConnection<?,?>>() {
@Override
public ServerProtocolConnection<?,?> get(
CodecConnection<Message.Server, Message.Client, ProtocolCodec<Message.Server, Message.Client, Message.Server, Message.Client>, ?> value) {
return ServerProtocolConnection.newInstance(value);
}
};
}
protected ServerConnectionFactory<? extends ServerProtocolConnection<?,?>> getDefaultServerConnectionFactory() {
ParameterizedFactory<SocketAddress, ? extends ServerConnectionFactory<? extends ServerProtocolConnection<?,?>>> serverConnectionFactory =
serverModule.getServerConnectionFactory(
codecFactory,
connectionFactory);
ServerConnectionFactory<? extends ServerProtocolConnection<?, ?>> serverConnections =
serverConnectionFactory.get(address.get());
return serverConnections;
}
protected ServerInetAddressView getDefaultAddress() {
return ClientAddressConfiguration.get(runtime.getConfiguration());
}
}