Example usage for java.lang.reflect Method isAnnotationPresent

List of usage examples for java.lang.reflect Method isAnnotationPresent

Introduction

In this page you can find the example usage for java.lang.reflect Method isAnnotationPresent.

Prototype

@Override
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 

Source Link

Usage

From source file:edu.ku.brc.specify.tools.datamodelgenerator.DatamodelGenerator.java

/**
 * @param className/*from ww  w  .  j  ava2 s  .  c o m*/
 * @param tableList
 */
@SuppressWarnings("cast")
protected void processClass(final String className, final List<Table> tableList) {
    try {
        Class<?> classObj = Class.forName(packageName + "." + className);

        Table table = null;
        String tableName = null;

        if (classObj.isAnnotationPresent(javax.persistence.Table.class)) {
            Vector<TableIndex> indexes = new Vector<TableIndex>();

            javax.persistence.Table tableAnno = (javax.persistence.Table) classObj
                    .getAnnotation(javax.persistence.Table.class);
            tableName = tableAnno.name();

            org.hibernate.annotations.Table hiberTableAnno = (org.hibernate.annotations.Table) classObj
                    .getAnnotation(org.hibernate.annotations.Table.class);
            if (hiberTableAnno != null) {
                //System.out.println("Table Indexes: ");
                for (Index index : hiberTableAnno.indexes()) {
                    //System.out.println("  "+index.name() + "  "+ index.columnNames());
                    indexes.add(new TableIndex(index.name(), index.columnNames()));
                }
            }

            table = createTable(packageName + "." + className, tableName);
            if (includeDesc) {
                table.setDesc(getTableDesc(tableName));
                table.setNameDesc(getTableNameDesc(tableName));
            }
            table.setIndexes(indexes);
            tableList.add(table);
        }

        if (table != null) {
            boolean isLob = false;
            for (Method method : classObj.getMethods()) {
                String methodName = method.getName();
                if (!methodName.startsWith("get")) {
                    continue;
                }

                if (DEBUG) {
                    System.out.println(className + " " + method.getName());
                }

                Type type = method.getGenericReturnType();
                Class<?> typeClass;
                if (type instanceof Class<?>) {
                    typeClass = (Class<?>) type;

                } else if (type instanceof ParameterizedType) {
                    typeClass = null;
                    for (Type t : ((ParameterizedType) type).getActualTypeArguments()) {
                        if (t instanceof Class<?>) {
                            typeClass = (Class<?>) t;
                        }
                    }
                } else {
                    if (!method.getName().equals("getDataObj") && !method.getName().equals("getTreeRootNode")) {
                        log.warn("Not handled: " + type);
                    }
                    typeClass = null;
                }

                // rods 07/10/08 - Used to skip all relationships that point to themselves
                // that works now and is needed.
                if (typeClass == null || typeClass == AttributeIFace.class
                        || typeClass == PickListItemIFace.class || typeClass == RecordSetItemIFace.class) {
                    continue;
                }

                String thisSideName = getFieldNameFromMethod(method);

                if (method.isAnnotationPresent(javax.persistence.Lob.class)) {
                    isLob = true;
                }

                if (method.isAnnotationPresent(javax.persistence.Column.class)) {
                    if (method.isAnnotationPresent(javax.persistence.Id.class)) {
                        table.addId(createId(method, (javax.persistence.Column) method
                                .getAnnotation(javax.persistence.Column.class)));
                    } else {
                        Field field = createField(method,
                                (javax.persistence.Column) method.getAnnotation(javax.persistence.Column.class),
                                isLob);
                        if (includeDesc) {
                            field.setDesc(getFieldDesc(tableName, field.getName()));
                            field.setNameDesc(getFieldNameDesc(tableName, field.getName()));
                        }

                        if (typeClass == java.util.Calendar.class) {
                            String mName = method.getName() + "Precision";
                            for (Method mthd : classObj.getMethods()) {
                                if (mthd.getName().equals(mName)) {
                                    field.setPartialDate(true);
                                    field.setDatePrecisionName(field.getName() + "Precision");
                                    break;
                                }
                            }
                        }
                        table.addField(field);
                    }

                } else if (method.isAnnotationPresent(javax.persistence.ManyToOne.class)) {
                    javax.persistence.ManyToOne oneToMany = (javax.persistence.ManyToOne) method
                            .getAnnotation(javax.persistence.ManyToOne.class);

                    boolean isSave = false;
                    for (CascadeType ct : oneToMany.cascade()) {
                        if (ct == CascadeType.ALL || ct == CascadeType.PERSIST) {
                            isSave = true;
                        }
                    }
                    isSave = !isSave ? isOKToSave(method) : isSave;

                    String otherSideName = getRightSideForManyToOne(classObj, typeClass, thisSideName);

                    javax.persistence.JoinColumn join = method
                            .isAnnotationPresent(javax.persistence.JoinColumn.class)
                                    ? (javax.persistence.JoinColumn) method
                                            .getAnnotation(javax.persistence.JoinColumn.class)
                                    : null;
                    if (join != null) {
                        //String othersideName = typeClass == null ? "" : getOthersideName(classObj, typeClass, thisSideName, RelType.OneToMany);
                        Relationship rel = createRelationship(method, "many-to-one", join, otherSideName,
                                join != null ? !join.nullable() : false);
                        table.addRelationship(rel);
                        rel.setSave(isSave);

                        if (includeDesc) {
                            rel.setDesc(getFieldDesc(tableName, rel.getRelationshipName()));
                            rel.setNameDesc(getFieldNameDesc(tableName, rel.getRelationshipName()));
                        }

                    } else {
                        log.error("No Join!");
                    }

                } else if (method.isAnnotationPresent(javax.persistence.ManyToMany.class)) {
                    javax.persistence.ManyToMany manyToMany = method
                            .getAnnotation(javax.persistence.ManyToMany.class);

                    String othersideName = manyToMany.mappedBy();
                    if (StringUtils.isEmpty(othersideName)) {
                        othersideName = getRightSideForManyToMany(classObj, typeClass,
                                getFieldNameFromMethod(method));
                    }

                    boolean isSave = false;
                    for (CascadeType ct : manyToMany.cascade()) {
                        if (ct == CascadeType.ALL || ct == CascadeType.PERSIST) {
                            isSave = true;
                        }
                    }
                    isSave = !isSave ? isOKToSave(method) : isSave;

                    javax.persistence.JoinColumn join = method
                            .isAnnotationPresent(javax.persistence.JoinColumn.class)
                                    ? (javax.persistence.JoinColumn) method
                                            .getAnnotation(javax.persistence.JoinColumn.class)
                                    : null;
                    Relationship rel = createRelationship(method, "many-to-many", join, othersideName,
                            join != null ? !join.nullable() : false);
                    rel.setLikeManyToOne(table.getIsLikeManyToOne(rel.getRelationshipName()));
                    rel.setSave(isSave);

                    table.addRelationship(rel);
                    if (includeDesc) {
                        rel.setDesc(getFieldDesc(tableName, rel.getRelationshipName()));
                        rel.setNameDesc(getFieldNameDesc(tableName, rel.getRelationshipName()));
                    }

                    javax.persistence.JoinTable joinTable = method
                            .getAnnotation(javax.persistence.JoinTable.class);
                    if (joinTable != null) {
                        rel.setJoinTableName(joinTable.name());
                    }

                } else if (method.isAnnotationPresent(javax.persistence.OneToMany.class)) {
                    javax.persistence.OneToMany oneToMany = (javax.persistence.OneToMany) method
                            .getAnnotation(javax.persistence.OneToMany.class);

                    String othersideName = oneToMany.mappedBy();
                    if (StringUtils.isEmpty(othersideName)) {
                        // This Should never happen
                        othersideName = getRightSideForOneToMany(classObj, typeClass, oneToMany.mappedBy());
                    }

                    boolean isSave = false;
                    for (CascadeType ct : oneToMany.cascade()) {
                        if (ct == CascadeType.ALL || ct == CascadeType.PERSIST) {
                            isSave = true;
                        }
                    }
                    isSave = !isSave ? isOKToSave(method) : isSave;

                    javax.persistence.JoinColumn join = method
                            .isAnnotationPresent(javax.persistence.JoinColumn.class)
                                    ? (javax.persistence.JoinColumn) method
                                            .getAnnotation(javax.persistence.JoinColumn.class)
                                    : null;
                    Relationship rel = createRelationship(method, "one-to-many", join, othersideName,
                            join != null ? !join.nullable() : false);
                    rel.setLikeManyToOne(table.getIsLikeManyToOne(rel.getRelationshipName()));
                    rel.setSave(isSave);
                    table.addRelationship(rel);
                    if (includeDesc) {
                        rel.setDesc(getFieldDesc(tableName, rel.getRelationshipName()));
                        rel.setNameDesc(getFieldNameDesc(tableName, rel.getRelationshipName()));
                    }

                } else if (method.isAnnotationPresent(javax.persistence.OneToOne.class)) {
                    javax.persistence.OneToOne oneToOne = (javax.persistence.OneToOne) method
                            .getAnnotation(javax.persistence.OneToOne.class);
                    String leftSideVarName = getFieldNameFromMethod(method);
                    boolean isMappedBy = true;
                    String othersideName = oneToOne.mappedBy();
                    if (StringUtils.isEmpty(othersideName)) {
                        isMappedBy = false;
                        othersideName = getRightSideForOneToOne(classObj, typeClass, leftSideVarName,
                                othersideName, isMappedBy);
                    }

                    boolean isSave = false;
                    for (CascadeType ct : oneToOne.cascade()) {
                        if (ct == CascadeType.ALL || ct == CascadeType.PERSIST) {
                            isSave = true;
                        }
                    }
                    isSave = !isSave ? isOKToSave(method) : isSave;

                    javax.persistence.JoinColumn join = method
                            .isAnnotationPresent(javax.persistence.JoinColumn.class)
                                    ? (javax.persistence.JoinColumn) method
                                            .getAnnotation(javax.persistence.JoinColumn.class)
                                    : null;
                    Relationship rel = createRelationship(method, "one-to-one", join, othersideName,
                            join != null ? !join.nullable() : false);
                    rel.setSave(isSave);
                    table.addRelationship(rel);
                    if (includeDesc) {
                        rel.setDesc(getFieldDesc(tableName, rel.getRelationshipName()));
                        rel.setNameDesc(getFieldNameDesc(tableName, rel.getRelationshipName()));
                    }

                }
                isLob = false;
            }

            // This updates each field as to whether it is an index
            table.updateIndexFields();
        }

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

From source file:org.b3log.latke.servlet.RequestProcessors.java

/**
 * Invokes a processor method with the specified request URI, method and context.
 *
 * @param requestURI the specified request URI
 * @param contextPath the specified context path
 * @param method the specified method/*from ww w . j  a v  a 2  s .com*/
 * @param context the specified context
 * @return invoke result, returns {@code null} if invoke failed
 */
public static Object invoke(final String requestURI, final String contextPath, final String method,
        final HTTPRequestContext context) {
    final ProcessorMethod processMethod = getProcessorMethod(requestURI, contextPath, method);

    if (null == processMethod) {
        LOGGER.log(Level.WARNING, "Can not find process method for request[requestURI={0}, method={1}]",
                new Object[] { requestURI, method });
        return null;
    }

    final Method processorMethod = processMethod.getProcessorMethod();
    final Class<?> processorClass = processMethod.getProcessorClass();
    Object processorObject = processors.get(processorMethod);

    try {
        if (null == processorObject) {
            final Object instance = processorClass.newInstance();

            processors.put(processorMethod, instance);
            processorObject = instance;
        }

        final Map<String, Object> args = new LinkedHashMap<String, Object>();

        final Class<?>[] parameterTypes = processorMethod.getParameterTypes();
        final String[] parameterName = processMethod.getMethodParamNames();

        // TODO need Optimization
        String relativeRequestURI = requestURI;

        if (contextPath != null && contextPath.length() > 1) {
            relativeRequestURI = requestURI.substring(contextPath.length());
        }
        final Map<String, String> pathVariableValueMap = processMethod.pathVariableValueMap(relativeRequestURI);

        final List<AbstractHTTPResponseRenderer> rendererList = new ArrayList<AbstractHTTPResponseRenderer>();

        for (int i = 0; i < parameterTypes.length; i++) {
            final Class<?> paramClass = parameterTypes[i];

            if (paramClass.equals(HTTPRequestContext.class)) {
                args.put(parameterName[i], context);
            } else if (paramClass.equals(HttpServletRequest.class)) {
                args.put(parameterName[i], context.getRequest());
            } else if (paramClass.equals(HttpServletResponse.class)) {
                args.put(parameterName[i], context.getResponse());
            } else if (AbstractHTTPResponseRenderer.class.isAssignableFrom(paramClass)
                    && !paramClass.equals(AbstractHTTPResponseRenderer.class)) {
                final AbstractHTTPResponseRenderer ins = (AbstractHTTPResponseRenderer) paramClass
                        .newInstance();
                final String rid = getRendererId(processorClass, processorMethod, i);

                ins.setRendererId(rid);
                rendererList.add(ins);
                args.put(parameterName[i], ins);

            } else if (pathVariableValueMap.containsKey(parameterName[i])) {
                args.put(parameterName[i], getConverter(processMethod.getConvertClass())
                        .convert(parameterName[i], pathVariableValueMap.get(parameterName[i]), paramClass));
            } else {
                args.put(parameterName[i], null);
            }
        }

        // before invoke(first class before advice and then method before advice).
        final List<Class<? extends BeforeRequestProcessAdvice>> beforeAdviceClassList = new ArrayList<Class<? extends BeforeRequestProcessAdvice>>();

        if (processorClass.isAnnotationPresent(Before.class)) {
            final Class<? extends BeforeRequestProcessAdvice>[] ac = processorClass.getAnnotation(Before.class)
                    .adviceClass();

            beforeAdviceClassList.addAll(Arrays.asList(ac));
        }
        if (processorMethod.isAnnotationPresent(Before.class)) {
            final Class<? extends BeforeRequestProcessAdvice>[] ac = processorMethod.getAnnotation(Before.class)
                    .adviceClass();

            beforeAdviceClassList.addAll(Arrays.asList(ac));
        }

        BeforeRequestProcessAdvice binstance;

        try {
            for (Class<? extends BeforeRequestProcessAdvice> clz : beforeAdviceClassList) {
                binstance = (BeforeRequestProcessAdvice) adviceMap.get(clz);
                if (binstance == null) {
                    binstance = clz.newInstance();
                }
                binstance.doAdvice(context, args);
            }
        } catch (final RequestReturnAdviceException re) {
            return null;
        } catch (final RequestProcessAdviceException e) {
            final JSONObject exception = e.getJsonObject();

            LOGGER.log(Level.WARNING, "Occurs an exception before request processing [errMsg={0}]",
                    exception.optString(Keys.MSG));

            final JSONRenderer ret = new JSONRenderer();

            ret.setJSONObject(exception);
            context.setRenderer(ret);
            return null;
        }

        for (int j = 0; j < rendererList.size(); j++) {
            rendererList.get(j).preRender(context, args);
        }

        final Object ret = processorMethod.invoke(processorObject, args.values().toArray());

        for (int j = rendererList.size() - 1; j >= 0; j--) {
            rendererList.get(j).postRender(context, ret);
        }

        // after invoke(first method before advice and then class before advice).
        final List<Class<? extends AfterRequestProcessAdvice>> afterAdviceClassList = new ArrayList<Class<? extends AfterRequestProcessAdvice>>();

        if (processorMethod.isAnnotationPresent(After.class)) {
            final Class<? extends AfterRequestProcessAdvice>[] ac = processorMethod.getAnnotation(After.class)
                    .adviceClass();

            afterAdviceClassList.addAll(Arrays.asList(ac));
        }

        if (processorClass.isAnnotationPresent(After.class)) {
            final Class<? extends AfterRequestProcessAdvice>[] ac = processorClass.getAnnotation(After.class)
                    .adviceClass();

            afterAdviceClassList.addAll(Arrays.asList(ac));
        }

        AfterRequestProcessAdvice instance;

        for (Class<? extends AfterRequestProcessAdvice> clz : afterAdviceClassList) {
            instance = (AfterRequestProcessAdvice) adviceMap.get(clz);
            if (instance == null) {
                instance = clz.newInstance();
            }
            instance.doAdvice(context, ret);
        }

        return ret;

    } catch (final Exception e) {
        LOGGER.log(Level.SEVERE, "Invokes processor method failed [method="
                + processorMethod.getDeclaringClass().getSimpleName() + '#' + processorMethod.getName() + ']',
                e);

        return null;
    }
}

From source file:org.openTwoFactor.client.util.TwoFactorClientCommonUtils.java

/**
 * get all getters from a class, including superclasses (if specified)
 * @param theClass to look for fields in
 * @param superclassToStopAt to go up to or null to go up to Object
 * @param propertyType is the type of the field to get
 * @param includeSuperclassToStopAt if we should include the superclass
 * @param markerAnnotation if this is not null, then if the field has this annotation, then do not
 * include in list//  www. ja  v a 2  s.c  o  m
 * @param getterSet set to add fields to
 * @param includeAnnotation if include or exclude
 */
@SuppressWarnings("unchecked")
private static void gettersHelper(Class theClass, Class superclassToStopAt, Class<?> propertyType,
        boolean includeSuperclassToStopAt, Class<? extends Annotation> markerAnnotation, Set<Method> getterSet,
        Boolean includeAnnotation) {

    Method[] methods = retrieveDeclaredMethods(theClass);
    if (length(methods) != 0) {
        for (Method method : methods) {
            //must be a getter
            if (!isGetter(method)) {
                continue;
            }
            //if checking for annotation
            if (markerAnnotation != null
                    && (includeAnnotation != method.isAnnotationPresent(markerAnnotation))) {
                continue;
            }
            //if checking for type, and not right type, continue
            if (propertyType != null && !propertyType.isAssignableFrom(method.getReturnType())) {
                continue;
            }

            //go for it
            getterSet.add(method);
        }
    }
    //see if done recursing (if superclassToStopAt is null, then stop at Object
    if (theClass.equals(superclassToStopAt) || theClass.equals(Object.class)) {
        return;
    }
    Class superclass = theClass.getSuperclass();
    if (!includeSuperclassToStopAt && superclass.equals(superclassToStopAt)) {
        return;
    }
    //recurse
    gettersHelper(superclass, superclassToStopAt, propertyType, includeSuperclassToStopAt, markerAnnotation,
            getterSet, includeAnnotation);
}

From source file:org.openTwoFactor.client.util.TwoFactorClientCommonUtils.java

/**
 * get all setters from a class, including superclasses (if specified)
 * @param theClass to look for fields in
 * @param superclassToStopAt to go up to or null to go up to Object
 * @param propertyType is the type of the field to get
 * @param includeSuperclassToStopAt if we should include the superclass
 * @param markerAnnotation if this is not null, then if the field has this annotation, then do not
 * include in list//w ww  . j a  v a2s  . c  o m
 * @param setterSet set to add fields to
 * @param includeAnnotation if include or exclude (or null if not looking for annotations)
 */
@SuppressWarnings("unchecked")
private static void settersHelper(Class theClass, Class superclassToStopAt, Class<?> propertyType,
        boolean includeSuperclassToStopAt, Class<? extends Annotation> markerAnnotation, Set<Method> setterSet,
        Boolean includeAnnotation) {

    Method[] methods = retrieveDeclaredMethods(theClass);
    if (length(methods) != 0) {
        for (Method method : methods) {
            //must be a getter
            if (!isSetter(method)) {
                continue;
            }
            //if checking for annotation
            if (markerAnnotation != null
                    && (includeAnnotation != method.isAnnotationPresent(markerAnnotation))) {
                continue;
            }
            //if checking for type, and not right type, continue
            if (propertyType != null && !propertyType.isAssignableFrom(method.getParameterTypes()[0])) {
                continue;
            }

            //go for it
            setterSet.add(method);
        }
    }
    //see if done recursing (if superclassToStopAt is null, then stop at Object
    if (theClass.equals(superclassToStopAt) || theClass.equals(Object.class)) {
        return;
    }
    Class superclass = theClass.getSuperclass();
    if (!includeSuperclassToStopAt && superclass.equals(superclassToStopAt)) {
        return;
    }
    //recurse
    settersHelper(superclass, superclassToStopAt, propertyType, includeSuperclassToStopAt, markerAnnotation,
            setterSet, includeAnnotation);
}

From source file:org.openTwoFactor.client.util.TwoFactorClientCommonUtils.java

/**
 * get the set of methods//from w  ww . j  a va  2  s .c  o  m
 * @param theClass
 * @param superclassToStopAt 
 * @param includeSuperclassToStopAt 
 * @param includeStaticMethods
 * @param markerAnnotation 
 * @param includeAnnotation 
 * @param methodSet
 */
public static void methodsHelper(Class<?> theClass, Class<?> superclassToStopAt,
        boolean includeSuperclassToStopAt, boolean includeStaticMethods,
        Class<? extends Annotation> markerAnnotation, boolean includeAnnotation, Set<Method> methodSet) {
    Method[] methods = theClass.getDeclaredMethods();
    if (length(methods) != 0) {
        for (Method method : methods) {
            // if not static, then continue
            if (!includeStaticMethods && Modifier.isStatic(method.getModifiers())) {
                continue;
            }
            // if checking for annotation
            if (markerAnnotation != null
                    && (includeAnnotation != method.isAnnotationPresent(markerAnnotation))) {
                continue;
            }
            // go for it
            methodSet.add(method);
        }
    }
    // see if done recursing (if superclassToStopAt is null, then stop at
    // Object
    if (theClass.equals(superclassToStopAt) || theClass.equals(Object.class)) {
        return;
    }
    Class superclass = theClass.getSuperclass();
    if (!includeSuperclassToStopAt && superclass.equals(superclassToStopAt)) {
        return;
    }
    // recurse
    methodsHelper(superclass, superclassToStopAt, includeSuperclassToStopAt, includeStaticMethods,
            markerAnnotation, includeAnnotation, methodSet);

}

From source file:org.openTwoFactor.client.util.TwoFactorClientCommonUtils.java

/**
 * get the set of methods/* ww  w. j  a  va2  s.c  o  m*/
 * @param theClass
 * @param methodName 
 * @param paramTypesOrArrayOrList
 *            types of the params
 * @param superclassToStopAt 
 * @param includeSuperclassToStopAt 
 * @param isStaticOrInstance true if static
 * @param markerAnnotation 
 * @param includeAnnotation 
 * @return the method or null if not found
 *            
 */
public static Method method(Class<?> theClass, String methodName, Object paramTypesOrArrayOrList,
        Class<?> superclassToStopAt, boolean includeSuperclassToStopAt, boolean isStaticOrInstance,
        Class<? extends Annotation> markerAnnotation, boolean includeAnnotation) {

    Class[] paramTypesArray = (Class[]) toArray(paramTypesOrArrayOrList);

    Method method = null;

    try {
        method = theClass.getDeclaredMethod(methodName, paramTypesArray);
    } catch (NoSuchMethodException nsme) {
        //this is ok
    } catch (Exception e) {
        throw new RuntimeException("Problem retrieving method: " + theClass.getSimpleName() + ", " + methodName,
                e);
    }

    if (method != null) {
        //we found a method, make sure it is valid
        // if not static, then return null (dont worry about superclass)
        if (!isStaticOrInstance && Modifier.isStatic(method.getModifiers())) {
            return null;
        }
        // if checking for annotation, if not there, then recurse
        if (markerAnnotation == null || (includeAnnotation == method.isAnnotationPresent(markerAnnotation))) {
            return method;
        }
    }
    // see if done recursing (if superclassToStopAt is null, then stop at
    // Object
    if (theClass.equals(superclassToStopAt) || theClass.equals(Object.class)) {
        return null;
    }
    Class superclass = theClass.getSuperclass();
    if (!includeSuperclassToStopAt && superclass.equals(superclassToStopAt)) {
        return null;
    }
    // recurse
    return method(superclass, methodName, paramTypesArray, superclassToStopAt, includeSuperclassToStopAt,
            isStaticOrInstance, markerAnnotation, includeAnnotation);
}

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

<T> T deserialize2Object(FieldData objectDTO) {
    Object valueToProcess = objectDTO.valueToProcess;
    Map<String, Object> map = null;

    if (valueToProcess != null && Map.class.isAssignableFrom(valueToProcess.getClass())) {
        map = (Map) valueToProcess;
    } else {//  ww  w  . ja v a 2  s  . c om
        map = new HashMap<>();
    }

    Class<T> valueType = objectDTO.returnType;
    T obj = (T) objectDTO.returnObj;

    Set<String> nameKeys = new HashSet(map.keySet());

    if (valueType == null) {
        valueType = (Class<T>) obj.getClass();
    }

    // first build up the class-level processing rules

    ClassMapper classMapper = objectDTO.classMapper;
    //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);
    }

    objectDTO.incrLevel();

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

        if (annotationSupport) {
            ca.oson.json.annotation.ClassMapper classMapperAnnotation = null;

            // 3. Apply annotations from other sources
            annotations = valueType.getAnnotations();
            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.FALSE)) {
                        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.FALSE) {
                            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;
                    } else if (jsonAutoDetect.fieldVisibility() != Visibility.DEFAULT) {
                        classMapper.useField = true;
                    }
                    if (jsonAutoDetect.setterVisibility() == Visibility.NONE) {
                        classMapper.useAttribute = false;
                    } else if (jsonAutoDetect.setterVisibility() != Visibility.DEFAULT) {
                        classMapper.useAttribute = true;
                    }

                    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);
            }
        }

        // 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.deserializer; // = getDeserializer(valueType);
        if (function == null) {
            function = DeSerializerUtil.getDeserializer(valueType.getName());
        }
        if (function != null) {
            try {
                Object returnedValue = null;
                if (function instanceof Json2DataMapperFunction) {
                    DataMapper classData = new DataMapper(valueToProcess, valueType, obj, classMapper,
                            objectDTO.level, getPrettyIndentation());
                    Json2DataMapperFunction f = (Json2DataMapperFunction) function;

                    return (T) f.apply(classData);

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

                    returnedValue = f.apply(fieldData);

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

                if (returnedValue instanceof Optional) {
                    Optional opt = (Optional) returnedValue;
                    returnedValue = opt.orElse(null);
                }

                if (returnedValue == null) {
                    return null;
                } else if (valueType.isAssignableFrom(returnedValue.getClass())) {
                    return (T) returnedValue;
                } else {
                    // not the correct returned object type, do nothing
                }

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

        Map<String, Method> getters = getGetters(valueType);
        Map<String, Method> setters = getSetters(valueType);
        Map<String, Method> otherMethods = getOtherMethods(valueType);
        Set<String> processedNameSet = new HashSet<>();

        Method jsonAnySetterMethod = null;

        Field[] fields = getFields(valueType); // getFields(obj);

        FIELD_NAMING format = getFieldNaming();

        // @Expose
        boolean exposed = false;
        if (isUseGsonExpose()) {
            // check if @exposed is used any where
            if (valueType.isAnnotationPresent(com.google.gson.annotations.Expose.class)) {
                exposed = true;
            }
            if (!exposed) {
                for (Field f : fields) {
                    if (f.isAnnotationPresent(com.google.gson.annotations.Expose.class)) {
                        exposed = true;
                        break;
                    }
                }
            }
        }

        for (Field f : fields) {
            String name = f.getName();
            String fieldName = name;
            String lcfieldName = name.toLowerCase();

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

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

            f.setAccessible(true);

            // getter and setter methods

            Method getter = null;
            Method setter = null;
            if (getters != null) {
                getter = getters.get(lcfieldName);
            }
            if (setters != null) {
                setter = setters.get(lcfieldName);
            }

            if (ignoreModifiers(f.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                if (setter != null) {
                    if (ignoreModifiers(setter.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                        setters.remove(lcfieldName);
                        nameKeys.remove(name);
                        continue;
                    }

                } else {
                    continue;
                }
            }

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

            // 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 with enclosing class type
            fieldMapper = classifyFieldMapper(fieldMapper, classMapper);

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

            boolean ignored = false;

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

            Set<String> names = new HashSet<>();

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

                if (setter != null
                        && ((javaFieldMapper == null || javaFieldMapper.useAttribute == null)
                                && (fieldMapper.useAttribute == null || fieldMapper.useAttribute))
                        || (javaFieldMapper != null && javaFieldMapper.isDeserializing()
                                && javaFieldMapper.useAttribute != null && javaFieldMapper.useAttribute)) {
                    annotations = Stream
                            .concat(Arrays.stream(annotations), Arrays.stream(setter.getDeclaredAnnotations()))
                            .toArray(Annotation[]::new);
                }

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

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

                boolean exposexists = false;
                for (Annotation annotation : annotations) {
                    if (ignoreField(annotation, classMapper.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.FALSE)) {
                            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.FALSE) {
                                fieldMapperAnnotation = ann;
                                //break; to enable the last one wins
                            }
                        }

                    } else {

                        switch (annotation.annotationType().getName()) {

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

                        case "javax.persistence.Transient":
                            fieldMapper.ignore = true;
                            break;

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

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

                        case "com.google.gson.annotations.Expose":
                            Expose expose = (Expose) annotation;
                            if (!expose.deserialize()) {
                                fieldMapper.ignore = true;
                            }
                            exposexists = true;
                            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.google.gson.annotations.SerializedName":
                            SerializedName serializedName = (SerializedName) annotation;
                            String[] alternates = serializedName.alternate();

                            if (alternates != null && alternates.length > 0) {
                                for (String alternate : alternates) {
                                    names.add(alternate);
                                }
                            }
                            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 "org.junit.Ignore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Enumerated":
                            fieldMapper.enumType = ((Enumerated) 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.READ_ONLY) {
                                fieldMapper.ignore = true;
                            }

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

                            if (fieldMapper.defaultValue == null) {
                                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);
                        }

                    }
                }

                if (exposed && !exposexists) {
                    fieldMapper.ignore = true;
                }

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

            if (ignored) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                setters.remove(lcfieldName);
                if (exposed) {
                    setNull(f, obj);
                }
                continue;
            }

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

            if (fieldMapper.ignore != null && fieldMapper.ignore) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                if (exposed) {
                    setNull(f, obj);
                }
                continue;
            }

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

            if (fieldMapper.jsonAnySetter != null && fieldMapper.jsonAnySetter && setter != null) {
                setters.remove(lcfieldName);
                otherMethods.put(lcfieldName, setter);
                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 (setter != null) {
                    setters.remove(lcfieldName);
                }
                continue;
            } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                continue;
            }

            // get value for name in map
            Object value = null;
            boolean jnameFixed = false;
            String json = fieldMapper.json;
            int size = nameKeys.size();
            if (json == null) {
                if (setter != null) {
                    setters.remove(lcfieldName);
                }
                continue;

            } else if (!json.equals(name)) {
                name = json;
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

            if (!jnameFixed) {
                for (String jsoname : names) {
                    if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) {
                        name = jsoname;
                        value = getMapValue(map, name, nameKeys);
                        if (value != null) {
                            jnameFixed = true;
                            break;
                        }
                    }
                }
            }

            if (!jnameFixed) {
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

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

            // either not null, or a null value exists in the value map
            if (value != null || size == nameKeys.size() + 1) {
                Object oldValue = value;
                FieldData fieldData = new FieldData(obj, f, value, returnType, true, fieldMapper,
                        objectDTO.level, objectDTO.set);
                fieldData.setter = setter;
                Class fieldType = guessComponentType(fieldData);
                value = json2Object(fieldData);

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

                    }

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

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

                try {
                    if (value == null && oldValue != null && oldValue.equals(f.get(obj) + "")) {
                        // keep original value

                    } else {
                        f.set(obj, value);
                    }

                } catch (IllegalAccessException | IllegalArgumentException ex) {
                    //ex.printStackTrace();
                    if (setter != null) {
                        ObjectUtil.setMethodValue(obj, setter, value);
                    }
                }
            }

            setters.remove(lcfieldName);
            nameKeys.remove(name);
        }

        for (Entry<String, Method> entry : setters.entrySet()) {
            String lcfieldName = entry.getKey();
            Method setter = entry.getValue();

            setter.setAccessible(true);

            String name = setter.getName();
            if (name != null && name.length() > 3 && name.substring(0, 3).equals("set")
                    && 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 (ignoreModifiers(setter.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                nameKeys.remove(name);
                continue;
            }

            if (Modifier.isFinal(setter.getModifiers()) && Modifier.isStatic(setter.getModifiers())) {
                nameKeys.remove(name);
                continue;
            }

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

            Class returnType = null;
            Class[] types = setter.getParameterTypes();
            if (types != null && types.length > 0) {
                returnType = types[0];
            }

            // not a proper setter
            if (returnType == null) {
                continue;
            }

            // 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 with enclosing class type
            fieldMapper = classifyFieldMapper(fieldMapper, classMapper);

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

            boolean ignored = false;

            Method getter = getters.get(lcfieldName);

            Set<String> names = new HashSet<>();

            if (annotationSupport) {

                annotations = setter.getDeclaredAnnotations();

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

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

                for (Annotation annotation : annotations) {
                    if (ignoreField(annotation, classMapper.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.FALSE)) {
                            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.FALSE) {
                                fieldMapperAnnotation = ann;
                                // break;
                            }
                        }

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

                        case "javax.persistence.Transient":
                            fieldMapper.ignore = true;
                            break;

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

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

                        case "com.google.gson.annotations.Expose":
                            Expose expose = (Expose) annotation;
                            if (!expose.deserialize()) {
                                fieldMapper.ignore = true;
                            }
                            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 "org.junit.Ignore":
                            fieldMapper.ignore = true;
                            break;

                        case "javax.persistence.Enumerated":
                            fieldMapper.enumType = ((Enumerated) 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.READ_ONLY) {
                                fieldMapper.ignore = true;
                            }

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

                            if (fieldMapper.defaultValue == null) {
                                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 (fname != null) {
                            names.add(fname);
                        }
                    }
                }

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

            if (ignored) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

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

            if (fieldMapper.ignore != null && fieldMapper.ignore) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

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

            if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

            if (fieldMapper.jsonAnySetter != null && fieldMapper.jsonAnySetter && setter != null) {
                setters.remove(lcfieldName);
                otherMethods.put(lcfieldName, setter);
                continue;
            }

            if (fieldMapper.since != null && fieldMapper.since > getVersion()) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) {
                nameKeys.remove(name);
                nameKeys.remove(fieldMapper.json);
                continue;
            }

            // get value for name in map
            Object value = null;
            boolean jnameFixed = false;
            String json = fieldMapper.json;
            if (json == null) {
                continue;

            } else if (!json.equals(name)) {
                name = json;
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

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

            if (!jnameFixed) {
                value = getMapValue(map, name, nameKeys);
                jnameFixed = true;
            }

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

            if (value != null) {

                FieldData fieldData = new FieldData(obj, null, value, returnType, true, fieldMapper,
                        objectDTO.level, objectDTO.set);
                fieldData.setter = setter;
                Class fieldType = guessComponentType(fieldData);

                value = json2Object(fieldData);

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

                    }

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

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

                ObjectUtil.setMethodValue(obj, setter, value);

                nameKeys.remove(name);
            }
        }

        if (annotationSupport) {
            //@JsonAnySetter
            if (nameKeys.size() > 0) {
                for (Entry<String, Method> entry : otherMethods.entrySet()) {
                    Method method = entry.getValue();

                    if (ignoreModifiers(method.getModifiers(), classMapper.includeFieldsWithModifiers)) {
                        continue;
                    }

                    if (method.isAnnotationPresent(JsonAnySetter.class)) {
                        if (ignoreField(JsonAnySetter.class, classMapper.ignoreFieldsWithAnnotations)) {
                            continue;
                        }

                        jsonAnySetterMethod = method;

                    } else if (method.isAnnotationPresent(org.codehaus.jackson.annotate.JsonAnySetter.class)) {
                        if (ignoreField(org.codehaus.jackson.annotate.JsonAnySetter.class,
                                classMapper.ignoreFieldsWithAnnotations)) {
                            continue;
                        }

                        jsonAnySetterMethod = method;

                    } else if (method.isAnnotationPresent(ca.oson.json.annotation.FieldMapper.class)) {
                        ca.oson.json.annotation.FieldMapper annotation = (ca.oson.json.annotation.FieldMapper) method
                                .getAnnotation(ca.oson.json.annotation.FieldMapper.class);
                        if (annotation.jsonAnySetter() == BOOLEAN.TRUE) {
                            jsonAnySetterMethod = method;
                            break;
                        }
                    }
                }
            }
        }

        if (jsonAnySetterMethod != null) {
            Parameter[] parameters = jsonAnySetterMethod.getParameters();
            if (parameters != null && parameters.length == 2) {
                for (String name : nameKeys) {
                    Object value = map.get(name);

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

                    if (value != null && !StringUtil.isEmpty(java)) {
                        ObjectUtil.setMethodValue(obj, jsonAnySetterMethod, java, value);
                    }

                }
            }
        }

        return obj;

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

    return null;
}