Example usage for java.lang.reflect Modifier isAbstract

List of usage examples for java.lang.reflect Modifier isAbstract

Introduction

In this page you can find the example usage for java.lang.reflect Modifier isAbstract.

Prototype

public static boolean isAbstract(int mod) 

Source Link

Document

Return true if the integer argument includes the abstract modifier, false otherwise.

Usage

From source file:eu.crisis_economics.abm.dashboard.Page_Parameters.java

ClassElement[] fetchPossibleTypes(final SubmodelInfo parameterInfo) throws ComboBoxIsTooFullException {
    List<Class<?>> possibleTypes = possibleTypesCache.get(parameterInfo.getName());

    if (possibleTypes == null)
        possibleTypes = parameterInfo.getPossibleTypes();
    if (possibleTypes == null || possibleTypes.isEmpty()) {
        possibleTypes = new ArrayList<Class<?>>();
        possibleTypes.add(parameterInfo.getJavaType());

        possibleTypes.addAll(getSubtypes(parameterInfo.getJavaType()));

        // delete all interfaces and abstract classes
        for (final Iterator<Class<?>> iter = possibleTypes.iterator(); iter.hasNext();) {
            final Class<?> clazz = iter.next();
            if (Modifier.isAbstract(clazz.getModifiers()) || Modifier.isInterface(clazz.getModifiers()))
                iter.remove();//from   w w  w. j  a v a 2 s. c om
        }
    }

    possibleTypesCache.put(parameterInfo.getName(), possibleTypes);
    Collections.sort(possibleTypes, new Comparator<Class<?>>() {
        public int compare(final Class<?> class1, final Class<?> class2) {
            return class1.getName().compareTo(class2.getName());
        }

    });

    final ClassElement[] result = new ClassElement[possibleTypes.size() + 1];
    result[0] = new ClassElement(null, null);

    for (int i = 0; i < possibleTypes.size(); ++i) {
        if (possibleTypes.get(i).equals(parameterInfo.getActualType())) {
            result[i + 1] = new ClassElement(possibleTypes.get(i), parameterInfo.getInstance());
        } else {
            result[i + 1] = new ClassElement(possibleTypes.get(i), null);
        }
    }

    return result;
}

From source file:edu.ku.brc.specify.tasks.subpane.wb.wbuploader.UploadTable.java

private Vector<Method> getGetters() {
    Method[] methods = tblClass.getMethods();
    Vector<Method> result = new Vector<Method>();
    for (Method m : methods) {
        if (m.getName().startsWith("get") && m.getParameterTypes().length == 0
                && m.getReturnType() != void.class && Modifier.isPublic(m.getModifiers())
                && !Modifier.isTransient(m.getModifiers()) && !Modifier.isStatic(m.getModifiers())
                && !Modifier.isAbstract(m.getModifiers())) {
            Annotation jc = m.getAnnotation(javax.persistence.Column.class);
            Annotation c = m.getAnnotation(javax.persistence.JoinColumn.class);
            Annotation otm = m.getAnnotation(javax.persistence.OneToMany.class);
            if (otm == null && (jc != null || c != null || m.getName().equalsIgnoreCase("getId"))) {
                result.add(m);//w w  w .  ja  v a2  s. c o m
            }

        }
    }
    return result;
}

From source file:org.kchine.r.server.DirectJNI.java

public static void generateMaps(URL jarUrl, boolean rawClasses) {

    try {//from   w w  w .j a  v a 2s .  co  m

        _mappingClassLoader = new URLClassLoader(new URL[] { jarUrl }, DirectJNI.class.getClassLoader());
        Vector<String> list = new Vector<String>();
        JarURLConnection jarConnection = (JarURLConnection) jarUrl.openConnection();
        JarFile jarfile = jarConnection.getJarFile();
        Enumeration<JarEntry> enu = jarfile.entries();
        while (enu.hasMoreElements()) {
            String entry = enu.nextElement().toString();
            if (entry.endsWith(".class"))
                list.add(entry.replace('/', '.').substring(0, entry.length() - ".class".length()));
        }

        log.info(list);

        for (int i = 0; i < list.size(); ++i) {
            String className = list.elementAt(i);
            if (className.startsWith("org.kchine.r.packages.")
                    && !className.startsWith("org.kchine.r.packages.rservices")) {
                Class<?> c_ = _mappingClassLoader.loadClass(className);

                if (c_.getSuperclass() != null && c_.getSuperclass().equals(RObject.class)
                        && !Modifier.isAbstract(c_.getModifiers())) {

                    if (c_.equals(RLogical.class) || c_.equals(RInteger.class) || c_.equals(RNumeric.class)
                            || c_.equals(RComplex.class) || c_.equals(RChar.class) || c_.equals(RMatrix.class)
                            || c_.equals(RArray.class) || c_.equals(RList.class) || c_.equals(RDataFrame.class)
                            || c_.equals(RFactor.class) || c_.equals(REnvironment.class)
                            || c_.equals(RVector.class) || c_.equals(RUnknown.class)) {
                    } else {
                        String rclass = DirectJNI.getRClassForBean(jarfile, className);
                        _s4BeansHash.put(className, c_);
                        _s4BeansMapping.put(rclass, className);
                        _s4BeansMappingRevert.put(className, rclass);
                    }

                } else if ((rawClasses && c_.getSuperclass() != null && c_.getSuperclass().equals(Object.class))
                        || (!rawClasses && RPackage.class.isAssignableFrom(c_) && (c_.isInterface()))) {

                    String shortClassName = className.substring(className.lastIndexOf('.') + 1);
                    _packageNames.add(shortClassName);

                    Vector<Class<?>> v = _rPackageInterfacesHash.get(className);
                    if (v == null) {
                        v = new Vector<Class<?>>();
                        _rPackageInterfacesHash.put(className, v);
                    }
                    v.add(c_);

                } else {
                    String nameWithoutPackage = className.substring(className.lastIndexOf('.') + 1);
                    if (nameWithoutPackage.indexOf("Factory") != -1
                            && c_.getMethod("setData", new Class[] { RObject.class }) != null) {
                        // if
                        // (DirectJNI._factoriesMapping.get(nameWithoutPackage
                        // )
                        // != null) throw new Exception("Factories Names
                        // Conflict : two " + nameWithoutPackage);
                        _factoriesMapping.put(nameWithoutPackage, className);
                        if (Modifier.isAbstract(c_.getModifiers()))
                            _abstractFactories.add(className);
                    }
                }
            }
        }

        // log.info("s4Beans:" +s4Beans);
        log.info("rPackageInterfaces:" + _packageNames);
        log.info("s4Beans MAP :" + _s4BeansMapping);
        log.info("s4Beans Revert MAP :" + _s4BeansMappingRevert);
        log.info("factories :" + _factoriesMapping);
        log.info("r package interface hash :" + _rPackageInterfacesHash);

    } catch (Exception ex) {
        ex.printStackTrace();
    }

}

From source file:ca.oson.json.Oson.java

private <E, R> Class guessComponentType(FieldData newFieldData) {
    boolean json2Java = newFieldData.json2Java;

    if (!json2Java) {
        return newFieldData.returnType;
    } else {//from   w  ww  . j ava 2s. co m

        E obj = (E) newFieldData.valueToProcess;

        Class returnType = newFieldData.returnType;
        Class itemType = null;
        if (obj != null) {
            itemType = obj.getClass();
        }

        if (newFieldData.componentType != null) {
            Class classType = newFieldData.componentType.getClassType();
            Class cls = newFieldData.componentType.getMainComponentType();
            if (cls != null
                    && (ObjectUtil.isBasicDataType(cls) || ObjectUtil.isSameDataType(classType, returnType))) {
                return cls;
            }
        }

        String returnTypeName = null;
        if (returnType != null) {
            returnTypeName = returnType.getName();
        }
        String itemTypeName = null;
        if (itemType != null) {
            itemTypeName = itemType.getName();
        }

        int returnTypeCount = 0;
        int itemTypeCount = 0;
        String toGenericString = null;
        Class fieldType = null;
        if (newFieldData.field != null) {
            toGenericString = newFieldData.field.toGenericString();
            Class[] fieldTypes = ObjectUtil.getComponentTypes(toGenericString);

            if (fieldTypes != null && fieldTypes.length > 0) {
                if (fieldTypes.length == 1) {
                    fieldType = fieldTypes[0];
                } else {
                    fieldType = fieldTypes[0];

                    if (newFieldData.isMapValue) {
                        fieldType = fieldTypes[1];
                    } else {
                        fieldType = fieldTypes[0];
                    }
                }
            }

            if (returnTypeName != null && toGenericString.indexOf(returnTypeName) > -1) {
                returnTypeCount++;
            }
            if (itemTypeName != null && toGenericString.indexOf(itemTypeName) > -1) {
                itemTypeCount++;
            }
        }
        if (fieldType == null && returnType != null) {
            toGenericString = returnType.toGenericString();
            fieldType = ObjectUtil.getComponentType(toGenericString);
            if (returnTypeName != null && toGenericString.indexOf(returnTypeName) > -1) {
                returnTypeCount++;
            }
            if (itemTypeName != null && toGenericString.indexOf(itemTypeName) > -1) {
                itemTypeCount++;
            }
        }
        if (fieldType == null && newFieldData.setter != null) {
            toGenericString = newFieldData.setter.toGenericString();
            fieldType = ObjectUtil.getComponentType(toGenericString);
            if (returnTypeName != null && toGenericString.indexOf(returnTypeName) > -1) {
                returnTypeCount++;
            }
            if (itemTypeName != null && toGenericString.indexOf(itemTypeName) > -1) {
                itemTypeCount++;
            }

            if (fieldType == null) {
                Class[] types = newFieldData.setter.getParameterTypes();
                if (types != null && types.length > 0) {
                    toGenericString = types[0].toGenericString();
                    fieldType = ObjectUtil.getComponentType(toGenericString);
                    if (returnTypeName != null && toGenericString.indexOf(returnTypeName) > -1) {
                        returnTypeCount++;
                    }
                    if (itemTypeName != null && toGenericString.indexOf(itemTypeName) > -1) {
                        itemTypeCount++;
                    }
                }
            }
        }

        ComponentType type = getComponentType();
        if (type == null) {
            Class enclosingtype = newFieldData.getEnclosingtype();
            if (enclosingtype != null) {
                type = cachedComponentTypes(enclosingtype);
            }
        }

        int level = newFieldData.level;

        if (fieldType != null) {
            if (returnTypeCount < itemTypeCount) {
                newFieldData.returnType = itemType;
            }

            if (type == null) {
                type = new ComponentType(newFieldData.returnType, fieldType);
                type = cachedComponentTypes(type);

            } else {
                type.add(fieldType);
            }

            if (newFieldData.returnType == Object.class) {
                newFieldData.returnType = fieldType;
            }

            return fieldType;
        }

        if (returnType != null) {
            Class comptype = returnType.getComponentType();
            if (comptype != null && !comptype.isInterface() && !Modifier.isAbstract(comptype.getModifiers())) {
                return comptype;
            }
        }

        if ((returnType != null && Map.class.isAssignableFrom(returnType))
                || (itemType != null && Map.class.isAssignableFrom(itemType))) {
            String className = ((Map<String, String>) obj).get(getJsonClassType());
            if (className != null && className.length() > 0) {
                try {
                    // figure out obj's class
                    fieldType = Class.forName(className);

                    if (type == null) {
                        if (newFieldData.returnType != fieldType) {
                            type = new ComponentType(newFieldData.returnType, fieldType);
                            type = cachedComponentTypes(type);
                        }

                    } else {
                        type.add(fieldType);
                    }
                    newFieldData.returnType = fieldType;

                    return fieldType;

                } catch (ClassNotFoundException e) {
                    // e.printStackTrace();
                }
            }

            if (returnTypeCount > 0 && !Map.class.isAssignableFrom(returnType)
                    && !Collection.class.isAssignableFrom(returnType) && returnType != Optional.class
                    && returnType != Object.class && !returnType.isArray()) {
                if (type != null) {
                    type.add(returnType);
                }

                return returnType;
            }

            if (type != null) {
                ComponentType componentType = type.getComponentType();
                while (componentType != null && componentType.getComponentType() != null && level > 1) {
                    componentType = componentType.getComponentType();
                    level--;
                }

                if (level == 1 && componentType != null && componentType.getClassType() != null) {
                    return componentType.getClassType();
                }

                Class[] ctypes = type.getComponentClassType();
                float MIN_MAX_COUNT = 20.0f;
                if (ctypes != null && ctypes.length > 0) {
                    int length = ctypes.length;

                    Map<String, R> map = (Map) obj;

                    Map<String, Class> lnames = new HashMap<>(); //names.stream().map(name -> name.toLowerCase()).collect(Collectors.toSet());
                    for (String name : map.keySet()) {
                        Object value = map.get(name);
                        if (value != null) {
                            lnames.put(name.toLowerCase(), map.get(name).getClass());
                        }
                    }
                    int maxIdx = -1;
                    float maxCount = 0.0f;
                    for (int i = 0; i < length; i++) {
                        Class ctype = ctypes[i];

                        Field[] fields = getFields(ctype);
                        if (fields != null && fields.length > 0) {
                            int count = 0;

                            for (Field field : fields) {
                                String name = field.getName().toLowerCase();
                                if (lnames.containsKey(name)) {
                                    count++;

                                    Class ftype = field.getType();
                                    Class mtype = lnames.get(name);
                                    if (ObjectUtil.isSameDataType(ftype, mtype)) {
                                        count++;
                                    }
                                }
                            }
                            float currentCount = count * 100.0f / fields.length;
                            if (currentCount > maxCount) {
                                maxCount = currentCount;
                                maxIdx = i;
                            } else if (maxIdx == -1 && ctype.isAssignableFrom(itemType)) {
                                maxIdx = i;
                            }
                        }
                    }

                    if (maxIdx > -1) {
                        newFieldData.returnType = ctypes[maxIdx];

                        return ctypes[maxIdx];
                    }

                    Set<Class> processed = new HashSet(Arrays.asList(ctypes));

                    // now try to locate it in all cachedComponentTypes
                    for (Entry<Class, ComponentType> entry : cachedComponentTypes.entrySet()) {
                        Class myMasterClass = entry.getKey();

                        if (myMasterClass != this.masterClass && entry.getValue() != null) {
                            ctypes = entry.getValue().getComponentClassType();
                            if (ctypes != null) {
                                length = ctypes.length;

                                maxCount = 0.0f;
                                for (int i = 0; i < length; i++) {
                                    Class ctype = ctypes[i];

                                    if (!processed.contains(ctype)) {
                                        Field[] fields = getFields(ctype);
                                        if (fields != null && fields.length > 0) {
                                            int count = 0;

                                            for (Field field : fields) {
                                                String name = field.getName();
                                                if (name != null) {
                                                    name = name.toLowerCase();
                                                    if (lnames.containsKey(name)) {
                                                        count++;

                                                        Class ftype = field.getType();
                                                        Class mtype = lnames.get(name);
                                                        if (ObjectUtil.isSameType(ftype, mtype)) {
                                                            count++;
                                                        }
                                                    }
                                                }
                                            }
                                            float currentCount = count * 100.0f / fields.length;
                                            if (currentCount > maxCount) {
                                                maxCount = currentCount;
                                                maxIdx = i;
                                            }
                                            //                                 else if (maxIdx == -1 && ctype.isAssignableFrom(itemType)) {
                                            //                                    maxIdx = i;
                                            //                                 }
                                        }
                                    }
                                }

                                if (maxIdx > -1 && maxCount > MIN_MAX_COUNT) {
                                    newFieldData.returnType = ctypes[maxIdx];

                                    type.add(ctypes[maxIdx]);

                                    return ctypes[maxIdx];
                                }

                                processed.addAll(Arrays.asList(ctypes));
                            }
                        }
                    }

                    if (ctypes != null && ctypes.length == 1) {
                        return ctypes[0];
                    }
                }

            }

        } else if ((returnType != null
                && (Collection.class.isAssignableFrom(returnType) || returnType.isArray()))
                || (itemType != null && (Collection.class.isAssignableFrom(itemType) || itemType.isArray()))) {

            //  && ComponentType.class.isAssignableFrom(erasedType.getClass())
            if (type != null) {

                ComponentType componentType = type.getComponentType();
                while (componentType != null && componentType.getComponentType() != null && level > 1) {
                    componentType = componentType.getComponentType();
                    level--;
                }

                if (level == 1 && componentType != null && componentType.getClassType() != null) {
                    return componentType.getClassType();
                }

                Class[] ctypes = type.getComponentClassType();

                if (ctypes != null && ctypes.length > 0) {
                    if (ctypes.length == 1) {
                        Class cmptype = ctypes[0].getComponentType();
                        if (cmptype != null
                                && (cmptype.isArray() || Collection.class.isAssignableFrom(cmptype))) {
                            type.add(cmptype);
                        }
                        //if (!ObjectUtil.isBasicDataType(ctypes[0])) {
                        return ctypes[0];
                        //}
                    }

                    int length = ctypes.length;
                    int depth = CollectionArrayTypeGuesser.getDepth(obj);
                    Class baseType = CollectionArrayTypeGuesser.getBaseType(obj);
                    Class possible = null;
                    for (int i = 0; i < length; i++) {
                        Class ctype = ctypes[i];

                        if (ctype.isArray() || Collection.class.isAssignableFrom(ctype)) {
                            //Class compType = CollectionArrayTypeGuesser.guessElementType(collection, ctype, getJsonClassType());
                            int typedepth = CollectionArrayTypeGuesser.getDepth(ctype);
                            Class cbaseType = CollectionArrayTypeGuesser.getBaseType(ctype);
                            if (depth == typedepth) {
                                if (ObjectUtil.isSameType(baseType, cbaseType)) {
                                    Class cmptype = ctype.getComponentType();
                                    if (cmptype.isArray() || Collection.class.isAssignableFrom(cmptype)) {
                                        type.add(cmptype);
                                    }

                                    return ctype;

                                } else if (itemType.isAssignableFrom(ctype)
                                        || ctype.isAssignableFrom(itemType)) {
                                    possible = ctype;
                                }
                            }
                        }

                    }

                    if (possible != null) {
                        return possible;
                    }

                }

            }

        }
        //         else if (StringUtil.isNumeric(obj.toString())) {
        //            if (obj.toString().contains(".")) {
        //               return Double.class;
        //            } else {
        //               return Integer.class;
        //            }
        //         }

        if (type != null && type.getComponentType() != null) {
            Class classType = type.getComponentType().getClassType();
            if (classType != null && ObjectUtil.isSameDataType(classType, itemType)) {
                return classType;
            }
        }

        return itemType;
    }
}

From source file:ca.oson.json.Oson.java

private <E, R> String object2Serialize(FieldData objectDTO) {
    E obj = (E) objectDTO.valueToProcess;

    Class<R> valueType = objectDTO.returnType;

    if (obj == null) {
        return null;
    }/*from   ww w .j  a  v  a 2s .c o  m*/

    // it is possible the same object shared by multiple variables inside the same enclosing object
    int hash = ObjectUtil.hashCode(obj, valueType);
    if (!objectDTO.goAhead(hash)) {
        return "{}";
    }

    ClassMapper classMapper = objectDTO.classMapper;
    // first build up the class-level processing rules
    // || (objectDTO.level == 0 && objectDTO.fieldMapper == null)
    //if (classMapper == null) {
    // 1. Create a blank class mapper instance
    classMapper = new ClassMapper(valueType);

    // 2. Globalize it
    classMapper = globalize(classMapper);
    objectDTO.classMapper = classMapper;
    //}

    if (objectDTO.fieldMapper != null && isInheritMapping()) {
        classMapper = overwriteBy(classMapper, objectDTO.fieldMapper);
    }

    FIELD_NAMING format = getFieldNaming();

    String repeated = getPrettyIndentationln(objectDTO.level), pretty = getPrettySpace();
    objectDTO.incrLevel();
    String repeatedItem = getPrettyIndentationln(objectDTO.level);

    // @Expose
    Set<String> exposed = null;
    if (isUseGsonExpose()) {
        exposed = new HashSet<>();
    }

    boolean annotationSupport = getAnnotationSupport();
    Annotation[] annotations = null;

    if (annotationSupport) {
        annotations = valueType.getAnnotations();

        ca.oson.json.annotation.ClassMapper classMapperAnnotation = null;

        // 3. Apply annotations from other sources
        for (Annotation annotation : annotations) {
            if (ignoreClass(annotation)) {
                return null;
            }

            switch (annotation.annotationType().getName()) {
            case "ca.oson.json.annotation.ClassMapper":
                classMapperAnnotation = (ca.oson.json.annotation.ClassMapper) annotation;
                if (!(classMapperAnnotation.serialize() == BOOLEAN.BOTH
                        || classMapperAnnotation.serialize() == BOOLEAN.TRUE)) {
                    classMapperAnnotation = null;
                }
                break;

            case "ca.oson.json.annotation.ClassMappers":
                ca.oson.json.annotation.ClassMappers classMapperAnnotations = (ca.oson.json.annotation.ClassMappers) annotation;
                for (ca.oson.json.annotation.ClassMapper ann : classMapperAnnotations.value()) {
                    if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.TRUE) {
                        classMapperAnnotation = ann;
                        //break;
                    }
                }
                break;

            case "com.google.gson.annotations.Since":
                Since since = (Since) annotation;
                classMapper.since = since.value();
                break;

            case "com.google.gson.annotations.Until":
                Until until = (Until) annotation;
                classMapper.until = until.value();
                break;

            case "com.fasterxml.jackson.annotation.JsonIgnoreProperties":
                JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation;
                String[] jsonnames = jsonIgnoreProperties.value();
                if (jsonnames != null && jsonnames.length > 0) {
                    if (classMapper.jsonIgnoreProperties == null) {
                        classMapper.jsonIgnoreProperties = new HashSet();
                    }

                    classMapper.jsonIgnoreProperties.addAll(Arrays.asList(jsonnames));
                }
                break;

            case "org.codehaus.jackson.annotate.JsonIgnoreProperties":
                org.codehaus.jackson.annotate.JsonIgnoreProperties jsonIgnoreProperties2 = (org.codehaus.jackson.annotate.JsonIgnoreProperties) annotation;
                String[] jsonnames2 = jsonIgnoreProperties2.value();
                if (jsonnames2 != null && jsonnames2.length > 0) {
                    if (classMapper.jsonIgnoreProperties == null) {
                        classMapper.jsonIgnoreProperties = new HashSet();
                    }

                    classMapper.jsonIgnoreProperties.addAll(Arrays.asList(jsonnames2));
                }
                break;

            case "com.fasterxml.jackson.annotation.JsonPropertyOrder":
                // first come first serve
                if (classMapper.propertyOrders == null) {
                    classMapper.propertyOrders = ((JsonPropertyOrder) annotation).value();
                }
                break;

            case "org.codehaus.jackson.annotate.JsonPropertyOrder":
                // first come first serve
                if (classMapper.propertyOrders == null) {
                    classMapper.propertyOrders = ((org.codehaus.jackson.annotate.JsonPropertyOrder) annotation)
                            .value();
                }
                break;

            case "com.fasterxml.jackson.annotation.JsonInclude":
                if (classMapper.defaultType == JSON_INCLUDE.NONE) {
                    JsonInclude jsonInclude = (JsonInclude) annotation;
                    switch (jsonInclude.content()) {
                    case ALWAYS:
                        classMapper.defaultType = JSON_INCLUDE.ALWAYS;
                        break;
                    case NON_NULL:
                        classMapper.defaultType = JSON_INCLUDE.NON_NULL;
                        break;
                    case NON_ABSENT:
                        classMapper.defaultType = JSON_INCLUDE.NON_NULL;
                        break;
                    case NON_EMPTY:
                        classMapper.defaultType = JSON_INCLUDE.NON_EMPTY;
                        break;
                    case NON_DEFAULT:
                        classMapper.defaultType = JSON_INCLUDE.NON_DEFAULT;
                        break;
                    case USE_DEFAULTS:
                        classMapper.defaultType = JSON_INCLUDE.DEFAULT;
                        break;
                    }
                }
                break;

            case "com.fasterxml.jackson.annotation.JsonAutoDetect":
                JsonAutoDetect jsonAutoDetect = (JsonAutoDetect) annotation;
                if (jsonAutoDetect.fieldVisibility() == Visibility.NONE) {
                    classMapper.useField = false;
                }
                if (jsonAutoDetect.getterVisibility() == Visibility.NONE) {
                    classMapper.useAttribute = false;
                }
                break;

            case "org.codehaus.jackson.annotate.JsonAutoDetect":
                org.codehaus.jackson.annotate.JsonAutoDetect jsonAutoDetect2 = (org.codehaus.jackson.annotate.JsonAutoDetect) annotation;
                if (jsonAutoDetect2
                        .fieldVisibility() == org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE) {
                    classMapper.useField = false;
                }
                if (jsonAutoDetect2
                        .getterVisibility() == org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE) {
                    classMapper.useAttribute = false;
                }

                break;

            case "org.junit.Ignore":
                classMapper.ignore = true;
                break;
            }
        }

        // 4. Apply annotations from Oson
        if (classMapperAnnotation != null) {
            classMapper = overwriteBy(classMapper, classMapperAnnotation);
            exposed = null;
        }

    }

    // 5. Apply Java configuration for this particular class
    ClassMapper javaClassMapper = getClassMapper(valueType);
    if (javaClassMapper != null) {
        classMapper = overwriteBy(classMapper, javaClassMapper);
    }

    // now processing at the class level

    if (classMapper.ignore()) {
        return null;
    }

    if (classMapper.since != null && classMapper.since > getVersion()) {
        return null;
    } else if (classMapper.until != null && classMapper.until <= getVersion()) {
        return null;
    }

    Function function = classMapper.serializer; //getSerializer(valueType);
    if (function == null) {
        function = DeSerializerUtil.getSerializer(valueType.getName());
    }

    if (function != null) {
        try {
            Object returnValue = null;
            if (function instanceof DataMapper2JsonFunction) {
                DataMapper classData = new DataMapper(valueType, obj, classMapper, objectDTO.level,
                        getPrettyIndentation());
                objectDTO.jsonRawValue = false;
                DataMapper2JsonFunction f = (DataMapper2JsonFunction) function;

                return f.apply(classData);

            } else if (function instanceof FieldData2JsonFunction) {
                FieldData2JsonFunction f = (FieldData2JsonFunction) function;
                FieldData fieldData = objectDTO.clone();

                returnValue = f.apply(fieldData);

            } else {
                returnValue = function.apply(obj);
            }

            if (returnValue != null) {
                Class returnType = returnValue.getClass();

                if (returnType == String.class) {
                    return StringUtil.doublequote(returnValue, isEscapeHtml());

                } else if (returnType == valueType || valueType.isAssignableFrom(returnType)) {
                    // just continue to do the serializing
                } else {
                    objectDTO.valueToProcess = returnValue;
                    objectDTO.returnType = returnType;

                    return object2String(objectDTO);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    Set<Class> ignoreFieldsWithAnnotations = classMapper.ignoreFieldsWithAnnotations;

    Map<String, String> keyJsonStrings = new LinkedHashMap<>();
    // to hold relation between name and changed name
    Map<String, String> fieldNames = new LinkedHashMap<>();

    Set<String> processedNameSet = new HashSet<>();
    //StringBuffer sb = new StringBuffer();

    Map<String, Method> getters = null;
    Map<String, Method> setters = null;
    Map<String, Method> otherMethods = null;

    if (valueType.isInterface()) {
        valueType = (Class<R>) obj.getClass();
    } else if (Modifier.isAbstract(valueType.getModifiers())) {
        // valueType

    } else {
        //         Class objClass = obj.getClass();
        //         if (valueType.isAssignableFrom(objClass)) {
        //            valueType = objClass;
        //         }
    }

    //      if (valueType.isInterface()) {
    //         getters = getGetters(obj);
    //         setters = getSetters(obj);
    //         otherMethods = getOtherMethods(obj);
    //      } else {
    getters = getGetters(valueType);
    setters = getSetters(valueType);
    otherMethods = getOtherMethods(valueType);
    //      }

    Set<Method> jsonAnyGetterMethods = new HashSet<>();

    if (classMapper.isToStringAsSerializer()) {
        try {
            Method getter = valueType.getDeclaredMethod("toString", null);

            if (getter != null) {
                E getterValue = ObjectUtil.getMethodValue(obj, getter);

                if (getterValue != null) {
                    Class returnType = getterValue.getClass();

                    if (returnType == String.class) {
                        return StringUtil.doublequote(getterValue, isEscapeHtml());

                    } else if (returnType == valueType || valueType.isAssignableFrom(returnType)) {
                        // just continue to do the serializing
                    } else {
                        objectDTO.valueToProcess = getterValue;
                        objectDTO.returnType = returnType;

                        return object2String(objectDTO);
                    }
                }
            }

        } catch (NoSuchMethodException | SecurityException e) {
            // e.printStackTrace();
        }
    }

    //if (getters != null && getters.size() > 0) {
    boolean isJsonRawValue = false;
    String jsonValueFieldName = DeSerializerUtil.getJsonValueFieldName(valueType.getName());
    //         if (jsonValueFieldName == null) {
    //            // get all fieldmappers for this class?
    //            Set<FieldMapper> fieldMappers = getFieldMappers(valueType);
    //            // looking for the method
    //            for (FieldMapper fieldMapper: fieldMappers) {
    //               if (fieldMapper.jsonValue != null && fieldMapper.jsonValue) {
    //                  jsonValueFieldName = fieldMapper.java;
    //                  isJsonRawValue = fieldMapper.isJsonRawValue();
    //                  break;
    //               }
    //            }
    //         }
    if (jsonValueFieldName == null) {
        jsonValueFieldName = classMapper.getJsonValueFieldName();
    }

    if (jsonValueFieldName != null) {
        String lcjava = jsonValueFieldName.toLowerCase();
        Method getter = null;
        if (getters != null && getters.containsKey(lcjava)) {
            getter = getters.get(lcjava);

        } else {
            try {
                getter = valueType.getMethod(jsonValueFieldName);
            } catch (NoSuchMethodException | SecurityException e) {
                // e.printStackTrace();
            }

            if (getter == null) {
                try {
                    getter = valueType.getMethod("get" + StringUtil.capitalize(jsonValueFieldName));
                } catch (NoSuchMethodException | SecurityException e) {
                    //e.printStackTrace();
                }
            }
        }

        if (getter != null) {
            E getterValue = ObjectUtil.getMethodValue(obj, getter);

            if (getterValue != null) {
                Class returnType = getterValue.getClass();

                if (returnType == String.class) {
                    if (isJsonRawValue) {
                        return getterValue.toString();

                    } else if (StringUtil.parenthesized(getterValue.toString())) {
                        return getterValue.toString();

                    } else {
                        return StringUtil.doublequote(getterValue, isEscapeHtml());
                    }

                } else if (returnType == valueType || valueType.isAssignableFrom(returnType)) {
                    // just continue to do the serializing
                } else {
                    objectDTO.valueToProcess = getterValue;
                    objectDTO.returnType = returnType;
                    objectDTO.jsonRawValue = isJsonRawValue;

                    return object2String(objectDTO);
                }
            }
        }
    }
    //}

    try {
        Field[] fields = null;
        //         if (valueType.isInterface()) {
        //            fields = getFields(obj);
        //         } else {
        fields = getFields(valueType);
        //         }

        for (Field f : fields) {
            f.setAccessible(true);

            String name = f.getName();
            String fieldName = name;
            String lcfieldName = fieldName.toLowerCase();

            if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) {
                getters.remove(lcfieldName);
                continue;
            }

            // 6. Create a blank field mapper instance
            FieldMapper fieldMapper = new FieldMapper(name, name, valueType);

            Class<?> returnType = f.getType(); // value.getClass();

            // 7. get the class mapper of returnType
            ClassMapper fieldClassMapper = getClassMapper(returnType);

            // 8. Classify this field mapper with returnType
            fieldMapper = classifyFieldMapper(fieldMapper, fieldClassMapper);

            // 9. Classify this field mapper
            fieldMapper = classifyFieldMapper(fieldMapper, classMapper);

            FieldMapper javaFieldMapper = getFieldMapper(name, null, valueType);

            // getter and setter methods
            Method getter = getters.get(lcfieldName);
            Method setter = setters.get(lcfieldName);

            if (getter != null) {
                getter.setAccessible(true);
            }

            // control by visibility is not always a good idea
            // here consider the visibility of field and related getter method together
            if (ignoreModifiers(f.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                if (getter != null) {
                    if (ignoreModifiers(getter.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                        getters.remove(lcfieldName);
                        continue;
                    }
                } else {
                    continue;
                }
            }

            boolean ignored = false;
            Set<String> names = new HashSet<>();

            if (annotationSupport) {
                annotations = f.getDeclaredAnnotations();//.getAnnotations();

                // field and getter should be treated the same way, if allowed in the class level
                // might not be 100% correct, as the useAttribute as not be applied from annotations yet
                //  && ((javaFieldMapper == null || javaFieldMapper.useAttribute == null) && (fieldMapper.useAttribute == null || fieldMapper.useAttribute))
                // || (javaFieldMapper != null && javaFieldMapper.useAttribute != null && javaFieldMapper.useAttribute)
                // annotations might apply to method only, not the field, so need to get them, regardless using attribute or not
                if (getter != null) {
                    annotations = Stream
                            .concat(Arrays.stream(annotations), Arrays.stream(getter.getDeclaredAnnotations()))
                            .toArray(Annotation[]::new);

                    // no annotations, then try set method
                    if ((annotations == null || annotations.length == 0) && setter != null) {
                        annotations = setter.getDeclaredAnnotations();
                    }
                }

                ca.oson.json.annotation.FieldMapper fieldMapperAnnotation = null;

                for (Annotation annotation : annotations) {
                    if (ignoreField(annotation, ignoreFieldsWithAnnotations)) {
                        ignored = true;
                        break;

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) {
                        fieldMapperAnnotation = (ca.oson.json.annotation.FieldMapper) annotation;
                        if (!(fieldMapperAnnotation.serialize() == BOOLEAN.BOTH
                                || fieldMapperAnnotation.serialize() == BOOLEAN.TRUE)) {
                            fieldMapperAnnotation = null;
                        }

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMappers) {
                        ca.oson.json.annotation.FieldMappers fieldMapperAnnotations = (ca.oson.json.annotation.FieldMappers) annotation;
                        for (ca.oson.json.annotation.FieldMapper ann : fieldMapperAnnotations.value()) {
                            if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.TRUE) {
                                fieldMapperAnnotation = ann;
                                //break;
                            }
                        }

                    } else {
                        // to improve performance, using swith on string
                        switch (annotation.annotationType().getName()) {

                        case "com.fasterxml.jackson.annotation.JsonAnyGetter":
                        case "org.codehaus.jackson.annotate.JsonAnyGetter":
                            fieldMapper.jsonAnyGetter = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnore":
                        case "org.codehaus.jackson.annotate.JsonIgnore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Transient":
                            ignored = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnoreProperties":
                            JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation;
                            if (!jsonIgnoreProperties.allowGetters()) {
                                fieldMapper.ignore = true;
                            } else {
                                fieldMapper.ignore = false;
                                classMapper.jsonIgnoreProperties.remove(name);
                            }
                            break;

                        case "com.google.gson.annotations.Expose":
                            Expose expose = (Expose) annotation;
                            if (!expose.serialize()) {
                                fieldMapper.ignore = true;
                            } else if (exposed != null) {
                                exposed.add(lcfieldName);
                            }
                            break;

                        case "com.google.gson.annotations.Since":
                            Since since = (Since) annotation;
                            fieldMapper.since = since.value();
                            break;

                        case "com.google.gson.annotations.Until":
                            Until until = (Until) annotation;
                            fieldMapper.until = until.value();
                            break;

                        case "com.fasterxml.jackson.annotation.JsonInclude":
                            if (fieldMapper.defaultType == JSON_INCLUDE.NONE) {
                                JsonInclude jsonInclude = (JsonInclude) annotation;

                                switch (jsonInclude.content()) {
                                case ALWAYS:
                                    fieldMapper.defaultType = JSON_INCLUDE.ALWAYS;
                                    break;
                                case NON_NULL:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_ABSENT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_EMPTY:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_EMPTY;
                                    break;
                                case NON_DEFAULT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_DEFAULT;
                                    break;
                                case USE_DEFAULTS:
                                    fieldMapper.defaultType = JSON_INCLUDE.DEFAULT;
                                    break;
                                }
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonRawValue":
                            if (((JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "org.codehaus.jackson.annotate.JsonRawValue":
                            if (((org.codehaus.jackson.annotate.JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonValue":
                        case "org.codehaus.jackson.annotate.JsonValue":
                            fieldMapper.jsonValue = true;
                            break;

                        case "org.junit.Ignore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Enumerated":
                            fieldMapper.enumType = ((Enumerated) annotation).value();
                            break;

                        //                  case "javax.persistence.MapKeyEnumerated":
                        //                     mapper.enumType = ((javax.persistence.MapKeyEnumerated) annotation).value();
                        //                     break;

                        case "javax.validation.constraints.NotNull":
                            fieldMapper.required = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonProperty":
                            JsonProperty jsonProperty = (JsonProperty) annotation;
                            Access access = jsonProperty.access();
                            if (access == Access.WRITE_ONLY) {
                                fieldMapper.ignore = true;
                                break;
                            }

                            if (jsonProperty.required()) {
                                fieldMapper.required = true;
                            }

                            if (jsonProperty.defaultValue() != null
                                    && jsonProperty.defaultValue().length() > 0) {
                                fieldMapper.defaultValue = jsonProperty.defaultValue();
                            }
                            break;

                        case "javax.validation.constraints.Size":
                            Size size = (Size) annotation;
                            if (size.min() > 0) {
                                fieldMapper.min = (long) size.min();
                            }
                            if (size.max() < Integer.MAX_VALUE) {
                                fieldMapper.max = (long) size.max();
                            }
                            break;

                        case "javax.persistence.Column":
                            Column column = (Column) annotation;
                            if (column.length() != 255) {
                                fieldMapper.length = column.length();
                            }
                            if (column.scale() > 0) {
                                fieldMapper.scale = column.scale();
                            }

                            if (column.precision() > 0) {
                                fieldMapper.precision = column.precision();
                            }

                            if (!column.nullable()) {
                                fieldMapper.required = true;
                            }

                            break;
                        }

                        String fname = ObjectUtil.getName(annotation);
                        if (!StringUtil.isEmpty(fname)) {
                            names.add(fname);
                        }
                    }
                }

                // 10. Apply annotations from Oson
                // special name to handle
                if (fieldMapperAnnotation != null) {
                    fieldMapper = overwriteBy(fieldMapper, fieldMapperAnnotation, classMapper);
                    exposed = null;
                }
            }

            if (ignored) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;
            }

            // 11. Apply Java configuration for this particular field
            if (javaFieldMapper != null && javaFieldMapper.isSerializing()) {
                fieldMapper = overwriteBy(fieldMapper, javaFieldMapper);
            }

            if (fieldMapper.ignore != null && fieldMapper.ignore) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;
            }

            // in the ignored list
            if (ObjectUtil.inSet(name, classMapper.jsonIgnoreProperties)) {
                getters.remove(lcfieldName);
                continue;
            }

            if (fieldMapper.jsonAnyGetter != null && fieldMapper.jsonAnyGetter && getter != null) {
                getters.remove(lcfieldName);
                jsonAnyGetterMethods.add(getter);
                continue;
            }

            if (fieldMapper.useField != null && !fieldMapper.useField) {
                // both should not be used, just like ignore
                if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) {
                    getters.remove(lcfieldName);
                }
                continue;
            }

            if (fieldMapper.since != null && fieldMapper.since > getVersion()) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;
            } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;
            }

            //jsonIgnoreProperties

            // handling name now
            boolean jnameFixed = false;
            String json = fieldMapper.json;
            if (StringUtil.isEmpty(json)) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;

            } else if (!json.equals(name)) {
                name = json;
                jnameFixed = true;
            }

            if (!jnameFixed) {
                for (String jsoname : names) {
                    if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) {
                        name = jsoname;
                        jnameFixed = true;
                        break;
                    }
                }
            }

            // only if the name is still the same as the field name
            // format it based on the naming settings
            // otherwise, it is set on purpose
            if (fieldName.equals(name)) {
                name = StringUtil.formatName(name, format);
                jnameFixed = true;
            }

            fieldMapper.java = fieldName;
            fieldMapper.json = name;

            // field valuie
            E value = null;
            try {
                value = (E) f.get(obj);// ObjectUtil.unwraponce(f.get(obj));
            } catch (Exception e) {
            }

            if (value != null) {
                Class vtype = value.getClass();
                if (returnType.isAssignableFrom(vtype)) {
                    returnType = vtype;
                }
            }

            // value from getter
            E getterValue = null;

            if (getter != null) {
                if (fieldMapper.useAttribute == null || fieldMapper.useAttribute) {
                    getterValue = ObjectUtil.getMethodValue(obj, getter);
                    //getterValue = ObjectUtil.unwraponce(getterValue);
                }

                getters.remove(lcfieldName);
            }

            // determine which value to use
            if (getterValue != null) {
                if (getterValue.equals(value) || StringUtil.isEmpty(value)) {
                    value = getterValue;

                } else if (DefaultValue.isDefault(value, returnType)
                        && !DefaultValue.isDefault(getterValue, returnType)) {
                    value = getterValue;
                }
                //               else if (getterValue.toString().length() > value.toString().length()) {
                //                  value = getterValue;
                //               }
            }

            String str;

            FieldData fieldData = new FieldData(obj, f, value, returnType, false, fieldMapper, objectDTO.level,
                    objectDTO.set);

            str = object2Json(fieldData);

            if (fieldMapper.jsonValue != null && fieldMapper.jsonValue) {
                if (fieldMapper.isJsonRawValue()) {
                    return StringUtil.unquote(str, isEscapeHtml());
                } else {
                    return StringUtil.doublequote(str, isEscapeHtml());
                }
            }

            if (StringUtil.isNull(str)) {
                if (fieldMapper.defaultType == JSON_INCLUDE.NON_NULL
                        || fieldMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                        || fieldMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                    continue;

                } else {
                    str = "null";
                }

            } else if (StringUtil.isEmpty(str)) {
                if (fieldMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                        || fieldMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                    continue;
                }

                str = "\"\"";

            } else if (fieldMapper.defaultType == JSON_INCLUDE.NON_DEFAULT
                    && DefaultValue.isDefault(str, returnType)) {
                continue;
            }

            StringBuffer sb = new StringBuffer();
            sb.append(repeatedItem);
            if (fieldMapper.jsonNoName == null || !fieldMapper.jsonNoName) {
                sb.append("\"" + name + "\":" + pretty);
            }
            sb.append(str);
            sb.append(",");

            keyJsonStrings.put(lcfieldName, sb.toString());
            processedNameSet.add(name);
            fieldNames.put(lcfieldName, name.toLowerCase());
        }

        // now process get methods
        for (Entry<String, Method> entry : getters.entrySet()) {
            String lcfieldName = entry.getKey();
            Method getter = entry.getValue();

            if (ignoreModifiers(getter.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                continue;
            }
            if (Modifier.isFinal(getter.getModifiers()) && Modifier.isStatic(getter.getModifiers())) {
                continue;
            }

            String name = getter.getName();
            if (name.substring(3).equalsIgnoreCase(lcfieldName)) {
                name = StringUtil.uncapitalize(name.substring(3));
            }

            // just use field name, even it might not be a field
            String fieldName = name;

            if (processedNameSet.contains(name) || fieldNames.containsKey(lcfieldName)) {
                continue;
            }

            getter.setAccessible(true);

            Method setter = setters.get(lcfieldName);

            // 6. Create a blank field mapper instance
            FieldMapper fieldMapper = new FieldMapper(name, name, valueType);

            Class<?> returnType = getter.getReturnType();

            // 7. get the class mapper of returnType
            ClassMapper fieldClassMapper = getClassMapper(returnType);

            // 8. Classify this field mapper with returnType
            fieldMapper = classifyFieldMapper(fieldMapper, fieldClassMapper);

            // 9. Classify this field mapper
            fieldMapper = classifyFieldMapper(fieldMapper, classMapper);

            FieldMapper javaFieldMapper = getFieldMapper(name, null, valueType);

            boolean ignored = false;
            Set<String> names = new HashSet<>();

            if (annotationSupport) {
                annotations = getter.getDeclaredAnnotations();//.getAnnotations();

                // no annotations, then try set method
                if ((annotations == null || annotations.length == 0) && setter != null) {
                    annotations = setter.getDeclaredAnnotations();
                }

                ca.oson.json.annotation.FieldMapper fieldMapperAnnotation = null;

                for (Annotation annotation : annotations) {
                    if (ignoreField(annotation, ignoreFieldsWithAnnotations)) {
                        ignored = true;
                        break;

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) {
                        fieldMapperAnnotation = (ca.oson.json.annotation.FieldMapper) annotation;
                        if (!(fieldMapperAnnotation.serialize() == BOOLEAN.BOTH
                                || fieldMapperAnnotation.serialize() == BOOLEAN.TRUE)) {
                            fieldMapperAnnotation = null;
                        }

                    } else if (annotation instanceof ca.oson.json.annotation.FieldMappers) {
                        ca.oson.json.annotation.FieldMappers fieldMapperAnnotations = (ca.oson.json.annotation.FieldMappers) annotation;
                        for (ca.oson.json.annotation.FieldMapper ann : fieldMapperAnnotations.value()) {
                            if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.TRUE) {
                                fieldMapperAnnotation = ann;
                                //break;
                            }
                        }

                    } else {
                        // to improve performance, using swith on string
                        switch (annotation.annotationType().getName()) {
                        case "com.fasterxml.jackson.annotation.JsonAnyGetter":
                        case "org.codehaus.jackson.annotate.JsonAnyGetter":
                            fieldMapper.jsonAnyGetter = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnore":
                        case "org.codehaus.jackson.annotate.JsonIgnore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Transient":
                            ignored = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonIgnoreProperties":
                            JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation;
                            if (!jsonIgnoreProperties.allowGetters()) {
                                fieldMapper.ignore = true;
                            } else {
                                fieldMapper.ignore = false;
                                classMapper.jsonIgnoreProperties.remove(name);
                            }
                            break;

                        case "com.google.gson.annotations.Expose":
                            Expose expose = (Expose) annotation;
                            if (!expose.serialize()) {
                                fieldMapper.ignore = true;
                            } else if (exposed != null) {
                                exposed.add(lcfieldName);
                            }
                            break;

                        case "com.google.gson.annotations.Since":
                            Since since = (Since) annotation;
                            fieldMapper.since = since.value();
                            break;

                        case "com.google.gson.annotations.Until":
                            Until until = (Until) annotation;
                            fieldMapper.until = until.value();
                            break;

                        case "com.fasterxml.jackson.annotation.JsonInclude":
                            if (fieldMapper.defaultType == JSON_INCLUDE.NONE) {
                                JsonInclude jsonInclude = (JsonInclude) annotation;

                                switch (jsonInclude.content()) {
                                case ALWAYS:
                                    fieldMapper.defaultType = JSON_INCLUDE.ALWAYS;
                                    break;
                                case NON_NULL:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_ABSENT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_NULL;
                                    break;
                                case NON_EMPTY:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_EMPTY;
                                    break;
                                case NON_DEFAULT:
                                    fieldMapper.defaultType = JSON_INCLUDE.NON_DEFAULT;
                                    break;
                                case USE_DEFAULTS:
                                    fieldMapper.defaultType = JSON_INCLUDE.DEFAULT;
                                    break;
                                }
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonRawValue":
                            if (((JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "org.codehaus.jackson.annotate.JsonRawValue":
                            if (((org.codehaus.jackson.annotate.JsonRawValue) annotation).value()) {
                                fieldMapper.jsonRawValue = true;
                            }
                            break;

                        case "com.fasterxml.jackson.annotation.JsonValue":
                        case "org.codehaus.jackson.annotate.JsonValue":
                            fieldMapper.jsonValue = true;
                            break;

                        case "javax.persistence.Enumerated":
                            fieldMapper.enumType = ((Enumerated) annotation).value();
                            break;

                        //                  case "javax.persistence.MapKeyEnumerated":
                        //                     mapper.enumType = ((javax.persistence.MapKeyEnumerated) annotation).value();
                        //                     break;

                        case "javax.validation.constraints.NotNull":
                            fieldMapper.required = true;
                            break;

                        case "com.fasterxml.jackson.annotation.JsonProperty":
                            JsonProperty jsonProperty = (JsonProperty) annotation;
                            Access access = jsonProperty.access();
                            if (access == Access.WRITE_ONLY) {
                                fieldMapper.ignore = true;
                                break;
                            }

                            if (jsonProperty.required()) {
                                fieldMapper.required = true;
                            }

                            if (jsonProperty.defaultValue() != null
                                    && jsonProperty.defaultValue().length() > 0) {
                                fieldMapper.defaultValue = jsonProperty.defaultValue();
                            }
                            break;

                        case "org.junit.Ignore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.validation.constraints.Size":
                            Size size = (Size) annotation;
                            if (size.min() > 0) {
                                fieldMapper.min = (long) size.min();
                            }
                            if (size.max() < Integer.MAX_VALUE) {
                                fieldMapper.max = (long) size.max();
                            }
                            break;

                        case "javax.persistence.Column":
                            Column column = (Column) annotation;
                            if (column.length() != 255) {
                                fieldMapper.length = column.length();
                            }
                            if (column.scale() > 0) {
                                fieldMapper.scale = column.scale();
                            }

                            if (column.precision() > 0) {
                                fieldMapper.precision = column.precision();
                            }

                            if (!column.nullable()) {
                                fieldMapper.required = true;
                            }

                            break;
                        }

                        String fname = ObjectUtil.getName(annotation);
                        if (fname != null) {
                            names.add(fname);
                        }
                    }
                }

                // 10. Apply annotations from Oson
                // special name to handle
                if (fieldMapperAnnotation != null) {
                    fieldMapper = overwriteBy(fieldMapper, fieldMapperAnnotation, classMapper);
                    exposed = null;
                }
            }

            if (ignored) {
                continue;
            }

            // 11. Apply Java configuration for this particular field
            if (javaFieldMapper != null && javaFieldMapper.isSerializing()) {
                fieldMapper = overwriteBy(fieldMapper, javaFieldMapper);
            }

            if (fieldMapper.ignore != null && fieldMapper.ignore) {
                continue;
            }

            // in the ignored list
            if (ObjectUtil.inSet(name, classMapper.jsonIgnoreProperties)) {
                continue;
            }

            if (fieldMapper.jsonAnyGetter != null && fieldMapper.jsonAnyGetter) {
                jsonAnyGetterMethods.add(getter);
                continue;
            }

            if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) {
                continue;
            }

            if (fieldMapper.since != null && fieldMapper.since > getVersion()) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;
            } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;
            }

            // handling name now
            boolean jnameFixed = false;
            String json = fieldMapper.json;
            if (StringUtil.isEmpty(json)) {
                if (getter != null) {
                    getters.remove(lcfieldName);
                }
                continue;

            } else if (!json.equals(name)) {
                name = json;
                jnameFixed = true;
            }

            if (!jnameFixed) {
                for (String jsoname : names) {
                    if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) {
                        name = jsoname;
                        jnameFixed = true;
                        break;
                    }
                }
            }

            // only if the name is still the same as the field name
            // format it based on the naming settings
            // otherwise, it is set on purpose
            if (fieldName.equals(name)) {
                name = StringUtil.formatName(name, format);
                jnameFixed = true;
            }

            fieldMapper.java = fieldName;
            fieldMapper.json = name;

            // get value
            E value = ObjectUtil.getMethodValue(obj, getter);

            if (fieldMapper.jsonValue != null && fieldMapper.jsonValue) {
                if (value != null) {
                    if (fieldMapper.isJsonRawValue()) {
                        return value.toString();
                    } else {
                        return StringUtil.doublequote(value, isEscapeHtml());
                    }
                }
            }

            if (returnType == Class.class) {
                if (value != null && returnType != value.getClass()) {
                    returnType = value.getClass();
                } else {
                    continue;
                }
            }

            String str = null;

            //if (returnType != valueType) {
            FieldData fieldData = new FieldData(obj, null, value, returnType, false, fieldMapper,
                    objectDTO.level, objectDTO.set);
            objectDTO.getter = getter;
            str = object2Json(fieldData);
            //}

            if (StringUtil.isNull(str)) {
                if (fieldMapper.defaultType == JSON_INCLUDE.NON_NULL
                        || fieldMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                        || fieldMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                    continue;

                } else {
                    str = "null";
                }

            } else if (StringUtil.isEmpty(str)) {
                if (fieldMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                        || fieldMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                    continue;
                }

                str = "null";

            } else if (fieldMapper.defaultType == JSON_INCLUDE.NON_DEFAULT
                    && DefaultValue.isDefault(str, returnType)) {
                continue;
            }

            StringBuffer sb = new StringBuffer();
            sb.append(repeatedItem);
            if (fieldMapper.jsonNoName == null || !fieldMapper.jsonNoName) {
                sb.append("\"" + name + "\":" + pretty);
            }
            sb.append(str);
            sb.append(",");

            keyJsonStrings.put(lcfieldName, sb.toString());
            processedNameSet.add(name);
            fieldNames.put(lcfieldName, name.toLowerCase());
        }

        // handle @JsonAnyGetter
        if (annotationSupport) {
            for (Entry<String, Method> entry : otherMethods.entrySet()) {
                Method method = entry.getValue();
                if (ignoreModifiers(method.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                    continue;
                }

                for (Annotation annotation : method.getAnnotations()) {
                    if (ignoreField(annotation, ignoreFieldsWithAnnotations)) {
                        continue;
                    }

                    if (annotation instanceof JsonValue
                            || annotation instanceof org.codehaus.jackson.annotate.JsonValue) {
                        Object mvalue = ObjectUtil.getMethodValue(obj, method);
                        if (mvalue != null) {
                            return StringUtil.doublequote(mvalue, isEscapeHtml());
                        }

                    } else if (annotation instanceof JsonAnyGetter
                            || annotation instanceof org.codehaus.jackson.annotate.JsonAnyGetter
                            || annotation instanceof ca.oson.json.annotation.FieldMapper) {

                        if (annotation instanceof ca.oson.json.annotation.FieldMapper) {
                            ca.oson.json.annotation.FieldMapper fieldMapper = (ca.oson.json.annotation.FieldMapper) annotation;

                            if (fieldMapper.jsonAnyGetter() == BOOLEAN.FALSE) {
                                continue;
                            }
                        }

                        jsonAnyGetterMethods.add(method);
                    }
                }
            }
        }

        for (Method method : jsonAnyGetterMethods) {
            if (method != null) {
                Object allValues = ObjectUtil.getMethodValue(obj, method);

                if (allValues != null && allValues instanceof Map) {
                    Map<String, Object> map = (Map) allValues;
                    String str;
                    for (String name : map.keySet()) {
                        Object value = map.get(name);

                        // java to json, check if this name is allowed or changed
                        name = java2Json(name);

                        if (!StringUtil.isEmpty(name)) {

                            FieldData newFieldData = new FieldData(value, value.getClass(), false,
                                    objectDTO.level, objectDTO.set);
                            newFieldData.defaultType = classMapper.defaultType;
                            str = object2Json(newFieldData);

                            if (StringUtil.isNull(str)) {
                                if (classMapper.defaultType == JSON_INCLUDE.NON_NULL
                                        || classMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                                        || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                                    continue;

                                } else {
                                    str = "null";
                                }

                            } else if (StringUtil.isEmpty(str)) {
                                if (classMapper.defaultType == JSON_INCLUDE.NON_EMPTY
                                        || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                                    continue;
                                }

                                str = "null";

                            } else if (DefaultValue.isDefault(str, value.getClass())) {
                                if (classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) {
                                    continue;
                                }
                            }

                            StringBuffer sb = new StringBuffer();
                            sb.append(repeatedItem);
                            sb.append("\"" + name + "\":" + pretty);
                            sb.append(str);
                            sb.append(",");
                            keyJsonStrings.put(name, sb.toString());
                        }
                    }
                }
            }
        }

        int size = keyJsonStrings.size();
        if (size == 0) {
            return "{}"; // ""

        } else {
            String includeClassType = "";
            if (classMapper.includeClassTypeInJson) { //getIncludeClassTypeInJson()
                includeClassType = repeatedItem + "\"@class\":" + pretty + "\"" + valueType.getName() + "\",";
            }

            if (exposed != null && exposed.size() > 0) {
                Map<String, String> map = new LinkedHashMap<>();

                for (String key : keyJsonStrings.keySet()) {
                    if (exposed.contains(key)) {
                        map.put(key, keyJsonStrings.get(key));
                    }
                }

                keyJsonStrings = map;
            }

            if (keyJsonStrings.size() == 1 && this.isValueOnly()) {
                for (Map.Entry<String, String> entry : keyJsonStrings.entrySet()) {
                    if (entry.getKey().toLowerCase().equals("value")) {
                        String value = entry.getValue();
                        String[] values = value.split(":");
                        value = null;
                        if (values.length == 1) {
                            value = values[0];
                        } else if (values.length == 2) {
                            value = values[1];
                        }
                        if (value != null && value.length() > 1) {
                            return value.substring(0, value.length() - 1);
                        }
                    }
                }
            }

            // based on sorting requirements
            StringBuffer sb = new StringBuffer();
            if (classMapper.propertyOrders != null) {
                for (String property : classMapper.propertyOrders) {
                    property = property.toLowerCase();
                    String jsonText = keyJsonStrings.get(property);
                    if (jsonText != null) {
                        sb.append(jsonText);
                        keyJsonStrings.remove(property);
                    } else {
                        property = fieldNames.get(property);
                        if (property != null && keyJsonStrings.containsKey(property)) {
                            sb.append(keyJsonStrings.get(property));
                            keyJsonStrings.remove(property);
                        }
                    }
                }
            }

            List<String> properties = new ArrayList(keyJsonStrings.keySet());
            if (classMapper.orderByKeyAndProperties) {
                Collections.sort(properties);
            }

            for (String property : properties) {
                sb.append(keyJsonStrings.get(property));
            }

            String text = sb.toString();
            size = text.length();
            if (size == 0) {
                return "{}";
            } else {
                return "{" + includeClassType + text.substring(0, size - 1) + repeated + "}";
            }
        }

    } catch (IllegalArgumentException | SecurityException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
        // } catch (InvocationTargetException e) {
    }
}

From source file:ca.oson.json.Oson.java

<T> T newInstance(Map<String, Object> map, Class<T> valueType) {
    InstanceCreator creator = getTypeAdapter(valueType);

    if (creator != null) {
        return (T) creator.createInstance(valueType);
    }/*from  w  w  w  . ja va  2s  .c o  m*/

    T obj = null;

    if (valueType != null) {
        obj = (T) getDefaultValue(valueType);
        if (obj != null) {
            return obj;
        }
    }

    if (map == null) {
        return null;
    }

    // @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = As.PROPERTY, property = "@class")
    //@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "@class")
    String JsonClassType = null;

    if (valueType != null) {
        if (getAnnotationSupport()) {
            for (Annotation annotation : valueType.getAnnotations()) {
                if (annotation instanceof JsonTypeInfo) {
                    JsonTypeInfo jsonTypeInfo = (JsonTypeInfo) annotation;
                    JsonTypeInfo.Id use = jsonTypeInfo.use();
                    JsonTypeInfo.As as = jsonTypeInfo.include();
                    if ((use == JsonTypeInfo.Id.MINIMAL_CLASS || use == JsonTypeInfo.Id.CLASS)
                            && as == As.PROPERTY) {
                        JsonClassType = jsonTypeInfo.property();
                    }
                }
            }
        }
    }
    if (JsonClassType == null) {
        JsonClassType = getJsonClassType();
    }

    String className = null;
    if (map.containsKey(JsonClassType)) {
        className = map.get(JsonClassType).toString();
    }

    Class<T> classType = getClassType(className);

    //  && (valueType == null || valueType.isAssignableFrom(classType) || Map.class.isAssignableFrom(valueType))
    if (classType != null) {
        valueType = classType;
    }

    if (valueType == null) {
        return (T) map; // or null, which is better?
    }

    Constructor<?>[] constructors = null;

    Class implClass = null;
    if (valueType.isInterface() || Modifier.isAbstract(valueType.getModifiers())) {
        implClass = DeSerializerUtil.implementingClass(valueType.getName());
    }

    if (implClass != null) {
        constructors = implClass.getDeclaredConstructors();
    } else {
        constructors = valueType.getDeclaredConstructors();//.getConstructors();
    }

    Object singleMapValue = null;
    Class singleMapValueType = null;
    if (map.size() == 1) {
        singleMapValue = map.get(valueType.getName());

        if (singleMapValue != null) {
            singleMapValueType = singleMapValue.getClass();

            if (singleMapValueType == String.class) {
                singleMapValue = StringUtil.unquote(singleMapValue.toString(), isEscapeHtml());
            }

            try {
                if (valueType == Locale.class) {
                    Constructor constructor = null;
                    String[] parts = ((String) singleMapValue).split("_");
                    if (parts.length == 1) {
                        constructor = valueType.getConstructor(String.class);
                        constructor.setAccessible(true);
                        obj = (T) constructor.newInstance(singleMapValue);
                    } else if (parts.length == 2) {
                        constructor = valueType.getConstructor(String.class, String.class);
                        constructor.setAccessible(true);
                        obj = (T) constructor.newInstance(parts);
                    } else if (parts.length == 3) {
                        constructor = valueType.getConstructor(String.class, String.class, String.class);
                        constructor.setAccessible(true);
                        obj = (T) constructor.newInstance(parts);
                    }

                    if (obj != null) {
                        return obj;
                    }
                }
            } catch (Exception e) {
            }

            Map<Class, Constructor> cmaps = new HashMap<>();
            for (Constructor constructor : constructors) {
                //Class[] parameterTypes = constructor.getParameterTypes();

                int parameterCount = constructor.getParameterCount();
                if (parameterCount == 1) {

                    Class[] types = constructor.getParameterTypes();

                    cmaps.put(types[0], constructor);
                }
            }

            if (cmaps.size() > 0) {
                Constructor constructor = null;

                if ((cmaps.containsKey(Boolean.class) || cmaps.containsKey(boolean.class))
                        && BooleanUtil.isBoolean(singleMapValue.toString())) {
                    constructor = cmaps.get(Boolean.class);
                    if (constructor == null) {
                        constructor = cmaps.get(boolean.class);
                    }
                    if (constructor != null) {
                        try {
                            constructor.setAccessible(true);
                            obj = (T) constructor
                                    .newInstance(BooleanUtil.string2Boolean(singleMapValue.toString()));

                            if (obj != null) {
                                return obj;
                            }
                        } catch (Exception e) {
                        }
                    }

                } else if (StringUtil.isNumeric(singleMapValue.toString())) {

                    Class[] classes = new Class[] { int.class, Integer.class, long.class, Long.class,
                            double.class, Double.class, Byte.class, byte.class, Short.class, short.class,
                            Float.class, float.class, BigDecimal.class, BigInteger.class, AtomicInteger.class,
                            AtomicLong.class, Number.class };

                    for (Class cls : classes) {
                        constructor = cmaps.get(cls);

                        if (constructor != null) {
                            try {
                                obj = (T) constructor.newInstance(NumberUtil.getNumber(singleMapValue, cls));

                                if (obj != null) {
                                    return obj;
                                }
                            } catch (Exception e) {
                            }
                        }
                    }

                } else if (StringUtil.isArrayOrList(singleMapValue.toString())
                        || singleMapValue.getClass().isArray()
                        || Collection.class.isAssignableFrom(singleMapValue.getClass())) {
                    for (Entry<Class, Constructor> entry : cmaps.entrySet()) {
                        Class cls = entry.getKey();
                        constructor = entry.getValue();

                        if (cls.isArray() || Collection.class.isAssignableFrom(cls)) {
                            Object listObject = null;
                            if (singleMapValue instanceof String) {
                                JSONArray objArray = new JSONArray(singleMapValue.toString());
                                listObject = (List) fromJsonMap(objArray);
                            } else {
                                listObject = singleMapValue;
                            }

                            FieldData objectDTO = new FieldData(listObject, cls, true);
                            listObject = json2Object(objectDTO);
                            if (listObject != null) {
                                try {
                                    obj = (T) constructor.newInstance(listObject);
                                    if (obj != null) {
                                        return obj;
                                    }
                                } catch (Exception e) {
                                }
                            }
                        }

                    }

                }

                for (Entry<Class, Constructor> entry : cmaps.entrySet()) {
                    Class cls = entry.getKey();
                    constructor = entry.getValue();
                    try {
                        obj = (T) constructor.newInstance(singleMapValue);
                        if (obj != null) {
                            return obj;
                        }
                    } catch (Exception e) {
                    }
                }

            }

        }
    }

    if (implClass != null) {
        valueType = implClass;
    }

    try {
        obj = valueType.newInstance();

        if (obj != null) {
            return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
        }

    } catch (InstantiationException | IllegalAccessException e) {
        //e.printStackTrace();
    }

    ///*
    for (Constructor constructor : constructors) {
        //Class[] parameterTypes = constructor.getParameterTypes();

        int parameterCount = constructor.getParameterCount();
        if (parameterCount > 0) {
            constructor.setAccessible(true);

            Annotation[] annotations = constructor.getDeclaredAnnotations(); // getAnnotations();

            for (Annotation annotation : annotations) {
                boolean isJsonCreator = false;
                if (annotation instanceof JsonCreator) {
                    isJsonCreator = true;
                } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) {
                    ca.oson.json.annotation.FieldMapper fieldMapper = (ca.oson.json.annotation.FieldMapper) annotation;

                    if (fieldMapper.jsonCreator() == BOOLEAN.TRUE) {
                        isJsonCreator = true;
                    }
                }

                if (isJsonCreator) {
                    Parameter[] parameters = constructor.getParameters();
                    String[] parameterNames = ObjectUtil.getParameterNames(parameters);

                    //parameterCount = parameters.length;
                    Object[] parameterValues = new Object[parameterCount];
                    int i = 0;
                    for (String parameterName : parameterNames) {
                        parameterValues[i] = getParameterValue(map, valueType, parameterName,
                                parameters[i].getType());
                        i++;
                    }

                    try {
                        obj = (T) constructor.newInstance(parameterValues);

                        if (obj != null) {
                            return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
                        }

                    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                            | InvocationTargetException e) {
                        //e.printStackTrace();
                    }
                }
            }

        } else {
            try {
                constructor.setAccessible(true);
                obj = (T) constructor.newInstance();

                if (obj != null) {
                    return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
                }

            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException e) {
                //e.printStackTrace();
            }

        }
    }
    //*/

    // try again
    for (Constructor constructor : constructors) {
        int parameterCount = constructor.getParameterCount();
        if (parameterCount > 0) {
            constructor.setAccessible(true);

            try {
                List<String> parameterNames = ObjectUtil.getParameterNames(constructor);

                if (parameterNames != null && parameterNames.size() > 0) {
                    Class[] parameterTypes = constructor.getParameterTypes();

                    int length = parameterTypes.length;
                    if (length == parameterNames.size()) {
                        Object[] parameterValues = new Object[length];
                        Object parameterValue;
                        for (int i = 0; i < length; i++) {
                            parameterValues[i] = getParameterValue(map, valueType, parameterNames.get(i),
                                    parameterTypes[i]);
                        }

                        try {
                            obj = (T) constructor.newInstance(parameterValues);
                            if (obj != null) {
                                return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
                            }

                        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                                | InvocationTargetException e) {
                            //e.printStackTrace();
                        }

                    }
                }

            } catch (IOException e1) {
                // e1.printStackTrace();
            }
        }
    }

    // try more
    for (Constructor constructor : constructors) {
        int parameterCount = constructor.getParameterCount();
        if (parameterCount > 0) {
            constructor.setAccessible(true);

            Class[] parameterTypes = constructor.getParameterTypes();
            List<String> parameterNames;
            try {
                parameterNames = ObjectUtil.getParameterNames(constructor);

                if (parameterNames != null) {
                    int length = parameterTypes.length;

                    if (length > parameterNames.size()) {
                        length = parameterNames.size();
                    }

                    Object[] parameterValues = new Object[length];
                    for (int i = 0; i < length; i++) {
                        parameterValues[i] = getParameterValue(map, valueType, parameterNames.get(i),
                                parameterTypes[i]);
                    }

                    obj = (T) constructor.newInstance(parameterValues);
                    if (obj != null) {
                        return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
                    }
                }

            } catch (InstantiationException | IllegalAccessException | IllegalArgumentException
                    | InvocationTargetException | IOException e) {
                //e.printStackTrace();
            }
        }
    }

    // try more
    try {
        Method[] methods = valueType.getMethods(); // .getMethod("getInstance", null);

        List<Method> methodList = new ArrayList<>();

        if (methods != null) {
            for (Method method : methods) {
                String methodName = method.getName();

                if (methodName.equals("getInstance") || methodName.equals("newInstance")
                        || methodName.equals("createInstance") || methodName.equals("factory")) {
                    Class returnType = method.getReturnType();

                    if (valueType.isAssignableFrom(returnType) && Modifier.isStatic(method.getModifiers())) {
                        int parameterCount = method.getParameterCount();
                        if (parameterCount == 0) {
                            try {
                                obj = ObjectUtil.getMethodValue(null, method);
                                if (obj != null) {
                                    return setSingleMapValue(obj, valueType, singleMapValue,
                                            singleMapValueType);
                                }

                            } catch (IllegalArgumentException e) {
                                // TODO Auto-generated catch block
                                //e.printStackTrace();
                            }

                        } else {
                            methodList.add(method);
                        }

                    }
                }
            }

            for (Method method : methodList) {
                try {
                    int parameterCount = method.getParameterCount();
                    Object[] parameterValues = new Object[parameterCount];
                    Object parameterValue;
                    int i = 0;
                    Class[] parameterTypes = method.getParameterTypes();

                    String[] parameterNames = ObjectUtil.getParameterNames(method);

                    if (parameterCount == 1 && valueType != null && singleMapValue != null
                            && singleMapValueType != null) {

                        if (ObjectUtil.isSameDataType(parameterTypes[0], singleMapValueType)) {
                            try {
                                obj = ObjectUtil.getMethodValue(null, method, singleMapValue);
                                if (obj != null) {
                                    return obj;
                                }

                            } catch (IllegalArgumentException ex) {
                                //ex.printStackTrace();
                            }

                        }

                    } else if (parameterNames != null && parameterNames.length == parameterCount) {
                        for (String parameterName : ObjectUtil.getParameterNames(method)) {
                            parameterValues[i] = getParameterValue(map, valueType, parameterName,
                                    parameterTypes[i]);
                            i++;
                        }

                    } else {
                        // try annotation
                        Parameter[] parameters = method.getParameters();
                        parameterNames = ObjectUtil.getParameterNames(parameters);
                        parameterCount = parameters.length;
                        parameterValues = new Object[parameterCount];
                        i = 0;
                        for (String parameterName : parameterNames) {
                            parameterValues[i] = getParameterValue(map, valueType, parameterName,
                                    parameterTypes[i]);
                            i++;
                        }
                    }

                    obj = ObjectUtil.getMethodValue(null, method, parameterValues);

                    if (obj != null) {
                        return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
                    }

                } catch (IOException | IllegalArgumentException e) {
                    //e.printStackTrace();
                }
            }

        }

    } catch (SecurityException e) {
        // e.printStackTrace();
    }

    // try all static methods, if the return type is correct, get it as the final object
    Method[] methods = valueType.getDeclaredMethods();
    for (Method method : methods) {
        if (Modifier.isStatic(method.getModifiers())) {
            Class returnType = method.getReturnType();

            if (valueType.isAssignableFrom(returnType)) {
                try {
                    Object[] parameterValues = null;

                    int parameterCount = method.getParameterCount();
                    if (parameterCount > 0) {
                        if (parameterCount == 1 && map.size() == 1 && singleMapValue != null
                                && singleMapValueType != null) {
                            if (ObjectUtil.isSameDataType(method.getParameterTypes()[0], singleMapValueType)) {
                                obj = ObjectUtil.getMethodValue(null, method, singleMapValueType);
                                if (obj != null) {
                                    return obj;
                                }
                            }
                        }

                        parameterValues = new Object[parameterCount];
                        Object parameterValue;
                        int i = 0;
                        Class[] parameterTypes = method.getParameterTypes();

                        String[] parameterNames = ObjectUtil.getParameterNames(method);
                        if (parameterNames != null && parameterNames.length == parameterCount) {
                            for (String parameterName : ObjectUtil.getParameterNames(method)) {
                                parameterValues[i] = getParameterValue(map, valueType, parameterName,
                                        parameterTypes[i]);
                                i++;
                            }

                        } else {
                            // try annotation
                            Parameter[] parameters = method.getParameters();
                            parameterNames = ObjectUtil.getParameterNames(parameters);
                            parameterCount = parameters.length;
                            parameterValues = new Object[parameterCount];
                            i = 0;
                            for (String parameterName : parameterNames) {
                                parameterValues[i] = getParameterValue(map, valueType, parameterName,
                                        parameterTypes[i]);
                                i++;
                            }
                        }
                    }

                    obj = ObjectUtil.getMethodValue(obj, method, parameterValues);
                    if (obj != null) {
                        return setSingleMapValue(obj, valueType, singleMapValue, singleMapValueType);
                    }

                } catch (IOException | IllegalArgumentException e) {
                    //e.printStackTrace();
                }

            }
        }

    }

    return null;
}