org.locationtech.geogig.plumbing.HashObject.java Source code

Java tutorial

Introduction

Here is the source code for org.locationtech.geogig.plumbing.HashObject.java

Source

/* Copyright (c) 2012-2016 Boundless and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/edl-v10.html
 *
 * Contributors:
 * Johnathan Garrett (LMN Solutions) - initial implementation
 */
package org.locationtech.geogig.plumbing;

import static org.locationtech.geogig.model.RevObject.TYPE.COMMIT;
import static org.locationtech.geogig.model.RevObject.TYPE.FEATURE;
import static org.locationtech.geogig.model.RevObject.TYPE.FEATURETYPE;
import static org.locationtech.geogig.model.RevObject.TYPE.TAG;
import static org.locationtech.geogig.model.RevObject.TYPE.TREE;

import java.util.List;
import java.util.SortedMap;

import org.eclipse.jdt.annotation.Nullable;
import org.locationtech.geogig.model.Bucket;
import org.locationtech.geogig.model.HashObjectFunnels;
import org.locationtech.geogig.model.Node;
import org.locationtech.geogig.model.ObjectId;
import org.locationtech.geogig.model.RevObject;
import org.locationtech.geogig.repository.AbstractGeoGigOp;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.hash.Funnel;
import com.google.common.hash.Hasher;

/**
 * Hashes a RevObject and returns the ObjectId.
 * 
 * @see RevObject
 * @see ObjectId#HASH_FUNCTION
 */
public class HashObject extends AbstractGeoGigOp<ObjectId> {

    @SuppressWarnings("unchecked")
    private static final Funnel<? extends RevObject>[] FUNNELS = new Funnel[RevObject.TYPE.values().length];
    static {
        FUNNELS[COMMIT.value()] = HashObjectFunnels.commitFunnel();
        FUNNELS[TREE.value()] = HashObjectFunnels.treeFunnel();
        FUNNELS[FEATURE.value()] = HashObjectFunnels.featureFunnel();
        FUNNELS[TAG.value()] = HashObjectFunnels.tagFunnel();
        FUNNELS[FEATURETYPE.value()] = HashObjectFunnels.featureTypeFunnel();
    }

    private RevObject object;

    /**
     * @param object {@link RevObject} to hash.
     * @return {@code this}
     */
    public HashObject setObject(RevObject object) {
        this.object = object;
        return this;
    }

    /**
     * Hashes a RevObject using a SHA1 hasher.
     * 
     * @return a new ObjectId created from the hash of the RevObject.
     */
    @Override
    protected ObjectId _call() {
        Preconditions.checkState(object != null, "Object has not been set.");

        final Hasher hasher = ObjectId.HASH_FUNCTION.newHasher();
        @SuppressWarnings("unchecked")
        final Funnel<RevObject> funnel = (Funnel<RevObject>) FUNNELS[object.getType().value()];
        funnel.funnel(object, hasher);
        final byte[] rawKey = hasher.hash().asBytes();
        final ObjectId id = ObjectId.createNoClone(rawKey);

        return id;
    }

    public static ObjectId hashFeature(List<Object> values) {
        final Hasher hasher = ObjectId.HASH_FUNCTION.newHasher();

        HashObjectFunnels.feature(hasher, values);

        final byte[] rawKey = hasher.hash().asBytes();
        final ObjectId id = ObjectId.createNoClone(rawKey);

        return id;
    }

    public static ObjectId hashTree(@Nullable List<Node> trees, @Nullable List<Node> features,
            @Nullable SortedMap<Integer, Bucket> buckets) {

        final Hasher hasher = ObjectId.HASH_FUNCTION.newHasher();
        trees = trees == null ? ImmutableList.of() : trees;
        features = features == null ? ImmutableList.of() : features;
        buckets = buckets == null ? ImmutableSortedMap.of() : buckets;
        HashObjectFunnels.tree(hasher, trees, features, buckets);

        final byte[] rawKey = hasher.hash().asBytes();
        final ObjectId id = ObjectId.createNoClone(rawKey);

        return id;
    }

    public static ObjectId hashTree(Optional<ImmutableList<Node>> trees, Optional<ImmutableList<Node>> features,
            Optional<ImmutableSortedMap<Integer, Bucket>> buckets) {

        return hashTree(trees.or(ImmutableList.of()), features.or(ImmutableList.of()),
                buckets.or(ImmutableSortedMap.of()));
    }
}