com.google.gcloud.datastore.BaseKey.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gcloud.datastore.BaseKey.java

Source

/*
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.gcloud.datastore;

import static com.google.gcloud.datastore.Validator.validateDatabase;
import static com.google.gcloud.datastore.Validator.validateKind;
import static com.google.gcloud.datastore.Validator.validateNamespace;

import com.google.api.services.datastore.DatastoreV1;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

/**
 * Base class for keys.
 */
public abstract class BaseKey extends Serializable<DatastoreV1.Key> {

    private static final long serialVersionUID = -4671243265877410635L;

    private final transient String projectId;
    private final transient String namespace;
    private final transient ImmutableList<PathElement> path;

    /**
     * Base class for key builders.
     *
     * @param <B> the key builder.
     */
    protected abstract static class Builder<B extends Builder<B>> {

        String projectId;
        String namespace;
        String kind;
        final List<PathElement> ancestors;

        private static final int MAX_PATH = 100;

        Builder(String projectId) {
            this.projectId = validateDatabase(projectId);
            ancestors = new LinkedList<>();
        }

        Builder(String projectId, String kind) {
            this(projectId);
            this.kind = validateKind(kind);
        }

        Builder(BaseKey copyFrom) {
            projectId = copyFrom.projectId();
            namespace = copyFrom.namespace();
            ancestors = new LinkedList<>(copyFrom.ancestors());
            kind = copyFrom.kind();
        }

        @SuppressWarnings("unchecked")
        B self() {
            return (B) this;
        }

        public B ancestors(PathElement ancestor) {
            Preconditions.checkState(ancestors.size() < MAX_PATH, "path can have at most 100 elements");
            ancestors.add(ancestor);
            return self();
        }

        public B ancestors(PathElement ancestor, PathElement... other) {
            return ancestors(ImmutableList.<PathElement>builder().add(ancestor).add(other).build());
        }

        public B ancestors(Iterable<PathElement> ancestors) {
            ImmutableList<PathElement> list = ImmutableList.copyOf(ancestors);
            Preconditions.checkState(this.ancestors.size() + list.size() < MAX_PATH,
                    "path can have at most 100 elements");
            this.ancestors.addAll(list);
            return self();
        }

        public B kind(String kind) {
            this.kind = validateKind(kind);
            return self();
        }

        public B projectId(String projectId) {
            this.projectId = validateDatabase(projectId);
            return self();
        }

        public B namespace(String namespace) {
            this.namespace = validateNamespace(namespace);
            return self();
        }

        protected abstract BaseKey build();
    }

    BaseKey(String projectId, String namespace, ImmutableList<PathElement> path) {
        Preconditions.checkArgument(!path.isEmpty(), "Path must not be empty");
        this.projectId = projectId;
        this.namespace = namespace;
        this.path = path;
    }

    /**
     * Returns the key's projectId.
     */
    public String projectId() {
        return projectId;
    }

    /**
     * Returns the key's namespace or {@code null} if not provided.
     */
    public String namespace() {
        return namespace;
    }

    /**
     * Returns an immutable list with the key's ancestors.
     */
    public List<PathElement> ancestors() {
        return path().subList(0, path().size() - 1);
    }

    /**
     * Returns an immutable list of the key's path (ancestors + self).
     */
    List<PathElement> path() {
        return path;
    }

    PathElement leaf() {
        return path().get(path().size() - 1);
    }

    /**
     * Returns the key's kind.
     */
    public String kind() {
        return leaf().kind();
    }

    abstract BaseKey parent();

    @Override
    public int hashCode() {
        return Objects.hash(projectId(), namespace(), path());
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (!(obj instanceof BaseKey)) {
            return false;
        }
        BaseKey other = (BaseKey) obj;
        return Objects.equals(projectId(), other.projectId()) && Objects.equals(namespace(), other.namespace())
                && Objects.equals(path(), other.path());
    }

    @Override
    DatastoreV1.Key toPb() {
        DatastoreV1.Key.Builder keyPb = DatastoreV1.Key.newBuilder();
        DatastoreV1.PartitionId.Builder partitionIdPb = DatastoreV1.PartitionId.newBuilder();
        if (projectId != null) {
            partitionIdPb.setDatasetId(projectId);
        }
        if (namespace != null) {
            partitionIdPb.setNamespace(namespace);
        }
        if (partitionIdPb.hasDatasetId() || partitionIdPb.hasNamespace()) {
            keyPb.setPartitionId(partitionIdPb.build());
        }
        for (PathElement pathEntry : path) {
            keyPb.addPathElement(pathEntry.toPb());
        }
        return keyPb.build();
    }
}