org.apache.ignite.cache.store.cassandra.common.PropertyMappingHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.ignite.cache.store.cassandra.common.PropertyMappingHelper.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.ignite.cache.store.cassandra.common;

import com.datastax.driver.core.DataType;
import com.datastax.driver.core.Row;
import java.beans.PropertyDescriptor;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.ignite.cache.store.cassandra.serializer.Serializer;

/**
 * Helper class providing bunch of methods to discover fields of POJO objects and
 * map builtin Java types to appropriate Cassandra types.
 */
public class PropertyMappingHelper {
    /** Bytes array Class type. */
    private static final Class BYTES_ARRAY_CLASS = (new byte[] {}).getClass();

    /** Mapping from Java to Cassandra types. */
    private static final Map<Class, DataType.Name> JAVA_TO_CASSANDRA_MAPPING = new HashMap<Class, DataType.Name>() {
        {
            put(String.class, DataType.Name.TEXT);
            put(Integer.class, DataType.Name.INT);
            put(int.class, DataType.Name.INT);
            put(Short.class, DataType.Name.INT);
            put(short.class, DataType.Name.INT);
            put(Long.class, DataType.Name.BIGINT);
            put(long.class, DataType.Name.BIGINT);
            put(Double.class, DataType.Name.DOUBLE);
            put(double.class, DataType.Name.DOUBLE);
            put(Boolean.class, DataType.Name.BOOLEAN);
            put(boolean.class, DataType.Name.BOOLEAN);
            put(Float.class, DataType.Name.FLOAT);
            put(float.class, DataType.Name.FLOAT);
            put(ByteBuffer.class, DataType.Name.BLOB);
            put(BYTES_ARRAY_CLASS, DataType.Name.BLOB);
            put(BigDecimal.class, DataType.Name.DECIMAL);
            put(InetAddress.class, DataType.Name.INET);
            put(Date.class, DataType.Name.TIMESTAMP);
            put(UUID.class, DataType.Name.UUID);
            put(BigInteger.class, DataType.Name.VARINT);
        }
    };

    /**
     * Maps Cassandra type to specified Java type.
     *
     * @param clazz java class.
     *
     * @return Cassandra type.
     */
    public static DataType.Name getCassandraType(Class clazz) {
        return JAVA_TO_CASSANDRA_MAPPING.get(clazz);
    }

    /**
     * Returns property descriptor by class property name.
     *
     * @param clazz class from which to get property descriptor.
     * @param prop name of the property.
     *
     * @return property descriptor.
     */
    public static PropertyDescriptor getPojoPropertyDescriptor(Class clazz, String prop) {
        List<PropertyDescriptor> descriptors = getPojoPropertyDescriptors(clazz, false);

        if (descriptors == null || descriptors.isEmpty())
            throw new IllegalArgumentException(
                    "POJO class " + clazz.getName() + " doesn't have '" + prop + "' property");

        for (PropertyDescriptor descriptor : descriptors) {
            if (descriptor.getName().equals(prop))
                return descriptor;
        }

        throw new IllegalArgumentException(
                "POJO class " + clazz.getName() + " doesn't have '" + prop + "' property");
    }

    /**
     * Extracts all property descriptors from a class.
     *
     * @param clazz class which property descriptors should be extracted.
     * @param primitive boolean flag indicating that only property descriptors for primitive properties
     *      should be extracted.
     *
     * @return list of class property descriptors
     */
    public static List<PropertyDescriptor> getPojoPropertyDescriptors(Class clazz, boolean primitive) {
        PropertyDescriptor[] descriptors = PropertyUtils.getPropertyDescriptors(clazz);

        List<PropertyDescriptor> list = new ArrayList<>(descriptors == null ? 1 : descriptors.length);

        if (descriptors == null || descriptors.length == 0)
            return list;

        for (PropertyDescriptor descriptor : descriptors) {
            if (descriptor.getReadMethod() == null || (primitive && !isPrimitivePropertyDescriptor(descriptor)))
                continue;

            list.add(descriptor);
        }

        return list;
    }

    /**
     * Checks if property descriptor describes primitive property (int, boolean, long and etc.)
     *
     * @param desc property descriptor.
     *
     * @return {@code true} property is primitive
     */
    public static boolean isPrimitivePropertyDescriptor(PropertyDescriptor desc) {
        return PropertyMappingHelper.JAVA_TO_CASSANDRA_MAPPING.containsKey(desc.getPropertyType());
    }

    /**
     * Returns value of specific column in the row returned by CQL statement.
     *
     * @param row row returned by CQL statement.
     * @param col column name.
     * @param clazz java class to which column value should be casted.
     * @param serializer serializer to use if column stores BLOB otherwise could be null.
     *
     * @return row column value.
     */
    public static Object getCassandraColumnValue(Row row, String col, Class clazz, Serializer serializer) {
        if (String.class.equals(clazz))
            return row.getString(col);

        if (Integer.class.equals(clazz) || int.class.equals(clazz))
            return row.getInt(col);

        if (Short.class.equals(clazz) || short.class.equals(clazz))
            return (short) row.getInt(col);

        if (Long.class.equals(clazz) || long.class.equals(clazz))
            return row.getLong(col);

        if (Double.class.equals(clazz) || double.class.equals(clazz))
            return row.getDouble(col);

        if (Boolean.class.equals(clazz) || boolean.class.equals(clazz))
            return row.getBool(col);

        if (Float.class.equals(clazz) || float.class.equals(clazz))
            return row.getFloat(col);

        if (ByteBuffer.class.equals(clazz))
            return row.getBytes(col);

        if (PropertyMappingHelper.BYTES_ARRAY_CLASS.equals(clazz)) {
            ByteBuffer buf = row.getBytes(col);

            return buf == null ? null : buf.array();
        }

        if (BigDecimal.class.equals(clazz))
            return row.getDecimal(col);

        if (InetAddress.class.equals(clazz))
            return row.getInet(col);

        if (Date.class.equals(clazz))
            return row.getTimestamp(col);

        if (UUID.class.equals(clazz))
            return row.getUUID(col);

        if (BigInteger.class.equals(clazz))
            return row.getVarint(col);

        if (serializer == null) {
            throw new IllegalStateException("Can't deserialize value from '" + col + "' Cassandra column, "
                    + "cause there is no BLOB serializer specified");
        }

        ByteBuffer buf = row.getBytes(col);

        return buf == null ? null : serializer.deserialize(buf);
    }
}