http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/d45e1351/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html
b/juneau-core/src/main/javadoc/overview.html
index 7eb40bd..07d18c9 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -55,30 +55,43 @@
}
}
</script>
-<p>
- A generalized toolkit for converting POJOs to and from a variety of
content types (JSON, XML, HTML, URLs, RDF/XML, N-Tuple, Turtle, N3, SOAP,
Cognos, ATOM), and a REST toolkit for building up REST interfaces using simple
POJOs.
-</p>
+<ul class='spaced-list'>
+ <li>A toolkit for marshalling POJOs to a wide variety of content types
using a common framework.
+ <li>A REST server API for creating self-documenting REST interfaces
using POJOs.
+ <li>A REST client API for interacting with REST interfaces using POJOs.
+ <li>A remote proxy API built on top of REST.
+ <li>A sophisticated INI config file API.
+ <li>A REST microservice API that combines all the features above for
creating lightweight standalone REST interfaces that start up in milliseconds.
+</ul>
<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
<ol class='toc'>
<li><p><a class='doclink' href='#Intro'>Juneau - What is it?</a></p>
- <li><p><a class='doclink' href='#Core'>Juneau Core (juneau.jar)</a></p>
+ <li><p><a class='doclink' href='#Core'>Juneau Core
(org.apache.juneau)</a></p>
<ol>
- <li><p><a class='doclink' href='#Core.PojoCategories'>POJO
Categories</a></p>
<li><p><a class='doclink'
href='#Core.Serializers'>Serializers</a></p>
<li><p><a class='doclink' href='#Core.Parsers'>Parsers</a></p>
+ <li><p><a class='doclink'
href='#Core.SerializerAndParserGroups'>SerializerGroups and ParserGroups</a></p>
<li><p><a class='doclink' href='#Core.ObjectMap'>ObjectMap and
ObjectList</a></p>
<li><p><a class='doclink'
href='#Core.ConfigurableProperties'>Configurable Properties</a></p>
- <li><p><a class='doclink'
href='#Core.Annotations'>Annotations</a></p>
<li><p><a class='doclink'
href='#Core.Transforms'>Transforms</a></p>
+ <ol>
+ <li><p><a class='doclink'
href='#Core.PojoSwaps'>PojoSwaps</a></p>
+ <li><p><a class='doclink'
href='#Core.BeanFilters'>BeanFilters and @Bean annotations</a></p>
+ </ol>
+ <li><p><a class='doclink' href='#Core.BeanDictionaries'>Bean
Name and Dictionaries</a></p>
+ <ol>
+ <li><p><a class='doclink'
href='#Core.BeanSubTypes'>Bean Subtypes</a></p>
+ </ol>
+ <li><p><a class='doclink' href='#Core.PojoCategories'>POJO
Categories</a></p>
<li><p><a class='doclink' href='#Core.SimpleVarLanguage'>Simple
Variable Language</a></p>
<li><p><a class='doclink' href='#Core.ConfigFile'>Configuration
Files</a></p>
<li><p><a class='doclink'
href='#Core.SupportedLanguages'>Supported Languages</a></p>
</ol>
- <li><p><a class='doclink' href='#Server'>Juneau Server
(juneau-server.jar)</a></p>
- <li><p><a class='doclink' href='#Client'>Juneau Client
(juneau-client.jar)</a></p>
- <li><p><a class='doclink' href='#Remoteable'>Remoteable services</a></p>
- <li><p><a class='doclink' href='#Microservices'>Juneau Microservices
(juneau-microservice.jar)</a></p>
+ <li><p><a class='doclink' href='#Server'>Juneau Server
(org.apache.juneau.server)</a></p>
+ <li><p><a class='doclink' href='#Client'>Juneau Client
(org.apache.juneau.client)</a></p>
+ <li><p><a class='doclink' href='#Remoteable'>Remoteable services
(org.apache.juneau.server.remoteable)</a></p>
+ <li><p><a class='doclink' href='#Microservices'>Juneau Microservices
(org.apache.juneau.microservice)</a></p>
<li><p><a class='doclink' href='#Samples'>Samples</a></p>
<ol>
<li><p><a class='doclink' href='#Samples.Installing'>Installing
in Eclipse</a></p>
@@ -136,33 +149,35 @@
<h2 class='topic' onclick='toggle(this)'>1 - Juneau - What is it?</h2>
<div class='topic'>
<p>
- Juneau started off as a simple library for serializing and
parsing POJOs to and from JSON.
- Since then, it has expanded into serializing and parsing a
variety of other content types.
- Later, entire REST client, server, and microservice APIs were
developed that utilized the power of these serializers and parsers.
- Together, these features allow the construction of powerful
REST interfaces wrapped around existing POJOs using very little code.
+ Juneau started off as a popular internal IBM toolkit called
Juno.
+ Originally used for serializing POJOs to and from JSON, it
later expanded in scope to include a variety of content types, and then later
REST servlet, client, and microservice APIs.
+ It's use grew to more than 50 projects and was one of the most
popular community source projects within IBM.
</p>
-
+ <p>
+ In 2016, the code was donated to the Apache Foundation under
the project <l>Apache Juneau</l>.
+ </p>
<h5 class='toc'>Features</h5>
<ol class='toc'>
<li>
- <p>Extensive and extensible support for a large variety
of POJOs, including structured data (beans) and unstructured data (<l>Maps</l>
and <l>Collections</l>).</p>
+ <p>Extensive and extensible support for a large variety
of POJOs, including structured data (beans) and unstructured data
(<code>Maps</code> and <code>Collections</code>).</p>
<li>
- <p>Support for serializing POJO models to:</p>
+ <p>Serialization support:</p>
<ul>
<li>JSON (including variants)
- <li>XML
+ <li>XML
<li>HTML
<li>URL-Encoding
<li>UON (URL-Encoded Object Notation)
<li>MessagePack
- <li>RDF/XML (including abbreviated)
+ <li>RDF/XML
+ <li>RDF/XML-Abbrev
<li>N-Triple
<li>Turtle
<li>N3
<li>SOAP/XML
</ul>
<li>
- <p>Support for parsing the following into POJO
models:</p>
+ <p>Parsing support:</p>
<ul>
<li>JSON (including lax syntax, comments,
concatenated strings)
<li>XML
@@ -170,336 +185,110 @@
<li>URL-Encoding
<li>UON (URL-Encoded Object Notation)
<li>MessagePack
- <li>RDF/XML (including abbreviated)
+ <li>RDF/XML
+ <li>RDF/XML-Abbrev
<li>N-Triple
<li>Turtle
<li>N3
</ul>
<li>
- <p>Data Transfer Objects for the following:</p>
+ <p>Data Transfer Objects:</p>
<ul>
<li>ATOM
<li>Cognos
<li>JSON-Schema
<li>HTML 5 (in progress)
</ul>
- <p>DTOs can be used with any serializers and parsers.
+ <p>DTOs can be used with any serializers and parsers
(e.g. ATOM as JSON).
<li>
- <p>Support for serializing POJO meta-models
(specifically the POJO class structure itself) to:</p>
+ <p>Serialization of POJO meta-models (e.g. the POJO
class structure itself) to:</p>
<ul>
<li>JSON-Schema
<li>XML-Schema
<li>HTML-Schema
</ul>
<li>
- <div>
- JSON parser supports ALL valid JSON, such as:
- <ul class='normal'>
- <li>Javascript comments.
- <li>Single or double quoted values.
- <li>Quoted (strict) or unquoted
(non-strict) attributes.
- <li>JSON fragments (such as string,
numeric, or boolean primitive values).
- <li>Concatenated strings.
- </ul>
- </div>
- <li>
- <div>
- REST server interface that allows POJOs to be
accessed through REST calls.
- <ul class='normal'>
- <li>Serialization and parsing layer is
completely transparent to developer.
- Simply pass a POJO to the
toolkit, and all serialization and parsing is taken care of.
- <li>Extensible / customizable design.
- Ability to define support for
additional content types, or to handle requests manually at many different
levels.
- <li>Default built-in support for
serializing output to all supported languages.
- <li>Default built-in support for
parsing input from all supported languages.
- <li>Ability to easily design
self-documenting interfaces (specifically REST interfaces described entirely
through OPTIONS requests).
- <li>Ability to debug interface using
nothing more than a browser, including the ability to specify any HTTP headers
as GET parameters.
- </ul>
- </div>
- <li>
- <p>REST client interface that allows clients to parse
POJOs from the REST server, typically in a single line of code.</p>
- <li>
- <p>No code generators required. Can be used against
existing POJO models, unlike other APIs like Java Web Services.</p>
- <li>
<p>
- Serializers/parsers require only Java 1.6+.
+ Serializers/parsers require only Java 6+.
(RDF support requires Jena 2.7.1+)
</p>
<li>
<p>
- REST APIs require only Java 1.6+ and JEE 1.3+.
+ REST APIs require only Java 6+ and JEE 1.3+.
(JAX/RS integration component requires JAX/RS
provider)
</p>
- <li>
- <p>Extensive and up-to-date Javadocs with color-coded
code examples.</p>
- <li>
- <p>
- Code written for
high-performance/high-concurrency/low-memory consumption.<br>
- Caching of POJO metadata speeds execution of
serialization and parsing.<br>
- JSON parser is written using a state-machine
architecture.<br>
- XML and HTML parsers are written using
StAX.<br>
- POJOs are serialized/parsed directly from POJOs
without a DOM layer, reducing object creation.
- </p>
- <li>
- <p>A simple-to-use JAX-RS / Wink provider for using the
existing Juneau serializers and parsers in a JAX-RS environment.</p>
- <li>
- <p>An external INI-style configuration file API.</p>
- <li>
- <p>An API for defining REST resource microservices as
simple executable jars.</p>
</ol>
<h5 class='topic'>Components</h5>
<p>
- Juneau consists of the following libraries:
+ Juneau ships as a single Java library called <l>juneau.jar</l>.
</p>
- <ul class='spaced-list'>
- <li><l>juneau.jar</l> - Core library that contains the
serializers, parsers, and bean map support.<br>
- Prereqs Java 1.6+.<br>
- This package can be used by itself if you only need to
serialize or parse from any of the supported languages, or use the Bean Map
support separately.<br>
- See the following subtopic <a class='doclink'
href='#Core'>Juneau Core (juneau.jar)</a> for details on this library.<br>
- <li><l>juneau-server.jar</l> - Contains the REST server
APIs.<br>
- Prereqs Java 1.6+, JEE 1.3+.<br>
- This package can be used to create servlet-based REST
interfaces.<br>
- See <a class='doclink' href="#Server">Juneau Server
(juneau-server.jar)</a> for details on this library.<br>
- <li><l>juneau-client.jar</l> - Contains the REST client
APIs.<br>
- Prereqs Java 1.6+.<br>
- This package can be used to easily communicate with
Juneau REST servlets.<br>
- See <a class='doclink' href="#Client">Juneau Client
(juneau-client.jar)</a> for details on this library.<br>
- <li><l>juneau-microservice.jar</l> - An API for defining REST
services as executable jars.<br>
- See <a class='doclink' href="#Microservices">Juneau
Microservices (juneau-microservice.jar)</a> for details on this package.<br>
- <li><l>juneau-all.jar</l> - Combines all the jars above into a
single library.
+ <p>
+ Juneau requires Java 6+. The majority of the code has no other
dependencies except for the following packages:
+ </p>
+ <ul class='javahierarchy'>
+ <li class='p'> {@link org.apache.juneau.jena} - RDF support.
Requires Apache Jena 2.7.1+.
+ <li class='p'> {@link org.apache.juneau.server} - REST servlet
support. Requires JEE 1.3+.
+ <li class='p'> {@link org.apache.juneau.client} - REST client
support. Requires Apache HttpClient 4.5+.
</ul>
<p>
- Typically, you want to simply pick up and use
<l>juneau-all.jar</l> as this contains everything and is not very large (<
1MB).
+ OSGi bundles are also provided that break down Juneau into the
following components:
</p>
+ <ul class='spaced-list'>
+ <li><l>org.apache.juneau.core.jar</l> - Serializers, parsers,
INI file support.<br>
+ <li><l>org.apache.juneau.server.jar</l> - REST servlet
support.<br>
+ <li><l>org.apache.juneau.client.jar</l> - REST client
support.<br>
+ <li><l>org.apache.juneau.microservice.jar</l> - Microservice
support.<br>
+ </ul>
<p>
The following zip files are also provided:
</p>
<ul class='spaced-list'>
<li><l>microservice-project.zip</l> - Contains a template
Eclipse project for quickly creating REST resources as executable jars.
- <li><l>microservice-samples-project.zip</l> - Contains sample
code demonstrating various aspects of the Juneau Cloud Tools.<br>
+ <li><l>microservice-samples-project.zip</l> - Contains sample
code demonstrating various aspects of Juneau.<br>
These are discussed in detail in the <a class='doclink'
href="#Samples">Samples</a> section.
</ul>
+
+ <h5 class='topic'>A note about examples</h5>
<p class='info'>
- Many of the examples below use beans with public field
properties.
- While the toolkit allows for public bean properties, it's
standard practice to use getters and setters for bean properties.
- However, the examples below use public fields simply to reduce
their verbosity.
+ Many of the examples below use beans with public field
properties instead of standard getters/setters.
+ This is to simplify the examples.
</p>
</div>
<!--
========================================================================================================
-->
<a id="Core"></a>
-<h2 class='topic' onclick='toggle(this)'>2 - Juneau Core (juneau.jar)</h2>
+<h2 class='topic' onclick='toggle(this)'>2 - Juneau Core
(org.apache.juneau)</h2>
<div class='topic'>
<p>
- The Juneau core library <l>juneau.jar</l> contains serializers
and parsers for converting POJOs to and from
- a wide variety of content types:
+ The core packages of Juneau contains serializers and parsers
for converting POJOs to and from a wide variety of content types.
+ It uses a common API for defining serializers and parsers.
+ </p>
+ <p>
+ One of the goals of Juneau was to make serialization as simple
as possible.
+ In a single line of code, you should be able to serialize and
parse most POJOs.
+ Despite this simplicity, Juneau provides lots of extensibility
and configuration properties for tailoring how POJOs are serialized and parsed.
</p>
- <ul>
- <li>JSON
- <li>XML
- <li>HTML
- <li>URL-Encoding
- <li>UON
- <li>MessagePack
- <li>RDF-XML
- <li>RDF-XML-Abbrev
- <li>Turtle
- <li>N3
- <li>N-Triple
- <li>Plain text
- <li>Cognos XML
- </ul>
<!--
========================================================================================================
-->
- <a id="Core.PojoCategories"></a>
- <h3 class='topic' onclick='toggle(this)'>2.1 - POJO Categories</h3>
- <div class='topic'>
- <p>
- The Juneau serializers and parsers can handle a wide
variety of POJOs.
- </p>
- <p>
- The following chart shows POJOs categorized into groups
and whether they can be serialized or parsed:
- </p>
- <table class='styled' style='border-collapse: collapse;'>
-
<tr><th>Group</th><th>Description</th><th>Examples</th><th>Can<br>serialize?</th><th>Can<br>parse?</th></tr>
- <tr class='dark bb'
style='background-color:lightyellow;'>
- <td style='text-align:center'>1</td>
- <td><b>Java primitive objects</b></td>
- <td>
- <ul class='normal'>
- <li>{@code String}
- <li>{@code Integer}
- <li>{@code Float}
- <li>{@code Boolean}
- </ul>
- </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- </tr>
- <tr class='dark bb'
style='background-color:lightyellow'>
- <td style='text-align:center'>2</td>
- <td><b>Java Collections Framework objects and
Java arrays</b></td>
- <td> </td>
- <td> </td>
- <td> </td>
- </tr>
- <tr class='light bb'>
- <td style='text-align:center'>2a</td>
- <td>
- <b>With standard keys/values</b><br>
- Map keys are group [1, 4a, 5]
objects.<br>
- Map, Collection, and array values are
group [1, 2, 3a, 4a, 5] objects.
- </td>
- <td>
- <ul class='normal'>
- <li>{@code
HashSet<String,Integer>}
- <li>{@code
TreeMap<Integer,Bean>}
-
<li><code>List<<jk>int</jk>[][]></code>
- <li>{@code Bean[]}
- </ul>
- </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- </tr>
- <tr class='light bb'>
- <td style='text-align:center'>2b</td>
- <td>
- <b>With non-standard keys/values</b><br>
- Map keys are group [2, 3, 4b, 5, 6]
objects.<br>
- Map, Collection, and array values are
group [3b, 4, 5, 6] objects.
- </td>
- <td>
- <ul class='normal'>
- <li>{@code
HashSet<Bean,Integer>}
- <li>{@code
TreeMap<Integer,Reader>}
- </ul>
- </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:salmon;text-align:center'><b>no</b></td>
- </tr>
- <tr class='dark bb'
style='background-color:lightyellow'>
- <td style='text-align:center'>3</td>
- <td><b>Java Beans</b></td>
- <td> </td>
- <td> </td>
- <td> </td>
- </tr>
- <tr class='light bb'>
- <td style='text-align:center'>3a</td>
- <td>
- <b>With standard properties</b><br>
- These are beans that have no-arg
constructors and one or more properties defined by public getter and setter
methods or public fields.<br>
- Property values are group [1, 2, 3a,
4a, 5] objects.
- </td>
- <td> </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- </tr>
- <tr class='light bb'>
- <td style='text-align:center'>3b</td>
- <td>
- <b>With non-standard properties or not
true beans</b><br>
- These include true beans that have
no-arg constructors and one or more properties defined by getter and setter
methods or properties,
- but property types include
group [3b, 4b, 5, 6] objects.<br>
- This also includes classes that look
like beans but aren't true beans.
- For example, classes that have getters
but not setters, or classes without no-arg constructors.
- </td>
- <td> </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:salmon;text-align:center'><b>no</b></td>
- </tr>
- <tr class='dark bb'
style='background-color:lightyellow'>
- <td style='text-align:center'>4</td>
- <td>
- <b>Swapped objects</b><br>
- These are objects that are not directly
serializable, but have {@link org.apache.juneau.transform.PojoSwap PojoSwaps}
associated with them.
- The purpose of a POJO swap is to
convert an object to another object that is easier to serialize and parse.
- For example, the {@link
org.apache.juneau.transforms.DateSwap.ISO8601DT} class can be used to serialize
{@link java.util.Date} objects
- to ISO8601 strings, and parse
them back into {@link java.util.Date} objects.
- </td>
- <td> </td>
- <td> </td>
- <td> </td>
- </tr>
- <tr class='light bb'>
- <td style='text-align:center'>4a</td>
- <td>
- <b>2-way swapped to group [1, 2a, 3a]
objects</b><br>
- For example, a swap that converts a
{@code Date} to a {@code String}.
- </td>
- <td> </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- </tr>
- <tr class='light bb'>
- <td style='text-align:center'>4b</td>
- <td>
- <b>1-way swapped to group [1, 2, 3]
objects</b><br>
- For example, a swap that converts an
{@code Iterator} to a {@code List}.
- This would be one way, since you cannot
reconstruct an {@code Iterator}.
- </td>
- <td> </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:salmon;text-align:center'><b>no</b></td>
- </tr>
- <tr class='dark bb'
style='background-color:lightyellow'>
- <td style='text-align:center'>5</td>
- <td>
- <b>Objects with standardized
<code>static T valueOf(String)</code>/<code>static T fromString(String)</code>
methods, or constructors with a <code>String</code> argument.</b><br>
- During serialization, objects are
converted to strings using the <code>toString()</code> method.
- During parsing, strings are converted
to objects using one of these static methods or constructors.
- </td>
- <td><code>java.util.UUID</code></td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- </tr>
- <tr class='dark' style='background-color:lightyellow'>
- <td style='text-align:center'>6</td>
- <td>
- <b>All other objects</b><br>
- Anything that doesn't fall into one of
the groups above are simply converted to {@code Strings} using the {@code
toString()} method.
- </td>
- <td> </td>
- <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
- <td
style='background-color:salmon;text-align:center'><b>no</b></td>
- </tr>
- </table>
- <p>
- One other important note is that the serializers are
designed to work on tree-shaped POJO models.
- These are models where there are no referential loops
(e.g. leaves with references to nodes, or nodes in one branch referencing nodes
in another branch).
- There is a serializer setting {@code detectRecursions}
to look for and handle these kinds of loops (by setting these references to
<jk>null</jk>),
- but it is not enabled by default since it
introduces a moderate performance penalty.
- </p>
- </div>
-
- <!--
========================================================================================================
-->
<a id="Core.Serializers"></a>
- <h3 class='topic' onclick='toggle(this)'>2.2 - Serializers</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.1 - Serializers</h3>
<div class='topic'>
<p>
- The built-in serializers in Juneau are fast and
efficient, and are highly customizable, for example, allowing you to produce
strict or non-strict syntax,
- various whitespace options, and automatic
detection of recursions.
- </p>
- <p>
- The serializers work by serializing POJOs directly to
streams instead of using intermediate Document Object Model objects.
- This allows serialization with minimal memory use.
- </p>
- <p>
- Default serialization support is provided for Java
primitives, <l>Maps</l>, <l>Collections</l>, beans, and arrays. <br>
- Extensible support for other data types such as
<l>Calendars</l>, <l>Dates</l>, <l>Iterators</l> is available through the use
of POJO swaps.
+ The built-in serializers in Juneau are fast, efficient,
and highly configurable.
+ They work by serializing POJOs directly to streams
instead of using intermediate Document Object Model objects.
</p>
<p>
In most cases, you can serialize objects in one line of
code by using one of the default serializers:
</p>
<p class='bcode'>
- <jc>// A simple POJO class</jc>
+ <jc>// A simple bean</jc>
<jk>public class</jk> Person {
<jk>public</jk> String <jf>name</jf> = <js>"John Smith"</js>;
<jk>public int</jk> <jf>age</jf> = 21;
}
- <jc>// Serialize a bean to JSON, XML, or HTML</jc>
+ <jc>// Serialize to JSON, XML, or HTML</jc>
Person p = <jk>new</jk> Person();
<jc>// Produces:
@@ -546,6 +335,10 @@
<jc>// Serialize a POJO to JSON</jc>
String json = serializer.serialize(someObject);
</p>
+ <p>
+ Default serialization support is provided for Java
primitives, <code>Maps</code>, <code>Collections</code>, beans, and arrays.
<br>
+ Extensible support for other data types such as
<code>Calendars</code>, <code>Dates</code>, <code>Iterators</code> is available
through the use of POJO swaps (described later).
+ </p>
<h6 class='topic'>Additional Information</h6>
<ul class='javahierarchy'>
@@ -555,22 +348,24 @@
<!--
========================================================================================================
-->
<a id="Core.Parsers"></a>
- <h3 class='topic' onclick='toggle(this)'>2.3 - Parsers</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.2 - Parsers</h3>
<div class='topic'>
<p>
Parsers work by parsing input directly into POJOs
instead of having to create intermediate Document Object Models.
This allows them to parse input with minimal object
creation.
</p>
<p>
- The JSON parser can handle any valid JSON syntax (such
as quoted or unquoted attributes, single or double quotes).<br>
- It can also handle JSON fragements and embedded
Javascript comments.
+ Like the serializers, you can often parse objects in
one line of code by using one of the default parsers:
</p>
<p class='bcode'>
<jc>// Use one of the predefined parsers.</jc>
Parser parser = JsonParser.<jsf>DEFAULT</jsf>;
- <jc>// Parse a JSON object (creates a generic ObjectMap).</jc>
+ <jc>// Parse a JSON object as a bean.</jc>
String json = <js>"{name:'John Smith',age:21}"</js>;
+ Person p = parser.parse(json, Person.<jk>class</jk>);
+
+ <jc>// Or parse it into a generic Map.</jc>
Map m1 = parser.parse(json, Map.<jk>class</jk>);
<jc>// Parse a JSON string.</jc>
@@ -582,17 +377,13 @@
Long l3 = parser.parse(json, Long.<jk>class</jk>);
Float f3 = parser.parse(json, Float.<jk>class</jk>);
- <jc>// Parse a JSON object as a bean.</jc>
- json = <js>"{name:'John Smith',age:21}"</js>;
- Person p4 = parser.parse(json, Person.<jk>class</jk>);
-
<jc>// Parse a JSON object as a HashMap<String,Person>.</jc>
json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe
Smith',age:42}}"</js>;
- Map<String,Person> m5 = parser.parseMap(json,
HashMap.<jk>class</jk>, String.<jk>class</jk>, Person.<jk>class</jk>)
+ Map<String,Person> m4 = parser.parseMap(json,
HashMap.<jk>class</jk>, String.<jk>class</jk>, Person.<jk>class</jk>)
<jc>// Parse a JSON array of integers as a Collection of Integers or
int[] array.</jc>
json = <js>"[1,2,3]"</js>;
- List<Integer> l6 = parser.parseCollection(json,
LinkedList.<jk>class</jk>, Integer.<jk>class</jk>);
+ List<Integer> l5 = parser.parseCollection(json,
LinkedList.<jk>class</jk>, Integer.<jk>class</jk>);
<jk>int</jk>[] i6 = parser.parse(json, <jk>int</jk>[].<jk>class</jk>);
</p>
<p>
@@ -617,19 +408,13 @@
Map<String,Person> m3 = <jk>new</jk>
TreeMap<String,Person>();
parser.parseIntoMap(json, m3, String.<jk>class</jk>,
Person.<jk>class</jk>);
</p>
- <p>
- Juneau can parse both structured models (composed of
serialized beans) and unstructured models (composed of generic maps,
collections, primitives, and so on).
- Any valid JSON can be parsed into an unstructured model
consisting of generic {@link org.apache.juneau.ObjectMap} and {@link
org.apache.juneau.ObjectList} objects.
+ <p class='info'>
+ In the example above, we're parsing "lax" JSON (single
quotes, unquoted attributes).
+ The JSON parser can handle any valid JSON syntax (such
as quoted or unquoted attributes, single or double quotes).<br>
+ It can also handle JSON fragements and embedded
Javascript comments.
+ Many of the JSON examples provided will use lax syntax
which is easier to read since we don't have to deal with escapes.
</p>
- <p class='bcode'>
- <jc>// Parse an arbitrary JSON document into an unstructered data model
- // consisting of ObjectMaps, ObjectLists, and java primitive
objects.</jc>
- Parser parser = JsonParser.<jsf>DEFAULT</jsf>;
- String json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe
Smith',age:42}}"</js>;
- ObjectMap m = parser.parse(json, ObjectMap.<jk>class</jk>);
-
- <jc>// Use ObjectMap API to extract data from the unstructured
model.</jc>
- <jk>int</jk> johnSmithAge =
m.getObjectMap(<js>"a"</js>).getInt(<js>"age"</js>);
+ <p>
</p>
<h6 class='topic'>Additional Information</h6>
@@ -639,16 +424,54 @@
</div>
<!--
========================================================================================================
-->
+ <a id="Core.SerializerAndParserGroups"></a>
+ <h3 class='topic' onclick='toggle(this)'>2.3 - SerializerGroups and
ParserGroups</h3>
+ <div class='topic'>
+ <p>
+ Above the serializers and parsers are the {@link
org.apache.juneau.serializer.SerializerGroup} and {@link
org.apache.juneau.parser.ParserGroup} classes.
+ These classes allow serializers and parsers to be
retrieved by W3C-compliant HTTP <code>Accept</code> and
<code>Content-Type</code> values...
+ </p>
+ <p class='bcode'>
+ <jc>// Construct a new serializer group with configuration parameters
that get applied to all serializers.</jc>
+ SerializerGroup sg = <jk>new</jk> SerializerGroup()
+ .append(JsonSerializer.<jk>class</jk>,
UrlEncodingSerializer.<jk>class</jk>);
+
.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>,
<jk>true</jk>)
+ .addTransforms(CalendarSwap.ISO8601DT.<jk>class</jk>);
+
+ <jc>// Find the appropriate serializer by Accept type and serialize our
POJO to the specified writer.</jc>
+ sg.getSerializer(<js>"text/invalid, text/json;q=0.8, text/*;q:0.6,
*\/*;q=0.0"</js>)
+ .serialize(myPersonObject, myWriter);
+
+ <jc>// Construct a new parser group with configuration parameters that
get applied to all parsers.</jc>
+ ParserGroup pg = <jk>new</jk> ParserGroup()
+ .append(JsonSerializer.<jk>class</jk>,
UrlEncodingSerializer.<jk>class</jk>);
+ .addTransforms(CalendarSwap.ISO8601DT.<jk>class</jk>);
+
+ Person p = pg.getParser(<js>"text/json"</js>).parse(myReader,
Person.<jk>class</jk>);
+ </p>
+ <p>
+ The REST servlet API builds upon the
<code>SerializerGroup</code> and <code>ParserGroup</code> classes
+ to provide annotated REST servlets that automatically
negotiate the HTTP media types and allow the developer
+ to work with requests and responses as POJOs.
+ </p>
+ <h6 class='topic'>Additional Information</h6>
+ <ul class='javahierarchy'>
+ <li class='c'>{@link
org.apache.juneau.serializer.SerializerGroup}
+ <li class='c'>{@link
org.apache.juneau.parser.ParserGroup}
+ </ul>
+ </div>
+
+ <!--
========================================================================================================
-->
<a id="Core.ObjectMap"></a>
<h3 class='topic' onclick='toggle(this)'>2.4 - ObjectMap and
ObjectList</h3>
<div class='topic'>
<p>
The {@link org.apache.juneau.ObjectMap} and {@link
org.apache.juneau.ObjectList} classes are generic Java representations of JSON
objects and arrays.
These classes can be used to create "unstructured"
models for serialization (as opposed to "structured" models consisting of
beans).
- If you want to quickly generate JSON/XML/HTML from
generic maps/collections, or parse JSON/XML/HTML into generic maps/collections,
these objects work well.
+ If you want to quickly generate JSON/XML/HTML from
generic maps/collections, or parse JSON/XML/HTML into generic maps/collections,
these classes work well.
</p>
<p>
- These classes extend directly from JCF classes:
+ These classes extend directly from the following JCF
classes:
</p>
<ul class='javahierarchy'>
<li class='c'> {@link java.util.LinkedHashMap
java.util.LinkedHashMap}
@@ -661,7 +484,7 @@
</ul>
</ul>
<p>
- The <l>ObjectMap</l> and <l>ObjectList</l> are very
similar to the <l>JSONObject</l> and <l>JSONArray</l>
+ The <l>ObjectMap</l> and <l>ObjectList</l> classes are
very similar to the <l>JSONObject</l> and <l>JSONArray</l>
classes found in other libraries. However, the
names were chosen
because the concepts of <l>Maps</l> and
<l>Lists</l> are already familiar to
Java programmers, and these classes can be used
with any of the serialzers or parsers.
@@ -673,6 +496,25 @@
<li>Using the provided {@link
org.apache.juneau.ObjectMap#serializeTo(java.io.Writer)} or {@link
org.apache.juneau.ObjectList#serializeTo(java.io.Writer)} methods.
<li>Passing them to one of the {@link
org.apache.juneau.serializer.Serializer} serialize methods.
</ol>
+ <p>
+ Any valid JSON can be parsed into an unstructured model
consisting of generic {@link org.apache.juneau.ObjectMap} and {@link
org.apache.juneau.ObjectList} objects.
+ </p>
+ <p class='bcode'>
+ <jc>// Parse an arbitrary JSON document into an unstructered data model
+ // consisting of ObjectMaps, ObjectLists, and java primitive
objects.</jc>
+ Parser parser = JsonParser.<jsf>DEFAULT</jsf>;
+ String json = <js>"{a:{name:'John Smith',age:21},b:{name:'Joe
Smith',age:42}}"</js>;
+ ObjectMap m = parser.parse(json, ObjectMap.<jk>class</jk>);
+
+ <jc>// Use ObjectMap API to extract data from the unstructured
model.</jc>
+ <jk>int</jk> johnSmithAge =
m.getObjectMap(<js>"a"</js>).getInt(<js>"age"</js>);
+
+ <jc>// Convert it back into JSON.</jc>
+ json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(m);
+
+ <jc>// Or convert it to XML.</jc>
+ String xml = XmlSerializer.<jsf>DEFAULT</jsf>.serialize(m);
+ </p>
<p class='info'>
As a general rule, if you do not specify a target type
during parsing, or if the target type cannot be determined
through reflection, the parsers automatically
generate <l>ObjectMaps</l> and <l>ObjectLists</l>.
@@ -689,8 +531,8 @@
<h3 class='topic' onclick='toggle(this)'>2.5 - Configurable
Properties</h3>
<div class='topic'>
<p>
- Serializers and parsers have a wide variety of
configurable properties that can be set on them.<br>
- For example, the following code shows how to set
configurable properties on the JSON serializerclass:
+ Serializers and parsers have a wide variety of
configurable properties.<br>
+ For example, the following code shows how to configure
a JSON serializer:
</p>
<p class='bcode'>
JsonSerializer s = <jk>new</jk> JsonSerializer()
@@ -700,7 +542,7 @@
.setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>,
<js>'\''</js>);
</p>
<p>
- Each of the serializers and parsers contain common
reusable instances with common configuration properties.<br>
+ However, each of the serializers and parsers already
contain reusable instances with common configurations.<br>
For example, JSON has the following predefined reusable
serializers and parsers:
</p>
<ul class='javahierarchy'>
@@ -725,79 +567,75 @@
String json = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.serialize(myPojo);
</p>
<p>
- Properties can be set using the following methods:
- </p>
- <ul class='javahierarchy'>
- <li class='m'>{@link
org.apache.juneau.serializer.Serializer#setProperty(String,Object)} - On any
serializers.
- <li class='m'>{@link
org.apache.juneau.serializer.SerializerGroup#setProperty(String,Object)} - On
groups of serializers.
- <li class='m'>{@link
org.apache.juneau.parser.Parser#setProperty(String,Object)} - On any parsers.
- <li class='m'>{@link
org.apache.juneau.parser.ParserGroup#setProperty(String,Object)} - On groups of
parsers.
- </ul>
- <p>
- The REST server API also provides various ways of
setting properties:
- </p>
- <ul class='javahierarchy'>
- <li class='n'>{@link
org.apache.juneau.server.annotation.RestResource#properties()
@RestResource.properties()} - Annotation on instances of {@link
org.apache.juneau.server.RestServlet}.
- <li class='n'>{@link
org.apache.juneau.server.annotation.RestMethod#properties()
@RestMethod.properties()} - Annotation on java methods in instances of {@link
org.apache.juneau.server.RestServlet}.
- <li class='m'>{@link
org.apache.juneau.server.RestServlet#createSerializers(ObjectMap,Class[],Class[])}
- Properties can be set programmatically on serializers by overriding this
method.
- <li class='m'>{@link
org.apache.juneau.server.RestServlet#createParsers(ObjectMap,Class[],Class[])}
- Properties can be set programmatically on parsers by overriding this method.
- </ul>
- <p>
- Similarly, the REST client API provides ways of setting
properties:
+ Serializers and parsers can be locked to prevent
further modification to the properties.
+ They can also be cloned to copy the configuration of
other serializers and parsers.
</p>
- <ul class='javahierarchy'>
- <li class='m'>{@link
org.apache.juneau.client.RestClient#setProperty(String,Object)} - Set property
on the serializer and parser associated with a REST client.
- </ul>
- <p>
- The {@link
org.apache.juneau.serializer.Serializer#lock()} and {@link
org.apache.juneau.parser.Parser#lock()}
- methods can be used to make serializer and parser
properties read only.
- All the common reusable serializers and parsers are
read only.
- If you attempt to modify any properties on those
instances, a {@link org.apache.juneau.LockedException} is thrown.
+ <p class='bcode'>
+ <jc>// Clone and customize an existing serializer.</jc>
+ JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>
+ .clone()
+ .setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>,
<js>'"'</js>);
+
+ <jc>// Lock it so that the configuration cannot be changed.</jc>
+ s.lock();
</p>
<h6 class='topic'>Additional Information</h6>
+ <p>
+ The following is a list of all configurable properties
across all serializers and parsers.
+ </p>
<ul class='javahierarchy'>
- <li class='c'>{@link org.apache.juneau.BeanContext} -
Properties associated with handling beans on serializers and parsers.
- <li class='c'>{@link
org.apache.juneau.serializer.SerializerContext} - Configurable properties
common to all serializers.
- <li class='c'>{@link
org.apache.juneau.parser.ParserContext} - Configurable properties common to all
parsers.
- <li class='c'>{@link
org.apache.juneau.html.HtmlSerializerContext} - Configurable properties on the
HTML serializer.
- <li class='c'>{@link
org.apache.juneau.html.HtmlDocSerializerContext} - Configurable properties on
the HTML document serializer.
- <li class='c'>{@link
org.apache.juneau.html.HtmlParserContext} - Configurable properties on the HTML
parser.
- <li class='c'>{@link
org.apache.juneau.jena.RdfCommonContext} - Configurable properties common to
the RDF serializers and parsers.
- <li class='c'>{@link
org.apache.juneau.jena.RdfSerializerContext} - Configurable properties on the
RDF serializer.
- <li class='c'>{@link
org.apache.juneau.jena.RdfParserContext} - Configurable properties on the RDF
parsers.
- <li class='c'>{@link
org.apache.juneau.json.JsonSerializerContext} - Configurable properties on the
JSON serializer.
- <li class='c'>{@link
org.apache.juneau.json.JsonParserContext} - Configurable properties on the JSON
parser.
- <li class='c'>{@link
org.apache.juneau.soap.SoapXmlSerializerContext} - Configurable properties on
the SOAP/XML serializer.
- <li class='c'>{@link
org.apache.juneau.urlencoding.UonSerializerContext} - Configurable properties
on the URL-Encoding and UON serializers.
- <li class='c'>{@link
org.apache.juneau.urlencoding.UonParserContext} - Configurable properties on
the URL-Encoding and UON parsers.
- <li class='c'>{@link
org.apache.juneau.xml.XmlSerializerContext} - Configurable properties on the
XML serializer.
- <li class='c'>{@link
org.apache.juneau.xml.XmlParserContext} - Configurable properties on the XML
parser.
- <li class='c'>{@link
org.apache.juneau.server.RestServletContext} - Configurable properties on the
REST servlet.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/BeanContext.html#ConfigProperties'>BeanContext</a> -
Properties associated with handling beans on serializers and parsers.
+ <ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/serializer/SerializerContext.html#ConfigProperties'>SerializerContext</a>
- Configurable properties common to all serializers.
+ <ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/html/HtmlSerializerContext.html#ConfigProperties'>HtmlSerializerContext</a>
- Configurable properties on the HTML serializer.
+ <ul>
+ <li class='c'><a
class='doclink'
href='org/apache/juneau/html/HtmlDocSerializerContext.html#ConfigProperties'>HtmlDocSerializerContext</a>
- Configurable properties on the HTML document serializer.
+ </ul>
+ <li class='i'><a class='doclink'
href='org/apache/juneau/jena/RdfCommonContext.html#ConfigProperties'>RdfCommonContext</a>
- Configurable properties common to the RDF serializers and parsers.
+ <ul>
+ <li class='c'><a
class='doclink'
href='org/apache/juneau/jena/RdfSerializerContext.html#ConfigProperties'>RdfSerializerContext</a>
- Configurable properties on the RDF serializers.
+ </ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/json/JsonSerializerContext.html#ConfigProperties'>JsonSerializerContext</a>
- Configurable properties on the JSON serializer.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/msgpack/MsgPackSerializerContext.html#ConfigProperties'>MsgPackSerializerContext</a>
- Configurable properties on the MessagePack serializer.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/soap/SoapXmlSerializerContext.html#ConfigProperties'>SoapXmlSerializerContext</a>
- Configurable properties on the SOAP/XML serializer.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/urlencoding/UonSerializerContext.html#ConfigProperties'>UonSerializerContext</a>
- Configurable properties on the URL-Encoding and UON serializers.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/xml/XmlSerializerContext.html#ConfigProperties'>XmlSerializerContext</a>
- Configurable properties on the XML serializer.
+ </ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/parser/ParserContext.html#ConfigProperties'>ParserContext</a>
- Configurable properties common to all parsers.
+ <ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/html/HtmlParserContext.html#ConfigProperties'>HtmlParserContext</a>
- Configurable properties on the HTML parser.
+ <li class='i'><a class='doclink'
href='org/apache/juneau/jena/RdfCommonContext.html#ConfigProperties'>RdfCommonContext</a>
- Configurable properties common to the RDF serializers and parsers.
+ <ul>
+ <li class='c'><a
class='doclink'
href='org/apache/juneau/jena/RdfParserContext.html#ConfigProperties'>RdfParserContext</a>
- Configurable properties on the RDF parsers.
+ </ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/json/JsonParserContext.html#ConfigProperties'>JsonParserContext</a>
- Configurable properties on the JSON parser.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/msgpack/MsgPackParserContext.html#ConfigProperties'>MsgPackParserContext</a>
- Configurable properties on the MessagePack parser.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/urlencoding/UonParserContext.html#ConfigProperties'>UonParserContext</a>
- Configurable properties on the URL-Encoding and UON parsers.
+ <li class='c'><a class='doclink'
href='org/apache/juneau/xml/XmlParserContext.html#ConfigProperties'>XmlParserContext</a>
- Configurable properties on the XML parser.
+ </ul>
+ </ul>
+ <li class='c'><a class='doclink'
href='org/apache/juneau/server/RestServletContext.html#ConfigProperties'>RestServletContext</a>
- Configurable properties on the REST servlet.
</ul>
</div>
<!--
========================================================================================================
-->
- <a id="Core.Annotations"></a>
- <h3 class='topic' onclick='toggle(this)'>2.6 - Annotations</h3>
+ <a id="Core.Transforms"></a>
+ <h3 class='topic' onclick='toggle(this)'>2.6 - Transforms</h3>
<div class='topic'>
<p>
- The {@link org.apache.juneau.annotation} package
contains several annotations that can be applied to classes to alter how
they're
- handled by the serializers and parsers.
+ By default, the Juneau framework can serialize and
parse a wide variety of POJOs out-of-the-box.
+ However, two special classes are provided tailor how
certain Java objects are handled by the framework.
+ These classes are:
</p>
+ <ul class='javahierarchy'>
+ <li class='c'>{@link
org.apache.juneau.transform.PojoSwap} - Tailor how specific non-bean classes
are handled by the framework.
+ <li class='c'>{@link
org.apache.juneau.transform.BeanFilter} - Tailor how specific bean classes are
handled by the framework.
+ </ul>
<p>
- For example, the {@link
org.apache.juneau.annotation.Bean @Bean} annotation can be used to limit which
getters and setters get
- interpreted as bean properties:
+ Annotations are also provided that allow you to use
transformations directly on class definitions:
</p>
- <p class='bcode'>
- <jc>// Address class with only street/city/state properties (in that
order).</jc>
- <jc>// All other properties are ignored.</jc>
-
<ja>@Bean</ja>(properties={<js>"street"</js>,<js>"city"</js>,<js>"state"</js>})
- <jk>public class</jk> Address {
- ...
- </p>
-
- <h6 class='topic'>Additional Information</h6>
<ul class='javahierarchy'>
<li class='n'>{@link org.apache.juneau.annotation.Pojo
@Pojo} - Used to tailor how non-bean POJOs get interpreted by the framework.
<li class='n'>{@link org.apache.juneau.annotation.Bean
@Bean} - Used to tailor how beans get interpreted by the framework.
@@ -808,94 +646,489 @@
<li class='n'>{@link
org.apache.juneau.annotation.ParentProperty @ParentProperty} - Identifies a
setter as a method for adding a parent reference to a child object.
<li class='n'>{@link org.apache.juneau.annotation.URI
@URI} - Used to identify a class or bean property as a URI.
</ul>
- </div>
+
+ <!--
========================================================================================================
-->
+ <a id="Core.PojoSwaps"></a>
+ <h4 class='topic' onclick='toggle(this)'>2.6.1 - PojoSwaps</h4>
+ <div class='topic'>
+ <p>
+ {@link org.apache.juneau.transform.PojoSwap
PojoSwaps} are a critical component of Juneau.
+ They allow the serializers and parsers to
handle Java objects that wouldn't normally be serializable.
+ </p>
+ <p>
+ Swaps are very easy to understand.
+ Simply put, they can be thought of as 'object
swappers' that swap in serializable objects for non-serializable ones during
serialization, and vis-versa during parsing.
+ </p>
+ <p>
+ Some examples of non-serializable POJOs are
<code>File</code>, <code>Reader</code>, <code>Iterable</code>, etc...
+ These are classes that aren't beans and cannot
be represented as simple maps, collections, or primitives.
+ </p>
+ <p>
+ In the following example, we introduce a
<code>PojoSwap</code> that will swap in ISO8601 strings for <code>Date</code>
objects:
+ </p>
+ <p class='bcode'>
+ <jc>// Sample swap for converting Dates to ISO8601 strings.</jc>
+ <jk>public class</jk> MyDateSwap <jk>extends</jk>
PojoSwap<Date,String> {
+
+ <jc>// ISO8601 formatter.</jc>
+ <jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk>
SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>);
+
+ <jd>/** Converts a Date object to an ISO8601 string. */</jd>
+ <ja>@Override</ja>
+ <jk>public</jk> String swap(Date o) {
+ <jk>return</jk> <jf>format</jf>.format(o);
+ }
+
+ <jd>/** Converts an ISO8601 string to a Date object. */</jd>
+ <ja>@Override</ja>
+ <jk>public</jk> Date unswap(String o) <jk>throws</jk>
ParseException {
+ <jk>try</jk> {
+ <jk>return</jk> <jf>format</jf>.parse(o);
+ } <jk>catch</jk> (java.text.ParseException e) {
+ <jk>throw new</jk> ParseException(e);
+ }
+ }
+ }
+ </p>
+ <p>
+ The swap can then be associated with
serializers and parsers like so:
+ </p>
+ <p class='bcode'>
+ <jc>// Sample bean with a Date field.</jc>
+ <jk>public class</jk> MyBean {
+ <jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2,
3, 4, 5, 6);
+ }
+
+ <jc>// Create a new JSON serializer, associate our date swap with it,
and serialize a sample bean.</jc>
+ Serializer serializer = <jk>new</jk>
JsonSerializer().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+ String json = serializer.serialize(<jk>new</jk> MyBean()); <jc>//
== "{date:'2012-03-03T04:05:06-0500'}"</jc>
+
+ <jc>// Create a JSON parser, associate our date swap with it, and
reconstruct our bean (including the date).</jc>
+ ReaderParser parser = <jk>new</jk>
JsonParser().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+ MyBean bean = parser.parse(json, MyBean.<jk>class</jk>);
+ <jk>int</jk> day = bean.<jf>date</jf>.getDay();
<jc>// == 3</jc>
+ </p>
+ <p>
+ Several <code>PojoSwaps</code> are already
provided for common Java objects:
+ </p>
+ <ul class='javahierarchy'>
+ <li class='p'>{@link
org.apache.juneau.transforms}
+ <ul>
+ <li class='c'>{@link
org.apache.juneau.transforms.ByteArrayBase64Swap}
+ <li class='c'>{@link
org.apache.juneau.transforms.CalendarLongSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.CalendarMapSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.CalendarSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.DateLongSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.DateMapSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.DateSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.EnumerationSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.IteratorSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.ReaderSwap}
+ <li class='c'>{@link
org.apache.juneau.transforms.XMLGregorianCalendarSwap}
+ </ul>
+ </ul>
+ <p class='info'>
+ The 'swapped' class type must be a serializable
type.<br>
+ See the definition for Category 4 objects in <a
class='doclink' href='#Core.PojoCategories'>POJO Categories</a>.
+ </p>
+ </div>
+
+ <!--
========================================================================================================
-->
+ <a id="Core.BeanFilters"></a>
+ <h4 class='topic' onclick='toggle(this)'>2.6.2 - BeanFilters
and @Bean annotations</h4>
+ <div class='topic'>
+ <p>
+ {@link org.apache.juneau.transform.BeanFilter
BeanFilters} are used to control aspects of how beans are handled during
serialization and parsing.
+ They allow you to control various aspects of
beans, such as...
+ </p>
+ <ul>
+ <li>Which properties to include or exclude.
+ <li>Property order.
+ <li>Property naming conventions.
+ <li>Overriding reading and writing of
properties.
+ </ul>
+ <p>
+ In practice, however, it's simpler to use the
{@link org.apache.juneau.annotation.Bean @Bean} and {@link
org.apache.juneau.annotation.BeanProperty @BeanProperty}
+ annotations on your bean classes.
+ The annotations are functionally equivalent to
the bean filter class.
+ </p>
+ <p class='bcode'>
+ <jc>// Address class with only street/city/state properties (in that
order).</jc>
+ <jc>// All other properties are ignored.</jc>
+
<ja>@Bean</ja>(properties={<js>"street"</js>,<js>"city"</js>,<js>"state"</js>})
+ <jk>public class</jk> Address {
+ ...
+ </p>
+ <p>
+ Bean filters are defined through {@link
org.apache.juneau.transform.BeanFilterBuilder BeanFilterBuilders}.
+ The programmatic equivalent to the the
annotation above would be:
+ </p>
+ <p class='bcode'>
+ <jk>public class</jk> MyAddressBeanFilter <jk>extends</jk>
BeanFilterBuilder {
+
+ <jc>// Must provide a no-arg constructor!</jc>
+ <jk>public</jk> MyAddressBeanFilter() {
+ <jk>super</jk>(Address.<jk>class</jk>); <jc>// The
bean class that this filter applies to.</jc>
+ setIncludeProperties(<js>"street,city,state"</js>);
<jc>// The properties we want exposed.</jc>
+ }
+ }
+ </p>
+ <p>
+ Bean filters are added to serializers and
parsers using the <code>addBeanFilters(Class...)</code> method.
+ For example:
+ </p>
+ <p class='bcode'>
+ <jc>// Create a new JSON serializer and associate a bean filter with
it.</jc>
+ Serializer serializer = <jk>new</jk>
JsonSerializer().addBeanFilters(MyAddressBeanFilter.<jk>class</jk>);
+ </p>
+ <p>
+ Note that if you use the annotation, you do NOT
need to set anything on the serializers/parsers.
+ The annotations will be detected and bean
filters will automatically be created for them.
+ </p>
+ <p>
+ The <code>addBeanFilter(Class...)</code> method
also allows you to pass in interfaces.
+ Any class that's not a subclass of {@link
org.apache.juneau.transform.BeanFilterBuilder} get interpreted
+ as bean interface classes.
+ These cause bean implementations of those
interfaces to only expose the properties defined on the interface.
+ </p>
+ <p class='bcode'>
+ <jc>// An interface with the 3 properties we want serialized.</jc>
+ <jk>public interface</jk> AddressInterface {
+ <jk>public</jk> String getStreet();
+ <jk>public</jk> String getCity();
+ <jk>public</jk> String getState();
+ }
+
+ <jc>// Our bean implementation.</jc>
+ <jk>public class</jk> Address <jk>implements</jk> AddressInterface {
+ ...
+ }
+
+ <jc>// Create a new JSON serializer that only exposes street,city,state
on Address bean.</jc>
+ Serializer serializer = <jk>new</jk>
JsonSerializer().addBeanFilters(AddressInterface.<jk>class</jk>);
+ </p>
+ <h6 class='topic'>Additional Information</h6>
+ <ul class='javahierarchy'>
+ <li class='p'>{@link
org.apache.juneau.transform}
+ </ul>
+ </div>
+
+ </div>
+
<!--
========================================================================================================
-->
- <a id="Core.Transforms"></a>
- <h4 class='topic' onclick='toggle(this)'>2.7 - Transforms</h4>
+ <a id="Core.BeanDictionaries"></a>
+ <h3 class='topic' onclick='toggle(this)'>2.7 - Bean Names and
Dictionaries</h3>
<div class='topic'>
<p>
- The programmatic equivalent to the annotations are the
{@link org.apache.juneau.transform.BeanFilter} and
- {@link org.apache.juneau.transform.PojoSwap} classes.
+ While parsing into beans, Juneau attempts to determine
the class types of bean properties through reflection on the bean property
getter or setter.
+ Often this is insufficient if the property type is an
interface or abstract class that cannot be instantiated.
+ This is where bean names and dictionaries come into
play.
</p>
<p>
- The following example is equivalent to specifying the
<l>@Bean</l> annotation in the previous example using a bean filter:
+ Bean names and dictionary are used for identifying
class types when they cannot be inferred through reflection.
</p>
- <p class='bcode'>
- <jc>// Define bean filter that returns properties in the following
order: "street", "city", "state"</jc>
- <jk>public class</jk> AddressFilter <jk>extends</jk>
BeanFilter<Address> {
- <jk>public</jk> AddressFilter() {
-
setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>);
- }
- }
-
- WriterSerializer s = <jk>new</jk>
JsonSerializer().addBeanFilters(AddressFilter.<jk>class</jk>);
- Address a = getAddress();
- String json = s.serialize(a); <jc>// Prints
"{street:'...',city:'...',state;'...'}"</jc>
+ <p>
+ Bean classes are given names through the {@link
org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()} annotation.
+ These names are then added to the serialized output as
virtual <js>"_type"</js> properties (or element names in XML).
+ </p>
+ <p>
+ On the parsing side, these type names are resolved to
classes through the use of bean dictionaries.
</p>
<p>
- The {@link org.apache.juneau.transform.PojoSwap} class
is a critical component of Juneau that allows serializers and parsers to
- be able to handle virtually any Java object.
- Simply put, they can be thought of as 'transformers'
that convert non-serializable objects to serializable objects and vice versa.
+ For example, if a bean property is of type
<code>Object</code>, then the serializer will add <js>"_type"</js> attributes
so that the class can be determined during parsing.
</p>
+ <p class='bcode'>
+ <ja>@Bean</ja>(typeName=<js>"foo"</js>)
+ <jk>public class</jk> Foo {
+ <jc>// A bean property where the object types cannot be
inferred since it's an Object[].</jc>
+
<ja>@BeanProperty</ja>(typeDictionary={Bar.<jk>class</jk>,Baz.<jk>class</jk>})
+ <jk>public</jk> Object[] x = <jk>new</jk> Object[]{<jk>new</jk>
Bar(), <jk>new</jk> Baz()};
+ }
+
+ <ja>@Bean</ja>(typeName=<js>"bar"</js>)
+ <jk>public class</jk> Bar {}
+
+ <ja>@Bean</ja>(typeName=<js>"baz"</js>)
+ <jk>public class</jk> Baz {}
+ </p>
+ <p>
+ When serialized as JSON, <js>"_type"</js> attributes
would be added when needed to infer the type during parsing:
+ </p>
+ <p class='bcode'>
+ {
+ <jsa>x</jsa>: [
+ {<jsa>_type</jsa>:<jss>'bar'</jss>},
+ {<jsa>_type</jsa>:<jss>'baz'</jss>}
+ ]
+ }
+ </p>
+ <p>
+ Type names can be represented slightly differently in
different languages.
+ For example, the dictionary name is used as element
names when serialized to XML.
+ This allows the <code>typeName</code> annotation to be
used as a shortcut for defining element names for beans.
+ </p>
<p>
- For example, <l>Date</l> objects are not normally
serializable.
- (Technically, they look like beans with getters/setters
and so get serialized as such, which typically is not the desired result.)
- The following POJO swap can be used to represent dates
in ISO8601 format:
+ When serialized as XML, the bean is rendered as:
</p>
<p class='bcode'>
- <jc>// Sample swap for converting Dates to ISO8601 strings.</jc>
- <jk>public class</jk> MyDateSwap <jk>extends</jk>
PojoSwap<Date,String> {
-
- <jc>// ISO8601 formatter.</jc>
- <jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk>
SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>);
-
- <jd>/** Converts a Date object to an ISO8601 string. */</jd>
- <ja>@Override</ja>
- <jk>public</jk> String swap(Date o) {
- <jk>return</jk> <jf>format</jf>.format(o);
- }
-
- <jd>/** Converts an ISO8601 string to a Date object. */</jd>
- <ja>@Override</ja>
- <jk>public</jk> Date unswap(String o) <jk>throws</jk>
ParseException {
- <jk>try</jk> {
- <jk>return</jk> <jf>format</jf>.parse(o);
- } <jk>catch</jk> (java.text.ParseException e) {
- <jk>throw new</jk> ParseException(e);
- }
- }
- }
+ <xt><foo></xt>
+ <xt><x></xt>
+ <xt><bar/></xt>
+ <xt><baz/></xt>
+ <xt></x></xt>
+ <xt></foo></xt>
</p>
<p>
- The swap above can then be associated with serializers
and parsers as the following example shows:
+ Bean dictionaries are defined at two levels:
</p>
- <p class='bcode'>
- <jc>// Sample bean with a Date field.</jc>
- <jk>public class</jk> MyBean {
- <jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2,
3, 4, 5, 6);
+ <ul>
+ <li>On individual bean properties through the {@link
org.apache.juneau.annotation.BeanProperty#beanDictionary()
@BeanProperty.beanDictionary()} annotation.
+ <li>Globally for a parser using the {@link
org.apache.juneau.parser.Parser#addToDictionary(Class...)} method.
+ </ul>
+ <p class='info'>
+ Type names do not need to be universally unique.
+ However, they must be unique within a dictionary.
+ </p>
+ <p class='info'>
+ The following reserved words cannot be used as type
names: <code>object, array, number, boolean, null</code>.
+ </p>
+ <p class='info'>
+ Serialized type names are DISABLED by default.
+ They must be enabled on the serializer using the {@link
org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties}
configuration property.
+ </p>
+ <p class='info'>
+ The <js>"_type"</js> property name can be overridden
using the {@link org.apache.juneau.BeanContext#BEAN_beanTypePropertyName}
configuration property.
+ </p>
+
+ <!--
========================================================================================================
-->
+ <a id="Core.BeanSubTypes"></a>
+ <h4 class='topic' onclick='toggle(this)'>2.7.1 - Bean
Subtypes</h4>
+ <div class='topic'>
+ <p>
+ In addition to the bean type name support
described above, simplified support is provided
+ for bean subtypes.
+ </p>
+ <p>
+ Bean subtypes are similar in concept to bean
type names, except for the following differences:
+ </p>
+ <ul>
+ <li>You specify the list of possible subclasses
through an annotation on a parent bean class.
+ <li>You do not need to register the subtype
classes on the bean dictionary of the parser.
+ <li>The default helper attribute name is
<js>"_subtype"</js>, not <js>"_type"</js>.
+ <li>Bean subtype virtual properties are ALWAYS
serialized.
+ They are not controlled by the {@link
org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties}
setting.
+ </ul>
+ <p>
+ In the following example, the abstract class
has two subclasses:
+ </p>
+ <p class='bcode'>
+ <jc>// Abstract superclass</jc>
+ <ja>@Bean</ja>(
+ subTypes={A1.<jk>class</jk>, A2.<jk>class</jk>}
+ )
+ <jk>public abstract class</jk> A {
+ <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
}
-
- <jc>// Create a new JSON serializer, associate our date swap with it,
and serialize a sample bean.</jc>
- Serializer serializer = <jk>new</jk>
JsonSerializer().addPojoSwaps(MyDateSwap.<jk>class</jk>);
- String json = serializer.serialize(<jk>new</jk> MyBean()); <jc>//
== "{date:'2012-03-03T04:05:06-0500'}"</jc>
-
- <jc>// Create a JSON parser, associate our date swap with it, and
reconstruct our bean (including the date).</jc>
- ReaderParser parser = <jk>new</jk>
JsonParser().addPojoSwaps(MyDateSwap.<jk>class</jk>);
- MyBean bean = parser.parse(json, MyBean.<jk>class</jk>);
- <jk>int</jk> day = bean.<jf>date</jf>.getDay();
<jc>// == 3</jc>
+
+ <jc>// Subclass 1</jc>
+ <ja>@Bean</ja>(typeName=<js>"A1"</js>)
+ <jk>public class</jk> A1 <jk>extends</jk> A {
+ <jk>public</jk> String <jf>f1</jf>;
+ }
+
+ <jc>// Subclass 2</jc>
+ <ja>@Bean</ja>(typeName=<js>"A2"</js>)
+ <jk>public class</jk> A2 <jk>extends</jk> A {
+ <jk>public</jk> String <jf>f2</jf>;
+ }
+ </p>
+ <p>
+ When serialized, the subtype is serialized as a
virtual <js>"_subtype"</js> property:
+ </p>
+ <p class='bcode'>
+ JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>;
+ A1 a1 = <jk>new</jk> A1();
+ a1.<jf>f1</jf> = <js>"f1"</js>;
+ String r = s.serialize(a1);
+ <jsm>assertEquals</jsm>(<js>"{_subtype:'A1',f1:'f1',f0:'f0'}"</js>, r);
+ </p>
+ <p>
+ The following shows what happens when parsing
back into the original object.
+ </p>
+ <p class='bcode'>
+ JsonParser p = JsonParser.<jsf>DEFAULT</jsf>;
+ A a = p.parse(r, A.<jk>class</jk>);
+ <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1);
+ </p>
+ <p class='info'>
+ The <js>"_subtype"</js> property name can be
overridden using the {@link org.apache.juneau.annotation.Bean#subTypeProperty()
@Bean.subTypeProperty()} annotation.
+ </p>
+ </div>
+ </div>
+
+ <!--
========================================================================================================
-->
+ <a id="Core.PojoCategories"></a>
+ <h3 class='topic' onclick='toggle(this)'>2.8 - POJO Categories</h3>
+ <div class='topic'>
+ <p>
+ The following chart shows POJOs categorized into groups
and whether they can be serialized or parsed:
+ </p>
+ <table class='styled' style='border-collapse: collapse;'>
+
<tr><th>Group</th><th>Description</th><th>Examples</th><th>Can<br>serialize?</th><th>Can<br>parse?</th></tr>
+ <tr class='dark bb'
style='background-color:lightyellow;'>
+ <td style='text-align:center'>1</td>
+ <td><b>Java primitive objects</b></td>
+ <td>
+ <ul class='normal'>
+ <li>{@code String}
+ <li>{@code Integer}
+ <li>{@code Float}
+ <li>{@code Boolean}
+ </ul>
+ </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ </tr>
+ <tr class='dark bb'
style='background-color:lightyellow'>
+ <td style='text-align:center'>2</td>
+ <td><b>Java Collections Framework objects and
Java arrays</b></td>
+ <td> </td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr class='light bb'>
+ <td style='text-align:center'>2a</td>
+ <td>
+ <b>With standard keys/values</b><br>
+ Map keys are group [1, 4a, 5]
objects.<br>
+ Map, Collection, and array values are
group [1, 2, 3a, 4a, 5] objects.
+ </td>
+ <td>
+ <ul class='normal'>
+ <li>{@code
HashSet<String,Integer>}
+ <li>{@code
TreeMap<Integer,Bean>}
+
<li><code>List<<jk>int</jk>[][]></code>
+ <li>{@code Bean[]}
+ </ul>
+ </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ </tr>
+ <tr class='light bb'>
+ <td style='text-align:center'>2b</td>
+ <td>
+ <b>With non-standard keys/values</b><br>
+ Map keys are group [2, 3, 4b, 5, 6]
objects.<br>
+ Map, Collection, and array values are
group [3b, 4, 5, 6] objects.
+ </td>
+ <td>
+ <ul class='normal'>
+ <li>{@code
HashSet<Bean,Integer>}
+ <li>{@code
TreeMap<Integer,Reader>}
+ </ul>
+ </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:salmon;text-align:center'><b>no</b></td>
+ </tr>
+ <tr class='dark bb'
style='background-color:lightyellow'>
+ <td style='text-align:center'>3</td>
+ <td><b>Java Beans</b></td>
+ <td> </td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr class='light bb'>
+ <td style='text-align:center'>3a</td>
+ <td>
+ <b>With standard properties</b><br>
+ These are beans that have no-arg
constructors and one or more properties defined by public getter and setter
methods or public fields.<br>
+ Property values are group [1, 2, 3a,
4a, 5] objects.
+ </td>
+ <td> </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ </tr>
+ <tr class='light bb'>
+ <td style='text-align:center'>3b</td>
+ <td>
+ <b>With non-standard properties or not
true beans</b><br>
+ These include true beans that have
no-arg constructors and one or more properties defined by getter and setter
methods or properties,
+ but property types include
group [3b, 4b, 5, 6] objects.<br>
+ This also includes classes that look
like beans but aren't true beans.
+ For example, classes that have getters
but not setters, or classes without no-arg constructors.
+ </td>
+ <td> </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:salmon;text-align:center'><b>no</b></td>
+ </tr>
+ <tr class='dark bb'
style='background-color:lightyellow'>
+ <td style='text-align:center'>4</td>
+ <td>
+ <b>Swapped objects</b><br>
+ These are objects that are not directly
serializable, but have {@link org.apache.juneau.transform.PojoSwap PojoSwaps}
associated with them.
+ The purpose of a POJO swap is to
convert an object to another object that is easier to serialize and parse.
+ For example, the {@link
org.apache.juneau.transforms.DateSwap.ISO8601DT} class can be used to serialize
{@link java.util.Date} objects
+ to ISO8601 strings, and parse
them back into {@link java.util.Date} objects.
+ </td>
+ <td> </td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ <tr class='light bb'>
+ <td style='text-align:center'>4a</td>
+ <td>
+ <b>2-way swapped to group [1, 2a, 3a]
objects</b><br>
+ For example, a swap that converts a
{@code Date} to a {@code String}.
+ </td>
+ <td> </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ </tr>
+ <tr class='light bb'>
+ <td style='text-align:center'>4b</td>
+ <td>
+ <b>1-way swapped to group [1, 2, 3]
objects</b><br>
+ For example, a swap that converts an
{@code Iterator} to a {@code List}.
+ This would be one way, since you cannot
reconstruct an {@code Iterator}.
+ </td>
+ <td> </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:salmon;text-align:center'><b>no</b></td>
+ </tr>
+ <tr class='dark bb'
style='background-color:lightyellow'>
+ <td style='text-align:center'>5</td>
+ <td>
+ <b>Objects with standardized
<code>static T valueOf(String)</code>/<code>static T fromString(String)</code>
methods, or constructors with a <code>String</code> argument.</b><br>
+ During serialization, objects are
converted to strings using the <code>toString()</code> method.
+ During parsing, strings are converted
to objects using one of these static methods or constructors.
+ </td>
+ <td><code>java.util.UUID</code></td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ </tr>
+ <tr class='dark' style='background-color:lightyellow'>
+ <td style='text-align:center'>6</td>
+ <td>
+ <b>All other objects</b><br>
+ Anything that doesn't fall into one of
the groups above are simply converted to {@code Strings} using the {@code
toString()} method.
+ </td>
+ <td> </td>
+ <td
style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+ <td
style='background-color:salmon;text-align:center'><b>no</b></td>
+ </tr>
+ </table>
+ <p class='info'>
+ Serializers are designed to work on tree-shaped POJO
models.
+ These are models where there are no referential loops
(e.g. leaves with references to nodes, or nodes in one branch referencing nodes
in another branch).
+ There is a serializer setting {@code detectRecursions}
to look for and handle these kinds of loops (by setting these references to
<jk>null</jk>),
+ but it is not enabled by default since it
introduces a moderate performance penalty.
</p>
-
- <h6 class='topic'>Additional Information</h6>
- <ul class='javahierarchy'>
- <li class='p'><a class='doclink'
href='org/apache/juneau/transform/package-summary.html#TOC'>org.apache.juneau.transform</a>
- Transform API Javadocs.
- <li class='p'><a class='doclink'
href='org/apache/juneau/transforms/package-summary.html#TOC'>org.apache.juneau.transforms</a>
- Predefined reusable transform classes.
- </ul>
</div>
-
+
<!--
========================================================================================================
-->
<a id="Core.SVL"></a>
- <h4 class='topic' onclick='toggle(this)'>2.8 - Simple Variable
Language</h4>
+ <h4 class='topic' onclick='toggle(this)'>2.9 - Simple Variable
Language</h4>
<div class='topic'>
<p>
The {@link org.apache.juneau.svl} package defines an
API for a language called "Simple Variable Language".
@@ -919,7 +1152,10 @@
// 3) 'not found' string if system property not found.</jc>
String myproperty =
VarResolver.<jsf>DEFAULT</jsf>.resolve(<js>"$E{MYPROPERTY,$S{my.property,not
found}}"</js>);
</p>
-
+ <p>
+ SVL is a large topic on it's own.
+ It is used extensively in the ConfigFile, REST and
Microservice APIs.
+ </p>
<h6 class='topic'>Additional Information</h6>
<ul class='javahierarchy'>
<li class='p'><a class='doclink'
href='org/apache/juneau/svl/package-summary.html#TOC'>org.apache.juneau.svl</a>
- Simple Variable Language Javadocs.
@@ -928,7 +1164,7 @@
<!--
========================================================================================================
-->
<a id="Core.ConfigFile"></a>
- <h3 class='topic' onclick='toggle(this)'>2.9 - Configuration Files</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.10 - Configuration Files</h3>
<div class='topic'>
<p>
The {@link org.apache.juneau.ini} package contains a
powerful API for creating and using INI-style config files.
@@ -951,7 +1187,7 @@
<ck>key4</ck> = <cv>http://bar</cv>
</p>
<p>
- This class can be used to easily access contents of
this file, using the various capabilities of the {@link
org.apache.juneau.ObjectMap} class, as follows:
+ This class can be used to easily access contents of the
file:
</p>
<p class='bcode'>
<jk>int</jk> key1;
@@ -1097,7 +1333,7 @@
<!--
========================================================================================================
-->
<a id="Core.SupportedLanguages"></a>
- <h3 class='topic' onclick='toggle(this)'>2.10 - Supported Languages</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.11 - Supported Languages</h3>
<div class='topic'>
<p>
Extensive javadocs exist for individual language
support.
@@ -1109,6 +1345,7 @@
<li class='p'><a class='doclink'
href='org/apache/juneau/jena/package-summary.html#TOC'>org.apache.juneau.jena</a>
- RDF support.
<li class='p'><a class='doclink'
href='org/apache/juneau/jso/package-summary.html#TOC'>org.apache.juneau.jso</a>
- Java Serialized Object support.
<li class='p'><a class='doclink'
href='org/apache/juneau/json/package-summary.html#TOC'>org.apache.juneau.json</a>
- JSON support.
+ <li class='p'><a class='doclink'
href='org/apache/juneau/msgpack/package-summary.html#TOC'>org.apache.juneau.msgpack</a>
- MessagePack support.
<li class='p'><a class='doclink'
href='org/apache/juneau/plaintext/package-summary.html#TOC'>org.apache.juneau.plaintext</a>
- Plain-text support.
<li class='p'><a class='doclink'
href='org/apache/juneau/soap/package-summary.html#TOC'>org.apache.juneau.soap</a>
- SOAP support.
<li class='p'><a class='doclink'
href='org/apache/juneau/urlencoding/package-summary.html#TOC'>org.apache.juneau.urlencoding</a>
- URL-Encoding and UON support.
@@ -1121,7 +1358,7 @@
<!--
========================================================================================================
-->
<a id="Server"></a>
-<h2 class='topic' onclick='toggle(this)'>3 - Juneau Server
(juneau-server.jar)</h2>
+<h2 class='topic' onclick='toggle(this)'>3 - Juneau Server
(org.apache.juneau.server)</h2>
<div class='topic'>
<p>
The Juneau REST Server API provides a variety of servlet-based
REST resource classes that provides REST interfaces on top of existing POJOs,
@@ -1225,26 +1462,28 @@
<jk>import</jk> org.apache.juneau.xml.annotation.*;
<jd>/** Address book bean */</jd>
- <ja>@Xml</ja>(name=<js>"addressBook"</js>)
- <jk>public class</jk> AddressBook <jk>extends</jk>
!LinkedList<Person> {}
+ <ja>@Bean</ja>(typeName=<js>"addressBook"</js>)
+ <jk>public class</jk> AddressBook <jk>extends</jk>
LinkedList<Person> {}
<jd>/** Person bean */</jd>
- <ja>@Xml</ja>(prefix=<js>"per"</js>,name=<js>"person"</js>)
+ <ja>@Xml</ja>(prefix=<js>"per"</js>)
+ <ja>@Bean</ja>(typeName=<js>"person"</js>)
<jk>public class</jk> Person {
<jc>// Bean properties</jc>
- <ja>@BeanProperty</ja>(beanUri=<jk>true</jk>) <jk>public</jk>
URI <jf>uri</jf>;
+ <ja>@Rdf</ja>(beanUri=<jk>true</jk>) <jk>public</jk> URI
<jf>uri</jf>;
<jk>public</jk> URI <jf>addressBookUri</jf>;
<jk>public int</jk> <jf>id</jf>;
<jk>public</jk> String <jf>name</jf>;
-
<ja>@BeanProperty</ja>(pojoSwaps=CalendarSwap.Medium.<jk>class</jk>)
<jk>public</jk> Calendar <jf>birthDate</jf>;
+ <ja>@BeanProperty</ja>(swap=CalendarSwap.Medium.<jk>class</jk>)
<jk>public</jk> Calendar <jf>birthDate</jf>;
<jk>public</jk> LinkedList<Address> <jf>addresses</jf>;
}
<jd>/** Address bean */</jd>
- <ja>@Xml</ja>(prefix=<js>"addr"</js>,name=<js>"address"</js>)
+ <ja>@Xml</ja>(prefix=<js>"addr"</js>)
+ <ja>@Bean</ja>(typeName=<js>"address"</js>)
<jk>public class</jk> Address {
<jc>// Bean properties</jc>
- <ja>@BeanProperty</ja>(beanUri=<jk>true</jk>) <jk>public</jk>
URI <jf>uri</jf>;
+ <ja>@Rdf</ja>(beanUri=<jk>true</jk>) <jk>public</jk> URI
<jf>uri</jf>;
<jk>public</jk> URI <jf>personUri</jf>;
<jk>public int</jk> <jf>id</jf>;
<ja>@Xml</ja>(prefix=<js>"mail"</js>) <jk>public</jk> String
<jf>street</jf>, <jf>city</jf>, <jf>state</jf>;
@@ -1288,7 +1527,7 @@
<!--
========================================================================================================
-->
<a id="Client"></a>
-<h2 class='topic' onclick='toggle(this)'>4 - Juneau Client
(juneau-client.jar)</h2>
+<h2 class='topic' onclick='toggle(this)'>4 - Juneau Client
(org.apache.juneau.client)</h2>
<div class='topic'>
<p>
The REST client API provides the ability to access remote REST
interfaces and transparently convert the input and output to and from POJOs
using any
@@ -1331,7 +1570,7 @@
<!--
========================================================================================================
-->
<a id="Remoteable"></a>
-<h2 class='topic' onclick='toggle(this)'>5 - Remoteable Services</h2>
+<h2 class='topic' onclick='toggle(this)'>5 - Remoteable Services
(org.apache.juneau.server.remoteable)</h2>
<div class='topic'>
<p>
Juneau provides the capability of calling methods on POJOs on a
server through client-side proxy interfaces.
@@ -1396,7 +1635,7 @@
<!--
========================================================================================================
-->
<a id="Microservices"></a>
-<h2 class='topic' onclick='toggle(this)'>6 - Microservices</h2>
+<h2 class='topic' onclick='toggle(this)'>6 - Juneau Microservices
(org.apache.juneau.microservice)</h2>
<div class='topic'>
<p>
<b>WARNING - The microservice API is still in beta. It may be
replaced with an OSGi-based architecture.</b>
@@ -2505,18 +2744,19 @@
<h6 class='figure'>Person.java</h6>
<p class='bcode'>
<jd>/** Person bean */</jd>
- <ja>@Xml</ja>(ns=<js>"per"</js>,elementName=<js>"person"</js>)
+ <ja>@Xml</ja>(ns=<js>"per"</js>)
<ja>@Rdf</ja>(prefix=<js>"per"</js>)
+ <ja>@Bean</ja>(typeName=<js>"person"</js>)
<jk>public class</jk> Person {
<jk>private static int</jk> <jsf>nextPersonId</jsf> = 1;
<jc>// Bean properties.</jc>
- <ja>@BeanProperty</ja>(uri=<jk>true</jk>) public URI
<jf>uri</jf>;
+ <ja>@Rdf</ja>(beanUri=<jk>true</jk>) public URI <jf>uri</jf>;
<jk>public</jk> URI <jf>addressBookUri</jf>;
<jk>public</jk> String <jf>id</jf>;
<jk>public</jk> String <jf>name</jf>;
-
<ja>@BeanProperty</ja>(pojoSwap=CalendarSwap.Medium.<jk>class</jk>)
<jk>public</jk> Calendar <jf>birthDate</jf>;
+ <ja>@BeanProperty</ja>(swap=CalendarSwap.Medium.<jk>class</jk>)
<jk>public</jk> Calendar <jf>birthDate</jf>;
<jk>public</jk> LinkedList<Address> <jf>addresses</jf> =
new LinkedList<Address>();
<jd>/** Bean constructor - Needed for instantiating on server
side */</jd>
@@ -2556,11 +2796,10 @@
<ul class='spaced-list'>
<li>The <l>ns="per"</l> annotations override
the default <l>"ab"</l> namespace defined on the package.
It applies to this class and all
properties of this class.
- <li>The
<code><ja>@BeanProperty</ja>(uri=<jk>true</jk>)</code> annotation identifies
the <l>uri</l> property as the resource URI for this
- resource.
- This property has special meaning for
the XML and RDF serializizers. The XML serializer serializes this as a
<l>uri</l> attribute instead of an <l><uri></l> element, and
- the RDF serializer uses this
property for the value of the <l>rdf:resource</l> attribute.
- <li>The
<code><ja>@BeanProperty</ja>(pojoSwap=CalendarSwap.Medium.<jk>class</jk>)</code>
annotation causes the date field to
+ <li>The
<code><ja>@Rdf</ja>(beanUri=<jk>true</jk>)</code> annotation identifies the
<l>uri</l> property as the resource URI for this resource.
+ This property has special meaning for
the RDF serializer.
+ The RDF serializer uses this property
for the value of the <l>rdf:resource</l> attribute.
+ <li>The
<code><ja>@BeanProperty</ja>(swap=CalendarSwap.Medium.<jk>class</jk>)</code>
annotation causes the date field to
be serialized in the format
<l>"MM dd, yyyy"</l>.
This could have also been specified
globally on the resource level through the {@link
org.apache.juneau.server.annotation.RestResource#properties} annotation.
</ul>
@@ -2572,14 +2811,15 @@
<jd>/**
* Address bean
*/</jd>
- <ja>@Xml</ja>(prefix=<js>"addr"</js>,name=<js>"address"</js>)
+ <ja>@Xml</ja>(prefix=<js>"addr"</js>)
<ja>@Rdf</ja>(prefix=<js>"addr"</js>)
+ <ja>@Bean</ja>(typeName=<js>"address"</js>)
<jk>public class</jk> Address {
<jk>private static int</jk> <jsf>nextAddressId</jsf> = 1;
<jc>// Bean properties</jc>
- <ja>@BeanProperty</ja>(beanUri=<jk>true</jk>) <jk>public</jk>
URI <jf>uri</jf>;
+ <ja>@Rdf</ja>(beanUri=<jk>true</jk>) <jk>public</jk> URI
<jf>uri</jf>;
<jk>public</jk> URI <jf>personUri</jf>;
<jk>public int</jk> <jf>id</jf>;
<ja>@Xml</ja>(prefix=<js>"mail"</js>)
<ja>@Rdf</ja>(prefix=<js>"mail"</js>) <jk>public</jk> String <jf>street</jf>,
<jf>city</jf>, <jf>state</jf>;
@@ -2613,13 +2853,14 @@
<h6 class='figure'>CreatePerson.java</h6>
<p class='bcode'>
<jd>/** Bean for creating a new person */</jd>
- <ja>@Xml</ja>(ns=<js>"per"</js>,elementName=<js>"person"</js>)
+ <ja>@Xml</ja>(ns=<js>"per"</js>)
<ja>@Rdf</ja>(ns=<js>"addr"</js>)
+ <ja>@Bean</ja>(typeName=<js>"person"</js>)
<jk>public class</jk> CreatePerson {
<jc>// Bean properties</jc>
<jk>public</jk> String <jf>name</jf>;
-
<ja>@BeanProperty(</ja>pojoSwap=CalendarSwap.Medium.<jk>class</jk>)
<jk>public</jk> Calendar <jf>birthDate</jf>;
+ <ja>@BeanProperty(</ja>swap=CalendarSwap.Medium.<jk>class</jk>)
<jk>public</jk> Calendar <jf>birthDate</jf>;
<jk>public</jk> LinkedList<CreateAddress>
<jf>addresses</jf>;
<jd>/** Bean constructor - Needed for instantiating on server
side */</jd>
@@ -2635,8 +2876,9 @@
<h6 class='figure'>CreateAddress.java</h6>
<p class='bcode'>
<jd>/** Bean for creating a new address */</jd>
- <ja>@Xml</ja>(ns=<js>"addr"</js>,elementName=<js>"address"</js>)
+ <ja>@Xml</ja>(ns=<js>"addr"</js>)
<ja>@Rdf</ja>(ns=<js>"addr"</js>)
+ <ja>@Bean</ja>(typeName=<js>"address"</js>)
<jk>public class</jk> CreateAddress {
<jc>// Bean properties</jc>
@@ -4721,6 +4963,26 @@
<li>Support for stream-based variables
- {@link org.apache.juneau.svl.StreamedVar}.
<li>Added support for context and
session objects.
</ul>
+ <li>Eliminated <js>"_class"</js> properties and
replaced them with <js>"_type"</js> properties.
+ The class properties were a little-used feature
where we would serialize fully-qualified class names when the class type could
not be inferred through reflection.
+ It's been replaced with bean type names and
bean dictionaries.
+ Instead of class names, we serialize
<js>"_type"</js> properties whose name is the type name defined on the bean
being serialized.
+ The parsers use a 'dictionary' of bean classes
to resolve those names to actual bean classes.
+ The following features were added to enable
this support:
+ <ul>
+ <li>{@link
org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()} - Annotation
that defines an identifying name for a bean class.
+ <li>{@link
org.apache.juneau.transform.BeanFilterBuilder#setTypeName(String)} -
Programmatic equivalent to annotation above.
+ <li>{@link
org.apache.juneau.BeanContext#BEAN_beanDictionary} - List of bean classes that
make up the bean dictionary for lookup
+ during parsing.
+ <li>{@link
org.apache.juneau.BeanContext#BEAN_beanTypePropertyName} - The overridable type
property name. Default is <js>"_type"</js>.
+ <li>{@link
org.apache.juneau.annotation.BeanProperty#beanDictionary()
@BeanProperty.beanDictionary()} - Define a type dictionary
+ for a particular bean property
value. This overrides the value specified using {@link
org.apache.juneau.BeanContext#BEAN_beanDictionary}.
+ <li>{@link
org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties}
- Controls whether type properties are serialized.
+ </ul>
+ In addition, the {@link
org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()} value replaces
the <code>@Xml.name()</code> annotation, and the
+ <js>"type"</js> and <js>"_class"</js>
attributes in the XML and HTML serializers have been standardized on a single
<js>"_type"</js> attribute.
+ <li>Refactor bean filter support to use {@link
org.apache.juneau.transform.BeanFilterBuilder} class.
+ Allows the <code>BeanFilter</code> class to use
final fields.
<li>{@link org.apache.juneau.msgpack MessagePack}
support.
<li>Serializers can now serialize directly to {@link
java.io.File Files}.
See {@link
org.apache.juneau.serializer.Serializer#serialize(Object,Object)}
@@ -4743,12 +5005,6 @@
</ul>
</li>
<li>New {@link org.apache.juneau.annotation.Bean#sort()
@Bean.sort()} annotation.
- <li>New methods on {@link
org.apache.juneau.transform.BeanFilter}:
- <ul>
- <li>{@link
org.apache.juneau.transform.BeanFilter#isSortProperties()}
- <li>{@link
org.apache.juneau.transform.BeanFilter#setSortProperties(boolean)}
- </ul>
- </li>
<li>Added <ja>@Bean.properties</ja> annotations on
various DTO beans to make the ordering consistent
between IBM and Oracle JVMs.<br>
IBM JVMs maintain the order of methods in a
class, whereas Oracle JVMs do not.
@@ -6340,7 +6596,7 @@
New {@link
org.apache.juneau.annotation.Bean#stopClass @Bean.stopClass} annotation for
specifying stop classes for bean properties.
</li>
<li>
- New {@link
org.apache.juneau.transform.BeanFilter#setStopClass(Class)} which is the
program equivalent to the annotation above.
+ New
<del><code>BeanFilter.setStopClass(Class)</code></del> which is the program
equivalent to the annotation above.
</li>
<li>
New methods on {@link
org.apache.juneau.dto.ResultSetList}:
@@ -7321,7 +7577,7 @@
Used for customizing bean
property names.
</li>
<li>
- New {@link
org.apache.juneau.annotation.BeanProperty#beanUri() @BeanProperty.beanUri} and
<code>@BeanProperty.id</code> annotations.<br>
+ New
<del><code>@BeanProperty.beanUri</code></del> and
<del><code>@BeanProperty.id</code></del> annotations.<br>
Used for associating beans with
URLs and IDs.<br>
Used by XML serializer to add a
url attribute on a bean element.<br>
Used by RDF/XML serializer to
construct <code>rdf:resource</code> attributes.
@@ -7659,5 +7915,4 @@
</div>
</div>
-
-</body>
\ No newline at end of file
+</body>