001package io.avaje.json.mapper;
002
003import io.avaje.json.JsonAdapter;
004import io.avaje.json.JsonReader;
005import io.avaje.json.JsonWriter;
006import io.avaje.json.PropertyNames;
007import io.avaje.json.stream.JsonStream;
008
009import java.io.InputStream;
010import java.io.OutputStream;
011import java.io.Reader;
012import java.io.Writer;
013import java.util.List;
014import java.util.Map;
015import java.util.function.Function;
016
017/**
018 * A mapper for mapping to basic Java types.
019 * <p>
020 * This supports the basic Java types of String, Boolean, Integer, Long, Double and
021 * Maps and List of these.
022 * <p>
023 * If avaje-jsonb is available then you will use that and NOT use this JsonMapper at all.
024 * This JsonMapper is intended to be used by code that ONLY wants to depend on avaje-json-core
025 * and process the basic Java types or provide its own JsonAdapters.
026 * <p>
027 * For full support with more types and binding to custom types use avaje-jsonb instead.
028 *
029 * <h3>Example</h3>
030 * <pre>{@code
031 *
032 *   static final JsonMapper jsonMapper = JsonMapper.builder().build();
033 *
034 *   Map<String, Long> map = new LinkedHashMap<>();
035 *   map.put("one", 45L);
036 *   map.put("two", 93L);
037 *
038 *   String asJson = jsonMapper.toJson(map);
039 *
040 * }</pre>
041 */
042public interface JsonMapper {
043
044  /**
045   * Create a new builder for JsonMapper.
046   */
047  static Builder builder() {
048    return new DJsonMapperBuilder();
049  }
050
051  /**
052   * Return a mapper for any json content.
053   */
054  Type<Object> object();
055
056  /**
057   * Return a mapper for json OBJECT content with more reading/writing options.
058   */
059  Type<Map<String, Object>> map();
060
061  /**
062   * Return a mapper for json ARRAY content with more reading/writing options.
063   */
064  Type<List<Object>> list();
065
066  /**
067   * Write the object to JSON string.
068   * <p>
069   * For options to write json content to OutputStream, Writer etc
070   * use {@link Type}.
071   *
072   * <pre>{@code
073   *
074   * var list = List.of(42, "hello");
075   *
076   * var asJson = mapper.toJson(list);
077   * }</pre>
078   */
079  String toJson(Object object);
080
081  /**
082   * Write the object to JsonWriter.
083   * <p>
084   * For options to write json content to OutputStream, Writer etc
085   * use {@link Type}.
086   */
087  void toJson(Object object, JsonWriter jsonWriter);
088
089  /**
090   * Read the object from JSON string.
091   */
092  Object fromJson(String json);
093
094  /**
095   * Read the object from JSON.
096   */
097  Object fromJson(JsonReader jsonReader);
098
099  /**
100   * Read a Map from JSON OBJECT string.
101   * <p>
102   * Use {@link #map()} for more reading options.
103   */
104  Map<String, Object> fromJsonObject(String json);
105
106  /**
107   * Read a Map from JSON OBJECT.
108   * <p>
109   * Use {@link #map()} for more reading options.
110   */
111  Map<String, Object> fromJsonObject(JsonReader jsonReader);
112
113  /**
114   * Read a List from JSON ARRAY string.
115   * <p>
116   * Use {@link #list()} for more reading options.
117   */
118  List<Object> fromJsonArray(String json);
119
120  /**
121   * Read a List from JSON ARRAY.
122   * <p>
123   * Use {@link #list()} for more reading options.
124   */
125  List<Object> fromJsonArray(JsonReader jsonReader);
126
127  /**
128   * Return the property names as PropertyNames.
129   * <p>
130   * Provides the option of optimising the writing of json for property names
131   * by having them already escaped and encoded rather than as plain strings.
132   */
133  PropertyNames properties(String... names);
134
135  /**
136   * Return a Type specific mapper for the given JsonAdapter.
137   *
138   * @param customAdapter The custom adapter to use.
139   * @param <T>           The type of the class to map to/from json.
140   * @return The Type specific mapper.
141   */
142  <T> Type<T> type(JsonAdapter<T> customAdapter);
143
144  /**
145   * Return a Type specific mapper using a function that creates a JsonAdapter.
146   * <p>
147   * Often the adapterFunction is the constructor of the custom JsonAdapter where
148   * the constructor takes JsonMapper as the only argument.
149   *
150   * @param adapterFunction The function that creates a JsonAdapter.
151   * @param <T>             The type of the class to map to/from json.
152   * @return The Type specific mapper.
153   */
154  <T> Type<T> type(Function<JsonMapper, JsonAdapter<T>> adapterFunction);
155
156  /**
157   * Return the map wrapped via JsonExtract to make extracting values easier.
158   */
159  default JsonExtract extract(Map<String, Object> map) {
160    return new DExtract(map);
161  }
162
163  /**
164   * Build the JsonNodeMapper.
165   */
166  interface Builder {
167
168    /**
169     * Set the default JsonStream to use.
170     * <p>
171     * When not set this defaults to {@code JsonStream.builder().build()}.
172     *
173     * @see JsonStream#builder()
174     */
175    Builder jsonStream(JsonStream jsonStream);
176
177    /**
178     * Build and return the JsonNodeMapper.
179     */
180    JsonMapper build();
181  }
182
183  /**
184   * Reading and writing with all options such and InputStream, Reader etc.
185   */
186  interface Type<T> {
187
188    /**
189     * Create a list type for this type.
190     */
191    Type<List<T>> list();
192
193    /**
194     * Create a map type with string keys and this type as the value type.
195     */
196    Type<Map<String, T>> map();
197
198    /**
199     * Read the return the value from the json content.
200     */
201    T fromJson(String content);
202
203    /**
204     * Read the return the value from the reader.
205     */
206    T fromJson(JsonReader reader);
207
208    /**
209     * Read the return the value from the json content.
210     */
211    T fromJson(byte[] content);
212
213    /**
214     * Read the return the value from the reader.
215     */
216    T fromJson(Reader reader);
217
218    /**
219     * Read the return the value from the inputStream.
220     */
221    T fromJson(InputStream inputStream);
222
223    /**
224     * Return as json string.
225     */
226    String toJson(T value);
227
228    /**
229     * Return as json string in pretty format.
230     */
231    String toJsonPretty(T value);
232
233    /**
234     * Return the value as json content in bytes form.
235     */
236    byte[] toJsonBytes(T value);
237
238    /**
239     * Write to the given writer.
240     */
241    void toJson(T value, JsonWriter writer);
242
243    /**
244     * Write to the given writer.
245     */
246    void toJson(T value, Writer writer);
247
248    /**
249     * Write to the given outputStream.
250     */
251    void toJson(T value, OutputStream outputStream);
252
253  }
254}