source: josm/trunk/src/javax/json/stream/JsonParser.java@ 13590

Last change on this file since 13590 was 13231, checked in by Don-vip, 6 years ago

see #15682 - upgrade to JSR 374 (JSON Processing) API 1.1.2

File size: 18.6 KB
Line 
1/*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright (c) 2011-2017 Oracle and/or its affiliates. All rights reserved.
5 *
6 * The contents of this file are subject to the terms of either the GNU
7 * General Public License Version 2 only ("GPL") or the Common Development
8 * and Distribution License("CDDL") (collectively, the "License"). You
9 * may not use this file except in compliance with the License. You can
10 * obtain a copy of the License at
11 * https://oss.oracle.com/licenses/CDDL+GPL-1.1
12 * or LICENSE.txt. See the License for the specific
13 * language governing permissions and limitations under the License.
14 *
15 * When distributing the software, include this License Header Notice in each
16 * file and include the License file at LICENSE.txt.
17 *
18 * GPL Classpath Exception:
19 * Oracle designates this particular file as subject to the "Classpath"
20 * exception as provided by Oracle in the GPL Version 2 section of the License
21 * file that accompanied this code.
22 *
23 * Modifications:
24 * If applicable, add the following below the License Header, with the fields
25 * enclosed by brackets [] replaced by your own identifying information:
26 * "Portions Copyright [year] [name of copyright owner]"
27 *
28 * Contributor(s):
29 * If you wish your version of this file to be governed by only the CDDL or
30 * only the GPL Version 2, indicate your decision by adding "[Contributor]
31 * elects to include this software in this distribution under the [CDDL or GPL
32 * Version 2] license." If you don't indicate a single choice of license, a
33 * recipient has the option to distribute your version of this file under
34 * either the CDDL, the GPL Version 2 or to extend the choice of license to
35 * its licensees as provided above. However, if you add GPL Version 2 code
36 * and therefore, elected the GPL Version 2 license, then the option applies
37 * only if the new code is made subject to such option by the copyright
38 * holder.
39 */
40
41package javax.json.stream;
42
43
44import java.io.Closeable;
45import java.math.BigDecimal;
46import java.util.stream.Stream;
47import java.util.Map;
48
49import javax.json.JsonValue;
50import javax.json.JsonObject;
51import javax.json.JsonArray;
52
53/**
54 * Provides forward, read-only access to JSON data in a streaming way. This
55 * is the most efficient way for reading JSON data.
56 * This is the only way to parse and process JSON data that are too big to be loaded in memory.
57 * <p>The class
58 * {@link javax.json.Json} contains methods to create parsers from input
59 * sources ({@link java.io.InputStream} and {@link java.io.Reader}).
60 *
61 * <p>
62 * The following example demonstrates how to create a parser from a string
63 * that contains an empty JSON array:
64 * <pre>
65 * <code>
66 * JsonParser parser = Json.createParser(new StringReader("[]"));
67 * </code>
68 * </pre>
69 *
70 * <p>
71 * The class {@link JsonParserFactory} also contains methods to create
72 * {@code JsonParser} instances. {@link JsonParserFactory} is preferred
73 * when creating multiple parser instances. A sample usage is shown
74 * in the following example:
75 * <pre>
76 * <code>
77 * JsonParserFactory factory = Json.createParserFactory();
78 * JsonParser parser1 = factory.createParser(...);
79 * JsonParser parser2 = factory.createParser(...);
80 * </code>
81 * </pre>
82 *
83 * <p>
84 * {@code JsonParser} parses JSON using the pull parsing programming model.
85 * In this model the client code controls the thread and calls the method
86 * {@code next()} to advance the parser to the next state after
87 * processing each element. The parser can generate the following events:
88 * {@code START_OBJECT}, {@code END_OBJECT}, {@code START_ARRAY},
89 * {@code END_ARRAY}, {@code KEY_NAME}, {@code VALUE_STRING},
90 * {@code VALUE_NUMBER}, {@code VALUE_TRUE}, {@code VALUE_FALSE},
91 * and {@code VALUE_NULL}.
92 *
93 * <p>
94 * <b>For example</b>, for an empty JSON object ({ }), the parser generates the event
95 * {@code START_OBJECT} with the first call to the method {@code next()} and the
96 * event {@code END_OBJECT} with the second call to the method {@code next()}.
97 * The following code demonstrates how to access these events:
98 *
99 * <pre>
100 * <code>
101 * Event event = parser.next(); // START_OBJECT
102 * event = parser.next(); // END_OBJECT
103 * </code>
104 * </pre>
105 *
106 * <p>
107 * <b>For example</b>, for the following JSON:
108 * <pre>
109 * {
110 * "firstName": "John", "lastName": "Smith", "age": 25,
111 * "phoneNumber": [
112 * { "type": "home", "number": "212 555-1234" },
113 * { "type": "fax", "number": "646 555-4567" }
114 * ]
115 * }
116 * </pre>
117 *
118 * <p>calls to the method {@code next()} result in parse events at the specified
119 * locations below (marked in bold):
120 *
121 * <pre>
122 * {<B>START_OBJECT</B>
123 * "firstName"<B>KEY_NAME</B>: "John"<B>VALUE_STRING</B>, "lastName"<B>KEY_NAME</B>: "Smith"<B>VALUE_STRING</B>, "age"<B>KEY_NAME</B>: 25<B>VALUE_NUMBER</B>,
124 * "phoneNumber"<B>KEY_NAME</B> : [<B>START_ARRAY</B>
125 * {<B>START_OBJECT</B> "type"<B>KEY_NAME</B>: "home"<B>VALUE_STRING</B>, "number"<B>KEY_NAME</B>: "212 555-1234"<B>VALUE_STRING</B> }<B>END_OBJECT</B>,
126 * {<B>START_OBJECT</B> "type"<B>KEY_NAME</B>: "fax"<B>VALUE_STRING</B>, "number"<B>KEY_NAME</B>: "646 555-4567"<B>VALUE_STRING</B> }<B>END_OBJECT</B>
127 * ]<B>END_ARRAY</B>
128 * }<B>END_OBJECT</B>
129 * </pre>
130 *
131 * The methods {@link #next()} and {@link #hasNext()} enable iteration over
132 * parser events to process JSON data. {@code JsonParser} provides get methods
133 * to obtain the value at the current state of the parser. For example, the
134 * following code shows how to obtain the value "John" from the JSON above:
135 *
136 * <pre>
137 * <code>
138 * Event event = parser.next(); // START_OBJECT
139 * event = parser.next(); // KEY_NAME
140 * event = parser.next(); // VALUE_STRING
141 * parser.getString(); // "John"
142 * </code>
143 * </pre>
144 *
145 * Starting in version 1.1, it is possible to build a partial JSON object
146 * model from the stream, at the current parser position.
147 * The methods {@link #getArray} and {@link #getObject} can be used to read in
148 * a {@code JsonArray} or {@code JsonObject}. For example, the following code
149 * shows how to obtain the phoneNumber in a JsonArray, from the JSON above:
150 *
151 * <pre><code>
152 * while (parser.hasNext() {
153 * Event event = parser.next();
154 * if (event == JsonParser.Event.KEY_NAME ) {
155 * String key = getString();
156 * event = parser.next();
157 * if (key.equals("phoneNumber") {
158 * JsonArray phones = parser.getArray();
159 * }
160 * }
161 * }
162 * </code></pre>
163 *
164 * The methods {@link #getArrayStream} and {@link #getObjectStream} can be used
165 * to get a stream of the elements of a {@code JsonArray} or {@code JsonObject}.
166 * For example, the following code shows another way to obtain John's phoneNumber
167 * in a {@code JsonArray} :
168 *
169 * <pre>{@code
170 * Event event = parser.next(); // START_OBJECT
171 * JsonArray phones = (JsonArray)
172 * parser.getObjectStream().filter(e->e.getKey().equals("phoneNumber"))
173 * .map(e->e.getValue())
174 * .findFirst()
175 * .get();
176 * }</pre>
177 *
178 * The methods {@link #skipArray} and {@link #skipObject} can be used to
179 * skip tokens and position the parser to {@code END_ARRAY} or
180 * {@code END_OBJECT}.
181 * <p>
182 * {@code JsonParser} can be used to parse sequence of JSON values that are not
183 * enclosed in a JSON array, e.g. { } { }. The following code demonstrates how
184 * to parse such sequence.
185 * <pre><code>
186 * JsonParser parser = Json.createParser(...);
187 * while (parser.hasNext) {
188 * parser.next(); // advance parser state
189 * JsonValue value = parser.getValue();
190 * }
191 * </code></pre>
192 *
193 * @see javax.json.Json
194 * @see JsonParserFactory
195 */
196public interface JsonParser extends /*Auto*/Closeable {
197
198 /**
199 * An event from {@code JsonParser}.
200 */
201 enum Event {
202 /**
203 * Start of a JSON array. The position of the parser is after '['.
204 */
205 START_ARRAY,
206 /**
207 * Start of a JSON object. The position of the parser is after '{'.
208 */
209 START_OBJECT,
210 /**
211 * Name in a name/value pair of a JSON object. The position of the parser
212 * is after the key name. The method {@link #getString} returns the key
213 * name.
214 */
215 KEY_NAME,
216 /**
217 * String value in a JSON array or object. The position of the parser is
218 * after the string value. The method {@link #getString}
219 * returns the string value.
220 */
221 VALUE_STRING,
222 /**
223 * Number value in a JSON array or object. The position of the parser is
224 * after the number value. {@code JsonParser} provides the following
225 * methods to access the number value: {@link #getInt},
226 * {@link #getLong}, and {@link #getBigDecimal}.
227 */
228 VALUE_NUMBER,
229 /**
230 * {@code true} value in a JSON array or object. The position of the
231 * parser is after the {@code true} value.
232 */
233 VALUE_TRUE,
234 /**
235 * {@code false} value in a JSON array or object. The position of the
236 * parser is after the {@code false} value.
237 */
238 VALUE_FALSE,
239 /**
240 * {@code null} value in a JSON array or object. The position of the
241 * parser is after the {@code null} value.
242 */
243 VALUE_NULL,
244 /**
245 * End of a JSON object. The position of the parser is after '}'.
246 */
247 END_OBJECT,
248 /**
249 * End of a JSON array. The position of the parser is after ']'.
250 */
251 END_ARRAY
252 }
253
254 /**
255 * Returns {@code true} if there are more parsing states. This method returns
256 * {@code false} if the parser reaches the end of the JSON text.
257 *
258 * @return {@code true} if there are more parsing states.
259 * @throws javax.json.JsonException if an i/o error occurs (IOException
260 * would be cause of JsonException)
261 * @throws JsonParsingException if the parser encounters invalid JSON
262 * when advancing to next state.
263 */
264 boolean hasNext();
265
266 /**
267 * Returns the event for the next parsing state.
268 *
269 * @throws javax.json.JsonException if an i/o error occurs (IOException
270 * would be cause of JsonException)
271 * @throws JsonParsingException if the parser encounters invalid JSON
272 * when advancing to next state.
273 * @throws java.util.NoSuchElementException if there are no more parsing
274 * states.
275 * @return the event for the next parsing state
276 */
277 Event next();
278
279 /**
280 * Returns a {@code String} for the name in a name/value pair,
281 * for a string value or a number value. This method should only be called
282 * when the parser state is {@link Event#KEY_NAME}, {@link Event#VALUE_STRING},
283 * or {@link Event#VALUE_NUMBER}.
284 *
285 * @return a name when the parser state is {@link Event#KEY_NAME}
286 * a string value when the parser state is {@link Event#VALUE_STRING}
287 * a number value when the parser state is {@link Event#VALUE_NUMBER}
288 * @throws IllegalStateException when the parser state is not
289 * {@code KEY_NAME}, {@code VALUE_STRING}, or {@code VALUE_NUMBER}
290 */
291 String getString();
292
293 /**
294 * Returns true if the JSON number at the current parser state is a
295 * integral number. A {@link BigDecimal} may be used to store the value
296 * internally and this method semantics are defined using its
297 * {@code scale()}. If the scale is zero, then it is considered integral
298 * type. This integral type information can be used to invoke an
299 * appropriate accessor method to obtain a numeric value as in the
300 * following example:
301 *
302 * <pre>
303 * <code>
304 * JsonParser parser = ...
305 * if (parser.isIntegralNumber()) {
306 * parser.getInt(); // or other methods to get integral value
307 * } else {
308 * parser.getBigDecimal();
309 * }
310 * </code>
311 * </pre>
312 *
313 * @return true if this number is a integral number, otherwise false
314 * @throws IllegalStateException when the parser state is not
315 * {@code VALUE_NUMBER}
316 */
317 boolean isIntegralNumber();
318
319 /**
320 * Returns a JSON number as an integer. The returned value is equal
321 * to {@code new BigDecimal(getString()).intValue()}. Note that
322 * this conversion can lose information about the overall magnitude
323 * and precision of the number value as well as return a result with
324 * the opposite sign. This method should only be called when the parser
325 * state is {@link Event#VALUE_NUMBER}.
326 *
327 * @return an integer for a JSON number
328 * @throws IllegalStateException when the parser state is not
329 * {@code VALUE_NUMBER}
330 * @see java.math.BigDecimal#intValue()
331 */
332 int getInt();
333
334 /**
335 * Returns a JSON number as a long. The returned value is equal
336 * to {@code new BigDecimal(getString()).longValue()}. Note that this
337 * conversion can lose information about the overall magnitude and
338 * precision of the number value as well as return a result with
339 * the opposite sign. This method is only called when the parser state is
340 * {@link Event#VALUE_NUMBER}.
341 *
342 * @return a long for a JSON number
343 * @throws IllegalStateException when the parser state is not
344 * {@code VALUE_NUMBER}
345 * @see java.math.BigDecimal#longValue()
346 */
347 long getLong();
348
349 /**
350 * Returns a JSON number as a {@code BigDecimal}. The {@code BigDecimal}
351 * is created using {@code new BigDecimal(getString())}. This
352 * method should only called when the parser state is
353 * {@link Event#VALUE_NUMBER}.
354 *
355 * @return a {@code BigDecimal} for a JSON number
356 * @throws IllegalStateException when the parser state is not
357 * {@code VALUE_NUMBER}
358 */
359 BigDecimal getBigDecimal();
360
361 /**
362 * Return the location that corresponds to the parser's current state in
363 * the JSON input source. The location information is only valid in the
364 * current parser state (or until the parser is advanced to a next state).
365 *
366 * @return a non-null location corresponding to the current parser state
367 * in JSON input source
368 */
369 JsonLocation getLocation();
370
371 /**
372 * Returns a {@code JsonObject} and advances the parser to the
373 * corresponding {@code END_OBJECT}.
374 *
375 * @return the {@code JsonObject} at the current parser position
376 *
377 * @throws IllegalStateException when the parser state is not
378 * {@code START_OBJECT}
379 *
380 * @since 1.1
381 */
382 default public JsonObject getObject() {
383 throw new UnsupportedOperationException();
384 }
385
386 /**
387 * Returns a {@code JsonValue} at the current parser position.
388 * If the parser state is {@code START_ARRAY}, the behavior is
389 * the same as {@link #getArray}. If the parser state is
390 * {@code START_OBJECT}, the behavior is the same as
391 * {@link #getObject}. For all other cases, if applicable, the JSON value is
392 * read and returned.
393 *
394 * @return the {@code JsonValue} at the current parser position.
395 * @throws IllegalStateException when the parser state is
396 * {@code END_OBJECT} or {@code END_ARRAY}
397 *
398 * @since 1.1
399 */
400 default public JsonValue getValue() {
401 throw new UnsupportedOperationException();
402 }
403
404 /**
405 * Returns a {@code JsonArray} and advance the parser to the
406 * the corresponding {@code END_ARRAY}.
407 *
408 * @return the {@code JsonArray} at the current parser position
409 *
410 * @throws IllegalStateException when the parser state is not
411 * {@code START_ARRAY}
412 *
413 * @since 1.1
414 */
415 default public JsonArray getArray() {
416 throw new UnsupportedOperationException();
417 }
418
419 /**
420 * Returns a stream of the {@code JsonArray} elements.
421 * The parser state must be {@code START_ARRAY}.
422 * The elements are read lazily, on an as-needed basis, as
423 * required by the stream operations.
424 * If the stream operations do not consume
425 * all of the array elements, {@link skipArray} can be used to
426 * skip the unprocessed array elements.
427 *
428 * @return a stream of elements of the {@code JsonArray}
429 *
430 * @throws IllegalStateException when the parser state is not
431 * {@code START_ARRAY}
432 *
433 * @since 1.1
434 */
435 default public Stream<JsonValue> getArrayStream() {
436 throw new UnsupportedOperationException();
437 }
438
439 /**
440 * Returns a stream of the {@code JsonObject}'s
441 * name/value pairs. The parser state must be {@code START_OBJECT}.
442 * The name/value pairs are read lazily, on an as-needed basis, as
443 * required by the stream operations.
444 * If the stream operations do not consume
445 * all of the object's name/value pairs, {@link skipObject} can be
446 * used to skip the unprocessed elements.
447 *
448 * @return a stream of name/value pairs of the {@code JsonObject}
449 *
450 * @throws IllegalStateException when the parser state is not
451 * {@code START_OBJECT}
452 *
453 * @since 1.1
454 */
455 default public Stream<Map.Entry<String,JsonValue>> getObjectStream() {
456 throw new UnsupportedOperationException();
457 }
458
459 /**
460 * Returns a stream of {@code JsonValue} from a sequence of
461 * JSON values. The values are read lazily, on an as-needed basis,
462 * as needed by the stream operations.
463 *
464 * @return a Stream of {@code JsonValue}
465 *
466 * @throws IllegalStateException if the parser is in an array or object.
467 *
468 * @since 1.1
469 */
470 default public Stream<JsonValue> getValueStream() {
471 throw new UnsupportedOperationException();
472 }
473
474 /**
475 * Advance the parser to {@code END_ARRAY}.
476 * If the parser is in array context, i.e. it has previously
477 * encountered a {@code START_ARRAY} without encountering the
478 * corresponding {@code END_ARRAY}, the parser is advanced to
479 * the corresponding {@code END_ARRAY}.
480 * If the parser is not in any array context, nothing happens.
481 *
482 * @since 1.1
483 */
484 default public void skipArray() {
485 throw new UnsupportedOperationException();
486 }
487
488 /**
489 * Advance the parser to {@code END_OBJECT}.
490 * If the parser is in object context, i.e. it has previously
491 * encountered a {@code START_OBJECT} without encountering the
492 * corresponding {@code END_OBJECT}, the parser is advanced to
493 * the corresponding {@code END_OBJECT}.
494 * If the parser is not in any object context, nothing happens.
495 *
496 * @since 1.1
497 */
498 default public void skipObject() {
499 throw new UnsupportedOperationException();
500 }
501
502 /**
503 * Closes this parser and frees any resources associated with the
504 * parser. This method closes the underlying input source.
505 *
506 * @throws javax.json.JsonException if an i/o error occurs (IOException
507 * would be cause of JsonException)
508 */
509 @Override
510 void close();
511}
Note: See TracBrowser for help on using the repository browser.