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.*;
008import java.lang.reflect.Type;
009import java.util.Iterator;
010import java.util.ServiceLoader;
011
012/**
013 * Provides access to json adapters by type.
014 *
015 * <pre>{@code
016 *
017 *   Jsonb jsonb = Jsonb.newBuilder().build();
018 *
019 *   JsonType<Customer> customerType = jsonb.type(Customer.class);
020 *
021 *   Customer customer = ...;
022 *
023 *   // write json
024 *   String asJson = customerType.toJson(customer);
025 *
026 *   // read json
027 *   Customer customer = customerType.fromJson(asJson);
028 *
029 * }</pre>
030 */
031public interface Jsonb {
032
033  /**
034   * Create and return a new Jsonb.Builder to configure before building the Jsonb instance.
035   * <p>
036   * We can register JsonAdapter's to use for specific types before building and returning
037   * the Jsonb instance to use.
038   * <p>
039   * Note that JsonAdapter's that are generated are automatically registered via service
040   * loading so there is no need to explicitly register those generated JsonAdapters.
041   */
042  static Builder newBuilder() {
043    Iterator<Bootstrap> bootstrapService = ServiceLoader.load(Bootstrap.class).iterator();
044    if (bootstrapService.hasNext()) {
045      return bootstrapService.next().newBuilder();
046    }
047    return DefaultBootstrap.newBuilder();
048  }
049
050  /**
051   * Return the JsonType used to read and write json for the given class.
052   */
053  <T> JsonType<T> type(Class<T> cls);
054
055  /**
056   * Return the JsonType used to read and write json for the given type.
057   */
058  <T> JsonType<T> type(Type type);
059
060  /**
061   * Return the JsonAdapter used to read and write json for the given class.
062   */
063  <T> JsonAdapter<T> adapter(Class<T> cls);
064
065  /**
066   * Return the JsonAdapter used to read and write json for the given type.
067   */
068  <T> JsonAdapter<T> adapter(Type type);
069
070  /**
071   * Return the JsonReader used to read the given json content.
072   */
073  JsonReader reader(String json);
074
075  /**
076   * Return the JsonReader used to read the given json content in bytes.
077   */
078  JsonReader reader(byte[] jsonBytes);
079
080  /**
081   * Return the JsonReader used to read the json content from the given reader.
082   */
083  JsonReader reader(Reader reader);
084
085  /**
086   * Return the JsonReader used to read the json content from the given inputStream.
087   */
088  JsonReader reader(InputStream inputStream);
089
090  /**
091   * Return the JsonWriter used to write json to the given writer.
092   */
093  JsonWriter writer(Writer writer);
094
095  /**
096   * Return the JsonWriter used to write json to the given outputStream.
097   */
098  JsonWriter writer(OutputStream outputStream);
099
100  /**
101   * Return the property names as PropertyNames.
102   * <p>
103   * Provides the option of optimising the writing of json for property names
104   * by having them already escaped and encoded rather than as plain strings.
105   */
106  PropertyNames properties(String... names);
107
108  /**
109   * Build the Jsonb instance adding JsonAdapter, Factory or AdapterBuilder.
110   */
111  interface Builder {
112
113    /**
114     * Set failOnUnknown to true such that an exception is thrown when unknown
115     * properties are read in the json content.
116     */
117    Builder failOnUnknown(boolean failOnUnknown);
118
119    /**
120     * Set to true for BigDecimal and BigInteger to serialise as String values rather than number values.
121     */
122    Builder mathTypesAsString(boolean mathTypesAsString);
123
124    /**
125     * Add a JsonAdapter to use for the given type.
126     */
127    <T> Builder add(Type type, JsonAdapter<T> jsonAdapter);
128
129    /**
130     * Add a AdapterBuilder which provides a JsonAdapter to use for the given type.
131     */
132    Builder add(Type type, AdapterBuilder builder);
133
134    /**
135     * Add a Component which can provide multiple JsonAdapters and or configuration.
136     */
137    Builder add(Jsonb.Component component);
138
139    /**
140     * Add a JsonAdapter.Factory which provides JsonAdapters to use.
141     */
142    Builder add(JsonAdapter.Factory factory);
143
144    /**
145     * Build and return the Jsonb instance with all the given adapters and factories registered.
146     */
147    Jsonb build();
148  }
149
150  /**
151   * Function to build a JsonAdapter that needs Jsonb.
152   */
153  @FunctionalInterface
154  interface AdapterBuilder {
155
156    /**
157     * Create a JsonAdapter given the Jsonb instance.
158     */
159    JsonAdapter<?> build(Jsonb jsonb);
160  }
161
162  /**
163   * Components register JsonAdapters Jsonb.Builder
164   */
165  @FunctionalInterface
166  interface Component {
167
168    /**
169     * Register JsonAdapters with the Builder.
170     */
171    void register(Builder builder);
172  }
173}