com.madrobot.di.Converter.java Source code

Java tutorial

Introduction

Here is the source code for com.madrobot.di.Converter.java

Source

/*******************************************************************************
 * Copyright (c) 2012 MadRobot.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the GNU Lesser Public License v2.1
 *  which accompanies this distribution, and is available at
 *  http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 *  
 *  Contributors:
 *  Elton Kent - initial API and implementation
 ******************************************************************************/
package com.madrobot.di;

import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import com.madrobot.di.wizard.json.JSONDeserializer;
import com.madrobot.di.wizard.json.annotations.BooleanFormat;

import android.util.Log;

/**
 * Primitive mapper for XML and JSON serialization classes
 * 
 * @author elton.stephen.kent
 * 
 */
public final class Converter {

    private static Map<Class<?>, Integer> clzTypeKeyMap = new HashMap<Class<?>, Integer>();

    private static final int TYPE_BOOLEAN = 8;
    private static final int TYPE_CHAR = 5;
    private static final int TYPE_DATE = 9;
    private static final int TYPE_DOUBLE = 7;
    private static final int TYPE_FLOAT = 6;
    private static final int TYPE_INT = 3;
    private static final int TYPE_LONG = 4;
    private static final int TYPE_SHORT = 2;
    private static final int TYPE_STRING = 1;

    static {
        clzTypeKeyMap.put(String.class, TYPE_STRING);
        clzTypeKeyMap.put(short.class, TYPE_SHORT);
        clzTypeKeyMap.put(int.class, TYPE_INT);
        clzTypeKeyMap.put(long.class, TYPE_LONG);
        clzTypeKeyMap.put(char.class, TYPE_CHAR);
        clzTypeKeyMap.put(float.class, TYPE_FLOAT);
        clzTypeKeyMap.put(double.class, TYPE_DOUBLE);
        clzTypeKeyMap.put(boolean.class, TYPE_BOOLEAN);
        clzTypeKeyMap.put(Date.class, TYPE_DATE);
    }

    public static Object convertTo(final JSONObject jsonObject, final String fieldName, final Class<?> clz,
            final Field field) {

        Object value = null;

        if (clzTypeKeyMap.containsKey(clz)) {
            try {
                final int code = clzTypeKeyMap.get(clz);
                switch (code) {
                case TYPE_STRING:
                    value = jsonObject.optString(fieldName);
                    break;
                case TYPE_SHORT:
                    value = Short.parseShort(jsonObject.optString(fieldName, "0"));
                    break;
                case TYPE_INT:
                    value = jsonObject.optInt(fieldName);
                    break;
                case TYPE_LONG:
                    value = jsonObject.optLong(fieldName);
                    break;
                case TYPE_CHAR:
                    String chatValue = jsonObject.optString(fieldName);
                    if (chatValue.length() > 0) {
                        value = chatValue.charAt(0);
                    } else {
                        value = '\0';
                    }
                    break;
                case TYPE_FLOAT:
                    value = Float.parseFloat(jsonObject.optString(fieldName, "0.0f"));
                    break;
                case TYPE_DOUBLE:
                    value = jsonObject.optDouble(fieldName);
                    break;
                case TYPE_BOOLEAN:
                    value = jsonObject.optString(fieldName);
                    if (field.isAnnotationPresent(BooleanFormat.class)) {
                        BooleanFormat formatAnnotation = field.getAnnotation(BooleanFormat.class);
                        String trueFormat = formatAnnotation.trueFormat();
                        String falseFormat = formatAnnotation.falseFormat();
                        if (trueFormat.equals(value)) {
                            value = true;
                        } else if (falseFormat.equals(value)) {
                            value = false;
                        } else {
                            Log.e(JSONDeserializer.TAG,
                                    "Expecting " + trueFormat + " / " + falseFormat + " but its " + value);
                        }
                    } else {
                        value = Boolean.parseBoolean((String) value);
                    }
                    break;
                case TYPE_DATE:
                    value = DateFormat.getDateInstance().parse(jsonObject.optString(fieldName));
                    break;
                }
            } catch (NumberFormatException e) {
                Log.e(JSONDeserializer.TAG, e.getMessage());
            } catch (ParseException e) {
                Log.e(JSONDeserializer.TAG, e.getMessage());
            }
        }
        return value;
    }

    /**
     * Converts a {@link String} value to specified type, if possible.
     * 
     * @param raw
     *            Raw, string value, to be converted
     * @param clz
     *            Target type to be converted to
     * @return Converted value, if converstion was possible, null otherwise
     * @throws NumberFormatException
     *             If the value was not in correct format, while converting to numeric type
     * @throws RuntimeException
     *             If the value was not in correct format, while converting to Date or Boolean type
     */
    public static Object convertTo(final String raw, final Class<?> clz) {
        Object value = null;
        if (clzTypeKeyMap.containsKey(clz)) {
            final int code = clzTypeKeyMap.get(clz);
            switch (code) {
            case TYPE_STRING:
                value = raw;
                break;
            case TYPE_SHORT:
                value = Short.parseShort(raw);
                break;
            case TYPE_INT:
                value = Integer.parseInt(raw);
                break;
            case TYPE_LONG:
                value = Long.parseLong(raw);
                break;
            case TYPE_CHAR:
                if ((raw != null) && (raw.length() > 0)) {
                    value = raw.charAt(0);
                } else {
                    value = '\0';
                }
                break;
            case TYPE_FLOAT:
                value = Float.parseFloat(raw);
                break;
            case TYPE_DOUBLE:
                value = Double.parseDouble(raw);
                break;
            case TYPE_BOOLEAN:
                value = Boolean.parseBoolean(raw);
                break;
            case TYPE_DATE:
                value = Date.parse(raw);
                break;
            default:
                break;
            }
        }
        return value;
    }

    public static boolean isBoolean(final Class<?> clz) {
        Integer type = clzTypeKeyMap.get(clz);
        if (type != null && type == TYPE_BOOLEAN)
            return true;
        else
            return false;
    }

    public static boolean isCollectionType(Class<?> type) {
        return Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type);
    }

    public static boolean isPseudoPrimitive(final Class<?> clz) {
        return clzTypeKeyMap.containsKey(clz);
    }

    public static void storeValue(final JSONObject jsonObject, final String key, Object value, final Field field)
            throws JSONException {

        Class<?> classType = field.getType();

        if (clzTypeKeyMap.containsKey(classType)) {
            final int code = clzTypeKeyMap.get(classType);
            switch (code) {
            case TYPE_STRING:
            case TYPE_SHORT:
            case TYPE_INT:
            case TYPE_LONG:
            case TYPE_CHAR:
            case TYPE_FLOAT:
            case TYPE_DOUBLE:
                break;
            case TYPE_BOOLEAN:
                Boolean userValue = (Boolean) value;
                if (field.isAnnotationPresent(BooleanFormat.class)) {
                    BooleanFormat formatAnnotation = field.getAnnotation(BooleanFormat.class);
                    String trueFormat = formatAnnotation.trueFormat();
                    String falseFormat = formatAnnotation.falseFormat();
                    if (userValue) {
                        value = trueFormat;
                    } else {
                        value = falseFormat;
                    }
                } else {
                    value = userValue;
                }
                break;
            case TYPE_DATE:
                Date date = (Date) value;
                SimpleDateFormat simpleDateFormat = null;
                if (field.isAnnotationPresent(com.madrobot.di.wizard.json.annotations.DateFormat.class)) {
                    com.madrobot.di.wizard.json.annotations.DateFormat formatAnnotation = field
                            .getAnnotation(com.madrobot.di.wizard.json.annotations.DateFormat.class);
                    String dateFormat = formatAnnotation.format();
                    simpleDateFormat = new SimpleDateFormat(dateFormat);
                } else {
                    simpleDateFormat = new SimpleDateFormat();
                }
                value = simpleDateFormat.format(date);
                break;
            }
            jsonObject.put(key, value);
        }
    }

    private Converter() {
    }
}