List of usage examples for java.lang Class getAnnotations
public Annotation[] getAnnotations()
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 {/* w w w .j a v a 2 s. c om*/ map = new HashMap<>(); } Class<T> valueType = objectDTO.returnType; T obj = (T) objectDTO.returnObj; Set<String> nameKeys = new HashSet(map.keySet()); if (valueType == null) { valueType = (Class<T>) obj.getClass(); } // first build up the class-level processing rules ClassMapper classMapper = objectDTO.classMapper; //if (classMapper == null) { // 1. Create a blank class mapper instance classMapper = new ClassMapper(valueType); // 2. Globalize it classMapper = globalize(classMapper); objectDTO.classMapper = classMapper; //} if (objectDTO.fieldMapper != null && isInheritMapping()) { classMapper = overwriteBy(classMapper, objectDTO.fieldMapper); } objectDTO.incrLevel(); try { boolean annotationSupport = getAnnotationSupport(); Annotation[] annotations = null; if (annotationSupport) { ca.oson.json.annotation.ClassMapper classMapperAnnotation = null; // 3. Apply annotations from other sources annotations = valueType.getAnnotations(); for (Annotation annotation : annotations) { if (ignoreClass(annotation)) { return null; } switch (annotation.annotationType().getName()) { case "ca.oson.json.annotation.ClassMapper": classMapperAnnotation = (ca.oson.json.annotation.ClassMapper) annotation; if (!(classMapperAnnotation.serialize() == BOOLEAN.BOTH || classMapperAnnotation.serialize() == BOOLEAN.FALSE)) { classMapperAnnotation = null; } break; case "ca.oson.json.annotation.ClassMappers": ca.oson.json.annotation.ClassMappers classMapperAnnotations = (ca.oson.json.annotation.ClassMappers) annotation; for (ca.oson.json.annotation.ClassMapper ann : classMapperAnnotations.value()) { if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.FALSE) { classMapperAnnotation = ann; // break; } } break; case "com.google.gson.annotations.Since": Since since = (Since) annotation; classMapper.since = since.value(); break; case "com.google.gson.annotations.Until": Until until = (Until) annotation; classMapper.until = until.value(); break; case "com.fasterxml.jackson.annotation.JsonIgnoreProperties": JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation; String[] jsonnames = jsonIgnoreProperties.value(); if (jsonnames != null && jsonnames.length > 0) { if (classMapper.jsonIgnoreProperties == null) { classMapper.jsonIgnoreProperties = new HashSet(); } classMapper.jsonIgnoreProperties.addAll(Arrays.asList(jsonnames)); } break; case "org.codehaus.jackson.annotate.JsonIgnoreProperties": org.codehaus.jackson.annotate.JsonIgnoreProperties jsonIgnoreProperties2 = (org.codehaus.jackson.annotate.JsonIgnoreProperties) annotation; String[] jsonnames2 = jsonIgnoreProperties2.value(); if (jsonnames2 != null && jsonnames2.length > 0) { if (classMapper.jsonIgnoreProperties == null) { classMapper.jsonIgnoreProperties = new HashSet(); } classMapper.jsonIgnoreProperties.addAll(Arrays.asList(jsonnames2)); } break; case "com.fasterxml.jackson.annotation.JsonPropertyOrder": // first come first serve if (classMapper.propertyOrders == null) { classMapper.propertyOrders = ((JsonPropertyOrder) annotation).value(); } break; case "org.codehaus.jackson.annotate.JsonPropertyOrder": // first come first serve if (classMapper.propertyOrders == null) { classMapper.propertyOrders = ((org.codehaus.jackson.annotate.JsonPropertyOrder) annotation) .value(); } break; case "com.fasterxml.jackson.annotation.JsonInclude": if (classMapper.defaultType == JSON_INCLUDE.NONE) { JsonInclude jsonInclude = (JsonInclude) annotation; switch (jsonInclude.content()) { case ALWAYS: classMapper.defaultType = JSON_INCLUDE.ALWAYS; break; case NON_NULL: classMapper.defaultType = JSON_INCLUDE.NON_NULL; break; case NON_ABSENT: classMapper.defaultType = JSON_INCLUDE.NON_NULL; break; case NON_EMPTY: classMapper.defaultType = JSON_INCLUDE.NON_EMPTY; break; case NON_DEFAULT: classMapper.defaultType = JSON_INCLUDE.NON_DEFAULT; break; case USE_DEFAULTS: classMapper.defaultType = JSON_INCLUDE.DEFAULT; break; } } break; case "com.fasterxml.jackson.annotation.JsonAutoDetect": JsonAutoDetect jsonAutoDetect = (JsonAutoDetect) annotation; if (jsonAutoDetect.fieldVisibility() == Visibility.NONE) { classMapper.useField = false; } else if (jsonAutoDetect.fieldVisibility() != Visibility.DEFAULT) { classMapper.useField = true; } if (jsonAutoDetect.setterVisibility() == Visibility.NONE) { classMapper.useAttribute = false; } else if (jsonAutoDetect.setterVisibility() != Visibility.DEFAULT) { classMapper.useAttribute = true; } break; case "org.codehaus.jackson.annotate.JsonAutoDetect": org.codehaus.jackson.annotate.JsonAutoDetect jsonAutoDetect2 = (org.codehaus.jackson.annotate.JsonAutoDetect) annotation; if (jsonAutoDetect2 .fieldVisibility() == org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE) { classMapper.useField = false; } if (jsonAutoDetect2 .getterVisibility() == org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE) { classMapper.useAttribute = false; } break; case "org.junit.Ignore": classMapper.ignore = true; break; } } // 4. Apply annotations from Oson if (classMapperAnnotation != null) { classMapper = overwriteBy(classMapper, classMapperAnnotation); } } // 5. Apply Java configuration for this particular class ClassMapper javaClassMapper = getClassMapper(valueType); if (javaClassMapper != null) { classMapper = overwriteBy(classMapper, javaClassMapper); } // now processing at the class level if (classMapper.ignore()) { return null; } if (classMapper.since != null && classMapper.since > getVersion()) { return null; } else if (classMapper.until != null && classMapper.until <= getVersion()) { return null; } Function function = classMapper.deserializer; // = getDeserializer(valueType); if (function == null) { function = DeSerializerUtil.getDeserializer(valueType.getName()); } if (function != null) { try { Object returnedValue = null; if (function instanceof Json2DataMapperFunction) { DataMapper classData = new DataMapper(valueToProcess, valueType, obj, classMapper, objectDTO.level, getPrettyIndentation()); Json2DataMapperFunction f = (Json2DataMapperFunction) function; return (T) f.apply(classData); } else if (function instanceof Json2FieldDataFunction) { Json2FieldDataFunction f = (Json2FieldDataFunction) function; FieldData fieldData = objectDTO.clone(); returnedValue = f.apply(fieldData); } else { returnedValue = function.apply(obj); } if (returnedValue instanceof Optional) { Optional opt = (Optional) returnedValue; returnedValue = opt.orElse(null); } if (returnedValue == null) { return null; } else if (valueType.isAssignableFrom(returnedValue.getClass())) { return (T) returnedValue; } else { // not the correct returned object type, do nothing } } catch (Exception e) { e.printStackTrace(); } } Map<String, Method> getters = getGetters(valueType); Map<String, Method> setters = getSetters(valueType); Map<String, Method> otherMethods = getOtherMethods(valueType); Set<String> processedNameSet = new HashSet<>(); Method jsonAnySetterMethod = null; Field[] fields = getFields(valueType); // getFields(obj); FIELD_NAMING format = getFieldNaming(); // @Expose boolean exposed = false; if (isUseGsonExpose()) { // check if @exposed is used any where if (valueType.isAnnotationPresent(com.google.gson.annotations.Expose.class)) { exposed = true; } if (!exposed) { for (Field f : fields) { if (f.isAnnotationPresent(com.google.gson.annotations.Expose.class)) { exposed = true; break; } } } } for (Field f : fields) { String name = f.getName(); String fieldName = name; String lcfieldName = name.toLowerCase(); Class<?> returnType = f.getType(); // value.getClass(); if (Modifier.isFinal(f.getModifiers()) && Modifier.isStatic(f.getModifiers())) { setters.remove(lcfieldName); nameKeys.remove(name); continue; } f.setAccessible(true); // getter and setter methods Method getter = null; Method setter = null; if (getters != null) { getter = getters.get(lcfieldName); } if (setters != null) { setter = setters.get(lcfieldName); } if (ignoreModifiers(f.getModifiers(), classMapper.includeFieldsWithModifiers)) { if (setter != null) { if (ignoreModifiers(setter.getModifiers(), classMapper.includeFieldsWithModifiers)) { setters.remove(lcfieldName); nameKeys.remove(name); continue; } } else { continue; } } // 6. Create a blank field mapper instance // using valueType of enclosing obj FieldMapper fieldMapper = new FieldMapper(name, name, valueType); // 7. get the class mapper of returnType ClassMapper fieldClassMapper = getClassMapper(returnType); // 8. Classify this field mapper with returnType fieldMapper = classifyFieldMapper(fieldMapper, fieldClassMapper); // 9. Classify this field mapper with enclosing class type fieldMapper = classifyFieldMapper(fieldMapper, classMapper); FieldMapper javaFieldMapper = getFieldMapper(name, null, valueType); boolean ignored = false; if (setter != null) { setter.setAccessible(true); } Set<String> names = new HashSet<>(); if (annotationSupport) { annotations = f.getAnnotations(); if (setter != null && ((javaFieldMapper == null || javaFieldMapper.useAttribute == null) && (fieldMapper.useAttribute == null || fieldMapper.useAttribute)) || (javaFieldMapper != null && javaFieldMapper.isDeserializing() && javaFieldMapper.useAttribute != null && javaFieldMapper.useAttribute)) { annotations = Stream .concat(Arrays.stream(annotations), Arrays.stream(setter.getDeclaredAnnotations())) .toArray(Annotation[]::new); } // no annotations, then try get method if ((annotations == null || annotations.length == 0) && getter != null) { annotations = getter.getDeclaredAnnotations(); } ca.oson.json.annotation.FieldMapper fieldMapperAnnotation = null; boolean exposexists = false; for (Annotation annotation : annotations) { if (ignoreField(annotation, classMapper.ignoreFieldsWithAnnotations)) { ignored = true; break; } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) { fieldMapperAnnotation = (ca.oson.json.annotation.FieldMapper) annotation; if (!(fieldMapperAnnotation.serialize() == BOOLEAN.BOTH || fieldMapperAnnotation.serialize() == BOOLEAN.FALSE)) { fieldMapperAnnotation = null; } } else if (annotation instanceof ca.oson.json.annotation.FieldMappers) { ca.oson.json.annotation.FieldMappers fieldMapperAnnotations = (ca.oson.json.annotation.FieldMappers) annotation; for (ca.oson.json.annotation.FieldMapper ann : fieldMapperAnnotations.value()) { if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.FALSE) { fieldMapperAnnotation = ann; //break; to enable the last one wins } } } else { switch (annotation.annotationType().getName()) { case "com.fasterxml.jackson.annotation.JsonAnySetter": case "org.codehaus.jackson.annotate.JsonAnySetter": fieldMapper.jsonAnySetter = true; break; case "javax.persistence.Transient": fieldMapper.ignore = true; break; case "com.fasterxml.jackson.annotation.JsonIgnore": case "org.codehaus.jackson.annotate.JsonIgnore": fieldMapper.ignore = true; break; case "com.fasterxml.jackson.annotation.JsonIgnoreProperties": JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation; if (!jsonIgnoreProperties.allowSetters()) { fieldMapper.ignore = true; } else { fieldMapper.ignore = false; classMapper.jsonIgnoreProperties.remove(name); } break; case "com.google.gson.annotations.Expose": Expose expose = (Expose) annotation; if (!expose.deserialize()) { fieldMapper.ignore = true; } exposexists = true; break; case "com.google.gson.annotations.Since": Since since = (Since) annotation; fieldMapper.since = since.value(); break; case "com.google.gson.annotations.Until": Until until = (Until) annotation; fieldMapper.until = until.value(); break; case "com.google.gson.annotations.SerializedName": SerializedName serializedName = (SerializedName) annotation; String[] alternates = serializedName.alternate(); if (alternates != null && alternates.length > 0) { for (String alternate : alternates) { names.add(alternate); } } break; case "com.fasterxml.jackson.annotation.JsonInclude": if (fieldMapper.defaultType == JSON_INCLUDE.NONE) { JsonInclude jsonInclude = (JsonInclude) annotation; switch (jsonInclude.content()) { case ALWAYS: fieldMapper.defaultType = JSON_INCLUDE.ALWAYS; break; case NON_NULL: fieldMapper.defaultType = JSON_INCLUDE.NON_NULL; break; case NON_ABSENT: fieldMapper.defaultType = JSON_INCLUDE.NON_NULL; break; case NON_EMPTY: fieldMapper.defaultType = JSON_INCLUDE.NON_EMPTY; break; case NON_DEFAULT: fieldMapper.defaultType = JSON_INCLUDE.NON_DEFAULT; break; case USE_DEFAULTS: fieldMapper.defaultType = JSON_INCLUDE.DEFAULT; break; } } break; case "com.fasterxml.jackson.annotation.JsonRawValue": if (((JsonRawValue) annotation).value()) { fieldMapper.jsonRawValue = true; } break; case "org.codehaus.jackson.annotate.JsonRawValue": if (((org.codehaus.jackson.annotate.JsonRawValue) annotation).value()) { fieldMapper.jsonRawValue = true; } break; case "org.junit.Ignore": fieldMapper.ignore = true; break; case "javax.persistence.Enumerated": fieldMapper.enumType = ((Enumerated) annotation).value(); break; case "javax.validation.constraints.NotNull": fieldMapper.required = true; break; case "com.fasterxml.jackson.annotation.JsonProperty": JsonProperty jsonProperty = (JsonProperty) annotation; Access access = jsonProperty.access(); if (access == Access.READ_ONLY) { fieldMapper.ignore = true; } if (jsonProperty.required()) { fieldMapper.required = true; } if (fieldMapper.defaultValue == null) { fieldMapper.defaultValue = jsonProperty.defaultValue(); } break; case "javax.validation.constraints.Size": Size size = (Size) annotation; if (size.min() > 0) { fieldMapper.min = (long) size.min(); } if (size.max() < Integer.MAX_VALUE) { fieldMapper.max = (long) size.max(); } break; case "javax.persistence.Column": Column column = (Column) annotation; if (column.length() != 255) { fieldMapper.length = column.length(); } if (column.scale() > 0) { fieldMapper.scale = column.scale(); } if (column.precision() > 0) { fieldMapper.precision = column.precision(); } if (!column.nullable()) { fieldMapper.required = true; } break; } String fname = ObjectUtil.getName(annotation); if (!StringUtil.isEmpty(fname)) { names.add(fname); } } } if (exposed && !exposexists) { fieldMapper.ignore = true; } // 10. Apply annotations from Oson if (fieldMapperAnnotation != null) { fieldMapper = overwriteBy(fieldMapper, fieldMapperAnnotation, classMapper); } } if (ignored) { nameKeys.remove(name); nameKeys.remove(fieldMapper.json); setters.remove(lcfieldName); if (exposed) { setNull(f, obj); } continue; } // 11. Apply Java configuration for this particular field if (javaFieldMapper != null && javaFieldMapper.isDeserializing()) { fieldMapper = overwriteBy(fieldMapper, javaFieldMapper); } if (fieldMapper.ignore != null && fieldMapper.ignore) { if (setter != null) { setters.remove(lcfieldName); } nameKeys.remove(name); nameKeys.remove(fieldMapper.json); if (exposed) { setNull(f, obj); } continue; } // in the ignored list if (ObjectUtil.inSet(name, classMapper.jsonIgnoreProperties)) { setters.remove(lcfieldName); nameKeys.remove(name); continue; } if (fieldMapper.jsonAnySetter != null && fieldMapper.jsonAnySetter && setter != null) { setters.remove(lcfieldName); otherMethods.put(lcfieldName, setter); continue; } if (fieldMapper.useField != null && !fieldMapper.useField) { // both should not be used, just like ignore if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) { getters.remove(lcfieldName); } continue; } if (fieldMapper.since != null && fieldMapper.since > getVersion()) { if (setter != null) { setters.remove(lcfieldName); } continue; } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) { if (setter != null) { setters.remove(lcfieldName); } continue; } // get value for name in map Object value = null; boolean jnameFixed = false; String json = fieldMapper.json; int size = nameKeys.size(); if (json == null) { if (setter != null) { setters.remove(lcfieldName); } continue; } else if (!json.equals(name)) { name = json; value = getMapValue(map, name, nameKeys); jnameFixed = true; } if (!jnameFixed) { for (String jsoname : names) { if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) { name = jsoname; value = getMapValue(map, name, nameKeys); if (value != null) { jnameFixed = true; break; } } } } if (!jnameFixed) { value = getMapValue(map, name, nameKeys); jnameFixed = true; } fieldMapper.java = fieldName; fieldMapper.json = name; // either not null, or a null value exists in the value map if (value != null || size == nameKeys.size() + 1) { Object oldValue = value; FieldData fieldData = new FieldData(obj, f, value, returnType, true, fieldMapper, objectDTO.level, objectDTO.set); fieldData.setter = setter; Class fieldType = guessComponentType(fieldData); value = json2Object(fieldData); if (StringUtil.isNull(value)) { if (classMapper.defaultType == JSON_INCLUDE.NON_NULL || classMapper.defaultType == JSON_INCLUDE.NON_EMPTY || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) { continue; } } else if (StringUtil.isEmpty(value)) { if (classMapper.defaultType == JSON_INCLUDE.NON_EMPTY || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) { continue; } } else if (DefaultValue.isDefault(value, returnType)) { if (classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) { continue; } } try { if (value == null && oldValue != null && oldValue.equals(f.get(obj) + "")) { // keep original value } else { f.set(obj, value); } } catch (IllegalAccessException | IllegalArgumentException ex) { //ex.printStackTrace(); if (setter != null) { ObjectUtil.setMethodValue(obj, setter, value); } } } setters.remove(lcfieldName); nameKeys.remove(name); } for (Entry<String, Method> entry : setters.entrySet()) { String lcfieldName = entry.getKey(); Method setter = entry.getValue(); setter.setAccessible(true); String name = setter.getName(); if (name != null && name.length() > 3 && name.substring(0, 3).equals("set") && name.substring(3).equalsIgnoreCase(lcfieldName)) { name = StringUtil.uncapitalize(name.substring(3)); } // just use field name, even it might not be a field String fieldName = name; if (ignoreModifiers(setter.getModifiers(), classMapper.includeFieldsWithModifiers)) { nameKeys.remove(name); continue; } if (Modifier.isFinal(setter.getModifiers()) && Modifier.isStatic(setter.getModifiers())) { nameKeys.remove(name); continue; } // 6. Create a blank field mapper instance FieldMapper fieldMapper = new FieldMapper(name, name, valueType); Class returnType = null; Class[] types = setter.getParameterTypes(); if (types != null && types.length > 0) { returnType = types[0]; } // not a proper setter if (returnType == null) { continue; } // 7. get the class mapper of returnType ClassMapper fieldClassMapper = getClassMapper(returnType); // 8. Classify this field mapper with returnType fieldMapper = classifyFieldMapper(fieldMapper, fieldClassMapper); // 9. Classify this field mapper with enclosing class type fieldMapper = classifyFieldMapper(fieldMapper, classMapper); FieldMapper javaFieldMapper = getFieldMapper(name, null, valueType); boolean ignored = false; Method getter = getters.get(lcfieldName); Set<String> names = new HashSet<>(); if (annotationSupport) { annotations = setter.getDeclaredAnnotations(); // no annotations, then try get method if ((annotations == null || annotations.length == 0) && getter != null) { annotations = getter.getDeclaredAnnotations(); } ca.oson.json.annotation.FieldMapper fieldMapperAnnotation = null; for (Annotation annotation : annotations) { if (ignoreField(annotation, classMapper.ignoreFieldsWithAnnotations)) { ignored = true; break; } else if (annotation instanceof ca.oson.json.annotation.FieldMapper) { fieldMapperAnnotation = (ca.oson.json.annotation.FieldMapper) annotation; if (!(fieldMapperAnnotation.serialize() == BOOLEAN.BOTH || fieldMapperAnnotation.serialize() == BOOLEAN.FALSE)) { fieldMapperAnnotation = null; } } else if (annotation instanceof ca.oson.json.annotation.FieldMappers) { ca.oson.json.annotation.FieldMappers fieldMapperAnnotations = (ca.oson.json.annotation.FieldMappers) annotation; for (ca.oson.json.annotation.FieldMapper ann : fieldMapperAnnotations.value()) { if (ann.serialize() == BOOLEAN.BOTH || ann.serialize() == BOOLEAN.FALSE) { fieldMapperAnnotation = ann; // break; } } } else { // to improve performance, using swith on string switch (annotation.annotationType().getName()) { case "com.fasterxml.jackson.annotation.JsonAnySetter": case "org.codehaus.jackson.annotate.JsonAnySetter": fieldMapper.jsonAnySetter = true; break; case "javax.persistence.Transient": fieldMapper.ignore = true; break; case "com.fasterxml.jackson.annotation.JsonIgnore": case "org.codehaus.jackson.annotate.JsonIgnore": fieldMapper.ignore = true; break; case "com.fasterxml.jackson.annotation.JsonIgnoreProperties": JsonIgnoreProperties jsonIgnoreProperties = (JsonIgnoreProperties) annotation; if (!jsonIgnoreProperties.allowSetters()) { fieldMapper.ignore = true; } else { fieldMapper.ignore = false; classMapper.jsonIgnoreProperties.remove(name); } break; case "com.google.gson.annotations.Expose": Expose expose = (Expose) annotation; if (!expose.deserialize()) { fieldMapper.ignore = true; } break; case "com.google.gson.annotations.Since": Since since = (Since) annotation; fieldMapper.since = since.value(); break; case "com.google.gson.annotations.Until": Until until = (Until) annotation; fieldMapper.until = until.value(); break; case "com.fasterxml.jackson.annotation.JsonInclude": if (fieldMapper.defaultType == JSON_INCLUDE.NONE) { JsonInclude jsonInclude = (JsonInclude) annotation; switch (jsonInclude.content()) { case ALWAYS: fieldMapper.defaultType = JSON_INCLUDE.ALWAYS; break; case NON_NULL: fieldMapper.defaultType = JSON_INCLUDE.NON_NULL; break; case NON_ABSENT: fieldMapper.defaultType = JSON_INCLUDE.NON_NULL; break; case NON_EMPTY: fieldMapper.defaultType = JSON_INCLUDE.NON_EMPTY; break; case NON_DEFAULT: fieldMapper.defaultType = JSON_INCLUDE.NON_DEFAULT; break; case USE_DEFAULTS: fieldMapper.defaultType = JSON_INCLUDE.DEFAULT; break; } } break; case "com.fasterxml.jackson.annotation.JsonRawValue": if (((JsonRawValue) annotation).value()) { fieldMapper.jsonRawValue = true; } break; case "org.codehaus.jackson.annotate.JsonRawValue": if (((org.codehaus.jackson.annotate.JsonRawValue) annotation).value()) { fieldMapper.jsonRawValue = true; } break; case "org.junit.Ignore": fieldMapper.ignore = true; break; case "javax.persistence.Enumerated": fieldMapper.enumType = ((Enumerated) annotation).value(); break; case "javax.validation.constraints.NotNull": fieldMapper.required = true; break; case "com.fasterxml.jackson.annotation.JsonProperty": JsonProperty jsonProperty = (JsonProperty) annotation; Access access = jsonProperty.access(); if (access == Access.READ_ONLY) { fieldMapper.ignore = true; } if (jsonProperty.required()) { fieldMapper.required = true; } if (fieldMapper.defaultValue == null) { fieldMapper.defaultValue = jsonProperty.defaultValue(); } break; case "javax.validation.constraints.Size": Size size = (Size) annotation; if (size.min() > 0) { fieldMapper.min = (long) size.min(); } if (size.max() < Integer.MAX_VALUE) { fieldMapper.max = (long) size.max(); } break; case "javax.persistence.Column": Column column = (Column) annotation; if (column.length() != 255) { fieldMapper.length = column.length(); } if (column.scale() > 0) { fieldMapper.scale = column.scale(); } if (column.precision() > 0) { fieldMapper.precision = column.precision(); } if (!column.nullable()) { fieldMapper.required = true; } break; } String fname = ObjectUtil.getName(annotation); if (fname != null) { names.add(fname); } } } // 10. Apply annotations from Oson if (fieldMapperAnnotation != null) { fieldMapper = overwriteBy(fieldMapper, fieldMapperAnnotation, classMapper); } } if (ignored) { nameKeys.remove(name); nameKeys.remove(fieldMapper.json); continue; } // 11. Apply Java configuration for this particular field if (javaFieldMapper != null && javaFieldMapper.isDeserializing()) { fieldMapper = overwriteBy(fieldMapper, javaFieldMapper); } if (fieldMapper.ignore != null && fieldMapper.ignore) { nameKeys.remove(name); nameKeys.remove(fieldMapper.json); continue; } // in the ignored list if (ObjectUtil.inSet(name, classMapper.jsonIgnoreProperties)) { nameKeys.remove(name); continue; } if (fieldMapper.useAttribute != null && !fieldMapper.useAttribute) { nameKeys.remove(name); nameKeys.remove(fieldMapper.json); continue; } if (fieldMapper.jsonAnySetter != null && fieldMapper.jsonAnySetter && setter != null) { setters.remove(lcfieldName); otherMethods.put(lcfieldName, setter); continue; } if (fieldMapper.since != null && fieldMapper.since > getVersion()) { nameKeys.remove(name); nameKeys.remove(fieldMapper.json); continue; } else if (fieldMapper.until != null && fieldMapper.until <= getVersion()) { nameKeys.remove(name); nameKeys.remove(fieldMapper.json); continue; } // get value for name in map Object value = null; boolean jnameFixed = false; String json = fieldMapper.json; if (json == null) { continue; } else if (!json.equals(name)) { name = json; value = getMapValue(map, name, nameKeys); jnameFixed = true; } if (!jnameFixed) { for (String jsoname : names) { if (!name.equals(jsoname) && !StringUtil.isEmpty(jsoname)) { name = jsoname; value = getMapValue(map, name, nameKeys); jnameFixed = true; break; } } } if (!jnameFixed) { value = getMapValue(map, name, nameKeys); jnameFixed = true; } fieldMapper.java = fieldName; fieldMapper.json = name; if (value != null) { FieldData fieldData = new FieldData(obj, null, value, returnType, true, fieldMapper, objectDTO.level, objectDTO.set); fieldData.setter = setter; Class fieldType = guessComponentType(fieldData); value = json2Object(fieldData); if (StringUtil.isNull(value)) { if (classMapper.defaultType == JSON_INCLUDE.NON_NULL || classMapper.defaultType == JSON_INCLUDE.NON_EMPTY || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) { continue; } } else if (StringUtil.isEmpty(value)) { if (classMapper.defaultType == JSON_INCLUDE.NON_EMPTY || classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) { continue; } } else if (DefaultValue.isDefault(value, returnType)) { if (classMapper.defaultType == JSON_INCLUDE.NON_DEFAULT) { continue; } } ObjectUtil.setMethodValue(obj, setter, value); nameKeys.remove(name); } } if (annotationSupport) { //@JsonAnySetter if (nameKeys.size() > 0) { for (Entry<String, Method> entry : otherMethods.entrySet()) { Method method = entry.getValue(); if (ignoreModifiers(method.getModifiers(), classMapper.includeFieldsWithModifiers)) { continue; } if (method.isAnnotationPresent(JsonAnySetter.class)) { if (ignoreField(JsonAnySetter.class, classMapper.ignoreFieldsWithAnnotations)) { continue; } jsonAnySetterMethod = method; } else if (method.isAnnotationPresent(org.codehaus.jackson.annotate.JsonAnySetter.class)) { if (ignoreField(org.codehaus.jackson.annotate.JsonAnySetter.class, classMapper.ignoreFieldsWithAnnotations)) { continue; } jsonAnySetterMethod = method; } else if (method.isAnnotationPresent(ca.oson.json.annotation.FieldMapper.class)) { ca.oson.json.annotation.FieldMapper annotation = (ca.oson.json.annotation.FieldMapper) method .getAnnotation(ca.oson.json.annotation.FieldMapper.class); if (annotation.jsonAnySetter() == BOOLEAN.TRUE) { jsonAnySetterMethod = method; break; } } } } } if (jsonAnySetterMethod != null) { Parameter[] parameters = jsonAnySetterMethod.getParameters(); if (parameters != null && parameters.length == 2) { for (String name : nameKeys) { Object value = map.get(name); // json to java, check if this name is allowed or changed String java = json2Java(name); if (value != null && !StringUtil.isEmpty(java)) { ObjectUtil.setMethodValue(obj, jsonAnySetterMethod, java, value); } } } } return obj; // | InvocationTargetException } catch (IllegalArgumentException e) { e.printStackTrace(); } return null; }
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; }/*w w w .j av a 2s .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) { } }