org.beangle.model.entity.populator.ConvertPopulatorBean.java Source code

Java tutorial

Introduction

Here is the source code for org.beangle.model.entity.populator.ConvertPopulatorBean.java

Source

/* Copyright c 2005-2012.
 * Licensed under GNU  LESSER General Public License, Version 3.
 * http://www.gnu.org/licenses
 */
package org.beangle.model.entity.populator;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.beangle.commons.converters.Converter;
import org.beangle.model.entity.Model;
import org.beangle.model.entity.ObjectAndType;
import org.beangle.model.entity.Populator;
import org.beangle.model.entity.Type;
import org.beangle.model.entity.types.EntityType;
import org.beangle.model.predicates.ValidEntityKeyPredicate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConvertPopulatorBean implements Populator {

    protected static final Logger logger = LoggerFactory.getLogger(ConvertPopulatorBean.class);

    public static final boolean TRIM_STR = true;

    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private BeanUtilsBean beanUtils;

    public ConvertPopulatorBean() {
        beanUtils = new BeanUtilsBean(Converter.getDefault());
    }

    public ConvertPopulatorBean(ConvertUtilsBean convertUtils) {
        beanUtils = new BeanUtilsBean(convertUtils);
    }

    /**
     * ?<br>
     * a.b.c,?a a.b a.b.c???
     * 
     * @param attr
     * @param target
     * @return ???
     */
    public ObjectAndType initProperty(final Object target, String entityName, final String attr) {
        Object propObj = target;
        Object property = null;

        int index = 0;
        String[] attrs = StringUtils.split(attr, ".");
        Type type = Model.getType(entityName);
        while (index < attrs.length) {
            try {
                property = PropertyUtils.getProperty(propObj, attrs[index]);
                Type propertyType = type.getPropertyType(attrs[index]);
                // ?
                if (null == propertyType) {
                    logger.error("Cannot find property type [{}] of {}", attrs[index], propObj.getClass());
                    throw new RuntimeException(
                            "Cannot find property type " + attrs[index] + " of " + propObj.getClass().getName());
                }
                if (null == property) {
                    property = propertyType.newInstance();
                    PropertyUtils.setProperty(propObj, attrs[index], property);
                }
                index++;
                propObj = property;
                type = propertyType;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return new ObjectAndType(property, type);
    }

    /**
     * ???
     * 
     * @param target
     * @param attr
     * @param value
     */
    public void populateValue(final Object target, String entityName, final String attr, Object value) {
        try {
            if (attr.indexOf('.') > -1) {
                initProperty(target, entityName, StringUtils.substringBeforeLast(attr, "."));
            }
            // BugDate??
            if (value instanceof Date) {
                Date date = (Date) value;
                value = sdf.format(date);
            }
            // ???
            if ("".equals(value) || "?".equals(value)) {
                Class type = beanUtils.getPropertyUtils().getPropertyDescriptor(target, attr).getPropertyType();
                if (Boolean.class.equals(type) || "boolean".equals(type.getName())) {
                    if ("".equals(value)) {
                        value = "1";
                    } else {
                        value = "0";
                    }
                }
            }
            beanUtils.copyProperty(target, attr, value);
        } catch (Exception e) {
            logger.error("copy property failure:[class:" + entityName + " attr:" + attr + " value:" + value + "]:",
                    e);
        }
    }

    public void populateValue(Object target, String attr, Object value) {
        populateValue(target, Model.getEntityType(target.getClass()).getEntityName(), attr, value);
    }

    public Object populate(Object target, Map<String, Object> params) {
        return populate(target, Model.getEntityName(target), params);
    }

    public Object populate(String entityName, Map<String, Object> params) {
        Type type = Model.getType(entityName);
        if (null == type) {
            throw new RuntimeException(entityName + " was not configured!");
        } else {
            return populate(type.newInstance(), type.getName(), params);
        }
    }

    public Object populate(Class<?> entityClass, Map<String, Object> params) {
        EntityType entityType = Model.getEntityType(entityClass);
        return populate(entityType.newInstance(), entityType.getEntityName(), params);
    }

    /**
     * params([attr(string)->value(object)]<br>
     * <br>
     * paramsidnullnull.<br>
     * ??idparams null?
     * 
     * @param params
     * @param entity
     */
    public Object populate(Object entity, String entityName, Map<String, Object> params) {
        Type type = Model.getType(entityName);
        for (final Map.Entry<String, Object> paramEntry : params.entrySet()) {
            String attr = paramEntry.getKey();
            Object value = paramEntry.getValue();
            if (value instanceof String) {
                if (StringUtils.isEmpty((String) value)) {
                    value = null;
                } else if (TRIM_STR) {
                    value = ((String) value).trim();
                }
            }
            // 
            if (null != type && type.isEntityType() && attr.equals(((EntityType) type).getIdPropertyName())) {
                if (ValidEntityKeyPredicate.INSTANCE.evaluate(value)) {
                    setValue(attr, value, entity);
                } else {
                    try {
                        PropertyUtils.setProperty(entity, attr, null);
                    } catch (Exception e) {
                        throw new RuntimeException(e.getMessage());
                    }
                }
                continue;
            }
            // 
            if (-1 == attr.indexOf('.')) {
                setValue(attr, value, entity);
            } else {
                String parentAttr = StringUtils.substring(attr, 0, attr.lastIndexOf('.'));
                try {
                    ObjectAndType ot = initProperty(entity, entityName, parentAttr);
                    if (null == ot) {
                        logger.error("error attr:[" + attr + "] value:[" + value + "]");
                        continue;
                    }
                    // 
                    if (ot.getType().isEntityType()) {
                        String foreignKey = ((EntityType) ot.getType()).getIdPropertyName();
                        if (attr.endsWith("." + foreignKey)) {
                            if (null == value) {
                                setValue(parentAttr, null, entity);
                            } else {
                                Object foreignValue = PropertyUtils.getProperty(entity, attr);
                                // ?
                                if (null != foreignValue) {
                                    if (!foreignValue.toString().equals(value.toString())) {
                                        setValue(parentAttr, null, entity);
                                        initProperty(entity, entityName, parentAttr);
                                        setValue(attr, value, entity);
                                    }
                                } else {
                                    setValue(attr, value, entity);
                                }
                            }
                        } else {
                            setValue(attr, value, entity);
                        }
                    } else {
                        setValue(attr, value, entity);
                    }
                } catch (Exception e) {
                    logger.error("error attr:[" + attr + "] value:[" + value + "]", e);
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug("populate attr:[" + attr + "] value:[" + value + "]");
            }
        }
        return entity;
    }

    private void setValue(final String attr, final Object value, final Object target) {
        try {
            beanUtils.copyProperty(target, attr, value);
        } catch (Exception e) {
            logger.error("copy property failure:[class:" + target.getClass().getName() + " attr:" + attr + " value:"
                    + value + "]:", e);
        }
    }
}