1 package de.juplo.jackson;
4 import com.fasterxml.jackson.core.JsonLocation;
5 import com.fasterxml.jackson.core.JsonParser;
6 import com.fasterxml.jackson.core.JsonToken;
7 import java.io.IOException;
8 import java.util.Iterator;
9 import java.util.LinkedHashMap;
10 import java.util.LinkedList;
11 import java.util.List;
13 import java.util.Map.Entry;
14 import java.util.NoSuchElementException;
15 import java.util.Spliterator;
16 import static java.util.Spliterator.IMMUTABLE;
17 import java.util.function.Consumer;
18 import java.util.stream.Stream;
19 import java.util.stream.StreamSupport;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
29 public abstract class SimpleMapper
31 private static final Logger LOG =
32 LoggerFactory.getLogger(SimpleMapper.class);
35 public static Spliterator<Object> getArraySpliterator(final JsonParser parser)
39 JsonToken token = parser.nextToken();
44 if (!JsonToken.START_ARRAY.equals(token))
45 fail(parser, "The root-element must be an array!");
47 return new Spliterator<Object>()
50 public boolean tryAdvance(Consumer<? super Object> action)
54 JsonToken token = parser.nextToken();
56 fail(parser, "Unexpected end of data!");
57 if (JsonToken.END_ARRAY.equals(token))
59 if (parser.nextToken() != null)
60 fail(parser, "unexpected data after parsed array");
63 action.accept(convertInternal(parser));
68 throw new IllegalArgumentException(e);
73 public Spliterator<Object> trySplit()
79 public long estimateSize()
81 return Long.MAX_VALUE;
85 public int characteristics()
92 public static Stream<Object> getArrayStream(final JsonParser parser)
96 return StreamSupport.stream(getArraySpliterator(parser), false);
99 public static Iterator<Object> getArrayIterator(final JsonParser parser)
103 Spliterator<Object> spliterator = getArraySpliterator(parser);
104 return new Iterator<Object>()
106 private Object next = null;
110 public boolean hasNext()
115 return spliterator.tryAdvance((Object o) -> { next = o; });
121 if (next == null && !hasNext())
122 throw new NoSuchElementException();
131 public static Spliterator<Entry<String, Object>> getObjectSpliterator(final JsonParser parser)
135 JsonToken token = parser.nextToken();
140 if (!JsonToken.START_OBJECT.equals(token))
141 fail(parser, "The root-element must be an object!");
143 return new Spliterator<Entry<String, Object>>()
146 public boolean tryAdvance(Consumer<? super Entry<String, Object>> action)
150 JsonToken token = parser.nextToken();
152 fail(parser, "Unexpected end of data!");
153 if (JsonToken.END_OBJECT.equals(token))
155 if (parser.nextToken() != null)
156 fail(parser, "unexpected data after parsed object");
159 if (!JsonToken.FIELD_NAME.equals(token))
160 fail(parser, "expected a field-name");
161 final String key = parser.getText();
163 final Object value = convertInternal(parser);
164 action.accept(new Entry<String, Object>()
167 public String getKey()
173 public Object getValue()
179 public Object setValue(Object value)
181 throw new UnsupportedOperationException("Not supported.");
186 catch (IOException e)
188 throw new IllegalArgumentException(e);
193 public Spliterator<Entry<String, Object>> trySplit()
199 public long estimateSize()
201 return Long.MAX_VALUE;
205 public int characteristics()
212 public static Stream<Entry<String, Object>> getObjectStream(final JsonParser parser)
216 return StreamSupport.stream(getObjectSpliterator(parser), false);
219 public static Iterator<Entry<String, Object>> getObjectIterator(
220 final JsonParser parser
225 Spliterator<Entry<String, Object>> spliterator = getObjectSpliterator(parser);
226 return new Iterator<Entry<String, Object>>()
228 private Entry<String, Object> next = null;
232 public boolean hasNext()
237 return spliterator.tryAdvance((Entry<String, Object> e) -> { next = e; });
241 public Entry<String, Object> next()
243 if (next == null && !hasNext())
244 throw new NoSuchElementException();
245 Entry<String, Object> e = next;
253 public static List<Object> convertArray(JsonParser parser) throws IOException
255 JsonToken token = parser.nextToken();
260 if (!JsonToken.START_ARRAY.equals(token))
261 fail(parser, "The root-element must be an array!");
263 List<Object> array = convertArrayInternal(parser);
265 if (parser.nextToken() != null)
266 fail(parser, "unexpected data after parsed array");
271 public static Map<String, Object> convertObject(JsonParser parser) throws IOException
273 JsonToken token = parser.nextToken();
278 if (!JsonToken.START_OBJECT.equals(token))
279 fail(parser, "The root-element must be an object!");
281 Map<String, Object> object = convertObjectInternal(parser);
283 if (parser.nextToken() != null)
284 fail(parser, "unexpected data after parsed object");
289 public static Object convert(JsonParser parser) throws IOException
291 JsonToken token = parser.nextToken();
302 fail(parser, "The root-element must be either an object or an array!");
305 Object object = convertInternal(parser);
307 if (parser.nextToken() != null)
308 fail(parser, "unexpected data after parsed object");
314 static Object convertInternal(JsonParser parser) throws IOException
316 JsonToken token = parser.getCurrentToken();
319 fail(parser, "unexpected EOF");
320 return null; // << Will never be reached, because fail always throws an exception
325 case VALUE_STRING: return parser.getText();
326 case VALUE_NUMBER_INT: return parser.getIntValue();
327 case VALUE_NUMBER_FLOAT: return parser.getDoubleValue();
328 case START_OBJECT: return convertObjectInternal(parser);
329 case START_ARRAY: return convertArrayInternal(parser);
330 case VALUE_TRUE: return Boolean.TRUE;
331 case VALUE_FALSE: return Boolean.FALSE;
332 case VALUE_NULL: return null;
335 fail(parser, "unexpected token " + token);
336 return null; // << Will never be reached, because fail always throws an exception
340 static Map<String, Object> convertObjectInternal(JsonParser parser)
344 JsonToken token = parser.nextToken();
346 fail(parser, "unexpected EOF");
348 Map<String, Object> map = new LinkedHashMap<>();
350 while (!JsonToken.END_OBJECT.equals(token))
352 if (!JsonToken.FIELD_NAME.equals(token))
353 fail(parser, "expected a field-name");
355 String name = parser.getText();
357 Object value = convertInternal(parser);
358 map.put(name, value);
360 token = parser.nextToken();
362 fail(parser, "unexpected EOF");
368 static List<Object> convertArrayInternal(JsonParser parser) throws IOException
370 JsonToken token = parser.nextToken();
372 fail(parser, "unexpected EOF");
374 List<Object> list = new LinkedList<>();
376 while (!JsonToken.END_ARRAY.equals(token))
378 list.add(convertInternal(parser));
380 token = parser.nextToken();
382 fail(parser, "unexpected EOF");
389 static void fail(JsonParser parser, String message)
391 JsonLocation location = parser.getCurrentLocation();
393 "{} at char-offset {} (line {}, column {})",
395 location.getCharOffset(),
396 location.getLineNr(),
397 location.getColumnNr()
399 throw new IllegalArgumentException("Cannot parse JSON: " + message);