Repository: incubator-juneau
Updated Branches:
  refs/heads/master b89cb9823 -> ab8f0faaa


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ab8f0faa/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/package.html
----------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/package.html
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/package.html
new file mode 100644
index 0000000..3c3e845
--- /dev/null
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/yaml/proto/package.html
@@ -0,0 +1,1005 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * 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.
+ *
+ 
***************************************************************************************************************************/
+ -->
+<html>
+<head>
+       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+       <style type="text/css">
+               /* For viewing in Page Designer */
+               @IMPORT url("../../../../../../javadoc.css");
+
+               /* For viewing in REST interface */
+               @IMPORT url("../htdocs/javadoc.css");
+               body { 
+                       margin: 20px; 
+               }       
+       </style>
+       <script>
+               /* Replace all @code and @link tags. */ 
+               window.onload = function() {
+                       document.body.innerHTML = 
document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+                       document.body.innerHTML = 
document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, 
'<code>$3</code>');
+               }
+       </script>
+</head>
+<body>
+<p>JSON serialization and parsing support</p>
+<script>
+       function toggle(x) {
+               var div = x.nextSibling;
+               while (div != null && div.nodeType != 1)
+                       div = div.nextSibling;
+               if (div != null) {
+                       var d = div.style.display;
+                       if (d == 'block' || d == '') {
+                               div.style.display = 'none';
+                               x.className += " closed";
+                       } else {
+                               div.style.display = 'block';
+                               x.className = 
x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+                       }
+               }
+       }
+</script>
+
+<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
+<ol class='toc'>
+       <li><p><a class='doclink' href='#Overview'>JSON support 
overview</a></p> 
+       <ol>
+               <li><p><a class='doclink' 
href='#OverviewExample'>Example</a></p>
+       </ol>
+       <li><p><a class='doclink' href='#JsonSerializer'>JsonSerializer 
class</a></p> 
+       <ol>
+               <li><p><a class='doclink' href='#BeanAnnotations'>@Bean and 
@BeanProperty annotations</a></p>
+               <li><p><a class='doclink' 
href='#Collections'>Collections</a></p>
+               <li><p><a class='doclink' href='#JsonSchemaSupport'>JSON-Schema 
support</a></p>
+               <li><p><a class='doclink' href='#Recursion'> Non-tree models 
and recursion detection</a></p>
+               <li><p><a class='doclink' 
href='#SerializerConfigurableProperties'>Configurable properties</a></p>
+               <li><p><a class='doclink' href='#SerializerOtherNotes'>Other 
notes</a></p>
+       </ol>
+       <li><p><a class='doclink' href='#JsonParser'>JsonParser class</a></p> 
+       <ol>
+               <li><p><a class='doclink' href='#GenericParsing'>Parsing into 
generic POJO models</a></p>
+               <li><p><a class='doclink' 
href='#ParserConfigurableProperties'>Configurable properties</a></p>
+               <li><p><a class='doclink' href='#ParserOtherNotes'>Other 
notes</a></p>
+       </ol>
+</ol>
+
+<!-- 
========================================================================================================
 -->
+<a id="Overview"></a>
+<h2 class='topic' onclick='toggle(this)'>1 -JSON support overview</h2>
+<div class='topic'>
+       <p>
+               Juneau supports converting arbitrary POJOs to and from JSON 
using ultra-efficient serializers and parsers.
+               <br>The JSON serializer converts POJOs directly to JSON without 
the need for intermediate DOM objects using a 
+               highly-efficient state machine.
+               <br>Likewise, the JSON parser creates POJOs directly from JSON 
without the need for intermediate DOM objects. 
+       </p>
+       <p>
+               Juneau can serialize and parse instances of any of the 
following POJO types:
+       </p>
+       <ul class='spaced-list'>
+               <li>
+                       Java primitives and primitive objects (e.g. 
<code>String</code>, <code>Integer</code>, <code>Boolean</code>, 
+                       <code>Float</code>).
+               <li>
+                       Java Collections Framework objects (e.g. 
<code>HashSet</code>, <code>TreeMap</code>) containing anything on 
+                       this list.
+               <li>
+                       Multi-dimensional arrays of any type on this list.
+               <li>
+                       Java Beans with properties of any type on this list.
+               <li>
+                       Classes with standard transformations to and from 
<code>Strings</code> (e.g. classes containing 
+                       <code>toString()</code>, <code>fromString()</code>, 
<code>valueOf()</code>, <code>constructor(String)</code>).
+               <li>
+                       Non-serializable classes and properties with associated 
<code>PojoSwaps</code> that convert them to 
+                       serializable forms.
+       </ul>
+       <p>
+               Refer to <a 
href='../../../../overview-summary.html#juneau-marshall.PojoCategories' 
class='doclink'>POJO Categories</a> 
+               for a complete definition of supported POJOs.
+       </p>
+       
+       <h6 class='topic'>Prerequisites</h6>
+       <p>
+               The Juneau JSON serialization and parsing support does not 
require any external prerequisites.  
+               It only requires Java 1.6 or above.
+       </p>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="OverviewExample"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.1 - JSON support overview - 
example</h3>
+       <div class='topic'>
+               <p>
+                       The example shown here is from the Address Book 
resource located in the 
+                       <code>org.apache.juneau.sample.war</code> application.
+                       <br>The POJO model consists of a <code>List</code> of 
<code>Person</code> beans, with each <code>Person</code> 
+                       containing zero or more <code>Address</code> beans.
+               </p>
+               <p>
+                       When you point a browser at 
<code>/sample/addressBook</code>, the POJO is rendered as HTML:
+               </p>
+               <img class='bordered' src="doc-files/Example_HTML.png">
+               <p>
+                       By appending 
<code>?Accept=<i>mediaType</i>&amp;plainText=true</code> to the URL, you can 
view the data in 
+                       the various supported JSON formats:
+               </p>
+               
+               <h6 class='figure'>Normal JSON</h6>
+               <img class='bordered' src="doc-files/Example_JSON.png">
+               
+               <h6 class='figure'>Simple JSON</h6>
+               <img class='bordered' src="doc-files/Example_JSONSimple.png">
+
+               <p>
+                       In addition to serializing POJOs to JSON, Juneau 
includes support for serializing POJO metamodels to 
+                       JSON Schema.
+               </p>
+               
+               <h6 class='figure'>JSON Schema</h6>
+               <img class='bordered' src="doc-files/Example_JSONSchema.png">
+               
+               <p>
+                       The JSON data type produced depends on the Java object 
type being serialized.
+               </p>
+               <ul class='spaced-list'>
+                       <li>
+                               Primitives and primitive objects are converted 
to JSON primitives.
+                       <li>
+                               Beans and Maps are converted to JSON objects.
+                       <li>
+                               Collections and arrays are converted to JSON 
arrays.
+                       <li>
+                               Anything else is converted to JSON strings.
+               </ul>
+                       
+               <h6 class='topic'>Examples:</h6>
+               <table class='styled'>
+                       <tr>
+                               <th>POJO type</th>
+                               <th>Example</th>
+                               <th>Serialized form</th>
+                       </tr>
+                       <tr>
+                               <td>String</td>
+                               
<td><code>serializer.serialize(<js>"foobar"</js>);</code></td>
+                               <td><code><js>'foobar'</js></code>
+                       </tr>
+                       <tr>
+                               <td>Number</td>
+                               <td><code>serializer.serialize(123);</code></td>
+                               <td><code><jk>123</jk></code>
+                       </tr>
+                       <tr>
+                               <td>Boolean</td>
+                               
<td><code>serializer.serialize(<jk>true</jk>);</code></td>
+                               <td><code><jk>true</jk></code>
+                       </tr>
+                       <tr>
+                               <td>Null</td>
+                               
<td><code>serializer.serialize(<jk>null</jk>);</code></td>
+                               <td><code><jk>null</jk></code>
+                       </tr>
+                       <tr>
+                               <td>Beans with properties of any type on this 
list</td>
+                               <td><code>serializer.serialize(<jk>new</jk> 
MyBean());</code></td>
+                               
<td><code>{p1:<js>'val1'</js>,p2:<jk>true</jk>}</code>
+                       </tr>
+                       <tr>
+                               <td>Maps with values of any type on this 
list</td>
+                               <td><code>serializer.serialize(<jk>new</jk> 
TreeMap());</code></td>
+                               
<td><code>{key1:<js>'val1'</js>,key2:<jk>true</jk>}</code>
+                       </tr>
+                       <tr>
+                               <td>Collections and arrays of any type on this 
list</td>
+                               <td><code>serializer.serialize(<jk>new</jk> 
Object[]{1,<js>"foo"</js>,<jk>true</jk>});</code></td>
+                               <td><code>[1,'foo',true]</code>
+                       </tr>
+               </table>
+               <p>
+                       In addition, swaps can be used to convert 
non-serializable POJOs into serializable forms, such as converting 
+                       <code>Calendar</code> object to ISO8601 strings, or 
<code><jk>byte</jk>[]</code> arrays to Base-64 
+                       encoded strings.
+                       <br>These swaps can be associated at various levels:
+               </p>
+               <ul class='spaced-list'>
+                       <li>
+                               On serializer and parser instances to handle 
all objects of the class type globally.
+                       <li>
+                               On classes through the 
<code><ja>@Bean</ja></code> annotation.
+                       <li>
+                               On bean properties through the 
<code><ja>@BeanProperty</ja></code> annotations.
+               </ul>
+               <p>
+                       For more information about transforms, refer to <a 
class='doclink' 
+                       
href='../transform/package-summary.html#TOC'>org.apache.juneau.transform</a>.
+               </p>
+       </div>
+</div>
+
+<!-- 
========================================================================================================
 -->
+<a id="JsonSerializer"></a>
+<h2 class='topic' onclick='toggle(this)'>2 - JsonSerializer class</h2>
+<div class='topic'>
+       <p>
+               {@link org.apache.juneau.json.JsonSerializer} is the class used 
to convert POJOs to JSON.
+               <br>{@link org.apache.juneau.json.JsonSchemaSerializer} is the 
class used to generate JSON-Schema from POJOs.
+       </p>    
+       <p>
+               The JSON serializer includes several configurable settings.
+               <br>Static reusable instances of Json serializers are provided 
with commonly-used settings:
+       </p>
+       <ul class='spaced-list'>
+               <li>
+                       {@link org.apache.juneau.json.JsonSerializer#DEFAULT} - 
All default settings
+               <li>
+                       {@link 
org.apache.juneau.json.JsonSerializer#DEFAULT_LAX} - Single quotes, only quote 
attributes when 
+                       necessary.
+               <li>
+                       {@link 
org.apache.juneau.json.JsonSerializer#DEFAULT_LAX_READABLE} - Readable output.
+       </ul>
+       
+       <h6 class='topic'>Notes about examples</h6>
+       <p>
+               The examples shown in this document will use single-quote, 
readable settings.
+               <br>For brevity, the examples will use public fields instead of 
getters/setters to reduce the size of the examples.
+               <br>In the real world, you'll typically want to use standard 
bean getters and setters.
+       </p>
+       <p>
+               To start off simple, we'll begin with the following simplified 
bean and build upon it.
+       </p>
+       <p class='bcode'>
+       <jk>public class</jk> Person {
+               <jc>// Bean properties</jc>
+               <jk>public int</jk> <jf>id</jf>;
+               <jk>public</jk> String <jf>name</jf>;
+
+               <jc>// Bean constructor (needed by parser)</jc>
+               <jk>public</jk> Person() {}
+
+               <jc>// Normal constructor</jc>
+               <jk>public</jk> Person(<jk>int</jk> id, String name) {
+                       <jk>this</jk>.<jf>id</jf> = id;
+                       <jk>this</jk>.<jf>name</jf> = name;
+               }
+       }
+       </p>
+       <p>
+               The following code shows how to convert this to simple JSON:
+       </p>
+       <p class='bcode'>
+       <jc>// Use serializer with readable output, simple mode.</jc>
+       JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>;
+
+       <jc>// Create our bean.</jc>
+       Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>);
+
+       <jc>// Serialize the bean to JSON.</jc>
+       String json = s.serialize(p);
+       </p>
+       <p>
+               We could have also created a new serializer with the same 
settings using the following code:
+       </p>
+       <p class='bcode'>
+       JsonSerializer s = <jk>new</jk> 
JsonSerializerBuilder().simple().ws().sq().build();
+       </p>
+       
+       <p>
+               The code above produces the following output:
+       </p>
+       <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>
+       }
+       </p>
+       
+
+       <!-- 
========================================================================================================
 -->
+       <a id="BeanAnnotations"></a>
+       <h3 class='topic' onclick='toggle(this)'>2.1 - @Bean and @BeanProperty 
annotations</h3>
+       <div class='topic'>
+               <p>
+                       The {@link org.apache.juneau.annotation.Bean @Bean} and 
+                       {@link org.apache.juneau.annotation.BeanProperty 
@BeanProperty} annotations are used to customize the 
+                       behavior of beans across the entire framework.
+                       <br>They have various uses:
+               </p>
+               <ul class='spaced-list'>
+                       <li>
+                               Hiding bean properties.
+                       <li>
+                               Specifying the ordering of bean properties.
+                       <li>
+                               Overriding the names of bean properties.
+                       <li>
+                               Associating swaps at both the class and 
property level (to convert non-serializable POJOs to 
+                               serializable forms).
+               </ul>
+               <p>
+                       For example, we now add a <code>birthDate</code> 
property, and associate a swap with it to transform it to 
+                       an ISO8601 date-time string in GMT time.
+                       <br>We'll also add a couple of <code>URI</code> 
properties.
+                       <br>By default, <code>Calendars</code> are treated as 
beans by the framework, which is usually not how you 
+                       want them serialized.
+                       <br>Using swaps, we can convert them to standardized 
string forms.
+               </p>
+               <p class='bcode'>       
+       <jk>public class</jk> Person {
+               <jc>// Bean properties</jc>
+               <jk>public int</jk> <jf>id</jf>;
+               <jk>public</jk> String <jf>name</jf>;
+               <jk>public</jk> URI <jf>uri</jf>;
+               <jk>public</jk> URI <jf>addressBookUri</jf>;
+
+               
<ja>@BeanProperty</ja>(swap=CalendarSwap.ISO8601DTZ.<jk>class</jk>) 
<jk>public</jk> Calendar <jf>birthDate</jf>;
+
+
+               <jc>// Bean constructor (needed by parser)</jc>
+               <jk>public</jk> Person() {}
+
+               <jc>// Normal constructor</jc>
+               <jk>public</jk> Person(<jk>int</jk> id, String name, String 
uri, String addressBookUri, String birthDate) <jk>throws</jk> Exception {
+                       <jk>this</jk>.<jf>id</jf> = id;
+                       <jk>this</jk>.<jf>name</jf> = name;
+                       <jk>this</jk>.<jf>uri</jf> = <jk>new</jk> URI(uri);
+                       <jk>this</jk>.<jf>addressBookUri</jf> = <jk>new</jk> 
URI(addressBookUri);
+                       <jk>this</jk>.<jf>birthDate</jf> = <jk>new</jk> 
GregorianCalendar();
+                       
<jk>this</jk>.<jf>birthDate</jf>.setTime(DateFormat.<jsm>getDateInstance</jsm>(DateFormat.<jsf>MEDIUM</jsf>).parse(birthDate));
+               }
+       }
+               </p>
+               <p>
+                       Next, we alter our code to pass in the birthdate:
+               </p>
+               <p class='bcode'>
+       <jc>// Create our bean.</jc>
+       Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, 
<js>"http://sample/addressBook/person/1";</js>, 
+               <js>"http://sample/addressBook";</js>, <js>"Aug 12, 1946"</js>);
+               </p>
+               <p>
+                       Now when we rerun the sample code, we'll get the 
following:
+               </p>
+               <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               addressBookUri: <js>'http://sample/addressBook'</js>, 
+               birthDate: <js>'1946-08-12T00:00:00Z'</js>
+       }
+               </p>
+               <p>
+                       Another useful feature is the {@link 
org.apache.juneau.annotation.Bean#propertyNamer()} annotation that 
+                       allows you to plug in your own logic for determining 
bean property names.
+                       <br>The {@link org.apache.juneau.PropertyNamerDLC} is 
an example of an alternate property namer.
+                       It converts bean property names to lowercase-dashed 
format.
+               </p>
+               
+               <h6 class='topic'>Example:</h6>
+               <p class='bcode'>       
+       <ja>@Bean</ja>(propertyNamer=PropertyNamerDLC.<jk>class</jk>)
+       <jk>public class</jk> Person {
+               ...
+               </p>
+               
+               <h6 class='figure'>Results</h6>
+               <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               <js>'address-book-uri'</js>: 
<js>'http://sample/addressBook'</js>, 
+               <js>'birth-date'</js>: <js>'1946-08-12T00:00:00Z'</js>
+       }
+               </p>
+       </div>
+       
+               
+       <!-- 
========================================================================================================
 -->
+       <a id="Collections"></a>
+       <h3 class='topic' onclick='toggle(this)'>2.2 - Collections</h3>
+       <div class='topic'>
+               <p>
+                       In our example, let's add a list-of-beans property to 
our sample class:
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> Person {
+               
+               <jc>// Bean properties</jc>
+               <jk>public</jk> LinkedList&lt;Address&gt; <jf>addresses</jf> = 
<jk>new</jk> LinkedList&lt;Address&gt;();
+               ...
+       }
+               </p>
+               <p>
+                       The <code>Address</code> class has the following 
properties defined:
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> Address {
+
+               <jc>// Bean properties</jc>
+               <jk>public</jk> URI <jf>uri</jf>;
+               <jk>public</jk> URI <jf>personUri</jf>;
+               <jk>public int</jk> <jf>id</jf>;
+               <jk>public</jk> String <jf>street</jf>, <jf>city</jf>, 
<jf>state</jf>;
+               <jk>public int</jk> <jf>zip</jf>;
+               <jk>public boolean</jk> <jf>isCurrent</jf>;
+       }
+               </p>
+               <p>
+                       Next, add some quick-and-dirty code to add an address 
to our person bean:
+               </p>
+               <p class='bcode'>
+       <jc>// Use serializer with readable output, simple mode.</jc>
+       JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>;
+
+       <jc>// Create our bean.</jc>
+       Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, 
<js>"http://sample/addressBook/person/1";</js>, 
+               <js>"http://sample/addressBook";</js>, <js>"Aug 12, 1946"</js>);
+       Address a = <jk>new</jk> Address();
+       a.<jf>uri</jf> = <jk>new</jk> 
URI(<js>"http://sample/addressBook/address/1";</js>);
+       a.<jf>personUri</jf> = <jk>new</jk> 
URI(<js>"http://sample/addressBook/person/1";</js>);
+       a.<jf>id</jf> = 1;
+       a.<jf>street</jf> = <js>"100 Main Street"</js>;
+       a.<jf>city</jf> = <js>"Anywhereville"</js>;
+       a.<jf>state</jf> = <js>"NY"</js>;
+       a.<jf>zip</jf> = 12345;
+       a.<jf>isCurrent</jf> = <jk>true</jk>;
+       p.<jf>addresses</jf>.add(a);    
+               </p>
+               <p>
+                       Now when we run the sample code, we get the following:
+               </p>
+               <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               addressBookUri: <js>'http://sample/addressBook'</js>, 
+               birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+               addresses: [
+                       {
+                               uri: 
<js>'http://sample/addressBook/address/1'</js>, 
+                               personUri: 
<js>'http://sample/addressBook/person/1'</js>, 
+                               id: <jk>1</jk>, 
+                               street: <js>'100 Main Street'</js>, 
+                               city: <js>'Anywhereville'</js>, 
+                               state: <js>'NY'</js>, 
+                               zip: <jk>12345</jk>, 
+                               isCurrent: <jk>true</jk>
+                       }
+               ]
+       }
+               </p>
+       </div>
+       
+
+       <!-- 
========================================================================================================
 -->
+       <a id="JsonSchemaSupport"></a>
+       <h3 class='topic' onclick='toggle(this)'>2.3 - JSON-Schema support</h3>
+       <div class='topic'>
+               <p>
+                       Juneau provides the {@link 
org.apache.juneau.json.JsonSchemaSerializer} class for generating JSON-Schema 
+                       documents that describe the output generated by the 
{@link org.apache.juneau.json.JsonSerializer} class.
+                       <br>This class shares the same properties as 
<code>JsonSerializer</code>.
+                       <br>For convenience the {@link 
org.apache.juneau.json.JsonSerializer#getSchemaSerializer()} method has been 
+                       added for creating instances of schema serializers from 
the regular serializer instance.
+               </p>
+               <p>
+                       <i>Note:</i> As of this writing, JSON-Schema has not 
been standardized, so the output generated by the 
+                       schema serializer may be subject to future 
modifications.
+               </p>
+               <p>
+                       Lets start with the classes from the previous examples:
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> Person {
+               <jc>// Bean properties</jc>
+               <jk>public int</jk> <jf>id</jf>;
+               <jk>public</jk> String <jf>name</jf>;
+               <jk>public</jk> URI <jf>uri</jf>;
+               <jk>public</jk> URI <jf>addressBookUri</jf>;
+               
<ja>@BeanProperty</ja>(swap=CalendarSwap.ISO8601DTZ.<jk>class</jk>) 
<jk>public</jk> Calendar <jf>birthDate</jf>;
+               <jk>public</jk> LinkedList&lt;Address&gt; <jf>addresses</jf> = 
<jk>new</jk> LinkedList&lt;Address&gt;();
+
+               <jc>// Bean constructor (needed by parser)</jc>
+               <jk>public</jk> Person() {}
+
+               <jc>// Normal constructor</jc>
+               <jk>public</jk> Person(<jk>int</jk> id, String name, String 
uri, String addressBookUri, String birthDate) <jk>throws</jk> Exception {
+                       <jk>this</jk>.<jf>id</jf> = id;
+                       <jk>this</jk>.<jf>name</jf> = name;
+                       <jk>this</jk>.<jf>uri</jf> = <jk>new</jk> URI(uri);
+                       <jk>this</jk>.<jf>addressBookUri</jf> = <jk>new</jk> 
URI(addressBookUri);
+                       <jk>this</jk>.<jf>birthDate</jf> = <jk>new</jk> 
GregorianCalendar();
+                       
<jk>this</jk>.<jf>birthDate</jf>.setTime(DateFormat.getDateInstance(DateFormat.<jsf>MEDIUM</jsf>).parse(birthDate));
+               }
+       }
+
+       <jk>public class</jk> Address {
+               <jc>// Bean properties</jc>
+               <jk>public</jk> URI <jf>uri</jf>;
+               <jk>public</jk> URI <jf>personUri</jf>;
+               <jk>public int</jk> <jf>id</jf>;
+               <jk>public</jk> String <jf>street</jf>, <jf>city</jf>, 
<jf>state</jf>;
+               <jk>public int</jk> <jf>zip</jf>;
+               <jk>public boolean</jk> <jf>isCurrent</jf>;
+       }
+               </p>
+               <p>
+                       The code for creating our POJO model and generating 
JSON-Schema is shown below:
+               </p>
+               <p class='bcode'>
+       <jc>// Get the schema serializer for one of the default JSON 
serializers.</jc>
+       JsonSchemaSerializer s = 
JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.getSchemaSerializer();
+
+       <jc>// Create our bean.</jc>
+       Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, 
<js>"http://sample/addressBook/person/1";</js>, 
+               <js>"http://sample/addressBook";</js>, <js>"Aug 12, 1946"</js>);
+       Address a = <jk>new</jk> Address();
+       a.<jf>uri</jf> = <jk>new</jk> 
URI(<js>"http://sample/addressBook/address/1";</js>);
+       a.<jf>personUri</jf> = <jk>new</jk> 
URI(<js>"http://sample/addressBook/person/1";</js>);
+       a.<jf>id</jf> = 1;
+       a.<jf>street</jf> = <js>"100 Main Street"</js>;
+       a.<jf>city</jf> = <js>"Anywhereville"</js>;
+       a.<jf>state</jf> = <js>"NY"</js>;
+       a.<jf>zip</jf> = 12345;
+       a.<jf>isCurrent</jf> = <jk>true</jk>;
+       p.<jf>addresses</jf>.add(a);
+
+       <jc>// Get the JSON Schema corresponding to the JSON generated 
above.</jc>
+       String jsonSchema = s.serialize(p);
+               </p>
+               
+               <h6 class='figure'>Results</h6>
+               <p class='bcode'>
+       {
+               type: <js>'object'</js>, 
+               description: <js>'org.apache.juneau.sample.Person'</js>, 
+               properties: {
+                       id: {
+                               type: <js>'number'</js>, 
+                               description: <js>'int'</js>
+                       }, 
+                       name: {
+                               type: <js>'string'</js>, 
+                               description: <js>'java.lang.String'</js>
+                       }, 
+                       uri: {
+                               type: <js>'any'</js>, 
+                               description: <js>'java.net.URI'</js>
+                       }, 
+                       addressBookUri: {
+                               type: <js>'any'</js>, 
+                               description: <js>'java.net.URI'</js>
+                       }, 
+                       birthDate: {
+                               type: <js>'any'</js>, 
+                               description: <js>'java.util.Calendar'</js>
+                       }, 
+                       addresses: {
+                               type: <js>'array'</js>, 
+                               description: 
<js>'java.util.LinkedList&lt;org.apache.juneau.sample.Address&gt;'</js>, 
+                               items: {
+                                       type: <js>'object'</js>, 
+                                       description: 
<js>'org.apache.juneau.sample.Address'</js>, 
+                                       properties: {
+                                               uri: {
+                                                       type: <js>'any'</js>, 
+                                                       description: 
<js>'java.net.URI'</js>
+                                               }, 
+                                               personUri: {
+                                                       type: <js>'any'</js>, 
+                                                       description: 
<js>'java.net.URI'</js>
+                                               }, 
+                                               id: {
+                                                       type: 
<js>'number'</js>, 
+                                                       description: 
<js>'int'</js>
+                                               }, 
+                                               street: {
+                                                       type: 
<js>'string'</js>, 
+                                                       description: 
<js>'java.lang.String'</js>
+                                               }, 
+                                               city: {
+                                                       type: 
<js>'string'</js>, 
+                                                       description: 
<js>'java.lang.String'</js>
+                                               }, 
+                                               state: {
+                                                       type: 
<js>'string'</js>, 
+                                                       description: 
<js>'java.lang.String'</js>
+                                               }, 
+                                               zip: {
+                                                       type: 
<js>'number'</js>, 
+                                                       description: 
<js>'int'</js>
+                                               }, 
+                                               isCurrent: {
+                                                       type: 
<js>'boolean'</js>, 
+                                                       description: 
<js>'boolean'</js>
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+               </p>
+       </div>
+
+
+       <!-- 
========================================================================================================
 -->
+       <a id="Recursion"></a>
+       <h3 class='topic' onclick='toggle(this)'>2.4 - Non-tree models and 
recursion detection</h3>
+       <div class='topic'>
+               <p>
+                       The JSON serializer is designed to be used against POJO 
tree structures. 
+                       <br>It expects that there not be loops in the POJO 
model (e.g. children with references to parents, etc...).
+                       <br>If you try to serialize models with loops, you will 
usually cause a <code>StackOverflowError</code> to 
+                       be thrown (if {@link 
org.apache.juneau.serializer.SerializerContext#SERIALIZER_maxDepth} is not 
reached 
+                       first).
+               </p>
+               <p>
+                       If you still want to use the JSON serializer on such 
models, Juneau provides the 
+                       {@link 
org.apache.juneau.serializer.SerializerContext#SERIALIZER_detectRecursions} 
setting.
+                       <br>It tells the serializer to look for instances of an 
object in the current branch of the tree and skip 
+                       serialization when a duplicate is encountered.
+               </p>
+               <p>
+                       For example, let's make a POJO model out of the 
following classes:
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> A {
+               <jk>public</jk> B b;
+       }
+       
+       <jk>public class</jk> B {
+               <jk>public</jk> C c;
+       }
+       
+       <jk>public class</jk> C {
+               <jk>public</jk> A a;
+       }
+               </p>
+               <p>
+                       Now we create a model with a loop and serialize the 
results.
+               </p>
+               <p class='bcode'>
+       <jc>// Clone an existing serializer and set property for detecting 
recursions.</jc>
+       JsonSerializer s = 
JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.builder().detectRecursions(<jk>true</jk>).build();
+
+       <jc>// Create a recursive loop.</jc>
+       A a = <jk>new</jk> A();
+       a.<jf>b</jf> = <jk>new</jk> B();
+       a.<jf>b</jf>.<jf>c</jf> = <jk>new</jk> C();
+       a.<jf>b</jf>.<jf>c</jf>.<jf>a</jf> = a;
+       
+       <jc>// Serialize to JSON.</jc>
+       String json = s.serialize(a);
+               </p>
+               <p>
+                       What we end up with is the following, which does not 
serialize the contents of the <code>c</code> field:
+               </p>
+               <p class='bcode'>
+       {
+               b: {
+                       c: {
+                       }
+               }
+       }
+               </p>
+               <p>
+                       Without recursion detection enabled, this would cause a 
stack-overflow error.
+               </p>
+               <p>
+                       Recursion detection introduces a performance penalty of 
around 20%.
+                       <br>For this reason the setting is disabled by default.
+               </p>
+       </div>
+
+
+       <!-- 
========================================================================================================
 -->
+       <a id="SerializerConfigurableProperties"></a>
+       <h3 class='topic' onclick='toggle(this)'>2.5 - Configurable 
properties</h3>
+       <div class='topic'>
+               <p>
+                       See the following classes for all configurable 
properties that can be used on this serializer:
+               </p>
+               <ul class='spaced-list'>
+                       <li>
+                               {@link org.apache.juneau.BeanContext} - Bean 
context properties.
+                       <li>
+                               {@link 
org.apache.juneau.json.JsonSerializerContext} - Serializer context properties.
+               </ul>
+       </div>          
+
+
+       <!-- 
========================================================================================================
 -->
+       <a id="SerializerOtherNotes"></a>
+       <h3 class='topic' onclick='toggle(this)'>2.6 - Other notes</h3>
+       <div class='topic'>
+               <ul class='spaced-list'>
+                       <li>
+                               Like all other Juneau serializers, the JSON 
serializer is thread safe and maintains an internal cache 
+                               of bean classes encountered.
+                               <br>For performance reasons, it's recommended 
that serializers be reused whenever possible instead of 
+                               always creating new instances.
+               </ul>
+       </div>
+</div>
+
+
+<!-- 
========================================================================================================
 -->
+<a id="JsonParser"></a>
+<h2 class='topic' onclick='toggle(this)'>3 - JsonParser class</h2>
+<div class='topic'>
+       <p>
+               The {@link org.apache.juneau.json.JsonParser} class is the 
class used to parse JSON back into POJOs.
+       </p>    
+       <p>
+               The JSON parser supports ALL valid JSON, including:
+       </p>
+       <ul class='spaced-list'>
+               <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>   
+       <p>
+               A static reusable instance of <code>JsonParser</code> is also 
provided for convenience:
+       </p>
+       <ul>
+               <li>{@link org.apache.juneau.json.JsonParser#DEFAULT}
+       </ul>
+       <p>
+               Let's build upon the previous example and parse the generated 
JSON back into the original bean.
+               <br>We start with the JSON that was generated.
+       </p>
+       <p class='bcode'>
+       <jc>// Use serializer with readable output, simple mode.</jc>
+       JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>;
+
+       <jc>// Create our bean.</jc>
+       Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, 
<js>"http://sample/addressBook/person/1";</js>, 
+               <js>"http://sample/addressBook";</js>, <js>"Aug 12, 1946"</js>);
+       Address a = <jk>new</jk> Address();
+       a.<jf>uri</jf> = <jk>new</jk> 
URI(<js>"http://sample/addressBook/address/1";</js>);
+       a.<jf>personUri</jf> = <jk>new</jk> 
URI(<js>"http://sample/addressBook/person/1";</js>);
+       a.<jf>id</jf> = 1;
+       a.<jf>street</jf> = <js>"100 Main Street"</js>;
+       a.<jf>city</jf> = <js>"Anywhereville"</js>;
+       a.<jf>state</jf> = <js>"NY"</js>;
+       a.<jf>zip</jf> = 12345;
+       a.<jf>isCurrent</jf> = <jk>true</jk>;
+       p.<jf>addresses</jf>.add(a);    
+
+       <jc>// Serialize the bean to JSON.</jc>
+       String json = s.serialize(p);
+       </p>
+       <p>
+               This code produced the following:
+       </p>
+       <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               addressBookUri: <js>'http://sample/addressBook'</js>, 
+               birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+               addresses: [
+                       {
+                               uri: 
<js>'http://sample/addressBook/address/1'</js>, 
+                               personUri: 
<js>'http://sample/addressBook/person/1'</js>, 
+                               id: <jk>1</jk>, 
+                               street: <js>'100 Main Street'</js>, 
+                               city: <js>'Anywhereville'</js>, 
+                               state: <js>'NY'</js>, 
+                               zip: <jk>12345</jk>, 
+                               isCurrent: <jk>true</jk>
+                       }
+               ]
+       }
+       </p>
+       <p>
+               The code to convert this back into a bean is:
+       </p>
+       <p class='bcode'>
+       <jc>// Parse it back into a bean using the reusable JSON parser.</jc>
+       Person p = JsonParser.<jsf>DEFAULT</jsf>.parse(json, 
Person.<jk>class</jk>);
+
+       <jc>// Render it back as JSON.</jc>
+       json = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(p);
+       </p>
+       <p>
+               We print it back out to JSON to show that all the data has been 
preserved:
+       </p>
+       <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               addressBookUri: <js>'http://sample/addressBook'</js>, 
+               birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+               addresses: [
+                       {
+                               uri: 
<js>'http://sample/addressBook/address/1'</js>, 
+                               personUri: 
<js>'http://sample/addressBook/person/1'</js>, 
+                               id: <jk>1</jk>, 
+                               street: <js>'100 Main Street'</js>, 
+                               city: <js>'Anywhereville'</js>, 
+                               state: <js>'NY'</js>, 
+                               zip: <jk>12345</jk>, 
+                               isCurrent: <jk>true</jk>
+                       }
+               ]
+       }       
+       </p>
+       
+
+       <!-- 
========================================================================================================
 -->
+       <a id="GenericParsing"></a>
+       <h3 class='topic' onclick='toggle(this)'>3.1 - Parsing into generic 
POJO models</h3>
+       <div class='topic'>
+               <p>
+                       The JSON parser is not limited to parsing back into the 
original bean classes.
+                       <br>If the bean classes are not available on the 
parsing side, the parser can also be used to 
+                       parse into a generic model consisting of 
<code>Maps</code>, <code>Collections</code>, and primitive
+                       objects.
+               </p>
+               <p>
+                       You can parse into any <code>Map</code> type (e.g. 
<code>HashMap</code>, <code>TreeMap</code>), but
+                       using {@link org.apache.juneau.ObjectMap} is 
recommended since it has many convenience methods
+                       for converting values to various types.
+                       <br>The same is true when parsing collections.  You can 
use any Collection (e.g. <code>HashSet</code>, 
+                       <code>LinkedList</code>) or array (e.g. 
<code>Object[]</code>, <code>String[]</code>, 
+                       <code>String[][]</code>), but using {@link 
org.apache.juneau.ObjectList} is recommended.
+               </p>
+               <p>
+                       When the map or list type is not specified, or is the 
abstract <code>Map</code>, <code>Collection</code>, 
+                       or <code>List</code> types, the parser will use 
<code>ObjectMap</code> and <code>ObjectList</code> by 
+                       default.
+               </p>
+               <p>
+                       Starting back with our original JSON:
+               </p>
+               <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               addressBookUri: <js>'http://sample/addressBook'</js>, 
+               birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+               addresses: [
+                       {
+                               uri: 
<js>'http://sample/addressBook/address/1'</js>, 
+                               personUri: 
<js>'http://sample/addressBook/person/1'</js>, 
+                               id: <jk>1</jk>, 
+                               street: <js>'100 Main Street'</js>, 
+                               city: <js>'Anywhereville'</js>, 
+                               state: <js>'NY'</js>, 
+                               zip: <jk>12345</jk>, 
+                               isCurrent: <jk>true</jk>
+                       }
+               ]
+       }
+               </p>
+               <p>
+                       We can parse this into a generic <code>ObjectMap</code>:
+               </p>
+               <p class='bcode'>       
+       <jc>// Parse JSON into a generic POJO model.</jc>
+       ObjectMap m = JsonParser.<jsf>DEFAULT</jsf>.parse(json, 
ObjectMap.<jk>class</jk>);
+
+       <jc>// Convert it back to JSON.</jc>
+       String json = 
JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(m);
+               </p>
+               <p>
+                       What we end up with is the exact same output.
+                       <br>Even the numbers and booleans are preserved because 
they are parsed into <code>Number</code> and 
+                       <code>Boolean</code> objects when parsing into generic 
models.
+               </p>
+               <p class='bcode'>
+       {
+               id: <jk>1</jk>, 
+               name: <js>'John Smith'</js>, 
+               uri: <js>'http://sample/addressBook/person/1'</js>, 
+               addressBookUri: <js>'http://sample/addressBook'</js>, 
+               birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+               addresses: [
+                       {
+                               uri: 
<js>'http://sample/addressBook/address/1'</js>, 
+                               personUri: 
<js>'http://sample/addressBook/person/1'</js>, 
+                               id: <jk>1</jk>, 
+                               street: <js>'100 Main Street'</js>, 
+                               city: <js>'Anywhereville'</js>, 
+                               state: <js>'NY'</js>, 
+                               zip: <jk>12345</jk>, 
+                               isCurrent: <jk>true</jk>
+                       }
+               ]
+       }
+               </p>
+               <p>
+                       Once parsed into a generic model, various convenience 
methods are provided on the <code>ObjectMap</code>
+                               and <code>ObjectList</code> classes to retrieve 
values:
+               </p>
+               <p class='bcode'>
+       <jc>// Parse JSON into a generic POJO model.</jc>
+       ObjectMap m = JsonParser.<jsf>DEFAULT</jsf>.parse(json, 
ObjectMap.<jk>class</jk>);
+
+       <jc>// Get some simple values.</jc>
+       String name = m.getString(<js>"name"</js>);
+       <jk>int</jk> id = m.getInt(<js>"id"</js>);
+
+       <jc>// Get a value convertable from a String.</jc>
+       URI uri = m.get(URI.<jk>class</jk>, <js>"uri"</js>);
+
+       <jc>// Get a value using a swap.</jc>
+       CalendarSwap swap = <jk>new</jk> CalendarSwap.ISO8601DTZ();
+       Calendar birthDate = m.get(swap, <js>"birthDate"</js>);
+
+       <jc>// Get the addresses.</jc>
+       ObjectList addresses = m.getObjectList(<js>"addresses"</js>);
+
+       <jc>// Get the first address and convert it to a bean.</jc>
+       Address address = addresses.get(Address.<jk>class</jk>, 0);
+               </p>
+
+               <p>
+                       As a general rule, parsing into beans is often more 
efficient than parsing into generic models.
+                       <br>And working with beans is often less error prone 
than working with generic models.
+               </p>            
+       </div>
+
+
+       <!-- 
========================================================================================================
 -->
+       <a id="ParserConfigurableProperties"></a>
+       <h3 class='topic' onclick='toggle(this)'>3.2 - Configurable 
properties</h3>
+       <div class='topic'>
+               <p>
+                       See the following classes for all configurable 
properties that can be used on this parser:
+               </p>
+               <ul class='spaced-list'>
+                       <li>
+                               {@link org.apache.juneau.BeanContext} - Bean 
context properties.
+                       <li>
+                               {@link 
org.apache.juneau.json.JsonParserContext} - Serializer context properties.
+               </ul>
+       </div>          
+
+
+       <!-- 
========================================================================================================
 -->
+       <a id="ParserOtherNotes"></a>
+       <h3 class='topic' onclick='toggle(this)'>3.3 - Other notes</h3>
+       <div class='topic'>
+               <ul class='spaced-list'>
+                       <li>
+                               Like all other Juneau parsers, the JSON parser 
is thread safe and maintains an internal cache of bean 
+                               classes encountered.
+                               <br>For performance reasons, it's recommended 
that parser be reused whenever possible instead of always 
+                               creating new instances.
+               </ul>
+       </div>
+       
+</div>
+<p align="center"><i><b>*** fín ***</b></i></p>
+
+</body>
+</html>
\ No newline at end of file


Reply via email to