v7db.files.mongodb.MongoReferenceTracking.java Source code

Java tutorial

Introduction

Here is the source code for v7db.files.mongodb.MongoReferenceTracking.java

Source

/**
 * Copyright (c) 2012, Thilo Planz. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package v7db.files.mongodb;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import v7db.files.spi.ContentPointer;
import v7db.files.spi.ContentSHA;
import v7db.files.spi.InlineContent;
import v7db.files.spi.ReferenceTracking;
import v7db.files.spi.StoredContent;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;

/**
 * References are stored in a collection, with a document for each owner.
 * 
 * <ul>
 * <li> <code>_id</code>: The ownerId as given by the application.
 * <li> <code>refs</code>: The sha hashes used by the ContentPointers from the
 * last updates in an array.
 * <li> <code>refHistory</code>: The sum of all previous and current entries in
 * <code>ref</code>.
 * <li><code>purge</code>: This field is added when the object is to be purged.
 * It contains the timestamp of that event.
 * </ul>
 * 
 * 
 */

public class MongoReferenceTracking implements ReferenceTracking {

    private final DBCollection refCollection;

    public final static String DEFAULT_REFERENCE_COLLECTION_NAME = "v7files.refs";

    public MongoReferenceTracking(DB db) {
        this(db.getCollection(DEFAULT_REFERENCE_COLLECTION_NAME));
    }

    public MongoReferenceTracking(DBCollection refCollection) {
        this.refCollection = refCollection;
    }

    public void purge(Object ownerId) throws IOException {
        refCollection.update(new BasicDBObject("_id", ownerId),
                new BasicDBObject("$set", new BasicDBObject("purge", new Date())));
    }

    public void updateReferences(Object ownerId, ContentPointer... contents) throws IOException {
        List<byte[]> content = new ArrayList<byte[]>();
        for (ContentPointer cp : contents) {
            if (cp instanceof InlineContent)
                continue;
            if (cp instanceof StoredContent)
                content.add(((StoredContent) cp).getBaseSHA());
            else if (cp instanceof ContentSHA)
                content.add(((ContentSHA) cp).getSHA());
            else
                throw new IllegalArgumentException(cp.getClass().getName());
        }

        WriteResult r = refCollection.update(new BasicDBObject("_id", ownerId),
                new BasicDBObject("$set", new BasicDBObject("refs", content)).append("$addToSet",
                        new BasicDBObject("refHistory", new BasicDBObject("$each", content))),
                false, false, WriteConcern.SAFE);
        if (r.getN() == 1)
            return;
        if (r.getN() != 0)
            throw new IllegalStateException();
        refCollection.insert(WriteConcern.SAFE,
                new BasicDBObject("_id", ownerId).append("refs", content).append("refHistory", content));

    }

}