com.spotify.asyncdatastoreclient.Key.java Source code

Java tutorial

Introduction

Here is the source code for com.spotify.asyncdatastoreclient.Key.java

Source

/*
 * Copyright (c) 2011-2015 Spotify AB
 *
 * 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.spotify.asyncdatastoreclient;

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

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * Represents an entity key.
 *
 * A key is immutable; use {@code Key.builder()} to construct new
 * {@code Key} instances.
 */
public final class Key {

    /**
     * Represents an key path element.
     *
     * A key path element is immutable.
     */
    public static final class Element {

        private final DatastoreV1.Key.PathElement element;

        private Element(final DatastoreV1.Key.PathElement element) {
            this.element = element;
        }

        public String getKind() {
            return element.hasKind() ? element.getKind() : null;
        }

        public Long getId() {
            return element.hasId() ? element.getId() : null;
        }

        public String getName() {
            return element.hasName() ? element.getName() : null;
        }

        DatastoreV1.Key.PathElement getPb() {
            return element;
        }

        @Override
        public String toString() {
            final Long id = getId();
            return getKind() + ":" + (id == null ? getName() : id);
        }
    }

    private final DatastoreV1.Key key;

    private Key(final DatastoreV1.Key key) {
        this.key = key;
    }

    public static final class Builder {

        private final DatastoreV1.Key.Builder key;

        private Builder() {
            this.key = DatastoreV1.Key.newBuilder();
        }

        private Builder(final Key key) {
            this(key.getPb());
        }

        private Builder(final DatastoreV1.Key key) {
            this.key = DatastoreV1.Key.newBuilder(key);
        }

        /**
         * Creates a new {@code Key}.
         *
         * @return an immutable key.
         */
        public Key build() {
            return new Key(key.build());
        }

        /**
         * Set the namespace for this {@code Key}.
         *
         * @param namespace the namespace to set.
         * @return this key builder.
         */
        public Builder namespace(final String namespace) {
            key.setPartitionId(DatastoreV1.PartitionId.newBuilder().setNamespace(namespace));
            return this;
        }

        /**
         * Add a path element to this key.
         *
         * @param element the path element to add.
         * @return this key builder.
         */
        public Builder path(final Element element) {
            key.addPathElement(element.getPb());
            return this;
        }

        /**
         * Add a path element of a given kind to this key.
         *
         * @param kind the path element kind.
         * @return this key builder.
         */
        public Builder path(final String kind) {
            key.addPathElement(DatastoreV1.Key.PathElement.newBuilder().setKind(kind));
            return this;
        }

        /**
         * Add a path element of a given kind and id to this key.
         *
         * @param kind the path element kind.
         * @param id the path element id.
         * @return this key builder.
         */
        public Builder path(final String kind, final long id) {
            key.addPathElement(DatastoreV1.Key.PathElement.newBuilder().setKind(kind).setId(id));
            return this;
        }

        /**
         * Add a path element of a given kind and name to this key.
         *
         * @param kind the path element kind.
         * @param name the path element name.
         * @return this key builder.
         */
        public Builder path(final String kind, final String name) {
            key.addPathElement(DatastoreV1.Key.PathElement.newBuilder().setKind(kind).setName(name));
            return this;
        }

        /**
         * Add a given key as a parent of this key.
         *
         * @param parent the parent key to add.
         * @return this key builder.
         */
        public Builder parent(final Key parent) {
            for (final Element element : parent.getPath()) {
                final Long id = element.getId();
                final String name = element.getName();
                if (id != null) {
                    path(element.getKind(), id);
                } else if (name != null) {
                    path(element.getKind(), name);
                }
            }
            return this;
        }
    }

    /**
     * Creates a new empty {@code Key} builder.
     *
     * @return an key builder.
     */
    public static Key.Builder builder() {
        return new Key.Builder();
    }

    /**
     * Creates a new {@code Key} builder for a given kind.
     *
     * This is a shortcut for {@code Key.builder().path(kind).build()}
     *
     * @param kind the kind of entity key.
     * @return a key builder.
     */
    public static Key.Builder builder(final String kind) {
        return new Key.Builder().path(kind);
    }

    /**
     * Creates a new {@code Key} builder for a given kind with a parent.
     *
     * This is a shortcut for {@code Key.builder().parent(parent).path(kind).build()}
     *
     * @param kind the kind of entity key.
     * @param parent the parent key to add.
     * @return a key builder.
     */
    public static Key.Builder builder(final String kind, final Key parent) {
        return new Key.Builder().parent(parent).path(kind);
    }

    /**
     * Creates a new {@code Key} builder for a given kind and an id.
     *
     * This is a shortcut for {@code Key.builder().path(kind, id).build()}
     *
     * @param kind the kind of entity key.
     * @param id the id of entity key.
     * @return a key builder.
     */
    public static Key.Builder builder(final String kind, final long id) {
        return new Key.Builder().path(kind, id);
    }

    /**
     * Creates a new {@code Key} builder for a given kind and an id with a parent.
     *
     * This is a shortcut for {@code Key.builder().parent(parent).path(kind, id).build()}
     *
     * @param kind the kind of entity key.
     * @param id the id of entity key.
     * @param parent the parent key to add.
     * @return a key builder.
     */
    public static Key.Builder builder(final String kind, final long id, final Key parent) {
        return new Key.Builder().parent(parent).path(kind, id);
    }

    /**
     * Creates a new {@code Key} builder for a given kind and a name.
     *
     * This is a shortcut for {@code Key.builder().path(kind, name).build()}
     *
     * @param kind the kind of entity key.
     * @param name the name of entity key.
     * @return a key builder.
     */
    public static Key.Builder builder(final String kind, final String name) {
        return new Key.Builder().path(kind, name);
    }

    /**
     * Creates a new {@code Key} builder for a given kind and an name with a parent.
     *
     * This is a shortcut for {@code Key.builder().parent(parent).path(kind, name).build()}
     *
     * @param kind the kind of entity key.
     * @param name the name of entity key.
     * @param parent the parent key to add.
     * @return a key builder.
     */
    public static Key.Builder builder(final String kind, final String name, final Key parent) {
        return new Key.Builder().parent(parent).path(kind, name);
    }

    /**
     * Creates a new {@code Key} builder based on an existing key.
     *
     * @param key the key to base this builder.
     * @return a key builder.
     */
    public static Key.Builder builder(final Key key) {
        return new Key.Builder(key);
    }

    static Key.Builder builder(final DatastoreV1.Key key) {
        return new Key.Builder(key);
    }

    /**
     * Return the namespace for this key.
     *
     * @return the namespace.
     */
    public String getNamespace() {
        return key.hasPartitionId() && key.getPartitionId().hasNamespace() ? key.getPartitionId().getNamespace()
                : null;
    }

    /**
     * Return whether this key is complete or not.
     *
     * A complete key is a key that includes a "kind" and ("id" or "name").
     *
     * @return true if the key is complete.
     */
    public boolean isComplete() {
        if (key.getPathElementCount() == 0) {
            return false;
        }
        for (final DatastoreV1.Key.PathElement element : key.getPathElementList()) {
            if (!element.hasId() && !element.hasName()) {
                return false;
            }
        }
        return true;
    }

    /**
     * Return element kind of key, or null if not set.
     *
     * This is a shortcut for {@code Key.getPath().get(Key.getPath().size() - 1).getKind()}
     *
     * @return the element kind.
     */
    public String getKind() {
        final DatastoreV1.Key.PathElement element = Iterables.getLast(key.getPathElementList(), null);
        if (element == null) {
            return null;
        }
        return element.hasKind() ? element.getKind() : null;
    }

    /**
     * Return element key id, or null if not set.
     *
     * This is a shortcut for {@code Key.getPath().get(Key.getPath().size() - 1).getId()}
     *
     * @return the key id.
     */
    public Long getId() {
        final DatastoreV1.Key.PathElement element = Iterables.getLast(key.getPathElementList(), null);
        if (element == null) {
            return null;
        }
        return element.hasId() ? element.getId() : null;
    }

    /**
     * Return element key name, or null if not set.
     *
     * This is a shortcut for {@code Key.getPath().get(Key.getPath().size() - 1).getName()}
     *
     * @return the key name.
     */
    public String getName() {
        final DatastoreV1.Key.PathElement element = Iterables.getLast(key.getPathElementList(), null);
        if (element == null) {
            return null;
        }
        return element.hasName() ? element.getName() : null;
    }

    /**
     * Return element path that represents this key.
     *
     * @return a list of path elements that make up this key.
     */
    public List<Element> getPath() {
        return ImmutableList
                .copyOf(key.getPathElementList().stream().map(Element::new).collect(Collectors.toList()));
    }

    @Override
    public String toString() {
        return "{" + getPath().stream().map(Element::toString).collect(Collectors.joining(", ")) + "}";
    }

    @Override
    public int hashCode() {
        return key.hashCode();
    }

    @Override
    public boolean equals(final Object obj) {
        return obj == this || (obj instanceof Key && Objects.equals(key, ((Key) obj).key));
    }

    DatastoreV1.Key getPb() {
        return key;
    }

    DatastoreV1.Key getPb(final String namespace) {
        if (namespace == null) {
            return key;
        } else {
            return DatastoreV1.Key.newBuilder(key)
                    .setPartitionId(DatastoreV1.PartitionId.newBuilder().setNamespace(namespace)).build();
        }
    }
}