software.amazon.ion.overview.html Maven / Gradle / Ivy
Show all versions of ion-java Show documentation
ion-java is the reference implementation of the
Ion data notation for the
JavaTM 2 Platform Standard Edition 5.0
and above.
This document describes all APIs intended for public consumption, limited to
the packages listed here. The ion-java library distribution includes other
packages not documented here; use of those packages is not supported,
so don't use them!
More generally:
Any behavior or features not present in this API documentation is
unsupported, probably untested, and subject to change without notice.
In addition, unless otherwise noted, interfaces and classes listed here
should not be implemented or extended by code outside of this library! We
may add or remove API(s) of existing interfaces or classes in future releases.
If your application does not observe these warnings, it will impede the release
cycle of this library.
Start at IonSystem
The central interface in ion-java is {@link software.amazon.ion.IonSystem}, which is
the main factory and facade for all Ion processing.
The intended architectural pattern is for your application to build a
single system instance and use it
throughout the application. The {@code IonSystem} interface provides access
to all other components, including the capability to construct
{@link software.amazon.ion.IonValue IonValue} hierarchies.
What all this means is that your first task is acquiring a system instance, and
for that we turn to
{@link software.amazon.ion.system.IonSystemBuilder IonSystemBuilder}.
Here's the easiest way to bootstrap:
IonSystem ion = IonSystemBuilder.standard().build();
That should be sufficient for many, but not all, applications. Long-running
services will probably want to use a non-default
{@linkplain software.amazon.ion.IonCatalog catalog} by configuring the builder
before calling {@link software.amazon.ion.system.IonSystemBuilder#build() build()}.
SystemFactory is Deprecated
As of early 2011, the {@link software.amazon.ion.system.SystemFactory SystemFactory}
class has been deprecated in favor of {@code IonSystemBuilder}.
This should be a straightforward application change and we strongly recommend
that all applications update.
An Important Caveat
Objects returned by one {@code IonSystem} cannot by mixed with objects returned
by another {@code IonSystem}! For example, the following code is not
guaranteed to work:
IonSystem sys1 = IonSystemBuilder.standard().build();
IonSystem sys2 = IonSystemBuilder.standard().build();
IonList parent = sys1.newEmptyList();
IonInt child = sys2.newInt(23);
parent.add(child); // NOT SUPPORTED
Given any {@code IonValue} instance it is possible to retrieve the relevant
system via {@link software.amazon.ion.IonValue#getSystem()}.
This is generally the best way to ensure
that you're using the correct system while modifying existing trees.
You can also use the "Curried" insertion methods to add new values to
collections:
struct.put("f").newInt(3);
list.add().newString("demo");
Getting Data In
This release defines three mechanisms for accepting Ion data:
- {@link software.amazon.ion.IonReader IonReader} scans an input stream using a
"pull parsing" paradigm. This is a low-level, high-performance API, and
the other mechanisms are built on top of it.
- Iteration reads an input stream by
iterating over its top-level elements. This "one at a time" input
mechanism is intended for stream-oriented applications.
- {@link software.amazon.ion.IonLoader IonLoader} loads an entire input stream
into a single {@linkplain software.amazon.ion.IonDatagram datagram}.
This "all at once" input mechanism is intended for document-oriented
applications.
All mechanisms accept either text or binary Ion data, and applications should
rarely care about the input format.
To construct an {@code IonReader}, call one of the {@code newReader} methods
on {@code IonSystem}; for example
{@link software.amazon.ion.IonSystem#newReader(InputStream)}.
You can then pull data from the reader. Don't forget to
{@link software.amazon.ion.IonReader#close() close} it when you're done!
Ion iterators are extensions of
{@link java.util.Iterator} so they are used once and then discarded.
Use the various {@code iterate} methods on {@code IonSystem} to
create them; for example
{@link software.amazon.ion.IonSystem#iterate(InputStream)}.
To construct an {@code IonLoader}, call
{@link software.amazon.ion.IonSystem#newLoader()} and configure it as necessary.
{@code IonLoaders} are safe for use by multiple threads. The {@code IonSystem}
also maintains a "default loader" so you don't have to pass one around, see
{@link software.amazon.ion.IonSystem#getLoader()}.
Getting Data Out
There's also several mechanisms for generating Ion data:
- {@link software.amazon.ion.IonWriter IonWriter} is the low-level API for
generating Ion data in some form. It's agnostic to the output format; in
theory the actual output could be some other format entirely.
- {@link software.amazon.ion.IonValue#toString() IonValue.toString()} will also
generate Ion text, but it's primarily intended for debugging purposes and
cannot be customized. The particular layout is not specified by contract,
so don't assume that it will always output the same thing!
- {@link software.amazon.ion.IonValue#writeTo(IonWriter)} outputs Ion data in
the writer's format. This is the best way to output the data model.
- From an {@link software.amazon.ion.IonDatagram IonDatagram} you can call
{@link software.amazon.ion.IonDatagram#getBytes() getBytes()} to get Ion
binary data.
You can create {@code IonWriter}s using methods on {@code IonSystem}, but the
{@link software.amazon.ion.system.IonTextWriterBuilder} provides more flexibility.
No Canonical Serialization
There is no specified canonical form of Ion serialized data, and none of the
APIs in this library attempt to create one. Further, no API in this library
guarantees repeatable or stable output for any data type. Different releases
of this library, or even different invocations of the same API, may produce
different encodings from the same input.
This caveat applies to both Ion text and binary forms, although violations
are far more common (and easier to make) using Ion text.
Therefore, applications and tests should never compare the serialized form of
data to determine equality. For example, the following JUnit idiom is
not supported:
assertEquals(expectedIonValue.toString(), actualIonValue.toString());
The same goes for output via any other API, including
{@link software.amazon.ion.IonWriter IonWriter}s.
The correct approach to performing semantic equivalence checks over Ion data is
to use documented equivalence APIs such as
{@link software.amazon.ion.IonValue#equals(Object) IonValue.equals()}.
JSON Integration
The Ion text format is a superset of JSON, so JSON data is Ion data.
This means that you can read JSON data as-is using the Ion libraries, with a
caveat:
JSON numbers with exponents are decoded as Ion float, while those with
fractions (but not exponents) are decoded as Ion decimal.
To output JSON with this library, Ion data can be "downconverted" to JSON
format using an
{@link software.amazon.ion.system.IonTextWriterBuilder IonTextWriterBuilder}.
This replaces Ion-only datatypes with more-or-less equivalent JSON values.
(The {@link software.amazon.ion.util.Printer Printer} can also be used, but it is
no longer recommended and will be deprecated.)
Thread Safety
All interfaces and classes are not safe for use by multiple threads
unless documented otherwise.