All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.permazen.tuple.Tuples Maven / Gradle / Ivy

The newest version!

/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package io.permazen.tuple;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import java.util.Arrays;

/**
 * Tuple utility methods.
 */
public final class Tuples {

    private Tuples() {
    }

    /**
     * Create a {@link Tuple} of the appropriate cardinality for the given number of objects.
     *
     * @param values tuple values
     * @return newly created tuple
     * @throws IllegalArgumentException if {@code values} is null or empty
     * @throws UnsupportedOperationException if {@code values} has more elements than exist concrete {@link Tuple} classes
     */
    public static Tuple createTuple(Iterable values) {
        Preconditions.checkArgument(values != null, "null values");
        return Tuples.createTuple(Lists.newArrayList(values).toArray());
    }

    /**
     * Create a {@link Tuple} of the appropriate cardinality for the given number of objects.
     *
     * @param values tuple values
     * @return newly created tuple
     * @throws IllegalArgumentException if {@code values} is null or empty
     * @throws UnsupportedOperationException if {@code values} has more elements than exist concrete {@link Tuple} classes
     */
    public static Tuple createTuple(Object... values) {
        Preconditions.checkArgument(values != null, "null values");
        final Class tupleClass = Tuples.tupleClassForSize(values.length);
        final Class[] parameterTypes = new Class[values.length];
        Arrays.fill(parameterTypes, Object.class);
        try {
            return tupleClass.getConstructor(parameterTypes).newInstance(values);
        } catch (Exception e) {
            throw new UnsupportedOperationException(String.format("can't instantiate %s", tupleClass), e);
        }
    }

    /**
     * Get the {@link Tuple} subinterface having the specified cardinality.
     *
     * @param size number of objects in the tuple
     * @return {@link Tuple} subinterface with cardinality {@code size}
     * @throws IllegalArgumentException if {@code size} is less than one
     * @throws UnsupportedOperationException if {@code size} is more than exist concrete {@link Tuple} classes
     */
    public static Class tupleClassForSize(int size) {
        Preconditions.checkArgument(size >= 1, "invalid non-positive size");
        final String name = Tuple.class.getName() + size;
        try {
            return Class.forName(name, false, Tuple.class.getClassLoader()).asSubclass(Tuple.class);
        } catch (Exception e) {
            throw new UnsupportedOperationException(String.format("can't find class \"%s\" for size %d", name, size), e);
        }
    }

    /**
     * Get the cardinality of the given {@link Tuple} subtype.
     *
     * @param tupleClass tuple class
     * @return cardinality of {@code tupleClass}
     * @throws IllegalArgumentException if {@code tupleClass} is not a recognized tuple class
     */
    public static int tupleSizeOf(Class tupleClass) {
        for (int size = 1; true; size++) {
            try {
                if (Tuples.tupleClassForSize(size).isAssignableFrom(tupleClass))
                    return size;
            } catch (UnsupportedOperationException e) {
                throw new IllegalArgumentException(String.format("not a tuple (sub)class: %s", tupleClass));
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy