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 <[email protected]>
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);
}
/**