# Package oracle.dbtools.plugin.api.json.objects

API for creating in memory representations of JSON object graphs (`JSONObjects`) and for serializing object graphs to JSON representations. Developers may find this an easier to use API compared to the `JSONStreams` stream based API, however since `JSONObjects` requires storing a representation of an entire JSON document in memory it requires greater memory overhead and is not suitable for parsing or generating documents that may exceed available memory in size. In general, developers are encouraged to use the `JSONStreams` API in preference to this API. See below for instructions on how to:

- Read a JSON Document into an in-memory representation.
- Modify an in-memory representation of a JSON document.
- Write an in-memory representation of a JSON document to a text stream.
- Write Java object graphs to JSON representation.

### Reading a JSON Document

      @Provides
      class SomeService {
        @Inject SomeService(JSONObjects json) {
         this.json = json;
        }

        void doSomething(InputStream content) throws IOException {
         JSONObject object = (JSONObject)json.read(content); // assumes root is an object
         ... // process the JSONObject instance
        }
      }

- A service injects `JSONObjects` in the usual manner
- The service uses the `JSONObjects.read(java.io.InputStream)` method to transform the byte stream into a `JSONObject` instance.

### Iterating over a JSONObject's properties

       JSONObject object = (JSONObject)json.read(content); // assumes root is an object
       for ( String propertyName: object.propertyNames() ) {
        Object value = object.get(propertyName);
        ... // process the value
       }

- The `JSONObject.propertyNames()` method returns an `Iterable` of all property names in the object
- The `JSONObject.get(String)` method returns the value of the named property.

#### JSON Value Types

The value will be one of the following:

- `null` if no such property exists or the property has a null value.
- An instance of `String` if the value is a JSON String
- An instance of `BigDecimal` if the value is a JSON numeric.
- An instance of `Boolean` if the value is a JSON boolean.
- An instance of `JSONArray` if the value is a JSON array.
- An instance of `JSONObject` if the value is a JSON object.

The `instanceof` operator can be used to determine which actual type a value is

### Iterating over a JSONArray's elements

       JSONArray array = (JSONArray)json.read(content); // assumes root is an array
       for ( Object value: array.values() ) {
        ... // process the value
       }

- The `JSONArray.values()` method returns an `Iterable` of all values in the array
- Each value will be an instance of one of the types defined in the JSON Value Types section.

### Modifying a JSONObject

`JSONObject`s are immutable objects, to create a modified `JSONObject` instance, the `JSONObject.Builder` type must be used.

       JSONObject existing = ... // acquire a handle to existing JSONObject
       JSONObject modified = existing.modify()
                                     .add("someProperty","someValue")
                                     .remove("someOtherProperty")
                                     .build();

- The `JSONObject.modify()` method returns a `JSONObject.Builder` instance populated with the existing properties of the object.
- The `JSONObject.Builder` type contains methods to add and remove properties, and a `JSONObject.Builder.build()` method to produce the modified instance.

### Modifying a JSONArray

`JSONArray`s are immutable objects, to create a modified `JSONArray` instance, the `JSONArray.Builder` type must be used.

       JSONArray existing = ... // acquire a handle to existing JSONArray
       JSONArray modified = existing.modify()
                                     .add("someValue")
                                     .remove(0)
                                     .build();

- The `JSONArray.modify()` method returns a `JSONArray.Builder` instance populated with the existing elements of the array.
- The `JSONArray.Builder` type contains methods to add and remove elements, and a `JSONArray.Builder.build()` method to produce the modified instance.

### Creating JSONObjects and JSONArrays

       JSONObjects json = ... // acquire handle to JSONObjects service
       JSONArray array = json.array().add("something").add(2).addNull().build();

       // array => ["something",2,null]

       JSONObject object = json.object().add("foo","bar").add("nested",array).build();

       // object => {"foo": "bar", "nested": ["something",2,null]}

- The `JSONObjects.array()` method returns a `JSONArray.Builder` instance, whose methods are then used to produce a new `JSONArray` instance.
- The `JSONObjects.object()` method returns a `JSONObject.Builder` instance, whose methods are then used to produce a new `JSONObject` instance.

### Writing in-memory JSON representations

`JSONNode` graphs can be written to streams using the `JSONObjects.write(Appendable, JSONNode)` and `JSONObjects.write(java.io.OutputStream, JSONNode)` methods.

      java.io.Writer out = ... // acquire handler to Appendable instance
      JSONObjects json = ... // acquire handle to JSONObjects service

      // create a JSON graph
      JSONArray array = json.array().add("something").add(2).addNull().build();
      JSONObject object = json.object().add("foo","bar").add("nested",array).build();

      // write the graph to the stream
      json.write(out,object);

      // out contents => {"foo": "bar", "nested": ["something",2,null]}

### Serializing Java Object Graphs

Any Java object graph conforming to the rules outlined below may be serialized to a JSON representation using the `JSONObjects.write(java.io.OutputStream, Object)` method:

#### Supported Types

The nodes in the object graph can be any of the following sub-types:

### Scalar Types

- `CharSequence` and all sub-types, including `String`.
- `char[]` array, which is treated in the same manner as a `CharSequence`.
- `Number` and all sub-types (excluding the `Character` and `Byte` types), and their primitive type equivalents.
- `Boolean` type and it's primitive type equivalent.
- `Date` type and all sub-types.
- `Readable` type and all sub-types.
- The `null` value.

### Container Types

- A java array instance, whose elements are all one of the supported types, excluding `char[]` and `byte[]` arrays.
- `Iterable`s, whose elements are all one of the supported types
- `Iterator`s, whose elements are all one of the supported types
- `Map`s, whose keys can be converted to a `String` via the `Object.toString()` method and whose values are all one of the supported types.

Cycles in the graph are not permitted.

Author:
  cdivilly

- Interface Summary
  Interface | Description
  --- | ---
  JSONArray | An array of zero or more values
  JSONArray.Builder | Build a `JSONArray` instance
  JSONNode | Represents a `JSONObject` or `JSONArray` in a JSON document.
  JSONNode.Builder | Abstract interface implemented by all builders that build `JSONNode` instances
  JSONObject | Represents a JSON object
  JSONObject.Builder | Build `JSONObject` instances
  JSONObjects | API for creating in memory JSON Object representations, and for serializing in memory Object Graphs to JSON representations.

- Enum Summary
  Enum | Description
  --- | ---
  JSONNode.Type | The type of node in the object hierarchy