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

com.vladmihalcea.hibernate.type.array.internal.ArrayUtil Maven / Gradle / Ivy

There is a newer version: 2.21.1
Show newest version
package com.vladmihalcea.hibernate.type.array.internal;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * ArrayUtil - Array utilities holder.
 *
 * @author Vlad Mihalcea
 */
public class ArrayUtil {

    /**
     * Clone an array.
     *
     * @param originalArray original array
     * @param  array element type
     * @return cloned array
     */
    public static  T deepCopy(Object originalArray) {
        Class arrayClass = originalArray.getClass();

        if (boolean[].class.equals(arrayClass)) {
            boolean[] array = (boolean[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (byte[].class.equals(arrayClass)) {
            byte[] array = (byte[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (short[].class.equals(arrayClass)) {
            short[] array = (short[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (int[].class.equals(arrayClass)) {
            int[] array = (int[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (long[].class.equals(arrayClass)) {
            long[] array = (long[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (float[].class.equals(arrayClass)) {
            float[] array = (float[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (double[].class.equals(arrayClass)) {
            double[] array = (double[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else if (char[].class.equals(arrayClass)) {
            char[] array = (char[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        } else {
            Object[] array = (Object[]) originalArray;
            return (T) Arrays.copyOf(array, array.length);
        }
    }

    /**
     * Wrap a given array so that primitives become wrapper objects.
     *
     * @param originalArray original array
     * @return wrapped array
     */
    public static Object[] wrapArray(Object originalArray) {
        Class arrayClass = originalArray.getClass();

        if (boolean[].class.equals(arrayClass)) {
            boolean[] fromArray = (boolean[]) originalArray;
            Boolean[] array = new Boolean[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (byte[].class.equals(arrayClass)) {
            byte[] fromArray = (byte[]) originalArray;
            Byte[] array = new Byte[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (short[].class.equals(arrayClass)) {
            short[] fromArray = (short[]) originalArray;
            Short[] array = new Short[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (int[].class.equals(arrayClass)) {
            int[] fromArray = (int[]) originalArray;
            Integer[] array = new Integer[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (long[].class.equals(arrayClass)) {
            long[] fromArray = (long[]) originalArray;
            Long[] array = new Long[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (float[].class.equals(arrayClass)) {
            float[] fromArray = (float[]) originalArray;
            Float[] array = new Float[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (double[].class.equals(arrayClass)) {
            double[] fromArray = (double[]) originalArray;
            Double[] array = new Double[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (char[].class.equals(arrayClass)) {
            char[] fromArray = (char[]) originalArray;
            Character[] array = new Character[fromArray.length];
            for (int i = 0; i < fromArray.length; i++) {
                array[i] = fromArray[i];
            }
            return array;
        } else if (originalArray instanceof List) {
            return ((List) originalArray).toArray();
        } else {
            return (Object[]) originalArray;
        }
    }

    /**
     * Unwrap {@link Object[]} array to an array of the provided type
     *
     * @param originalArray original array
     * @param arrayClass array class
     * @param  array element type
     * @return unwrapped array
     */
    public static  T unwrapArray(Object[] originalArray, Class arrayClass) {

        if (boolean[].class.equals(arrayClass)) {
            boolean[] array = new boolean[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Boolean) originalArray[i] : Boolean.FALSE;
            }
            return (T) array;
        } else if (byte[].class.equals(arrayClass)) {
            byte[] array = new byte[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Byte) originalArray[i] : 0;
            }
            return (T) array;
        } else if (short[].class.equals(arrayClass)) {
            short[] array = new short[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Short) originalArray[i] : 0;
            }
            return (T) array;
        } else if (int[].class.equals(arrayClass)) {
            int[] array = new int[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Integer) originalArray[i] : 0;
            }
            return (T) array;
        } else if (long[].class.equals(arrayClass)) {
            long[] array = new long[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Long) originalArray[i] : 0L;
            }
            return (T) array;
        } else if (float[].class.equals(arrayClass)) {
            float[] array = new float[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Float) originalArray[i] : 0f;
            }
            return (T) array;
        } else if (double[].class.equals(arrayClass)) {
            double[] array = new double[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Double) originalArray[i] : 0d;
            }
            return (T) array;
        } else if (char[].class.equals(arrayClass)) {
            char[] array = new char[originalArray.length];
            for (int i = 0; i < originalArray.length; i++) {
                array[i] = originalArray[i] != null ? (Character) originalArray[i] : 0;
            }
            return (T) array;
        } else if (Enum[].class.isAssignableFrom(arrayClass)) {
            T array = arrayClass.cast(Array.newInstance(arrayClass.getComponentType(), originalArray.length));
            for (int i = 0; i < originalArray.length; i++) {
                Object objectValue = originalArray[i];
                if (objectValue != null) {
                    String stringValue = (objectValue instanceof String) ? (String) objectValue : String.valueOf(objectValue);
                    objectValue = Enum.valueOf((Class) arrayClass.getComponentType(), stringValue);
                }
                Array.set(array, i, objectValue);
            }
            return array;
        } else if (java.time.LocalDate[].class.equals(arrayClass) && java.sql.Date[].class.equals(originalArray.getClass())) {
            // special case because conversion is neither with ctor nor valueOf
            Object[] array = (Object[]) Array.newInstance(java.time.LocalDate.class, originalArray.length);
            for (int i = 0; i < array.length; ++i) {
                array[i] = originalArray[i] != null ? ((java.sql.Date) originalArray[i]).toLocalDate() : null;
            }
            return (T) array;
        } else if (java.time.LocalDateTime[].class.equals(arrayClass) && java.sql.Timestamp[].class.equals(originalArray.getClass())) {
            // special case because conversion is neither with ctor nor valueOf
            Object[] array = (Object[]) Array.newInstance(java.time.LocalDateTime.class, originalArray.length);
            for (int i = 0; i < array.length; ++i) {
                array[i] = originalArray[i] != null ? ((java.sql.Timestamp) originalArray[i]).toLocalDateTime() : null;
            }
            return (T) array;
        } else if(arrayClass.getComponentType() != null && arrayClass.getComponentType().isArray()) {
            int arrayLength = originalArray.length;
            Object[] array = (Object[]) Array.newInstance(arrayClass.getComponentType(), arrayLength);
            if (arrayLength > 0) {
                for (int i = 0; i < originalArray.length; i++) {
                    array[i] = unwrapArray((Object[]) originalArray[i], arrayClass.getComponentType());
                }
            }
            return (T) array;
        } else {
            if (arrayClass.isInstance(originalArray)) {
                return (T) originalArray;
            } else {
                return (T) Arrays.copyOf(originalArray, originalArray.length, (Class) arrayClass);
            }
        }
    }

    /**
     * Create array from its {@link String} representation.
     *
     * @param string     string representation
     * @param arrayClass array class
     * @param         array element type
     * @return array
     */
    public static  T fromString(String string, Class arrayClass) {
        String stringArray = string.replaceAll("[\\[\\]]", "");
        String[] tokens = stringArray.split(",");

        int length = tokens.length;

        if (boolean[].class.equals(arrayClass)) {
            boolean[] array = new boolean[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Boolean.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (byte[].class.equals(arrayClass)) {
            byte[] array = new byte[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Byte.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (short[].class.equals(arrayClass)) {
            short[] array = new short[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Short.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (int[].class.equals(arrayClass)) {
            int[] array = new int[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Integer.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (long[].class.equals(arrayClass)) {
            long[] array = new long[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Long.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (float[].class.equals(arrayClass)) {
            float[] array = new float[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Float.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (double[].class.equals(arrayClass)) {
            double[] array = new double[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = Double.valueOf(tokens[i]);
            }
            return (T) array;
        } else if (char[].class.equals(arrayClass)) {
            char[] array = new char[length];
            for (int i = 0; i < tokens.length; i++) {
                array[i] = tokens[i].length() > 0 ? tokens[i].charAt(0) : Character.MIN_VALUE;
            }
            return (T) array;
        } else {
            return (T) tokens;
        }
    }

    /**
     * Check if two arrays are equal.
     *
     * @param firstArray first array
     * @param secondArray second array
     * @return arrays are equal
     */
    public static boolean isEquals(Object firstArray, Object secondArray) {
        if (firstArray.getClass() != secondArray.getClass()) {
            return false;
        }
        Class arrayClass = firstArray.getClass();

        if (boolean[].class.equals(arrayClass)) {
            return Arrays.equals((boolean[]) firstArray, (boolean[]) secondArray);
        } else if (byte[].class.equals(arrayClass)) {
            return Arrays.equals((byte[]) firstArray, (byte[]) secondArray);
        } else if (short[].class.equals(arrayClass)) {
            return Arrays.equals((short[]) firstArray, (short[]) secondArray);
        } else if (int[].class.equals(arrayClass)) {
            return Arrays.equals((int[]) firstArray, (int[]) secondArray);
        } else if (long[].class.equals(arrayClass)) {
            return Arrays.equals((long[]) firstArray, (long[]) secondArray);
        } else if (float[].class.equals(arrayClass)) {
            return Arrays.equals((float[]) firstArray, (float[]) secondArray);
        } else if (double[].class.equals(arrayClass)) {
            return Arrays.equals((double[]) firstArray, (double[]) secondArray);
        } else if (char[].class.equals(arrayClass)) {
            return Arrays.equals((char[]) firstArray, (char[]) secondArray);
        } else {
            return Arrays.equals((Object[]) firstArray, (Object[]) secondArray);
        }
    }

    /**
     * Get the array class for the provided array element class.
     *
     * @param arrayElementClass array element class
     * @param  array element type
     * @return array class
     */
    public static  Class toArrayClass(Class arrayElementClass) {

        if (boolean.class.equals(arrayElementClass)) {
            return (Class) boolean[].class;
        } else if (byte.class.equals(arrayElementClass)) {
            return (Class) byte[].class;
        } else if (short.class.equals(arrayElementClass)) {
            return (Class) short[].class;
        } else if (int.class.equals(arrayElementClass)) {
            return (Class) int[].class;
        } else if (long.class.equals(arrayElementClass)) {
            return (Class) long[].class;
        } else if (float.class.equals(arrayElementClass)) {
            return (Class) float[].class;
        } else if (double[].class.equals(arrayElementClass)) {
            return (Class) double[].class;
        } else if (char[].class.equals(arrayElementClass)) {
            return (Class) char[].class;
        } else {
            Object array = Array.newInstance(arrayElementClass, 0);
            return (Class) array.getClass();
        }
    }

    /**
     * Transforms an array to a {@link List}. The reason why {@link Arrays#asList(Object[])}
     * is not used is because on Java 6 it wraps the {@link List} so we end up
     * with two nested {@link List} objects.
     *
     * @param array array to transform
     * @param    array element type
     * @return the {@link List} representation of the array
     */
    public static  List asList(T[] array) {
        List list = new ArrayList(array.length);
        for (int i = 0; i < array.length; i++) {
            list.add(i, array[i]);
        }
        return list;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy