Package org.waveprotocol.box.server.persistence.mongodb

Source Code of org.waveprotocol.box.server.persistence.mongodb.MongoDbDeltaStoreUtil

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.box.server.persistence.mongodb;

import com.google.common.collect.ImmutableList;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;

import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

import org.waveprotocol.box.server.common.CoreWaveletOperationSerializer;
import org.waveprotocol.box.server.persistence.PersistenceException;
import org.waveprotocol.box.server.persistence.protos.ProtoDeltaStoreDataSerializer;
import org.waveprotocol.box.server.waveserver.ByteStringMessage;
import org.waveprotocol.box.server.waveserver.WaveletDeltaRecord;
import org.waveprotocol.wave.federation.Proto.ProtocolDocumentOperation;
import org.waveprotocol.wave.model.document.operation.DocOp;
import org.waveprotocol.wave.model.operation.wave.AddParticipant;
import org.waveprotocol.wave.model.operation.wave.BlipContentOperation;
import org.waveprotocol.wave.model.operation.wave.BlipOperation;
import org.waveprotocol.wave.model.operation.wave.NoOp;
import org.waveprotocol.wave.model.operation.wave.RemoveParticipant;
import org.waveprotocol.wave.model.operation.wave.TransformedWaveletDelta;
import org.waveprotocol.wave.model.operation.wave.WaveletBlipOperation;
import org.waveprotocol.wave.model.operation.wave.WaveletOperation;
import org.waveprotocol.wave.model.operation.wave.WaveletOperationContext;
import org.waveprotocol.wave.model.version.HashedVersion;
import org.waveprotocol.wave.model.wave.ParticipantId;

/**
* A utility class to serialize/deserialize delta objects to/from MongoDB. The
* implementation approach is analog to the provided at
* {@link CoreWaveletOperationSerializer} and
* {@link ProtoDeltaStoreDataSerializer}
*
* @author pablojan@gmail.com (Pablo Ojanguren)
*/
public class MongoDbDeltaStoreUtil {
  public static final String WAVELET_OP_WAVELET_BLIP_OPERATION = "WaveletBlipOperation";
  public static final String WAVELET_OP_REMOVE_PARTICIPANT = "RemoveParticipant";
  public static final String WAVELET_OP_ADD_PARTICIPANT = "AddParticipant";
  public static final String WAVELET_OP_NOOP = "NoOp";
  public static final String FIELD_BYTES = "bytes";
  public static final String FIELD_CONTENTOP = "contentop";
  public static final String FIELD_BLIPOP = "blipop";
  public static final String FIELD_BLIPID = "blipid";
  public static final String FIELD_PARTICIPANT = "participant";
  public static final String FIELD_TYPE = "type";
  public static final String FIELD_OPS = "ops";
  public static final String FIELD_APPLICATIONTIMESTAMP = "applicationtimestamp";
  public static final String FIELD_AUTHOR = "author";
  public static final String FIELD_ADDRESS = "address";
  public static final String FIELD_HISTORYHASH = "historyhash";
  public static final String FIELD_VERSION = "version";
  public static final String FIELD_TRANSFORMED_RESULTINGVERSION_VERSION =
      "transformed.resultingversion.version";
  public static final String FIELD_TRANSFORMED_APPLIEDATVERSION = "transformed.appliedatversion";
  public static final String FIELD_TRANSFORMED_RESULTINGVERSION = "transformed.resultingversion";
  public static final String FIELD_APPLIEDATVERSION = "appliedatversion";
  public static final String FIELD_RESULTINGVERSION = "resultingversion";
  public static final String FIELD_TRANSFORMED = "transformed";
  public static final String FIELD_APPLIED = "applied";
  public static final String FIELD_WAVELET_ID = "waveletid";
  public static final String FIELD_WAVE_ID = "waveid";

  public static DBObject serialize(WaveletDeltaRecord waveletDelta, String waveId, String waveletId) {

    BasicDBObject mongoWaveletDelta = new BasicDBObject();

    mongoWaveletDelta.append(FIELD_WAVE_ID, waveId);
    mongoWaveletDelta.append(FIELD_WAVELET_ID, waveletId);

    mongoWaveletDelta.append(FIELD_APPLIEDATVERSION, serialize(waveletDelta.getAppliedAtVersion()));
    mongoWaveletDelta.append(FIELD_APPLIED, waveletDelta.getAppliedDelta().getByteArray());
    mongoWaveletDelta.append(FIELD_TRANSFORMED, serialize(waveletDelta.getTransformedDelta()));

    return mongoWaveletDelta;
  }

  public static DBObject serialize(HashedVersion hashedVersion) {
    BasicDBObject mongoHashedVersion = new BasicDBObject();
    mongoHashedVersion.append(FIELD_VERSION, hashedVersion.getVersion());
    mongoHashedVersion.append(FIELD_HISTORYHASH, hashedVersion.getHistoryHash());
    return mongoHashedVersion;
  }

  public static DBObject serialize(ParticipantId participantId) {
    BasicDBObject mongoParticipantId = new BasicDBObject();
    mongoParticipantId.append(FIELD_ADDRESS, participantId.getAddress());
    return mongoParticipantId;
  }

  public static DBObject serialize(TransformedWaveletDelta transformedWaveletDelta) {
    BasicDBObject mongoTransformedWaveletDelta = new BasicDBObject();
    mongoTransformedWaveletDelta.append(FIELD_AUTHOR,
        serialize(transformedWaveletDelta.getAuthor()));
    mongoTransformedWaveletDelta.append(FIELD_RESULTINGVERSION,
        serialize(transformedWaveletDelta.getResultingVersion()));
    mongoTransformedWaveletDelta.append(FIELD_APPLICATIONTIMESTAMP,
        transformedWaveletDelta.getApplicationTimestamp());

    mongoTransformedWaveletDelta.append(FIELD_APPLIEDATVERSION,
        transformedWaveletDelta.getAppliedAtVersion());

    BasicDBList mongoWaveletOperations = new BasicDBList();

    for (WaveletOperation op : transformedWaveletDelta) {
      mongoWaveletOperations.add(serialize(op));
    }

    mongoTransformedWaveletDelta.append(FIELD_OPS, mongoWaveletOperations);

    return mongoTransformedWaveletDelta;
  }

  public static DBObject serialize(WaveletOperation waveletOp) {
    final BasicDBObject mongoOp = new BasicDBObject();

    if (waveletOp instanceof NoOp) {
      mongoOp.append(FIELD_TYPE, WAVELET_OP_NOOP);

    } else if (waveletOp instanceof AddParticipant) {
      mongoOp.append(FIELD_TYPE, WAVELET_OP_ADD_PARTICIPANT);
      mongoOp.append(FIELD_PARTICIPANT, serialize(((AddParticipant) waveletOp).getParticipantId()));

    } else if (waveletOp instanceof RemoveParticipant) {
      mongoOp.append(FIELD_TYPE, WAVELET_OP_REMOVE_PARTICIPANT);
      mongoOp.append(FIELD_PARTICIPANT,
          serialize(((RemoveParticipant) waveletOp).getParticipantId()));
    } else if (waveletOp instanceof WaveletBlipOperation) {
      final WaveletBlipOperation waveletBlipOp = (WaveletBlipOperation) waveletOp;

      mongoOp.append(FIELD_TYPE, WAVELET_OP_WAVELET_BLIP_OPERATION);
      mongoOp.append(FIELD_BLIPID, waveletBlipOp.getBlipId());

      if (waveletBlipOp.getBlipOp() instanceof BlipContentOperation) {
        mongoOp.append(FIELD_BLIPOP, serialize((BlipContentOperation) waveletBlipOp.getBlipOp()));
      } else {
        throw new IllegalArgumentException("Unsupported blip operation: "
            + waveletBlipOp.getBlipOp());
      }
    } else {
      throw new IllegalArgumentException("Unsupported wavelet operation: " + waveletOp);
    }
    return mongoOp;
  }

  public static DBObject serialize(BlipContentOperation blipContentOp) {
    BasicDBObject mongoBlipContentOp = new BasicDBObject();
    mongoBlipContentOp.append(FIELD_CONTENTOP, serialize(blipContentOp.getContentOp()));
    return mongoBlipContentOp;
  }

  public static DBObject serialize(DocOp docOp) {
    BasicDBObject mongoDocOp = new BasicDBObject();
    mongoDocOp.append(FIELD_BYTES, CoreWaveletOperationSerializer.serialize(docOp).toByteArray());
    return mongoDocOp;
  }

  public static WaveletDeltaRecord deserializeWaveletDeltaRecord(DBObject dbObject)
      throws PersistenceException {
    try {
      return new WaveletDeltaRecord(
          deserializeHashedVersion((DBObject) dbObject.get(FIELD_APPLIEDATVERSION)),
          ByteStringMessage.parseProtocolAppliedWaveletDelta(ByteString.copyFrom((byte[]) dbObject
              .get(FIELD_APPLIED))),
          deserializeTransformedWaveletDelta((DBObject) dbObject.get(FIELD_TRANSFORMED)));

    } catch (InvalidProtocolBufferException e) {
      throw new PersistenceException(e);
    }
  }

  public static HashedVersion deserializeHashedVersion(DBObject dbObject) {
    return HashedVersion.of((Long) dbObject.get(FIELD_VERSION),
        (byte[]) dbObject.get(FIELD_HISTORYHASH));
  }

  public static ParticipantId deserializeParicipantId(DBObject dbObject) {
    return ParticipantId.ofUnsafe((String) dbObject.get(FIELD_ADDRESS));
  }

  public static TransformedWaveletDelta deserializeTransformedWaveletDelta(DBObject dbObject)
      throws PersistenceException {

    ParticipantId author = deserializeParicipantId((DBObject) dbObject.get(FIELD_AUTHOR));
    HashedVersion resultingVersion =
        deserializeHashedVersion((DBObject) dbObject.get(FIELD_RESULTINGVERSION));
    long applicationTimestamp = (Long) dbObject.get(FIELD_APPLICATIONTIMESTAMP);

    BasicDBList dbOps = (BasicDBList) dbObject.get(FIELD_OPS);
    ImmutableList.Builder<WaveletOperation> operations = ImmutableList.builder();

    int numOperations = dbOps.size();

    // Code analog to ProtoDeltaStoreDataSerializer.deserialize
    for (int i = 0; i < numOperations; i++) {

      WaveletOperationContext context;
      if (i == numOperations - 1) {
        context = new WaveletOperationContext(author, applicationTimestamp, 1, resultingVersion);
      } else {
        context = new WaveletOperationContext(author, applicationTimestamp, 1);
      }
      operations.add(deserializeWaveletOperation((DBObject) dbOps.get(i), context));
    }

    return new TransformedWaveletDelta(author, resultingVersion, applicationTimestamp,
        operations.build());
  }

  public static WaveletOperation deserializeWaveletOperation(DBObject dbObject,
      WaveletOperationContext context) throws PersistenceException {
    String type = (String) dbObject.get(FIELD_TYPE);
    if (type.equals(WAVELET_OP_NOOP)) {
      return new NoOp(context);
    } else if (type.equals(WAVELET_OP_ADD_PARTICIPANT)) {
      return new AddParticipant(context,
          deserializeParicipantId((DBObject) dbObject.get(FIELD_PARTICIPANT)));
    } else if (type.equals(WAVELET_OP_REMOVE_PARTICIPANT)) {
      return new RemoveParticipant(context,
          deserializeParicipantId((DBObject) dbObject.get(FIELD_PARTICIPANT)));
    } else if (type.equals(WAVELET_OP_WAVELET_BLIP_OPERATION)) {
      return new WaveletBlipOperation((String) dbObject.get(FIELD_BLIPID),
          deserializeBlipContentOperation((DBObject) dbObject.get(FIELD_BLIPOP), context));
    } else {
      throw new IllegalArgumentException("Unsupported operation: " + type);
    }
  }

  public static BlipOperation deserializeBlipContentOperation(DBObject dbObject,
      WaveletOperationContext context) throws PersistenceException {
    return new BlipContentOperation(context,
        deserializeDocOp((DBObject) dbObject.get(FIELD_CONTENTOP)));
  }

  private static DocOp deserializeDocOp(DBObject dbObject) throws PersistenceException {
    try {
      return CoreWaveletOperationSerializer.deserialize(ProtocolDocumentOperation
          .parseFrom(((byte[]) dbObject.get(FIELD_BYTES))));
    } catch (InvalidProtocolBufferException e) {
      throw new PersistenceException(e);
    }
  }
}
TOP

Related Classes of org.waveprotocol.box.server.persistence.mongodb.MongoDbDeltaStoreUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.