com.google.devtools.moe.client.database.FileDb.java Source code

Java tutorial

Introduction

Here is the source code for com.google.devtools.moe.client.database.FileDb.java

Source

/*
 * Copyright (c) 2011 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 com.google.devtools.moe.client.database;

import com.google.common.collect.ImmutableSet;
import com.google.devtools.moe.client.FileSystem;
import com.google.devtools.moe.client.MoeProblem;
import com.google.devtools.moe.client.database.Db.HasDbStorage;
import com.google.devtools.moe.client.project.InvalidProject;
import com.google.devtools.moe.client.repositories.Revision;
import com.google.devtools.moe.client.testing.DummyDb;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;

import dagger.Provides;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * A file-backed implementation of MOE {@link Db}.
 */
public class FileDb implements Db, HasDbStorage {

    private final String location;
    private final DbStorage dbStorage;

    // TODO(cgruber): Rationalize DbStorage.
    public FileDb(String location, DbStorage dbStorage) {
        this.location = location;
        this.dbStorage = dbStorage;
    }

    @Override
    public String location() {
        return location;
    }

    /**
     * @return all Equivalences stored in the database
     */
    public Set<RepositoryEquivalence> getEquivalences() {
        return ImmutableSet.copyOf(dbStorage.equivalences());
    }

    @Override
    public void noteEquivalence(RepositoryEquivalence equivalence) {
        dbStorage.addEquivalence(equivalence);
    }

    @Override
    public Set<Revision> findEquivalences(Revision revision, String otherRepository) {
        ImmutableSet.Builder<Revision> equivalentToRevision = ImmutableSet.builder();
        for (RepositoryEquivalence e : dbStorage.equivalences()) {
            if (e.hasRevision(revision)) {
                Revision otherRevision = e.getOtherRevision(revision);
                if (otherRevision.repositoryName().equals(otherRepository)) {
                    equivalentToRevision.add(otherRevision);
                }
            }
        }
        return equivalentToRevision.build();
    }

    /**
     * @return all {@link SubmittedMigration} objects stored in the database
     */
    public Set<SubmittedMigration> getMigrations() {
        return ImmutableSet.copyOf(dbStorage.migrations());
    }

    @Override
    public boolean noteMigration(SubmittedMigration migration) {
        return dbStorage.addMigration(migration);
    }

    @Override
    public DbStorage getStorage() {
        return dbStorage;
    }

    /**
     * Writes a database implementing {@link HasDbStorage} to the supplied filesystem at a given
     * location, or at the location originally attached to the database.
     */
    public static class Writer implements Db.Writer {
        private final Gson gson;
        private final FileSystem filesystem;

        @Inject
        public Writer(Gson gson, FileSystem filesystem) {
            this.gson = gson;
            this.filesystem = filesystem;
        }

        @Override
        public void write(Db db) {
            writeToLocation(db.location(), db);
        }

        @Override
        public void writeToLocation(String dbLocation, Db db) {
            if (db instanceof HasDbStorage) {
                try {
                    DbStorage storage = ((HasDbStorage) db).getStorage();
                    filesystem.write(gson.toJson(storage), new File(dbLocation));
                } catch (IOException e) {
                    throw new MoeProblem("I/O Error writing database: " + e.getMessage());
                }
            } else {
                throw new MoeProblem("Database does not support exporting its internal storage.");
            }
        }
    }

    /** An injectable Factory to produce {@link FileDb} instances. */
    // TODO(cgruber) @AutoFactory?
    public static class Factory implements Db.Factory {
        private final Gson gson;
        private final FileSystem filesystem;

        @Inject
        public Factory(FileSystem filesystem, Gson gson) {
            this.filesystem = filesystem;
            this.gson = gson;
        }

        @Override
        public Db parseJson(String dbText) throws InvalidProject {
            return parseJson(null, dbText);
        }

        public Db parseJson(String location, String dbText) throws InvalidProject {
            try {
                DbStorage dbStorage = gson.fromJson(dbText, DbStorage.class);
                return new FileDb(location, dbStorage);
            } catch (JsonParseException e) {
                throw new InvalidProject("Could not parse MOE DB: " + e.getMessage());
            }
        }

        @Override
        public Db load(String location) throws MoeProblem {
            if (location.equals("dummy")) {
                return new DummyDb(true);
            } else {
                try {
                    if (filesystem.exists(new File(location))) {
                        String dbText = filesystem.fileToString(new File(location));
                        return parseJson(location, dbText);
                    } else {
                        return new FileDb(location, new DbStorage());
                    }
                } catch (IOException e) {
                    throw new MoeProblem(e.getMessage());
                }
            }
        }
    }

    /** Supplies the various bindings needed to use this database in a dagger graph. */
    @dagger.Module
    public static class Module {
        @Provides
        @Singleton
        Db.Factory dbFactory(FileDb.Factory impl) {
            return impl;
        }

        @Provides
        @Singleton
        Db.Writer dbWriter(FileDb.Writer impl) {
            return impl;
        }
    }
}