package edu.uw.zookeeper.data;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import com.google.common.base.Functions;
import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import edu.uw.zookeeper.common.TimeValue;
import edu.uw.zookeeper.protocol.ConnectMessage;
import edu.uw.zookeeper.protocol.Operation;
import edu.uw.zookeeper.protocol.Session;
import edu.uw.zookeeper.protocol.proto.*;
public abstract class Operations {
public static interface Builder<T extends Records.Coded> extends edu.uw.zookeeper.common.Builder<T> {
OpCode getOpCode();
T build();
}
public static interface PathBuilder<T extends Records.Coded, C extends PathBuilder<T,C>> extends Builder<T> {
ZNodePath getPath();
C setPath(ZNodePath path);
}
public static interface DataBuilder<T extends Records.Coded, C extends DataBuilder<T,C>> extends Builder<T> {
byte[] getData();
C setData(byte[] data);
}
public static abstract class AbstractBuilder<T extends Records.Coded> implements Builder<T> {
protected OpCode opcode;
protected AbstractBuilder(OpCode opcode) {
this.opcode = opcode;
}
@Override
public OpCode getOpCode() {
return opcode;
}
protected Builder<T> setOpCode(OpCode opcode) {
this.opcode = opcode;
return this;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this).toString();
}
}
public static abstract class AbstractPath<T extends Records.Coded, C extends AbstractPath<T,C>> extends AbstractBuilder<T> implements PathBuilder<T,C> {
protected ZNodePath path;
protected AbstractPath(OpCode opcode) {
super(opcode);
this.path = RootZNodePath.getInstance();
}
protected AbstractPath(OpCode opcode, ZNodePath path) {
super(opcode);
this.path = path;
}
@Override
public ZNodePath getPath() {
return path;
}
@Override
@SuppressWarnings("unchecked")
public C setPath(ZNodePath path) {
this.path = checkNotNull(path);
return (C) this;
}
}
public static abstract class Requests {
public static interface VersionBuilder<T extends Records.Request, C extends VersionBuilder<T,C>> extends Builder<T> {
int getVersion();
C setVersion(int version);
}
public static interface WatchBuilder<T extends Records.Request, C extends WatchBuilder<T,C>> extends Builder<T> {
boolean getWatch();
C setWatch(boolean watch);
}
public static abstract class AbstractWatch<T extends Records.Request, C extends AbstractWatch<T,C>> extends AbstractPath<T,C> implements WatchBuilder<T, AbstractWatch<T,C>> {
protected boolean watch;
protected AbstractWatch(OpCode opcode) {
super(opcode);
this.watch = false;
}
protected AbstractWatch(OpCode opcode, ZNodePath path, boolean watch) {
super(opcode, path);
this.watch = watch;
}
@Override
public boolean getWatch() {
return watch;
}
@Override
@SuppressWarnings("unchecked")
public C setWatch(boolean watch) {
this.watch = watch;
return (C) this;
}
}
public static abstract class AbstractVersion<T extends Records.Request, C extends AbstractVersion<T,C>> extends AbstractPath<T,C> implements VersionBuilder<T, AbstractVersion<T,C>> {
protected int version;
protected AbstractVersion(OpCode opcode) {
super(opcode);
this.version = Stats.VERSION_ANY;
}
protected AbstractVersion(OpCode opcode, ZNodePath path, int version) {
super(opcode, path);
this.version = version;
}
@Override
public int getVersion() {
return version;
}
@Override
@SuppressWarnings("unchecked")
public C setVersion(int version) {
this.version = version;
return (C) this;
}
}
public static abstract class AbstractData<T extends Records.Request, C extends AbstractData<T,C>> extends AbstractPath<T,C> implements DataBuilder<T,C> {
protected byte[] data;
protected AbstractData(OpCode opcode) {
super(opcode);
this.data = new byte[0];
}
protected AbstractData(OpCode opcode, ZNodePath path, byte[] data) {
super(opcode, path);
this.data = data;
}
@Override
public byte[] getData() {
return data;
}
@Override
@SuppressWarnings("unchecked")
public C setData(byte[] data) {
this.data = checkNotNull(data);
return (C) this;
}
}
public static class Check extends AbstractVersion<ICheckVersionRequest, Check> {
public static Check fromRecord(ICheckVersionRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
int version = request.getVersion();
return new Check(path, version);
}
public Check() {
super(OpCode.CHECK);
}
public Check(ZNodePath path, int version) {
super(OpCode.CHECK, path, version);
}
@Override
public ICheckVersionRequest build() {
ICheckVersionRequest record = new ICheckVersionRequest(
getPath().toString(), getVersion());
return record;
}
}
public static class Connect extends AbstractBuilder<ConnectMessage.Request> {
public static Connect fromRecord(ConnectMessage.Request request) {
return new Connect(
request.toSession(),
TimeValue.milliseconds(request.getTimeOut()),
request.getLastZxidSeen());
}
protected long lastZxid;
protected Session session;
protected TimeValue timeOut;
public Connect() {
super(OpCode.CREATE_SESSION);
this.lastZxid = 0L;
this.session = Session.uninitialized();
this.timeOut = TimeValue.milliseconds(0L);
}
public Connect(Session session, TimeValue timeOut, long lastZxid) {
super(OpCode.CREATE_SESSION);
this.lastZxid = lastZxid;
this.session = session;
this.timeOut = timeOut;
}
public Session getSession() {
return session;
}
public Connect setSession(Session session) {
this.session = session;
return this;
}
public long getLastZxid() {
return lastZxid;
}
public Connect setLastZxid(long lastZxid) {
this.lastZxid = lastZxid;
return this;
}
public TimeValue getTimeOut() {
return timeOut;
}
public Connect setTimeOut(TimeValue timeOut) {
this.timeOut = timeOut;
return this;
}
@Override
public ConnectMessage.Request build() {
if (Session.uninitialized().id() == session.id()) {
return ConnectMessage.Request.NewRequest.newInstance(timeOut, lastZxid);
} else {
return ConnectMessage.Request.RenewRequest.newInstance(session, lastZxid);
}
}
}
public static class Create extends AbstractData<Records.Request, Create> {
public static Create fromRecord(Records.Request request) {
Records.CreateModeGetter record = (Records.CreateModeGetter) request;
OpCode opcode = request.opcode();
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(record.getPath());
byte[] data = record.getData();
CreateMode mode = CreateMode.valueOf(record.getFlags());
List<Acls.Acl> acl = Acls.Acl.fromRecordList(record.getAcl());
return new Create(opcode, path, data, mode, acl);
}
protected CreateMode mode;
protected List<Acls.Acl> acl;
public Create() {
super(OpCode.CREATE);
this.mode = CreateMode.PERSISTENT;
this.acl = Acls.Definition.ANYONE_ALL.asList();
}
public Create(OpCode opcode, ZNodePath path, byte[] data, CreateMode mode, List<Acls.Acl> acl) {
super(opcode, path, data);
this.mode = mode;
this.acl = acl;
}
public CreateMode getMode() {
return mode;
}
public Create setMode(CreateMode mode) {
this.mode = checkNotNull(mode);
return this;
}
public boolean getStat() {
return (getOpCode() == OpCode.CREATE2);
}
/**
* >= 3.5.0
*/
public Create setStat(boolean getStat) {
setOpCode(getStat? OpCode.CREATE2 : OpCode.CREATE);
return this;
}
public List<Acls.Acl> getAcl() {
return acl;
}
public Create setAcl(List<Acls.Acl> acl) {
this.acl = checkNotNull(acl);
return this;
}
@Override
public Records.Request build() {
String path = getPath().toString();
byte[] data = getData();
List<ACL> acls = Acls.Acl.asRecordList(getAcl());
int mode = getMode().intValue();
Records.Request record = getStat()
? new ICreate2Request(path, data, acls, mode)
: new ICreateRequest(path, data, acls, mode);
return record;
}
}
public static class Delete extends AbstractVersion<IDeleteRequest, Delete> {
public static Delete fromRecord(IDeleteRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
int version = request.getVersion();
return new Delete(path, version);
}
public Delete() {
super(OpCode.DELETE);
}
public Delete(ZNodePath path, int version) {
super(OpCode.DELETE, path, version);
}
@Override
public IDeleteRequest build() {
IDeleteRequest record = new IDeleteRequest(
getPath().toString(), getVersion());
return record;
}
}
public static enum Disconnect implements Builder<IDisconnectRequest> {
DISCONNECT;
public static Disconnect getInstance() {
return DISCONNECT;
}
public static Disconnect fromRecord(IDisconnectRequest request) {
return getInstance();
}
@Override
public OpCode getOpCode() {
return OpCode.CLOSE_SESSION;
}
@Override
public IDisconnectRequest build() {
return Records.getShared(IDisconnectRequest.class);
}
}
public static class Exists extends AbstractWatch<IExistsRequest, Exists> {
public static Exists fromRecord(IExistsRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
boolean watch = request.getWatch();
return new Exists(path, watch);
}
public Exists() {
super(OpCode.EXISTS);
}
public Exists(ZNodePath path, boolean watch) {
super(OpCode.EXISTS, path, watch);
}
@Override
public IExistsRequest build() {
IExistsRequest record = new IExistsRequest(
getPath().toString(), getWatch());
return record;
}
}
public static class GetAcl extends AbstractPath<IGetACLRequest, GetAcl> {
public static GetAcl fromRecord(IGetACLRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
return new GetAcl(path);
}
public GetAcl() {
super(OpCode.GET_ACL);
}
public GetAcl(ZNodePath path) {
super(OpCode.GET_ACL, path);
}
@Override
public IGetACLRequest build() {
return new IGetACLRequest(getPath().toString());
}
}
public static class GetChildren extends AbstractWatch<Records.Request, GetChildren> {
public static GetChildren fromRecord(Records.Request request) {
OpCode opcode = request.opcode();
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(((Records.PathGetter)request).getPath());
boolean watch = ((Records.WatchGetter)request).getWatch();
return new GetChildren(opcode, path, watch);
}
public GetChildren() {
super(OpCode.GET_CHILDREN);
}
public GetChildren(OpCode opcode, ZNodePath path, boolean watch) {
super(opcode, path, watch);
}
public boolean getStat() {
return (getOpCode() == OpCode.GET_CHILDREN2);
}
public GetChildren setStat(boolean getStat) {
setOpCode(getStat ? OpCode.GET_CHILDREN2 : OpCode.GET_CHILDREN);
return this;
}
@Override
public Records.Request build() {
Records.Request record = getStat()
? new IGetChildren2Request(getPath().toString(), getWatch())
: new IGetChildrenRequest(getPath().toString(), getWatch());
return record;
}
}
public static class GetData extends AbstractWatch<IGetDataRequest, GetData> {
public static GetData fromRecord(IGetDataRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
boolean watch = request.getWatch();
return new GetData(path, watch);
}
public GetData() {
super(OpCode.GET_DATA);
}
public GetData(ZNodePath path, boolean watch) {
super(OpCode.GET_DATA, path, watch);
}
@Override
public IGetDataRequest build() {
IGetDataRequest record = new IGetDataRequest(
getPath().toString(), getWatch());
return record;
}
}
public static class Multi extends AbstractBuilder<IMultiRequest> implements Iterable<Builder<? extends Records.Request>> {
public static Multi fromRecord(IMultiRequest request) {
Multi builder = new Multi();
for (Records.MultiOpRequest e: request){
builder.add(Requests.fromRecord(e));
}
return builder;
}
protected List<Builder<? extends Records.Request>> builders;
public Multi() {
super(OpCode.MULTI);
this.builders = Lists.newArrayList();
}
public Multi add(Builder<? extends Records.Request> builder) {
builders.add(builder);
return this;
}
@Override
public Iterator<Builder<? extends Records.Request>> iterator() {
return builders.iterator();
}
@Override
public IMultiRequest build() {
ImmutableList.Builder<Records.MultiOpRequest> ops = ImmutableList.builder();
for (Builder<? extends Records.Request> builder: this) {
ops.add((Records.MultiOpRequest) builder.build());
}
return new IMultiRequest(ops.build());
}
}
public static enum Ping implements Builder<IPingRequest> {
PING;
public static Ping getInstance() {
return PING;
}
public static Ping fromRecord(IPingRequest request) {
return getInstance();
}
@Override
public OpCode getOpCode() {
return OpCode.PING;
}
@Override
public IPingRequest build() {
return Records.getShared(IPingRequest.class);
}
}
public static class RemoveWatches extends AbstractPath<IRemoveWatchesRequest, RemoveWatches> {
public static RemoveWatches fromRecord(IRemoveWatchesRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
Watcher.WatcherType type = Watcher.WatcherType.fromInt(request.getType());
return new RemoveWatches(path, type);
}
protected Watcher.WatcherType type;
public RemoveWatches() {
super(OpCode.REMOVE_WATCHES);
this.type = Watcher.WatcherType.Any;
}
public RemoveWatches(ZNodePath path, Watcher.WatcherType type) {
super(OpCode.REMOVE_WATCHES, path);
this.type = type;
}
public Watcher.WatcherType getType() {
return type;
}
public RemoveWatches setType(Watcher.WatcherType type) {
this.type = type;
return this;
}
@Override
public IRemoveWatchesRequest build() {
IRemoveWatchesRequest record = new IRemoveWatchesRequest(
getPath().toString(), getType().getIntValue());
return record;
}
}
public static class SetAcl extends AbstractVersion<ISetACLRequest, SetAcl> {
public static SetAcl fromRecord(ISetACLRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
int version = request.getVersion();
List<Acls.Acl> acl = Acls.Acl.fromRecordList(request.getAcl());
return new SetAcl(path, version, acl);
}
protected List<Acls.Acl> acl;
public SetAcl() {
super(OpCode.SET_ACL);
this.acl = Acls.Definition.ANYONE_ALL.asList();
}
public SetAcl(ZNodePath path, int version, List<Acls.Acl> acl) {
super(OpCode.SET_ACL, path, version);
this.acl = acl;
}
public List<Acls.Acl> getAcl() {
return acl;
}
public SetAcl setAcl(List<Acls.Acl> acls) {
this.acl = checkNotNull(acls);
return this;
}
@Override
public ISetACLRequest build() {
ISetACLRequest record = new ISetACLRequest(
getPath().toString(), Acls.Acl.asRecordList(getAcl()), getVersion());
return record;
}
}
public static class SetData extends AbstractData<ISetDataRequest, SetData> implements VersionBuilder<ISetDataRequest, SetData> {
public static SetData fromRecord(ISetDataRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
byte[] data = request.getData();
int version = request.getVersion();
return new SetData(path, data, version);
}
protected int version;
public SetData() {
super(OpCode.SET_DATA);
this.version = -1;
}
public SetData(ZNodePath path, byte[] data, int version) {
super(OpCode.SET_DATA, path, data);
this.version = version;
}
public int getVersion() {
return version;
}
public SetData setVersion(int version) {
this.version = version;
return this;
}
@Override
public ISetDataRequest build() {
ISetDataRequest record = new ISetDataRequest(
getPath().toString(), getData(), getVersion());
return record;
}
}
public static class Sync extends AbstractPath<ISyncRequest, Sync> {
public static Sync fromRecord(ISyncRequest request) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(request.getPath());
return new Sync(path);
}
public Sync() {
super(OpCode.SYNC);
}
public Sync(ZNodePath path) {
super(OpCode.SYNC, path);
}
@Override
public ISyncRequest build() {
return new ISyncRequest(getPath().toString());
}
}
public static class SerializedData<T extends Records.Request, C extends AbstractData<T,C>, V> extends AbstractBuilder<T> implements PathBuilder<T,SerializedData<T,C,V>>, DataBuilder<T,SerializedData<T,C,V>> {
public static <T extends Records.Request, C extends AbstractData<T,C>, V> SerializedData<T,C,V> of (C delegate, Serializers.ByteSerializer<? super V> serializer, V input) {
return new SerializedData<T,C,V>(delegate, serializer, input);
}
protected final C delegate;
protected final Serializers.ByteSerializer<? super V> serializer;
protected final V input;
public SerializedData(C delegate, Serializers.ByteSerializer<? super V> serializer, V input) {
super(delegate.getOpCode());
this.delegate = delegate;
this.input = input;
this.serializer = serializer;
}
public V input() {
return input;
}
public Serializers.ByteSerializer<? super V> serializer() {
return serializer;
}
public C delegate() {
return delegate;
}
@Override
public T build() {
if (input() != null) {
try {
delegate().setData(serializer().toBytes(input()));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}
return delegate().build();
}
@Override
public ZNodePath getPath() {
return delegate().getPath();
}
@Override
public SerializedData<T,C,V> setPath(ZNodePath path) {
delegate().setPath(path);
return this;
}
@Override
public byte[] getData() {
return delegate().getData();
}
@Override
public SerializedData<T,C,V> setData(byte[] data) {
delegate.setData(data);
return this;
}
}
public static Builder<? extends Records.Request> fromRecord(Records.Request record) {
switch (record.opcode()) {
case CHECK:
return Check.fromRecord((ICheckVersionRequest) record);
case CREATE_SESSION:
return Connect.fromRecord((ConnectMessage.Request) record);
case CREATE:
case CREATE2:
return Create.fromRecord(record);
case CLOSE_SESSION:
return Disconnect.fromRecord((IDisconnectRequest) record);
case DELETE:
return Delete.fromRecord((IDeleteRequest) record);
case EXISTS:
return Exists.fromRecord((IExistsRequest) record);
case GET_ACL:
return GetAcl.fromRecord((IGetACLRequest) record);
case GET_CHILDREN:
case GET_CHILDREN2:
return GetChildren.fromRecord(record);
case GET_DATA:
return GetData.fromRecord((IGetDataRequest) record);
case MULTI:
return Multi.fromRecord((IMultiRequest) record);
case PING:
return Ping.fromRecord((IPingRequest) record);
case SET_ACL:
return SetAcl.fromRecord((ISetACLRequest) record);
case SET_DATA:
return SetData.fromRecord((ISetDataRequest) record);
case SYNC:
return Sync.fromRecord((ISyncRequest) record);
default:
throw new IllegalArgumentException(record.toString());
}
}
public static Builder<? extends Records.Request> fromOpCode(OpCode opcode) {
switch (opcode) {
case CHECK:
return check();
case CREATE_SESSION:
return connect();
case CLOSE_SESSION:
return disconnect();
case CREATE:
return create();
case CREATE2:
return create().setStat(true);
case DELETE:
return delete();
case EXISTS:
return exists();
case GET_ACL:
return getAcl();
case GET_CHILDREN:
return getChildren();
case GET_CHILDREN2:
return getChildren().setStat(true);
case GET_DATA:
return getData();
case MULTI:
return multi();
case PING:
return ping();
case SET_ACL:
return setAcl();
case SET_DATA:
return setData();
case SYNC:
return sync();
default:
throw new IllegalArgumentException(opcode.toString());
}
}
public static Connect connect() {
return new Connect();
}
public static Check check() {
return new Check();
}
public static Create create() {
return new Create();
}
public static Delete delete() {
return new Delete();
}
public static Disconnect disconnect() {
return Disconnect.getInstance();
}
public static Exists exists() {
return new Exists();
}
public static GetAcl getAcl() {
return new GetAcl();
}
public static GetChildren getChildren() {
return new GetChildren();
}
public static GetData getData() {
return new GetData();
}
public static Multi multi() {
return new Multi();
}
public static Ping ping() {
return Ping.getInstance();
}
public static RemoveWatches removeWatches() {
return new RemoveWatches();
}
public static SetAcl setAcl() {
return new SetAcl();
}
public static SetData setData() {
return new SetData();
}
public static Sync sync() {
return new Sync();
}
public static <T extends Records.Request, C extends AbstractData<T,C>, V> SerializedData<T,C,V> serialized(C delegate, Serializers.ByteSerializer<? super V> serializer, V input) {
return SerializedData.of(delegate, serializer, input);
}
private Requests() {}
}
public static abstract class Responses {
public static interface StatBuilder<T extends Records.Response, C extends StatBuilder<T,C>> extends Builder<T> {
Stat getStat();
C setStat(Stat stat);
}
public static abstract class AbstractStat<T extends Records.Response, C extends AbstractStat<T,C>> extends AbstractBuilder<T> implements StatBuilder<T,C> {
protected Stat stat;
protected AbstractStat(OpCode opcode) {
super(opcode);
this.stat = Stats.ImmutableStat.uninitialized();
}
protected AbstractStat(OpCode opcode, Stat stat) {
super(opcode);
this.stat = stat;
}
@Override
public Stat getStat() {
return stat;
}
@Override
@SuppressWarnings("unchecked")
public C setStat(Stat stat) {
this.stat = stat;
return (C) this;
}
}
public static class Connect extends AbstractBuilder<ConnectMessage.Response> {
public static Connect fromRecord(ConnectMessage.Response record) {
return new Connect(
record.toSession());
}
protected Session session;
public Connect() {
super(OpCode.CREATE_SESSION);
this.session = Session.uninitialized();
}
public Connect(Session session) {
super(OpCode.CREATE_SESSION);
this.session = session;
}
public Session getSession() {
return session;
}
public Connect setSession(Session session) {
this.session = session;
return this;
}
@Override
public ConnectMessage.Response build() {
if (Session.uninitialized().id() == session.id()) {
return ConnectMessage.Response.Invalid.newInstance();
} else {
return ConnectMessage.Response.Valid.newInstance(session);
}
}
}
public static class Check extends AbstractStat<ICheckVersionResponse, Check> {
public static Check fromRecord(ICheckVersionResponse record) {
Stat stat = record.getStat();
return new Check(stat);
}
public Check() {
super(OpCode.CHECK);
}
public Check(Stat stat) {
super(OpCode.CHECK, stat);
}
@Override
public ICheckVersionResponse build() {
return new ICheckVersionResponse(getStat());
}
}
public static class Create extends AbstractStat<Records.Response, Create> implements PathBuilder<Records.Response, Create> {
public static Create fromRecord(Records.Response record) {
OpCode opcode = record.opcode();
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(((Records.PathGetter) record).getPath());
Stat stat = null;
if (record instanceof Records.StatGetter) {
stat = ((Records.StatGetter) record).getStat();
}
return new Create(opcode, stat, path);
}
protected ZNodePath path;
public Create() {
super(OpCode.CREATE);
this.path = RootZNodePath.getInstance();
}
public Create(OpCode opcode, Stat stat, ZNodePath path) {
super(opcode, stat);
this.path = path;
}
@Override
public ZNodePath getPath() {
return path;
}
@Override
public Create setPath(ZNodePath path) {
this.path = path;
return this;
}
@Override
public Create setStat(Stat stat) {
setOpCode((stat != null) ? OpCode.CREATE2 : OpCode.CREATE);
super.setStat(stat);
return this;
}
@Override
public Records.Response build() {
Records.Response record = (getOpCode() == OpCode.CREATE2)
? new ICreate2Response(getPath().toString(), getStat())
: new ICreateResponse(getPath().toString());
return record;
}
}
public static enum Delete implements Builder<IDeleteResponse> {
DELETE;
public static Delete getInstance() {
return DELETE;
}
public static Delete fromRecord(IDeleteResponse record) {
return getInstance();
}
@Override
public OpCode getOpCode() {
return OpCode.DELETE;
}
@Override
public IDeleteResponse build() {
return Records.getShared(IDeleteResponse.class);
}
}
public static enum Disconnect implements Builder<IDisconnectResponse> {
DISCONNECT;
public static Disconnect getInstance() {
return DISCONNECT;
}
public static Disconnect fromRecord(IDisconnectResponse request) {
return getInstance();
}
@Override
public OpCode getOpCode() {
return OpCode.CLOSE_SESSION;
}
@Override
public IDisconnectResponse build() {
return Records.getShared(IDisconnectResponse.class);
}
}
public static class Exists extends AbstractStat<IExistsResponse, Exists> {
public static Exists fromRecord(IExistsResponse record) {
Stat stat = record.getStat();
return new Exists(stat);
}
public Exists() {
super(OpCode.EXISTS);
}
public Exists(Stat stat) {
super(OpCode.EXISTS, stat);
}
@Override
public IExistsResponse build() {
return new IExistsResponse(getStat());
}
}
public static class Error extends AbstractBuilder<IErrorResponse> {
public static Error fromRecord(IErrorResponse record) {
return new Error(record.error());
}
protected KeeperException.Code error;
public Error() {
this(KeeperException.Code.OK);
}
public Error(KeeperException.Code error) {
super(OpCode.ERROR);
this.error = error;
}
public KeeperException.Code getError() {
return error;
}
public Error setError(KeeperException.Code error) {
this.error = error;
return this;
}
@Override
public IErrorResponse build() {
return new IErrorResponse(getError());
}
}
public static class GetAcl extends AbstractStat<IGetACLResponse, GetAcl> {
public static GetAcl fromRecord(IGetACLResponse record) {
Stat stat = record.getStat();
List<Acls.Acl> acl = Acls.Acl.fromRecordList(record.getAcl());
return new GetAcl(stat, acl);
}
protected List<Acls.Acl> acl;
public GetAcl() {
super(OpCode.GET_ACL);
this.acl = ImmutableList.of();
}
public GetAcl(Stat stat, List<Acls.Acl> acl) {
super(OpCode.GET_ACL, stat);
this.acl = acl;
}
public List<Acls.Acl> getAcl() {
return acl;
}
public GetAcl setAcl(List<Acls.Acl> acl) {
this.acl = acl;
return this;
}
@Override
public IGetACLResponse build() {
return new IGetACLResponse(Acls.Acl.asRecordList(getAcl()), getStat());
}
}
public static class GetChildren extends AbstractStat<Records.Response, GetChildren> {
public static GetChildren fromRecord(Records.Response record) {
OpCode opcode = record.opcode();
Stat stat = null;
if (record instanceof Records.StatGetter) {
stat = ((Records.StatGetter) record).getStat();
}
List<String> childrenStr = ((Records.ChildrenGetter) record).getChildren();
List<ZNodeLabel> children = Lists.newArrayListWithCapacity(childrenStr.size());
for (String e: childrenStr) {
children.add(ZNodeLabel.fromString(e));
}
return new GetChildren(opcode, stat, children);
}
protected Iterable<ZNodeLabel> children;
public GetChildren() {
super(OpCode.GET_CHILDREN);
this.children = ImmutableList.of();
}
public GetChildren(OpCode opcode, Stat stat, Iterable<ZNodeLabel> children) {
super(opcode, stat);
this.children = children;
}
@Override
public GetChildren setStat(Stat stat) {
setOpCode((stat != null) ? OpCode.GET_CHILDREN2 : OpCode.GET_CHILDREN);
super.setStat(stat);
return this;
}
public Iterable<ZNodeLabel> getChildren() {
return children;
}
public GetChildren setChildren(Iterable<ZNodeLabel> children) {
this.children = children;
return this;
}
@Override
public Records.Response build() {
List<String> children = ImmutableList.copyOf(Iterables.transform(getChildren(), Functions.toStringFunction()));
Records.Response record = (OpCode.GET_CHILDREN2 == getOpCode())
? new IGetChildren2Response(children, getStat())
: new IGetChildrenResponse(children);
return record;
}
}
public static class GetData extends AbstractStat<IGetDataResponse, GetData> implements DataBuilder<IGetDataResponse, GetData> {
public static GetData fromRecord(IGetDataResponse record) {
Stat stat = record.getStat();
byte[] data = record.getData();
return new GetData(stat, data);
}
protected byte[] data;
public GetData() {
super(OpCode.GET_DATA, Stats.ImmutableStat.uninitialized());
this.data = new byte[0];
}
public GetData(Stat stat, byte[] data) {
super(OpCode.GET_DATA, stat);
this.data = data;
}
@Override
public byte[] getData() {
return data;
}
@Override
public GetData setData(byte[] data) {
this.data = data;
return this;
}
@Override
public IGetDataResponse build() {
return new IGetDataResponse(getData(), getStat());
}
}
public static class Multi extends AbstractBuilder<IMultiResponse> implements Iterable<Builder<? extends Records.Response>> {
public static Multi fromRecord(IMultiResponse record) {
Multi builder = new Multi();
for (Records.MultiOpResponse e: record){
builder.add(Responses.fromRecord(e));
}
return builder;
}
protected List<Builder<? extends Records.Response>> builders;
public Multi() {
super(OpCode.MULTI);
this.builders = Lists.newArrayList();
}
public Multi add(Builder<? extends Records.Response> builder) {
builders.add(builder);
return this;
}
@Override
public Iterator<Builder<? extends Records.Response>> iterator() {
return builders.iterator();
}
@Override
public IMultiResponse build() {
ImmutableList.Builder<Records.MultiOpResponse> ops = ImmutableList.builder();
for (Builder<? extends Records.Response> builder: this) {
ops.add((Records.MultiOpResponse) builder.build());
}
return new IMultiResponse(ops.build());
}
}
public static enum Ping implements Builder<IPingResponse> {
PING;
public static Ping getInstance() {
return PING;
}
public static Ping fromRecord(IPingResponse record) {
return getInstance();
}
@Override
public OpCode getOpCode() {
return OpCode.PING;
}
@Override
public IPingResponse build() {
return Records.getShared(IPingResponse.class);
}
}
public static class Notification extends AbstractPath<IWatcherEvent, Notification> {
public static Notification fromRecord(IWatcherEvent record) {
return new Notification(
(ZNodePath) ZNodeLabelVector.fromString(record.getPath()),
EventType.fromInt(record.getType()),
KeeperState.fromInt(record.getState()));
}
private KeeperState keeperState;
private EventType eventType;
public Notification() {
super(OpCode.NOTIFICATION);
this.eventType = EventType.None;
this.keeperState = KeeperState.SyncConnected;
}
public Notification(
ZNodePath path,
EventType eventType,
KeeperState keeperState) {
super(OpCode.NOTIFICATION, path);
this.eventType = eventType;
this.keeperState = keeperState;
}
public KeeperState getKeeperState() {
return keeperState;
}
public Notification setKeeperState(KeeperState keeperState) {
this.keeperState = keeperState;
return this;
}
public EventType getEventType() {
return eventType;
}
public Notification setEventType(EventType eventType) {
this.eventType = eventType;
return this;
}
@Override
public IWatcherEvent build() {
return new IWatcherEvent(
getEventType().getIntValue(),
getKeeperState().getIntValue(),
getPath().toString());
}
}
public static enum RemoveWatches implements Builder<IRemoveWatchesResponse> {
REMOVE_WATCHES;
public static RemoveWatches getInstance() {
return REMOVE_WATCHES;
}
public static RemoveWatches fromRecord(IRemoveWatchesResponse request) {
return getInstance();
}
@Override
public OpCode getOpCode() {
return OpCode.REMOVE_WATCHES;
}
@Override
public IRemoveWatchesResponse build() {
return Records.getShared(IRemoveWatchesResponse.class);
}
}
public static class SetAcl extends AbstractStat<ISetACLResponse, SetAcl> {
public static SetAcl fromRecord(ISetACLResponse record) {
Stat stat = record.getStat();
return new SetAcl(stat);
}
public SetAcl() {
super(OpCode.SET_ACL);
}
public SetAcl(Stat stat) {
super(OpCode.SET_ACL, stat);
}
@Override
public ISetACLResponse build() {
return new ISetACLResponse(getStat());
}
}
public static class SetData extends AbstractStat<ISetDataResponse, SetData> {
public static SetData fromRecord(ISetDataResponse record) {
Stat stat = record.getStat();
return new SetData(stat);
}
public SetData() {
super(OpCode.SET_DATA);
}
public SetData(Stat stat) {
super(OpCode.SET_DATA, stat);
}
@Override
public ISetDataResponse build() {
return new ISetDataResponse(getStat());
}
}
public static class Sync extends AbstractPath<ISyncResponse, Sync> {
public static Sync fromRecord(ISyncResponse record) {
ZNodePath path = (ZNodePath) ZNodeLabelVector.fromString(record.getPath());
return new Sync(path);
}
public Sync() {
super(OpCode.SYNC);
}
public Sync(ZNodePath path) {
super(OpCode.SYNC, path);
}
@Override
public ISyncResponse build() {
return new ISyncResponse(getPath().toString());
}
}
public static Builder<? extends Records.Response> fromRecord(Records.Response record) {
switch (record.opcode()) {
case CHECK:
return Check.fromRecord((ICheckVersionResponse) record);
case CREATE:
case CREATE2:
return Create.fromRecord(record);
case CREATE_SESSION:
return Connect.fromRecord((ConnectMessage.Response) record);
case CLOSE_SESSION:
return Disconnect.fromRecord((IDisconnectResponse) record);
case DELETE:
return Delete.fromRecord((IDeleteResponse) record);
case ERROR:
return Error.fromRecord((IErrorResponse) record);
case EXISTS:
return Exists.fromRecord((IExistsResponse) record);
case GET_ACL:
return GetAcl.fromRecord((IGetACLResponse) record);
case GET_CHILDREN:
case GET_CHILDREN2:
return GetChildren.fromRecord(record);
case GET_DATA:
return GetData.fromRecord((IGetDataResponse) record);
case MULTI:
return Multi.fromRecord((IMultiResponse) record);
case PING:
return Ping.fromRecord((IPingResponse) record);
case NOTIFICATION:
return Notification.fromRecord((IWatcherEvent) record);
case SET_ACL:
return SetAcl.fromRecord((ISetACLResponse) record);
case SET_DATA:
return SetData.fromRecord((ISetDataResponse) record);
case SYNC:
return Sync.fromRecord((ISyncResponse) record);
default:
throw new IllegalArgumentException(record.toString());
}
}
public static Builder<? extends Records.Response> fromOpCode(OpCode opcode) {
switch (opcode) {
case CHECK:
return check();
case CREATE:
return create();
case CREATE2:
return create().setStat(Stats.ImmutableStat.uninitialized());
case CREATE_SESSION:
return connect();
case CLOSE_SESSION:
return disconnect();
case DELETE:
return delete();
case ERROR:
return error();
case EXISTS:
return exists();
case GET_ACL:
return getAcl();
case GET_CHILDREN:
return getChildren();
case GET_CHILDREN2:
return getChildren().setStat(Stats.ImmutableStat.uninitialized());
case GET_DATA:
return getData();
case MULTI:
return multi();
case PING:
return ping();
case NOTIFICATION:
return notification();
case SET_ACL:
return setAcl();
case SET_DATA:
return setData();
case SYNC:
return sync();
default:
throw new IllegalArgumentException(opcode.toString());
}
}
public static Check check() {
return new Check();
}
public static Create create() {
return new Create();
}
public static Connect connect() {
return new Connect();
}
public static Delete delete() {
return Delete.getInstance();
}
public static Disconnect disconnect() {
return Disconnect.getInstance();
}
public static Error error() {
return new Error();
}
public static Exists exists() {
return new Exists();
}
public static GetAcl getAcl() {
return new GetAcl();
}
public static GetChildren getChildren() {
return new GetChildren();
}
public static GetData getData() {
return new GetData();
}
public static Multi multi() {
return new Multi();
}
public static Ping ping() {
return Ping.getInstance();
}
public static Notification notification() {
return new Notification();
}
public static RemoveWatches removeWatches() {
return RemoveWatches.getInstance();
}
public static SetAcl setAcl() {
return new SetAcl();
}
public static SetData setData() {
return new SetData();
}
public static Sync sync() {
return new Sync();
}
}
public static Builder<? extends Records.Coded> fromRecord(Records.Coded input) {
if (input instanceof Records.Request) {
return Requests.fromRecord((Records.Request) input);
} else {
return Responses.fromRecord((Records.Response) input);
}
}
public static <T extends Operation.ProtocolResponse<?>> T unlessProtocolError(Records.PathGetter request, T response) throws KeeperException {
return unlessProtocolError(response, request.getPath());
}
public static <T extends Operation.ProtocolResponse<?>> T unlessProtocolError(T response) throws KeeperException {
return unlessProtocolError(response, "");
}
public static <T extends Operation.ProtocolResponse<?>> T unlessProtocolError(T response, String path) throws KeeperException {
unlessError(response.record(), path);
return response;
}
public static <T extends Records.Response> T unlessError(Records.PathGetter request, T response) throws KeeperException {
return unlessError(response, request.getPath());
}
public static <T extends Records.Response> T unlessError(T response) throws KeeperException {
return unlessError(response, "");
}
public static <T extends Records.Response> T unlessError(T response, String path) throws KeeperException {
if (response instanceof Operation.Error) {
KeeperException.Code error = ((Operation.Error) response).error();
throw KeeperException.create(error, path);
} else {
return response;
}
}
public static IMultiResponse unlessMultiError(IMultiResponse response) throws KeeperException {
return Operations.unlessMultiError(response, "");
}
public static IMultiResponse unlessMultiError(IMultiResponse response, String path) throws KeeperException {
for (Records.MultiOpResponse record: response) {
maybeError(record, path, KeeperException.Code.OK);
}
return response;
}
public static Optional<Operation.Error> maybeMultiError(IMultiResponse response, KeeperException.Code... expected) throws KeeperException {
return Operations.maybeMultiError(response, "", expected);
}
public static Optional<Operation.Error> maybeMultiError(IMultiResponse response, String path, KeeperException.Code... expected) throws KeeperException {
for (Records.MultiOpResponse record: response) {
if (record instanceof Operation.Error) {
Operation.Error error = (Operation.Error) record;
if (error.error() != KeeperException.Code.OK) {
for (KeeperException.Code code: expected) {
if (error.error() == code) {
return Optional.of(error);
}
}
}
throw KeeperException.create(error.error(), path);
}
}
return Optional.absent();
}
public static Operation.Error expectError(Records.Response response, KeeperException.Code expected) throws KeeperException {
return Operations.expectError(response, "", expected);
}
public static Operation.Error expectError(Records.Response response, String path, KeeperException.Code expected) throws KeeperException {
if (response instanceof Operation.Error) {
Operation.Error error = (Operation.Error) response;
if (expected != error.error()) {
throw KeeperException.create(error.error(), path);
}
return error;
} else {
throw new KeeperException.RuntimeInconsistencyException();
}
}
public static Optional<Operation.Error> maybeProtocolError(Records.PathGetter request, Operation.ProtocolResponse<?> response, KeeperException.Code... expected) throws KeeperException {
return maybeProtocolError(response, request.getPath(), expected);
}
public static Optional<Operation.Error> maybeProtocolError(Operation.ProtocolResponse<?> response, KeeperException.Code... expected) throws KeeperException {
return maybeProtocolError(response, "", expected);
}
public static Optional<Operation.Error> maybeProtocolError(Operation.ProtocolResponse<?> response, String path, KeeperException.Code... expected) throws KeeperException {
return maybeError(response.record(), path);
}
public static Optional<Operation.Error> maybeError(Records.PathGetter request, Records.Response response, KeeperException.Code... expected) throws KeeperException {
return maybeError(response, request.getPath(), expected);
}
public static Optional<Operation.Error> maybeError(Records.Response response, KeeperException.Code... expected) throws KeeperException {
return maybeError(response, "", expected);
}
public static Optional<Operation.Error> maybeError(Records.Response response, String path, KeeperException.Code... expected) throws KeeperException {
if (response instanceof Operation.Error) {
Operation.Error error = (Operation.Error) response;
for (KeeperException.Code code: expected) {
if (error.error() == code) {
return Optional.of(error);
}
}
throw KeeperException.create(error.error(), path);
}
return Optional.absent();
}
private Operations() {}
}