001/* 002 * Copyright (C) 2014 Square, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.avaje.json; 017 018import java.io.Closeable; 019import java.math.BigDecimal; 020import java.math.BigInteger; 021 022/** 023 * Reads json content as a stream of JSON tokens and content. 024 */ 025public interface JsonReader extends Closeable { 026 027 /** 028 * Unwrap and return the underlying JsonParser. 029 * <p> 030 * When using avaje-jsonb-jackson this will return the underlying Jackson JsonParser. 031 * 032 * <pre>{@code 033 * 034 * // when using avaje-jsonb-jackson 035 * var jacksonParser = jsonReader.unwrap(JsonParser.class); 036 * 037 * }</pre> 038 */ 039 <T> T unwrap(Class<T> type); 040 041 /** 042 * Read the beginning of an ARRAY or x-json-stream (new line delimited json content). 043 */ 044 default void beginStream() { 045 beginArray(); 046 } 047 048 /** 049 * Read the end of an ARRAY or x-json-stream (new line delimited json content). 050 */ 051 default void endStream() { 052 endArray(); 053 } 054 055 /** 056 * Return true if there is a next element in an ARRAY or x-json-stream (new line delimited json content). 057 * <p> 058 * Effectively this allows for new line delimited rather than commas between array elements. 059 */ 060 default boolean hasNextStreamElement() { 061 return hasNextElement(); 062 } 063 064 /** 065 * Read array begin. 066 */ 067 void beginArray(); 068 069 /** 070 * Read array end. 071 */ 072 void endArray(); 073 074 /** 075 * Return true if there is a next element in an ARRAY. 076 */ 077 boolean hasNextElement(); 078 079 /** 080 * Set the current property names. 081 * <p> 082 * Can be used by the reader to optimize the reading of known names. 083 */ 084 void beginObject(PropertyNames names); 085 086 /** 087 * Read begin object. 088 */ 089 void beginObject(); 090 091 /** 092 * Read end object. 093 */ 094 void endObject(); 095 096 /** 097 * Return true if there is a next field to be read in an OBJECT. 098 */ 099 boolean hasNextField(); 100 101 /** 102 * Return the next field. 103 */ 104 String nextField(); 105 106 /** 107 * Return true if the value to be read is a null. 108 */ 109 boolean isNullValue(); 110 111 /** 112 * Read and return the next value as a boolean. 113 */ 114 boolean readBoolean(); 115 116 /** 117 * Read and return the next value as an int. 118 */ 119 int readInt(); 120 121 /** 122 * Read and return the next value as a long. 123 */ 124 long readLong(); 125 126 /** 127 * Read and return the next value as a double. 128 */ 129 double readDouble(); 130 131 /** 132 * Read and return the next value as a BigDecimal. 133 */ 134 BigDecimal readDecimal(); 135 136 /** 137 * Read and return the next value as a BigInteger. 138 */ 139 BigInteger readBigInteger(); 140 141 /** 142 * Read and return the next value as String. 143 */ 144 String readString(); 145 146 /** 147 * Read and return the binary value from base64. 148 */ 149 byte[] readBinary(); 150 151 /** 152 * Read and return raw json content as a String. 153 */ 154 String readRaw(); 155 156 /** 157 * Return the current location. This is typically used when reporting errors. 158 */ 159 String location(); 160 161 /** 162 * Return the current Token. 163 */ 164 Token currentToken(); 165 166 /** 167 * Close the resources of the reader. 168 */ 169 void close(); 170 171 /** 172 * Skip the next value. 173 */ 174 void skipValue(); 175 176 /** 177 * Reading json with an unmapped field, throw an Exception if failOnUnmapped is true. 178 */ 179 void unmappedField(String fieldName); 180 181 /** 182 * Explicitly state if the streaming content contains ARRAY '[' and ']' tokens. 183 * <p> 184 * The builtin avaje-jsonb parser detects this automatically. Effectively we only need 185 * to set this when we are using the Jackson core parser. 186 * 187 * <pre>{@code 188 * 189 * try (JsonReader reader = jsonb.reader(arrayJson)) { 190 * // content contains ARRAY '[' and ']' tokens, use streamArray(true) 191 * Stream<MyBasic> asStream = type.stream(reader.streamArray(true)); 192 * asStream.forEach(...); 193 * } 194 * 195 * }</pre> 196 * 197 * @param streamArray When true the content is expected to contain ARRAY '[' and ']' tokens. 198 */ 199 default JsonReader streamArray(boolean streamArray) { 200 // do nothing by default, jackson specifically needs this option 201 return this; 202 } 203 204 /** 205 * A structure, name, or value type in a JSON-encoded string. 206 */ 207 enum Token { 208 209 /** 210 * The opening of a JSON array. Written using {@link JsonWriter#beginArray} and read using 211 * {@link JsonReader#beginArray}. 212 */ 213 BEGIN_ARRAY, 214 215 /** 216 * The opening of a JSON object. Written using {@link JsonWriter#beginObject} and read using 217 * {@link JsonReader#beginObject}. 218 */ 219 BEGIN_OBJECT, 220 221 /** 222 * A JSON string. 223 */ 224 STRING, 225 226 /** 227 * A JSON number represented in this API by a Java {@code double}, {@code long}, or {@code int}. 228 */ 229 NUMBER, 230 231 /** 232 * A JSON {@code true} or {@code false}. 233 */ 234 BOOLEAN, 235 236 /** 237 * A JSON {@code null}. 238 */ 239 NULL, 240 241 } 242}