001package io.avaje.jsonb.stream; 002 003import io.avaje.jsonb.JsonReader; 004import io.avaje.jsonb.JsonWriter; 005import io.avaje.jsonb.spi.*; 006 007import java.io.*; 008import java.nio.charset.StandardCharsets; 009 010/** 011 * Default implementation of JsonStreamAdapter provided with Jsonb. 012 */ 013public final class JsonStream implements JsonStreamAdapter { 014 015 /** 016 * Used to build JsonStream with custom settings. 017 */ 018 public static final class Builder { 019 020 private boolean serializeNulls; 021 private boolean serializeEmpty; 022 private boolean failOnUnknown; 023 024 /** 025 * Set to true to serialize nulls. Defaults to false. 026 */ 027 public Builder serializeNulls(boolean serializeNulls) { 028 this.serializeNulls = serializeNulls; 029 return this; 030 } 031 032 /** 033 * Set to true to serialize empty collections. Defaults to false. 034 */ 035 public Builder serializeEmpty(boolean serializeEmpty) { 036 this.serializeEmpty = serializeEmpty; 037 return this; 038 } 039 040 /** 041 * Set to true to fail on unknown properties. Defaults to false. 042 */ 043 public Builder failOnUnknown(boolean failOnUnknown) { 044 this.failOnUnknown = failOnUnknown; 045 return this; 046 } 047 048 /** 049 * Build and return the JsonStream. 050 */ 051 public JsonStream build() { 052 return new JsonStream(serializeNulls, serializeEmpty, failOnUnknown); 053 } 054 } 055 056 private final boolean serializeNulls; 057 private final boolean serializeEmpty; 058 private final boolean failOnUnknown; 059 060 /** 061 * Create with the given default configuration. 062 */ 063 public JsonStream() { 064 this(false, false, false); 065 } 066 067 /** 068 * Create additionally providing the jsonFactory. 069 */ 070 public JsonStream(boolean serializeNulls, boolean serializeEmpty, boolean failOnUnknown) { 071 this.serializeNulls = serializeNulls; 072 this.serializeEmpty = serializeEmpty; 073 this.failOnUnknown = failOnUnknown; 074 } 075 076 /** 077 * Return a new builder to create a JsonStream with custom configuration. 078 * 079 * <pre>{@code 080 * 081 * var jsonStream = JsonStream.builder() 082 * .serializeNulls(true) 083 * .build(); 084 * 085 * }</pre> 086 */ 087 public static Builder builder() { 088 return new Builder(); 089 } 090 091 @Override 092 public PropertyNames properties(String... names) { 093 return JsonNames.of(names); 094 } 095 096 @Override 097 public JsonReader reader(String json) { 098 return reader(json.getBytes(StandardCharsets.UTF_8)); 099 } 100 101 @Override 102 public JsonReader reader(byte[] json) { 103 JsonParser parser = Recycle.parser(json); 104 return new JsonReadAdapter(parser, failOnUnknown); 105 } 106 107 @Override 108 public JsonReader reader(Reader reader) { 109 // TODO: Could recycle encoder and buffer 110 return reader(new ReaderInputStream(reader, StandardCharsets.UTF_8)); 111 } 112 113 @Override 114 public JsonReader reader(InputStream inputStream) { 115 JsonParser parser = Recycle.parser(inputStream); 116 return new JsonReadAdapter(parser, failOnUnknown); 117 } 118 119 @Override 120 public JsonWriter writer(Writer writer) { 121 // TODO: Could recycle buffer used 122 return writer(new WriterOutputStream(writer, StandardCharsets.UTF_8)); 123 } 124 125 @Override 126 public JsonWriter writer(OutputStream outputStream) { 127 return wrap(gen(outputStream)); 128 } 129 130 @Override 131 public BufferedJsonWriter bufferedWriter() { 132 JsonGenerator generator = Recycle.generator(); 133 return new BufferedWriter(wrap(generator), generator); 134 } 135 136 @Override 137 public BytesJsonWriter bufferedWriterAsBytes() { 138 JsonGenerator generator = Recycle.generator(); 139 return new BytesWriter(wrap(generator), generator); 140 } 141 142 private JsonGenerator gen(OutputStream outputStream) { 143 return Recycle.generator(outputStream); 144 } 145 146 private JsonWriteAdapter wrap(JsonGenerator generator) { 147 return new JsonWriteAdapter(generator, serializeNulls, serializeEmpty); 148 } 149 150 private static class BufferedWriter extends DelegateJsonWriter implements BufferedJsonWriter { 151 152 private final JsonGenerator generator; 153 154 BufferedWriter(JsonWriteAdapter delegate, JsonGenerator generator) { 155 super(delegate); 156 this.generator = generator; 157 } 158 159 @Override 160 public String result() { 161 return generator.toString(); 162 } 163 } 164 165 private static class BytesWriter extends DelegateJsonWriter implements BytesJsonWriter { 166 167 private final JsonGenerator generator; 168 169 public BytesWriter(JsonWriteAdapter delegate, JsonGenerator generator) { 170 super(delegate); 171 this.generator = generator; 172 } 173 174 @Override 175 public byte[] result() { 176 return generator.toByteArray(); 177 } 178 } 179}