JsonSerialisationUtil { public static Map<String, String> getSerialisedFieldClasses(final String className) { final Map<String, String> cachedResult = cache.get(className); if (null != cachedResult) { return cachedResult; } final Class<?> clazz; try { clazz = Class.forName(SimpleClassNameIdResolver.getClassName(className)); } catch (final Exception e) { throw new IllegalArgumentException("Class name was not recognised: " + className, e); } final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(clazz); final BeanDescription introspection = mapper.getSerializationConfig() .introspect(type); final Class<?> builder = introspection.findPOJOBuilder(); String buildMethodPrefix = "with"; if (null != builder) { JsonPOJOBuilder anno = findAnnotation(builder, JsonPOJOBuilder.class); if (null != anno) { buildMethodPrefix = anno.withPrefix(); } } Constructor<?> creator = null; for (final Constructor<?> constructor : type.getRawClass().getDeclaredConstructors()) { final JsonCreator anno = constructor.getAnnotation(JsonCreator.class); if (null != anno) { creator = constructor; break; } } final List<BeanPropertyDefinition> properties = introspection.findProperties(); final Map<String, String> fieldMap = new HashMap<>(); for (final BeanPropertyDefinition property : properties) { final String propName = property.getName(); final String propClass; if ("class".equals(propName)) { propClass = Class.class.getName(); } else { Type genericType = null; if (null != builder) { final String methodName = buildMethodPrefix + propName; Method matchedMethod = null; for (final Method method : builder.getMethods()) { if (methodName.equalsIgnoreCase(method.getName())) { final Type[] params = method.getGenericParameterTypes(); if (null != params && 1 == params.length) { final JsonSetter jsonSetter = method.getAnnotation(JsonSetter.class); if (null != jsonSetter && propName.equals(jsonSetter.value())) { matchedMethod = method; break; } final JsonProperty jsonProperty = method.getAnnotation(JsonProperty.class); if (null != jsonProperty && propName.equals(jsonProperty.value())) { matchedMethod = method; break; } if (null == matchedMethod) { matchedMethod = method; } else if (builder.equals(method.getReturnType())) { matchedMethod = method; } } } } if (null != matchedMethod) { genericType = matchedMethod.getGenericParameterTypes()[0]; } } if (null == genericType && null != creator) { for (final Parameter parameter : creator.getParameters()) { final JsonProperty anno = parameter.getAnnotation(JsonProperty.class); if (null != anno && propName.equals(anno.value())) { if (null != parameter.getParameterizedType()) { genericType = parameter.getParameterizedType(); } else { genericType = parameter.getType(); } break; } } } if (null == genericType && null != property.getSetter() && null != property.getSetter().getGenericParameterTypes() && 1 == property.getSetter().getGenericParameterTypes().length) { genericType = property.getSetter().getGenericParameterTypes()[0]; } if (null != genericType && genericType instanceof Class && ((Class) genericType).isEnum()) { genericType = String.class; } if (null == genericType) { propClass = Object.class.getName(); } else { propClass = getFieldTypeString(clazz, genericType); } } fieldMap.put(propName, propClass); } final Map<String, Map<String, String>> newCache = new HashMap<>(cache); newCache.put(className, Collections.unmodifiableMap(fieldMap)); cache = Collections.unmodifiableMap(newCache); return fieldMap; } private  JsonSerialisationUtil(); static Map<String, String> getSerialisedFieldClasses(final String className); static String getTypeString(final Type typeArg); static String getFieldTypeString(final Class<?> clazz, final Type typeArg);  }
@Test public void testClassWithNoFields() { final String className = ClassWithNoFields.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(className); assertTrue(result.entrySet().isEmpty()); }
@Test public void testClassWithJsonAnnotations() { final String className = ClassWithAnnotations.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(className); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("field1", String.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testClassWithCreator() { final String className = ClassWithCreator.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(className); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("field1", String.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testClassWithBuilder() { final String className = ClassWithBuilder.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(className); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("field1", String.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testIsIn() { final String className = IsIn.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(className); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("values", "java.lang.Object[]"); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testInRange() { final String className = InRange.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(className); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("start", "java.lang.Comparable<T>"); expectedValues.put("end", "java.lang.Comparable<T>"); expectedValues.put("startInclusive", Boolean.class.getName()); expectedValues.put("endInclusive", Boolean.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testInDateRangeAndInTimeRange() { final String classNameIDR = InDateRange.class.getName(); final String classNameITR = InTimeRange.class.getName(); final Map<String, String> resultIDR = JsonSerialisationUtil.getSerialisedFieldClasses(classNameIDR); final Map<String, String> resultITR = JsonSerialisationUtil.getSerialisedFieldClasses(classNameITR); final Map<String, String> expected = getExpectedIDRStringStringMap(); assertEquals(expected.entrySet(), resultIDR.entrySet()); assertEquals(resultIDR.entrySet(), resultITR.entrySet()); }
@Test public void testClassWithTypeParamAndOtherField() { final String classWithTypeParamAndOtherFieldName = ClassWithTypeParamAndOtherField.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(classWithTypeParamAndOtherFieldName); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("test", String.class.getName()); expectedValues.put("t", Object.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testClassWithJustTypeParam() { final String classWithTypeParamName = ClassWithTypeParam.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(classWithTypeParamName); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("t", Object.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }
@Test public void testClassWithTypeParamExtendingComparable() { final String classWithTypeParamExtendingComparableName = ClassWithTypeParamExtendingComparable.class.getName(); final Map<String, String> result = JsonSerialisationUtil.getSerialisedFieldClasses(classWithTypeParamExtendingComparableName); final Map<String, String> expectedValues = new HashMap<>(); expectedValues.put("t", Comparable.class.getName()); assertEquals(expectedValues.entrySet(), result.entrySet()); }