This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new b29fc42  Javadocs.
b29fc42 is described below

commit b29fc42e42d1ec43188b3f2350088e78155a817d
Author: JamesBognar <jamesbog...@apache.org>
AuthorDate: Mon Jul 2 16:42:49 2018 -0400

    Javadocs.
---
 .../juneau/httppart/HttpPartSchemaTest_Body.java   |   8 +-
 .../httppart/HttpPartSchemaTest_FormData.java      |   8 +-
 .../juneau/httppart/HttpPartSchemaTest_Header.java |   8 +-
 .../juneau/httppart/HttpPartSchemaTest_Path.java   |   8 +-
 .../juneau/httppart/HttpPartSchemaTest_Query.java  |   8 +-
 .../httppart/HttpPartSchemaTest_Response.java      |   8 +-
 .../HttpPartSchemaTest_ResponseHeader.java         |   8 +-
 .../juneau/httppart/OpenApiPartParserTest.java     | 439 +++++++++++++++++++++
 .../main/java/org/apache/juneau/BeanSession.java   |  51 ++-
 .../src/main/java/org/apache/juneau/ClassMeta.java |  58 ++-
 .../org/apache/juneau/httppart/HttpPartSchema.java | 141 ++++++-
 .../apache/juneau/httppart/OpenApiPartParser.java  |  84 +++-
 .../org/apache/juneau/internal/StringUtils.java    |  19 +-
 13 files changed, 805 insertions(+), 43 deletions(-)

diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
index 4318149..0a7242e 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
@@ -47,7 +47,7 @@ public class HttpPartSchemaTest_Body {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A02.class).noValidate().build();
                assertTrue(s.getRequired());
                
assertObjectEquals("{description:'b1\\nb2',example:'f1',required:true,schema:{'$ref':'c1'},_value:'{g1:true}'}",
 s.getApi());
        }
@@ -68,7 +68,7 @@ public class HttpPartSchemaTest_Body {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A03.class.getMethod("a", String.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A03.class.getMethod("a", String.class), 0).noValidate().build();
                assertTrue(s.getRequired());
                
assertObjectEquals("{description:'b1\\nb2',example:'f1',required:true,schema:{'$ref':'c1'},_value:'{g1:true}'}",
 s.getApi());
        }
@@ -89,7 +89,7 @@ public class HttpPartSchemaTest_Body {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A04.class.getMethod("a", A02.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A04.class.getMethod("a", A02.class), 0).noValidate().build();
                assertNull(s.getRequired());
                
assertObjectEquals("{description:'b3\\nb3',example:'f2',schema:{'$ref':'c3'},_value:'{g2:true}'}",
 s.getApi());
        }
@@ -173,7 +173,7 @@ public class HttpPartSchemaTest_Body {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Body.class, 
A05.class).noValidate().build();
 
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
index c492f3f..d8c125a 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
@@ -75,7 +75,7 @@ public class HttpPartSchemaTest_FormData {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, A02.class).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -132,7 +132,7 @@ public class HttpPartSchemaTest_FormData {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, A03.class.getMethod("a", 
String.class), 0).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, A03.class.getMethod("a", 
String.class), 0).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -189,7 +189,7 @@ public class HttpPartSchemaTest_FormData {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, A04.class.getMethod("a", 
A01.class), 0).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, A04.class.getMethod("a", 
A01.class), 0).noValidate().build();
                assertEquals("y", s.getName());
                assertEquals(HttpPartSchema.Type.INTEGER, s.getType());
                assertEquals(HttpPartSchema.Format.INT64, s.getFormat());
@@ -291,7 +291,7 @@ public class HttpPartSchemaTest_FormData {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(FormData.class, A05.class).noValidate().build();
                assertEquals("x", s.getName());
 
                HttpPartSchema items = s.getItems();
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
index aab298f..eb4bc39 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
@@ -75,7 +75,7 @@ public class HttpPartSchemaTest_Header {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A02.class).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -132,7 +132,7 @@ public class HttpPartSchemaTest_Header {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A03.class.getMethod("a", String.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A03.class.getMethod("a", String.class), 0).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -189,7 +189,7 @@ public class HttpPartSchemaTest_Header {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A04.class.getMethod("a", A01.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A04.class.getMethod("a", A01.class), 0).noValidate().build();
                assertEquals("y", s.getName());
                assertEquals(HttpPartSchema.Type.INTEGER, s.getType());
                assertEquals(HttpPartSchema.Format.INT64, s.getFormat());
@@ -291,7 +291,7 @@ public class HttpPartSchemaTest_Header {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Header.class, 
A05.class).noValidate().build();
                assertEquals("x", s.getName());
 
                HttpPartSchema items = s.getItems();
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
index ee0f017..2f855e0 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
@@ -69,7 +69,7 @@ public class HttpPartSchemaTest_Path {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A02.class).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -114,7 +114,7 @@ public class HttpPartSchemaTest_Path {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A03.class.getMethod("a", String.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A03.class.getMethod("a", String.class), 0).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -159,7 +159,7 @@ public class HttpPartSchemaTest_Path {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A04.class.getMethod("a", A01.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A04.class.getMethod("a", A01.class), 0).noValidate().build();
                assertEquals("y", s.getName());
                assertEquals(HttpPartSchema.Type.INTEGER, s.getType());
                assertEquals(HttpPartSchema.Format.INT64, s.getFormat());
@@ -255,7 +255,7 @@ public class HttpPartSchemaTest_Path {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Path.class, 
A05.class).noValidate().build();
                assertEquals("x", s.getName());
 
                HttpPartSchema items = s.getItems();
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
index d45eeb8..0afebbc 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
@@ -75,7 +75,7 @@ public class HttpPartSchemaTest_Query {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A02.class).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -132,7 +132,7 @@ public class HttpPartSchemaTest_Query {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A03.class.getMethod("a", String.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A03.class.getMethod("a", String.class), 0).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -189,7 +189,7 @@ public class HttpPartSchemaTest_Query {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A04.class.getMethod("a", A01.class), 0).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A04.class.getMethod("a", A01.class), 0).noValidate().build();
                assertEquals("y", s.getName());
                assertEquals(HttpPartSchema.Type.INTEGER, s.getType());
                assertEquals(HttpPartSchema.Format.INT64, s.getFormat());
@@ -291,7 +291,7 @@ public class HttpPartSchemaTest_Query {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = HttpPartSchema.create().apply(Query.class, 
A05.class).noValidate().build();
                assertEquals("x", s.getName());
 
                HttpPartSchema items = s.getItems();
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
index 8a94af9..52688ad 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
@@ -46,7 +46,7 @@ public class HttpPartSchemaTest_Response {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, A02.class).noValidate().build();
                
assertObjectEquals("{description:'b1\\nb2',example:'f1',schema:{'$ref':'c1'},_value:'{g1:true}'}",
 s.getApi());
        }
 
@@ -65,7 +65,7 @@ public class HttpPartSchemaTest_Response {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, A03.class.getMethod("a", 
String.class), 0).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, A03.class.getMethod("a", 
String.class), 0).noValidate().build();
                
assertObjectEquals("{description:'b1\\nb2',example:'f1',schema:{'$ref':'c1'},_value:'{g1:true}'}",
 s.getApi());
        }
 
@@ -84,7 +84,7 @@ public class HttpPartSchemaTest_Response {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, A04.class.getMethod("a", 
A02.class), 0).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, A04.class.getMethod("a", 
A02.class), 0).noValidate().build();
                
assertObjectEquals("{description:'b3\\nb3',example:'f2',schema:{'$ref':'c3'},_value:'{g2:true}'}",
 s.getApi());
        }
 
@@ -167,7 +167,7 @@ public class HttpPartSchemaTest_Response {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(Response.class, A05.class).noValidate().build();
 
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
index 485f503..ef1ec7c 100644
--- 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
@@ -73,7 +73,7 @@ public class HttpPartSchemaTest_ResponseHeader {
 
        @Test
        public void a02_basic_onClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, 
A02.class).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, 
A02.class).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -126,7 +126,7 @@ public class HttpPartSchemaTest_ResponseHeader {
 
        @Test
        public void a03_basic_onParameter() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, A03.class.getMethod("a", 
String.class), 0).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, A03.class.getMethod("a", 
String.class), 0).noValidate().build();
                assertEquals("x", s.getName());
                assertEquals(HttpPartSchema.Type.NUMBER, s.getType());
                assertEquals(HttpPartSchema.Format.INT32, s.getFormat());
@@ -179,7 +179,7 @@ public class HttpPartSchemaTest_ResponseHeader {
 
        @Test
        public void a04_basic_onParameterAndClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, A04.class.getMethod("a", 
A01.class), 0).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, A04.class.getMethod("a", 
A01.class), 0).noValidate().build();
                assertEquals("y", s.getName());
                assertEquals(HttpPartSchema.Type.INTEGER, s.getType());
                assertEquals(HttpPartSchema.Format.INT64, s.getFormat());
@@ -281,7 +281,7 @@ public class HttpPartSchemaTest_ResponseHeader {
 
        @Test
        public void a05_basic_nestedItems_onClass() throws Exception {
-               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, 
A05.class).noValidate(true).build();
+               HttpPartSchema s = 
HttpPartSchema.create().apply(ResponseHeader.class, 
A05.class).noValidate().build();
                assertEquals("x", s.getName());
 
                HttpPartSchema items = s.getItems();
diff --git 
a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java
 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java
new file mode 100644
index 0000000..44d668b
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java
@@ -0,0 +1,439 @@
+// 
***************************************************************************************************************************
+// * 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.httppart;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.internal.*;
+import org.junit.*;
+
+public class OpenApiPartParserTest {
+
+       static OpenApiPartParser p = OpenApiPartParser.DEFAULT;
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Input validations
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Test
+       public void a01_inputValidations_nullInput() throws Exception {
+               HttpPartSchema s = HttpPartSchema.create().build();
+               assertNull(p.parse(s, null, String.class));
+
+               s = HttpPartSchema.create().required(false).build();
+               assertNull(p.parse(s, null, String.class));
+
+               s = HttpPartSchema.create().required().build();
+               try {
+                       p.parse(s, null, String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("No value specified.", e.getMessage());
+               }
+
+               s = HttpPartSchema.create().required(true).build();
+               try {
+                       p.parse(s, null, String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("No value specified.", e.getMessage());
+               }
+       }
+
+       @Test
+       public void a02_inputValidations_emptyInput() throws Exception {
+
+               HttpPartSchema s = 
HttpPartSchema.create().allowEmptyValue().build();
+               assertEquals("", p.parse(s, "", String.class));
+
+               s = HttpPartSchema.create().allowEmptyValue().build();
+               assertEquals("", p.parse(s, "", String.class));
+
+               s = HttpPartSchema.create().allowEmptyValue(false).build();
+               try {
+                       p.parse(s, "", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Empty value not allowed.", 
e.getMessage());
+               }
+
+               try {
+                       p.parse(s, "", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Empty value not allowed.", 
e.getMessage());
+               }
+
+               assertEquals(" ", p.parse(s, " ", String.class));
+       }
+
+       @Test
+       public void a03_inputValidations_pattern() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().pattern("x.*").allowEmptyValue().build();
+               assertEquals("x", p.parse(s, "x", String.class));
+               assertEquals("xx", p.parse(s, "xx", String.class));
+               assertEquals(null, p.parse(s, null, String.class));
+
+               try {
+                       p.parse(s, "y", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match expected pattern.  
Must match pattern: x.*", e.getMessage());
+               }
+
+               try {
+                       p.parse(s, "", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match expected pattern.  
Must match pattern: x.*", e.getMessage());
+               }
+
+               // Blank/null patterns are ignored.
+               s = 
HttpPartSchema.create().pattern("").allowEmptyValue().build();
+               assertEquals("x", p.parse(s, "x", String.class));
+               s = 
HttpPartSchema.create().pattern(null).allowEmptyValue().build();
+               assertEquals("x", p.parse(s, "x", String.class));
+       }
+
+       @Test
+       public void a04_inputValidations_enum() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create()._enum("foo").allowEmptyValue().build();
+
+               assertEquals("foo", p.parse(s, "foo", String.class));
+               assertEquals(null, p.parse(s, null, String.class));
+
+               try {
+                       p.parse(s, "bar", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match one of the expected 
values.  Must be one of the following: ['foo']", e.getMessage());
+               }
+
+               try {
+                       p.parse(s, "", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match one of the expected 
values.  Must be one of the following: ['foo']", e.getMessage());
+               }
+
+               s = HttpPartSchema.create()._enum((Set<String>)null).build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+               s = 
HttpPartSchema.create()._enum((Set<String>)null).allowEmptyValue().build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+
+               s = HttpPartSchema.create()._enum("foo","foo").build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+       }
+
+       @Test
+       public void a05_inputValidations_minMaxLength() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().minLength(1l).maxLength(2l).allowEmptyValue().build();
+
+               assertEquals(null, p.parse(s, null, String.class));
+               assertEquals("1", p.parse(s, "1", String.class));
+               assertEquals("12", p.parse(s, "12", String.class));
+
+               try {
+                       p.parse(s, "", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Minimum length of value not met.", 
e.getMessage());
+               }
+
+               try {
+                       p.parse(s, "123", String.class);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Maximum length of value exceeded.", 
e.getMessage());
+               }
+
+               try {
+                       s = 
HttpPartSchema.create().minLength(2l).maxLength(1l).build();
+                       fail();
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("maxLength cannot be 
less than minLength."));
+               }
+
+               try {
+                       s = HttpPartSchema.create().minLength(-1l).build();
+                       fail();
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("minLength cannot be 
less than zero."));
+               }
+
+               try {
+                       s = HttpPartSchema.create().maxLength(-1l).build();
+                       fail();
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("maxLength cannot be 
less than zero."));
+               }
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Primitive defaults
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Test
+       public void b01_primitiveDefaults() throws Exception {
+
+               assertEquals(null, p.parse(null, null, Boolean.class));
+               assertEquals(false, p.parse(null, null, boolean.class));
+               assertEquals(null, p.parse(null, null, Character.class));
+               assertEquals("\0", p.parse(null, null, char.class).toString());
+               assertEquals(null, p.parse(null, null, Short.class));
+               assertEquals(0, p.parse(null, null, short.class).intValue());
+               assertEquals(null, p.parse(null, null, Integer.class));
+               assertEquals(0, p.parse(null, null, int.class).intValue());
+               assertEquals(null, p.parse(null, null, Long.class));
+               assertEquals(0, p.parse(null, null, long.class).intValue());
+               assertEquals(null, p.parse(null, null, Float.class));
+               assertEquals(0, p.parse(null, null, float.class).intValue());
+               assertEquals(null, p.parse(null, null, Double.class));
+               assertEquals(0, p.parse(null, null, double.class).intValue());
+               assertEquals(null, p.parse(null, null, Byte.class));
+               assertEquals(0, p.parse(null, null, byte.class).intValue());
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = string
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Test
+       public void c01_stringType_simple() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+       }
+
+       @Test
+       public void c02_stringType_default() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string")._default("x").build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+               assertEquals("x", p.parse(s, null, String.class));
+       }
+
+       public static class C3 {
+               private String f;
+               public C3(byte[] b) {
+                       f = new String(b);
+               }
+               @Override
+               public String toString() {
+                       return f;
+               }
+       }
+
+       @Test
+       public void c03_stringType_byteFormat() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").format("byte").build();
+               String in = StringUtils.base64Encode("foo".getBytes());
+               assertEquals("foo", p.parse(s, in, String.class));
+               assertEquals("foo", IOUtils.read(p.parse(s, in, 
InputStream.class)));
+               assertEquals("foo", IOUtils.read(p.parse(s, in, Reader.class)));
+               assertEquals("foo", p.parse(s, in, C3.class).toString());
+       }
+
+       @Test
+       public void c04_stringType_binaryFormat() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").format("binary").build();
+               String in = StringUtils.toHex("foo".getBytes());
+               assertEquals("foo", p.parse(s, in, String.class));
+               assertEquals("foo", IOUtils.read(p.parse(s, in, 
InputStream.class)));
+               assertEquals("foo", IOUtils.read(p.parse(s, in, Reader.class)));
+               assertEquals("foo", p.parse(s, in, C3.class).toString());
+       }
+
+       @Test
+       public void c05_stringType_binarySpacedFormat() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").format("binary-spaced").build();
+               String in = StringUtils.toSpacedHex("foo".getBytes());
+               assertEquals("foo", p.parse(s, in, String.class));
+               assertEquals("foo", IOUtils.read(p.parse(s, in, 
InputStream.class)));
+               assertEquals("foo", IOUtils.read(p.parse(s, in, Reader.class)));
+               assertEquals("foo", p.parse(s, in, C3.class).toString());
+       }
+
+       @Test
+       public void c06_stringType_dateFormat() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").format("date").build();
+               String in = "2012-12-21";
+               assertTrue(p.parse(s, in, String.class).contains("2012"));
+               assertTrue(p.parse(s, in, 
Date.class).toString().contains("2012"));
+               assertEquals(2012, p.parse(s, in, 
Calendar.class).get(Calendar.YEAR));
+               assertEquals(2012, p.parse(s, in, 
GregorianCalendar.class).get(Calendar.YEAR));
+       }
+
+       @Test
+       public void c07_stringType_dateTimeFormat() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").format("date-time").build();
+               String in = "2012-12-21T12:34:56.789";
+               assertTrue(p.parse(s, in, String.class).contains("2012"));
+               assertTrue(p.parse(s, in, 
Date.class).toString().contains("2012"));
+               assertEquals(2012, p.parse(s, in, 
Calendar.class).get(Calendar.YEAR));
+               assertEquals(2012, p.parse(s, in, 
GregorianCalendar.class).get(Calendar.YEAR));
+       }
+
+       public static class C8 {
+               private String f;
+               public C8(String s) {
+                       f = s;
+               }
+               @Override
+               public String toString() {
+                       return f;
+               }
+       }
+
+       @Test
+       public void c08_stringType_uonFormat() throws Exception {
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").format("uon").build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+               assertEquals("foo", p.parse(s, "'foo'", String.class));
+               assertEquals("foo", p.parse(s, "'foo'", C8.class).toString());
+               assertEquals("C8", p.parse(s, "'foo'", 
C8.class).getClass().getSimpleName());
+               // UonPartParserTest should handle all other cases.
+       }
+
+       @Test
+       public void c08_stringType_noneFormat() throws Exception {
+               // If no format is specified, then we should transform directly 
from a string.
+               HttpPartSchema s = 
HttpPartSchema.create().type("string").build();
+               assertEquals("foo", p.parse(s, "foo", String.class));
+               assertEquals("'foo'", p.parse(s, "'foo'", String.class));
+               assertEquals("foo", p.parse(s, "foo", C8.class).toString());
+               assertEquals("C8", p.parse(s, "foo", 
C8.class).getClass().getSimpleName());
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = array
+       
//-----------------------------------------------------------------------------------------------------------------
+
+//     case ARRAY: {
+//     if (type.isObject())
+//             type = (ClassMeta<T>)getClassMeta(ObjectList.class);
+//
+//     ClassMeta<?> eType = type.isObject() ? string() : type.getElementType();
+//     if (eType == null)
+//             throw new ParseException("Value of type ARRAY cannot be 
converted to type {0}", type);
+//
+//     String[] ss = new String[0];
+//     switch (schema.getCollectionFormat()) {
+//             case MULTI:
+//                     ss = new String[]{in};
+//                     break;
+//             case CSV:
+//                     ss = split(in, ',');
+//                     break;
+//             case PIPES:
+//                     ss = split(in, '|');
+//                     break;
+//             case SSV:
+//                     ss = splitQuoted(in);
+//                     break;
+//             case TSV:
+//                     ss = split(in, '\t');
+//                     break;
+//             case UON:
+//                     return super.parse(partType, null, in, type);
+//             case NONE:
+//                     if (firstNonWhitespaceChar(in) == '@' && 
lastNonWhitespaceChar(in) == ')')
+//                             return super.parse(partType, null, in, type);
+//                     ss = split(in, ',');
+//     }
+//     Object[] o = null;
+//     if (schema.getItems() != null) {
+//             o = new Object[ss.length];
+//             for (int i = 0; i < ss.length; i++)
+//                     o[i] = parse(partType, schema.getItems(), ss[i], eType);
+//     } else {
+//             o = ss;
+//     }
+//     return toType(o, type);
+//}
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = boolean
+       
//-----------------------------------------------------------------------------------------------------------------
+
+//     case BOOLEAN: {
+//     if (type.isObject())
+//             type = (ClassMeta<T>)getClassMeta(Boolean.class);
+//     return super.parse(partType, schema, in, type);
+//}
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = integer
+       
//-----------------------------------------------------------------------------------------------------------------
+
+
+//                             case INTEGER: {
+//                                     if (type.isObject()) {
+//                                             switch (schema.getFormat()) {
+//                                                     case INT64:
+//                                                             type = 
(ClassMeta<T>)getClassMeta(Long.class);
+//                                                             break;
+//                                                     default:
+//                                                             type = 
(ClassMeta<T>)getClassMeta(Integer.class);
+//
+//                                             }
+//                                     }
+//                                     return super.parse(partType, schema, 
in, type);
+//                             }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = number
+       
//-----------------------------------------------------------------------------------------------------------------
+//                             case NUMBER: {
+//                                     if (type.isObject()) {
+//                                             switch (schema.getFormat()) {
+//                                                     case DOUBLE:
+//                                                             type = 
(ClassMeta<T>)getClassMeta(Double.class);
+//                                                             break;
+//                                                     default:
+//                                                             type = 
(ClassMeta<T>)getClassMeta(Float.class);
+//                                             }
+//                                     }
+//                                     return super.parse(partType, schema, 
in, type);
+//                             }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = object
+       
//-----------------------------------------------------------------------------------------------------------------
+//                             case OBJECT: {
+//                                     if (type.isObject())
+//                                             type = 
(ClassMeta<T>)getClassMeta(ObjectMap.class);
+//                                     switch (schema.getFormat()) {
+//                                             default:
+//                                                     return 
super.parse(partType, schema, in, type);
+//                                     }
+//                             }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = file
+       
//-----------------------------------------------------------------------------------------------------------------
+//                             case FILE: {
+//                                     throw new ParseException("File part not 
supported.");
+//                             }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // type = none
+       
//-----------------------------------------------------------------------------------------------------------------
+//                             case NONE: {
+//                                     throw new ParseException("Invalid 
type.");
+//                             }
+//                     }
+//             }
+
+}
\ No newline at end of file
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 1f42e35..8c7fba9 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -17,8 +17,10 @@ import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
 
+import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
+import java.util.Date;
 import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.http.*;
@@ -585,7 +587,9 @@ public class BeanSession extends Session {
                        }
 
                        if (type.isString()) {
-                               if (vt.isMapOrBean() || 
vt.isCollectionOrArray()) {
+                               if (vt.isByteArray()) {
+                                       return (T) new String((byte[])value);
+                               } else if (vt.isMapOrBean() || 
vt.isCollectionOrArray()) {
                                        if (JsonSerializer.DEFAULT_LAX != null)
                                                return 
(T)JsonSerializer.DEFAULT_LAX.serialize(value);
                                } else if (vt.isClass()) {
@@ -630,12 +634,57 @@ public class BeanSession extends Session {
                                return newBeanMap(tc).load((Map<?,?>) 
value).getBean();
                        }
 
+                       if (type.isInputStream()) {
+                               if (vt.isByteArray()) {
+                                       byte[] b = (byte[])value;
+                                       return (T) new ByteArrayInputStream(b, 
0, b.length);
+                               }
+                               byte[] b = value.toString().getBytes();
+                               return (T)new ByteArrayInputStream(b, 0, 
b.length);
+                       }
+
+                       if (type.isReader()) {
+                               if (vt.isByteArray()) {
+                                       byte[] b = (byte[])value;
+                                       return (T) new StringReader(new 
String(b));
+                               }
+                               return (T)new StringReader(value.toString());
+                       }
+
                        if (type.canCreateNewInstanceFromNumber(outer) && value 
instanceof Number)
                                return type.newInstanceFromNumber(this, outer, 
(Number)value);
 
                        if (type.canCreateNewInstanceFromString(outer))
                                return type.newInstanceFromString(outer, 
value.toString());
 
+                       if (type.isCalendar()) {
+                               if (vt.isCalendar()) {
+                                       Calendar c = (Calendar)value;
+                                       if (value instanceof GregorianCalendar) 
{
+                                               GregorianCalendar c2 = new 
GregorianCalendar(c.getTimeZone());
+                                               c2.setTime(c.getTime());
+                                               return (T)c2;
+                                       }
+                               }
+                               if (vt.isDate()) {
+                                       Date d = (Date)value;
+                                       if (value instanceof GregorianCalendar) 
{
+                                               GregorianCalendar c2 = new 
GregorianCalendar(TimeZone.getDefault());
+                                               c2.setTime(d);
+                                               return (T)c2;
+                                       }
+                               }
+                       }
+
+                       if (type.isDate() && type.getInnerClass() == 
Date.class) {
+                               if (vt.isCalendar())
+                                       return (T)((Calendar)value).getTime();
+                       }
+
+                       Transform t = type.getTransform(value.getClass());
+                       if (t != null)
+                               return (T) t.transform(value);
+
                        if (type.isBean())
                                return 
newBeanMap(type.getInnerClass()).load(value.toString()).getBean();
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index e16bee9..0a4b1c6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -119,6 +119,7 @@ public final class ClassMeta<T> implements Type {
        private final BeanRegistry beanRegistry;                // The bean 
registry of this class meta (if it has one).
        private final ClassMeta<?>[] args;                      // Arg types if 
this is an array of args.
        private final Object example;                          // Example 
object.
+       private final Map<Class<?>,Transform<?,T>> transforms = new 
ConcurrentHashMap<>();
        private final Transform<Reader,T> readerTransform;
        private final Transform<InputStream,T> inputStreamTransform;
        private final Transform<String,T> stringTransform;
@@ -1184,6 +1185,15 @@ public final class ClassMeta<T> implements Type {
        }
 
        /**
+        * Returns <jk>true</jk> if this class is <code><jk>byte</jk>[]</code>.
+        *
+        * @return <jk>true</jk> if this class is <code><jk>byte</jk>[]</code>.
+        */
+       public boolean isByteArray() {
+               return cc == ARRAY && this.innerClass == byte[].class;
+       }
+
+       /**
         * Returns <jk>true</jk> if this class is {@link Class}.
         *
         * @return <jk>true</jk> if this class is {@link Class}.
@@ -1369,11 +1379,29 @@ public final class ClassMeta<T> implements Type {
         *
         * @return <jk>true</jk> if this class is a {@link Date} or {@link 
Calendar}.
         */
-       public boolean isDate() {
+       public boolean isDateOrCalendar() {
                return cc == DATE;
        }
 
        /**
+        * Returns <jk>true</jk> if this class is a {@link Date}.
+        *
+        * @return <jk>true</jk> if this class is a {@link Date}.
+        */
+       public boolean isDate() {
+               return cc == DATE && ClassUtils.isParentClass(Date.class, 
innerClass);
+       }
+
+       /**
+        * Returns <jk>true</jk> if this class is a {@link Calendar}.
+        *
+        * @return <jk>true</jk> if this class is a {@link Calendar}.
+        */
+       public boolean isCalendar() {
+               return cc == DATE && ClassUtils.isParentClass(Calendar.class, 
innerClass);
+       }
+
+       /**
         * Returns <jk>true</jk> if this class is a {@link URI} or {@link URL}.
         *
         * @return <jk>true</jk> if this class is a {@link URI} or {@link URL}.
@@ -2053,7 +2081,7 @@ public final class ClassMeta<T> implements Type {
         * @return <jk>true</jk> if this class has a transform associated with 
it that allows it to be created from a Reader.
         */
        public boolean hasReaderTransform() {
-               return readerTransform != null;
+               return getTransform(Reader.class) != null;
        }
 
        /**
@@ -2062,7 +2090,7 @@ public final class ClassMeta<T> implements Type {
         * @return The transform, or <jk>null</jk> if no such transform exists.
         */
        public Transform<Reader,T> getReaderTransform() {
-               return readerTransform;
+               return getTransform(Reader.class);
        }
 
        /**
@@ -2071,7 +2099,7 @@ public final class ClassMeta<T> implements Type {
         * @return <jk>true</jk> if this class has a transform associated with 
it that allows it to be created from an InputStream.
         */
        public boolean hasInputStreamTransform() {
-               return inputStreamTransform != null;
+               return getTransform(InputStream.class) != null;
        }
 
        /**
@@ -2080,7 +2108,7 @@ public final class ClassMeta<T> implements Type {
         * @return The transform, or <jk>null</jk> if no such transform exists.
         */
        public Transform<InputStream,T> getInputStreamTransform() {
-               return inputStreamTransform;
+               return getTransform(InputStream.class);
        }
 
        /**
@@ -2100,4 +2128,24 @@ public final class ClassMeta<T> implements Type {
        public Transform<String,T> getStringTransform() {
                return stringTransform;
        }
+
+       /**
+        * Returns the transform for this class for creating instances from 
other object types.
+        *
+        * @param c The transform-from class.
+        * @return The transform, or <jk>null</jk> if no such transform exists.
+        */
+       @SuppressWarnings({ "rawtypes", "unchecked" })
+       public <I> Transform<I,T> getTransform(Class<I> c) {
+               Transform t = transforms.get(c);
+               if (t == TransformCache.NULL)
+                       return null;
+               if (t == null) {
+                       t = TransformCache.get(c, innerClass);
+                       if (t == null)
+                               t = TransformCache.NULL;
+                       transforms.put(c, t);
+               }
+               return t == TransformCache.NULL ? null : t;
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
index 8e4a65f..66619c4 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
@@ -268,7 +268,7 @@ public class HttpPartSchema {
                                notAllowed.appendIf(maxItems != null, 
"maxItems");
                                notAllowed.appendIf(minItems != null, 
"minItems");
                                notAllowed.appendIf(minProperties != null, 
"minProperties");
-                               invalidFormat = ! format.isOneOf(Format.BYTE, 
Format.BINARY, Format.DATE, Format.DATE_TIME, Format.PASSWORD, Format.UON, 
Format.NONE);
+                               invalidFormat = ! format.isOneOf(Format.BYTE, 
Format.BINARY, Format.BINARY_SPACED, Format.DATE, Format.DATE_TIME, 
Format.PASSWORD, Format.UON, Format.NONE);
                                break;
                        }
                        case ARRAY: {
@@ -375,6 +375,26 @@ public class HttpPartSchema {
                        errors.add("Cannot specify exclusiveMinimum with 
minimum.");
                if (required != null && required && _default != null)
                        errors.add("Cannot specify a default value on a 
required value.");
+               if (minLength != null && maxLength != null && maxLength < 
minLength)
+                       errors.add("maxLength cannot be less than minLength.");
+               if (minimum != null && maximum != null && maximum.doubleValue() 
< minimum.doubleValue())
+                       errors.add("maximum cannot be less than minimum.");
+               if (minItems != null && maxItems != null && maxItems < minItems)
+                       errors.add("maxItems cannot be less than minItems.");
+               if (minProperties != null && maxProperties != null && 
maxProperties < minProperties)
+                       errors.add("maxProperties cannot be less than 
minProperties.");
+               if (minLength != null && minLength < 0)
+                       errors.add("minLength cannot be less than zero.");
+               if (maxLength != null && maxLength < 0)
+                       errors.add("maxLength cannot be less than zero.");
+               if (minItems != null && minItems < 0)
+                       errors.add("minItems cannot be less than zero.");
+               if (maxItems != null && maxItems < 0)
+                       errors.add("maxItems cannot be less than zero.");
+               if (minProperties != null && minProperties < 0)
+                       errors.add("minProperties cannot be less than zero.");
+               if (maxProperties != null && maxProperties < 0)
+                       errors.add("maxProperties cannot be less than zero.");
 
                if (! errors.isEmpty())
                        throw new ContextRuntimeException("Schema specification 
errors: \n\t" + join(errors, "\n\t"));
@@ -819,6 +839,18 @@ public class HttpPartSchema {
                }
 
                /**
+                * <mk>required</mk> field.
+                *
+                * <p>
+                * Shortcut for calling <code>required(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder required() {
+                       return required(true);
+               }
+
+               /**
                 * <mk>type</mk> field.
                 *
                 * <p>
@@ -918,6 +950,10 @@ public class HttpPartSchema {
                 *              <br>Only valid with type <js>"string"</js>.
                 *              <br>Parameters of type POJO convertible from 
string are converted after the string has been decoded.
                 *      <li>
+                *              <js>"binary-spaced"</js> - Hexadecimal encoded 
octets, spaced (e.g. <js>"00 FF"</js>).
+                *              <br>Only valid with type <js>"string"</js>.
+                *              <br>Parameters of type POJO convertible from 
string are converted after the string has been decoded.
+                *      <li>
                 *              <js>"date"</js> - An <a 
href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 
full-date</a>.
                 *              <br>Only valid with type <js>"string"</js>.
                 *      <li>
@@ -987,6 +1023,18 @@ public class HttpPartSchema {
                }
 
                /**
+                * <mk>allowEmptyValue</mk> field.
+                *
+                * <p>
+                * Shortcut for calling 
<code>allowEmptyValue(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder allowEmptyValue() {
+                       return allowEmptyValue(true);
+               }
+
+               /**
                 * <mk>items</mk> field.
                 *
                 * <p>
@@ -1170,6 +1218,18 @@ public class HttpPartSchema {
                }
 
                /**
+                * <mk>exclusiveMaximum</mk> field.
+                *
+                * <p>
+                * Shortcut for calling 
<code>exclusiveMaximum(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder exclusiveMaximum() {
+                       return exclusiveMaximum(true);
+               }
+
+               /**
                 * <mk>minimum</mk> field.
                 *
                 * <p>
@@ -1229,6 +1289,18 @@ public class HttpPartSchema {
                }
 
                /**
+                * <mk>exclusiveMinimum</mk> field.
+                *
+                * <p>
+                * Shortcut for calling 
<code>exclusiveMinimum(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder exclusiveMinimum() {
+                       return exclusiveMinimum(true);
+               }
+
+               /**
                 * <mk>maxLength</mk> field.
                 *
                 * <p>
@@ -1413,6 +1485,18 @@ public class HttpPartSchema {
                }
 
                /**
+                * <mk>uniqueItems</mk> field.
+                *
+                * <p>
+                * Shortcut for calling 
<code>uniqueItems(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder uniqueItems() {
+                       return uniqueItems(true);
+               }
+
+               /**
                 * Identifies whether an item should be skipped if it's empty.
                 *
                 * @param value
@@ -1427,6 +1511,18 @@ public class HttpPartSchema {
                }
 
                /**
+                * Identifies whether an item should be skipped if it's empty.
+                *
+                * <p>
+                * Shortcut for calling 
<code>skipIfEmpty(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder skipIfEmpty() {
+                       return skipIfEmpty(true);
+               }
+
+               /**
                 * <mk>enum</mk> field.
                 *
                 * <p>
@@ -1443,16 +1539,31 @@ public class HttpPartSchema {
                 *
                 * @param value
                 *      The new value for this property.
-                *      <br>Ignored if value is <jk>null</jk>.
+                *      <br>Ignored if value is <jk>null</jk> or an empty set.
                 * @return This object (for method chaining).
                 */
                public Builder _enum(Set<String> value) {
-                       if (value != null)
+                       if (value != null && ! value.isEmpty())
                                this._enum = value;
                        return this;
                }
 
                /**
+                * <mk>_enum</mk> field.
+                *
+                * <p>
+                * Same as {@link #_enum(Set)} but takes in a var-args array.
+                *
+                * @param values
+                *      The new values for this property.
+                *      <br>Ignored if value is empty.
+                * @return This object (for method chaining).
+                */
+               public Builder _enum(String...values) {
+                       return _enum(new ASet<String>().appendAll(values));
+               }
+
+               /**
                 * <mk>multipleOf</mk> field.
                 *
                 * <p>
@@ -1593,13 +1704,26 @@ public class HttpPartSchema {
                /**
                 * Disables Swagger schema usage validation checking.
                 *
-                * @param noValidate Specify <jk>true</jk> to prevent {@link 
ContextRuntimeException} from being thrown if invalid Swagger usage was 
detected.
+                * @param value Specify <jk>true</jk> to prevent {@link 
ContextRuntimeException} from being thrown if invalid Swagger usage was 
detected.
                 * @return This object (for method chaining).
                 */
-               public Builder noValidate(boolean noValidate) {
-                       this.noValidate = noValidate;
+               public Builder noValidate(Boolean value) {
+                       if (value != null)
+                               this.noValidate = value;
                        return this;
                }
+
+               /**
+                * Disables Swagger schema usage validation checking.
+                *
+                * <p>
+                * Shortcut for calling <code>noValidate(<jk>true</jk>);</code>.
+                *
+                * @return This object (for method chaining).
+                */
+               public Builder noValidate() {
+                       return noValidate(true);
+               }
        }
 
        /**
@@ -1744,6 +1868,11 @@ public class HttpPartSchema {
                BINARY,
 
                /**
+                * Spaced-separated hexadecimal encoded octets (e.g. <js>"00 
FF"</js>).
+                */
+               BINARY_SPACED,
+
+               /**
                 * An <a 
href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 
full-date</a>.
                 */
                DATE,
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
index 90532ba..70e7cc5 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
@@ -14,12 +14,71 @@ package org.apache.juneau.httppart;
 
 import static org.apache.juneau.internal.StringUtils.*;
 
+import java.io.*;
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
 
 /**
  * OpenAPI part parser.
+ *
+ * <table class='styled'>
+ *     <tr><th>Type</th><th>Format</th><th>Valid parameter types</th></tr>
+ *     <tr>
+ *             <td ><code>string</code></td>
+ *             <td>
+ *                     <code>byte</code>
+ *                     <br><code>binary</code>
+ *                     <br><code>binary-spaced</br>
+ *             </td>
+ *             <td>
+ *                     <ul>
+ *                             <li><code><jk>byte</jk>[]</code>
+ *                             <li>{@link InputStream} - Returns a {@link 
ByteArrayInputStream}.
+ *                             <li>{@link Reader} - Returns a {@link 
InputStreamReader} wrapped around a {@link ByteArrayInputStream}.
+ *                             <li>{@link String} - Constructed using {@link 
String#String(byte[])}.
+ *                             <li>Any POJO transformable from a 
<code><jk>byte</jk>[]</code> (via constructors or static create methods).
+ *                     </ul>
+ *             </td>
+ *     </tr>
+ *     <tr>
+ *             <td ><code>string</code></td>
+ *             <td>
+ *                     <code>date</code>
+ *                     <code>date-time</code>
+ *             </td>
+ *             <td>
+ *                     <ul>
+ *                             <li>{@link Calendar}
+ *                             <li>{@link Date}
+ *                             <li>{@link GregorianCalendar}
+ *                             <li>{@link String} - Converted using {@link 
Calendar#toString()}.
+ *                             <li>Any POJO transformable from a {@link 
Calendar} (via constructors or static create methods).
+ *                     </ul>
+ *             </td>
+ *     </tr>
+ *     <tr>
+ *             <td ><code>string</code></td>
+ *             <td><code>uon</code></td>
+ *             <td>
+ *                     <ul>
+ *                             <li>Any <a 
href='../../../../overview-summary#juneau-marshall.PojoCategories'>parsable 
POJO</a>.
+ *                     </ul>
+ *             </td>
+ *     </tr>
+ *     <tr>
+ *             <td ><code>string</code></td>
+ *             <td>none specified</td>
+ *             <td>
+ *                     <ul>
+ *                             <li>{@link String}
+ *                             <li>Any POJO transformable from a {@link 
String} (via constructors or static create methods).
+ *                     </ul>
+ *             </td>
+ *     </tr>
+ * </table>
  */
 public class OpenApiPartParser extends UonPartParser {
 
@@ -98,6 +157,23 @@ public class OpenApiPartParser extends UonPartParser {
                return new UonPartParserBuilder();
        }
 
+       /**
+        * Convenience method for parsing a part.
+        *
+        * @param schema
+        *      Schema information about the part.
+        *      <br>May be <jk>null</jk>.
+        *      <br>Not all part parsers use the schema information.
+        * @param in The input being parsed.
+        * @param type The category of value being parsed.
+        * @return The parsed value.
+        * @throws ParseException If a problem occurred while trying to parse 
the input.
+        * @throws SchemaValidationParseException If the input or resulting 
HTTP part object fails schema validation.
+        */
+       public <T> T parse(HttpPartSchema schema, String in, Class<T> type) 
throws ParseException, SchemaValidationParseException {
+               return parse(null, schema, in, 
BeanContext.DEFAULT.getClassMeta(type));
+       }
+
        @Override /* HttpPartParser */
        public <T> T parse(HttpPartType partType, HttpPartSchema schema, String 
in, ClassMeta<T> type) throws ParseException, SchemaValidationParseException {
                schema = ObjectUtils.firstNonNull(schema, this.schema, 
HttpPartSchema.DEFAULT);
@@ -124,9 +200,11 @@ public class OpenApiPartParser extends UonPartParser {
                                                                return 
(T)StringUtils.base64Decode(in);
                                                        case DATE:
                                                        case DATE_TIME:
-                                                               return 
(T)StringUtils.parseIsoDate(in);
+                                                               return 
(T)StringUtils.parseIsoCalendar(in);
                                                        case BINARY:
                                                                return 
(T)StringUtils.fromHex(in);
+                                                       case BINARY_SPACED:
+                                                               return 
(T)StringUtils.fromSpacedHex(in);
                                                        case UON:
                                                                return 
super.parse(partType, schema, in, type);
                                                        default:
@@ -138,9 +216,11 @@ public class OpenApiPartParser extends UonPartParser {
                                                        return 
toType(StringUtils.base64Decode(in), type);
                                                case DATE:
                                                case DATE_TIME:
-                                                       return 
toType(StringUtils.parseIsoDate(in), type);
+                                                       return 
toType(StringUtils.parseIsoCalendar(in), type);
                                                case BINARY:
                                                        return 
toType(StringUtils.fromHex(in), type);
+                                               case BINARY_SPACED:
+                                                       return 
toType(StringUtils.fromSpacedHex(in), type);
                                                case UON:
                                                        return 
super.parse(partType, schema, in, type);
                                                default:
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 9b0c980..72816ff 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -1193,6 +1193,23 @@ public final class StringUtils {
        public static Date parseIsoDate(String date) throws 
IllegalArgumentException {
                if (isEmpty(date))
                        return null;
+               return parseIsoCalendar(date).getTime();
+       }
+
+       /**
+        * Parses an ISO8601 string into a calendar.
+        *
+        * <p>
+        * Supports any of the following formats:
+        * <br><code>yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, 
yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS</code>
+        *
+        * @param date The date string.
+        * @return The parsed calendar.
+        * @throws IllegalArgumentException
+        */
+       public static Calendar parseIsoCalendar(String date) throws 
IllegalArgumentException {
+               if (isEmpty(date))
+                       return null;
                date = date.trim().replace(' ', 'T');  // Convert to 'standard' 
ISO8601
                if (date.indexOf(',') != -1)  // Trim milliseconds
                        date = date.substring(0, date.indexOf(','));
@@ -1206,7 +1223,7 @@ public final class StringUtils {
                        date += ":00:00";
                else if 
(date.matches("\\d{4}\\-\\d{2}\\-\\d{2}T\\d{2}\\:\\d{2}"))
                        date += ":00";
-               return DatatypeConverter.parseDateTime(date).getTime();
+               return DatatypeConverter.parseDateTime(date);
        }
 
        /**

Reply via email to