001package io.avaje.jsonb; 002 003import io.avaje.jsonb.core.DefaultBootstrap; 004import io.avaje.jsonb.spi.Bootstrap; 005import io.avaje.jsonb.spi.PropertyNames; 006 007import java.io.InputStream; 008import java.io.OutputStream; 009import java.io.Reader; 010import java.io.Writer; 011import java.lang.reflect.Type; 012import java.util.Iterator; 013import java.util.ServiceLoader; 014 015/** 016 * Provides access to json adapters by type. 017 * 018 * <h4>Initialise with defaults</h3> 019 * 020 * <pre>{@code 021 * Jsonb jsonb = Jsonb.newBuilder().build(); 022 * }</pre> 023 * 024 * <h4>Initialise with some configuration</h3> 025 * 026 * <pre>{@code 027 * Jsonb jsonb = Jsonb.newBuilder() 028 * .serializeNulls(true) 029 * .serializeEmpty(true) 030 * .failOnUnknown(true) 031 * .build(); 032 * }</pre> 033 * 034 * <h4>fromJson</h4> 035 * <p> 036 * Read json content from: String, byte[], Reader, InputStream, JsonReader 037 * </p> 038 * <pre>{@code 039 * 040 * JsonType<Customer> customerType = jsonb.type(Customer.class); 041 * 042 * Customer customer = customerType.fromJson(content); 043 * 044 * }</pre> 045 * 046 * <h4>toJson</h4> 047 * <p> 048 * Write json content to: String, byte[], Writer, OutputStream, JsonWriter 049 * </p> 050 * <pre>{@code 051 * 052 * JsonType<Customer> customerType = jsonb.type(Customer.class); 053 * 054 * String asJson = customerType.toJson(customer); 055 * 056 * }</pre> 057 */ 058public interface Jsonb { 059 060 /** 061 * Create and return a new Jsonb.Builder to configure before building the Jsonb instance. 062 * <p> 063 * We can register JsonAdapter's to use for specific types before building and returning 064 * the Jsonb instance to use. 065 * <p> 066 * Note that JsonAdapter's that are generated are automatically registered via service 067 * loading so there is no need to explicitly register those generated JsonAdapters. 068 * 069 * <pre>{@code 070 * 071 * Jsonb jsonb = Jsonb.newBuilder() 072 * .serializeNulls(true) 073 * .serializeEmpty(true) 074 * .failOnUnknown(true) 075 * .build(); 076 * 077 * }</pre> 078 */ 079 static Builder newBuilder() { 080 Iterator<Bootstrap> bootstrapService = ServiceLoader.load(Bootstrap.class).iterator(); 081 if (bootstrapService.hasNext()) { 082 return bootstrapService.next().newBuilder(); 083 } 084 return DefaultBootstrap.newBuilder(); 085 } 086 087 /** 088 * Return the JsonType used to read and write json for the given class. 089 * 090 * <h3>Using Object.class</h3> 091 * <p> 092 * We can use <code>type(Object.class)</code> when we don't know the specific type that is being 093 * written toJson or read fromJson. 094 * <p> 095 * When using <code>Object.class</code> and writing <code>toJson()</code> then the underlying JsonAdapter 096 * is determined dynamically based on the type of the object value passed in. 097 * <p> 098 * When using <code>Object.class</code> and reading <code>fromJson()</code> then the java types used in 099 * the result are determined dynamically based on the JSON types being read and the resulting java types 100 * are ArrayList, LinkedHashMap, String, boolean, and double. 101 */ 102 <T> JsonType<T> type(Class<T> cls); 103 104 /** 105 * Return the JsonType used to read and write json for the given type. 106 * 107 * <h3>Using Object.class</h3> 108 * <p> 109 * We can use <code>type(Object.class)</code> when we don't know the specific type that is being 110 * written toJson or read fromJson. 111 * <p> 112 * When using <code>Object.class</code> and writing <code>toJson()</code> then the underlying JsonAdapter 113 * is determined dynamically based on the type of the object value passed in. 114 * <p> 115 * When using <code>Object.class</code> and reading <code>fromJson()</code> then the java types used in 116 * the result are determined dynamically based on the JSON types being read and the resulting java types 117 * are ArrayList, LinkedHashMap, String, boolean, and double. 118 */ 119 <T> JsonType<T> type(Type type); 120 121 /** 122 * Return the JsonType for the given value using the values class. 123 * <p> 124 * This is a helper method that supports returning an inferred generic type. 125 * 126 * @param value The value of the given type 127 * @param <T> The inferred generic parameter type 128 * @return JsonType for the given value 129 */ 130 <T> JsonType<T> typeOf(Object value); 131 132 /** 133 * Return the JsonAdapter used to read and write json for the given class. 134 */ 135 <T> JsonAdapter<T> adapter(Class<T> cls); 136 137 /** 138 * Return the JsonAdapter used to read and write json for the given type. 139 */ 140 <T> JsonAdapter<T> adapter(Type type); 141 142 /** 143 * Return the JsonReader used to read the given json content. 144 */ 145 JsonReader reader(String json); 146 147 /** 148 * Return the JsonReader used to read the given json content in bytes. 149 */ 150 JsonReader reader(byte[] jsonBytes); 151 152 /** 153 * Return the JsonReader used to read the json content from the given reader. 154 */ 155 JsonReader reader(Reader reader); 156 157 /** 158 * Return the JsonReader used to read the json content from the given inputStream. 159 */ 160 JsonReader reader(InputStream inputStream); 161 162 /** 163 * Return the JsonWriter used to write json to the given writer. 164 */ 165 JsonWriter writer(Writer writer); 166 167 /** 168 * Return the JsonWriter used to write json to the given outputStream. 169 */ 170 JsonWriter writer(OutputStream outputStream); 171 172 /** 173 * Return the property names as PropertyNames. 174 * <p> 175 * Provides the option of optimising the writing of json for property names 176 * by having them already escaped and encoded rather than as plain strings. 177 */ 178 PropertyNames properties(String... names); 179 180 /** 181 * Build the Jsonb instance adding JsonAdapter, Factory or AdapterBuilder. 182 */ 183 interface Builder { 184 185 /** 186 * Set to serialise null values or not. 187 * <p> 188 * Default is to not serialise nulls. 189 */ 190 Builder serializeNulls(boolean serializeNulls); 191 192 /** 193 * Set to serialise empty collections or not. 194 * <p> 195 * Default is to not serialise empty collections. 196 */ 197 Builder serializeEmpty(boolean serializeEmpty); 198 199 /** 200 * Set failOnUnknown to true such that an exception is thrown when unknown 201 * properties are read in the json content. 202 */ 203 Builder failOnUnknown(boolean failOnUnknown); 204 205 /** 206 * Set to true for BigDecimal and BigInteger to serialise as String values rather than number values. 207 */ 208 Builder mathTypesAsString(boolean mathTypesAsString); 209 210 /** 211 * Add a JsonAdapter to use for the given type. 212 */ 213 <T> Builder add(Type type, JsonAdapter<T> jsonAdapter); 214 215 /** 216 * Add a AdapterBuilder which provides a JsonAdapter to use for the given type. 217 */ 218 Builder add(Type type, AdapterBuilder builder); 219 220 /** 221 * Add a Component which can provide multiple JsonAdapters and or configuration. 222 */ 223 Builder add(Jsonb.Component component); 224 225 /** 226 * Add a JsonAdapter.Factory which provides JsonAdapters to use. 227 */ 228 Builder add(JsonAdapter.Factory factory); 229 230 /** 231 * Build and return the Jsonb instance with all the given adapters and factories registered. 232 */ 233 Jsonb build(); 234 } 235 236 /** 237 * Function to build a JsonAdapter that needs Jsonb. 238 */ 239 @FunctionalInterface 240 interface AdapterBuilder { 241 242 /** 243 * Create a JsonAdapter given the Jsonb instance. 244 */ 245 JsonAdapter<?> build(Jsonb jsonb); 246 } 247 248 /** 249 * Components register JsonAdapters Jsonb.Builder 250 */ 251 @FunctionalInterface 252 interface Component { 253 254 /** 255 * Register JsonAdapters with the Builder. 256 */ 257 void register(Builder builder); 258 } 259}