package io.fathom.cloud.state; import io.fathom.cloud.CloudException; import io.fathom.cloud.state.StateStore.StateNode; import java.io.IOException; import java.util.List; import com.google.common.collect.Lists; import com.google.common.util.concurrent.SettableFuture; import com.google.protobuf.AbstractMessage.Builder; import com.google.protobuf.ByteString; import com.google.protobuf.GeneratedMessage; import com.google.protobuf.Message; import com.google.protobuf.MessageOrBuilder; public class ItemCollection { final StateNode parentNode; final Codec codec; public ItemCollection(StateNode parentNode, Codec codec) { this.parentNode = parentNode; if (codec == null) { codec = new ProtobufCodec(); } this.codec = codec; } public ItemCollection(StateNode parentNode) { this(parentNode, null); } protected Message update(StateNode node, Message.Builder item) throws CloudException { Message msg = toMessage(item); ByteString data; try { data = codec.serialize(msg); } catch (IOException e) { throw new CloudException("Error serializing data", e); } node.update(data); return msg; } protected Message toMessage(MessageOrBuilder item) { Message msg; if (item instanceof Message) { msg = (Message) item; } else { msg = ((GeneratedMessage.Builder) item).build(); } return msg; } protected <T> List<T> deserializeChildren(StateNode parent, Builder builder) throws CloudException { List<T> items = Lists.newArrayList(); for (StateNode child : parent.getChildren()) { builder.clear(); T item = (T) deserialize(child, builder); items.add(item); } return items; } <T extends Builder, V extends Message> V deserialize(StateNode node, Builder<T> builder) throws StateStoreException { return deserialize(node, builder, null); } <T extends Builder, V extends Message> V deserialize(StateNode node, Builder<T> builder, SettableFuture<Object> watch) throws StateStoreException { ByteString data = node.read(watch); if (data == null) { return null; } try { V v = (V) codec.deserialize(builder, data); return v; } catch (IOException e) { throw new StateStoreException("Error reading item: " + node.getPath(), e); } } }