Skip to content

Latest commit

 

History

History
872 lines (606 loc) · 38.2 KB

README.md

File metadata and controls

872 lines (606 loc) · 38.2 KB

JSONx Runtime API

JSON Schema for the enterprise

Build Status Coverage Status Javadocs Released Version Snapshot Version

Abstract

This document specifies the JSONx Runtime API, which offers facilities for binding Java classes to JSON objects whose structure is expressed in the JSON Schema Definition Language.

Table of Contents

  1 Introduction
    1.1 Dependencies on Other Specifications
    1.2 Conventions Used in This Document
  2 Purpose
  3 Requirements
  4 Getting Started
  5 Specification
    5.1 Structural
       5.1.1 JSON objects (JxObject)
       5.1.2 Property Annotations
           5.1.2.1 Special Considerations
       5.1.3 JSON arrays (@ArrayType)
           5.1.3.1 Special Considerations
       5.1.4 Element Annotations
       5.1.5 JSON Value Annotations
           5.1.5.1 object Type
               5.1.5.1.1 @ObjectProperty
               5.1.5.1.2 @ObjectElement
           5.1.5.2 array Type
               5.1.5.2.1 @ArrayProperty
               5.1.5.2.2 @ArrayElement
           5.1.5.3 boolean Type
               5.1.5.3.1 @BooleanProperty
               5.1.5.3.2 @BooleanElement
           5.1.5.4 number Type
               5.1.5.4.1 @NumberProperty
               5.1.5.4.2 @NumberElement
           5.1.5.5 string Type
               5.1.5.5.1 @StringProperty
               5.1.5.5.2 @StringElement
           5.1.5.6 any Type
               5.1.5.6.1 @AnyProperty
               5.1.5.6.2 @AnyElement
           5.1.5.7 AnyObject
           5.1.5.8 @AnyArray
    5.2 Functional
       5.2.1 ValidationException
       5.2.2 JxEncoder
           5.2.2.1 EncodeException
       5.2.3 JxDecoder
           5.2.3.1 DecodeException
  6 Contributing
  7 Special Thanks
  8 License

1 Introduction

This document sets out the structural part of the JSONx Runtime API. It also contains a directory of links to related resources.

The JSONx Runtime API is designed to bind JSON documents to Java objects. More specifically, the JSONx Runtime API provides a way for JSON objects whose structure is expressed in the JSON Schema Definition Language to be parsed and marshaled, to and from Java objects of strongly-typed classes. The JSONx Runtime API can also be used to validate JSON documents as they are parsed from text or marshaled from Java objects against a JSD. Thus, the JSONx Runtime API is a reference implementation of the validation and binding functionalities of the JSON Schema Definition Language.

Any application that consumes well-formed JSON can use the JSONx Runtime API to interface with JSON with Java classes. The JSONx Runtime API supports all facilities of the structural and logical features of the JSON Schema Definition Language.

1.1 Dependencies on Other Specifications

The definition of JSONx Runtime API depends on the following specifications: JSON Schema Definition Language.

1.2 Conventions Used in This Document

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119.

2 Purpose

Provide a runtime API for parsing and marshaling JSON documents to and from strongly-typed Java classes.

3 Requirements

  1. The runtime API MUST be able to model the full scope of normative meaning, usage, constraints and relationships of the constituent parts of a JSON document as specifiable with the schema language.

  2. The runtime API MUST enforce (via validation) the full scope of normative meaning, usage, constraints and relationships of the constituent parts of a JSON document as specifiable in the schema language.

  3. The runtime API MUST produce clear and useful error messages when exception of schema document constraints are encountered during validation of JSON documents.

  4. The runtime API MUST constrain the constituent parts of a schema document to Java type bindings that are as lightweight as necessary to retain the full normative scope of specification of the schema language.

  5. The runtime API MUST use light coupling, not imposing requirements for exclusionary patterns onto a class model of binding classes.

  6. The runtime API MUST offer easy patterns for manual description of bindings.

  7. The runtime API MUST be straightforward, intuitive, and resilient to human error.

4 Getting Started

The JSONx Runtime API uses annotations to bind class definitions to usage, constraints and relationships specifiable in the schema language.

The following illustrates usage of the runtime API with an example of an invoice.

  1. Create invoice.jsd or invoice.jsdx in src/main/resources/:

JSD
{
  "jx:ns": "http://www.jsonx.org/schema-0.4.jsd",
  "jx:schemaLocation": "http://www.jsonx.org/schema-0.4.jsd http://www.jsonx.org/schema.jsd",

  "money": { "jx:type": "number", "range": "[0,]", "scale": 2},
  "positiveInteger": { "jx:type": "number", "range": "[1,]", "scale": 0},
  "date": { "jx:type": "string", "pattern": "-?\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(02-(0[1-9]|1\\d|2\\d))|((0[469]|11)-(0[1-9]|[12]\\d|30)))" },
  "nonEmptyString": { "jx:type": "string", "pattern": "\\S|\\S.*\\S" },
  "address": { "jx:type": "object", "properties": {
    "name": { "jx:type": "reference", "nullable": false, "type": "nonEmptyString" },
    "address": { "jx:type": "reference", "nullable": false, "type": "nonEmptyString" },
    "city": { "jx:type": "reference", "nullable": false, "type": "nonEmptyString" },
    "postalCode": { "jx:type": "reference", "nullable": false, "type": "nonEmptyString", "use": "optional" },
    "country": { "jx:type": "reference", "type": "nonEmptyString" } }
  },
  "invoice": { "jx:type": "object", "properties": {
    "number": { "jx:type": "reference", "type": "positiveInteger" },
    "date": { "jx:type": "reference", "type": "date" },
    "billingAddress": { "jx:type": "reference", "type": "address" },
    "shippingAddress": { "jx:type": "reference", "type": "address" },
    "billedItems": { "jx:type": "array", "nullable": false, "elements": [
      { "jx:type": "reference", "type": "item" } ] } }
  },
  "item": { "jx:type": "object", "properties": {
    "description": { "jx:type": "reference", "nullable": false, "type": "nonEmptyString" },
    "code": { "jx:type": "reference", "nullable": false, "type": "positiveInteger" },
    "quantity": { "jx:type": "reference", "nullable": false, "type": "positiveInteger" },
    "price": { "jx:type": "reference", "nullable": false, "type": "money" } }
  }
}
JSDx
<schema
  xmlns="http://www.jsonx.org/schema-0.4.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.jsonx.org/schema-0.4.xsd http://www.jsonx.org/schema.xsd">

  <number name="money" range="[0,]" scale="2"/>
  <number name="positiveInteger" range="[1,]" scale="0"/>
  <string name="date" pattern="-?\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(02-(0[1-9]|1\d|2\d))|((0[469]|11)-(0[1-9]|[12]\d|30)))"/>
  <string name="nonEmptyString" pattern="\S|\S.*\S"/>
  <object name="address">
    <property name="name" xsi:type="reference" type="nonEmptyString" nullable="false"/>
    <property name="address" xsi:type="reference" type="nonEmptyString" nullable="false"/>
    <property name="city" xsi:type="reference" type="nonEmptyString" nullable="false"/>
    <property name="postalCode" xsi:type="reference" type="nonEmptyString" nullable="false" use="optional"/>
    <property name="country" xsi:type="reference" type="nonEmptyString"/>
  </object>
  <object name="invoice">
    <property name="number" xsi:type="reference" type="positiveInteger"/>
    <property name="date" xsi:type="reference" type="date"/>
    <property name="billingAddress" xsi:type="reference" type="address"/>
    <property name="shippingAddress" xsi:type="reference" type="address"/>
    <property name="billedItems" xsi:type="array" nullable="false">
      <reference type="item"/>
    </property>
  </object>
  <object name="item">
    <property name="description" xsi:type="reference" type="nonEmptyString" nullable="false"/>
    <property name="code" xsi:type="reference" type="positiveInteger" nullable="false"/>
    <property name="quantity" xsi:type="reference" type="positiveInteger" nullable="false"/>
    <property name="price" xsi:type="reference" type="money" nullable="false"/>
  </object>

</schema>

Note: You can use the [Converter][#converter] utility to automatically convert between JSD and JSDx.

  2. With the invoice.jsd or invoice.jsdx, you can use the [jsonx-maven-plugin][jsonx-maven-plugin] to automatically generate the Java class files. In your POM, add:

<plugin>
  <groupId>org.jsonx</groupId>
  <artifactId>jsonx-maven-plugin</artifactId>
  <version>0.4.0</version>
  <executions>
    <execution>
      <goals>
        <goal>generate</goal>
      </goals>
      <phase>generate-sources</phase>
      <configuration>
        <destDir>${project.build.directory}/generated-sources/jsonx</destDir>
        <namespacePackages>
          <namespacePackage package="com.example.invoice."/>
        </namespacePackages>
        <schemas>
          <schema>src/main/resources/invoice.jsd</schema> <!-- or invoice.jsdx -->
        </schemas>
      </configuration>
    </execution>
  </executions>
</plugin>

  3. (Alternatively) Create the Java class files by hand:

Note: Set-ters and get-ters have been replaced with public fields for conciseness.

import org.jsonx.*;

public class Address implements JxObject {
  @StringProperty(pattern="\\S|\\S.*\\S", nullable=false)
  public String name;

  @StringProperty(pattern="\\S|\\S.*\\S", nullable=false)
  public String address;

  @StringProperty(pattern="\\S|\\S.*\\S", nullable=false)
  public String city;

  @StringProperty(pattern="\\S|\\S.*\\S", use=Use.OPTIONAL, nullable=false)
  public String postalCode;

  @StringProperty(pattern="\\S|\\S.*\\S")
  public String country;
}
import org.jsonx.*;

public class Item implements JxObject {
  @StringProperty(pattern="\\S|\\S.*\\S", nullable=false)
  public String description;

  @NumberProperty(range="[1,]", scale=0, nullable=false)
  public long code;

  @NumberProperty(range="[1,]", scale=0, nullable=false)
  public long quantity;

  @NumberProperty(range="[1,]", scale=2, nullable=false)
  public java.math.BigDecimal price;
 }
import org.jsonx.*;

public class Invoice implements JxObject {
  @NumberProperty(range="[1,]", scale=0)
  public Long number;

  @StringProperty(pattern="-?\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(02-(0[1-9]|1\\d|2\\d))|((0[469]|11)-(0[1-9]|[12]\\d|30)))")
  public String date;

  @ObjectProperty
  public Address billingAddress;

  @ObjectProperty
  public Address shippingAddress;

  @ObjectElement(id=0, type=Item.class)
  @ArrayProperty(elementIds={0}, nullable=false)
  public java.util.List<Item> billedItems;
}

  4. You can use these classes to represent Addresses, Items, and Invoices.

Address address = new Address();
address.name = "John Doe";
address.address = "111 Wall St.";
address.city = "New York";
address.postalCode = "10043";
address.country = "USA";

Item item = new Item();
item.code = 123;
item.description = "Pocket Protector";
item.price = new BigDecimal("14.99");
item.quantity = 5;

Invoice invoice = new Invoice();
invoice.number = 14738L;
invoice.date = "2019-05-13";
invoice.billingAddress = address;
invoice.shippingAddress = address;
invoice.billedItems = Collections.singletonList(item);

  5. You can now marshal the Java objects to JSON:

String json = JxEncoder._2.marshal(invoice);
System.out.println(json);

... will produce:

{
  "number": 14738,
  "date": "2019-05-13",
  "billingAddress": {
    "name": "John Doe",
    "address": "111 Wall St.",
    "city": "New York",
    "postalCode": "10043",
    "country": "USA"
  },
  "shippingAddress": {
    "name": "John Doe",
    "address": "111 Wall St.",
    "city": "New York",
    "postalCode": "10043",
    "country": "USA"
  },
  "billedItems": [{
    "description": "Pocket Protector",
    "code": 123,
    "quantity": 5,
    "price": 14.99
  }]
}

  6. You can also parse the JSON into Java objects:

Invoice invoice2 = JxDecoder.parseObject(Invoice.class, json);
assertEquals(invoice, invoice2);

For the application code, see [Sample: Invoice][sample-invoice].

5 Specification

The JSONx Runtime API is comprised of Java classes, interfaces, and annotations that belong to the org.jsonx package. The API consists of two logical parts: Structural and Functional.

5.1 Structural

The Structural part of the JSONx Runtime API is used to define rules that bind Java classes to JSON Schemas. The primitive JSON value types boolean, number and string are represented by their analogous Java types of Boolean, Number, and String. The object value type is represented by the JxObject interface, with properties defined with Property Annotations. The array value type is represented by the @ArrayType, @ArrayProperty and @ArrayElement annotations, with elements defined with Element Annotations.

5.1.1 JSON objects (JxObject)

An object definition in a JSD can be bound to a Java class that implements the JxObject interface. The JxObject interface does not define any methods, and is used to specify to the JSONx Runtime API that the class supports JSON binding.

public class MyObject implements JxObject {
  @BooleanProperty
  public Boolean prop1;

  @NumberProperty
  public Double prop2;

  @StringProperty
  public String prop3;
}
5.1.2 Property Annotations

Property annotations are used to define property bindings in JSON objects. Property annotations annotate fields in a class to bind to JSON properties in a JSON object. There are 6 property annotations:

  1. @ObjectProperty
  2. @ArrayProperty
  3. @BooleanProperty
  4. @NumberProperty
  5. @StringProperty
  6. @AnyProperty

Property annotations define 3 common attributes:

  1. name()

    The name of the property. If omitted, the name of the property is the field's name.

  2. nullable()

    Whether the property is allowed to be null. Default: true.

  3. use()

    Whether the property is required or optional (Use.REQUIRED or Use.OPTIONAL). Default: Use.REQUIRED.

5.1.2.1 Special Considerations

Different combinations of nullable() and use() have different requirements regarding field's declared type:

  • (nullable=false, use=Use.REQUIRED)

    Declared type is unrestricted, and allows boolean primitive for boolean JSON values, and numerical primitives (byte, short, int, long, float, and double) for number JSON values.

  • (nullable=true, use=Use.REQUIRED)

    Declared type must support null to represent a null JSON value. Primitive types are therefore not allowed.

  • (nullable=false, use=Use.OPTIONAL)

    Declared type must support null to represent an absent property. Primitive types are therefore not allowed.

  • (nullable=true, use=Use.OPTIONAL)

    Declared type must be Optional<>, so as to support the presence of the property with a null value, as well as its absence.

5.1.3 JSON arrays (@ArrayType)

The @ArrayType annotation is used to annotate an annotation class that represents binding rules for a JSON array. The @ArrayType annotation describes the manifest of element members that are allowed to appear in the JSON array. The manifest of element members is represented by Element Annotations.

The @ArrayType, @ArrayProperty and @ArrayElement annotations define 3 common attributes that specify rules for the manifest of element members:

  1. elementIds()

    Specifies the ids of element annotations declared in the same annotation context.

  2. minIterate()

    The minimum inclusive number of iterations of child elements. Default: 1.

  3. maxIterate()

    The maximum inclusive number of iterations of child elements. Default: 1.

Note: In order to support validation based on the aforementioned attributes, the JSONx framework relies on a "Breadth First Search" algorithm to attempt to match each member in a JSON array to an element definition. Loosely defined elements can result in more costly validation times. Elements defined with strict attributes, however, will result in optimal performance. When matching member elements of an array, the array validator has a worst case performance of O(N * E!), where N is the number of elements in an array, and E is the number of element classes in the array definition.

Example: The annotation @Staff defines a JSON array that is comprised of zero or more Contractor and Employee member types in any order.

@ObjectElement(id=1, type=Contractor.class, minOccurs=0)
@ObjectElement(id=0, type=Employee.class, minOccurs=0)
@ArrayType(elementIds={0, 1}, maxIterate=Integer.MAX_VALUE)
public @interface Staff {
}
5.1.3.1 Special Considerations

The minIterate() and maxIterate() attributes define the repetition cardinality of element types in a JSON array. The default for both attributes is 1, which effectively removes the computational complexity of multi-iterable array definitions during parsing, marshaling, and validating JSON arrays. It is important to note that when set to non-1 values, the computational complexity increases by one dimension. The value of minIterate() must be less than or equal to maxIterate().

5.1.4 Element Annotations

Element annotations are used to define element bindings in JSON arrays. Element annotations specify the rules for parsing, marshaling and validating JSON arrays in string or Java object form. There are 6 element annotations:

  1. @ObjectElement
  2. @ArrayElement
  3. @BooleanElement
  4. @NumberElement
  5. @StringElement
  6. @AnyElement

Element annotations define 4 common attributes:

  1. id()

    The id of the element, to be referenced in the elementIds() attribute of @ArrayType, @ArrayProperty and @ArrayElement annotations. The id must be unique in relation to other elements defined in the context of a particular JSON array type, property, or element.

    One can define JSON array bindings of one or more member types of arbitrary cardinality rules.

    Example: A JSON array allowing alternating members of boolean and number would define 2 element annotations

    @NumberElement(id=2)
    @BooleanElement(id=1)

    The ids 1 and 2 would thereafter be used in one of:

    • @ArrayType(elementIds={1, 2})
    • @ArrayProperty(elementIds={1, 2})
    • @ArrayElement(elementIds={1, 2})

    The elementIds() attribute specifies the relationality rules of the member elements.

  2. nullable()

    Whether the member element is allowed to be null. Default: true.

  3. minOccurs()

    The minimum inclusive number of occurrence of this element. Default: 1.

  4. maxOccurs()

    The maximum inclusive number of occurrence of this element. Default: Integer.MAX_VALUE.

5.1.5 JSON Value Annotations

In addition to the default attributes defined for Property Annotations and Element Annotations, the JSONx Runtime API defines specific attributes for JSON Value Types that map to analogous contstraint properties in the JSON Schema Definition Language.

5.1.5.1 object Type

A JSON object is represented by Java objects that implement the JxObject interface.

5.1.5.1.1 @ObjectProperty

The @ObjectProperty annotation is used to bind a JSON object type to a field in a JxObject subclass. The field's class type specifies the JSON binding class, which must be a subclass of the JxObject interface. If the field's class type does not inherit from the JxObject interface, the JSONx Runtime API will throw a ValidationException during parsing or marshaling.

Example: The class MyObject defines an object property that is of its own type (i.e. MyObject.object is of type MyObject).

public class MyObject implements JxObject {
  @ObjectProperty
  public MyObject object;
}
5.1.5.1.2 @ObjectElement

The @ObjectElement annotation is used to bind a JSON object type as a member type of a JSON array. The @ObjectElement defines the following additional attributes:

  1. type()

    The JSON binding class of type Class<? extends JxObject>.

Example: The class Company describes a JSON object with a JSON array that is comprised of Employee members.

public class Company implements JxObject {
  @ObjectElement(id=0, type=Employee.class)
  @ArrayProperty(elementIds={0})
  public List<Employee> employees;
}
5.1.5.2 array Type

A JSON array is represented by instances of java.util.List.

5.1.5.2.1 @ArrayProperty

The @ArrayProperty annotation is used to bind a JSON array definition to a field defined in a subclass of a JxObject. The @ArrayProperty annotation allows one to declare JSON array binding rules specific to the field on which they are defined.

Note: The field's type is required to be java.util.List. The generic type is checked during parsing and marshaling.

Example: The class Company describes a JSON object with a JSON array that is comprised of zero or more Contractor and Employee members in any order.

public class Company implements JxObject {
  @ObjectElement(id=1, type=Contractor.class, minOccurs=0)
  @ObjectElement(id=0, type=Employee.class, minOccurs=0)
  @ArrayProperty(elementIds={0, 1}, maxIterate=Integer.MAX_VALUE)
  public List<? extends Person> staff;
}

An alternative way to define the same structural rules is by using the @Staff annotation defined as a @ArrayType:

public class Company implements JxObject {
  @ArrayProperty(type=Staff.class, maxIterate=Integer.MAX_VALUE)
  public List<? extends Person> staff;
}
5.1.5.2.2 @ArrayElement

The @ArrayElement annotation is used to bind a JSON array definition as a member type of a JSON array. The @ArrayElement annotation allows one to declare JSON array binding rules that are specific only to the member element on which they are defined.

Example: The class Company describes a JSON object with a JSON array that is comprised of arrays of Contractor and Employee members.

public class Company implements JxObject {
  @ObjectElement(id=3, type=Contractor.class, minOccurs=0)
  @ObjectElement(id=2, type=Employee.class, minOccurs=0)
  @ArrayElement(id=1, elementIds={3})
  @ArrayElement(id=0, elementIds={2})
  @ArrayProperty(elementIds={0, 1})
  public List<List<? extends Person>> object;
}
5.1.5.3 boolean Type

A JSON boolean is represented by instances of java.lang.Boolean and boolean (refer to Special Considerations to determine the appropriate declared type).

5.1.5.3.1 @BooleanProperty
public class Company implements JxObject {
  @BooleanProperty(nullable=false, use=Use.REQUIRED)
  public boolean foo;

  @BooleanProperty(nullable=true, use=Use.REQUIRED)
  public Boolean bar;

  @BooleanProperty(nullable=true, use=Use.OPTIONAL)
  public Optional<Boolean> optional;
}
5.1.5.3.2 @BooleanElement
public class Company implements JxObject {
  @BooleanElement(id=1)
  @ArrayProperty(elementIds={1})
  public List<Boolean> booleans;
}
5.1.5.4 number Type

A JSON number is represented by instances of java.lang.Number and the primitive numerical types (byte, short, int, long, float, and double-- refer to Special Considerations to determine the appropriate declared type).

The @NumberProperty and @NumberElement annotations define the following additional attributes:

  1. scale()

    Specifies the number of digits to the right of the decimal point. Default: Integer.MAX_VALUE.

  2. range()

    Specifies the value range in interval notation:

    • Open (exclusive) interval: (min,max)
    • Closed (inclusive) interal: [min,max]
    • Half-open or half-closed interval: [min,max)
    • Degenerate interval (left bounded): [val] or [val,]
    • Degenerate interval (right bounded): [,val]
5.1.5.4.1 @NumberProperty
public class Company implements JxObject {
  @NumberProperty(range="(,0)", scale=0, nullable=false)
  public long negativeLong;

  @NumberProperty(range="[0,]", scale=2)
  public BigDecimal money;

  @NumberProperty(nullable=true, use=Use.OPTIONAL)
  public Optional<? extends Number> optional;
}
5.1.5.4.2 @NumberElement
public class Company implements JxObject {
  @NumberElement(id=1, range="[-1,1)")
  @ArrayProperty(elementIds={1})
  public List<? extends Number> numbers;
}
5.1.5.5 string Type

A JSON string is represented by instances of java.lang.String.

The @StringProperty and @StringElement annotations define the following additional attributes:

  1. pattern()

    Specifies the regex pattern.

5.1.5.5.1 @StringProperty
public class Company implements JxObject {
  @StringProperty(pattern="[a-z]+", nullable=false, use=Use.REQUIRED)
  public double real;

  @StringProperty(pattern="[0-9]+", nullable=true, use=Use.REQUIRED)
  public Long integer;

  @StringProperty(pattern="\\S+", nullable=true, use=Use.OPTIONAL)
  public Optional<String> optional;
}
5.1.5.5.2 @StringElement
public class Company implements JxObject {
  @StringElement(id=1, pattern="[a-z0-9]+", range="[-1,1)")
  @ArrayProperty(elementIds={1})
  public List<String> strings;
}
5.1.5.6 any Type

any represents a meta value type that is used to refer to actual JSON value types.

The @AnyProperty and @AnyElement annotations define the following additional attributes:

  1. types()

    Specifies the list of accepted type definitions. If omitted, the property or element will accept object of any type.

    The types() attribute utilizes an annotation named @t for the type specification, which defines the following attributes:

    1. arrays()

      An annotation class that specifies a @ArrayType annotation.

    2. booleans()

      A boolean value specifying whether boolean properties or element members are allowed.

    3. numbers()

      A @NumberType annotation that declares form() and range() attributes specifying acceptable number values.

    4. strings()

      A regex specifying accepted String instances.

    5. objects()

      A Class<? extends JxObject> specifying acceptable object classes.

5.1.5.6.1 @AnyProperty
public class Company implements JxObject {
  @AnyProperty(types={@t(booleans=true)}, nullable=false, use=Use.REQUIRED)
  public Boolean booleans;

  @AnyProperty(types={@t(numbers=@NumebrType(range="[,100]"), scale=0)}, nullable=true, use=Use.REQUIRED)
  public Long integers;

  @AnyProperty(types={@t(numbers=@NumebrType(range="[,100]", scale=0), @t(strings="[a-z]+"))}, nullable=true, use=Use.OPTIONAL)
  public Optional<Object> optional;
}
5.1.5.6.2 @AnyElement
public class Company implements JxObject {
  @AnyElement(id=1, types={@t(numbers=@NumebrType(range="[,100]"), scale=0, @t(strings="[a-z]+"))}, nullable=false)
  @ArrayProperty(elementIds={1})
  public List<Object> any;
}
5.1.5.7 AnyObject

The AnyObject class is a JSON/Java binding that utilizes the @AnyProperty annotation to be able to represent any JSON object.

5.1.5.8 @AnyArray

The AnyArray annotation is a JSON/Java binding that utilizes the @AnyElement annotation to be able to represent any JSON array.

5.2 Functional

The functional part of the JSONx Runtime API is responsible for parsing, marshaling, and validating JSON documents in string or object form.

5.2.1 ValidationException

The ValidationException represents an error in the use of the Structural part of the JSONx Runtime API. The ValidationException is thrown when the binding model is evaluated during the process of parsing a JSON document string to binding classes, or marshaling binding classes to a JSON document string.

5.2.2 JxEncoder

The JxEncoder serializes Jx objects (that extend JxObject) and Jx arrays (with a provided annotation class that declares an @ArrayType annotation) to JSON documents. JxEncoder instances are differentiated by the indent value, which represents the number of spaces to use (as meaningless whitespace) when encoding JSON documents. The JxEncoder has a protected constructor, and exposes static fields and methods to obtain a JxEncoder instance so that instances can be cached.

  1. JxEncoder#_0

    The JxEncoder instance with indent=0.

  2. JxEncoder#_1

    The JxEncoder instance with indent=1.

  3. JxEncoder#_2

    The JxEncoder instance with indent=2.

  4. JxEncoder#_3

    The JxEncoder instance with indent=3.

  5. JxEncoder#_4

    The JxEncoder instance with indent=4.

  6. JxEncoder#_8

    The JxEncoder instance with indent=8.

  7. JxEncoder#get(int)

    Gets the the JxEncoder instance for the specified indent value. The specified value must be a non-negative integer.

  8. JxEncoder#get()

    Gets the the global JxEncoder instance. The default global JxEncoder has indent=0.

  9. JxEncoder#set(JxEncoder)

    Sets the the global JxEncoder instance to the specified JxEncoder.

Once a JxEncoder instance is obtained, it can be used to marshal binding objects to JSON document strings.

  1. JxEncoder#marshal(List<?>, Class<? extends Annotation>)

    Marshals the supplied list to the specification of the provided annotation type. The provided annotation type must declare an annotation of type @ArrayType that specifies the model of the list being marshaled.

  2. JxEncoder#marshal(JxObject)

    Marshals the specified JxObject.

5.2.2.1 EncodeException

Signals that an error has occurred while encoding a JSON document.

5.2.3 JxDecoder

The JxDecoder deserializes JSON documents to objects of JxObject classes, or to lists conforming to a provided annotation class that declares an @ArrayType annotation. The JxDecoder is an uninstantiable class that provides static methods for parsing JSON document strings.

  1. JxDecoder#parseObject(Class<? extends JxObject>, JsonReader)

    Parses a JSON object from the supplied JsonReader as per the specification of the provided JxObject class.

  2. JxDecoder#parseArray(Class<? extends Annotation>, JsonReader)

    Parses a JSON array from the supplied JsonReader as per the specification of the provided annotation class that declares an ArrayType annotation.

5.2.3.1 DecodeException

Signals that an error has occurred while decoding a JSON document.

6 Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

7 Special Thanks

Java Profiler
Special thanks to EJ Technologies for providing their award winning Java Profiler (JProfiler) for development of the JSONx Framework.

8 License

This project is licensed under the MIT License - see the LICENSE.txt file for details.