blob: ae5e5f89e3853051e2422f1277953b98d5c3aa15 [file] [log] [blame]
<!--
/***************************************************************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
***************************************************************************************************************************/
-->
Contexts, Builders, Sessions, and PropertyStores
<p>
All the serializers, parsers, and REST server/client classes use the following design pattern:
</p>
<ul class='spaced-list'>
<li>
<l>Context</l> - A thread-safe read-only object.
<ul>
<li>Heavy to construct and designed to be cached and reused.
<li>Created by <l>ContextBuilder</l> classes.
<li>Examples: <c>BeanContext</c>, <c>JsonSerializer</c>
</ul>
<li>
<l>Session</l> - A non-thread-safe single-use object with configuration combined from context and
runtime args such as locale/timezone.
<ul>
<li>Lightweight objects that take a minimum amount of time to instantiate and are not typically reused.
<li>Created by <c>Context</c> objects.
<li>Examples: <c>BeanSession</c>, <c>JsonSerializerSession</c>
</ul>
<li>
<l>PropertyStore</l> - A thread-safe read-only set of configuration properties.
<ul>
<li>Heavier to create than <c>Sessions</c> but lighter than <c>Contexts</c>.
<li>Each <c>Context</c> contains one <c>PropertyStore</c> that defines all the configuration about that object.
<li>Created by <l>PropertyStoreBuilder</l> classes.
</ul>
</ul>
<p>
For example, the class hierarchy for <c>JsonSerializer</c> is:
</p>
<ul class='javatree'>
<li class='jc'><c>Object</c>
<ul>
<li class='jac'>{@link oaj.Context}
<ul>
<li class='jc'>{@link oaj.BeanContext}
<ul>
<li class='jac'>{@link oaj.serializer.Serializer}
<ul>
<li class='jac'>{@link oaj.serializer.WriterSerializer}
<ul>
<li class='jc'>{@link oaj.json.JsonSerializer}
</ul>
</ul>
</ul>
</ul>
</ul>
</ul>
<p>
Each context object in the hierarchy define properties that can be stored in a <c>PropertyStore</c>
such as <jsf>WSERIALIZER_useWhitespace</jsf> or <jsf>JSON_simpleMode</jsf>.
</p>
<p>
The class hierarchy for <c>JsonSerializerBuilder</c> is:
</p>
<ul class='javatree'>
<li class='jc'><c>Object</c>
<ul>
<li class='jac'>{@link oaj.ContextBuilder}
<ul>
<li class='jc'>{@link oaj.BeanContextBuilder}
<ul>
<li class='jac'>{@link oaj.serializer.SerializerBuilder}
<ul>
<li class='jac'>{@link oaj.serializer.WriterSerializerBuilder}
<ul>
<li class='jc'>{@link oaj.json.JsonSerializerBuilder}
</ul>
</ul>
</ul>
</ul>
</ul>
</ul>
<p>
The class hierarchy for <c>JsonSerializerSession</c> is:
</p>
<ul class='javatree'>
<li class='jc'><c>Object</c>
<ul>
<li class='jac'>{@link oaj.Session}
<ul>
<li class='jc'>{@link oaj.BeanSession}
<ul>
<li class='jac'>{@link oaj.serializer.SerializerSession}
<ul>
<li class='jac'>{@link oaj.serializer.WriterSerializerSession}
<ul>
<li class='jc'>{@link oaj.json.JsonSerializerSession}
</ul>
</ul>
</ul>
</ul>
</ul>
</ul>
<p>
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'.
</p>
<p>
For example, two serializers of the same type created with the same configuration will always end up being
the same serializer:
</p>
<p class='bpcode w800'>
<jc>// Two serializers created with identical configurations will always be the same copy.</jc>
WriterSerializer s1 = JsonSerializer.<jsm>create</jsm>().pojoSwaps(MySwap.<jk>class</jk>).simple().build();
WriterSerializer s2 = JsonSerializer.<jsm>create</jsm>().set(<jsf>JSON_simpleMode</jsf>, <jk>true</jk>).pojoSwaps(MySwap.<jk>class</jk>).build();
<jk>assert</jk>(s1 == s2);
</p>
<p>
This has the effect of significantly improving performance especially if you're creating many
serializers and parsers.
</p>
<p>
The {@link oaj.PropertyStoreBuilder} class is used to build up and instantiate immutable
<c>PropertyStore</c> objects.
</p>
<p>
In the example above, the property store being built looks like the following:
</p>
<p class='bpcode w800'>
PropertyStore ps = PropertyStore
.<jsm>create</jsm>()
.set(<js>"BeanContext.pojoSwaps.lc"</js>, MySwap.<jk>class</jk>)
.set(<js>"JsonSerializer.simpleMode.b"</js>, <jk>true</jk>)
.build();
</p>
<p>
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.
</p>
<p>
Refer to the {@link oaj.PropertyStore} javadoc for a detailed explaination on how
property stores work.
</p>