github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/JSON.mustache (about) 1 {{>licenseInfo}} 2 3 package {{invokerPackage}}; 4 5 import com.google.gson.Gson; 6 import com.google.gson.GsonBuilder; 7 import com.google.gson.JsonParseException; 8 import com.google.gson.TypeAdapter; 9 import com.google.gson.internal.bind.util.ISO8601Utils; 10 import com.google.gson.stream.JsonReader; 11 import com.google.gson.stream.JsonWriter; 12 import com.google.gson.JsonElement; 13 import io.gsonfire.GsonFireBuilder; 14 import io.gsonfire.TypeSelector; 15 {{#joda}} 16 import org.joda.time.DateTime; 17 import org.joda.time.LocalDate; 18 import org.joda.time.format.DateTimeFormatter; 19 import org.joda.time.format.DateTimeFormatterBuilder; 20 import org.joda.time.format.ISODateTimeFormat; 21 {{/joda}} 22 {{#threetenbp}} 23 import org.threeten.bp.LocalDate; 24 import org.threeten.bp.OffsetDateTime; 25 import org.threeten.bp.format.DateTimeFormatter; 26 {{/threetenbp}} 27 28 {{#models.0}} 29 import {{modelPackage}}.*; 30 {{/models.0}} 31 import okio.ByteString; 32 33 import java.io.IOException; 34 import java.io.StringReader; 35 import java.lang.reflect.Type; 36 import java.text.DateFormat; 37 import java.text.ParseException; 38 import java.text.ParsePosition; 39 {{#java8}} 40 import java.time.LocalDate; 41 import java.time.OffsetDateTime; 42 import java.time.format.DateTimeFormatter; 43 {{/java8}} 44 import java.util.Date; 45 import java.util.Locale; 46 import java.util.Map; 47 import java.util.HashMap; 48 49 public class JSON { 50 private Gson gson; 51 private boolean isLenientOnJson = false; 52 private DateTypeAdapter dateTypeAdapter = new DateTypeAdapter(); 53 private SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter(); 54 {{#joda}} 55 private DateTimeTypeAdapter dateTimeTypeAdapter = new DateTimeTypeAdapter(); 56 private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); 57 {{/joda}} 58 {{#jsr310}} 59 private OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); 60 private LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); 61 {{/jsr310}} 62 private ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter(); 63 64 public static GsonBuilder createGson() { 65 GsonFireBuilder fireBuilder = new GsonFireBuilder() 66 {{#models}} 67 {{#model}} 68 {{#discriminator}} 69 .registerTypeSelector({{classname}}.class, new TypeSelector() { 70 @Override 71 public Class getClassForElement(JsonElement readElement) { 72 Map<String, Class> classByDiscriminatorValue = new HashMap<String, Class>(); 73 {{#mappedModels}} 74 classByDiscriminatorValue.put("{{mappingName}}"{{^discriminatorCaseSensitive}}.toUpperCase(Locale.ROOT){{/discriminatorCaseSensitive}}, {{modelName}}.class); 75 {{/mappedModels}} 76 classByDiscriminatorValue.put("{{name}}"{{^discriminatorCaseSensitive}}.toUpperCase(Locale.ROOT){{/discriminatorCaseSensitive}}, {{classname}}.class); 77 return getClassByDiscriminator(classByDiscriminatorValue, 78 getDiscriminatorValue(readElement, "{{{propertyBaseName}}}")); 79 } 80 }) 81 {{/discriminator}} 82 {{/model}} 83 {{/models}} 84 ; 85 GsonBuilder builder = fireBuilder.createGsonBuilder(); 86 {{#disableHtmlEscaping}} 87 builder.disableHtmlEscaping(); 88 {{/disableHtmlEscaping}} 89 return builder; 90 } 91 92 private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) { 93 JsonElement element = readElement.getAsJsonObject().get(discriminatorField); 94 if (null == element) { 95 throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">"); 96 } 97 return element.getAsString(); 98 } 99 100 /** 101 * Returns the Java class that implements the OpenAPI schema for the specified discriminator value. 102 * 103 * @param classByDiscriminatorValue The map of discriminator values to Java classes. 104 * @param discriminatorValue The value of the OpenAPI discriminator in the input data. 105 * @return The Java class that implements the OpenAPI schema 106 */ 107 private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) { 108 Class clazz = (Class) classByDiscriminatorValue.get(discriminatorValue{{^discriminatorCaseSensitive}}.toUpperCase(Locale.ROOT){{/discriminatorCaseSensitive}}); 109 if (null == clazz) { 110 throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">"); 111 } 112 return clazz; 113 } 114 115 public JSON() { 116 gson = createGson() 117 .registerTypeAdapter(Date.class, dateTypeAdapter) 118 .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter) 119 {{#joda}} 120 .registerTypeAdapter(DateTime.class, dateTimeTypeAdapter) 121 .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) 122 {{/joda}} 123 {{#jsr310}} 124 .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter) 125 .registerTypeAdapter(LocalDate.class, localDateTypeAdapter) 126 {{/jsr310}} 127 .registerTypeAdapter(byte[].class, byteArrayAdapter) 128 .create(); 129 } 130 131 /** 132 * Get Gson. 133 * 134 * @return Gson 135 */ 136 public Gson getGson() { 137 return gson; 138 } 139 140 /** 141 * Set Gson. 142 * 143 * @param gson Gson 144 * @return JSON 145 */ 146 public JSON setGson(Gson gson) { 147 this.gson = gson; 148 return this; 149 } 150 151 public JSON setLenientOnJson(boolean lenientOnJson) { 152 isLenientOnJson = lenientOnJson; 153 return this; 154 } 155 156 /** 157 * Serialize the given Java object into JSON string. 158 * 159 * @param obj Object 160 * @return String representation of the JSON 161 */ 162 public String serialize(Object obj) { 163 return gson.toJson(obj); 164 } 165 166 /** 167 * Deserialize the given JSON string to Java object. 168 * 169 * @param <T> Type 170 * @param body The JSON string 171 * @param returnType The type to deserialize into 172 * @return The deserialized Java object 173 */ 174 @SuppressWarnings("unchecked") 175 public <T> T deserialize(String body, Type returnType) { 176 try { 177 if (isLenientOnJson) { 178 JsonReader jsonReader = new JsonReader(new StringReader(body)); 179 // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean) 180 jsonReader.setLenient(true); 181 return gson.fromJson(jsonReader, returnType); 182 } else { 183 return gson.fromJson(body, returnType); 184 } 185 } catch (JsonParseException e) { 186 // Fallback processing when failed to parse JSON form response body: 187 // return the response body string directly for the String return type; 188 if (returnType.equals(String.class)) { 189 return (T) body; 190 } else { 191 throw (e); 192 } 193 } 194 } 195 196 /** 197 * Gson TypeAdapter for Byte Array type 198 */ 199 public class ByteArrayAdapter extends TypeAdapter<byte[]> { 200 201 @Override 202 public void write(JsonWriter out, byte[] value) throws IOException { 203 if (value == null) { 204 out.nullValue(); 205 } else { 206 out.value(ByteString.of(value).base64()); 207 } 208 } 209 210 @Override 211 public byte[] read(JsonReader in) throws IOException { 212 switch (in.peek()) { 213 case NULL: 214 in.nextNull(); 215 return null; 216 default: 217 String bytesAsBase64 = in.nextString(); 218 ByteString byteString = ByteString.decodeBase64(bytesAsBase64); 219 return byteString.toByteArray(); 220 } 221 } 222 } 223 224 {{#joda}} 225 /** 226 * Gson TypeAdapter for Joda DateTime type 227 */ 228 public static class DateTimeTypeAdapter extends TypeAdapter<DateTime> { 229 230 private DateTimeFormatter formatter; 231 232 public DateTimeTypeAdapter() { 233 this(new DateTimeFormatterBuilder() 234 .append(ISODateTimeFormat.dateTime().getPrinter(), ISODateTimeFormat.dateOptionalTimeParser().getParser()) 235 .toFormatter()); 236 } 237 238 public DateTimeTypeAdapter(DateTimeFormatter formatter) { 239 this.formatter = formatter; 240 } 241 242 public void setFormat(DateTimeFormatter dateFormat) { 243 this.formatter = dateFormat; 244 } 245 246 @Override 247 public void write(JsonWriter out, DateTime date) throws IOException { 248 if (date == null) { 249 out.nullValue(); 250 } else { 251 out.value(formatter.print(date)); 252 } 253 } 254 255 @Override 256 public DateTime read(JsonReader in) throws IOException { 257 switch (in.peek()) { 258 case NULL: 259 in.nextNull(); 260 return null; 261 default: 262 String date = in.nextString(); 263 return formatter.parseDateTime(date); 264 } 265 } 266 } 267 268 /** 269 * Gson TypeAdapter for Joda LocalDate type 270 */ 271 public class LocalDateTypeAdapter extends TypeAdapter<LocalDate> { 272 273 private DateTimeFormatter formatter; 274 275 public LocalDateTypeAdapter() { 276 this(ISODateTimeFormat.date()); 277 } 278 279 public LocalDateTypeAdapter(DateTimeFormatter formatter) { 280 this.formatter = formatter; 281 } 282 283 public void setFormat(DateTimeFormatter dateFormat) { 284 this.formatter = dateFormat; 285 } 286 287 @Override 288 public void write(JsonWriter out, LocalDate date) throws IOException { 289 if (date == null) { 290 out.nullValue(); 291 } else { 292 out.value(formatter.print(date)); 293 } 294 } 295 296 @Override 297 public LocalDate read(JsonReader in) throws IOException { 298 switch (in.peek()) { 299 case NULL: 300 in.nextNull(); 301 return null; 302 default: 303 String date = in.nextString(); 304 return formatter.parseLocalDate(date); 305 } 306 } 307 } 308 309 public JSON setDateTimeFormat(DateTimeFormatter dateFormat) { 310 dateTimeTypeAdapter.setFormat(dateFormat); 311 return this; 312 } 313 314 public JSON setLocalDateFormat(DateTimeFormatter dateFormat) { 315 localDateTypeAdapter.setFormat(dateFormat); 316 return this; 317 } 318 319 {{/joda}} 320 {{#jsr310}} 321 /** 322 * Gson TypeAdapter for JSR310 OffsetDateTime type 323 */ 324 public static class OffsetDateTimeTypeAdapter extends TypeAdapter<OffsetDateTime> { 325 326 private DateTimeFormatter formatter; 327 328 public OffsetDateTimeTypeAdapter() { 329 this(DateTimeFormatter.ISO_OFFSET_DATE_TIME); 330 } 331 332 public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) { 333 this.formatter = formatter; 334 } 335 336 public void setFormat(DateTimeFormatter dateFormat) { 337 this.formatter = dateFormat; 338 } 339 340 @Override 341 public void write(JsonWriter out, OffsetDateTime date) throws IOException { 342 if (date == null) { 343 out.nullValue(); 344 } else { 345 out.value(formatter.format(date)); 346 } 347 } 348 349 @Override 350 public OffsetDateTime read(JsonReader in) throws IOException { 351 switch (in.peek()) { 352 case NULL: 353 in.nextNull(); 354 return null; 355 default: 356 String date = in.nextString(); 357 if (date.endsWith("+0000")) { 358 date = date.substring(0, date.length()-5) + "Z"; 359 } 360 return OffsetDateTime.parse(date, formatter); 361 } 362 } 363 } 364 365 /** 366 * Gson TypeAdapter for JSR310 LocalDate type 367 */ 368 public class LocalDateTypeAdapter extends TypeAdapter<LocalDate> { 369 370 private DateTimeFormatter formatter; 371 372 public LocalDateTypeAdapter() { 373 this(DateTimeFormatter.ISO_LOCAL_DATE); 374 } 375 376 public LocalDateTypeAdapter(DateTimeFormatter formatter) { 377 this.formatter = formatter; 378 } 379 380 public void setFormat(DateTimeFormatter dateFormat) { 381 this.formatter = dateFormat; 382 } 383 384 @Override 385 public void write(JsonWriter out, LocalDate date) throws IOException { 386 if (date == null) { 387 out.nullValue(); 388 } else { 389 out.value(formatter.format(date)); 390 } 391 } 392 393 @Override 394 public LocalDate read(JsonReader in) throws IOException { 395 switch (in.peek()) { 396 case NULL: 397 in.nextNull(); 398 return null; 399 default: 400 String date = in.nextString(); 401 return LocalDate.parse(date, formatter); 402 } 403 } 404 } 405 406 public JSON setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { 407 offsetDateTimeTypeAdapter.setFormat(dateFormat); 408 return this; 409 } 410 411 public JSON setLocalDateFormat(DateTimeFormatter dateFormat) { 412 localDateTypeAdapter.setFormat(dateFormat); 413 return this; 414 } 415 416 {{/jsr310}} 417 /** 418 * Gson TypeAdapter for java.sql.Date type 419 * If the dateFormat is null, a simple "yyyy-MM-dd" format will be used 420 * (more efficient than SimpleDateFormat). 421 */ 422 public static class SqlDateTypeAdapter extends TypeAdapter<java.sql.Date> { 423 424 private DateFormat dateFormat; 425 426 public SqlDateTypeAdapter() {} 427 428 public SqlDateTypeAdapter(DateFormat dateFormat) { 429 this.dateFormat = dateFormat; 430 } 431 432 public void setFormat(DateFormat dateFormat) { 433 this.dateFormat = dateFormat; 434 } 435 436 @Override 437 public void write(JsonWriter out, java.sql.Date date) throws IOException { 438 if (date == null) { 439 out.nullValue(); 440 } else { 441 String value; 442 if (dateFormat != null) { 443 value = dateFormat.format(date); 444 } else { 445 value = date.toString(); 446 } 447 out.value(value); 448 } 449 } 450 451 @Override 452 public java.sql.Date read(JsonReader in) throws IOException { 453 switch (in.peek()) { 454 case NULL: 455 in.nextNull(); 456 return null; 457 default: 458 String date = in.nextString(); 459 try { 460 if (dateFormat != null) { 461 return new java.sql.Date(dateFormat.parse(date).getTime()); 462 } 463 return new java.sql.Date(ISO8601Utils.parse(date, new ParsePosition(0)).getTime()); 464 } catch (ParseException e) { 465 throw new JsonParseException(e); 466 } 467 } 468 } 469 } 470 471 /** 472 * Gson TypeAdapter for java.util.Date type 473 * If the dateFormat is null, ISO8601Utils will be used. 474 */ 475 public static class DateTypeAdapter extends TypeAdapter<Date> { 476 477 private DateFormat dateFormat; 478 479 public DateTypeAdapter() {} 480 481 public DateTypeAdapter(DateFormat dateFormat) { 482 this.dateFormat = dateFormat; 483 } 484 485 public void setFormat(DateFormat dateFormat) { 486 this.dateFormat = dateFormat; 487 } 488 489 @Override 490 public void write(JsonWriter out, Date date) throws IOException { 491 if (date == null) { 492 out.nullValue(); 493 } else { 494 String value; 495 if (dateFormat != null) { 496 value = dateFormat.format(date); 497 } else { 498 value = ISO8601Utils.format(date, true); 499 } 500 out.value(value); 501 } 502 } 503 504 @Override 505 public Date read(JsonReader in) throws IOException { 506 try { 507 switch (in.peek()) { 508 case NULL: 509 in.nextNull(); 510 return null; 511 default: 512 String date = in.nextString(); 513 try { 514 if (dateFormat != null) { 515 return dateFormat.parse(date); 516 } 517 return ISO8601Utils.parse(date, new ParsePosition(0)); 518 } catch (ParseException e) { 519 throw new JsonParseException(e); 520 } 521 } 522 } catch (IllegalArgumentException e) { 523 throw new JsonParseException(e); 524 } 525 } 526 } 527 528 public JSON setDateFormat(DateFormat dateFormat) { 529 dateTypeAdapter.setFormat(dateFormat); 530 return this; 531 } 532 533 public JSON setSqlDateFormat(DateFormat dateFormat) { 534 sqlDateTypeAdapter.setFormat(dateFormat); 535 return this; 536 } 537 538 }