http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transform/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/package.html 
b/juneau-core/src/main/java/org/apache/juneau/transform/package.html
new file mode 100644
index 0000000..c9a953e
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/package.html
@@ -0,0 +1,771 @@
+<!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>Transform API</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='#Transforms'>Transforms</a></p>
+       <ol>
+               <li><p><a class='doclink' href='#BeanTransforms'>BeanTransform 
Class</a></p>
+               <li><p><a class='doclink' href='#PojoTransforms'>PojoTransform 
Class</a></p>
+               <li><p><a class='doclink' href='#PojoTransforms_OneWay'>One-Way 
PojoTransforms</a></p>
+               <li><p><a class='doclink' href='#StopClasses'>Stop 
Classes</a></p>
+               <li><p><a class='doclink' href='#SurrogateClasses'>Surrogate 
Classes</a></p>
+               <li><p><a class='doclink' href='#ToObjectMaps'>Serializing to 
ObjectMaps</a></p>
+       </ol>
+</ol>
+
+<!-- 
========================================================================================================
 -->
+<a id="Transforms"></a>
+<h2 class='topic' onclick='toggle(this)'>1 - Transforms</h2>
+<div class='topic'>
+       <p>
+               By default, the Juneau framework can serialize and parse a wide 
variety of POJOs out-of-the-box.  
+               However, a <code>Transform</code> API is provided to tailor how 
certain Java objects are handled by the framework.
+               The class hierarchy is shown here:
+       </p>
+       <ul class='spaced-list'>
+               <li>{@link org.apache.juneau.transform.Transform} - Top-level 
interface for all transforms.
+       <ul class='spaced-list'>
+               <li>{@link org.apache.juneau.transform.BeanTransform} - 
Transforms that alter the way beans are handled.
+               <li>{@link org.apache.juneau.transform.PojoTransform} - 
Transforms that transform non-serializable POJOs into serializable POJOs during 
serialization 
+                       (and optionally vis-versa during parsing).
+               </ul>
+       </ul>
+       <p>
+               Transforms are added to serializers and parsers in a variety of 
ways:
+       </p> 
+       <ul class='spaced-list'>
+               <li>{@link 
org.apache.juneau.serializer.Serializer#addTransforms(Class[])} - On 
serializers.
+               <li>{@link 
org.apache.juneau.serializer.SerializerGroup#addTransforms(Class[])} - On 
groups of serializers.
+               <li>{@link 
org.apache.juneau.parser.Parser#addTransforms(Class[])} - On parsers.
+               <li>{@link 
org.apache.juneau.parser.ParserGroup#addTransforms(Class[])} - On groups of 
parsers.
+               <li>{@link 
org.apache.juneau.client.RestClient#addTransforms(Class[])} - On the serializer 
and parser registered on a REST client.
+               <li>{@link 
org.apache.juneau.server.annotation.RestResource#transforms() 
@RestResource.transforms()} - On all serializers and parsers defined on a REST 
servlet.
+               <li>{@link 
org.apache.juneau.server.annotation.RestMethod#transforms() 
@RestMethod.transforms()} - On all serializers and parsers defined on a method 
in a REST servlet.
+               <li>{@link 
org.apache.juneau.server.jaxrs.JuneauProvider#transforms()} - On all 
serializers and parsers defined on a JAX-RS provider.
+       </ul>
+       <p>
+               Transforms (typically <code>PojoTransforms</code>) can also be 
associated with classes through the {@link 
org.apache.juneau.annotation.Transform @Transform} annotation. 
+       </p>
+               
+       <!-- 
========================================================================================================
 -->
+       <a id="BeanTransforms"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.1 - BeanTransform Class</h3>
+       <div class='topic'>
+               <p>
+                       Bean transforms are used to tailor how Juneau handles 
bean classes.
+                       They can be used for the following purposes:
+               </p>
+               <ul class='spaced-list'>
+                       <li>Include or exclude which properties are exposed in 
beans, or the order those properties are serialized.
+                       <li>Define property-namers for customizing bean 
property names.
+                       <li>Define bean subtypes.
+                       <li>Define bean interface classes.
+               </ul>
+               <p>
+                       It should be noted that the {@link 
org.apache.juneau.annotation.Bean @Bean} annotation provides equivalent 
functionality
+                               through annotations.  
+                       However, the <code>BeanTransform</code> class allows 
you to provide the same features when you do
+                               not have access to the source code.
+               <p>
+               <h5 class='topic'>Examples</h5>
+
+               <h6 class='topic'>Explicitly specify which properties are 
visible on a bean class</h6>
+               <p class='bcode'>
+       <jc>// Define transform that orders properties by "age" then "name"</jc>
+       <jk>public class</jk> MyTransform <jk>extends</jk> 
BeanTransform&ltPerson&gt; {
+               <jk>public</jk> MyTransform() {
+                       setProperties(<js>"age"</js>,<js>"name"</js>);
+               }
+       }
+       
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyTransform.<jk>class</jk>);
+       Person p = getPerson();
+       String json = s.serialize(p);  <jc>// Prints "{age:45,name:'John 
Smith'}"</jc>
+               </p>
+               <p>
+                       Note that this is equivalent to specifying the 
following annotation on the bean class:
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(properties={<js>"age"</js>,<js>"name"</js>})
+       <jk>public class</jk> Person {
+               ...
+       }
+               </p>
+
+               <h6 class='topic'>Exclude which properties are visible on a 
bean class</h6>
+               <p class='bcode'>
+       <jc>// Define transform that excludes "name"</jc>
+       <jk>public class</jk> MyTransform <jk>extends</jk> 
BeanTransform&ltPerson&gt; {
+               <jk>public</jk> MyTransform() {
+                       setExcludeProperties(<js>"name"</js>);
+               }
+       }
+       
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyTransform.<jk>class</jk>);
+       Person p = getPerson();
+       String json = s.serialize(p);  <jc>// Prints "{age:45}"</jc>
+               </p>
+               <p>
+                       Note that this is equivalent to specifying the 
following annotation on the bean class:
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(excludeProperties={<js>"name"</js>})
+       <jk>public class</jk> Person {
+               ...
+       }
+               </p>
+
+               <h6 class='topic'>Define specialized property namers</h6>
+               <p class='bcode'>
+       <jc>// Define transform with our own property namer.</jc>
+       <jk>public class</jk> MyTransform <jk>extends</jk> 
BeanTransform&ltPerson&gt; {
+               <jk>public</jk> MyTransform() {
+                       setPropertyNamer(UpperCasePropertyNamer.<jk>class</jk>);
+               }
+       }
+
+       <jc>// Define property namer that upper-cases the property names</jc>   
+       <jk>public class</jk> UpperCasePropertyNamer <jk>implements</jk> 
PropertyNamer {
+       
+               <ja>@Override</ja>
+               <jk>public</jk> String getPropertyName(String name) {
+                       <jk>return</jk> name.toUpperCase();
+               }
+       }
+       
+       <jc>// Serialize to JSON</jc>
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyTransform.<jk>class</jk>);
+       Person person = getPerson();
+       String json = s.serialize(p);  <jc>// Prints "{AGE:45,NAME:'John 
Smith'}"</jc>
+       
+       <jc>// Parse back into bean</jc>
+       ReaderParser p = <jk>new</jk> 
JsonParser().addTransforms(MyTransform.<jk>class</jk>);
+       person = p.parse(json, Person.class); <jc>// Read back into original 
object</jc>
+               </p>
+               <p>
+                       Note that this is equivalent to specifying the 
following annotation on the bean class:
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(propertyNamer=UpperCasePropertyNamer.<jk>class</jk>)
+       <jk>public class</jk> Person {
+               ...
+       }
+               </p>
+               
+               <h6 class='topic'>Define bean subtypes</h6>
+               <p>
+                       Juneau allows you to losslessly serialize and parse 
abstract class fields back into the original 
+                               concrete objects by defining a subtype 
attribute and a list of subtypes/ids.
+               </p>
+               <p>
+                       For example, let's define the following parent class 
with two subclasses:
+               </p>
+               <p class='bcode'>
+       <jc>// Abstract parent class</jc>
+       <jk>public abstract class</jk> MyClass {
+               <jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+       }
+
+       <jc>// Subclass 1</jc>
+       <jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+               <jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+       }
+       
+       <jc>// Subclass 2</jc>
+       <jk>public class</jk> MyClassBaz <jk>extends</jk> MyClass {
+               <jk>public</jk> String <jf>baz</jf>=<js>"baz"</js>;
+       }
+               </p>
+               <p>
+                       Normally, when parsing a serialized 
<code>MyClass</code> object, the parser does not know what subtype to create.
+                       This can be fixed by defining the following transform:
+               </p>            
+               <p class='bcode'>
+       <jc>// Define transform with our own property namer.</jc>
+       <jk>public class</jk> MyClassTransform <jk>extends</jk> 
BeanTransform&ltMyClass&gt; {
+               <jk>public</jk> MyClassTransform() {
+                       setSubTypeProperty(<js>"subType"</js>);
+                       addSubType(MyClassBar.<jk>class</jk>, <js>"BAR"</js>);
+                       addSubType(MyClassBaz.<jk>class</jk>, <js>"BAZ"</js>);
+               }
+       }
+               </p>
+               <p>
+                       When serialized, the serialized bean will include a 
<code>"subType"</code> attribute that identifies the subclass, and
+                               allows it to be parsed back into the original 
subclass.
+               </p>
+               <p class='bcode'>
+       <jc>// Serialize to JSON</jc>
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyClassTransform.<jk>class</jk>);
+       MyClass c = <jk>new</jk> MyClassBar();
+       String json = s.serialize(p);  <jc>// Prints 
"{subType:'BAR',foo:'foo',bar:'bar'}"</jc>
+       
+       <jc>// Parse back into bean</jc>
+       ReaderParser p = <jk>new</jk> 
JsonParser().addTransforms(MyClassTransform.<jk>class</jk>);
+       c = p.parse(json, MyClass.<jk>class</jk>); <jc>// c is an instance of 
MyClassBar</jc>
+               </p>    
+               <p>
+                       It should be noted that the sub type attribute is 
always rendered first in the JSON object so 
+                               that the bean object can be instantiated before 
the real properties are set on it during parsing.  
+                       Beans with subtypes are thus 'lazy-instantiated' when 
the sub type attribute is set.
+                       If the sub type attribute is not listed first, the 
parser will still be able to parse the input,
+                       but with reduced efficiency since it must cache the 
incoming data until the bean can be instantiated.
+               </p>
+               <p>
+                       Note that this transform is equivalent to specifying 
the following annotation on the bean class:
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(
+               subTypeProperty=<js>"subType"</js>,
+               subTypes={
+                       <ja>@BeanSubType</ja>(type=MyClassBar.<jk>class</jk>, 
id=<js>"BAR"</js>),
+                       <ja>@BeanSubType</ja>(type=MyClassBaz.<jk>class</jk>, 
id=<js>"BAZ"</js>)
+               }
+       )
+       <jk>public abstract class</jk> MyClass {
+               ...
+       }
+               </p>
+                       
+               <h6 class='topic'>Limiting bean properties to parent bean 
classes</h6>
+               <p>
+                       Occassionally, you may want to limit bean properties to 
some parent interface.
+                       For example, in the <code>RequestEchoResource</code> 
class in the sample war file, we serialize instances of
+                               <code>HttpServletRequest</code> and 
<code>HttpServletResponse</code>.
+                       However, we really only want to serialize the 
properties defined on those specific APIs, not 
+                               vendor-specific methods on the instances of 
those classes.
+                       This can be done through the 
<code>interfaceClass</code> property of a bean transform.
+               </p>
+               <p>
+                       For example, let's define the following parent class 
and subclass:
+               </p>
+               <p class='bcode'>
+       <jc>// Abstract parent class</jc>
+       <jk>public abstract class</jk> MyClass {
+               <jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+       }
+
+       <jc>// Subclass 1</jc>
+       <jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+               <jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+       }
+               </p>
+               <p>
+                       Suppose we only want to render the properties defined 
on <code>MyClass</code>, not those defined on child classes.
+                       To do so, we can define the following transform:
+               </p>
+               <p class='bcode'>
+       <jc>// Define transform that limits properties to only those defined on 
MyClass</jc>
+       <jk>public class</jk> MyClassTransform <jk>extends</jk> 
BeanTransform&ltMyClass&gt; {
+               <jk>public</jk> MyClassTransform() {
+                       setInterfaceClass(MyClass.<jk>class</jk>);
+               }
+       }
+               </p>
+               <p>
+                       When serialized, the serialized bean will only include 
properties defined on the parent class.
+               </p>
+               <p class='bcode'>
+       <jc>// Serialize to JSON</jc>
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyClassTransform.<jk>class</jk>);
+       MyClass c = <jk>new</jk> MyClassBar();
+       String json = s.serialize(p);  <jc>// Prints "{foo:'foo'}"</jc>
+               </p>    
+               <p>
+                       The equivalent can be done through an annotation on the 
parent class, which applies to all child classes:
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+       <jk>public abstract class</jk> MyClass {
+               <jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+       }
+               </p>
+               <p>
+                       The annotation can also be applied on the individual 
child classes, like so...
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+       <jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+               <jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+       }
+               </p>
+               <p>
+                       Also, the <code>addTransforms(...)</code> methods will 
automatically interpret any non-<code>Transform</code> classes
+                               passed in as meaning interface classes.  
+                       So in the previous example, the 
<code>BeanTransform</code> class could have been avoided altogether by just 
+                               passing in <code>MyClass.<jk>class</jk></code> 
to the serializer, like so:
+               </p>
+               <p class='bcode'>
+       <jc>// Serialize to JSON</jc>
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyClass.<jk>class</jk>);
+               </p>
+               <p>
+                       In fact, this is the shortcut used in the 
<code>RequestEchoResource</code> sample class:
+               </p>
+               <p class='bcode'>
+       <ja>@RestResource</ja>(
+               transforms={
+                       <jc>// Interpret these as their parent classes, not 
subclasses</jc>
+                       HttpServletRequest.<jk>class</jk>, 
HttpSession.<jk>class</jk>, ServletContext.<jk>class</jk>
+               }
+       )
+       <jk>public class</jk> RequestEchoResource <jk>extends</jk> 
RestServletDefault {
+               </p>
+               
+               <h6 class='topic'>Allowing non-public bean 
classes/methods/fields to be used by the framework</h6>
+               <p>
+                       By default, only public classes are interpreted as 
beans.  Non-public classes are treated as 'other' POJOs that
+                       are typically just serialized to strings using the 
<code>toString()</code> method.
+                       Likewise, by default, only public fields/methods are 
interpreted as bean properties.
+               </p>
+               <p>
+                       The following bean context properties can be used to 
allow non-public classes/methods/fields to be
+                       used by the framework:
+               </p>
+               <ul>
+                       <li>{@link 
org.apache.juneau.BeanContext#BEAN_beanClassVisibility}
+                       <li>{@link 
org.apache.juneau.BeanContext#BEAN_beanConstructorVisibility}
+                       <li>{@link 
org.apache.juneau.BeanContext#BEAN_methodVisibility}
+                       <li>{@link 
org.apache.juneau.BeanContext#BEAN_beanFieldVisibility}
+               </ul>
+               <p>
+                       Also, specifying a {@link 
org.apache.juneau.annotation.BeanProperty @BeanProperty} annotation on 
non-public getters/setters/fields
+                               will also allow them to be detected by the 
framework.
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> MyBean {
+               <jc>// A bean property</jc>
+               <jk>public int</jk> f1;    
+               
+               <jc>// Not a bean property</jc>
+               <ja>@BeanIgnore</ja>
+               <jk>public int</jk> f2;     
+               
+               <jc>// A bean property</jc>
+               <ja>@BeanProperty</ja>    
+               <jk>protected int</jk> f3;  
+               
+               <jc>// A bean property</jc>
+               <ja>@BeanProperty</ja>    
+               <jk>private int</jk> getF3() {...}
+       }
+               </p>
+       </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="PojoTransforms"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.2 - PojoTransform Class</h3>
+       <div class='topic'>
+               <p>
+                       {@link org.apache.juneau.transform.PojoTransform 
PojoTransforms} are a critical component of the Juneau architecture.  
+                       They allow the Juneau serializers and parsers to be 
extended to handle virtually any kind of Java object. 
+               </p>
+               <p>
+                       As explained in the overview, Juneau has built-in 
support for serializing and parsing specific kinds of objects, like primitive 
objects, bean, maps, collections, and arrays.  
+                       Other kinds of POJOs, such as {@code Date} objects, 
cannot be serialized properly, since they are not true beans.  
+                       This is where <code>PojoTransforms</code> come into 
play.
+               </p>
+               <p>
+                       The purpose of an <code>PojoTransform</code> is to 
convert a non-serializable object to a serializable surrogate form during 
serialization, and to optionally convert that surrogate form back into the 
original object during parsing.
+               </p>
+               <p>
+                       For example, the following transform can be used to 
convert {@link java.util.Date} objects to ISO8601 strings during serialization, 
and {@link java.util.Date} objects from ISO8601 string during parsing:
+               </p>
+               <p class='bcode'>
+       <jc>// Sample transform for converting Dates to ISO8601 strings.</jc>
+       <jk>public class</jk> MyDateTransform <jk>extends</jk> 
PojoTransform&lt;Date,String&gt; {
+               
+               <jc>// ISO8601 formatter.</jc>
+               <jk>private</jk> DateFormat <jf>format</jf> = <jk>new</jk> 
SimpleDateFormat(<js>"yyyy-MM-dd'T'HH:mm:ssZ"</js>);
+               
+               <jd>/** Converts a Date object to an ISO8601 string. */</jd>
+               <ja>@Override</ja>
+               <jk>public</jk> String transform(Date o) {
+                       <jk>return</jk> <jf>format</jf>.format(o);
+               }
+               
+               <jd>/** Converts an ISO8601 string to a Date object. */</jd>
+               <ja>@Override</ja>
+               <jk>public</jk> Date normalize(String o, ClassMeta&lt;?&gt; 
hint) <jk>throws</jk> ParseException {
+                       <jk>try</jk> {
+                               <jk>return</jk> <jf>format</jf>.parse(o);
+                       } <jk>catch</jk> (java.text.ParseException e) {
+                               <jk>throw new</jk> ParseException(e);
+                       }
+               }
+       }
+               </p>
+               <p>
+                       The transform above can then be associated with 
serializers and parsers as the following example shows:
+               </p>
+               <p class='bcode'>
+       <jc>// Sample bean with a Date field.</jc>
+       <jk>public class</jk> MyBean {
+               <jk>public</jk> Date <jf>date</jf> = <jk>new</jk> Date(112, 2, 
3, 4, 5, 6);
+       }
+
+       <jc>// Create a new JSON serializer, associate our date transform with 
it, and serialize a sample bean.</jc>
+       Serializer serializer = <jk>new</jk> 
JsonSerializer().addTransforms(MyDateTransform.<jk>class</jk>);
+       String json = serializer.serialize(<jk>new</jk> MyBean());      <jc>// 
== "{date:'2012-03-03T04:05:06-0500'}"</jc>
+       
+       <jc>// Create a JSON parser, associate our date transform with it, and 
reconstruct our bean (including the date).</jc>
+       ReaderParser parser = <jk>new</jk> 
JsonParser().addTransforms(MyDateTransform.<jk>class</jk>);
+       MyBean bean = parser.parse(json, MyBean.<jk>class</jk>);
+       <jk>int</jk> day = bean.<jf>date</jf>.getDay();                         
                        <jc>// == 3</jc>
+               </p>
+               <p>
+                       In addition, the {@link 
org.apache.juneau.BeanMap#get(Object)} and {@link 
org.apache.juneau.BeanMap#put(String,Object)} methods will automatically 
convert to transformed values as the following example shows:
+               </p>
+               <p class='bcode'>
+       <jc>// Create a new bean context and add our transform.</jc>
+       BeanContext beanContext = <jk>new</jk> 
BeanContext().addTransforms(MyDateTransform.<jk>class</jk>);
+
+       <jc>// Create a new bean.</jc>
+       MyBean myBean = <jk>new</jk> MyBean();
+
+       <jc>// Wrap it in a bean map.</jc>
+       BeanMap&lt;Bean&gt; beanMap = beanContext.forBean(myBean);
+
+       <jc>// Use the get() method to get the date field as an ISO8601 
string.</jc>
+       String date = (String)beanMap.get(<js>"date"</js>);                     
        <jc>// == "2012-03-03T04:05:06-0500"</jc> 
+       
+       <jc>// Use the put() method to set the date field to an ISO8601 
string.</jc>
+       beanMap.put(<js>"date"</js>, <js>"2013-01-01T12:30:00-0500"</js>);      
<jc>// Set it to a new value.</jc> 
+       
+       <jc>// Verify that the date changed on the original bean.</jc>
+       <jk>int</jk> year = myBean.<jf>date</jf>.getYear();                     
                                        <jc>// == 113</jc>
+               </p>
+               <p>
+                       Another example of a <code>PojoTransform</code> is one 
that converts <code><jk>byte</jk>[]</code> arrays to BASE64-encoded strings:
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> ByteArrayBase64Transform <jk>extends</jk> 
PojoTransform&lt;<jk>byte</jk>[],String&gt; {
+       
+               <ja>@Override</ja>
+               <jk>public</jk> String transform(<jk>byte</jk>[] b) 
<jk>throws</jk> SerializeException {
+                       <jk>try</jk> {
+                               ByteArrayOutputStream baos = <jk>new</jk> 
ByteArrayOutputStream();
+                               OutputStream b64os = MimeUtility.encode(baos, 
<js>"base64"</js>);
+                               b64os.write(b);
+                               b64os.close();
+                               <jk>return new</jk> String(baos.toByteArray());
+                       } <jk>catch</jk> (Exception e) {
+                               <jk>throw new</jk> SerializeException(e);
+                       }
+               }
+               
+               <ja>@Override</ja>
+               <jk>public byte</jk>[] normalize(String s, ClassMeta&lt;?&gt; 
hint) <jk>throws</jk> ParseException {
+                       <jk>try</jk> {
+                               <jk>byte</jk>[] b = s.getBytes();
+                               ByteArrayInputStream bais = <jk>new</jk> 
ByteArrayInputStream(b);
+                               InputStream b64is = MimeUtility.decode(bais, 
<js>"base64"</js>);
+                               <jk>byte</jk>[] tmp = <jk>new 
byte</jk>[b.length];
+                               <jk>int</jk> n = b64is.read(tmp);
+                               <jk>byte</jk>[] res = <jk>new byte</jk>[n];
+                               System.<jsm>arraycopy</jsm>(tmp, 0, res, 0, n);
+                               <jk>return</jk> res;
+                       } <jk>catch</jk> (Exception e) {
+                               <jk>throw new</jk> ParseException(e);
+                       }
+               }
+       }
+               </p>
+               <p>
+                       The following example shows the BASE64 transform in use:
+               </p>
+               <p class='bcode'>
+       <jc>// Create a JSON serializer and register the BASE64 encoding 
transform with it.</jc>
+       Serializer serializer = <jk>new</jk> 
JsonSerializer().addTransforms(ByteArrayBase64Transform.<jk>class</jk>);
+       ReaderParser parser = <jk>new</jk> 
JsonParser().addTransforms(ByteArrayBase64Transform.<jk>class</jk>);
+       
+       <jk>byte</jk>[] a1 = {1,2,3};
+       String s1 = serializer.serialize(a1);           <jc>// Produces 
"'AQID'"</jc>
+       a1 = parser.parse(s1, <jk>byte</jk>[].<jk>class</jk>);          <jc>// 
Reproduces {1,2,3}</jc>
+       
+       <jk>byte</jk>[][] a2 = {{1,2,3},{4,5,6},<jk>null</jk>};
+       String s2 = serializer.serialize(a2);           <jc>// Produces 
"['AQID','BAUG',null]"</jc>
+       a2 = parser.parse(s2, <jk>byte</jk>[][].<jk>class</jk>);                
<jc>// Reproduces {{1,2,3},{4,5,6},null}</jc>
+               </p>
+               <p>
+                       It should be noted that the sample transforms shown 
above have already been implemented in the {@link org.apache.juneau.transforms} 
package.
+                       The following are a list of out-of-the-box transforms:
+               </p>
+               <ul class='spaced-list'>
+                       <li>{@link 
org.apache.juneau.transforms.ByteArrayBase64Transform} - Converts byte arrays 
to BASE64 encoded strings.
+                       <li>{@link 
org.apache.juneau.transforms.CalendarTransform} - Transforms for converting 
<code>Calendar</code> objects to various date format strings.
+                       <li>{@link org.apache.juneau.transforms.DateTransform} 
- Transforms for converting <code>Date</code> objects to various date format 
strings.
+                       <li>{@link 
org.apache.juneau.transforms.EnumerationTransform} - Transforms for converting 
<code>Enumeration</code> objects to arrays.
+                       <li>{@link 
org.apache.juneau.transforms.IteratorTransform} - Transforms for converting 
<code>Iterator</code> objects to arrays.
+                       <li>{@link 
org.apache.juneau.transforms.ReaderTransform} - Transforms for converting 
<code>Readers</code> to objects before serialization.
+                       <li>{@link 
org.apache.juneau.transforms.XMLGregorianCalendarTransform} - Transforms for 
converting <code>XMLGregorianCalendar</code> objects to ISO8601 strings.
+               </ul>
+               
+               <h6 class='topic'>Valid transformed class types</h6>
+               <p>
+                       The transformed class type can be any serializable 
class type as defined in the <a 
href='../package-summary.html#PojoCategories'>POJO categories</a> table.
+               </p>
+       </div>
+       
+
+       <!-- 
========================================================================================================
 -->
+       <a id="PojoTransforms_OneWay"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.3 - One-Way 
PojoTransforms</h3>
+       <div class='topic'>
+               <p>
+                       In the previous section, we defined two-way transforms, 
meaning transforms where the original objects could be reconstructing during 
parsing.  However, there are certain kinds of POJOs that we may want to support 
for serializing, but that are not possible to reconstruct during parsing.  For 
these, we can use one-way object transforms.
+               </p>
+               <p>
+                       A one-way object transform is simply an object 
transform that only implements the {@code transform()} method.  The {@code 
normalize()} method is simply left unimplemented.
+               </p>
+               <p>
+                       An example of a one-way transform would be one that 
allows {@code Iterators} to be serialized as JSON arrays.  It can make sense to 
be able to render {@code Iterators} as arrays, but in general it's not possible 
to reconstruct an {@code Iterator} during parsing. 
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> IteratorTransform <jk>extends</jk> 
PojoTransform&lt;Iterator,List&gt; {
+               
+               <ja>@Override</ja>
+               <jk>public</jk> List transform(Iterator o) {
+                       List l = <jk>new</jk> LinkedList();
+                       <jk>while</jk> (o.hasNext())
+                               l.add(o.next());
+                       <jk>return</jk> l;
+               }
+       }
+               </p>
+               <p>
+                       Here is an example of our one-way transform being used. 
 Note that trying to parse the original object will cause a {@link 
org.apache.juneau.parser.ParseException} to be thrown.
+               </p>
+               <p class='bcode'>
+       <jc>// Create a JSON serializer that can serialize Iterators.</jc>
+       Serializer serializer = <jk>new</jk> 
JsonSerializer().addTransforms(IteratorTransform.<jk>class</jk>);
+       
+       <jc>// Construct an iterator we want to serialize.</jc>
+       Iterator iterator = <jk>new</jk> ObjectList(1,2,3).iterator();
+       
+       <jc>// Serialize our Iterator</jc>
+       String s = serializer.serialize(iterator);              <jc>// Produces 
"[1,2,3]"</jc>
+       
+       <jc>// Try to parse it.</jc>
+       ReaderParser parser = <jk>new</jk> 
JsonParser().addTransforms(IteratorTransform.<jk>class</jk>);
+       iterator = parser.parse(s, Iterator.<jk>class</jk>);            <jc>// 
Throws ParseException!!!</jc>
+               </p>
+       </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="StopClasses"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.4 - Stop Classes</h3>
+       <div class='topic'>
+               <p>
+                       Occassionally, you may want to limit bean properties to 
only those defined on a parent class or interface.  
+                       There are a couple of ways of doing this.
+               </p>
+               <p>
+                       For example, let's define the following parent class 
and subclass:
+               </p>
+               <p class='bcode'>
+       <jc>// Abstract parent class</jc>
+       <jk>public abstract class</jk> MyClass {
+               <jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+       }
+
+       <jc>// Subclass 1</jc>
+       <jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+               <jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+       }
+               </p>
+               <p>
+                       Suppose we only want to render the properties defined 
on <code>MyClass</code>, not those defined on child classes. 
+                       To do so, we can define the following transform:
+               </p>
+               <p class='bcode'>
+       <jc>// Define transform that limits properties to only those defined on 
MyClass</jc>
+       <jk>public class</jk> MyClassTransform <jk>extends</jk> 
BeanTransform&ltMyClass&gt; {
+               <jk>public</jk> MyClassTransform() {
+                       setInterfaceClass(MyClass.<jk>class</jk>);
+               }
+       }
+               </p>
+               <p>
+                       When serialized, the serialized bean will only include 
properties defined on the parent class.
+               </p>
+               <p class='bcode'>
+       <jc>// Serialize to JSON</jc>
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyClassTransform.<jk>class</jk>);
+       MyClass c = <jk>new</jk> MyClassBar();
+       String json = s.serialize(p);  <jc>// Prints "{foo:'foo'}"</jc>
+               </p>    
+               <p>
+                       The equivalent can be done through an annotation on the 
parent class, which applies to all child classes:
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+       <jk>public abstract class</jk> MyClass {
+               <jk>public</jk> String <jf>foo</jf>=<js>"foo"</js>;
+       }
+               </p>
+               <p>
+                       The annotation can also be applied on the individual 
child classes, like so...
+               </p>
+               <p class='bcode'>
+       <ja>@Bean</ja>(interfaceClass=MyClass.<jk>class</jk>)
+       <jk>public class</jk> MyClassBar <jk>extends</jk> MyClass {
+               <jk>public</jk> String <jf>bar</jf>=<js>"bar"</js>;
+       }
+               </p>
+               <p>
+                       Also, the <code>addTransforms()</code> methods will 
automatically interpret any non-Transform classes passed in as meaning 
interface classes. 
+                       So in the previous example, the 
<code>BeanTransform</code> class could have been avoided altogether by just 
passing in <code>MyClass.<jk>class</jk></code> to the serializer, like so:
+               </p>
+               <p class='bcode'>
+       <jc>// Serialize to JSON</jc>
+       WriterSerializer s = <jk>new</jk> 
JsonSerializer().addTransforms(MyClass.<jk>class</jk>);
+               </p>
+       </div>
+
+       <!-- 
========================================================================================================
 -->
+       <a id="SurrogateClasses"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.5 - Surrogate Classes</h3>
+       <div class='topic'>
+               <p>
+                       Surrogate classes are very similar in concept to 
one-way <code>PojoTransforms</code> except they represent a simpler syntax.
+               </p>
+               <p>
+                       For example, let's say we want to be able to serialize 
the following class, but it's not serializable for some reason (for example, 
there are no
+                       properties exposed):  
+               <p class='bcode'>
+       <jk>public class</jk> MyNonSerializableClass {
+               <jk>protected</jk> String <jf>foo</jf>;
+       }
+               </p>
+               <p>
+                       This could be solved with the following 
<code>PojoTransform</code>.
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> MySerializableSurrogate {
+               <jk>public</jk> String <jf>foo</jf>;
+       }
+               
+       <jk>public class</jk> MyTransform <jk>extends</jk> 
PojoTransform&lt;MyNonSerializableClass,MySerializableSurrogate&gt; {
+               
+               <ja>@Override</ja>
+               <jk>public</jk> MySerializableSurrogate 
transform(MyNonSerializableClass o) {
+                       MySerializableSurrogate s = <jk>new</jk> 
MySerializableSurrogate();
+                       s.<jf>foo</jf> = o.<jf>foo</jf>;
+                       <jk>return</jk> s;
+               }
+       }
+               </p>
+               <p>
+                       However, the same can be accomplished by using a 
surrogate class that simply contains a constructor with the non-serializable 
class as an argument:
+               </p>
+               <p class='bcode'>
+       <jk>public class</jk> MySerializableSurrogate {
+               <jk>public</jk> String <jf>foo</jf>;
+               
+               <jk>public</jk> MySerializableSurrogate(MyNonSerializableClass 
c) {
+                       <jk>this</jk>.<jf>foo</jf> = c.<jf>foo</jf>;
+               }
+       }
+               </p>
+               <p>
+                       The surrogate class is registered just like any other 
transform:
+               </p>
+               <p class='bcode'>
+       <jc>// Create a JSON serializer that can serialize Iterators.</jc>
+       Serializer serializer = <jk>new</jk> 
JsonSerializer().addTransforms(MySerializableSurrogate.<jk>class</jk>);
+               </p>
+               <p>
+                       When the serializer encounters the non-serializable 
class, it will serialize an instance of the surrogate instead.
+               </p>
+       </div>
+       
+       <!-- 
========================================================================================================
 -->
+       <a id="ToObjectMaps"></a>
+       <h3 class='topic' onclick='toggle(this)'>1.6 - Serializing to 
ObjectMaps</h3>
+       <div class='topic'>
+       <div class='topic'>
+               <p>
+                       A shortcut method for transforming is provided that can 
often be simpler than defining transforms.
+                       In this case, we add methods to our class to serialize 
to {@link org.apache.juneau.ObjectMap ObjectMaps}
+               </p>
+               <p>
+               <p class='bcode'>
+       <jk>public class</jk> MyClass {
+               <jk>private</jk> String <jf>f1</jf>;
+               
+               <jc>// Constructor that takes in an ObjectMap</jc>
+               <jk>public</jk> MyClass(ObjectMap m) {
+                       <jf>f1</jf> = m.getString(<js>"f1"</js>);
+               }
+               
+               <jc>// Method that converts object to an ObjectMap</jc>
+               <jk>public</jk> ObjectMap toObjectMap() {
+                       <jk>return new</jk> ObjectMap().append(<js>"f1"</js>, 
<jf>f1</jf>);
+               }
+               </p>
+               <p>
+                       The <code>toObjectMap()</code> method will 
automatically be used during serialization, and 
+                       the constructor will automatically be used during 
parsing.
+                       This will work for all serializers and parsers.
+               </p>
+       </div>
+</div>
+</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/transforms/BeanStringTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/BeanStringTransform.java
 
b/juneau-core/src/main/java/org/apache/juneau/transforms/BeanStringTransform.java
new file mode 100644
index 0000000..51ece7d
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/BeanStringTransform.java
@@ -0,0 +1,39 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import org.apache.juneau.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms beans into {@link String Strings} by simply calling the {@link 
Object#toString()} method.
+ * <p>
+ *     Allows you to specify classes that should just be converted to {@code 
Strings} instead of potentially
+ *     being turned into Maps by the {@link BeanContext} (or worse, throwing 
{@link BeanRuntimeException BeanRuntimeExceptions}).
+ * <p>
+ *     This is usually a one-way transform.
+ *     Beans serialized as strings cannot be reconstituted using a parser 
unless it is a <a class='doclink' 
href='../package-summary.html#PojoCategories'>Type 5 POJO</a>.
+ *
+ * @author James Bognar ([email protected])
+ * @param <T> The class type of the bean.
+ */
+public class BeanStringTransform<T> extends PojoTransform<T,String> {
+
+       /**
+        * Converts the specified bean to a {@link String}.
+        */
+       @Override /* PojoTransform */
+       public String transform(T o) {
+               return o.toString();
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/ByteArrayBase64Transform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/ByteArrayBase64Transform.java
 
b/juneau-core/src/main/java/org/apache/juneau/transforms/ByteArrayBase64Transform.java
new file mode 100644
index 0000000..f4f809d
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/ByteArrayBase64Transform.java
@@ -0,0 +1,51 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms <code><jk>byte</jk>[]</code> arrays to BASE-64 encoded {@link 
String Strings}.
+ *
+ * @author James Bognar ([email protected])
+ */
+public class ByteArrayBase64Transform extends PojoTransform<byte[],String> {
+
+       /**
+        * Converts the specified <code><jk>byte</jk>[]</code> to a {@link 
String}.
+        */
+       @Override /* PojoTransform */
+       public String transform(byte[] b) throws SerializeException {
+               try {
+                       return StringUtils.base64Encode(b);
+               } catch (Exception e) {
+                       throw new SerializeException(e);
+               }
+       }
+
+       /**
+        * Converts the specified {@link String} to a 
<code><jk>byte</jk>[]</code>.
+        */
+       @Override /* PojoTransform */
+       public byte[] normalize(String s, ClassMeta<?> hint) throws 
ParseException {
+               try {
+                       return StringUtils.base64Decode(s);
+               } catch (Exception e) {
+                       throw new ParseException(e);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarLongTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarLongTransform.java
 
b/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarLongTransform.java
new file mode 100644
index 0000000..48423c0
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarLongTransform.java
@@ -0,0 +1,54 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Calendar Calendars} to {@link Long Longs} using {@code 
Calender.getTime().getTime()}.
+ *
+ * @author James Bognar ([email protected])
+ */
+public class CalendarLongTransform extends PojoTransform<Calendar,Long> {
+
+       /**
+        * Converts the specified {@link Calendar} to a {@link Long}.
+        */
+       @Override /* PojoTransform */
+       public Long transform(Calendar o) {
+               return o.getTime().getTime();
+       }
+
+       /**
+        * Converts the specified {@link Long} to a {@link Calendar}.
+        */
+       @Override /* PojoTransform */
+       @SuppressWarnings("unchecked")
+       public Calendar normalize(Long o, ClassMeta<?> hint) throws 
ParseException {
+               ClassMeta<? extends Calendar> tt;
+               try {
+                       if (hint == null || ! hint.canCreateNewInstance())
+                               hint = 
getBeanContext().getClassMeta(GregorianCalendar.class);
+                       tt = (ClassMeta<? extends Calendar>)hint;
+                       Calendar c = tt.newInstance();
+                       c.setTimeInMillis(o);
+                       return c;
+               } catch (Exception e) {
+                       throw new ParseException(e);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarMapTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarMapTransform.java
 
b/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarMapTransform.java
new file mode 100644
index 0000000..1582a61
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarMapTransform.java
@@ -0,0 +1,62 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Calendar Calendars} to {@link Map Maps} of the format 
<code>{_class:String,value:long}</code>.
+ *
+ * @author James Bognar ([email protected])
+ */
+@SuppressWarnings("rawtypes")
+public class CalendarMapTransform extends PojoTransform<Calendar,Map> {
+
+       /**
+        * Converts the specified {@link Calendar} to a {@link Map}.
+        */
+       @Override /* PojoTransform */
+       public Map transform(Calendar o) {
+               ObjectMap m = new ObjectMap();
+               m.put("time", o.getTime().getTime());
+               m.put("timeZone", o.getTimeZone().getID());
+               return m;
+       }
+
+       /**
+        * Converts the specified {@link Map} to a {@link Calendar}.
+        */
+       @Override /* PojoTransform */
+       @SuppressWarnings("unchecked")
+       public Calendar normalize(Map o, ClassMeta<?> hint) throws 
ParseException {
+               ClassMeta<? extends Calendar> tt;
+               try {
+                       if (hint == null || ! hint.canCreateNewInstance())
+                               hint = 
getBeanContext().getClassMeta(GregorianCalendar.class);
+                       tt = (ClassMeta<? extends Calendar>)hint;
+                       long time = Long.parseLong(o.get("time").toString());
+                       String timeZone = o.get("timeZone").toString();
+                       Date d = new Date(time);
+                       Calendar c = tt.newInstance();
+                       c.setTime(d);
+                       c.setTimeZone(TimeZone.getTimeZone(timeZone));
+                       return c;
+               } catch (Exception e) {
+                       throw new ParseException(e);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarTransform.java 
b/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarTransform.java
new file mode 100644
index 0000000..6847dca
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/CalendarTransform.java
@@ -0,0 +1,293 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.text.*;
+import java.util.*;
+
+import javax.xml.bind.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.ParseException;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Calendar Calendars} to {@link String Strings}.
+ *
+ *
+ * <h6 class='topic'>Behavior-specific subclasses</h6>
+ * <p>
+ *     The following direct subclasses are provided for convenience:
+ * <ul class='spaced-list'>
+ *     <li>{@link ToString} - Transforms to {@link String Strings} using the 
{@code Date.toString()} method.
+ *     <li>{@link ISO8601DT} - Transforms to ISO8601 date-time strings.
+ *     <li>{@link ISO8601DTZ} - Same as {@link ISO8601DT}, except always 
serializes in GMT.
+ *     <li>{@link RFC2822DT} - Transforms to RFC2822 date-time strings.
+ *     <li>{@link RFC2822DTZ} - Same as {@link RFC2822DT}, except always 
serializes in GMT.
+ *     <li>{@link RFC2822D} - Transforms to RFC2822 date strings.
+ *     <li>{@link Simple} - Transforms to simple <js>"yyyy/MM/dd 
HH:mm:ss"</js> strings.
+ *     <li>{@link Medium} - Transforms to {@link DateFormat#MEDIUM} strings.
+ * </ul>
+ *
+ *
+ * @author James Bognar ([email protected])
+ */
+public class CalendarTransform extends PojoTransform<Calendar,String> {
+
+       private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+       /**
+        * Transforms {@link Calendar Calendars} to {@link String Strings} 
using the {@code Date.toString()} method.
+        *
+        * <dl>
+        *      <dt>Example output:</dt>
+        *      <dd>
+        *              <ul>
+        *                      <li><js>"Wed Jul 04 15:30:45 EST 2001"</js>
+        *              </ul>
+        *      </dd>
+        * </dl>
+        */
+       public static class ToString extends CalendarTransform {
+               /** Constructor */
+               public ToString() {
+                       super("EEE MMM dd HH:mm:ss zzz yyyy");
+               }
+       }
+
+       /**
+        * Transforms {@link Calendar Calendars} to ISO8601 date-time strings.
+        *
+        * <dl>
+        *      <dt>Example output:</dt>
+        *      <dd>
+        *              <ul>
+        *                      <li><js>"2001-07-04T15:30:45-05:00"</js>
+        *                      <li><js>"2001-07-04T15:30:45Z"</js>
+        *              </ul>
+        *      </dd>
+        *      <dt>Example input:</dt>
+        *      <dd>
+        *              <ul>
+        *                      <li><js>"2001-07-04T15:30:45-05:00"</js>
+        *                      <li><js>"2001-07-04T15:30:45Z"</js>
+        *                      <li><js>"2001-07-04T15:30:45.1Z"</js>
+        *                      <li><js>"2001-07-04T15:30Z"</js>
+        *                      <li><js>"2001-07-04"</js>
+        *                      <li><js>"2001-07"</js>
+        *                      <li><js>"2001"</js>
+        *                       </ul>
+        *      </dd>
+        * </dl>
+        */
+       public static class ISO8601DT extends CalendarTransform {
+
+               /** Constructor */
+               public ISO8601DT() {}
+
+               @Override /* PojoTransform */
+               public Calendar normalize(String o, ClassMeta<?> hint) throws 
ParseException {
+                       try {
+                               if (StringUtils.isEmpty(o))
+                                       return null;
+                               return 
convert(DatatypeConverter.parseDateTime(o), hint);
+                       } catch (Exception e) {
+                               throw new ParseException(e);
+                       }
+               }
+
+               @Override /* PojoTransform */
+               public String transform(Calendar o) {
+                       return DatatypeConverter.printDateTime(o);
+               }
+       }
+
+       /**
+        * Same as {@link ISO8601DT}, except always serializes in GMT.
+        * <p>
+        * Example output: <js>"2001-07-04T15:30:45Z"</js>
+        */
+       public static class ISO8601DTZ extends CalendarTransform {
+
+               /** Constructor */
+               public ISO8601DTZ() {}
+
+               @Override /* PojoTransform */
+               public Calendar normalize(String o, ClassMeta<?> hint) throws 
ParseException {
+                       try {
+                               if (StringUtils.isEmpty(o))
+                                       return null;
+                               return 
convert(DatatypeConverter.parseDateTime(o), hint);
+                       } catch (Exception e) {
+                               throw new ParseException(e);
+                       }
+               }
+
+               @Override /* PojoTransform */
+               public String transform(Calendar o) {
+                       if (o.getTimeZone().getRawOffset() != 0) {
+                               Calendar c = Calendar.getInstance(GMT);
+                               c.setTime(o.getTime());
+                               o = c;
+                       }
+                       return DatatypeConverter.printDateTime(o);
+               }
+       }
+
+       /**
+        * Transforms {@link Calendar Calendars} to RFC2822 date-time strings.
+        */
+       public static class RFC2822DT extends CalendarTransform {
+               /** Constructor */
+               public RFC2822DT() {
+                       super("EEE, dd MMM yyyy HH:mm:ss Z");
+               }
+       }
+
+       /**
+        * Same as {@link RFC2822DT}, except always serializes in GMT.
+        * <p>
+        * Example output: <js>"Wed, 31 Jan 2001 12:34:56 +0000"</js>
+        */
+       public static class RFC2822DTZ extends CalendarTransform {
+               /** Constructor */
+               public RFC2822DTZ() {
+                       super("EEE, dd MMM yyyy HH:mm:ss 'GMT'", GMT);
+               }
+       }
+
+       /**
+        * Transforms {@link Calendar Calendars} to RFC2822 date strings.
+        */
+       public static class RFC2822D extends CalendarTransform {
+               /** Constructor */
+               public RFC2822D() {
+                       super("dd MMM yyyy");
+               }
+       }
+
+       /**
+        * Transforms {@link Calendar Calendars} to simple <js>"yyyy/MM/dd 
HH:mm:ss"</js> strings.
+        */
+       public static class Simple extends CalendarTransform {
+               /** Constructor */
+               public Simple() {
+                       super("yyyy/MM/dd HH:mm:ss");
+               }
+       }
+
+       /**
+        * Transforms {@link Calendar Calendars} to {@link DateFormat#MEDIUM} 
strings.
+        */
+       public static class Medium extends CalendarTransform {
+               /** Constructor */
+               public Medium() {
+                       super(DateFormat.getDateInstance(DateFormat.MEDIUM));
+               }
+       }
+
+       /** The formatter to convert dates to Strings. */
+       private DateFormat format;
+
+       private TimeZone timeZone;
+
+       /**
+        * Default constructor.
+        * <p>
+        *      This constructor is used when <code>transform()</code> and 
<code>normalize()</code> are overridden by subclasses.
+        */
+       public CalendarTransform() {}
+
+       /**
+        * Construct a transform using the specified date format string that 
will be
+        *      used to construct a {@link SimpleDateFormat} that will be used 
to convert
+        *      dates to strings.
+        *
+        * @param simpleDateFormat The {@link SimpleDateFormat} pattern.
+        */
+       public CalendarTransform(String simpleDateFormat) {
+               this(new SimpleDateFormat(simpleDateFormat));
+       }
+
+       /**
+        * Construct a transform using the specified date format string that 
will be
+        *      used to construct a {@link SimpleDateFormat} that will be used 
to convert
+        *      dates to strings.
+        *
+        * @param simpleDateFormat The {@link SimpleDateFormat} pattern.
+        * @param timeZone The time zone to associate with the date pattern.
+        */
+       public CalendarTransform(String simpleDateFormat, TimeZone timeZone) {
+               this(new SimpleDateFormat(simpleDateFormat));
+               format.setTimeZone(timeZone);
+               this.timeZone = timeZone;
+       }
+
+       /**
+        * Construct a transform using the specified {@link DateFormat} that 
will be used to convert
+        *      dates to strings.
+        *
+        * @param format The format to use to convert dates to strings.
+        */
+       public CalendarTransform(DateFormat format) {
+               super();
+               this.format = format;
+       }
+
+       /**
+        * Converts the specified {@link Calendar} to a {@link String}.
+        */
+       @Override /* PojoTransform */
+       public String transform(Calendar o) {
+               DateFormat df = format;
+               TimeZone tz1 = o.getTimeZone();
+               TimeZone tz2 = format.getTimeZone();
+               if (timeZone == null && ! tz1.equals(tz2)) {
+                       df = (DateFormat)format.clone();
+                       df.setTimeZone(tz1);
+               }
+               return df.format(o.getTime());
+       }
+
+       /**
+        * Converts the specified {@link String} to a {@link Calendar}.
+        */
+       @Override /* PojoTransform */
+       public Calendar normalize(String o, ClassMeta<?> hint) throws 
ParseException {
+               try {
+                       if (StringUtils.isEmpty(o))
+                               return null;
+                       return convert(format.parse(o), hint);
+               } catch (Exception e) {
+                       throw new ParseException(e);
+               }
+       }
+
+       private static Calendar convert(Calendar in, ClassMeta<?> hint) throws 
Exception {
+               if (hint.isInstance(in) || ! hint.canCreateNewInstance())
+                       return in;
+               Calendar c = (Calendar)hint.newInstance();
+               c.setTime(in.getTime());
+               c.setTimeZone(in.getTimeZone());
+               return c;
+       }
+
+       private static Calendar convert(Date in, ClassMeta<?> hint) throws 
Exception {
+               if (hint == null || ! hint.canCreateNewInstance())
+                       hint = 
BeanContext.DEFAULT.getClassMeta(GregorianCalendar.class);
+               Calendar c = (Calendar)hint.newInstance();
+               c.setTime(in);
+               return c;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/DateLongTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/DateLongTransform.java 
b/juneau-core/src/main/java/org/apache/juneau/transforms/DateLongTransform.java
new file mode 100644
index 0000000..aadc314
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/DateLongTransform.java
@@ -0,0 +1,52 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Date Dates} to {@link Long Longs}.
+ *
+ * @author James Bognar ([email protected])
+ */
+public class DateLongTransform extends PojoTransform<Date,Long> {
+
+       /**
+        * Converts the specified {@link Date} to a {@link Long}.
+        */
+       @Override /* PojoTransform */
+       public Long transform(Date o) {
+               return o.getTime();
+       }
+
+       /**
+        * Converts the specified {@link Long} to a {@link Date}.
+        */
+       @Override /* PojoTransform */
+       public Date normalize(Long o, ClassMeta<?> hint) throws ParseException {
+               Class<?> c = (hint == null ? java.util.Date.class : 
hint.getInnerClass());
+               if (c == java.util.Date.class)
+                       return new java.util.Date(o);
+               if (c == java.sql.Date.class)
+                       return new java.sql.Date(o);
+               if (c == java.sql.Time.class)
+                       return new java.sql.Time(o);
+               if (c == java.sql.Timestamp.class)
+                       return new java.sql.Timestamp(o);
+               throw new ParseException("DateLongTransform is unable to narrow 
object of type ''{0}''", c);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/DateMapTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/DateMapTransform.java 
b/juneau-core/src/main/java/org/apache/juneau/transforms/DateMapTransform.java
new file mode 100644
index 0000000..3e34b5e
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/DateMapTransform.java
@@ -0,0 +1,56 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Date Dates} to {@link Map Maps} of the format 
<tt>{value:long}</tt>.
+ *
+ * @author James Bognar ([email protected])
+ */
+@SuppressWarnings("rawtypes")
+public class DateMapTransform extends PojoTransform<Date,Map> {
+
+       /**
+        * Converts the specified {@link Date} to a {@link Map}.
+        */
+       @Override /* PojoTransform */
+       public Map transform(Date o) {
+               ObjectMap m = new ObjectMap();
+               m.put("time", o.getTime());
+               return m;
+       }
+
+       /**
+        * Converts the specified {@link Map} to a {@link Date}.
+        */
+       @Override /* PojoTransform */
+       public Date normalize(Map o, ClassMeta<?> hint) throws ParseException {
+               Class<?> c = (hint == null ? java.util.Date.class : 
hint.getInnerClass());
+               long l = Long.parseLong(((Map<?,?>)o).get("time").toString());
+               if (c == java.util.Date.class)
+                       return new java.util.Date(l);
+               if (c == java.sql.Date.class)
+                       return new java.sql.Date(l);
+               if (c == java.sql.Time.class)
+                       return new java.sql.Time(l);
+               if (c == java.sql.Timestamp.class)
+                       return new java.sql.Timestamp(l);
+               throw new ParseException("DateMapTransform is unable to narrow 
object of type ''{0}''", c);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/DateTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/DateTransform.java 
b/juneau-core/src/main/java/org/apache/juneau/transforms/DateTransform.java
new file mode 100644
index 0000000..f38a52b
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/transforms/DateTransform.java
@@ -0,0 +1,370 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.text.*;
+import java.util.*;
+
+import javax.xml.bind.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.ParseException;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Date Dates} to {@link String Strings}.
+ *
+ *
+ * <h6 class='topic'>Behavior-specific subclasses</h6>
+ * <p>
+ *     The following direct subclasses are provided for convenience:
+ * <ul class='spaced-list'>
+ *     <li>{@link ToString} - Transforms to {@link String Strings} using the 
{@code Date.toString()} method.
+ *     <li>{@link ISO8601DT} - Transforms to ISO8601 date-time strings.
+ *     <li>{@link ISO8601DTP} - Transforms to ISO8601 date-time strings with 
millisecond precision.
+ *     <li>{@link ISO8601DTZ} - Same as {@link ISO8601DT}, except always 
serializes in GMT.
+ *     <li>{@link ISO8601DTZP} - Same as {@link ISO8601DTZ}, except with 
millisecond precision.
+ *     <li>{@link RFC2822DT} - Transforms to RFC2822 date-time strings.
+ *     <li>{@link RFC2822DTZ} - Same as {@link RFC2822DT}, except always 
serializes in GMT.
+ *     <li>{@link RFC2822D} - Transforms to RFC2822 date strings.
+ *     <li>{@link SimpleDT} - Transforms to simple <js>"yyyy/MM/dd 
HH:mm:ss"</js> strings.
+ *     <li>{@link SimpleT} - Transforms to simple <js>"yyyy/MM/dd 
HH:mm:ss"</js> strings.
+ *     <li>{@link Medium} - Transforms to {@link DateFormat#MEDIUM} strings.
+ * </ul>
+ *
+ *
+ * @author James Bognar ([email protected])
+ */
+public class DateTransform extends PojoTransform<Date,String> {
+
+       /**
+        * Transforms {@link Date Dates} to {@link String Strings} using the 
{@code Date.toString()} method.
+        * <p>
+        * <dl>
+        *      <dt>Example output:</dt>
+        *      <dd>
+        * <ul>
+        *      <li><js>"Wed Jul 04 15:30:45 EST 2001"</js>
+        * </ul>
+        *      </dd>
+        * </dl>
+        */
+       public static class ToString extends DateTransform {
+               /** Constructor */
+               public ToString() {
+                       super("EEE MMM dd HH:mm:ss zzz yyyy");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to ISO8601 date-time strings.
+        *
+        * <dl>
+        *      <dt>Example output:</dt>
+        *      <dd>
+        * <ul>
+        *      <li><js>"2001-07-04T15:30:45-05:00"</js>
+        *      <li><js>"2001-07-04T15:30:45Z"</js>
+        * </ul>
+        *      </dd>
+        *      <dt>Example input:</dt>
+        *      <dd>
+        * <ul>
+        *      <li><js>"2001-07-04T15:30:45-05:00"</js>
+        *      <li><js>"2001-07-04T15:30:45Z"</js>
+        *      <li><js>"2001-07-04T15:30:45.1Z"</js>
+        *      <li><js>"2001-07-04T15:30Z"</js>
+        *      <li><js>"2001-07-04"</js>
+        *      <li><js>"2001-07"</js>
+        *      <li><js>"2001"</js>
+        * </ul>
+        *      </dd>
+        * </dl>
+        */
+       public static class ISO8601DT extends DateTransform {
+               private SimpleDateFormat tzFormat = new SimpleDateFormat("Z");
+
+               /** Constructor */
+               public ISO8601DT() {
+                       this("yyyy-MM-dd'T'HH:mm:ss");
+               }
+
+               /**
+                * Constructor with specific pattern.
+                *
+                * @param pattern The {@link MessageFormat}-style format string.
+                */
+               protected ISO8601DT(String pattern) {
+                       super(pattern);
+               }
+
+               @Override /* PojoTransform */
+               public Date normalize(String o, ClassMeta<?> hint) throws 
ParseException {
+                       try {
+                               if (StringUtils.isEmpty(o))
+                                       return null;
+                               return 
convert(DatatypeConverter.parseDateTime(o).getTime(), hint);
+                       } catch (ParseException e) {
+                               throw e;
+                       } catch (Exception e) {
+                               throw new ParseException(e);
+                       }
+               }
+
+               @Override /* PojoTransform */
+               public String transform(Date o) {
+                       String s = super.transform(o);
+                       String tz = tzFormat.format(o);
+                       if (tz.equals("+0000"))
+                               return s + "Z";
+                       return s + tz.substring(0,3) + ':' + tz.substring(3);
+               }
+       }
+
+       /**
+        * Same as {@link ISO8601DT} except serializes to millisecond precision.
+        * <p>
+        * Example output: <js>"2001-07-04T15:30:45.123-05:00"</js>
+        */
+       public static class ISO8601DTP extends ISO8601DT {
+
+               /** Constructor */
+               public ISO8601DTP() {
+                       super("yyyy-MM-dd'T'HH:mm:ss.SSS");
+               }
+       }
+
+       /**
+        * Same as {@link ISO8601DT} except serializes to millisecond precision 
and doesn't include timezone.
+        * <p>
+        * Example output: <js>"2001-07-04T15:30:45.123"</js>
+        */
+       public static class ISO8601DTPNZ extends DateTransform {
+
+               /** Constructor */
+               public ISO8601DTPNZ() {
+                       super("yyyy-MM-dd'T'HH:mm:ss.SSS");
+               }
+       }
+
+       /**
+        * Same as {@link ISO8601DT}, except always serializes in GMT.
+        * <p>
+        * Example output:  <js>"2001-07-04T15:30:45Z"</js>
+        */
+       public static class ISO8601DTZ extends DateTransform {
+
+               /** Constructor */
+               public ISO8601DTZ() {
+                       this("yyyy-MM-dd'T'HH:mm:ss'Z'");
+               }
+
+               /**
+                * Constructor with specific pattern.
+                *
+                * @param pattern The {@link MessageFormat}-style format string.
+                */
+               protected ISO8601DTZ(String pattern) {
+                       super(pattern, "GMT");
+               }
+
+               @Override /* PojoTransform */
+               public Date normalize(String o, ClassMeta<?> hint) throws 
ParseException {
+                       try {
+                               if (StringUtils.isEmpty(o))
+                                       return null;
+                               return 
convert(DatatypeConverter.parseDateTime(o).getTime(), hint);
+                       } catch (ParseException e) {
+                               throw e;
+                       } catch (Exception e) {
+                               throw new ParseException(e);
+                       }
+               }
+       }
+
+       /**
+        * Same as {@link ISO8601DTZ} except serializes to millisecond 
precision.
+        * <p>
+        * Example output:  <js>"2001-07-04T15:30:45.123Z"</js>
+        */
+       public static class ISO8601DTZP extends ISO8601DT {
+
+               /** Constructor */
+               public ISO8601DTZP() {
+                       super("yyyy-MM-dd'T'HH:mm:ss.SSS");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to RFC2822 date-time strings.
+        */
+       public static class RFC2822DT extends DateTransform {
+               /** Constructor */
+               public RFC2822DT() {
+                       super("EEE, dd MMM yyyy HH:mm:ss z");
+               }
+       }
+
+       /**
+        * Same as {@link RFC2822DT}, except always serializes in GMT.
+        * <p>
+        * Example output:  <js>"2001-07-04T15:30:45Z"</js>
+        */
+       public static class RFC2822DTZ extends DateTransform {
+               /** Constructor */
+               public RFC2822DTZ() {
+                       super("EEE, dd MMM yyyy HH:mm:ss z", "GMT");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to RFC2822 date strings.
+        */
+       public static class RFC2822D extends DateTransform {
+               /** Constructor */
+               public RFC2822D() {
+                       super("dd MMM yyyy");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to simple <js>"yyyy/MM/dd 
HH:mm:ss"</js> strings.
+        */
+       public static class SimpleDT extends DateTransform {
+               /** Constructor */
+               public SimpleDT() {
+                       super("yyyy/MM/dd HH:mm:ss");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to simple <js>"yyyy/MM/dd 
HH:mm:ss.SSS"</js> strings.
+        */
+       public static class SimpleDTP extends DateTransform {
+               /** Constructor */
+               public SimpleDTP() {
+                       super("yyyy/MM/dd HH:mm:ss.SSS");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to simple <js>"HH:mm:ss"</js> strings.
+        */
+       public static class SimpleT extends DateTransform {
+               /** Constructor */
+               public SimpleT() {
+                       super("HH:mm:ss");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to simple <js>"HH:mm:ss.SSS"</js> 
strings.
+        */
+       public static class SimpleTP extends DateTransform {
+               /** Constructor */
+               public SimpleTP() {
+                       super("HH:mm:ss.SSS");
+               }
+       }
+
+       /**
+        * Transforms {@link Date Dates} to {@link DateFormat#MEDIUM} strings.
+        */
+       public static class Medium extends DateTransform {
+               /** Constructor */
+               public Medium() {
+                       super(DateFormat.getDateInstance(DateFormat.MEDIUM));
+               }
+       }
+
+       /** The formatter to convert dates to Strings. */
+       private DateFormat format;
+
+       /**
+        * Construct a transform using the specified date format string that 
will be
+        *      used to construct a {@link SimpleDateFormat} that will be used 
to convert
+        *      dates to strings.
+        *
+        * @param simpleDateFormat The {@link SimpleDateFormat} pattern.
+        */
+       public DateTransform(String simpleDateFormat) {
+               this(new SimpleDateFormat(simpleDateFormat));
+       }
+
+       /**
+        * Construct a transform using the specified date format string that 
will be
+        *      used to construct a {@link SimpleDateFormat} that will be used 
to convert
+        *      dates to strings.
+        *
+        * @param simpleDateFormat The {@link SimpleDateFormat} pattern.
+        * @param timeZone The time zone to associate with the date pattern.
+        */
+       public DateTransform(String simpleDateFormat, String timeZone) {
+               this(new SimpleDateFormat(simpleDateFormat));
+               format.setTimeZone(TimeZone.getTimeZone(timeZone));
+       }
+
+       /**
+        * Construct a transform using the specified {@link DateFormat} that 
will be used to convert
+        *      dates to strings.
+        *
+        * @param format The format to use to convert dates to strings.
+        */
+       public DateTransform(DateFormat format) {
+               super();
+               this.format = format;
+       }
+
+       /**
+        * Converts the specified {@link Date} to a {@link String}.
+        */
+       @Override /* PojoTransform */
+       public String transform(Date o) {
+               return format.format(o);
+       }
+
+       /**
+        * Converts the specified {@link String} to a {@link Date}.
+        */
+       @Override /* PojoTransform */
+       public Date normalize(String o, ClassMeta<?> hint) throws 
ParseException {
+               try {
+                       if (StringUtils.isEmpty(o))
+                               return null;
+                       Date d = format.parse(o);
+                       return convert(d, hint);
+               } catch (ParseException e) {
+                       throw e;
+               } catch (Exception e) {
+                       throw new ParseException(e);
+               }
+       }
+
+       private static Date convert(Date in, ClassMeta<?> hint) throws 
Exception {
+               if (in == null)
+                       return null;
+               if (hint == null || hint.isInstance(in))
+                       return in;
+               Class<?> c = hint.getInnerClass();
+               if (c == java.util.Date.class)
+                       return in;
+               if (c == java.sql.Date.class)
+                       return new java.sql.Date(in.getTime());
+               if (c == java.sql.Time.class)
+                       return new java.sql.Time(in.getTime());
+               if (c == java.sql.Timestamp.class)
+                       return new java.sql.Timestamp(in.getTime());
+               throw new ParseException("DateTransform is unable to narrow 
object of type ''{0}''", c);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/EnumerationTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/EnumerationTransform.java
 
b/juneau-core/src/main/java/org/apache/juneau/transforms/EnumerationTransform.java
new file mode 100644
index 0000000..6c3b124
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/EnumerationTransform.java
@@ -0,0 +1,39 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Enumeration Enumerations} to {@code List<Object>} objects.
+ * <p>
+ *     This is a one-way transform, since {@code Enumerations} cannot be 
reconstituted.
+ *
+ * @author James Bognar ([email protected])
+ */
+@SuppressWarnings({"unchecked","rawtypes"})
+public class EnumerationTransform extends PojoTransform<Enumeration,List> {
+
+       /**
+        * Converts the specified {@link Enumeration} to a {@link List}.
+        */
+       @Override /* PojoTransform */
+       public List transform(Enumeration o) {
+               List l = new LinkedList();
+               while (o.hasMoreElements())
+                       l.add(o.nextElement());
+               return l;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/IteratorTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/IteratorTransform.java 
b/juneau-core/src/main/java/org/apache/juneau/transforms/IteratorTransform.java
new file mode 100644
index 0000000..d5bfa77
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/IteratorTransform.java
@@ -0,0 +1,39 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link Iterator Iterators} to {@code List<Object>} objects.
+ * <p>
+ *     This is a one-way transform, since {@code Iterators} cannot be 
reconstituted.
+ *
+ * @author James Bognar ([email protected])
+ */
+@SuppressWarnings({"unchecked","rawtypes"})
+public class IteratorTransform extends PojoTransform<Iterator,List> {
+
+       /**
+        * Converts the specified {@link Iterator} to a {@link List}.
+        */
+       @Override /* PojoTransform */
+       public List transform(Iterator o) {
+               List l = new LinkedList();
+               while (o.hasNext())
+                       l.add(o.next());
+               return l;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/ReaderTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/ReaderTransform.java 
b/juneau-core/src/main/java/org/apache/juneau/transforms/ReaderTransform.java
new file mode 100644
index 0000000..77fb532
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/ReaderTransform.java
@@ -0,0 +1,112 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import java.io.*;
+
+import org.apache.juneau.html.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Transforms the contents of a {@link Reader} into an {@code Object}.
+ *
+ *
+ * <h6 class='topic'>Description</h6>
+ * <p>
+ *     The {@code Reader} must contain JSON, Juneau-generated XML (output from 
{@link XmlSerializer}),
+ *             or Juneau-generated HTML (output from {@link JsonSerializer}) 
in order to be parsed correctly.
+ * <p>
+ *     Useful for serializing models that contain {@code Readers} created by 
{@code RestCall} instances.
+ * <p>
+ *     This is a one-way transform, since {@code Readers} cannot be 
reconstituted.
+ *
+ *
+ * <h6 class='topic'>Behavior-specific subclasses</h6>
+ * <p>
+ *     The following direct subclasses are provided for convenience:
+ * <ul class='spaced-list'>
+ *     <li>{@link Json} - Parses JSON text.
+ *     <li>{@link Xml} - Parses XML text.
+ *     <li>{@link Html} - Parses HTML text.
+ *     <li>{@link PlainText} - Parses plain text.
+ * </ul>
+ *
+ *
+ * @author James Bognar ([email protected])
+ */
+public class ReaderTransform extends PojoTransform<Reader,Object> {
+
+       /** Reader transform for reading JSON text. */
+       public static class Json extends ReaderTransform {
+               /** Constructor */
+               public Json() {
+                       super(JsonParser.DEFAULT);
+               }
+       }
+
+       /** Reader transform for reading XML text. */
+       public static class Xml extends ReaderTransform {
+               /** Constructor */
+               public Xml() {
+                       super(XmlParser.DEFAULT);
+               }
+       }
+
+       /** Reader transform for reading HTML text. */
+       public static class Html extends ReaderTransform {
+               /** Constructor */
+               public Html() {
+                       super(HtmlParser.DEFAULT);
+               }
+       }
+
+       /** Reader transform for reading plain text. */
+       public static class PlainText extends ReaderTransform {
+               /** Constructor */
+               public PlainText() {
+                       super(null);
+               }
+       }
+
+       /** The parser to use to parse the contents of the Reader. */
+       private ReaderParser parser;
+
+       /**
+        * @param parser The parser to use to convert the contents of the 
reader to Java objects.
+        */
+       public ReaderTransform(ReaderParser parser) {
+               this.parser = parser;
+       }
+
+       /**
+        * Converts the specified {@link Reader} to an {@link Object} whose 
type is determined
+        * by the contents of the reader.
+        */
+       @Override /* PojoTransform */
+       public Object transform(Reader o) throws SerializeException {
+               try {
+                       if (parser == null)
+                               return IOUtils.read(o);
+                       return parser.parse(o, beanContext.object());
+               } catch (IOException e) {
+                       return e.getLocalizedMessage();
+               } catch (Exception e) {
+                       throw new SerializeException("ReaderTransform could not 
transform object of type ''{0}''", o == null ? null : 
o.getClass().getName()).initCause(e);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e6bf97a8/juneau-core/src/main/java/org/apache/juneau/transforms/XMLGregorianCalendarTransform.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/XMLGregorianCalendarTransform.java
 
b/juneau-core/src/main/java/org/apache/juneau/transforms/XMLGregorianCalendarTransform.java
new file mode 100644
index 0000000..ac56984
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transforms/XMLGregorianCalendarTransform.java
@@ -0,0 +1,64 @@
+/***************************************************************************************************************************
+ * 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.transforms;
+
+import javax.xml.datatype.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link XMLGregorianCalendar XMLGregorianCalendars} to ISO8601 
date-time {@link String Strings}.
+ * <p>
+ *     Objects are converted to strings using {@link 
XMLGregorianCalendar#toXMLFormat()}.
+ * <p>
+ *     Strings are converted to objects using {@link 
DatatypeFactory#newXMLGregorianCalendar(String)}.
+ *
+ * @author James Bognar ([email protected])
+ */
+public class XMLGregorianCalendarTransform extends 
PojoTransform<XMLGregorianCalendar,String> {
+
+       private DatatypeFactory dtf;
+
+       /**
+        * Constructor.
+        */
+       public XMLGregorianCalendarTransform() {
+               try {
+                       this.dtf = DatatypeFactory.newInstance();
+               } catch (DatatypeConfigurationException e) {
+                       throw new RuntimeException(e);
+               }
+       }
+
+       /**
+        * Converts the specified <code>XMLGregorianCalendar</code> to a {@link 
String}.
+        */
+       @Override /* PojoTransform */
+       public String transform(XMLGregorianCalendar b) throws 
SerializeException {
+               return b.toXMLFormat();
+       }
+
+       /**
+        * Converts the specified {@link String} to an 
<code>XMLGregorianCalendar</code>.
+        */
+       @Override /* PojoTransform */
+       public XMLGregorianCalendar normalize(String s, ClassMeta<?> hint) 
throws ParseException {
+               if (StringUtils.isEmpty(s))
+                       return null;
+               return dtf.newXMLGregorianCalendar(s);
+       }
+}
\ 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/transforms/package.html
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transforms/package.html 
b/juneau-core/src/main/java/org/apache/juneau/transforms/package.html
new file mode 100644
index 0000000..65016d3
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/transforms/package.html
@@ -0,0 +1,66 @@
+<!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>Predefined Transform implementations</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="PredefinedTransforms"></a><h2 class='topic'>1 - Predefined transform 
support</h2>
+<p>
+       This package contains various predefined instances of transforms for 
commonly-serialized/parsed class types.
+</p>
+<p>
+       See {@link org.apache.juneau.transform} for more information about 
transforms.
+</p>
+</body>

Reply via email to