1 package de.juplo.jackson;
4 import com.fasterxml.jackson.core.JsonFactory;
5 import com.fasterxml.jackson.core.JsonLocation;
6 import com.fasterxml.jackson.core.JsonParser;
7 import com.fasterxml.jackson.core.JsonToken;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.util.Collections;
11 import java.util.Iterator;
12 import java.util.LinkedHashMap;
13 import java.util.LinkedList;
14 import java.util.List;
16 import java.util.NoSuchElementException;
17 import java.util.Spliterator;
18 import static java.util.Spliterator.IMMUTABLE;
19 import java.util.Spliterators;
20 import java.util.function.Consumer;
21 import java.util.stream.Stream;
22 import java.util.stream.StreamSupport;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
32 public class SimpleMapper
34 private static final Logger LOG =
35 LoggerFactory.getLogger(SimpleMapper.class);
38 private JsonFactory factory = new JsonFactory();
41 public static Stream<Object> getArrayStream(final JsonParser parser)
45 return StreamSupport.stream(getArraySpliterator(parser), false);
48 public static Spliterator<Object> getArraySpliterator(final JsonParser parser)
52 JsonToken token = parser.nextToken();
56 LOG.warn("empty input");
57 return Spliterators.emptySpliterator();
60 if (!JsonToken.START_ARRAY.equals(token))
62 throw new IllegalArgumentException("The root-element must be an array!");
65 return new Spliterator<Object>()
68 public boolean tryAdvance(Consumer<? super Object> action)
72 JsonToken token = parser.nextToken();
74 throw new IllegalArgumentException("Unexpected end of data!");
75 if (JsonToken.END_ARRAY.equals(token))
77 action.accept(convert(parser));
82 throw new IllegalArgumentException(e);
87 public Spliterator<Object> trySplit()
93 public long estimateSize()
95 return Long.MAX_VALUE;
99 public int characteristics()
106 public static Iterator<Object> getArrayIterator(final JsonParser parser)
110 JsonToken token = parser.nextToken();
114 LOG.warn("empty input");
115 return Collections.emptyIterator();
118 if (!JsonToken.START_ARRAY.equals(token))
120 throw new IllegalArgumentException("The root-element must be an array!");
123 return new Iterator<Object>()
127 public boolean tryAdvance(Consumer<? super Object> action)
131 JsonToken token = parser.nextToken();
133 throw new IllegalArgumentException("Unexpected end of data!");
134 if (JsonToken.END_ARRAY.equals(token))
135 throw new NoSuchElementException();
136 action.accept(convert(parser));
139 catch (IOException e)
141 throw new IllegalArgumentException(e);
145 public boolean hasNext()
154 JsonToken token = parser.nextToken();
156 throw new IllegalArgumentException("Unexpected end of data!");
157 if (JsonToken.END_ARRAY.equals(token))
159 action.accept(convert(parser));
162 catch (IOException e)
164 throw new IllegalArgumentException(e);
170 public Object processAttribute(InputStream is)
175 * Read the JSON and create the variables
177 JsonParser parser = factory.createParser(is);
179 JsonToken token = parser.nextToken();
183 LOG.warn("empty input-stream");
187 Object result = convert(parser);
189 if (parser.nextToken() != null)
190 fail(parser, "unexpected data after parsed variables");
194 catch (IOException e)
196 LOG.error("cannot parse input-stream as JSON: {}", e.getMessage());
197 throw new RuntimeException(e);
202 static Object convert(JsonParser parser) throws IOException
204 JsonToken token = parser.getCurrentToken();
206 fail(parser, "unexpected EOF");
210 case VALUE_STRING: return parser.getText();
211 case VALUE_NUMBER_INT: return parser.getIntValue();
212 case VALUE_NUMBER_FLOAT: return parser.getDoubleValue();
213 case START_OBJECT: return convertObject(parser);
214 case START_ARRAY: return convertArray(parser);
215 case VALUE_TRUE: return Boolean.TRUE;
216 case VALUE_FALSE: return Boolean.FALSE;
217 case VALUE_NULL: return null;
220 fail(parser, "unexpected token " + token.toString());
221 return null; // << Will never be reached, because fail always throws an exception
224 static Map<String, Object> convertObject(JsonParser parser) throws IOException
226 JsonToken token = parser.nextToken();
228 fail(parser, "unexpected EOF");
230 Map<String, Object> map = new LinkedHashMap<>();
232 while (!JsonToken.END_OBJECT.equals(token))
234 if (!JsonToken.FIELD_NAME.equals(token))
235 fail(parser, "expected a field-name");
237 String name = parser.getText();
239 Object value = convert(parser);
240 map.put(name, value);
242 token = parser.nextToken();
244 fail(parser, "unexpected EOF");
250 static List<Object> convertArray(JsonParser parser) throws IOException
252 JsonToken token = parser.nextToken();
254 fail(parser, "unexpected EOF");
256 List<Object> list = new LinkedList<>();
258 while (!JsonToken.END_ARRAY.equals(token))
260 list.add(convert(parser));
262 token = parser.nextToken();
264 fail(parser, "unexpected EOF");
270 static void fail(JsonParser parser, String message)
272 JsonLocation location = parser.getCurrentLocation();
274 "{} at char-offset {} (line {}, column {})",
276 location.getCharOffset(),
277 location.getLineNr(),
278 location.getColumnNr()
280 throw new RuntimeException("Cannot parse JSON: " + message);