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

com.devops4j.reflection4j.factory.DefaultObjectFactory Maven / Gradle / Ivy

There is a newer version: 1.0.0-PRE1
Show newest version
package com.devops4j.reflection4j.factory;

import com.devops4j.reflection4j.ObjectFactory;
import com.devops4j.logtrace4j.ErrorContextFactory;
import com.devops4j.logtrace4j.TraceableRuntimeException;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class DefaultObjectFactory implements ObjectFactory, Serializable {

    final Map registers = new ConcurrentHashMap();

    public DefaultObjectFactory() {
        register(List.class, ArrayList.class);
        register(Collection.class, ArrayList.class);
        register(Iterable.class, ArrayList.class);
        register(Map.class, HashMap.class);
        register(SortedSet.class, TreeSet.class);
        register(Set.class, HashSet.class);
    }

    public  T create(Class type) {
        Class classToCreate = resolveInterface(type);
        return (T) instantiateClass(classToCreate, null, null);
    }

    public  T create(Class type, List constructorArgTypes, List constructorArgs) {
        Class classToCreate = resolveInterface(type);
        return (T) instantiateClass(classToCreate, constructorArgTypes, constructorArgs);
    }

    public  T create(Class type, Class[] constructorArgTypes, Object[] constructorArgs) {
        Class classToCreate = resolveInterface(type);
        return (T) instantiateClass(classToCreate, Arrays.asList(constructorArgTypes), Arrays.asList(constructorArgs));
    }

    public void register(Class interfaceClass, Class implementClass) {
        if (!interfaceClass.isInterface()) {
            ErrorContextFactory.instance().message("注册接口映射时,interfaceClass参数'{}'不是接口", interfaceClass).throwError();
            return;
        }
        if (implementClass.isInterface()) {
            ErrorContextFactory.instance().message("注册接口映射时,implementClass参数'{}'是接口", interfaceClass).solution("使用'{}'接口的实现类", interfaceClass).throwError();
            return;
        }
        if (implementClass.getModifiers() == Modifier.ABSTRACT) {
            ErrorContextFactory.instance().message("注册接口映射时,implementClass参数'{}'是抽象的", interfaceClass).solution("使用'{}'接口的非抽象实现类", interfaceClass).throwError();
            return;
        }
        registers.put(interfaceClass, implementClass);
    }

    public Map getMappings() {
        return new HashMap(registers);
    }

    public void setProperties(Properties properties) {
        // no props for default
    }


    /**
     * 实例化类
     *
     * @param type
     * @param constructorArgTypes
     * @param constructorArgs
     * @param 
     * @return
     */
     T instantiateClass(Class type, List constructorArgTypes, List constructorArgs) {
        if (type.isArray()) {
            Class arrayClass = type.getComponentType();
            return (T) Array.newInstance(arrayClass, 0);
        }
        try {
            Constructor constructor;
            //如果参数值或者参数类型为空,则采用默认构造函数进行创建
            if (constructorArgTypes == null || constructorArgs == null) {
                try {
                    constructor = type.getDeclaredConstructor();
                    //无参构造如果为私有,设置为可以访问
                    if (!constructor.isAccessible()) {
                        constructor.setAccessible(true);
                    }
                    //通过无参构造创建实例
                    return constructor.newInstance();
                } catch (Exception e) {
                    ErrorContextFactory.instance().message("类'{}'不能使用无参构造方法创建实例", type).solution("请换成该类的有参构造方法创建实例").cause(e).throwError();
                }
            }
            //如果参数值或者参数类型不为空,则采用带有参数的构造函数
            constructor = type.getDeclaredConstructor(constructorArgTypes.toArray(new Class[constructorArgTypes.size()]));
            if (!constructor.isAccessible()) {
                constructor.setAccessible(true);
            }
            return constructor.newInstance(constructorArgs.toArray(new Object[constructorArgs.size()]));
        } catch (TraceableRuntimeException e) {
            throw e;
        } catch (Exception e) {
            StringBuilder argTypes = new StringBuilder();
            if (constructorArgTypes != null && !constructorArgTypes.isEmpty()) {
                for (Class argType : constructorArgTypes) {
                    argTypes.append(argType.getSimpleName());
                    argTypes.append(",");
                }
                argTypes.deleteCharAt(argTypes.length() - 1); // remove trailing ,
            }
            StringBuilder argValues = new StringBuilder();
            if (constructorArgs != null && !constructorArgs.isEmpty()) {
                for (Object argValue : constructorArgs) {
                    argValues.append(String.valueOf(argValue));
                    argValues.append(",");
                }
                argValues.deleteCharAt(argValues.length() - 1); // remove trailing ,
            }
            ErrorContextFactory.instance().message("Error instantiating {} with invalid types {} or values {}", type, argTypes, argValues).cause(e).throwError();
            return null;
        }
    }

    /**
     * 根据对象接口连接到指定的实现类
     *
     * @param type
     * @return
     */
    protected Class resolveInterface(Class type) {
        Class classToCreate = registers.get(type);
        if (classToCreate == null) {
            classToCreate = type;
        }
        if (type == Byte.TYPE
                || type == Byte.class
                || type == Boolean.TYPE
                || type == Boolean.class
                || type == Short.TYPE
                || type == Short.class
                || type == Integer.TYPE
                || type == Integer.class
                || type == Long.TYPE
                || type == Long.class
                || type == Float.TYPE
                || type == Float.class
                || type == Double.TYPE
                || type == Double.class
                ) {
            ErrorContextFactory.instance().message("创建实例时,implementClass参数'{}'是基本类型", classToCreate).throwError();
            return null;
        }
        if (classToCreate.isInterface()) {
            ErrorContextFactory.instance().message("创建实例时,implementClass参数'{}'是接口", classToCreate).solution("使用'{}'接口的实现类", classToCreate).throwError();
            return null;
        }
        if (classToCreate.getModifiers() == Modifier.ABSTRACT) {
            ErrorContextFactory.instance().message("创建实例时,implementClass参数'{}'是抽象的", classToCreate).solution("使用'{}'接口的非抽象实现类", classToCreate).throwError();
            return null;
        }
        return classToCreate;
    }

    public  boolean isCollection(Class type) {
        return Collection.class.isAssignableFrom(type);
    }

}