// Invalid input should result in am object with empty JSON body
 @Test(expected = IllegalArgumentException.class)
 public void constructor_invalidInput_objectWithEmptyJsonShouldBeCreated() {
   DocumentBody body = new BasicDocumentBody("[]".getBytes());
   Assert.assertTrue(Arrays.equals("{}".getBytes(), body.asBytes()));
   Assert.assertNotNull(body.asMap());
   Assert.assertTrue(body.asMap().size() == 0);
 }
 @Test
 public void constructor_emptyMap_objectWithEmptyJsonShouldBeCreated() {
   DocumentBody body = new BasicDocumentBody(new HashMap());
   Assert.assertTrue(Arrays.equals("{}".getBytes(), body.asBytes()));
   Assert.assertNotNull(body.asMap());
   Assert.assertTrue(body.asMap().size() == 0);
 }
  @Test
  public void constructor_byteArray_correctObjectShouldBeCreated() throws Exception {
    DocumentBody body = new BasicDocumentBody(jsonData);
    Assert.assertTrue(Arrays.equals(jsonData, body.asBytes()));
    Assert.assertNotNull(body.asMap());

    Map<String, Object> actualMap = body.asMap();
    assertMapIsCorrect(actualMap);
  }
  @Test
  public void asMap_differentNumberTypes_jacksonPicksNaturalMapping() throws IOException {
    byte[] d =
        FileUtils.readFileToByteArray(
            TestUtils.loadFixture("fixture/basic_bdbody_test_as_map.json"));
    DocumentBody body = new BasicDocumentBody(d);
    Assert.assertEquals("-101", body.asMap().get("StringValue"));

    Map<String, Object> m = body.asMap();

    Assert.assertTrue(m.get("LongValue") instanceof Long);
    Assert.assertTrue(m.get("LongValue").equals(2147483648l)); // Integer.MAX_VALUE + 1

    Assert.assertTrue(m.get("IntegerValue") instanceof Integer);
    Assert.assertTrue(m.get("IntegerValue").equals(2147483647)); // Integer.MAX_VALUE
  }
  @Override
  public BasicDocumentRevision updateLocalDocument(
      String docId, String prevRevId, final DocumentBody body) {
    Preconditions.checkState(this.isOpen(), "Database is closed");
    Preconditions.checkArgument(
        !Strings.isNullOrEmpty(docId), "Input document id can not be empty");
    Preconditions.checkArgument(
        !Strings.isNullOrEmpty(prevRevId), "Input previous revision id can not be empty");
    Preconditions.checkNotNull(body, "Input document body can not be null");

    CouchUtils.validateRevisionId(prevRevId);

    DocumentRevision preRevision = this.getLocalDocument(docId, prevRevId);
    this.sqlDb.beginTransaction();
    try {
      String newRevId = CouchUtils.generateNextLocalRevisionId(prevRevId);
      ContentValues values = new ContentValues();
      values.put("revid", newRevId);
      values.put("json", body.asBytes());
      String[] whereArgs = new String[] {docId, prevRevId};
      int rowsUpdated = this.sqlDb.update("localdocs", values, "docid=? AND revid=?", whereArgs);
      if (rowsUpdated == 1) {
        this.sqlDb.setTransactionSuccessful();
        return this.getLocalDocument(docId, newRevId);
      } else {
        throw new IllegalStateException("Error updating local docs: " + preRevision);
      }
    } finally {
      this.sqlDb.endTransaction();
    }
  }
  @Override
  public BasicDocumentRevision createLocalDocument(String docId, final DocumentBody body) {
    Preconditions.checkState(this.isOpen(), "Database is closed");
    CouchUtils.validateDocumentId(docId);
    Preconditions.checkNotNull(body, "Input document body can not be null");
    this.sqlDb.beginTransaction();
    try {
      String firstRevId = CouchUtils.getFirstLocalDocRevisionId();
      ContentValues values = new ContentValues();
      values.put("docid", docId);
      values.put("revid", firstRevId);
      values.put("json", body.asBytes());

      long lineId = this.sqlDb.insert("localdocs", values);
      if (lineId < 0) {
        throw new IllegalArgumentException(
            "Can not insert new local doc, likely the docId exists already: " + docId);
      } else {
        Log.d(LOG_TAG, "New local doc inserted: " + lineId + ", " + docId);
      }

      this.sqlDb.setTransactionSuccessful();
      return getLocalDocument(docId, firstRevId);
    } finally {
      this.sqlDb.endTransaction();
    }
  }
 private void validateDBBody(DocumentBody body) {
   for (String name : body.asMap().keySet()) {
     if (name.startsWith("_")) {
       throw new IllegalArgumentException("Field name start with '_' is not allowed. ");
     }
   }
 }
 private String insertNewWinnerRevision(DocumentBody newWinner, DocumentRevision oldWinner) {
   String newRevisionId = CouchUtils.generateNextRevisionId(oldWinner.getRevision());
   this.insertRevision(
       oldWinner.getInternalNumericId(),
       newRevisionId,
       oldWinner.getSequence(),
       false,
       true,
       newWinner.asBytes(),
       true);
   return newRevisionId;
 }
  @Override
  public BasicDocumentRevision createDocument(String docId, final DocumentBody body) {
    Preconditions.checkState(this.isOpen(), "Database is closed");
    CouchUtils.validateDocumentId(docId);
    Preconditions.checkNotNull(body, "Input document body can not be null");
    this.validateDBBody(body);

    DocumentCreated documentCreated = null;
    this.sqlDb.beginTransaction();
    try {
      long docNumericID = insertDocumentID(docId);
      if (docNumericID < 0) {
        throw new IllegalArgumentException(
            "Can not insert new doc, likely the docId exists already: " + docId);
      }

      String revisionId = CouchUtils.getFirstRevisionId();
      long newSequence =
          insertRevision(docNumericID, revisionId, -1l, false, true, body.asBytes(), true);
      if (newSequence < 0) {
        throw new IllegalStateException("Error inserting data, please checking data.");
      }

      BasicDocumentRevision doc = getDocument(docId, revisionId);
      documentCreated = new DocumentCreated(doc);

      Log.d(LOG_TAG, "New document created: " + doc.toString());

      this.sqlDb.setTransactionSuccessful();
      return doc;
    } finally {
      this.sqlDb.endTransaction();
      if (documentCreated != null) {
        eventBus.post(documentCreated);
      }
    }
  }
 @Test
 public void constructor_map_correctObjectShouldBeCreated() {
   DocumentBody body = new BasicDocumentBody(JSONUtils.deserialize(jsonData));
   Map<String, Object> map = JSONUtils.deserialize(body.asBytes());
   assertMapIsCorrect(map);
 }