Preamble

The JON Reader and Writer are very simple to use and require minimal boilerplate code to use by default. This document attempts to capture the standard usage for getting started with using JON.

Usage

Indirect Type Library

JON needs a context for constructing lexical specifications for a set of object instances. Those specifications are instances of org.fuwjax.jon.IndirectType and the context which constructs them is org.fuwjax.jon.IndirectTypeLibrary. An IndirectTypeLibrary which builds IndirectType instances reflectively is provided by the JON package. Simply create a org.fuwjax.jon.ClassTypeLibrary to build this context.

IndirectTypeLibrary library = new ClassTypeLibrary();

IndirectType instances can be fetched from the library by one of two methods, getTypeFor(Object) or getType(Class). The getTypeFor method returns a IndirectType for the class of the provided object, whereas getType returns an IndirectType wrapping the class argument.

IndirectType type = library.getTypeFor(obj);

Writing

To write, we need an output destination which in JON is a org.fuwjax.jon.CachedAppendable instance. A simple implementation is provided by org.fuwjax.jon.DefaultCachedAppender. The default constructor creates a CachedAppendable which writes to a StringBuilder, or an Appendable instance can be provided to the alternate constructor.

CachedAppendable appender = new DefaultCachedAppender();

From there we can either create a writer from the IndirectTypeLibrary or from an IndirectType. Creating a writer from the library directly assumes no information about the type of object while the IndirectType generates a writer that assumes it will get instances of the class wrapped by the IndirectType. If this typed writer writes an object of the type it was expecting, it will not cast the object in the output.

Writer writer = library.createWriter(appender);

Once a writer is created, writing is simply a matter of passing an object in for serialization to the CachedAppendable.

writer.write(obj);

Reading

Reading works much the same way as writing. First we create a CachedLexable instance. And again JON provides a simple implementation org.fuwjax.jon.DefaultCachedLexer which takes a CharSequence in its constructor. This CharSequence must be a JON formatted sequence of characters.

CachedLexable lexer = new DefaultCachedLexer(jonString);

Again we can create a reader from the IndirectTypeLibrary or from an IndirectType. The reader from the IndirectType is expecting an object of that IndirectType, so if there is no cast, it will assume that type.

Reader reader = library.createReader(lexer);

The reader has two methods, read() and read(Object). Both will read and return the next object from the input, but the read method with an object argument will attempt to fill the supplied instance instead of creating a new instance.

Object obj = reader.read();

Exceptions

Both read and write methods throw two possible exceptions. SerialFormatException is thrown when there is a problem with respect to the JON format of the read or write operation. This includes things such as unexpected end of IO and unexpected tokens or identifiers. ObjectAccessException is thrown when there is a problem creating, accessing or mutating objects during the read or write process. It is expected that ObjectAccessExceptions are programmer problems and should not occur outside of development. SerialFormatExceptions are problems with the input and may crop up in production environments. These exceptions should be handled accordingly.