com.cinchapi.concourse.Link.java Source code

Java tutorial

Introduction

Here is the source code for com.cinchapi.concourse.Link.java

Source

/*
 * Copyright (c) 2013-2016 Cinchapi 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.cinchapi.concourse;

import javax.annotation.concurrent.Immutable;

import com.cinchapi.concourse.lang.BuildableState;
import com.cinchapi.concourse.lang.Criteria;
import com.cinchapi.concourse.util.Convert;
import com.cinchapi.concourse.util.Strings;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Longs;
import com.google.common.primitives.UnsignedLongs;

/**
 * A {@link Link} is a pointer to a record.
 * <p>
 * Links should never be written directly. They can be created using the
 * {@link Concourse#link(String, long, long) link()} methods in the
 * {@link Concourse} API.
 * </p>
 * <p>
 * Links may be returned when reading data using the
 * {@link Concourse#select(long)
 * select()}, {@link Concourse#get(Object) get()} and
 * {@link Concourse#browse(String) browse()} methods. When handling Link
 * objects, you can retrieve the underlying record id by calling
 * {@link Link#longValue()}.
 * </p>
 * <p>
 * When performing a
 * {@link Concourse#insert(com.google.common.collect.Multimap) bulk insert}, you
 * can use this class to create Link objects that are added to the data/json
 * blob. Links inserted in this manner will be written in the same way they
 * would have been if they were written using the
 * {@link Concourse#link(String, long, java.util.Collection) link()} API
 * methods.
 * </p>
 * <p>
 * To create a static link to a single record, use {@link Link#to(long)}.
 * </p>
 * <p>
 * To create static links to each of the records that match a criteria, use one
 * of the {@link Link#toWhere(Criteria) Link.toWhere()} methods (see the
 * documentation for {@link com.cinchapi.concourse.util.Convert.ResolvableLink
 * resolvable links} for more information).
 * </p>
 * 
 * @author Jeff Nelson
 */
// NOTE: This class extends Number so that it can be treated like other
// numerical Values during comparisons when the data is stored and sorted in a
// SecondaryIndex for efficient range queries.
@Immutable
public final class Link extends Number implements Comparable<Link> {

    /**
     * Return a Link that points to {@code record}.
     * 
     * @param record the record id
     * @return a {@link Link} that points to {@code record}
     */
    public static Link to(long record) {
        return new Link(record);
    }

    /**
     * Return a string that instructs Concourse to create links that point to
     * each of the records that match the {@code ccl} string.
     * 
     * <p>
     * <strong>NOTE:</strong> This method DOES NOT return a {@link Link} object,
     * so it should only be used when adding a
     * {@link com.cinchapi.concourse.util.Convert.ResolvableLink resolvable
     * link} value to a data/json blob that will be passed to the
     * {@link Concourse#insert(com.google.common.collect.Multimap)
     * insert()} methods.
     * </p>
     * 
     * @param ccl a CCL string that describes the records to which a Link should
     *            point
     * @return a {@link com.cinchapi.concourse.util.Convert.ResolvableLink
     *         resolvable link instruction}
     */
    public static String toWhere(String ccl) {
        return Convert.stringToResolvableLinkInstruction(ccl);
    }

    /**
     * Return a string that instructs Concourse to create links that point to
     * each of the records that match the {@code ccl} string.
     * 
     * <p>
     * <strong>NOTE:</strong> This method DOES NOT return a {@link Link} object,
     * so it should only be used when adding a
     * {@link com.cinchapi.concourse.util.Convert.ResolvableLink resolvable
     * link} value to a data/json blob that will be passed to the
     * {@link Concourse#insert(com.google.common.collect.Multimap)
     * insert()} methods.
     * </p>
     * 
     * @param criteria a {@link Criteria} that describes the records to which a
     *            Link should point
     * @return a {@link com.cinchapi.concourse.util.Convert.ResolvableLink
     *         resolvable link instruction}
     */
    public static String toWhere(Criteria criteria) {
        return toWhere(criteria.getCclString());
    }

    /**
     * Return a string that instructs Concourse to create links that point to
     * each of the records that match the {@code ccl} string.
     * 
     * <p>
     * <strong>NOTE:</strong> This method DOES NOT return a {@link Link} object,
     * so it should only be used when adding a
     * {@link com.cinchapi.concourse.util.Convert.ResolvableLink resolvable
     * link} value to a data/json blob that will be passed to the
     * {@link Concourse#insert(com.google.common.collect.Multimap)
     * insert()} methods.
     * </p>
     * 
     * @param criteria a criteria builder in a {@link BuildableState} that
     *            describes the records to which a Link should point
     * @return a {@link com.cinchapi.concourse.util.Convert.ResolvableLink
     *         resolvable link instruction}
     */
    public static String toWhere(Object criteria) {
        Preconditions.checkArgument(criteria instanceof BuildableState,
                Strings.format("{} is not a valid criteria", criteria));
        return toWhere(((BuildableState) criteria).build());
    }

    private static final long serialVersionUID = 1L; // Serializability is
                                                     // inherited from {@link
                                                     // Number}.
    /**
     * The signed representation for the primary key of the record to which this
     * Link points.
     */
    private final long record;

    /**
     * Construct a new instance.
     * 
     * @param record
     */
    private Link(long record) {
        this.record = record;
    }

    @Override
    public int compareTo(Link other) {
        return UnsignedLongs.compare(longValue(), other.longValue());
    }

    @Override
    public double doubleValue() {
        return (double) record;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Link) {
            Link other = (Link) obj;
            return UnsignedLongs.compare(record, other.record) == 0;
        }
        return false;
    }

    @Override
    public float floatValue() {
        return (float) record;
    }

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

    @Override
    public int intValue() {
        return (int) record;
    }

    @Override
    public long longValue() {
        return record;
    }

    @Override
    public String toString() {
        return "@" + UnsignedLongs.toString(longValue());
    }
}