From commits-return-5357-archive-asf-public=cust-asf.ponee.io@juneau.apache.org Thu Jul 5 22:57:08 2018 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id B6D5B18072F for ; Thu, 5 Jul 2018 22:57:05 +0200 (CEST) Received: (qmail 68648 invoked by uid 500); 5 Jul 2018 20:57:04 -0000 Mailing-List: contact commits-help@juneau.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@juneau.apache.org Delivered-To: mailing list commits@juneau.apache.org Received: (qmail 68631 invoked by uid 99); 5 Jul 2018 20:57:04 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 05 Jul 2018 20:57:04 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 0A046809F6; Thu, 5 Jul 2018 20:57:04 +0000 (UTC) Date: Thu, 05 Jul 2018 20:57:03 +0000 To: "commits@juneau.apache.org" Subject: [juneau] branch master updated: Implement OpenApiPartSerializer MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Message-ID: <153082422397.2749.15156399584461943683@gitbox.apache.org> From: jamesbognar@apache.org X-Git-Host: gitbox.apache.org X-Git-Repo: juneau X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: ec054fd83a3049acea3991e169858b137a96e1b0 X-Git-Newrev: 8abfc7027cbffd7ab2474dfe6d3bbdc8a90e4555 X-Git-Rev: 8abfc7027cbffd7ab2474dfe6d3bbdc8a90e4555 X-Git-NotificationType: ref_changed_plus_diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated 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 8abfc70 Implement OpenApiPartSerializer 8abfc70 is described below commit 8abfc7027cbffd7ab2474dfe6d3bbdc8a90e4555 Author: JamesBognar AuthorDate: Thu Jul 5 16:56:49 2018 -0400 Implement OpenApiPartSerializer --- .../juneau/httppart/OpenApiPartSerializerTest.java | 1079 ++++++++++++++++++++ .../main/java/org/apache/juneau/BeanSession.java | 5 +- .../src/main/java/org/apache/juneau/ClassMeta.java | 36 +- .../org/apache/juneau/httppart/HttpPartSchema.java | 2 +- .../apache/juneau/httppart/OpenApiPartParser.java | 18 +- .../juneau/httppart/OpenApiPartSerializer.java | 280 +++-- .../org/apache/juneau/internal/StringUtils.java | 20 + .../apache/juneau/rest/BasicRestCallHandler.java | 7 + .../java/org/apache/juneau/rest/RestContext.java | 46 +- .../org/apache/juneau/rest/RestContextBuilder.java | 20 + .../juneau/rest/annotation/RestResource.java | 25 + 11 files changed, 1363 insertions(+), 175 deletions(-) diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java new file mode 100644 index 0000000..7289117 --- /dev/null +++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java @@ -0,0 +1,1079 @@ +// *************************************************************************************************************************** +// * 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.util.*; + +import org.junit.*; + +public class OpenApiPartSerializerTest { + + static OpenApiPartSerializer s = OpenApiPartSerializer.DEFAULT; + + //----------------------------------------------------------------------------------------------------------------- + // Input validations + //----------------------------------------------------------------------------------------------------------------- + + @Test + public void a01_outputValidations_nullOutput() throws Exception { + HttpPartSchema ps = schema().build(); + assertNull(s.serialize(ps, null)); + + ps = schema().required(false).build(); + assertNull(s.serialize(ps, null)); + + ps = schema().required().build(); + try { + s.serialize(ps, null); + fail(); + } catch (Exception e) { + assertEquals("Required value not provided.", e.getMessage()); + } + + ps = schema().required(true).build(); + try { + s.serialize(ps, null); + fail(); + } catch (Exception e) { + assertEquals("Required value not provided.", e.getMessage()); + } + } + + @Test + public void a02_outputValidations_emptyOutput() throws Exception { + + HttpPartSchema ps = schema().allowEmptyValue().build(); + assertEquals("", s.serialize(ps, "")); + + ps = schema().allowEmptyValue().build(); + assertEquals("", s.serialize(ps, "")); + + ps = schema().allowEmptyValue(false).build(); + try { + s.serialize(ps, ""); + fail(); + } catch (Exception e) { + assertEquals("Empty value not allowed.", e.getMessage()); + } + + try { + s.serialize(ps, ""); + fail(); + } catch (Exception e) { + assertEquals("Empty value not allowed.", e.getMessage()); + } + + assertEquals(" ", s.serialize(ps, " ")); + } + + @Test + public void a03_outputValidations_pattern() throws Exception { + HttpPartSchema ps = schema().pattern("x.*").allowEmptyValue().build(); + assertEquals("x", s.serialize(ps, "x")); + assertEquals("xx", s.serialize(ps, "xx")); + assertEquals(null, s.serialize(ps, null)); + + try { + s.serialize(ps, "y"); + fail(); + } catch (Exception e) { + assertEquals("Value does not match expected pattern. Must match pattern: x.*", e.getMessage()); + } + + try { + s.serialize(ps, ""); + fail(); + } catch (Exception e) { + assertEquals("Value does not match expected pattern. Must match pattern: x.*", e.getMessage()); + } + + // Blank/null patterns are ignored. + ps = schema().pattern("").allowEmptyValue().build(); + assertEquals("x", s.serialize(ps, "x")); + ps = schema().pattern(null).allowEmptyValue().build(); + assertEquals("x", s.serialize(ps, "x")); + } + + @Test + public void a04_outputValidations_enum() throws Exception { + HttpPartSchema ps = schema()._enum("foo").allowEmptyValue().build(); + + assertEquals("foo", s.serialize(ps, "foo")); + assertEquals(null, s.serialize(ps, null)); + + try { + s.serialize(ps, "bar"); + fail(); + } catch (Exception e) { + assertEquals("Value does not match one of the expected values. Must be one of the following: ['foo']", e.getMessage()); + } + + try { + s.serialize(ps, ""); + fail(); + } catch (Exception e) { + assertEquals("Value does not match one of the expected values. Must be one of the following: ['foo']", e.getMessage()); + } + + ps = schema()._enum((Set)null).build(); + assertEquals("foo", s.serialize(ps, "foo")); + ps = schema()._enum((Set)null).allowEmptyValue().build(); + assertEquals("foo", s.serialize(ps, "foo")); + + ps = schema()._enum("foo","foo").build(); + assertEquals("foo", s.serialize(ps, "foo")); + } + + @Test + public void a05_outputValidations_minMaxLength() throws Exception { + HttpPartSchema ps = schema().minLength(1l).maxLength(2l).allowEmptyValue().build(); + + assertEquals(null, s.serialize(ps, null)); + assertEquals("1", s.serialize(ps, "1")); + assertEquals("12", s.serialize(ps, "12")); + + try { + s.serialize(ps, ""); + fail(); + } catch (Exception e) { + assertEquals("Minimum length of value not met.", e.getMessage()); + } + + try { + s.serialize(ps, "123"); + fail(); + } catch (Exception e) { + assertEquals("Maximum length of value exceeded.", e.getMessage()); + } + } + +// //----------------------------------------------------------------------------------------------------------------- +// // type = string +// //----------------------------------------------------------------------------------------------------------------- +// +// public static class C1 { +// private String f; +// public C1(byte[] b) { +// f = "C1-" + new String(b); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class C2 { +// private String f; +// public C2(String s) { +// f = "C2-" + s; +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class C3 { +// private String f; +// public C3(String[] in) { +// f = "C3-" + JsonSerializer.DEFAULT_LAX.toString(in); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// +// @Test +// public void c01_stringType_simple() throws Exception { +// HttpPartSchema ps = schema("string").build(); +// assertEquals("foo", s.serialize(ps, "foo", String.class)); +// } +// +// @Test +// public void c02_stringType_default() throws Exception { +// HttpPartSchema ps = schema("string")._default("x").build(); +// assertEquals("foo", s.serialize(ps, "foo", String.class)); +// assertEquals("x", s.serialize(ps, null, String.class)); +// } +// +// @Test +// public void c03_stringType_byteFormat() throws Exception { +// HttpPartSchema ps = schema("string", "byte").build(); +// String in = base64Encode("foo".getBytes()); +// assertEquals("foo", s.serialize(ps, in, String.class)); +// assertEquals("foo", IOUtils.read(s.serialize(ps, in, InputStream.class))); +// assertEquals("foo", IOUtils.read(s.serialize(ps, in, Reader.class))); +// assertEquals("C1-foo", s.serialize(ps, in, C1.class).toString()); +// } +// +// @Test +// public void c04_stringType_binaryFormat() throws Exception { +// HttpPartSchema ps = schema("string", "binary").build(); +// String in = toHex("foo".getBytes()); +// assertEquals("foo", s.serialize(ps, in, String.class)); +// assertEquals("foo", IOUtils.read(s.serialize(ps, in, InputStream.class))); +// assertEquals("foo", IOUtils.read(s.serialize(ps, in, Reader.class))); +// assertEquals("C1-foo", s.serialize(ps, in, C1.class).toString()); +// } +// +// @Test +// public void c05_stringType_binarySpacedFormat() throws Exception { +// HttpPartSchema ps = schema("string", "binary-spaced").build(); +// String in = toSpacedHex("foo".getBytes()); +// assertEquals("foo", s.serialize(ps, in, String.class)); +// assertEquals("foo", IOUtils.read(s.serialize(ps, in, InputStream.class))); +// assertEquals("foo", IOUtils.read(s.serialize(ps, in, Reader.class))); +// assertEquals("C1-foo", s.serialize(ps, in, C1.class).toString()); +// } +// +// @Test +// public void c06_stringType_dateFormat() throws Exception { +// HttpPartSchema ps = schema("string", "date").build(); +// String in = "2012-12-21"; +// assertTrue(s.serialize(ps, in, String.class).contains("2012")); +// assertTrue(s.serialize(ps, in, Date.class).toString().contains("2012")); +// assertEquals(2012, s.serialize(ps, in, Calendar.class).get(Calendar.YEAR)); +// assertEquals(2012, s.serialize(ps, in, GregorianCalendar.class).get(Calendar.YEAR)); +// } +// +// @Test +// public void c07_stringType_dateTimeFormat() throws Exception { +// HttpPartSchema ps = schema("string", "date-time").build(); +// String in = "2012-12-21T12:34:56.789"; +// assertTrue(s.serialize(ps, in, String.class).contains("2012")); +// assertTrue(s.serialize(ps, in, Date.class).toString().contains("2012")); +// assertEquals(2012, s.serialize(ps, in, Calendar.class).get(Calendar.YEAR)); +// assertEquals(2012, s.serialize(ps, in, GregorianCalendar.class).get(Calendar.YEAR)); +// } +// +// @Test +// public void c08_stringType_uonFormat() throws Exception { +// HttpPartSchema ps = schema("string", "uon").build(); +// assertEquals("foo", s.serialize(ps, "foo", String.class)); +// assertEquals("foo", s.serialize(ps, "'foo'", String.class)); +// assertEquals("C2-foo", s.serialize(ps, "'foo'", C2.class).toString()); +// // UonPartParserTest should handle all other cases. +// } +// +// @Test +// public void c09_stringType_noneFormat() throws Exception { +// // If no format is specified, then we should transform directly from a string. +// HttpPartSchema ps = schema("string").build(); +// assertEquals("foo", s.serialize(ps, "foo", String.class)); +// assertEquals("'foo'", s.serialize(ps, "'foo'", String.class)); +// assertEquals("C2-foo", s.serialize(ps, "foo", C2.class).toString()); +// } +// +// @Test +// public void c10_stringType_noneFormat_2d() throws Exception { +// HttpPartSchema ps = schema("array").items(schema("string")).build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", Object[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", List.class, Object.class)); +// Object o = s.serialize(ps, "foo,bar", Object.class); +// assertObjectEquals("['foo','bar']", o); +// assertClass(ObjectList.class, o); +// assertObjectEquals("['C2-foo','C2-bar']", s.serialize(ps, "foo,bar", C2[].class)); +// assertObjectEquals("['C2-foo','C2-bar']", s.serialize(ps, "foo,bar", List.class, C2.class)); +// assertEquals("C3-['foo','bar']", s.serialize(ps, "foo,bar", C3.class).toString()); +// } +// +// @Test +// public void c11_stringType_noneFormat_3d() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("string"))).build(); +// assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, "foo,bar|baz", String[][].class)); +// assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, "foo,bar|baz", List.class, String[].class)); +// assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, "foo,bar|baz", List.class, List.class, String.class)); +// assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, "foo,bar|baz", Object[][].class)); +// assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, "foo,bar|baz", List.class, Object[].class)); +// assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, "foo,bar|baz", List.class, List.class, Object.class)); +// Object o = s.serialize(ps, "foo,bar|baz", Object.class); +// assertObjectEquals("[['foo','bar'],['baz']]", o); +// assertClass(ObjectList.class, o); +// assertObjectEquals("[['C2-foo','C2-bar'],['C2-baz']]", s.serialize(ps, "foo,bar|baz", C2[][].class)); +// assertObjectEquals("[['C2-foo','C2-bar'],['C2-baz']]", s.serialize(ps, "foo,bar|baz", List.class, C2[].class)); +// assertObjectEquals("[['C2-foo','C2-bar'],['C2-baz']]", s.serialize(ps, "foo,bar|baz", List.class, List.class, C2.class)); +// assertObjectEquals("['C3-[\\'foo\\',\\'bar\\']','C3-[\\'baz\\']']", s.serialize(ps, "foo,bar|baz", C3[].class)); +// assertObjectEquals("['C3-[\\'foo\\',\\'bar\\']','C3-[\\'baz\\']']", s.serialize(ps, "foo,bar|baz", List.class, C3.class)); +// } +// +// //----------------------------------------------------------------------------------------------------------------- +// // type = array +// //----------------------------------------------------------------------------------------------------------------- +// +// public static class D { +// private String f; +// public D(String in) { +// this.f = "D-" + in; +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// @Test +// public void d01_arrayType_collectionFormatCsv() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("csv").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo,bar", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo,bar", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", Object.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", ObjectList.class)); +// } +// +// @Test +// public void d02_arrayType_collectionFormatPipes() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo|bar", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo|bar", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", Object.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", ObjectList.class)); +// } +// +// @Test +// public void d03_arrayType_collectionFormatSsv() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("ssv").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo bar", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo bar", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", Object.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", ObjectList.class)); +// } +// +// @Test +// public void d04_arrayType_collectionFormatTsv() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("tsv").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo\tbar", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo\tbar", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", Object.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", ObjectList.class)); +// } +// +// @Test +// public void d05_arrayType_collectionFormatUon() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("uon").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "@(foo,bar)", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "@(foo,bar)", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", Object.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", ObjectList.class)); +// } +// +// @Test +// public void d06a_arrayType_collectionFormatNone() throws Exception { +// HttpPartSchema ps = schema("array").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo,bar", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo,bar", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", Object.class)); +// } +// +// @Test +// public void d06b_arrayType_collectionFormatNone_autoDetectUon() throws Exception { +// HttpPartSchema ps = schema("array").build(); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", String[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", Object[].class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "@(foo,bar)", D[].class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", List.class, String.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", List.class, Object.class)); +// assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "@(foo,bar)", List.class, D.class)); +// assertObjectEquals("['foo','bar']", s.serialize(ps, "@(foo,bar)", Object.class)); +// } +// +// @Test +// public void d07_arrayType_collectionFormatMulti() throws Exception { +// // collectionFormat=multi should not do any sort of splitting. +// HttpPartSchema ps = schema("array").collectionFormat("multi").build(); +// assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", String[].class)); +// assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", Object[].class)); +// assertObjectEquals("['D-foo,bar']", s.serialize(ps, "foo,bar", D[].class)); +// assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", List.class, String.class)); +// assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", List.class, Object.class)); +// assertObjectEquals("['D-foo,bar']", s.serialize(ps, "foo,bar", List.class, D.class)); +// assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", Object.class)); +// } +// +// @Test +// public void d08_arrayType_collectionFormatCsvAndPipes() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").collectionFormat("csv")).build(); +// assertObjectEquals("[['foo','bar'],['baz','qux']]", s.serialize(ps, "foo,bar|baz,qux", String[][].class)); +// assertObjectEquals("[['foo','bar'],['baz','qux']]", s.serialize(ps, "foo,bar|baz,qux", Object[][].class)); +// assertObjectEquals("[['D-foo','D-bar'],['D-baz','D-qux']]", s.serialize(ps, "foo,bar|baz,qux", D[][].class)); +// assertObjectEquals("[['foo','bar'],['baz','qux']]", s.serialize(ps, "foo,bar|baz,qux", List.class, List.class, String.class)); +// assertObjectEquals("[['foo','bar'],['baz','qux']]", s.serialize(ps, "foo,bar|baz,qux", List.class, List.class, Object.class)); +// assertObjectEquals("[['D-foo','D-bar'],['D-baz','D-qux']]", s.serialize(ps, "foo,bar|baz,qux", List.class, List.class, D.class)); +// assertObjectEquals("[['foo','bar'],['baz','qux']]", s.serialize(ps, "foo,bar|baz,qux", Object.class)); +// } +// +// @Test +// public void d09_arrayType_itemsInteger() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("csv").items(schema("integer")).build(); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", int[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Integer[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Object[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Integer.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Object.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Object.class)); +// } +// +// //----------------------------------------------------------------------------------------------------------------- +// // type = boolean +// //----------------------------------------------------------------------------------------------------------------- +// +// public static class E1 { +// private String f; +// public E1(Boolean in) { +// this.f = "E1-" + in.toString(); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class E2 { +// private String f; +// public E2(Boolean[] in) { +// this.f = "E2-" + JsonSerializer.DEFAULT_LAX.toString(in); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// @Test +// public void e01_booleanType() throws Exception { +// HttpPartSchema ps = schema("boolean").build(); +// assertEquals(true, s.serialize(ps, "true", boolean.class)); +// assertEquals(true, s.serialize(ps, "true", Boolean.class)); +// assertEquals(true, s.serialize(ps, "True", boolean.class)); +// assertEquals(true, s.serialize(ps, "TRUE", boolean.class)); +// assertEquals("true", s.serialize(ps, "true", String.class)); +// assertEquals(true, s.serialize(ps, "true", Object.class)); +// assertObjectEquals("'E1-true'", s.serialize(ps, "true", E1.class)); +// } +// +// @Test +// public void e02_booleanType_2d() throws Exception { +// HttpPartSchema ps = schema("array").items(schema("boolean")).build(); +// assertObjectEquals("[true,true]", s.serialize(ps, "true,true", boolean[].class)); +// assertObjectEquals("[true,true]", s.serialize(ps, "true,true", Boolean[].class)); +// assertObjectEquals("[true,true]", s.serialize(ps, "true,true", List.class, Boolean.class)); +// assertObjectEquals("['true','true']", s.serialize(ps, "true,true", String[].class)); +// assertObjectEquals("['true','true']", s.serialize(ps, "true,true", List.class, String.class)); +// assertObjectEquals("[true,true]", s.serialize(ps, "true,true", Object[].class)); +// assertObjectEquals("[true,true]", s.serialize(ps, "true,true", List.class, Object.class)); +// assertObjectEquals("['E1-true','E1-true']", s.serialize(ps, "true,true", E1[].class)); +// assertObjectEquals("['E1-true','E1-true']", s.serialize(ps, "true,true", List.class, E1.class)); +// assertObjectEquals("'E2-[true,true]'", s.serialize(ps, "true,true", E2.class)); +// +// assertObjectEquals("[true,true]", s.serialize(ps, "True,true", boolean[].class)); +// assertObjectEquals("[true,true]", s.serialize(ps, "TRUE,true", boolean[].class)); +// } +// +// @Test +// public void e03_booleanType_3d() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("boolean"))).build(); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", boolean[][].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", List.class, boolean[].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", Boolean[][].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", List.class, Boolean[].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", List.class, List.class, Boolean.class)); +// assertObjectEquals("[['true','true'],['false']]", s.serialize(ps, "true,true|false", String[][].class)); +// assertObjectEquals("[['true','true'],['false']]", s.serialize(ps, "true,true|false", List.class, List.class, String.class)); +// assertObjectEquals("[['true','true'],['false']]", s.serialize(ps, "true,true|false", List.class, String[].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", Object[][].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", List.class, List.class, Object.class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "true,true|false", List.class, Object[].class)); +// assertObjectEquals("[['E1-true','E1-true'],['E1-false']]", s.serialize(ps, "true,true|false", E1[][].class)); +// assertObjectEquals("[['E1-true','E1-true'],['E1-false']]", s.serialize(ps, "true,true|false", List.class, List.class, E1.class)); +// assertObjectEquals("[['E1-true','E1-true'],['E1-false']]", s.serialize(ps, "true,true|false", List.class, E1[].class)); +// assertObjectEquals("['E2-[true,true]','E2-[false]']", s.serialize(ps, "true,true|false", E2[].class)); +// assertObjectEquals("['E2-[true,true]','E2-[false]']", s.serialize(ps, "true,true|false", List.class, E2.class)); +// +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "True,true|false", boolean[][].class)); +// assertObjectEquals("[[true,true],[false]]", s.serialize(ps, "TRUE,true|false", boolean[][].class)); +// } +// +// //----------------------------------------------------------------------------------------------------------------- +// // type = integer +// //----------------------------------------------------------------------------------------------------------------- +// +// public static class F1 { +// private String f; +// public F1(Integer in) { +// this.f = "F1-" + in.toString(); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class F2 { +// private String f; +// public F2(Integer[] in) { +// this.f = "F2-" + JsonSerializer.DEFAULT_LAX.toString(in); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class F3 { +// private String f; +// public F3(Long in) { +// this.f = "F3-" + in.toString(); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class F4 { +// private String f; +// public F4(Long[] in) { +// this.f = "F4-" + JsonSerializer.DEFAULT_LAX.toString(in); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// @Test +// public void f01_integerType_int32() throws Exception { +// HttpPartSchema ps = schema("integer", "int32").build(); +// assertObjectEquals("1", s.serialize(ps, "1", int.class)); +// assertObjectEquals("1", s.serialize(ps, "1", Integer.class)); +// assertObjectEquals("1", s.serialize(ps, "1", short.class)); +// assertObjectEquals("1", s.serialize(ps, "1", Short.class)); +// assertObjectEquals("1", s.serialize(ps, "1", long.class)); +// assertObjectEquals("1", s.serialize(ps, "1", Long.class)); +// assertObjectEquals("'1'", s.serialize(ps, "1", String.class)); +// Object o = s.serialize(ps, "1", Object.class); +// assertObjectEquals("1", o); +// assertClass(Integer.class, o); +// assertObjectEquals("'F1-1'", s.serialize(ps, "1", F1.class)); +// } +// +// @Test +// public void f02_integerType_int32_2d() throws Exception { +// HttpPartSchema ps = schema("array").items(schema("integer", "int32")).build(); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", int[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Integer[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Integer.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", short[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Short[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Short.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", long[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Long[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Long.class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", String[].class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", List.class, String.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Object[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Object.class)); +// assertObjectEquals("['F1-1','F1-2']", s.serialize(ps, "1,2", F1[].class)); +// assertObjectEquals("['F1-1','F1-2']", s.serialize(ps, "1,2", List.class, F1.class)); +// assertObjectEquals("'F2-[1,2]'", s.serialize(ps, "1,2", F2.class)); +// } +// +// @Test +// public void f03_integerType_int32_3d() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("integer", "int32"))).build(); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", int[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, int[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Integer[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Integer[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Integer.class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", short[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, short[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Short[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Short[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Short.class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", long[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, long[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Long[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Long[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Long.class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", String[][].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, String[].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, List.class, String.class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Object[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Object[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Object.class)); +// assertObjectEquals("[['F1-1','F1-2'],['F1-3']]", s.serialize(ps, "1,2|3", F1[][].class)); +// assertObjectEquals("[['F1-1','F1-2'],['F1-3']]", s.serialize(ps, "1,2|3", List.class, F1[].class)); +// assertObjectEquals("[['F1-1','F1-2'],['F1-3']]", s.serialize(ps, "1,2|3", List.class, List.class, F1.class)); +// assertObjectEquals("['F2-[1,2]','F2-[3]']", s.serialize(ps, "1,2|3", F2[].class)); +// assertObjectEquals("['F2-[1,2]','F2-[3]']", s.serialize(ps, "1,2|3", List.class, F2.class)); +// } +// +// @Test +// public void f04_integerType_int64() throws Exception { +// HttpPartSchema ps = schema("integer", "int64").build(); +// assertObjectEquals("1", s.serialize(ps, "1", int.class)); +// assertObjectEquals("1", s.serialize(ps, "1", Integer.class)); +// assertObjectEquals("1", s.serialize(ps, "1", short.class)); +// assertObjectEquals("1", s.serialize(ps, "1", Short.class)); +// assertObjectEquals("1", s.serialize(ps, "1", long.class)); +// assertObjectEquals("1", s.serialize(ps, "1", Long.class)); +// assertObjectEquals("'1'", s.serialize(ps, "1", String.class)); +// Object o = s.serialize(ps, "1", Object.class); +// assertObjectEquals("1", o); +// assertClass(Long.class, o); +// assertObjectEquals("'F3-1'", s.serialize(ps, "1", F3.class)); +// } +// +// @Test +// public void f05_integerType_int64_2d() throws Exception { +// HttpPartSchema ps = schema("array").items(schema("integer", "int64")).build(); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", int[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Integer[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Integer.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", short[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Short[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Short.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", long[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Long[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Long.class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", String[].class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", List.class, String.class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", Object[].class)); +// assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, Object.class)); +// assertObjectEquals("['F3-1','F3-2']", s.serialize(ps, "1,2", F3[].class)); +// assertObjectEquals("['F3-1','F3-2']", s.serialize(ps, "1,2", List.class, F3.class)); +// assertObjectEquals("'F4-[1,2]'", s.serialize(ps, "1,2", F4.class)); +// } +// +// @Test +// public void f06_integerType_int64_3d() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("integer", "int64"))).build(); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", int[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, int[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Integer[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Integer[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Integer.class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", short[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, short[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Short[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Short[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Short.class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", long[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, long[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Long[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Long[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Long.class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", String[][].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, String[].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, List.class, String.class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Object[][].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Object[].class)); +// assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Object.class)); +// assertObjectEquals("[['F3-1','F3-2'],['F3-3']]", s.serialize(ps, "1,2|3", F3[][].class)); +// assertObjectEquals("[['F3-1','F3-2'],['F3-3']]", s.serialize(ps, "1,2|3", List.class, F3[].class)); +// assertObjectEquals("[['F3-1','F3-2'],['F3-3']]", s.serialize(ps, "1,2|3", List.class, List.class, F3.class)); +// assertObjectEquals("['F4-[1,2]','F4-[3]']", s.serialize(ps, "1,2|3", F4[].class)); +// assertObjectEquals("['F4-[1,2]','F4-[3]']", s.serialize(ps, "1,2|3", List.class, F4.class)); +// } +// +// +// //----------------------------------------------------------------------------------------------------------------- +// // type = number +// //----------------------------------------------------------------------------------------------------------------- +// +// public static class G1 { +// private String f; +// public G1(Float in) { +// this.f = "G1-" + in.toString(); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class G2 { +// private String f; +// public G2(Float[] in) { +// this.f = "G2-" + JsonSerializer.DEFAULT_LAX.toString(in); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class G3 { +// private String f; +// public G3(Double in) { +// this.f = "G3-" + in.toString(); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// public static class G4 { +// private String f; +// public G4(Double[] in) { +// this.f = "G4-" + JsonSerializer.DEFAULT_LAX.toString(in); +// } +// @Override +// public String toString() { +// return f; +// } +// } +// +// @Test +// public void g01_numberType_float() throws Exception { +// HttpPartSchema ps = schema("number", "float").build(); +// assertObjectEquals("1.0", s.serialize(ps, "1", float.class)); +// assertObjectEquals("1.0", s.serialize(ps, "1", Float.class)); +// assertObjectEquals("1.0", s.serialize(ps, "1", double.class)); +// assertObjectEquals("1.0", s.serialize(ps, "1", Double.class)); +// assertObjectEquals("'1'", s.serialize(ps, "1", String.class)); +// Object o = s.serialize(ps, "1", Object.class); +// assertObjectEquals("1.0",o); +// assertClass(Float.class, o); +// assertObjectEquals("'G1-1.0'", s.serialize(ps, "1", G1.class)); +// } +// +// @Test +// public void g02_numberType_float_2d() throws Exception { +// HttpPartSchema ps = schema("array").items(schema("number", "float")).build(); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", float[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", Float[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", List.class, Float.class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", double[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", Double[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", List.class, Double.class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", String[].class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", List.class, String.class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", Object[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", List.class, Object.class)); +// assertObjectEquals("['G1-1.0','G1-2.0']", s.serialize(ps, "1,2", G1[].class)); +// assertObjectEquals("['G1-1.0','G1-2.0']", s.serialize(ps, "1,2", List.class, G1.class)); +// assertObjectEquals("'G2-[1.0,2.0]'", s.serialize(ps, "1,2", G2.class)); +// } +// +// @Test +// public void g03_numberType_float_3d() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("number", "float"))).build(); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", float[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, float[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", Float[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, Float[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, List.class, Float.class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", double[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, double[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", Double[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, Double[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, List.class, Double.class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", String[][].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, String[].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, List.class, String.class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", Object[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, Object[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, List.class, Object.class)); +// assertObjectEquals("[['G1-1.0','G1-2.0'],['G1-3.0']]", s.serialize(ps, "1,2|3", G1[][].class)); +// assertObjectEquals("[['G1-1.0','G1-2.0'],['G1-3.0']]", s.serialize(ps, "1,2|3", List.class, G1[].class)); +// assertObjectEquals("[['G1-1.0','G1-2.0'],['G1-3.0']]", s.serialize(ps, "1,2|3", List.class, List.class, G1.class)); +// assertObjectEquals("['G2-[1.0,2.0]','G2-[3.0]']", s.serialize(ps, "1,2|3", G2[].class)); +// assertObjectEquals("['G2-[1.0,2.0]','G2-[3.0]']", s.serialize(ps, "1,2|3", List.class, G2.class)); +// } +// +// @Test +// public void g04_numberType_double() throws Exception { +// HttpPartSchema ps = schema("number", "double").build(); +// assertObjectEquals("1.0", s.serialize(ps, "1", float.class)); +// assertObjectEquals("1.0", s.serialize(ps, "1", Float.class)); +// assertObjectEquals("1.0", s.serialize(ps, "1", double.class)); +// assertObjectEquals("1.0", s.serialize(ps, "1", Double.class)); +// assertObjectEquals("'1'", s.serialize(ps, "1", String.class)); +// Object o = s.serialize(ps, "1", Object.class); +// assertObjectEquals("1.0", o); +// assertClass(Double.class, o); +// assertObjectEquals("'G3-1.0'", s.serialize(ps, "1", G3.class)); +// } +// +// @Test +// public void g05_numberType_double_2d() throws Exception { +// HttpPartSchema ps = schema("array").items(schema("number", "double")).build(); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", float[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", Float[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", List.class, Float.class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", double[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", Double[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", List.class, Double.class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", String[].class)); +// assertObjectEquals("['1','2']", s.serialize(ps, "1,2", List.class, String.class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", Object[].class)); +// assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", List.class, Object.class)); +// assertObjectEquals("['G3-1.0','G3-2.0']", s.serialize(ps, "1,2", G3[].class)); +// assertObjectEquals("['G3-1.0','G3-2.0']", s.serialize(ps, "1,2", List.class, G3.class)); +// assertObjectEquals("'G4-[1.0,2.0]'", s.serialize(ps, "1,2", G4.class)); +// } +// +// @Test +// public void g06_numberType_double_3d() throws Exception { +// HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("number", "double"))).build(); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", float[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, float[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", Float[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, Float[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, List.class, Float.class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", double[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, double[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", Double[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, Double[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, List.class, Double.class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", String[][].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, String[].class)); +// assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, List.class, String.class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", Object[][].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, Object[].class)); +// assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, "1,2|3", List.class, List.class, Object.class)); +// assertObjectEquals("[['G3-1.0','G3-2.0'],['G3-3.0']]", s.serialize(ps, "1,2|3", G3[][].class)); +// assertObjectEquals("[['G3-1.0','G3-2.0'],['G3-3.0']]", s.serialize(ps, "1,2|3", List.class, G3[].class)); +// assertObjectEquals("[['G3-1.0','G3-2.0'],['G3-3.0']]", s.serialize(ps, "1,2|3", List.class, List.class, G3.class)); +// assertObjectEquals("['G4-[1.0,2.0]','G4-[3.0]']", s.serialize(ps, "1,2|3", G4[].class)); +// assertObjectEquals("['G4-[1.0,2.0]','G4-[3.0]']", s.serialize(ps, "1,2|3", List.class, G4.class)); +// } +// +// +// //----------------------------------------------------------------------------------------------------------------- +// // type = object +// //----------------------------------------------------------------------------------------------------------------- +// +// public static class H1 { +// public int f; +// } +// +// @Test +// public void h01_objectType() throws Exception { +// HttpPartSchema ps = HttpPartSchema.create().type("object").build(); +// assertObjectEquals("{f:1}", s.serialize(ps, "(f=1)", H1.class)); +// assertObjectEquals("{f:1}", s.serialize(ps, "(f=1)", ObjectMap.class)); +// Object o = s.serialize(ps, "(f=1)", Object.class); +// assertObjectEquals("{f:1}", o); +// assertClass(ObjectMap.class, o); +// } +// +// @Test +// public void h02_objectType_2d() throws Exception { +// HttpPartSchema ps = schema("array").format("uon").items(schema("object")).build(); +// assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, "@((f=1),(f=2))", H1[].class)); +// assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, "@((f=1),(f=2))", List.class, H1.class)); +// assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, "@((f=1),(f=2))", ObjectMap[].class)); +// assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, "@((f=1),(f=2))", List.class, ObjectMap.class)); +// assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, "@((f=1),(f=2))", Object[].class)); +// assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, "@((f=1),(f=2))", List.class, Object.class)); +// Object o = s.serialize(ps, "@((f=1),(f=2))", Object.class); +// assertObjectEquals("[{f:1},{f:2}]", o); +// assertClass(ObjectList.class, o); +// } +// +// @Test +// public void h03_objectType_3d() throws Exception { +// HttpPartSchema ps = schema("array").format("uon").items(schema("array").items(schema("object"))).build(); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", H1[][].class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", List.class, H1[].class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", List.class, List.class, H1.class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", ObjectMap[][].class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", List.class, ObjectMap[].class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", List.class, List.class, ObjectMap.class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", Object[][].class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", List.class, Object[].class)); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", List.class, List.class, Object.class)); +// Object o = s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", Object.class); +// assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", o); +// assertClass(ObjectList.class, o); +// } +// +// public static class H2 { +// public Object f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f99; +// } +// +// @Test +// public void h04_objectType_simpleProperties() throws Exception { +// HttpPartSchema ps = schema("object") +// .property("f1", schema("string")) +// .property("f2", schema("string", "byte")) +// .property("f4", schema("string", "date-time")) +// .property("f5", schema("string", "binary")) +// .property("f6", schema("string", "binary-spaced")) +// .property("f7", schema("string", "uon")) +// .property("f8", schema("integer")) +// .property("f9", schema("integer", "int64")) +// .property("f10", schema("number")) +// .property("f11", schema("number", "double")) +// .property("f12", schema("boolean")) +// .additionalProperties(schema("integer")) +// .build(); +// +// byte[] foob = "foo".getBytes(); +// String in = "(f1=foo,f2="+base64Encode(foob)+",f4=2012-12-21T12:34:56Z,f5="+toHex(foob)+",f6='"+toSpacedHex(foob)+"',f7=foo,f8=1,f9=1,f10=1,f11=1,f12=true,f99=1)"; +// +// H2 h2 = s.serialize(ps, in, H2.class); +// assertObjectEquals("{f1:'foo',f2:[102,111,111],f4:'2012-12-21T12:34:56Z',f5:[102,111,111],f6:[102,111,111],f7:'foo',f8:1,f9:1,f10:1.0,f11:1.0,f12:true,f99:1}", h2); +// assertClass(String.class, h2.f1); +// assertClass(byte[].class, h2.f2); +// assertClass(GregorianCalendar.class, h2.f4); +// assertClass(byte[].class, h2.f5); +// assertClass(byte[].class, h2.f6); +// assertClass(String.class, h2.f7); +// assertClass(Integer.class, h2.f8); +// assertClass(Long.class, h2.f9); +// assertClass(Float.class, h2.f10); +// assertClass(Double.class, h2.f11); +// assertClass(Boolean.class, h2.f12); +// assertClass(Integer.class, h2.f99); +// +// ObjectMap om = s.serialize(ps, in, ObjectMap.class); +// assertObjectEquals("{f1:'foo',f2:[102,111,111],f4:'2012-12-21T12:34:56Z',f5:[102,111,111],f6:[102,111,111],f7:'foo',f8:1,f9:1,f10:1.0,f11:1.0,f12:true,f99:1}", om); +// assertClass(String.class, om.get("f1")); +// assertClass(byte[].class, om.get("f2")); +// assertClass(GregorianCalendar.class, om.get("f4")); +// assertClass(byte[].class, om.get("f5")); +// assertClass(byte[].class, om.get("f6")); +// assertClass(String.class, om.get("f7")); +// assertClass(Integer.class, om.get("f8")); +// assertClass(Long.class, om.get("f9")); +// assertClass(Float.class, om.get("f10")); +// assertClass(Double.class, om.get("f11")); +// assertClass(Boolean.class, om.get("f12")); +// assertClass(Integer.class, om.get("f99")); +// +// om = (ObjectMap)s.serialize(ps, in, Object.class); +// assertObjectEquals("{f1:'foo',f2:[102,111,111],f4:'2012-12-21T12:34:56Z',f5:[102,111,111],f6:[102,111,111],f7:'foo',f8:1,f9:1,f10:1.0,f11:1.0,f12:true,f99:1}", om); +// assertClass(String.class, om.get("f1")); +// assertClass(byte[].class, om.get("f2")); +// assertClass(GregorianCalendar.class, om.get("f4")); +// assertClass(byte[].class, om.get("f5")); +// assertClass(byte[].class, om.get("f6")); +// assertClass(String.class, om.get("f7")); +// assertClass(Integer.class, om.get("f8")); +// assertClass(Long.class, om.get("f9")); +// assertClass(Float.class, om.get("f10")); +// assertClass(Double.class, om.get("f11")); +// assertClass(Boolean.class, om.get("f12")); +// assertClass(Integer.class, om.get("f99")); +// } +// +// @Test +// public void h05_objectType_arrayProperties() throws Exception { +// HttpPartSchema ps = schema("object") +// .property("f1", schema("array").items(schema("string"))) +// .property("f2", schema("array").items(schema("string", "byte"))) +// .property("f4", schema("array").items(schema("string", "date-time"))) +// .property("f5", schema("array").items(schema("string", "binary"))) +// .property("f6", schema("array").items(schema("string", "binary-spaced"))) +// .property("f7", schema("array").items(schema("string", "uon"))) +// .property("f8", schema("array").items(schema("integer"))) +// .property("f9", schema("array").items(schema("integer", "int64"))) +// .property("f10", schema("array").items(schema("number"))) +// .property("f11", schema("array").items(schema("number", "double"))) +// .property("f12", schema("array").items(schema("boolean"))) +// .additionalProperties(schema("array").items(schema("integer"))) +// .build(); +// +// byte[] foob = "foo".getBytes(); +// String in = "(f1=foo,f2="+base64Encode(foob)+",f4=2012-12-21T12:34:56Z,f5="+toHex(foob)+",f6='"+toSpacedHex(foob)+"',f7=foo,f8=1,f9=1,f10=1,f11=1,f12=true,f99=1)"; +// +// H2 h2 = s.serialize(ps, in, H2.class); +// assertObjectEquals("{f1:['foo'],f2:[[102,111,111]],f4:['2012-12-21T12:34:56Z'],f5:[[102,111,111]],f6:[[102,111,111]],f7:['foo'],f8:[1],f9:[1],f10:[1.0],f11:[1.0],f12:[true],f99:[1]}", h2); +// +// ObjectMap om = s.serialize(ps, in, ObjectMap.class); +// assertObjectEquals("{f1:['foo'],f2:[[102,111,111]],f4:['2012-12-21T12:34:56Z'],f5:[[102,111,111]],f6:[[102,111,111]],f7:['foo'],f8:[1],f9:[1],f10:[1.0],f11:[1.0],f12:[true],f99:[1]}", om); +// +// om = (ObjectMap)s.serialize(ps, in, Object.class); +// assertObjectEquals("{f1:['foo'],f2:[[102,111,111]],f4:['2012-12-21T12:34:56Z'],f5:[[102,111,111]],f6:[[102,111,111]],f7:['foo'],f8:[1],f9:[1],f10:[1.0],f11:[1.0],f12:[true],f99:[1]}", om); +// } +// +// @Test +// public void h06_objectType_arrayProperties_pipes() throws Exception { +// HttpPartSchema ps = schema("object") +// .property("f1", schema("array").collectionFormat("pipes").items(schema("string"))) +// .property("f2", schema("array").collectionFormat("pipes").items(schema("string", "byte"))) +// .property("f4", schema("array").collectionFormat("pipes").items(schema("string", "date-time"))) +// .property("f5", schema("array").collectionFormat("pipes").items(schema("string", "binary"))) +// .property("f6", schema("array").collectionFormat("pipes").items(schema("string", "binary-spaced"))) +// .property("f7", schema("array").collectionFormat("pipes").items(schema("string", "uon"))) +// .property("f8", schema("array").collectionFormat("pipes").items(schema("integer"))) +// .property("f9", schema("array").collectionFormat("pipes").items(schema("integer", "int64"))) +// .property("f10", schema("array").collectionFormat("pipes").items(schema("number"))) +// .property("f11", schema("array").collectionFormat("pipes").items(schema("number", "double"))) +// .property("f12", schema("array").collectionFormat("pipes").items(schema("boolean"))) +// .additionalProperties(schema("array").collectionFormat("pipes").items(schema("integer"))) +// .build(); +// +// byte[] foob = "foo".getBytes(), barb = "bar".getBytes(); +// String in = "(f1=foo|bar,f2="+base64Encode(foob)+"|"+base64Encode(barb)+",f4=2012-12-21T12:34:56Z|2012-12-21T12:34:56Z,f5="+toHex(foob)+"|"+toHex(barb)+",f6='"+toSpacedHex(foob)+"|"+toSpacedHex(barb)+"',f7=foo|bar,f8=1|2,f9=1|2,f10=1|2,f11=1|2,f12=true|true,f99=1|2)"; +// +// H2 h2 = s.serialize(ps, in, H2.class); +// assertObjectEquals("{f1:['foo','bar'],f2:[[102,111,111],[98,97,114]],f4:['2012-12-21T12:34:56Z','2012-12-21T12:34:56Z'],f5:[[102,111,111],[98,97,114]],f6:[[102,111,111],[98,97,114]],f7:['foo','bar'],f8:[1,2],f9:[1,2],f10:[1.0,2.0],f11:[1.0,2.0],f12:[true,true],f99:[1,2]}", h2); +// +// ObjectMap om = s.serialize(ps, in, ObjectMap.class); +// assertObjectEquals("{f1:['foo','bar'],f2:[[102,111,111],[98,97,114]],f4:['2012-12-21T12:34:56Z','2012-12-21T12:34:56Z'],f5:[[102,111,111],[98,97,114]],f6:[[102,111,111],[98,97,114]],f7:['foo','bar'],f8:[1,2],f9:[1,2],f10:[1.0,2.0],f11:[1.0,2.0],f12:[true,true],f99:[1,2]}", om); +// +// om = (ObjectMap)s.serialize(ps, in, Object.class); +// assertObjectEquals("{f1:['foo','bar'],f2:[[102,111,111],[98,97,114]],f4:['2012-12-21T12:34:56Z','2012-12-21T12:34:56Z'],f5:[[102,111,111],[98,97,114]],f6:[[102,111,111],[98,97,114]],f7:['foo','bar'],f8:[1,2],f9:[1,2],f10:[1.0,2.0],f11:[1.0,2.0],f12:[true,true],f99:[1,2]}", om); +// } +// + //----------------------------------------------------------------------------------------------------------------- + // Utility methods + //----------------------------------------------------------------------------------------------------------------- + + private static HttpPartSchemaBuilder schema() { + return HttpPartSchema.create(); + } +// +// private static HttpPartSchemaBuilder schema(String type) { +// return HttpPartSchema.create(type); +// } +// +// private static HttpPartSchemaBuilder schema(String type, String format) { +// return HttpPartSchema.create(type, format); +// } +} \ 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 8c7fba9..7feb819 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 @@ -681,9 +681,8 @@ public class BeanSession extends Session { return (T)((Calendar)value).getTime(); } - Transform t = type.getTransform(value.getClass()); - if (t != null) - return (T) t.transform(value); + if (type.hasTransformForObject(value)) + return type.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 0a4b1c6..d420d6f 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 @@ -2081,7 +2081,7 @@ public final class ClassMeta implements Type { * @return true if this class has a transform associated with it that allows it to be created from a Reader. */ public boolean hasReaderTransform() { - return getTransform(Reader.class) != null; + return hasTransform(Reader.class); } /** @@ -2099,7 +2099,7 @@ public final class ClassMeta implements Type { * @return true if this class has a transform associated with it that allows it to be created from an InputStream. */ public boolean hasInputStreamTransform() { - return getTransform(InputStream.class) != null; + return hasTransform(InputStream.class); } /** @@ -2130,6 +2130,38 @@ public final class ClassMeta implements Type { } /** + * Returns true if this class can be instantiated from the specified type. + * + * @param c The class type to convert from. + * @return true if this class can be instantiated from the specified type. + */ + public boolean hasTransform(Class c) { + return getTransform(c) != null; + } + + /** + * Returns true if this class can be instantiated from the specified object. + * + * @param o The object to convert from. + * @return true if this class can be instantiated from the specified object. + */ + public boolean hasTransformForObject(Object o) { + return getTransform(o.getClass()) != null; + } + + /** + * Transforms the specified object into an instance of this class. + * + * @param o The object to transform. + * @return The transformed object. + */ + @SuppressWarnings({"unchecked","rawtypes"}) + public T transform(Object o) { + Transform t = getTransform(o.getClass()); + return (T)(t == null ? null : t.transform(o)); + } + + /** * Returns the transform for this class for creating instances from other object types. * * @param c The transform-from class. 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 30c7876..e7d5b14 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 @@ -1010,7 +1010,7 @@ public class HttpPartSchema { * @throws SchemaValidationException if the specified parsed output does not validate against this schema. */ @SuppressWarnings("rawtypes") - public Object validateOutput(Object o, BeanContext bc) throws SchemaValidationException { + public T validateOutput(T o, BeanContext bc) throws SchemaValidationException { if (o == null) { if (! isValidRequired(o)) throw new SchemaValidationException("Required value not provided."); 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 14c07c6..d482732 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 @@ -273,25 +273,25 @@ public class OpenApiPartParser extends UonPartParser { if (t == STRING) { if (type.isObject()) { if (f == BYTE) - return (T)StringUtils.base64Decode(in); + return (T)base64Decode(in); if (f == DATE || f == DATE_TIME) - return (T)StringUtils.parseIsoCalendar(in); + return (T)parseIsoCalendar(in); if (f == BINARY) - return (T)StringUtils.fromHex(in); + return (T)fromHex(in); if (f == BINARY_SPACED) - return (T)StringUtils.fromSpacedHex(in); + return (T)fromSpacedHex(in); if (f == HttpPartSchema.Format.UON) return super.parse(partType, schema, in, type); return (T)in; } if (f == BYTE) - return toType(StringUtils.base64Decode(in), type); + return toType(base64Decode(in), type); if (f == DATE || f == DATE_TIME) - return toType(StringUtils.parseIsoCalendar(in), type); + return toType(parseIsoCalendar(in), type); if (f == BINARY) - return toType(StringUtils.fromHex(in), type); + return toType(fromHex(in), type); if (f == BINARY_SPACED) - return toType(StringUtils.fromSpacedHex(in), type); + return toType(fromSpacedHex(in), type); if (f == HttpPartSchema.Format.UON) return super.parse(partType, schema, in, type); return toType(in, type); @@ -333,7 +333,7 @@ public class OpenApiPartParser extends UonPartParser { } else { o = ss; } - if (type.getTransform(schema.getParsedType().getInnerClass()) != null) + if (type.hasTransform(schema.getParsedType().getInnerClass())) return toType(toType(o, schema.getParsedType()), type); return toType(o, type); diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java index 1eda116..6aac247 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java @@ -12,6 +12,14 @@ // *************************************************************************************************************************** package org.apache.juneau.httppart; +import static org.apache.juneau.httppart.HttpPartSchema.CollectionFormat.*; +import static org.apache.juneau.httppart.HttpPartSchema.Format.*; +import static org.apache.juneau.httppart.HttpPartSchema.Type.*; +import static org.apache.juneau.internal.StringUtils.*; + +import java.lang.reflect.*; +import java.util.*; + import org.apache.juneau.*; import org.apache.juneau.internal.*; import org.apache.juneau.serializer.*; @@ -60,6 +68,12 @@ public class OpenApiPartSerializer extends UonPartSerializer { /** Reusable instance of {@link OpenApiPartSerializer}, all default settings. */ public static final OpenApiPartSerializer DEFAULT = new OpenApiPartSerializer(PropertyStore.DEFAULT); + // Cache these for faster lookup + private static final BeanContext BC = BeanContext.DEFAULT; + private static final ClassMeta CM_ByteArray = BC.getClassMeta(byte[].class); + private static final ClassMeta CM_Calendar = BC.getClassMeta(Calendar.class); + + private static final HttpPartSchema DEFAULT_SCHEMA = HttpPartSchema.DEFAULT; //------------------------------------------------------------------------------------------------------------------- // Instance @@ -104,168 +118,116 @@ public class OpenApiPartSerializer extends UonPartSerializer { // Entry point methods //-------------------------------------------------------------------------------- + /** + * Convenience method for serializing a part. + * + * @param schema + * Schema information about the part. + *
May be null. + *
Not all part serializers use the schema information. + * @param value The value being serialized. + * @return The serialized value. + * @throws SerializeException If a problem occurred while trying to serialize the input. + * @throws SchemaValidationException If the input or resulting HTTP part object fails schema validation. + */ + public String serialize(HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException { + return serialize(null, schema, value); + } + @Override /* PartSerializer */ + @SuppressWarnings("rawtypes") public String serialize(HttpPartType partType, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException { - schema = ObjectUtils.firstNonNull(schema, this.schema, HttpPartSchema.DEFAULT); -// ClassMeta type = getClassMetaForObject(value); -// String out; -// -// switch (schema.getType()) { -// case STRING: { -// if (type.isObject()) { -// switch (schema.getFormat()) { -// case BYTE: -// return (T)StringUtils.base64Decode(in); -// case DATE: -// case DATE_TIME: -// 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: -// return (T)in; -// } -// } -// switch (schema.getFormat()) { -// case BYTE: -// return toType(StringUtils.base64Decode(in), type); -// case DATE: -// case DATE_TIME: -// 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: -// return toType(in, type); -// } -// } -// case ARRAY: { -// if (type.isObject()) -// type = (ClassMeta)CM_ObjectList; -// -// ClassMeta eType = type.isObject() ? string() : type.getElementType(); -// if (eType == null) -// eType = schema.getParsedType().getElementType(); -// -// 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; -// } -// if (type.getTransform(schema.getParsedType().getInnerClass()) != null) -// return toType(toType(o, schema.getParsedType()), type); -// return toType(o, type); -// } -// case BOOLEAN: { -// if (type.isObject()) -// type = (ClassMeta)CM_Boolean; -// if (type.isBoolean()) -// return super.parse(partType, schema, in, type); -// return toType(super.parse(partType, schema, in, CM_Boolean), type); -// } -// case INTEGER: { -// if (type.isObject()) { -// switch (schema.getFormat()) { -// case INT64: -// type = (ClassMeta)CM_Long; -// break; -// default: -// type = (ClassMeta)CM_Integer; -// -// } -// } -// if (type.isNumber()) -// return super.parse(partType, schema, in, type); -// return toType(super.parse(partType, schema, in, CM_Integer), type); -// } -// case NUMBER: { -// if (type.isObject()) { -// switch (schema.getFormat()) { -// case DOUBLE: -// type = (ClassMeta)CM_Double; -// break; -// default: -// type = (ClassMeta)CM_Float; -// } -// } -// if (type.isNumber()) -// return super.parse(partType, schema, in, type); -// return toType(super.parse(partType, schema, in, CM_Integer), type); -// } -// case OBJECT: { -// if (type.isObject()) -// type = (ClassMeta)CM_ObjectMap; -// if (schema.hasProperties() && type.isMapOrBean()) { -// try { -// if (type.isBean()) { -// BeanMap m = BC.createBeanSession().newBeanMap(type.getInnerClass()); -// for (Map.Entry e : parse(partType, DEFAULT_SCHEMA, in, CM_ObjectMap).entrySet()) { -// String key = e.getKey(); -// BeanPropertyMeta bpm = m.getPropertyMeta(key); -// m.put(key, parse(partType, schema.getProperty(key), asString(e.getValue()), bpm == null ? object() : bpm.getClassMeta())); -// } -// return m.getBean(); -// } -// Map m = (Map)type.newInstance(); -// for (Map.Entry e : parse(partType, DEFAULT_SCHEMA, in, CM_ObjectMap).entrySet()) { -// String key = e.getKey(); -// m.put(key, parse(partType, schema.getProperty(key), asString(e.getValue()), object())); -// } -// return (T)m; -// } catch (Exception e1) { -// throw new ParseException(e1, "Could not instantiate type ''{0}''.", type); -// } -// } -// return super.parse(partType, schema, in, type); -// } -// case FILE: { -// throw new ParseException("File part not supported."); -// } -// case NONE: { -// // This should never be returned by HttpPartSchema.getType(ClassMeta). -// throw new ParseException("Invalid type."); -// } -// } -// } - - - - - String out = super.serialize(partType, schema, value); + + schema = ObjectUtils.firstNonNull(schema, this.schema, DEFAULT_SCHEMA); + ClassMeta type = getClassMetaForObject(value); + if (type == null) + type = object(); + HttpPartSchema.Type t = schema.getType(type); + HttpPartSchema.Format f = schema.getFormat(); + + String out = null; + + schema.validateOutput(value, this); + + if (t == STRING) { + + if (f == BYTE) + out = base64Encode(toType(value, CM_ByteArray)); + else if (f == BINARY) + out = toHex(toType(value, CM_ByteArray)); + else if (f == BINARY_SPACED) + out = toSpacedHex(toType(value, CM_ByteArray)); + else if (f == DATE) + out = toIsoDate(toType(value, CM_Calendar)); + else if (f == DATE_TIME) + out = toIsoDateTime(toType(value, CM_Calendar)); + else if (f == HttpPartSchema.Format.UON) + out = super.serialize(partType, schema, value); + else + out = toType(value, string()); + + } else if (t == ARRAY) { + + List l = new ArrayList<>(); + HttpPartSchema items = schema.getItems(); + if (type.isArray()) { + for (int i = 0; i < Array.getLength(value); i++) + l.add(serialize(partType, items, Array.get(value, i))); + } else if (type.isCollection()) { + for (Object o : (Collection)value) + l.add(serialize(partType, items, o)); + } else { + l.add(serialize(partType, items, value)); + } + + HttpPartSchema.CollectionFormat cf = schema.getCollectionFormat(); + + if (cf == MULTI || cf == CSV) + out = join(l, ','); + else if (cf == PIPES) + out = join(l, '|'); + else if (cf == SSV) + out = join(l, ' '); + else if (cf == TSV) + out = join(l, '\t'); + else + out = super.serialize(partType, null, l); + + } else if (t == BOOLEAN || t == INTEGER || t == NUMBER) { + out = super.serialize(partType, null, value); + + } else if (t == OBJECT) { + if (schema.hasProperties() && type.isMapOrBean()) { + ObjectMap m = new ObjectMap(); + if (type.isBean()) { + for (Map.Entry e : BC.createBeanSession().toBeanMap(value).entrySet()) + m.put(e.getKey(), serialize(partType, schema.getProperty(e.getKey()), e.getValue())); + } else { + for (Map.Entry e : (Set)((Map)value).entrySet()) + m.put(asString(e.getKey()), serialize(partType, schema.getProperty(asString(e.getKey())), e.getValue())); + } + out = super.serialize(m); + } else { + out = super.serialize(partType, schema, value); + } + + } else if (t == FILE) { + throw new SerializeException("File part not supported."); + + } else if (t == NO_TYPE) { + // This should never be returned by HttpPartSchema.getType(ClassMeta). + throw new SerializeException("Invalid type."); + } + schema.validateInput(out); return out; } + + private T toType(Object in, ClassMeta type) throws SerializeException { + try { + return createBeanSession().convertToType(in, type); + } catch (InvalidDataConversionException e) { + throw new SerializeException(e.getMessage()); + } + } } 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 0c157c3..452fccf 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 @@ -1227,6 +1227,26 @@ public final class StringUtils { } /** + * Converts the specified object to an ISO8601 date string. + * + * @param c The object to convert. + * @return The converted object. + */ + public static String toIsoDate(Calendar c) { + return DatatypeConverter.printDate(c); + } + + /** + * Converts the specified object to an ISO8601 date-time string. + * + * @param c The object to convert. + * @return The converted object. + */ + public static String toIsoDateTime(Calendar c) { + return DatatypeConverter.printDateTime(c); + } + + /** * Simple utility for replacing variables of the form "{key}" with values in the specified map. * *

diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java index 341a600..a9f9c7c 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java @@ -287,6 +287,13 @@ public class BasicRestCallHandler implements RestCallHandler { */ @Override /* RestCallHandler */ public synchronized void handleError(HttpServletRequest req, HttpServletResponse res, RestException e) throws IOException { + if (context.isDebug()) { + String qs = req.getQueryString(); + int c = e.getOccurrence(); + String msg = '[' + Integer.toHexString(e.hashCode()) + '.' + e.getStatus() + '.' + c + "] HTTP " + req.getMethod() + " " + e.getStatus() + " " + req.getRequestURI() + (qs == null ? "" : "?" + qs); + System.err.println(msg); + e.printStackTrace(System.err); + } e.setOccurrence(context == null ? 0 : context.getStackTraceOccurrence(e)); logger.onError(req, res, e); renderError(req, res, e); diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java index 1ceebd1..dd36625 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java @@ -811,6 +811,34 @@ public final class RestContext extends BeanContext { public static final String REST_converters = PREFIX + "converters.lo"; /** + * Configuration property: Debug mode. + * + *

Property:
+ *
    + *
  • Name: "RestContext.debug.b" + *
  • Data type: Boolean + *
  • Default: false + *
  • Session-overridable: false + *
  • Annotations: + *
      + *
    • {@link RestResource#debug()} + *
    + *
  • Methods: + *
      + *
    • {@link RestContextBuilder#debug(boolean)} + *
    + *
+ * + *
Description:
+ *

+ * Enables the following: + *

    + *
  • A message and stack trace is printed to STDERR when {@link BasicRestCallHandler#handleError(HttpServletRequest, HttpServletResponse, RestException)} is called. + *
+ */ + public static final String REST_debug = PREFIX + "debug.b"; + + /** * Configuration property: Default character encoding. * *
Property:
@@ -2749,7 +2777,8 @@ public final class RestContext extends BeanContext { allowBodyParam, renderResponseStackTraces, useStackTraceHashes, - useClasspathResourceCaching; + useClasspathResourceCaching, + debug; private final String defaultCharset, clientVersionHeader, @@ -2874,6 +2903,7 @@ public final class RestContext extends BeanContext { allowedMethodParams = Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(StringUtils.split(getStringProperty(REST_allowedMethodParams, "HEAD,OPTIONS"))))); renderResponseStackTraces = getBooleanProperty(REST_renderResponseStackTraces, false); useStackTraceHashes = getBooleanProperty(REST_useStackTraceHashes, true); + debug = getBooleanProperty(REST_debug, false); defaultCharset = getStringProperty(REST_defaultCharset, "utf-8"); maxInput = getLongProperty(REST_maxInput, 100_000_000l); clientVersionHeader = getStringProperty(REST_clientVersionHeader, "X-Client-Version"); @@ -3900,6 +3930,20 @@ public final class RestContext extends BeanContext { } /** + * Returns true if debug mode is enabled on this resource. + * + *
See Also:
+ *
    + *
  • {@link RestContext#REST_debug} + *
+ * + * @return true if setting is enabled. + */ + public boolean isDebug() { + return debug; + } + + /** * Returns the default charset to use on requests and responses when not specified on the request. * *
See Also:
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java index e7c5cbc..a7c9d6b 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java @@ -223,6 +223,8 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon defaultCharset(vr.resolve(r.defaultCharset())); if (! r.maxInput().isEmpty()) maxInput(vr.resolve(r.maxInput())); + if (! r.debug().isEmpty()) + debug(Boolean.valueOf(vr.resolve(r.debug()))); mimeTypes(resolveVars(vr, r.mimeTypes())); HtmlDoc hd = r.htmldoc(); @@ -773,6 +775,24 @@ public class RestContextBuilder extends BeanContextBuilder implements ServletCon } /** + * Configuration property: Debug mode. + * + *
See Also:
+ *
    + *
  • {@link RestContext#REST_debug} + *
  • {@link BeanContext#BEAN_debug} + *
+ * + * @param value The new value for this setting. + * @return This object (for method chaining). + */ + @Override + public RestContextBuilder debug(boolean value) { + super.debug(value); + return set(REST_debug, value); + } + + /** * Configuration property: Default character encoding. * *

diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java index 9337288..adec8b1 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java @@ -17,6 +17,8 @@ import static java.lang.annotation.RetentionPolicy.*; import java.lang.annotation.*; +import javax.servlet.http.*; + import org.apache.juneau.*; import org.apache.juneau.config.*; import org.apache.juneau.encoders.*; @@ -943,4 +945,27 @@ public @interface RestResource { * */ String useStackTraceHashes() default ""; + + /** + * Enable debug mode. + * + *

+ * Enables the following: + *

    + *
  • A message and stack trace is printed to STDERR when {@link BasicRestCallHandler#handleError(HttpServletRequest, HttpServletResponse, RestException)} is called. + *
+ * + *
Notes:
+ * + * + *
See Also:
+ *
    + *
  • {@link RestContext#REST_debug} + *
+ */ + String debug() default ""; }