1 package com.atlassian.plugins.rest.doclet.generators.schema;
2
3 import com.atlassian.plugins.rest.doclet.generators.schema.Schema.Type;
4 import com.google.common.base.Objects;
5 import com.google.common.collect.ImmutableMap;
6 import org.codehaus.jackson.annotate.JsonRawValue;
7 import org.joda.time.DateTime;
8
9 import java.lang.reflect.AnnotatedElement;
10 import java.net.URI;
11 import java.util.Date;
12 import java.util.Map;
13 import java.util.Optional;
14
15 public class Types {
16
17 private Types() {}
18
19 private static final Map<Class<?>, Type> classToJsonType;
20
21 static {
22 ImmutableMap.Builder<Class<?>, Type> builder = ImmutableMap.<Class<?>, Type>builder()
23 .put(String.class, Type.String)
24 .put(Integer.class, Type.Integer)
25 .put(Long.class, Type.Integer)
26 .put(Number.class, Type.Number)
27 .put(Boolean.class, Type.Boolean)
28 .put(URI.class, Type.Uri)
29 .put(Enum.class, Type.String)
30 .put(Date.class, Type.String);
31 try {
32 builder.put(DateTime.class, Type.String);
33 } catch (NoClassDefFoundError notFound) {
34
35 }
36
37 classToJsonType = builder.build();
38 }
39
40 private static final Map<String, Type> primitiveTypeToJsonType = ImmutableMap.<String, Type>builder()
41 .put("boolean", Type.Boolean)
42 .put("int", Type.Integer)
43 .put("short", Type.Integer)
44 .put("long", Type.Integer)
45 .put("double", Type.Number)
46 .put("float", Type.Number)
47 .put("char", Type.String)
48 .put("byte", Type.Integer)
49 .build();
50
51 public static Type resolveType(final Class<?> modelClass, final AnnotatedElement containingField) {
52 if (containingField != null && containingField.isAnnotationPresent(JsonRawValue.class)) {
53 return Type.Any;
54 } else if (isPrimitive(modelClass)) {
55 return getPrimitiveType(modelClass).get();
56 } else if (isCollection(modelClass)) {
57 return Type.Array;
58 } else if (modelClass == Object.class) {
59 return Type.Any;
60 } else {
61 return Type.Object;
62 }
63 }
64
65 public static boolean isPrimitive(Class<?> modelClass) {
66 return getPrimitiveType(modelClass).isPresent();
67 }
68
69 private static Optional<Type> getPrimitiveType(Class<?> modelClass) {
70 for (Map.Entry<Class<?>, Type> classToTypeName : classToJsonType.entrySet()) {
71 if (classToTypeName.getKey().isAssignableFrom(modelClass)) {
72 return Optional.of(classToTypeName.getValue());
73 }
74 }
75
76 if (modelClass.isPrimitive()) {
77 Type mapped = primitiveTypeToJsonType.get(modelClass.getSimpleName());
78 return Optional.of(Objects.firstNonNull(mapped, Type.String));
79 }
80
81 return Optional.empty();
82 }
83
84 public static boolean isCollection(final Class<?> type) {
85 return type.isArray() || Iterable.class.isAssignableFrom(type);
86 }
87 }