/** * Copyright 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.waveprotocol.wave.examples.fedone.waveserver; import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; /** * Enforces consistency between serialised representations of protocol buffers (stored as * {@code ByteString}s) and their types. * * */ public final class ByteStringMessage<T extends Message> { private final ByteString byteString; private final T message; /** * Create a {@code ByteStringMessage} from a prototype of the message and its {@code ByteString} * representation. * * @param prototype to create the {@code Message} from * @param byteString representation of the message * @throws InvalidProtocolBufferException if byteString is not a valid protocol buffer */ public static <K extends Message> ByteStringMessage<K> from(K prototype, ByteString byteString) throws InvalidProtocolBufferException { return new ByteStringMessage<K>(prototype, byteString); } /** * Create a {@code ByteStringMessage} from the message itself. This should only ever be used when * committing the serialised version of a message, otherwise it defeats the purpose of this class. * * @param message to form the serialised version of */ @SuppressWarnings("unchecked") public static <K extends Message> ByteStringMessage<K> fromMessage(K message) { try { return (ByteStringMessage<K>) from( message.getDefaultInstanceForType(), message.toByteString()); } catch (InvalidProtocolBufferException e) { // This cannot possibly fail, unless the protocol buffer library is broken throw new AssertionError(e); } } @SuppressWarnings("unchecked") private ByteStringMessage(T prototype, ByteString byteString) throws InvalidProtocolBufferException { this.message = (T) prototype.newBuilderForType().mergeFrom(byteString).build(); this.byteString = byteString; } /** * @return the immutable underlying {@code Message} */ public T getMessage() { return message; } /** * @return the serialised representation of this message */ public ByteString getByteString() { return this.byteString; } /** * @return the serialised byte array representation of this message */ public byte[] getByteArray() { return this.byteString.toByteArray(); } @SuppressWarnings("unchecked") @Override public boolean equals(Object o) { if (!(o instanceof ByteStringMessage)) { return false; } else { ByteStringMessage<Message> bsm = (ByteStringMessage<Message>) o; return byteString.equals(bsm.byteString); } } @Override public int hashCode() { return byteString.hashCode(); } @Override public String toString() { return "ByteStringMessage: " + message; } }