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

play.data.binding.Unbinder Maven / Gradle / Ivy

There is a newer version: 1.5.0
Show newest version
package play.data.binding;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import play.data.binding.types.DateBinder;

/**
 * Try to unbind an object to a Map
 */
public class Unbinder {

    public static void unBind(Map result, Object src, String name) {
        if (src == null) {
            return;
        }
        unBind(result, src, src.getClass(), name);
    }

    private static void unBind(Map result, Object src, Class srcClazz, String name) {
        if (isDirect(srcClazz) || src == null) {
            if (!result.containsKey(name)) {
                result.put(name, src != null ? src.toString() : null);
            } else {
                @SuppressWarnings("unchecked") List objects = (List) result.get(name);
                objects.add(src != null ? src.toString() : null);
            }
        } else if (src.getClass().isArray()) {
            List objects = new ArrayList();
            result.put(name, objects);
            Class clazz = src.getClass().getComponentType();
            int size = Array.getLength(src);
            for (int i = 0; i < size; i++) {
                unBind(result, Array.get(src, i), clazz, name);
            }
        } else if (Collection.class.isAssignableFrom(src.getClass())) {
            if (Map.class.isAssignableFrom(src.getClass())) {
                throw new UnsupportedOperationException("Unbind won't work with maps yet");
            } else {
                Collection c = (Collection) src;
                List objects = new ArrayList();
                result.put(name, objects);
                for (Object object : c) {
                    unBind(result, object, object.getClass(), name);
                }
            }
        } else if (Date.class.isAssignableFrom(src.getClass())) {
            result.put(name, new SimpleDateFormat(DateBinder.ISO8601).format((Date)src));
        } else {
            Field[] fields = src.getClass().getDeclaredFields();
            for (Field field : fields) {
                String newName = name + "." + field.getName();
                boolean oldAcc = field.isAccessible();
                field.setAccessible(true);
                try {
                    unBind(result, field.get(src), field.getType(), newName);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Object" + src.getClass() + " won't unbind field " + field.getName(), e);
                } catch (IllegalArgumentException e) {
                    throw new RuntimeException("Object" + src.getClass() + " won't unbind field " + field.getName(), e);
                }
                field.setAccessible(oldAcc);
            }
        }
    }

    public static boolean isDirect(Class clazz) {
        return clazz.equals(String.class) || clazz.equals(Integer.class) || Enum.class.isAssignableFrom(clazz) || clazz.equals(Boolean.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.isPrimitive();
    }
    
}