1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.pipeline.impl;
21
22 import io.wcm.caravan.pipeline.JsonPipelineInputException;
23 import io.wcm.caravan.pipeline.JsonPipelineOutputException;
24
25 import java.io.IOException;
26 import java.io.StringWriter;
27
28 import rx.functions.Func1;
29
30 import com.fasterxml.jackson.core.JsonFactory;
31 import com.fasterxml.jackson.core.JsonGenerator;
32 import com.fasterxml.jackson.core.JsonParser;
33 import com.fasterxml.jackson.databind.DeserializationFeature;
34 import com.fasterxml.jackson.databind.JsonNode;
35 import com.fasterxml.jackson.databind.ObjectMapper;
36 import com.fasterxml.jackson.databind.node.ArrayNode;
37 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
38 import com.fasterxml.jackson.databind.node.ObjectNode;
39
40
41
42
43 public final class JacksonFunctions {
44
45 private static ObjectMapper objectMapper = new ObjectMapper()
46 .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
47 .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
48
49 private static JsonFactory jsonFactory = new JsonFactory(objectMapper)
50 .enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
51 .enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
52
53 private static JsonNodeFactory nodeFactory = JsonNodeFactory.withExactBigDecimals(false);
54
55
56
57 private JacksonFunctions() {
58 }
59
60
61
62
63
64
65
66
67
68
69 public static JsonNode stringToNode(String jsonString) {
70 JsonNode node = null;
71 try {
72 node = jsonFactory.createParser(jsonString).readValueAsTree();
73 }
74 catch (IOException ex) {
75 throw new JsonPipelineInputException(500, "Failed to parse JSON: " + jsonString, ex);
76 }
77 return node;
78 };
79
80
81
82
83
84
85
86 public static ObjectNode stringToObjectNode(String jsonString) {
87 ObjectNode node = null;
88 try {
89 node = jsonFactory.createParser(jsonString).readValueAsTree();
90 }
91 catch (IOException | ClassCastException ex) {
92 throw new JsonPipelineInputException(500, "Failed to parse JSON object from: " + jsonString, ex);
93 }
94 return node;
95 };
96
97
98
99
100
101
102
103 public static String nodeToString(JsonNode node) {
104 if (node.isMissingNode()) {
105 throw new JsonPipelineOutputException(
106 "Received a MissingNode from the JSON pipeline output. Please do not serialize this result as a String and handle MissingNode in your client.");
107 }
108 try {
109 StringWriter writer = new StringWriter();
110 JsonGenerator generator = jsonFactory.createGenerator(writer);
111 generator.writeObject(node);
112 return writer.toString();
113 }
114 catch (IOException ex) {
115 throw new JsonPipelineOutputException("Failed to serialize JsonNode. This was quite unexpected.", ex);
116 }
117 };
118
119
120
121
122
123
124
125 public static ObjectNode wrapInObject(String targetProperty, JsonNode propertyValue) {
126 ObjectNode objectNode = nodeFactory.objectNode();
127 objectNode.set(targetProperty, propertyValue);
128 return objectNode;
129 }
130
131
132
133
134 public static ObjectNode emptyObject() {
135 return nodeFactory.objectNode();
136 }
137
138
139
140
141
142
143
144 public static JsonNode pojoToNode(Object object) {
145 JsonNode node = null;
146 try {
147 node = objectMapper.valueToTree(object);
148 }
149 catch (IllegalArgumentException ex) {
150 throw new JsonPipelineInputException(500, "Failed to create JSONNode from object of class " + object.getClass().getName(), ex);
151 }
152 return node;
153 };
154
155
156
157
158
159
160
161
162 public static String pojoToString(Object pojo) {
163 try {
164 StringWriter writer = new StringWriter();
165 objectMapper.writeValue(writer, pojo);
166 return writer.toString();
167 }
168 catch (IOException ex) {
169 throw new JsonPipelineOutputException("Failed to serialize entity to JSON string", ex);
170 }
171 };
172
173
174
175
176
177
178
179
180
181
182 public static <T> Func1<String, T> stringToPojo(Class<T> targetType) {
183 return jsonString -> {
184 try {
185 return jsonFactory.createParser(jsonString).readValueAs(targetType);
186 }
187 catch (IOException ex) {
188 throw new JsonPipelineInputException(500, "Failed to create entity of " + targetType.getName() + " from JSON", ex);
189 }
190 };
191 }
192
193
194
195
196
197
198
199 public static <T> Func1<JsonNode, T> nodeToPojo(Class<T> targetType) {
200 return jsonNode -> {
201 String jsonString = nodeToString(jsonNode);
202 return stringToPojo(targetType).call(jsonString);
203 };
204 }
205
206 }