org.tinygroup.context2object.impl.ClassNameObjectGenerator.java Source code

Java tutorial

Introduction

Here is the source code for org.tinygroup.context2object.impl.ClassNameObjectGenerator.java

Source

/**
 *  Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com).
 *
 *  Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html
 *
 *  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.tinygroup.context2object.impl;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.tinygroup.beancontainer.BeanContainerFactory;
import org.tinygroup.commons.tools.StringUtil;
import org.tinygroup.context.Context;
import org.tinygroup.context2object.ObjectAssembly;
import org.tinygroup.context2object.ObjectGenerator;
import org.tinygroup.context2object.TypeConverter;
import org.tinygroup.context2object.config.BasicTypeConverter;
import org.tinygroup.logger.LogLevel;
import org.tinygroup.logger.Logger;
import org.tinygroup.logger.LoggerFactory;

import com.google.common.collect.ObjectArrays;

public class ClassNameObjectGenerator extends BaseClassNameObjectGenerator
        implements ObjectGenerator<Object, String> {
    private static final Logger LOGGER = LoggerFactory.getLogger(ClassNameObjectGenerator.class);
    private List<TypeConverter<?, ?>> typeConverterList = new ArrayList<TypeConverter<?, ?>>();

    public Object getObject(String varName, String bean, String className, ClassLoader loader, Context context) {
        if (className == null || "".equals(className)) {
            return getObject(varName, bean, null, context, null);
        }
        // 20130808LoaderManagerFactory
        // return getObject(varName, bean, LoaderManagerFactory.getManager()
        // .getClass(className), context, null);
        return getObject(varName, bean, getClazz(className, loader), context, null);
    }

    public Object getObjectArray(String varName, String className, ClassLoader loader, Context context) {
        // 20130808LoaderManagerFactory
        // return buildArrayObjectWithObject(varName, LoaderManagerFactory
        // .getManager().getClass(className), context, null);
        return buildArrayObjectWithObject(varName, getClazz(className, loader), context, null);
    }

    public Collection<Object> getObjectCollection(String collectionClassName, ClassLoader loader) {
        Class<?> collectionClass = getClazz(collectionClassName, loader);
        return (Collection<Object>) getObjectInstance(collectionClass);
    }

    public Collection<Object> getObjectCollection(String varName, String collectionName, String className,
            ClassLoader loader, Context context) {
        // 20130808LoaderManagerFactory
        // Class<?> collectionClass =
        // LoaderManagerFactory.getManager().getClass(
        // collectionName);
        // Class<?> clazz =
        // LoaderManagerFactory.getManager().getClass(className);
        Class<?> collectionClass = getClazz(collectionName, loader);
        Class<?> clazz = getClazz(className, loader);
        Collection<Object> collection = (Collection<Object>) getObjectInstance(collectionClass);
        buildCollection(varName, collection, clazz, context, null);
        if (collection.isEmpty()) {
            return null;
        }
        return collection;
    }

    private Object getObject(String varName, String bean, Class<?> clazz, Context context, String preName) {
        if (bean != null) {
            Object o = getInstanceBySpringBean(bean);
            if (o != null) { // ?
                Object result = buildObject(varName, o, context, preName);
                if (result == null) {// ?null(cotext?bean)
                    return o;
                } else {
                    return result; // ??
                }
            }
        }
        // beanid?bean
        if (clazz == null || isSimpleType(clazz)) {
            return null;
        } else if (clazz.isArray()) {
            return buildArrayObjectWithArray(varName, clazz, context, preName);
        } else {
            Object o = getObjectInstance(clazz);
            return buildObject(varName, o, context, preName);
        }
    }

    private Object buildObject(String varName, Object object, Context context, String preName) {
        if (object == null) {
            return null;
        }
        Class<?> clazz = object.getClass();

        String objName = varName;
        ObjectAssembly assembly = getObjectAssembly(object.getClass());
        if (assembly != null) {
            assembly.assemble(varName, object, context);
            return object;
        }
        // 20130424
        // ?
        boolean allPropertyNull = true;
        if (isNull(objName)) {
            objName = getObjName(object);
        }
        for (PropertyDescriptor descriptor : PropertyUtils.getPropertyDescriptors(object.getClass())) {
            if (descriptor.getPropertyType().equals(Class.class)) {
                continue;
            }

            // 201402025?propertyName?
            // String propertyName = getPropertyName(clazz,
            // descriptor.getName());
            String propertyName = descriptor.getName();
            Object propertyValue = getPerpertyValue(preName, objName, propertyName, context);// user.name,user_name,name
            if (propertyValue != null) { // ????
                try {
                    if (descriptor.getPropertyType().equals( // ?()
                            propertyValue.getClass())
                            || implmentInterface(propertyValue.getClass(), descriptor.getPropertyType())) {
                        BeanUtils.setProperty(object, descriptor.getName(), propertyValue);
                        allPropertyNull = false;
                        continue;
                    } else if (isSimpleType(descriptor.getPropertyType())) {// ?
                        if (String.class == propertyValue.getClass()) { // String
                            BeanUtils.setProperty(object, descriptor.getName(), BasicTypeConverter
                                    .getValue(propertyValue.toString(), descriptor.getPropertyType().getName()));
                            allPropertyNull = false;
                        } else if (isSimpleType(propertyValue.getClass())) { // ?????
                            BeanUtils.setProperty(object, descriptor.getName(), propertyValue.toString());
                            allPropertyNull = false;
                        } else {
                            LOGGER.logMessage(LogLevel.WARN,
                                    "?{0}.{1},{3},{4}", objName,
                                    propertyName, descriptor.getPropertyType(), propertyValue.getClass());
                        }
                        continue;
                    }
                    // else {
                    // }
                    // ???
                } catch (Exception e) {
                    LOGGER.errorMessage("{0}", e, descriptor.getName());
                }
            }

            // ????
            // ???
            TypeConverter typeConverter = getTypeConverter(descriptor.getPropertyType());
            if (typeConverter != null) {
                if (propertyValue != null) {
                    try {
                        BeanUtils.setProperty(object, descriptor.getName(), typeConverter.getObject(propertyValue));
                        allPropertyNull = false;
                    } catch (Exception e) {
                        LOGGER.errorMessage("{0}", e, descriptor.getName());
                    }
                }
                continue;
            }
            // ??
            if (!isSimpleType(descriptor.getPropertyType())) {
                // 
                try {
                    String newPreName = getReallyPropertyName(preName, objName, propertyName);
                    // ===============begin======================
                    // 20151208getDeclaredFieldWithParent?type???
                    // Class<?> type = null;
                    // try{
                    Field field = getDeclaredFieldWithParent(clazz, propertyName);
                    // type =
                    // clazz.getDeclaredField(descriptor.getName()).getType();
                    // type = descriptor.getPropertyType();
                    // }catch (NoSuchFieldException e)

                    if (field == null) {
                        LOGGER.logMessage(LogLevel.WARN, "{}?{}", clazz.getName(), propertyName);
                        continue;
                    }
                    Class<?> type = field.getType();
                    // ===============end======================
                    if (type.isArray()) {// 
                        Object value = getObject(newPreName, null, descriptor.getPropertyType(), context, null);
                        if (value != null) {
                            BeanUtils.setProperty(object, descriptor.getName(), value);
                            allPropertyNull = false;
                        }
                    } else if (implmentInterface(descriptor.getPropertyType(), Collection.class)) {// ?
                        // ===============begin======================
                        // 20151208getDeclaredFieldWithParent?type???
                        Field propertyType = getDeclaredFieldWithParent(clazz, propertyName);
                        if (propertyType == null) {
                            LOGGER.logMessage(LogLevel.WARN, "{}?{}", clazz.getName(), propertyName);
                            continue;
                        }
                        // ParameterizedType pt = (ParameterizedType) clazz
                        // .getDeclaredField(descriptor.getName())
                        // .getGenericType();
                        ParameterizedType pt = (ParameterizedType) propertyType.getGenericType();
                        // ===============end======================
                        Type[] actualTypeArguments = pt.getActualTypeArguments();
                        Collection<Object> collection = (Collection<Object>) getObjectInstance(type);
                        buildCollection(newPreName, collection, (Class) actualTypeArguments[0], context, null);
                        if (!collection.isEmpty()) {
                            BeanUtils.setProperty(object, descriptor.getName(), collection);
                            allPropertyNull = false;
                        }
                    } else {// 
                        Object value = getObject(newPreName, null, descriptor.getPropertyType(), context, null);
                        if (value != null) {
                            BeanUtils.setProperty(object, descriptor.getName(), value);
                            allPropertyNull = false;
                        }
                    }
                } catch (Exception e) {
                    LOGGER.errorMessage("{0}", e, descriptor.getName());
                }
            }
        }
        if (allPropertyNull) {
            return null;
        }
        return object;
    }

    private void buildCollection(String varName, Collection<Object> collection, Class<?> clazz, Context context,
            String preName) {
        if (clazz == null) {
            return;
        } else if (isSimpleType(clazz)) {
            buildCollectionSimple(varName, collection, clazz, context, preName);
            // } else if (clazz.isEnum()) {
            // buildCollectionEnum(varName, collection, clazz, context,
            // preName);
        } else {
            buildCollectionObject(varName, collection, clazz, context, preName);
        }
    }

    private void buildCollectionSimple(String varName, Collection<Object> collection, Class<?> clazz,
            Context context, String preName) {
        if (clazz == null) {
            return;
        }
        String reallyVarName = varName;
        if (isNull(reallyVarName)) {
            reallyVarName = preName;
        }
        if (isNull(reallyVarName)) {
            throw new RuntimeException("??,??????");
        }

        Object propertyValue = getPerpertyValue(reallyVarName, context);
        if (propertyValue != null) {
            if (propertyValue.getClass().isArray()) {
                // 
                Object[] objArray = (Object[]) propertyValue;
                if (objArray.getClass().getComponentType() == String.class) {
                    for (Object o : objArray) {
                        collection.add(BasicTypeConverter.getValue((String) o, clazz.getName()));
                    }
                } else {
                    for (Object o : objArray) {
                        collection.add(o);
                    }
                }
            } else {
                if (propertyValue.getClass() == String.class) {
                    collection.add(BasicTypeConverter.getValue((String) propertyValue, clazz.getName()));
                } else {
                    collection.add(propertyValue);
                }

            }
        }
        // return collection;
    }

    // ????enmu
    // ????preName.varName
    // ???preName.varNamepreName.varName.propertyName
    private boolean checkIfNotComplexObjectCollection(String varName, Collection<Object> collection, Class<?> clazz,
            Context context, String preName) {
        String reallyName = preName;
        if (StringUtil.isBlank(varName) && StringUtil.isBlank(preName)) {
            return false;
        } else if (StringUtil.isBlank(preName)) {
            reallyName = varName;
        } else if (StringUtil.isBlank(varName)) {
            reallyName = preName;
        } else {
            reallyName = getReallyPropertyName(null, preName, varName);
        }

        Object value = getPerpertyValue(reallyName, context);
        if (value == null) {
            return false;
        }
        if (!value.getClass().isArray()) {
            return false;
        }
        Object[] arrays = (Object[]) value;

        for (int i = 0; i < arrays.length; i++) {
            Object propertyValue = arrays[i];
            if (clazz.equals( // ?()
                    propertyValue.getClass()) || implmentInterface(propertyValue.getClass(), clazz)) {
                collection.add(propertyValue);
                continue;
            }
            TypeConverter typeConverter = getTypeConverter(clazz);
            if (typeConverter != null) {
                if (propertyValue != null) {
                    collection.add(typeConverter.getObject(propertyValue));
                }
            } else {
                throw new RuntimeException(
                        "" + clazz + "?,??:" + propertyValue.getClass());
                // throw new
                // RuntimeException("?"+objecList.get(index)+""+descriptor.getName()+""+descriptor
                // .getPropertyType()+":"+propertyValue);
            }
        }
        return true;
    }

    /**
     * ???
     * 
     * @param varName
     *            ????
     * @param collection
     *            ?
     * @param clazz
     *            class
     * @param context
     *            
     * @param preName
     *            ?????
     */
    private void buildCollectionObject(String varName, Collection<Object> collection, Class<?> clazz,
            Context context, String preName) {
        if (clazz == null) {
            return;
        }
        // ???,Enmu\BigDecimal?
        if (checkIfNotComplexObjectCollection(varName, collection, clazz, context, preName)) {
            return;
        }
        // ???
        dealComplexObject(varName, collection, clazz, context, preName);
    }

    private void dealComplexObject(String varName, Collection<Object> collection, Class<?> clazz, Context context,
            String preName) {
        Object object = getObjectInstance(clazz);
        String objName = varName;
        if (isNull(objName)) {
            // 20130806??????
            objName = getObjName(object);
        }
        Map<String, Object> valueMap = new HashMap<String, Object>();
        Class<?> reallyType = object.getClass();
        int size = -1;

        // collectionsize
        for (PropertyDescriptor descriptor : PropertyUtils.getPropertyDescriptors(reallyType)) {
            if (descriptor.getPropertyType().equals(Class.class)) {
                continue;
            }
            if (size != -1) {
                break;
            }
            // 201402025?propertyName?
            // String propertyName = getPropertyName(reallyType,
            // descriptor.getName());
            String propertyName = descriptor.getName();

            Object propertyValue = getPerpertyValue(preName, objName, propertyName, context);
            if (propertyValue != null) {
                valueMap.put(propertyName, propertyValue);
                if (propertyValue.getClass().isArray()) {
                    // 
                    Object[] objArray = (Object[]) propertyValue;
                    if (objArray.length > size) {
                        size = objArray.length;
                    }
                } else if (size == -1) {
                    size = 1;
                }
            }
        }
        // 20130424
        // ?
        // ?
        if (size == -1) {
            return;
        }
        // ?objecList?
        List<Object> objecList = new ArrayList<Object>();
        for (int i = 0; i < size; i++) {
            Object o = getObjectInstance(clazz);
            objecList.add(o);
        }

        for (PropertyDescriptor descriptor : PropertyUtils.getPropertyDescriptors(reallyType)) {
            if (descriptor.getPropertyType().equals(Class.class)) {
                continue;
            }
            // 201402025?propertyName?
            // String propertyName = getPropertyName(reallyType,
            // descriptor.getName());
            String propertyName = descriptor.getName();
            Object propertyValue = getPerpertyValue(preName, objName, propertyName, context);
            if (propertyValue == null) {
                continue;
            }

            try {
                if (size == 1) {
                    Object realvalue = propertyValue;
                    if (propertyValue.getClass().isArray()) {
                        realvalue = ((Object[]) propertyValue)[0];
                    }
                    setSimpleValue(objecList, 0, descriptor, realvalue);

                } else {
                    Object[] objArray = (Object[]) propertyValue;
                    for (int i = 0; i < size; i++) {
                        // BeanUtils.setProperty(objecList.get(i),
                        // descriptor.getName(), objArray[i]);
                        setSimpleValue(objecList, i, descriptor, objArray[i]);
                    }
                }
                continue;
            } catch (Exception e) {
                LOGGER.errorMessage("{0}", e, descriptor.getName());
            }
        }
        // objecList?collection
        for (Object o : objecList) {
            collection.add(o);
        }
        // return collection;
    }

    private void setSimpleValue(List<Object> objecList, int index, PropertyDescriptor descriptor,
            Object propertyValue) throws IllegalAccessException, InvocationTargetException {

        if (descriptor.getPropertyType().equals( // ?()
                propertyValue.getClass())
                || implmentInterface(propertyValue.getClass(), descriptor.getPropertyType())) {
            BeanUtils.setProperty(objecList.get(index), descriptor.getName(), propertyValue);
            return;
        } else if (isSimpleType(descriptor.getPropertyType())) {// ?
            if (isSimpleType(propertyValue.getClass())) { // ?????
                BeanUtils.setProperty(objecList.get(index), descriptor.getName(), propertyValue.toString());
            } else {
                LOGGER.logMessage(LogLevel.WARN, "{0}{1},{3},{4}",
                        objecList.get(index), descriptor.getName(), descriptor.getPropertyType(),
                        propertyValue.getClass());
            }
            return;
        }
        TypeConverter typeConverter = getTypeConverter(descriptor.getPropertyType());

        if (typeConverter != null) {
            if (propertyValue != null) {
                try {
                    BeanUtils.setProperty(objecList.get(index), descriptor.getName(),
                            typeConverter.getObject(propertyValue));
                } catch (Exception e) {
                    LOGGER.errorMessage("{0}", e, descriptor.getName());
                }
            }
        } else {
            throw new RuntimeException(
                    "?" + objecList.get(index) + "" + descriptor.getName()
                            + "" + descriptor.getPropertyType() + ":" + propertyValue);
        }

        // if(descriptor.getPropertyType().isEnum()){
        // BeanUtils.setProperty(objecList.get(index),
        // descriptor.getName(), getEnmuObject(descriptor.getPropertyType(),
        // propertyValue));
        // }else{
        // BeanUtils.setProperty(objecList.get(index),
        // descriptor.getName(), propertyValue);
        // }
    }

    private Object buildArrayObjectWithArray(String varName, Class<?> arrayClass, Context context, String preName) {
        return buildArrayObjectWithObject(varName, arrayClass.getComponentType(), context, preName);
    }

    private Object buildArrayObjectWithObject(String varName, Class<?> objectClass, Context context,
            String preName) {
        if (objectClass == null) {
            return null;
        }
        Collection<Object> collection = new ArrayList<Object>();
        buildCollection(varName, collection, objectClass, context, preName);
        if (collection.isEmpty()) {
            return null;
        } else {
            Object array = Array.newInstance(objectClass, collection.size());
            Iterator<Object> iterator = collection.iterator();
            Object[] objectsArray = (Object[]) array;
            for (int i = 0; i < collection.size(); i++) {
                objectsArray[i] = iterator.next();
            }
            return array;
        }
    }

    private TypeConverter<?, ?> getTypeConverter(Class<?> destType) {
        for (TypeConverter<?, ?> typeConverter : typeConverterList) {
            if (typeConverter.getDestinationType().equals(destType)) {
                return typeConverter;
            }
        }
        return null;
    }

    public void addTypeConverter(TypeConverter<?, ?> typeConverter) {
        typeConverterList.add(typeConverter);
    }

    public void removeTypeConverter(TypeConverter<?, ?> typeConverter) {
        typeConverterList.remove(typeConverter);
    }

}