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 WSERIALIZER_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().swaps(MySwap.class).simple().build();
WriterSerializer s2 = JsonSerializer.create().set(JSON_simpleMode, true).swaps(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.swaps.lo", 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.