Contexts, Builders, Sessions, and PropertyStores

All the serializers, parsers, and REST server/client classes use the following design pattern:

- Context - A thread-safe read-only object.
  - Heavy to construct and designed to be cached and reused.
  - Created by ContextBuilder classes.
  - Examples: `BeanContext`, `JsonSerializer`
- Session - A non-thread-safe single-use object with configuration combined from context and runtime args such as locale/timezone.
  - Lightweight objects that take a minimum amount of time to instantiate and are not typically reused.
  - Created by `Context` objects.
  - Examples: `BeanSession`, `JsonSerializerSession`
- PropertyStore - A thread-safe read-only set of configuration properties.
  - Heavier to create than `Sessions` but lighter than `Contexts`.
  - Each `Context` contains one `PropertyStore` that defines all the configuration about that object.
  - Created by PropertyStoreBuilder classes.

For example, the class hierarchy for `JsonSerializer` is:

- `Object`
  - {@link oaj.Context}
    - {@link oaj.BeanContext}
      - {@link oaj.serializer.Serializer}
        - {@link oaj.serializer.WriterSerializer}
          - {@link oaj.json.JsonSerializer}

Each context object in the hierarchy define properties that can be stored in a `PropertyStore` such as SERIALIZER_useWhitespace or JSON_simpleMode.

The class hierarchy for `JsonSerializerBuilder` is:

- `Object`
  - {@link oaj.ContextBuilder}
    - {@link oaj.BeanContextBuilder}
      - {@link oaj.serializer.SerializerBuilder}
        - {@link oaj.serializer.WriterSerializerBuilder}
          - {@link oaj.json.JsonSerializerBuilder}

The class hierarchy for `JsonSerializerSession` is:

- `Object`
  - {@link oaj.Session}
    - {@link oaj.BeanSession}
      - {@link oaj.serializer.SerializerSession}
        - {@link oaj.serializer.WriterSerializerSession}
          - {@link oaj.json.JsonSerializerSession}

The general idea behind a {@link oaj.PropertyStore} is to serve as a reusable configuration of an artifact (such as a serializer) such that the artifact can be cached and reused if the property stores are 'equal'.

For example, two serializers of the same type created with the same configuration will always end up being the same serializer:

// Two serializers created with identical configurations will always be the same copy. WriterSerializer s1 = JsonSerializer.create().pojoSwaps(MySwap.class).simple().build(); WriterSerializer s2 = JsonSerializer.create().set(JSON_simpleMode, true).pojoSwaps(MySwap.class).build(); assert(s1 == s2);

This has the effect of significantly improving performance especially if you're creating many serializers and parsers.

The {@link oaj.PropertyStoreBuilder} class is used to build up and instantiate immutable `PropertyStore` objects.

In the example above, the property store being built looks like the following:

PropertyStore ps = PropertyStore .create() .set("BeanContext.pojoSwaps.lc", MySwap.class) .set("JsonSerializer.simpleMode.b", true) .build();

Property stores are immutable, comparable, and their hashcodes are calculated exactly one time. That makes them particularly suited for use as hashmap keys, and thus for caching reusable serializers and parsers.

Refer to the {@link oaj.PropertyStore} javadoc for a detailed explaination on how property stores work.