Example usage for java.lang.reflect Method getDeclaredAnnotations

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

Introduction

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

Prototype

public Annotation[] getDeclaredAnnotations() 

Source Link

Usage

From source file:com.web.server.EARDeployer.java

/**
 * This method configures the executor services from the jar file.
 * /* w w  w  . j  a v  a 2s  . c  o m*/
 * @param jarFile
 * @param classList
 * @throws FileSystemException
 */
public void deployExecutorServicesEar(String earFileName, FileObject earFile,
        StandardFileSystemManager fsManager) throws FileSystemException {
    try {
        System.out.println("EARFILE NAMEs=" + earFileName);
        CopyOnWriteArrayList<FileObject> fileObjects = new CopyOnWriteArrayList<FileObject>();
        CopyOnWriteArrayList<FileObject> warObjects = new CopyOnWriteArrayList<FileObject>();
        ConcurrentHashMap jarClassListMap = new ConcurrentHashMap();
        CopyOnWriteArrayList<String> classList;
        obtainUrls(earFile, earFile, fileObjects, jarClassListMap, warObjects, fsManager);
        VFSClassLoader customClassLoaderBaseLib = new VFSClassLoader(
                fileObjects.toArray(new FileObject[fileObjects.size()]), fsManager,
                Thread.currentThread().getContextClassLoader());
        VFSClassLoader customClassLoader = null;
        Set keys = jarClassListMap.keySet();
        Iterator key = keys.iterator();
        FileObject jarFileObject;
        ConcurrentHashMap classLoaderPath = new ConcurrentHashMap();
        filesMap.put(earFileName, classLoaderPath);
        for (FileObject warFileObj : warObjects) {
            if (warFileObj.getName().getBaseName().endsWith(".war")) {
                //logger.info("filePath"+filePath);
                String filePath = scanDirectory + "/" + warFileObj.getName().getBaseName();
                log.info(filePath);
                String fileName = warFileObj.getName().getBaseName();
                WebClassLoader classLoader = new WebClassLoader(new URL[] {});
                log.info(classLoader);
                warDeployer.deleteDir(
                        new File(deployDirectory + "/" + fileName.substring(0, fileName.lastIndexOf(".war"))));
                new File(deployDirectory + "/" + fileName.substring(0, fileName.lastIndexOf(".war"))).mkdirs();
                log.info(deployDirectory + "/" + fileName.substring(0, fileName.lastIndexOf(".war")));
                urlClassLoaderMap.put(
                        deployDirectory + "/" + fileName.substring(0, fileName.lastIndexOf(".war")),
                        classLoader);
                classLoaderPath.put(warFileObj.getName().getBaseName(),
                        deployDirectory + "/" + fileName.substring(0, fileName.lastIndexOf(".war")));
                warDeployer.extractWar(new File(filePath), classLoader);

                if (exec != null) {
                    exec.shutdown();
                }
                new File(scanDirectory + "/" + warFileObj.getName().getBaseName()).delete();
                exec = Executors.newSingleThreadScheduledExecutor();
                exec.scheduleAtFixedRate(task, 0, 1000, TimeUnit.MILLISECONDS);
            }
        }
        for (int keyCount = 0; keyCount < keys.size(); keyCount++) {
            jarFileObject = (FileObject) key.next();
            {
                classList = (CopyOnWriteArrayList<String>) jarClassListMap.get(jarFileObject);
                customClassLoader = new VFSClassLoader(jarFileObject, fsManager, customClassLoaderBaseLib);
                this.urlClassLoaderMap.put(
                        scanDirectory + "/" + earFileName + "/" + jarFileObject.getName().getBaseName(),
                        customClassLoader);
                classLoaderPath.put(jarFileObject.getName().getBaseName(),
                        scanDirectory + "/" + earFileName + "/" + jarFileObject.getName().getBaseName());
                for (int classCount = 0; classCount < classList.size(); classCount++) {
                    String classwithpackage = classList.get(classCount).substring(0,
                            classList.get(classCount).indexOf(".class"));
                    classwithpackage = classwithpackage.replace("/", ".");
                    // System.out.println("classList:"+classwithpackage.replace("/","."));
                    try {
                        if (!classwithpackage.contains("$")) {

                            /*System.out.println("EARFILE NAME="+fileName);
                            System.out
                                  .println(scanDirectory
                            + "/"
                            + fileName
                            + "/"
                            + jarFileObject.getName()
                                  .getBaseName());
                                    
                            System.out.println(urlClassLoaderMap);*/
                            Class executorServiceClass = customClassLoader.loadClass(classwithpackage);

                            Annotation[] classServicesAnnot = executorServiceClass.getDeclaredAnnotations();

                            if (classServicesAnnot != null) {
                                for (int annotcount = 0; annotcount < classServicesAnnot.length; annotcount++) {
                                    if (classServicesAnnot[annotcount] instanceof RemoteCall) {
                                        RemoteCall remoteCall = (RemoteCall) classServicesAnnot[annotcount];
                                        //registry.unbind(remoteCall.servicename());
                                        System.out.println(remoteCall.servicename().trim());
                                        try {
                                            for (int count = 0; count < 2; count++) {
                                                RemoteInterface reminterface = (RemoteInterface) UnicastRemoteObject
                                                        .exportObject(
                                                                (Remote) executorServiceClass.newInstance(), 0);
                                                registry.rebind(remoteCall.servicename().trim(), reminterface);
                                            }
                                        } catch (Exception ex) {
                                            ex.printStackTrace();
                                        }
                                    }
                                }
                            }
                            // System.out.println(executorServiceClass.newInstance());
                            // System.out.println("executor class in ExecutorServicesConstruct"+executorServiceClass);
                            // System.out.println();
                            Method[] methods = executorServiceClass.getDeclaredMethods();
                            for (Method method : methods) {
                                Annotation[] annotations = method.getDeclaredAnnotations();
                                for (Annotation annotation : annotations) {
                                    if (annotation instanceof ExecutorServiceAnnot) {
                                        ExecutorServiceAnnot executorServiceAnnot = (ExecutorServiceAnnot) annotation;
                                        ExecutorServiceInfo executorServiceInfo = new ExecutorServiceInfo();
                                        executorServiceInfo.setExecutorServicesClass(executorServiceClass);
                                        executorServiceInfo.setMethod(method);
                                        executorServiceInfo.setMethodParams(method.getParameterTypes());
                                        //                              System.out.println("serice name="
                                        //                                    + executorServiceAnnot
                                        //                                          .servicename());
                                        //                              System.out.println("method info="
                                        //                                    + executorServiceInfo);
                                        //                              System.out.println(method);
                                        // if(servicesMap.get(executorServiceAnnot.servicename())==null)throw
                                        // new Exception();
                                        executorServiceMap.put(executorServiceAnnot.servicename(),
                                                executorServiceInfo);
                                    }
                                }
                            }
                        }
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            jarFileObject.close();
        }
        for (FileObject fobject : fileObjects) {
            fobject.close();
        }
        System.out.println("Channel unlocked");
        earFile.close();
        fsManager.closeFileSystem(earFile.getFileSystem());
        // ClassLoaderUtil.closeClassLoader(customClassLoader);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

From source file:com.tacticlogistics.crm.view.backing.RadicacionBacking.java

private void setValue(Object object, String columnName, Object value) {
    Field[] declaredFields = object.getClass().getDeclaredFields();
    for (Field field : declaredFields) {
        String methodName = "get" + JSFUtil.toUpperCaseFirst(field.getName());
        try {/*w  ww  . j av  a  2  s.  c  om*/
            Method method = object.getClass().getDeclaredMethod(methodName, new Class[] {});
            Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
            for (Annotation annotation : declaredAnnotations) {
                try {
                    Column column = (Column) annotation;
                    if (column.name().toLowerCase().equalsIgnoreCase(columnName.toLowerCase())) {
                        if (value != null && value.toString().trim().isEmpty()) {
                            value = null;
                        }
                        BeanUtils.setProperty(object, field.getName(), value);
                    }
                } catch (IllegalAccessException | InvocationTargetException | ClassCastException ex) {

                }
            }
        } catch (NoSuchMethodException ex) {

        }
    }
}

From source file:com.tacticlogistics.crm.view.backing.RadicacionBacking.java

private void setValueFinal(Object object, String columnName, Object value) {
    Field[] declaredFields = object.getClass().getDeclaredFields();
    for (Field field : declaredFields) {
        String methodName = "get" + JSFUtil.toUpperCaseFirst(field.getName());
        try {//from   w ww.  j  a v a 2  s  .c o  m
            Method method = object.getClass().getDeclaredMethod(methodName, new Class[] {});
            Annotation[] declaredAnnotations = method.getDeclaredAnnotations();
            for (Annotation annotation : declaredAnnotations) {
                try {
                    Column column = (Column) annotation;
                    if (column.name().toLowerCase().equalsIgnoreCase(columnName.toLowerCase())) {
                        if (value != null && value.toString().isEmpty()) {
                            value = null;
                        }
                        BeanUtils.setProperty(object, field.getName(), value);
                    }
                } catch (IllegalAccessException | InvocationTargetException | ClassCastException ex) {

                }
            }
        } catch (NoSuchMethodException ex) {

        }
    }
}

From source file:com.toolsverse.mvc.model.ModelImpl.java

/**
 * Instantiates a new ModelImpl. The constructor reads the annotations and sets the values for the getter\setter\reader\writer\params attributes.
 */// ww  w  . j  a v  a  2 s  .  co  m
public ModelImpl() {
    _updateDirtyOnChange = false;

    _silentUpdate = false;

    _isDirty = false;

    _suffix = null;

    _attributes = new LinkedHashMap<String, Attribute>();

    _propertyChangeSupport = new PropertyChangeSupport(this);

    _subModels = new ArrayList<Model>();

    Method[] methods = getClass().getMethods();

    List<TypedKeyValue<Method, Annotation>> readers = new ArrayList<TypedKeyValue<Method, Annotation>>();
    List<TypedKeyValue<Method, Annotation>> writers = new ArrayList<TypedKeyValue<Method, Annotation>>();

    for (Method method : methods) {
        Annotation[] annotations = method.getDeclaredAnnotations();
        if (annotations != null)
            for (Annotation annotation : annotations) {
                if (annotation instanceof Getter && isGetterMethod(method)) {
                    Attribute attr = getAttribute(((Getter) annotation).name());

                    Object attrParams = getAttrParams(((Getter) annotation).paramsClass());

                    if (attr == null) {
                        attr = new Attribute(method.getReturnType(), method.getName(), null, attrParams);

                        _attributes.put(((Getter) annotation).name(), attr);
                    } else {
                        attr.setGetter(method.getName());
                        attr.setAttributeClass(method.getReturnType());
                        if (attr.getParams() == null && attrParams != null)
                            attr.setParams(attrParams);
                    }
                } else if (annotation instanceof Setter && isSetterMethod(method)) {
                    Attribute attr = getAttribute(((Setter) annotation).name());

                    Object attrParams = getAttrParams(((Setter) annotation).paramsClass());

                    if (attr == null) {
                        attr = new Attribute(method.getParameterTypes()[0], null, method.getName(), attrParams);

                        _attributes.put(((Setter) annotation).name(), attr);
                    } else {
                        attr.setSetter(method.getName());

                        if (attr.getAttributeClass() == null)
                            attr.setAttributeClass(method.getParameterTypes()[0]);
                        if (attr.getParams() == null && attrParams != null)
                            attr.setParams(attrParams);
                    }
                } else if (annotation instanceof Reader && isReaderMethod(method)) {
                    readers.add(new TypedKeyValue<Method, Annotation>(method, annotation));
                } else if (annotation instanceof Writer && isWriterMethod(method)) {
                    writers.add(new TypedKeyValue<Method, Annotation>(method, annotation));
                }
            }
    }

    for (TypedKeyValue<Method, Annotation> keyValue : readers) {
        Attribute attr = getAttribute(((Reader) keyValue.getValue()).name());

        Object attrParams = getAttrParams(((Reader) keyValue.getValue()).paramsClass());

        if (attr == null) {
            attr = new Attribute(keyValue.getKey().getParameterTypes()[0], null, null, attrParams,
                    keyValue.getKey().getName(), null);

            _attributes.put(((Reader) keyValue.getValue()).name(), attr);
        } else {
            attr.setReader(keyValue.getKey().getName());

            if (attr.getAttributeClass() == null)
                attr.setAttributeClass(keyValue.getKey().getParameterTypes()[0]);
            if (attr.getParams() == null && attrParams != null)
                attr.setParams(attrParams);
        }

    }

    for (TypedKeyValue<Method, Annotation> keyValue : writers) {
        Attribute attr = getAttribute(((Writer) keyValue.getValue()).name());

        Object attrParams = getAttrParams(((Writer) keyValue.getValue()).paramsClass());

        if (attr == null) {
            attr = new Attribute(keyValue.getKey().getReturnType(), keyValue.getKey().getName(), null,
                    attrParams);

            _attributes.put(((Writer) keyValue.getValue()).name(), attr);
        } else {
            attr.setWriter(keyValue.getKey().getName());

            if (attr.getAttributeClass() == null)
                attr.setAttributeClass(keyValue.getKey().getParameterTypes()[0]);
            if (attr.getParams() == null && attrParams != null)
                attr.setParams(attrParams);
        }

    }
}

From source file:org.wso2.carbon.apimgt.webapp.publisher.lifecycle.util.AnnotationUtil.java

private List<APIResource> getApiResources(String rootContext, Method[] annotatedMethods) throws Throwable {
    List<APIResource> resourceList;
    resourceList = new ArrayList<APIResource>();
    for (Method method : annotatedMethods) {
        Annotation methodContextAnno = method.getAnnotation(pathClazz);
        if (methodContextAnno != null) {
            String subCtx = invokeMethod(pathClazzMethods[0], methodContextAnno, STRING);
            APIResource resource = new APIResource();
            resource.setUriTemplate(makeContextURLReady(subCtx));

            String serverIP = System.getProperty(SERVER_HOST);
            String httpServerPort = System.getProperty(HTTP_PORT);

            resource.setUri(PROTOCOL_HTTP + "://" + serverIP + ":" + httpServerPort
                    + makeContextURLReady(rootContext) + makeContextURLReady(subCtx));
            resource.setAuthType(AUTH_TYPE);

            Annotation[] annotations = method.getDeclaredAnnotations();
            for (int i = 0; i < annotations.length; i++) {

                if (annotations[i].annotationType().getName().equals(GET.class.getName())) {
                    resource.setHttpVerb(HttpMethod.GET);
                }//from   w  w w  .j av  a2 s.  c om
                if (annotations[i].annotationType().getName().equals(POST.class.getName())) {
                    resource.setHttpVerb(HttpMethod.POST);
                }
                if (annotations[i].annotationType().getName().equals(OPTIONS.class.getName())) {
                    resource.setHttpVerb(HttpMethod.OPTIONS);
                }
                if (annotations[i].annotationType().getName().equals(DELETE.class.getName())) {
                    resource.setHttpVerb(HttpMethod.DELETE);
                }
                if (annotations[i].annotationType().getName().equals(PUT.class.getName())) {
                    resource.setHttpVerb(HttpMethod.PUT);
                }
                if (annotations[i].annotationType().getName().equals(Consumes.class.getName())) {
                    Class<Consumes> consumesClass = (Class<Consumes>) classLoader
                            .loadClass(Consumes.class.getName());
                    Method[] consumesClassMethods = consumesClass.getMethods();
                    Annotation consumesAnno = method.getAnnotation(consumesClass);
                    resource.setConsumes(invokeMethod(consumesClassMethods[0], consumesAnno, STRING_ARR));
                }
                if (annotations[i].annotationType().getName().equals(Produces.class.getName())) {
                    Class<Produces> producesClass = (Class<Produces>) classLoader
                            .loadClass(Produces.class.getName());
                    Method[] producesClassMethods = producesClass.getMethods();
                    Annotation producesAnno = method.getAnnotation(producesClass);
                    resource.setProduces(invokeMethod(producesClassMethods[0], producesAnno, STRING_ARR));
                }
            }
            resourceList.add(resource);
        }
    }
    return resourceList;
}

From source file:org.kuali.rice.krad.data.provider.annotation.impl.AnnotationMetadataProviderImpl.java

/**
 * Handle annotations made at the method level and add their data to the given metadata object.
  *//from w ww.  j  ava2s .  c  o  m
  * @param clazz the class to process.
  * @param metadata the metadata for the class.
 * 
 * @return <b>true</b> if any annotations are found.
 */
protected boolean processMethodLevelAnnotations(Class<?> clazz, DataObjectMetadataImpl metadata) {
    boolean fieldAnnotationsFound = false;
    if (LOG.isDebugEnabled()) {
        LOG.debug("Processing Method Annotations on " + clazz);
    }
    List<DataObjectAttribute> attributes = new ArrayList<DataObjectAttribute>(metadata.getAttributes());
    for (Method m : clazz.getDeclaredMethods()) {
        // we only care about properties which are designated as non-persistent
        // we don't want to load metadata about everything just because it's there
        // (E.g., we don't know how expensive all method calls are)
        if (!m.isAnnotationPresent(NonPersistentProperty.class)) {
            if (LOG.isTraceEnabled()) {
                LOG.trace("Rejecting method " + m.getName()
                        + " because does not have NonPersistentProperty annotation");
            }
            continue;
        }
        // we only care about getters
        if (!m.getName().startsWith("get") && !m.getName().startsWith("is")) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Rejecting method " + m.getName() + " because name does not match getter pattern");
            }
            continue;
        }
        // we also need it to return a value and have no arguments to be a proper getter
        if (m.getReturnType() == null || m.getParameterTypes().length > 0) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Rejecting method " + m.getName() + " because has no return type or has arguments");
            }
            continue;
        }
        String propertyName = getPropertyNameFromGetterMethod(m);
        boolean fieldAnnotationFound = false;
        boolean existingAttribute = true;
        DataObjectAttributeImpl attr = (DataObjectAttributeImpl) metadata.getAttribute(propertyName);
        if (attr == null) {
            existingAttribute = false;
            attr = new DataObjectAttributeImpl();
            attr.setName(propertyName);
            attr.setType(m.getReturnType());
            DataType dataType = DataType.getDataTypeFromClass(m.getReturnType());
            if (dataType == null) {
                dataType = DataType.STRING;
            }
            attr.setDataType(dataType);
            attr.setOwningType(metadata.getType());
        }
        Annotation[] methodAnnotations = m.getDeclaredAnnotations();
        if (LOG.isDebugEnabled()) {
            LOG.debug(m.getDeclaringClass() + "." + m.getName() + " Method-level annotations: "
                    + Arrays.asList(methodAnnotations));
        }
        for (Annotation a : methodAnnotations) {
            fieldAnnotationFound |= processAnnotationForAttribute(a, attr, metadata);
        }
        if (fieldAnnotationFound) {
            if (!existingAttribute) {
                attributes.add(attr);
            }
            fieldAnnotationsFound = true;
        }
    }
    if (fieldAnnotationsFound) {
        metadata.setAttributes(attributes);
    }

    return fieldAnnotationsFound;
}

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

private <E> String enum2Json(FieldData objectDTO) {
    Object value = objectDTO.valueToProcess;
    Class<E> valueType = objectDTO.returnType;
    EnumType enumType = objectDTO.getEnumType();

    if (value == null) {
        return null;
    }//from  w  ww  . j av  a  2  s.  com

    Enum en = (Enum) value;

    try {
        Function function = objectDTO.getSerializer();
        if (function != null) {
            try {
                if (function instanceof DataMapper2JsonFunction) {
                    DataMapper classData = new DataMapper(objectDTO.returnType, value, objectDTO.classMapper,
                            objectDTO.level, getPrettyIndentation());
                    return ((DataMapper2JsonFunction) function).apply(classData);

                } else if (function instanceof Enum2JsonFunction) {
                    return ((Enum2JsonFunction) function).apply(en);

                } else {

                    Object returnedValue = null;
                    if (function instanceof FieldData2JsonFunction) {
                        FieldData2JsonFunction f = (FieldData2JsonFunction) function;
                        FieldData fieldData = objectDTO.clone();
                        returnedValue = f.apply(fieldData);
                    } else {
                        returnedValue = function.apply(value);
                    }

                    if (returnedValue instanceof Optional) {
                        returnedValue = ObjectUtil.unwrap(returnedValue);
                    }

                    if (returnedValue == null) {
                        return null; // just ignore it, right?
                    } else if (Enum.class.isAssignableFrom(returnedValue.getClass())) {
                        en = (Enum) returnedValue;

                    } else {
                        objectDTO.valueToProcess = returnedValue;
                        return object2String(objectDTO);
                    }

                }

            } catch (Exception e) {
            }
        }
    } catch (Exception ex) {
    }

    String name = en.name();

    if (enumType == null || enumType == EnumType.STRING) {

        for (Method method : valueType.getDeclaredMethods()) {
            for (Annotation annotation : method.getDeclaredAnnotations()) {
                String aname = annotation.annotationType().getName();

                switch (aname) {
                case "com.fasterxml.jackson.annotation.JsonValue":
                case "org.codehaus.jackson.annotate.JsonValue":
                    return ObjectUtil.getMethodValue(en, method);

                case "ca.oson.json.annotation.FieldMapper":
                    ca.oson.json.annotation.FieldMapper fieldMapper = (ca.oson.json.annotation.FieldMapper) annotation;
                    if (fieldMapper.jsonValue() != null && fieldMapper.jsonValue() == BOOLEAN.TRUE) {
                        return ObjectUtil.getMethodValue(en, method);
                    }
                }
            }

        }

        for (Field field : valueType.getDeclaredFields()) {
            if (name.equalsIgnoreCase(field.getName())) {
                ca.oson.json.annotation.FieldMapper fieldMapper = field
                        .getAnnotation(ca.oson.json.annotation.FieldMapper.class);
                if (fieldMapper != null) {
                    String aname = fieldMapper.name();
                    if (!StringUtil.isEmpty(aname)) {
                        return aname;
                    }

                } else {
                    for (Annotation annotation : field.getAnnotations()) {
                        String aname = ObjectUtil.getName(annotation);
                        if (!StringUtil.isEmpty(aname)) {
                            return aname;
                        }
                    }
                }
            }
        }

        return name;
    }

    switch (enumType) {
    case STRING:
        return en.name();
    case ORDINAL:
    default:
        return "" + en.ordinal();
    }
}

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

private <E> Enum<?> json2Enum(FieldData objectDTO) {
    objectDTO.valueToProcess = StringUtil.unquote(objectDTO.valueToProcess, isEscapeHtml());
    Object valueToProcess = objectDTO.valueToProcess;
    Class<E> returnType = objectDTO.returnType;
    boolean required = objectDTO.required();
    Enum defaultValue = (Enum) objectDTO.defaultValue;
    boolean json2Java = objectDTO.json2Java;

    if (returnType == null || valueToProcess == null) {
        if (required) {
            return defaultValue;
        }/*  w  w  w . j av  a 2 s. c  o  m*/

        return null;
    }

    String value = (String) valueToProcess;

    Class<Enum> enumType = (Class<Enum>) returnType;

    try {
        Function function = objectDTO.getDeserializer();

        if (function != null) {

            Object returnedValue = null;

            if (function instanceof Json2DataMapperFunction) {
                DataMapper classData = new DataMapper(returnType, value, objectDTO.classMapper, objectDTO.level,
                        getPrettyIndentation());
                returnedValue = ((Json2DataMapperFunction) function).apply(classData);

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

                returnedValue = f.apply(fieldData);

            } else if (function instanceof Json2EnumFunction) {
                return (Enum<?>) ((Json2EnumFunction) function).apply(value);
            } else {
                returnedValue = function.apply(value);
            }

            if (returnedValue instanceof Optional) {
                returnedValue = ObjectUtil.unwrap(returnedValue);
            }

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

            Class type = returnedValue.getClass();

            if (Enum.class.isAssignableFrom(type)) {
                return (Enum<?>) returnedValue;

            } else if (Number.class.isAssignableFrom(type)) {
                int ordinal = ((Number) returnedValue).intValue();

                for (Enum enumValue : enumType.getEnumConstants()) {
                    if (enumValue.ordinal() == ordinal) {
                        return enumValue;
                    }
                }

            } else {
                String name = returnedValue.toString();

                for (Enum enumValue : enumType.getEnumConstants()) {
                    if (enumValue.toString().equalsIgnoreCase(name)
                            || enumValue.name().equalsIgnoreCase(name)) {
                        return enumValue;
                    }
                }
            }

        }

    } catch (Exception ex) {
    }

    for (Method method : enumType.getDeclaredMethods()) {
        for (Annotation annotation : method.getDeclaredAnnotations()) {
            String aname = annotation.annotationType().getName();

            switch (aname) {
            case "com.fasterxml.jackson.annotation.JsonCreator":
            case "org.codehaus.jackson.annotate.JsonCreator":
                return ObjectUtil.getMethodValue(null, method, value);

            case "ca.oson.json.annotation.FieldMapper":
                ca.oson.json.annotation.FieldMapper fieldMapper = (ca.oson.json.annotation.FieldMapper) annotation;
                if (fieldMapper.jsonCreator() != null && fieldMapper.jsonCreator() == BOOLEAN.TRUE) {
                    return ObjectUtil.getMethodValue(null, method, value);
                }
            }
        }

    }

    String fieldName = null;
    for (Field field : enumType.getDeclaredFields()) {
        String name = null;
        ca.oson.json.annotation.FieldMapper fieldMapper = field
                .getAnnotation(ca.oson.json.annotation.FieldMapper.class);
        if (fieldMapper != null) {
            name = fieldMapper.name();

            if (value.equalsIgnoreCase(name)) {
                fieldName = field.getName();
                break;
            }

        } else {
            for (Annotation annotation : field.getAnnotations()) {
                name = ObjectUtil.getName(annotation);
                if (value.equalsIgnoreCase(name)) {
                    fieldName = field.getName();
                    break;
                }
            }
        }
    }
    if (fieldName != null) {
        try {
            return Enum.valueOf(enumType, fieldName.toUpperCase());
        } catch (IllegalArgumentException ex) {
        }
    }

    try {
        return Enum.valueOf(enumType, value.toUpperCase());
    } catch (IllegalArgumentException ex) {
    }

    for (Enum enumValue : enumType.getEnumConstants()) {
        if (enumValue.toString().equalsIgnoreCase(value) || enumValue.name().equalsIgnoreCase(value)) {
            return enumValue;
        }
    }

    FieldData fieldData = new FieldData(value, Integer.class, true);
    Integer ordinal = json2Integer(fieldData);

    if (ordinal != null) {
        for (Enum enumValue : enumType.getEnumConstants()) {
            if (enumValue.ordinal() == ordinal) {
                return enumValue;
            }
        }
    }

    return null;
}

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 {//from  www.j  ava  2  s  .c o m
        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;
}

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 . ja  v  a2 s . c om*/

    // 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) {
    }
}