|
24 | 24 | import io.gsonfire.GsonFireBuilder;
|
25 | 25 | import io.gsonfire.TypeSelector;
|
26 | 26 |
|
| 27 | +import io.kubernetes.client.gson.V1StatusPreProcessor; |
| 28 | +import io.kubernetes.client.openapi.models.V1Status; |
27 | 29 | import okio.ByteString;
|
28 | 30 |
|
29 | 31 | import java.io.IOException;
|
|
35 | 37 | import java.time.LocalDate;
|
36 | 38 | import java.time.OffsetDateTime;
|
37 | 39 | import java.time.format.DateTimeFormatter;
|
| 40 | +import java.time.format.DateTimeFormatterBuilder; |
| 41 | +import java.time.format.DateTimeParseException; |
| 42 | +import java.time.temporal.ChronoField; |
38 | 43 | import java.util.Date;
|
39 | 44 | import java.util.Locale;
|
40 | 45 | import java.util.Map;
|
|
49 | 54 | public class JSON {
|
50 | 55 | private static Gson gson;
|
51 | 56 | private static boolean isLenientOnJson = false;
|
| 57 | + |
| 58 | + private static final DateTimeFormatter RFC3339MICRO_FORMATTER = |
| 59 | + new DateTimeFormatterBuilder() |
| 60 | + .parseDefaulting(ChronoField.OFFSET_SECONDS, 0) |
| 61 | + .append(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")) |
| 62 | + .optionalStart() |
| 63 | + .appendFraction(ChronoField.NANO_OF_SECOND, 6, 6, true) |
| 64 | + .optionalEnd() |
| 65 | + .appendLiteral("Z") |
| 66 | + .toFormatter(); |
52 | 67 | private static DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
|
53 | 68 | private static SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter();
|
54 |
| - private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); |
| 69 | + private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(RFC3339MICRO_FORMATTER); |
55 | 70 | private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
|
56 | 71 | private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter();
|
57 | 72 |
|
58 | 73 | @SuppressWarnings("unchecked")
|
59 | 74 | public static GsonBuilder createGson() {
|
60 | 75 | GsonFireBuilder fireBuilder = new GsonFireBuilder()
|
61 | 76 | ;
|
62 |
| - GsonBuilder builder = fireBuilder.createGsonBuilder(); |
| 77 | + GsonBuilder builder = |
| 78 | + fireBuilder |
| 79 | + .registerPreProcessor(V1Status.class, new V1StatusPreProcessor()) |
| 80 | + .createGsonBuilder(); |
63 | 81 | return builder;
|
64 | 82 | }
|
65 | 83 |
|
@@ -778,11 +796,14 @@ public static class ByteArrayAdapter extends TypeAdapter<byte[]> {
|
778 | 796 |
|
779 | 797 | @Override
|
780 | 798 | public void write(JsonWriter out, byte[] value) throws IOException {
|
| 799 | + boolean oldHtmlSafe = out.isHtmlSafe(); |
| 800 | + out.setHtmlSafe(false); |
781 | 801 | if (value == null) {
|
782 | 802 | out.nullValue();
|
783 | 803 | } else {
|
784 | 804 | out.value(ByteString.of(value).base64());
|
785 | 805 | }
|
| 806 | + out.setHtmlSafe(oldHtmlSafe); |
786 | 807 | }
|
787 | 808 |
|
788 | 809 | @Override
|
@@ -838,7 +859,12 @@ public OffsetDateTime read(JsonReader in) throws IOException {
|
838 | 859 | if (date.endsWith("+0000")) {
|
839 | 860 | date = date.substring(0, date.length()-5) + "Z";
|
840 | 861 | }
|
841 |
| - return OffsetDateTime.parse(date, formatter); |
| 862 | + try { |
| 863 | + return OffsetDateTime.parse(date, formatter); |
| 864 | + } catch (DateTimeParseException e) { |
| 865 | + // backward-compatibility for ISO8601 timestamp format |
| 866 | + return OffsetDateTime.parse(date, DateTimeFormatter.ISO_OFFSET_DATE_TIME); |
| 867 | + } |
842 | 868 | }
|
843 | 869 | }
|
844 | 870 | }
|
|
0 commit comments