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

com.rethinkdb.response.DBResponseMapper Maven / Gradle / Ivy

The newest version!
package com.rethinkdb.response;

import com.rethinkdb.RethinkDBException;
import com.rethinkdb.ast.query.gen.Timezone;
import com.rethinkdb.proto.Q2L;

import java.lang.reflect.Field;
import java.util.*;

public class DBResponseMapper {

    /**
     * Maps a ProtoBuf Datum object to a java object
     *
     * @param datum datum
     * @return DBObject
     */
    public static  T fromDatumObject(Q2L.Datum datum) {
        // Null is Null
        if (datum.getType() == Q2L.Datum.DatumType.R_NULL) {
            return null;
        }

        // Number, Str, bool go to simple java datatypes
        if (datum.getType() == Q2L.Datum.DatumType.R_NUM ||
            datum.getType() == Q2L.Datum.DatumType.R_STR ||
            datum.getType() == Q2L.Datum.DatumType.R_BOOL) {
            return (T)handleType(datum);
        }

        // R_OBJECT is Map
        if (datum.getType() == Q2L.Datum.DatumType.R_OBJECT) {
            Map repr = new HashMap();
            for (Q2L.Datum.AssocPair assocPair : datum.getRObjectList()) {

                if (assocPair.getKey().equals("$reql_type$") && "TIME".equals(assocPair.getVal().getRStr())) {
                    return (T)asDate(datum);
                }

                repr.put(assocPair.getKey(), handleType(assocPair.getVal()));
            }
            return (T)repr;
        }

        // Array goes to List
        if (datum.getType() == Q2L.Datum.DatumType.R_ARRAY) {
            return (T)makeArray(datum.getRArrayList());
        }

        throw new RethinkDBException("Can't map datum to JavaObject for {}" + datum.getType());

    }

    private static Date asDate(Q2L.Datum datum) {
        String timezone = "";
        Double epoch_time = 0.0;

        for (Q2L.Datum.AssocPair assocPair : datum.getRObjectList()) {

            if (assocPair.getKey().equals("epoch_time")) {
                epoch_time = assocPair.getVal().getRNum();
            }
            if (assocPair.getKey().equals("timezone")) {
                timezone = assocPair.getVal().getRStr();
            }

        }

        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(epoch_time.longValue() * 1000);
            calendar.setTimeZone(TimeZone.getTimeZone(timezone));
            return calendar.getTime();
        }
        catch (Exception ex) {
            throw new RethinkDBException("Error handling date",ex);
        }
    }

    /**
     * Maps a list of Datum Objects to a list of java objects
     *
     * @param datums datum objects
     * @return DBObject
     */
    public static  List fromDatumObjectList(List datums) {
        List results = new ArrayList();
        for (Q2L.Datum datum : datums) {
            results.add((T)fromDatumObject(datum));
        }
        return results;
    }

    private static Object handleType(Q2L.Datum val) {
        switch (val.getType()) {
            case R_OBJECT:
                return fromDatumObject(val);
            case R_STR:
                return val.getRStr();
            case R_BOOL:
                return val.getRBool();
            case R_NULL:
                return null;
            case R_NUM:
                return val.getRNum();
            case R_ARRAY:
                return makeArray(val.getRArrayList());
            case R_JSON:
            default:
                throw new RuntimeException("Not implemented" + val.getType());
        }
    }

    private static List makeArray(List elements) {
        List objects = new ArrayList();
        for (Q2L.Datum element : elements) {
            objects.add(handleType(element));
        }
        return objects;
    }

    /**
     * Populates the fields in to based on values out of from
     *
     * @param to   the object to map into
     * @param from the object to map from
     * @param   the type of the into object
     * @return the into object
     */
    public static  T populateObject(T to, Map from) {
        for (Field field : to.getClass().getDeclaredFields()) {
            try {
                field.setAccessible(true);

                Object result = convertField(field, from);
                if (result != null || !field.getType().isPrimitive()) {
                    field.set(to, result);
                }

            } catch (IllegalAccessException e) {
                throw new RethinkDBException("Error populating from DBObject: " + field.getName(), e);
            }
        }
        return to;
    }

    public static  List populateList(Class clazz, List> from) {
        List results = new ArrayList();
        for (Map stringObjectMap : from) {
            try {
                results.add(populateObject(clazz.newInstance(),stringObjectMap));
            } catch (InstantiationException e) {
                throw new RethinkDBException("Error instantiating " + clazz, e);
            } catch (IllegalAccessException e) {
                throw new RethinkDBException("Illegal access on " + clazz, e);
            }
        }
        return results;
    }



    private static Object convertField(Field toField, Map from) {
        if (from.get(toField.getName()) == null) {
            return null;
        }
        if (toField.getType().equals(Integer.class) || toField.getType().equals(int.class)) {
            return ((Number) from.get(toField.getName())).intValue();
        }
        if (toField.getType().equals(Float.class) || toField.getType().equals(float.class)) {
            return ((Number) from.get(toField.getName())).floatValue();
        }
        return from.get(toField.getName());
    }


}