You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/09 19:53:57 UTC

[24/51] [partial] incubator-juneau git commit: Rename project directories.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java
new file mode 100644
index 0000000..eada090
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonWriter.java
@@ -0,0 +1,265 @@
+/***************************************************************************************************************************
+ * 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.
+ ***************************************************************************************************************************/
+package org.apache.juneau.json;
+
+import java.io.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Specialized writer for serializing JSON.
+ * <p>
+ * 	<b>Note:  This class is not intended for external use.</b>
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+public final class JsonWriter extends SerializerWriter {
+
+	private final boolean laxMode, escapeSolidus;
+
+	// Characters that trigger special handling of serializing attribute values.
+	private static final AsciiSet
+		encodedChars = new AsciiSet("\n\t\b\f\r'\"\\"),
+		encodedChars2 = new AsciiSet("\n\t\b\f\r'\"\\/");
+
+	private static final KeywordSet reservedWords = new KeywordSet(
+		"arguments","break","case","catch","class","const","continue","debugger","default","delete",
+		"do","else","enum","eval","export","extends","false","finally","for","function","if",
+		"implements","import","in","instanceof","interface","let","new","null","package",
+		"private","protected","public","return","static","super","switch","this","throw",
+		"true","try","typeof","var","void","while","with","undefined","yield"
+	);
+
+
+	// Characters that represent attribute name characters that don't trigger quoting.
+	// These are actually more strict than the actual Javascript specification, but
+	// can be narrowed in the future if necessary.
+	// For example, we quote attributes that start with $ even though we don't need to.
+	private static final AsciiSet validAttrChars = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
+	private static final AsciiSet validFirstAttrChars = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_");
+
+	private final AsciiSet ec;
+
+	/**
+	 * Constructor.
+	 * @param out The writer being wrapped.
+	 * @param useIndentation If <jk>true</jk>, tabs will be used in output.
+	 * @param useWhitespace If <jk>true</jk>, whitespace will be used in output.
+	 * @param escapeSolidus If <jk>true</jk>, forward slashes should be escaped in the output.
+	 * @param quoteChar The quote character to use (i.e. <js>'\''</js> or <js>'"'</js>)
+	 * @param laxMode If <jk>true</jk>, JSON attributes will only be quoted when necessary.
+	 * @param trimStrings If <jk>true</jk>, strings will be trimmed before being serialized.
+	 * @param relativeUriBase The base (e.g. <js>https://localhost:9443/contextPath"</js>) for relative URIs (e.g. <js>"my/path"</js>).
+	 * @param absolutePathUriBase The base (e.g. <js>https://localhost:9443"</js>) for relative URIs with absolute paths (e.g. <js>"/contextPath/my/path"</js>).
+	 */
+	protected JsonWriter(Writer out, boolean useIndentation, boolean useWhitespace, boolean escapeSolidus, char quoteChar, boolean laxMode, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) {
+		super(out, useIndentation, useWhitespace, trimStrings, quoteChar, relativeUriBase, absolutePathUriBase);
+		this.laxMode = laxMode;
+		this.escapeSolidus = escapeSolidus;
+		this.ec = escapeSolidus ? encodedChars2 : encodedChars;
+	}
+
+	/**
+	 * Serializes the specified object as a JSON string value.
+	 * @param s The object being serialized.
+	 * @return This object (for method chaining).
+	 * @throws IOException Should never happen.
+	 */
+	public JsonWriter stringValue(String s) throws IOException {
+		 /*
+		  * Fixes up a Java string so that it can be used as a JSON string.<br>
+		  * Does the following:<br>
+		  * <ul>
+		  *  <li> Replaces {@code \r?\n} with {@code \\n}<br>
+		  *  <li> Replaces {@code \t} with {@code \\t}<br>
+		  *  <li> Replaces {@code '} with {@code \\'}<br>
+		  *  <li> Replaces {@code "} with {@code \\"}<br>
+		  * </ul>
+		  */
+		if (s == null)
+			return this;
+//		if (trimStrings)
+//			s = s.trim();
+		boolean doConvert = false;
+		for (int i = 0; i < s.length() && ! doConvert; i++) {
+			char c = s.charAt(i);
+			doConvert |= ec.contains(c);
+		}
+		q();
+		if (! doConvert) {
+			out.append(s);
+		} else {
+			for (int i = 0; i < s.length(); i++) {
+				char c = s.charAt(i);
+				if (ec.contains(c)) {
+					if (c == '\n')
+						out.append('\\').append('n');
+					else if (c == '\t')
+						out.append('\\').append('t');
+					else if (c == '\b')
+						out.append('\\').append('b');
+					else if (c == '\f')
+						out.append('\\').append('f');
+					else if (c == quoteChar)
+						out.append('\\').append(quoteChar);
+					else if (c == '\\')
+						out.append('\\').append('\\');
+					else if (c == '/' && escapeSolidus)
+						out.append('\\').append('/');
+					else if (c != '\r')
+						out.append(c);
+				} else {
+					out.append(c);
+				}
+			}
+		}
+		q();
+		return this;
+	}
+
+	/**
+	 * Serializes the specified object as a JSON attribute name.
+	 * @param s The object being serialized.
+	 * @return This object (for method chaining).
+	 * @throws IOException Should never happen.
+	 */
+	public JsonWriter attr(String s) throws IOException {
+		/*
+		 * Converts a Java string to an acceptable JSON attribute name. If
+		 * useStrictJson is false, then quotes will only be used if the attribute
+		 * name consists of only alphanumeric characters.
+		 */
+		boolean doConvert = trimStrings || ! laxMode;		// Always convert when not in lax mode.
+
+		// If the attribute is null, it must always be printed as null without quotes.
+		// Technically, this isn't part of the JSON spec, but it does allow for null key values.
+		if (s == null) {
+			s = "null";
+			doConvert = false;
+
+		} else {
+
+			// Look for characters that would require the attribute to be quoted.
+			// All possible numbers should be caught here.
+			if (! doConvert) {
+				for (int i = 0; i < s.length() && ! doConvert; i++) {
+					char c = s.charAt(i);
+					doConvert |= ! (i == 0 ? validFirstAttrChars.contains(c) : validAttrChars.contains(c));
+				}
+			}
+
+			// Reserved words and blanks must be quoted.
+			if (! doConvert) {
+				if (s.isEmpty() || reservedWords.contains(s))
+					doConvert = true;
+			}
+		}
+
+		// If no conversion necessary, just print the attribute as-is.
+		if (doConvert)
+			stringValue(s);
+		else
+			out.append(s);
+
+		return this;
+	}
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* SerializerWriter */
+	public JsonWriter cr(int depth) throws IOException {
+		super.cr(depth);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter appendln(int indent, String text) throws IOException {
+		super.appendln(indent, text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter appendln(String text) throws IOException {
+		super.appendln(text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter append(int indent, String text) throws IOException {
+		super.append(indent, text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter append(int indent, char c) throws IOException {
+		super.append(indent, c);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter s() throws IOException {
+		super.s();
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter q() throws IOException {
+		super.q();
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter i(int indent) throws IOException {
+		super.i(indent);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter nl() throws IOException {
+		super.nl();
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter append(Object text) throws IOException {
+		super.append(text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter append(String text) throws IOException {
+		super.append(text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter appendIf(boolean b, String text) throws IOException {
+		super.appendIf(b, text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter appendIf(boolean b, char c) throws IOException {
+		super.appendIf(b, c);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public JsonWriter append(char c) throws IOException {
+		super.append(c);
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/annotation/Json.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/annotation/Json.java b/juneau-core/src/main/java/org/apache/juneau/json/annotation/Json.java
new file mode 100644
index 0000000..38648e7
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/annotation/Json.java
@@ -0,0 +1,76 @@
+/***************************************************************************************************************************
+ * 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.
+ ***************************************************************************************************************************/
+package org.apache.juneau.json.annotation;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotation for specifying various JSON options for the JSON serializers and parsers.
+ * <p>
+ * 	Can be applied to Java types.
+ * <p>
+ * 	Can be used for the following:
+ * <ul class='spaced-list'>
+ * 	<li>Wrap bean instances inside wrapper object (e.g. <code>{'wrapperAttr':bean}</code>).
+ * </ul>
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+@Documented
+@Target({TYPE})
+@Retention(RUNTIME)
+@Inherited
+public @interface Json {
+
+	/**
+	 * Wraps beans in a JSON object with the specified attribute name.
+	 * <p>
+	 * 	Applies only to {@link ElementType#TYPE}.
+	 * <p>
+	 * 	This annotation can be applied to beans as well as other objects serialized to other types (e.g. strings).
+	 *
+	 * <dl>
+	 * 	<dt>Example:</dt>
+	 * 	<dd>
+	 * 		<p class='bcode'>
+	 * 	<ja>@Json</ja>(wrapperAttr=<js>"myWrapper"</js>)
+	 * 	<jk>public class</jk> MyBean {
+	 * 		<jk>public int</jk> f1 = 123;
+	 * 	}
+	 * 		</p>
+	 * 		<p>
+	 * 			Without the <ja>@Xml</ja> annotations, serializing this bean as JSON would have produced the following...
+	 * 		</p>
+	 * 		<p class='bcode'>
+	 * 	{
+	 * 		f1: 123
+	 * 	}
+	 * 		</p>
+	 * 		<p>
+	 * 			With the annotations, serializing this bean as XML produces the following...
+	 * 		</p>
+	 * 		<p class='bcode'>
+	 * 	{
+	 * 		myWrapper: {
+	 * 			f1: 123
+	 * 		}
+	 * 	}
+	 * 		</p>
+	 * 	</dd>
+	 * </dl>
+	 */
+	String wrapperAttr() default "";
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/annotation/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/annotation/package.html b/juneau-core/src/main/java/org/apache/juneau/json/annotation/package.html
new file mode 100644
index 0000000..df41b35
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/annotation/package.html
@@ -0,0 +1,41 @@
+<!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 annotations</p>
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_HTML.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_HTML.png b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_HTML.png
new file mode 100644
index 0000000..b4a3576
Binary files /dev/null and b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_HTML.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSON.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSON.png b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSON.png
new file mode 100644
index 0000000..13b5c22
Binary files /dev/null and b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSON.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSchema.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSchema.png b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSchema.png
new file mode 100644
index 0000000..bf1cdc6
Binary files /dev/null and b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSchema.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSimple.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSimple.png b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSimple.png
new file mode 100644
index 0000000..935e8a9
Binary files /dev/null and b/juneau-core/src/main/java/org/apache/juneau/json/doc-files/Example_JSONSimple.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/json/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/package.html b/juneau-core/src/main/java/org/apache/juneau/json/package.html
new file mode 100644
index 0000000..c34a5c1
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/package.html
@@ -0,0 +1,1361 @@
+<!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>
+	<li><p><a class='doclink' href='#RestApiSupport'>REST API support</a></p> 
+	<ol>
+		<li><p><a class='doclink' href='#RestServerSupport'>REST server support</a></p>
+		<ol>
+		<li><p><a class='doclink' href='#RestServletDefault'>Using RestServletDefault</a></p>
+		<li><p><a class='doclink' href='#RestServlet'>Using RestServlet with annotations</a></p>
+		<li><p><a class='doclink' href='#DefaultProvider'>Using JAX-RS DefaultProvider</a></p>
+		<li><p><a class='doclink' href='#BaseProvider'>Using JAX-RS BaseProvider with annotations</a></p>
+		</ol>
+		<li><p><a class='doclink' href='#RestClientSupport'>REST client support</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>PojoTransforms</code> that convert them to serializable forms.
+	</ul>
+	<p>
+		Refer to <a href='../package-summary.html#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>&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.<br>
+			<li>Beans and Maps are converted to JSON objects.<br>
+			<li>Collections and arrays are converted to JSON arrays.<br>
+			<li>Anything else is converted to JSON strings.
+		</ul>
+			
+		<h6 class='figure'>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, transforms 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 transforms 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 {@link org.apache.juneau.transform}.
+		</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.<br>
+	</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> JsonSerializer()
+		.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>, <jk>true</jk>)
+		.setProperty(JsonSerializerContext.<jsf>JSON_useWhitespace</jsf>, <jk>true</jk>)
+		.setProperty(JsonSerializerContext.<jsf>JSON_simpleMode</jsf>, <jk>true</jk>)
+		.setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, <js>'\''</js>);
+	</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 transforms 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 transform 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 transforms, 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>(transform=CalendarTransform.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.PropertyNamerDashedLC} is an example of an alternate property namer.
+			It converts bean property names to lowercase-dashed format.
+		</p>
+		<h6 class='figure'>Example</h6>
+		<p class='bcode'>	
+	<ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<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>(transform=CalendarTransform.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>.clone().setProperty(SerializerContext.<jsf>SERIALIZER_detectRecursions</jsf>, <jk>true</jk>);
+
+	<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>
+		</table>	
+	</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 transform.</jc>
+	CalendarTransform transform = <jk>new</jk> CalendarTransform.ISO8601DTZ();
+	Calendar birthDate = m.get(transform, <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>
+
+
+<!-- ======================================================================================================== -->
+<a id="RestApiSupport"></a>
+<h2 class='topic' onclick='toggle(this)'>4 - REST API support</h2>
+<div class='topic'>
+	<p>
+		Juneau provides fully-integrated support for JSON serialization/parsing in the REST server and client APIs.<br>
+		The next two sections describe these in detail.
+	</p>
+
+	<!-- ======================================================================================================== -->
+	<a id="RestServerSupport"></a>
+	<h3 class='topic' onclick='toggle(this)'>4.1 - REST server support</h3>
+	<div class='topic'>
+		<p>
+			There are four general ways of defining REST interfaces with support for JSON.
+			Two using the built-in Juneau Server API, and two using the JAX-RS integration component.
+		</p>
+		<ul class='spaced-list'>
+			<li>Create a servlet that subclasses from {@link org.apache.juneau.server.RestServletDefault}.<br>
+					This includes JSON serialization/parsing support by default, in addition to several other media types.
+			<li>Create a servlet that subclasses from {@link org.apache.juneau.server.RestServlet} and specify the
+					a JSON serializer and/or parser using the {@link org.apache.juneau.server.annotation.RestResource#serializers()} and
+					{@link org.apache.juneau.server.annotation.RestResource#parsers()} on the entire servlet class, or 
+					the {@link org.apache.juneau.server.annotation.RestMethod#serializers()} and {@link org.apache.juneau.server.annotation.RestMethod#parsers()}
+					annotations on individual methods within the class.
+			<li>Register {@link org.apache.juneau.server.jaxrs.DefaultProvider} with JAX-RS.<br>
+					This includes JSON serialization/parsing support by default, in addition to several other media types.
+			<li>Create and register a subclass of {@link org.apache.juneau.server.jaxrs.BaseProvider} and specify the serializers and parsers to use on JAX-RS resources.
+		</ul>
+		<p>
+			In general, the Juneau REST server API is much more configurable and easier to use than JAX-RS, but beware that the author may be slightly biased in this statement.
+		</p>
+
+		<!-- ======================================================================================================== -->
+		<a id="RestServletDefault"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.1 - Using RestServletDefault</h4>
+		<div class='topic'>
+			<p>
+				The quickest way to implement a REST resource with JSON support is to create a subclass of {@link org.apache.juneau.server.RestServletDefault}.<br>
+				This class provides support for JSON, XML, HTML, URL-Encoding, and others.
+			</p>
+			<p>
+				The <code>AddressBookResource</code> example shown in the first chapter uses the <code>RestServletJenaDefault</code> class
+					which is a subclass of <code>RestServletDefault</code> with additional support for RDF languages.<br>
+				The start of the class definition is shown below:
+			</p>
+			<p class='bcode'>
+	<jc>// Proof-of-concept resource that shows off the capabilities of working with POJO resources.
+	// Consists of an in-memory address book repository.</jc>
+	<ja>@RestResource</ja>(
+		messages=<js>"nls/AddressBookResource"</js>,
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>),
+			<ja>@Property</ja>(name=HtmlSerializerContext.<jsf>HTML_uriAnchorText</jsf>, value=<jsf>TO_STRING</jsf>),
+			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
+			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
+			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+		},
+		encoders=GzipEncoder.<jk>class</jk>
+	)
+	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
+			</p>
+			<p>
+				Notice how serializer and parser properties can be specified using the <code>@RestResource.properties()</code> annotation.<br>
+				The <jsf>SERIALIZER_quoteChar</jsf> is a property common to all serializers, including the JSON serializer.
+				The remaining properties are specific to the HTML serializer.
+			</p>
+			<p>
+ 				The <code>$L{...}</code> variable represent localized strings pulled from the resource bundle identified by the <code>messages</code> annotation.
+ 				These variables are replaced at runtime based on the HTTP request locale.
+				Several built-in runtime variable types are defined, and the API can be extended to include user-defined variables.
+				See {@link org.apache.juneau.server.RestServlet#getVarResolver()} for more information.
+			</p>
+			<p>
+				This document won't go into all the details of the Juneau <code>RestServlet</code> class.<br>
+				Refer to the {@link org.apache.juneau.server} documentation for more information on the REST servlet class in general.
+			</p>
+			<p>
+				The rest of the code in the resource class consists of REST methods that simply accept and return POJOs.<br>
+				The framework takes care of all content negotiation, serialization/parsing, and error handling.<br>
+				Below are 3 of those methods to give you a general idea of the concept:
+			</p>
+			<p class='bcode'>
+	<jc>// GET person request handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
+	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Attr</ja> <jk>int</jk> id) throws Exception {
+		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+		<jk>return</jk> findPerson(id);
+	}
+	
+	<jc>// POST person handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"POST"</js>, path=<js>"/people"</js>, guards=AdminGuard.<jk>class</jk>, rc={307,404})
+	<jk>public void</jk> createPerson(RestResponse res, <ja>@Content</ja> CreatePerson cp) <jk>throws</jk> Exception {
+		Person p = addressBook.createPerson(cp);
+		res.sendRedirect(p.<jf>uri</jf>);
+	}
+
+	<jc>// DELETE person handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"DELETE"</js>, path=<js>"/people/{id}"</js>, guards=AdminGuard.<jk>class</jk>, rc={200,404})
+	<jk>public</jk> String deletePerson(RestResponse res, <ja>@Attr</ja> <jk>int</jk> id) <jk>throws</jk> Exception {
+		Person p = findPerson(id);
+		addressBook.remove(p);
+		<jk>return</jk> <js>"DELETE successful"</js>;			
+	}	
+			</p>
+			<p>
+				The resource class can be registered with the web application like any other servlet, or can be 
+					defined as a child of another resource through the {@link org.apache.juneau.server.annotation.RestResource#children()} annotation.
+		</div>
+
+		<!-- ======================================================================================================== -->
+		<a id="RestServlet"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.2 - Using RestServlet with annotations</h4>
+		<div class='topic'>
+			<p>
+				For fine-tuned control of media types, the {@link org.apache.juneau.server.RestServlet} class 
+					can be subclassed directly.<br>
+				The serializers/parsers can be specified through annotations at the class and/or method levels.
+			</p>
+			<p>
+				An equivalent <code>AddressBookResource</code> class could be defined to only support JSON using
+					the following definition:
+			</p>
+			<p class='bcode'>
+	<ja>@RestResource</ja>(
+		serializers={JsonSerializer.<jk>class</jk>},
+		parsers={JsonParser.<jk>class</jk>},
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
+		}
+	)
+	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServlet {
+			</p>
+			<p>
+				Likewise, serializers and parsers can be specified/augmented/overridden at the method level like so:
+			</p>
+			<p class='bcode'>
+	<jc>// GET person request handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404},
+		serializers={JsonSerializer.<jk>class</jk>},
+		parsers={JsonParser.<jk>class</jk>},
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
+		}
+	)
+	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Attr</ja> <jk>int</jk> id) throws Exception {
+		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+		<jk>return</jk> findPerson(id);
+	}
+			</p>
+			<p>
+				The {@link org.apache.juneau.server.annotation.RestMethod#serializersInherit()} and 
+					{@link org.apache.juneau.server.annotation.RestMethod#parsersInherit()} control how various artifacts
+					are inherited from the parent class.<br>
+				Refer to {@link org.apache.juneau.server} for additional information on using these annotations.
+			</p>
+		</div>
+
+		<!-- ======================================================================================================== -->
+		<a id="DefaultProvider"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.3 - Using JAX-RS DefaultProvider</h4>
+		<div class='topic'>
+			<p>
+				JSON media type support in JAX-RS can be achieved by using the {@link org.apache.juneau.server.jaxrs.DefaultProvider} class.<br>
+				It implements the JAX-RS <code>MessageBodyReader</code> and <code>MessageBodyWriter</code> interfaces for all Juneau supported media types.
+			</p>
+			<p>
+				The <code>DefaultProvider</code> class definition is shown below:
+			</p>
+			<p class='bcode'>
+	<ja>@Provider</ja>
+	<ja>@Produces</ja>({
+		<js>"application/json"</js>, <js>"text/json"</js>,                 <jc>// JsonSerializer</jc>
+		<js>"application/json+simple"</js>,<js>"text/json+simple"</js>,    <jc>// JsonSerializer.Simple</jc>
+		<js>"application/json+schema"</js>,<js>"text/json+schema"</js>,    <jc>// JsonSchemaSerializer</jc>
+		<js>"text/xml"</js>,                                      <jc>// XmlDocSerializer</jc>
+		<js>"text/xml+simple"</js>,                               <jc>// XmlDocSerializer.Simple</jc>
+		<js>"text/xml+schema"</js>,                               <jc>// XmlSchemaDocSerializer</jc>
+		<js>"text/html"</js>,                                     <jc>// HtmlDocSerializer</jc>
+		<js>"application/x-www-form-urlencoded"</js>,             <jc>// UrlEncodingSerializer</jc>
+		<js>"text/xml+soap"</js>,                                 <jc>// SoapXmlSerializer</jc>
+		<js>"application/x-java-serialized-object"</js>           <jc>// JavaSerializedObjectSerializer</jc>
+	})
+	<ja>@Consumes</ja>({
+		<js>"application/json"</js>, <js>"text/json"</js>,                 <jc>// JsonParser</jc>
+		<js>"text/xml"</js>,                                      <jc>// XmlParser</jc>
+		<js>"text/html"</js>,                                     <jc>// HtmlParser</jc>
+		<js>"application/x-www-form-urlencoded"</js>,             <jc>// UrlEncodingParser</jc>
+		<js>"application/x-java-serialized-object"</js>           <jc>// JavaSerializedObjectParser</jc>
+	})
+	<ja>@JuneauProvider</ja>(
+		serializers={
+			JsonSerializer.<jk>class</jk>,
+			JsonSerializer.Simple.<jk>class</jk>,
+			JsonSchemaSerializer.<jk>class</jk>,
+			XmlDocSerializer.<jk>class</jk>,
+			XmlDocSerializer.Simple.<jk>class</jk>,
+			XmlSchemaDocSerializer.<jk>class</jk>,
+			HtmlDocSerializer.<jk>class</jk>,
+			UrlEncodingSerializer.<jk>class</jk>,
+			SoapXmlSerializer.<jk>class</jk>,
+			JavaSerializedObjectSerializer.<jk>class</jk>
+		},
+		parsers={
+			JsonParser.<jk>class</jk>,
+			XmlParser.<jk>class</jk>,
+			HtmlParser.<jk>class</jk>,
+			UrlEncodingParser.<jk>class</jk>,
+			JavaSerializedObjectParser.<jk>class</jk>,
+		}
+	)
+	<jk>public final class</jk> DefaultProvider <jk>extends</jk> BaseProvider {}
+			</p>
+			<p>
+				That's the entire class.  It consists of only annotations to hook up media types to Juneau serializers and parsers.
+				The <ja>@Provider</ja>, <ja>@Produces</ja>, and <ja>@Consumes</ja> annotations are standard JAX-RS annotations, and the <ja>@JuneauProvider</ja> annotation is from Juneau.
+			</p>
+			<p>
+				To enable the provider, you need to make the JAX-RS environment aware of it.
+				In Wink, this is accomplished by adding an entry to a config file.
+			</p>
+			<p class='bcode'>
+	<xt>&lt;web-app</xt> <xa>version</xa>=<xs>"2.3"</xs><xt>&gt;</xt>
+		<xt>&lt;servlet&gt;</xt>
+			<xt>&lt;servlet-name&gt;</xt>WinkService<xt>&lt;/servlet-name&gt;</xt>
+			<xt>&lt;servlet-class&gt;</xt>org.apache.wink.server.internal.servlet.RestServlet<xt>&lt;/servlet-class&gt;</xt>
+			<xt>&lt;init-param&gt;</xt>
+				<xt>&lt;param-name&gt;</xt>applicationConfigLocation<xt>&lt;/param-name&gt;</xt>
+				<xt>&lt;param-value&gt;</xt>/WEB-INF/wink.cfg<xt>&lt;/param-value&gt;</xt>
+			<xt>&lt;/init-param&gt;</xt>
+		<xt>&lt;/servlet&gt;</xt>
+			</p>
+			<p>
+				Simply include a reference to the provider in the configuration file.
+			<p class='bcode'>
+	org.apache.juneau.server.jaxrs.DefaultProvider
+			</p>
+			<p>
+				Properties can be specified on providers through the {@link org.apache.juneau.server.jaxrs.JuneauProvider#properties()} annotation.<br>
+				Properties can also be specified at the method level by using the {@link org.apache.juneau.server.annotation.RestMethod#properties} annotation, like so:
+			</p>
+			<p class='bcode'>
+	<ja>@GET</ja>
+	<ja>@Produces</ja>(<js>"*/*"</js>)
+	<ja>@RestMethod</ja>( <jc>/* Override some properties */</jc>
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
+		}
+	)
+	<jk>public</jk> Message getMessage() {
+		<jk>return</jk> message;
+	}
+			</p>
+			<h6 class='topic'>Limitations</h6>
+			<p>
+				In general, the Juneau REST API is considerably more flexible than the JAX-RS API, since you can specify and override
+					serializers, parsers, properties, transforms, converters, guards, etc... at both the class and method levels.<br>
+				Therefore, the JAX-RS API has the following limitations that the Juneau Server API does not:
+			</p>
+			<ul class='spaced-list'>
+				<li>The ability to specify different media type providers at the class and method levels.<br> 
+					For example, you may want to use <code>JsonSerializer</code> with one set of properties on 
+						one class, and another instance with different properties on another class.<br>
+					There is currently no way to define this at the class level.<br>
+					You can override properties at the method level, but this can be cumbersome since it would have to be
+						done for all methods in the resource.
+				<li>The Juneau Server API allows you to manipulate properties programatically through the {@link org.apache.juneau.server.RestResponse#setProperty(String,Object)}
+					method, and through the {@link org.apache.juneau.server.annotation.Properties} annotation.<br>
+					There is no equivalent in JAX-RS.
+			</ul>
+		</div>
+
+		<!-- ======================================================================================================== -->
+		<a id="BaseProvider"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.4 - Using JAX-RS BaseProvider with annotations</h4>
+		<div class='topic'>
+			<p>
+				To provide support for only JSON media types, you can define your own provider class, like so:
+			</p>
+			<p class='bcode'>
+	<ja>@Provider</ja>
+	<ja>@Produces</ja>({
+		<js>"application/json"</js>, <js>"text/json"</js>,                 <jc>// JsonSerializer</jc>
+		<js>"application/json+simple"</js>,<js>"text/json+simple"</js>,    <jc>// JsonSerializer.Simple</jc>
+		<js>"application/json+schema"</js>,<js>"text/json+schema"</js>     <jc>// JsonSchemaSerializer</jc>
+	})
+	<ja>@Consumes</ja>({
+		<js>"application/json"</js>, <js>"text/json"</js>                  <jc>// JsonParser</jc>
+	})
+	<ja>@JuneauProvider</ja>(
+		serializers={
+			JsonSerializer.<jk>class</jk>,
+			JsonSerializer.Simple.<jk>class</jk>,
+			JsonSchemaSerializer.<jk>class</jk>,
+		},
+		parsers={
+			JsonParser.<jk>class</jk>,
+		}
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>, value=<js>"'"</js>)
+		}
+	)
+	<jk>public final class</jk> MyRdfProvider <jk>extends</jk> BaseProvider {}
+			</p>
+			<p>
+				Then register it with Wink the same way as <code>DefaultProvider</code>.
+			</p>
+		</div>
+
+	</div>
+
+	<!-- ======================================================================================================== -->
+	<a id="RestClientSupport"></a>
+	<h3 class='topic' onclick='toggle(this)'>4.2 - REST client support</h3>
+	<div class='topic'>
+		<p>
+			The {@link org.apache.juneau.client.RestClient} class provides an easy-to-use REST client interface with 
+				pluggable media type handling using any of the Juneau serializers and parsers.<br>
+			Defining a client to support JSON media types on HTTP requests and responses can be done in one line of code:
+		</p>
+		<p class='bcode'>
+	<jc>// Create a client to handle JSON requests and responses.</jc>
+	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>);
+		</p>
+		<p>
+			The client handles all content negotiation based on the registered serializers and parsers.
+		</p>
+		<p>
+			The following code is pulled from the main method of the <code>ClientTest</code> class in the sample web application, and
+				is run against the <code>AddressBookResource</code> class running within the sample app.<br>
+			It shows how the client can be used to interact with the REST API while completely hiding the negotiated content type and working with nothing more than beans.
+		</p>
+		<h6 class='figure'>Example</h6>
+		<p class='bcode'>
+	String root = <js>"http://localhost:9080/sample/addressBook"</js>;
+	
+	<jc>// Get the current contents of the address book</jc>
+	AddressBook ab = client.doGet(root).getResponse(AddressBook.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Number of entries = "</js> + ab.size());
+	
+	<jc>// Delete the existing entries</jc>
+	<jk>for</jk> (Person p : ab) {
+		String r = client.doDelete(p.<jf>uri</jf>).getResponse(String.<jk>class</jk>);
+		System.<jsm>out</jsm>.println(<js>"Deleted person "</js> + p.<jf>name</jf> + <js>", response = "</js> + r);
+	}
+	
+	<jc>// Make sure they're gone</jc>
+	ab = client.doGet(root).getResponse(AddressBook.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Number of entries = "</js> + ab.size());
+	
+	<jc>// Add 1st person again</jc>
+	CreatePerson cp = <jk>new</jk> CreatePerson(
+		<js>"Barack Obama"</js>, 
+		<jsm>toCalendar</jsm>(<js>"Aug 4, 1961"</js>),
+		<jk>new</jk> CreateAddress(<js>"1600 Pennsylvania Ave"</js>, <js>"Washington"</js>, <js>"DC"</js>, 20500, <jk>true</jk>),
+		<jk>new</jk> CreateAddress(<js>"5046 S Greenwood Ave"</js>, <js>"Chicago"</js>, <js>"IL"</js>, 60615, <jk>false</jk>)
+	); 
+	Person p = client.doPost(root + <js>"/people"</js>, cp).getResponse(Person.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created person "</js> + p.<jf>name</jf> + <js>", uri = "</js> + p.<jf>uri</jf>);
+	
+	<jc>// Add 2nd person again, but add addresses separately</jc>
+	cp = <jk>new</jk> CreatePerson(
+		<js>"George Walker Bush"</js>, 
+		toCalendar(<js>"Jul 6, 1946"</js>)
+	);
+	p = client.doPost(root + <js>"/people"</js>, cp).getResponse(Person.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created person "</js> + p.<jf>name</jf> + <js>", uri = "</js> + p.<jf>uri</jf>);
+	
+	<jc>// Add addresses to 2nd person</jc>
+	CreateAddress ca = <jk>new</jk> CreateAddress(<js>"43 Prairie Chapel Rd"</js>, <js>"Crawford"</js>, <js>"TX"</js>, 76638, <jk>true</jk>);
+	Address a = client.doPost(p.<jf>uri</jf> + <js>"/addresses"</js>, ca).getResponse(Address.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created address "</js> + a.<jf>uri</jf>);
+				
+	ca = <jk>new</jk> CreateAddress(<js>"1600 Pennsylvania Ave"</js>, <js>"Washington"</js>, <js>"DC"</js>, 20500, <jk>false</jk>);
+	a = client.doPost(p.<jf>uri</jf> + "/addresses"</js>, ca).getResponse(Address.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created address "</js> + a.<jf>uri</jf>);
+	
+	<jc>// Find 1st person, and change name</jc>
+	Person[] pp = client.doGet(root + <js>"?q={name:\"'Barack+Obama'\"}"</js>).getResponse(Person[].<jk>class</jk>);
+	String r = client.doPut(pp[0].<jf>uri</jf> + <js>"/name"</js>, <js>"Barack Hussein Obama"</js>).getResponse(String.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Changed name, response = "</js> + r);
+	p = client.doGet(pp[0].<jf>uri</jf>).getResponse(Person.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"New name = "</js> + p.<jf>name</jf>);
+		</p>
+		<h6 class='figure'>Results</h6>
+		<p class='bcode'>
+	Number of entries = 2
+	Deleted person Barack Obama, response = DELETE successful
+	Deleted person George Walker Bush, response = DELETE successful
+	Number of entries = 0
+	Created person Barack Obama, uri = http://localhost:9080/sample/addressBook/people/3
+	Created person George Walker Bush, uri = http://localhost:9080/sample/addressBook/people/4
+	Created address http://localhost:9080/sample/addressBook/addresses/7
+	Created address http://localhost:9080/sample/addressBook/addresses/8
+	Changed name, response = PUT successful
+	New name = Barack Hussein Obama
+		</p>
+	</div>
+</div>
+<p align="center"><i><b>*** f�n ***</b></i></p>
+
+</body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/msgpack/DataType.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/DataType.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/DataType.java
new file mode 100644
index 0000000..53be5f0
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/DataType.java
@@ -0,0 +1,73 @@
+/***************************************************************************************************************************
+ * 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.
+ ***************************************************************************************************************************/
+package org.apache.juneau.msgpack;
+
+/**
+ * Constants for the MessagePack format.
+ *
+ * @author James Bognar (james.bognar@salesforce.com)
+ */
+enum DataType {
+	NULL, BOOLEAN, INT, LONG, FLOAT, DOUBLE, STRING, BIN, EXT, ARRAY, MAP, INVALID;
+
+	boolean isOneOf(DataType...dataTypes) {
+		for (DataType dt : dataTypes)
+			if (this == dt)
+				return true;
+		return false;
+	}
+
+	static final int
+		POSFIXINT_L  = 0x00,  //   pos fixint     0xxxxxxx     0x00 - 0x7f
+		POSFIXINT_U  = 0x7F,
+		FIXMAP_L     = 0x80,  //   fixmap         1000xxxx     0x80 - 0x8f
+		FIXMAP_U     = 0x8F,
+		FIXARRAY_L   = 0x90,  //   fixarray       1001xxxx     0x90 - 0x9f
+		FIXARRAY_U   = 0x9F,
+		FIXSTR_L     = 0xA0,  //   fixstr         101xxxxx     0xa0 - 0xbf
+		FIXSTR_U     = 0xBF,
+		NIL          = 0xC0,  //   nil            11000000     0xc0
+		NU           = 0xC1,  //   (never used)   11000001     0xc1
+		FALSE        = 0xC2,  //   false          11000010     0xc2
+		TRUE         = 0xC3,  //   true           11000011     0xc3
+		BIN8         = 0xC4,  //   bin 8          11000100     0xc4
+		BIN16        = 0xC5,  //   bin 16         11000101     0xc5
+		BIN32        = 0xC6,  //   bin 32         11000110     0xc6
+		EXT8         = 0xC7,  //   ext 8          11000111     0xc7
+		EXT16        = 0xC8,  //   ext 16         11001000     0xc8
+		EXT32        = 0xC9,  //   ext 32         11001001     0xc9
+		FLOAT32      = 0xCA,  //   float 32       11001010     0xca
+		FLOAT64      = 0xCB,  //   float 64       11001011     0xcb
+		UINT8        = 0xCC,  //   uint 8         11001100     0xcc
+		UINT16       = 0xCD,  //   uint 16        11001101     0xcd
+		UINT32       = 0xCE,  //   uint 32        11001110     0xce
+		UINT64       = 0xCF,  //   uint 64        11001111     0xcf
+		INT8         = 0xD0,  //   int 8          11010000     0xd0
+		INT16        = 0xD1,  //   int 16         11010001     0xd1
+		INT32        = 0xD2,  //   int 32         11010010     0xd2
+		INT64        = 0xD3,  //   int 64         11010011     0xd3
+		FIXEXT1      = 0xD4,  //   fixext 1       11010100     0xd4
+		FIXEXT2      = 0xD5,  //   fixext 2       11010101     0xd5
+		FIXEXT4      = 0xD6,  //   fixext 4       11010110     0xd6
+		FIXEXT8      = 0xD7,  //   fixext 8       11010111     0xd7
+		FIXEXT16     = 0xD8,  //   fixext 16      11011000     0xd8
+		STR8         = 0xD9,  //   str 8          11011001     0xd9
+		STR16        = 0xDA,  //   str 16         11011010     0xda
+		STR32        = 0xDB,  //   str 32         11011011     0xdb
+		ARRAY16      = 0xDC,  //   array 16       11011100     0xdc
+		ARRAY32      = 0xDD,  //   array 32       11011101     0xdd
+		MAP16        = 0xDE,  //   map 16         11011110     0xde
+		MAP32        = 0xDF,  //   map 32         11011111     0xdf
+		NEGFIXINT_L  = 0xE0,  //   neg fixint     111xxxxx     0xe0 - 0xff
+		NEGFIXINT_U  = 0xFF;
+}