| <!-- |
| /*************************************************************************************************************************** |
| * 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. |
| ***************************************************************************************************************************/ |
| --> |
| |
| OpenAPI Methodology |
| |
| <p> |
| Unlike the other Juneau serializers and parsers that convert input and output directly to-and-from POJOs, |
| the OpenAPI serializers and parsers use intermediate objects based on the <c>type</c> and <c>format</c> |
| of the schema. |
| </p> |
| <p> |
| The following table shows the "natural" intermediate type of the object based on the <c>type/format</c>: |
| </p> |
| <table class='styled w800'> |
| <tr><th>Type</th><th>Format</th><th>Intermediate Java Type</th></tr> |
| <tr class='dark bb'> |
| <td rowspan='4'><c>string</c> or empty</td> |
| <td><c>byte<br>binary<br>binary-spaced</c></td> |
| <td><c><jk>byte</jk>[]</c></td> |
| </tr> |
| <tr class='dark bb'> |
| <td><c>date<br>date-time</c></td> |
| <td>{@link java.util.Calendar}</td> |
| </tr> |
| <tr class='dark bb'> |
| <td><c>uon</c></td> |
| <td>No intermediate type.<br>(serialized directly to/from POJO)</td> |
| </tr> |
| <tr class='dark bb'> |
| <td>empty</td> |
| <td>{@link java.lang.String}</td> |
| </tr> |
| <tr class='light bb'> |
| <td rowspan='1'><c>boolean</c></td> |
| <td>empty</td> |
| <td>{@link java.lang.Boolean}</td> |
| </tr> |
| <tr class='dark bb'> |
| <td rowspan='2'><c>integer</c></td> |
| <td><c>int32</c></td> |
| <td>{@link java.lang.Integer}</td> |
| </tr> |
| <tr class='dark bb'> |
| <td><c>int64</c></td> |
| <td>{@link java.lang.Long}</td> |
| </tr> |
| <tr class='light bb'> |
| <td rowspan='2'><c>number</c></td> |
| <td><c>float</c></td> |
| <td>{@link java.lang.Float}</td> |
| </tr> |
| <tr class='light bb'> |
| <td><c>double</c></td> |
| <td>{@link java.lang.Double}</td> |
| </tr> |
| <tr class='dark bb'> |
| <td rowspan='2'><c>array</c></td> |
| <td>empty</td> |
| <td>Arrays of intermediate types on this list.</td> |
| </tr> |
| <tr class='dark bb'> |
| <td><c>uon</c></td> |
| <td>No intermediate type.<br>(serialized directly to/from POJO)</td> |
| </tr> |
| <tr class='light bb'> |
| <td rowspan='2'><c>object</c></td> |
| <td>empty</td> |
| <td><c>Map<String,Object></c></td> |
| </tr> |
| <tr class='light bb'> |
| <td><c>uon</c></td> |
| <td>No intermediate type.<br>(serialized directly to/from POJO)</td> |
| </tr> |
| </table> |
| <p> |
| The valid POJO types for serializing/parsing are based on the intermediate types above. |
| As a general rule, any POJOs that are the intermediate type or transformable to or from |
| the intermediate type are valid POJO types. |
| </p> |
| <p> |
| For example, the following POJO type can be transformed to and from a byte array. |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Sample POJO class convertable to and from a byte[].</jc> |
| <jk>public class</jk> MyPojo { |
| |
| <jc>// Constructor used by parser.</jc> |
| <jk>public</jk> MyPojo(<jk>byte</jk>[] fromBytes) {...} |
| |
| <jc>// toX method used by serializer.</jc> |
| <jk>public byte</jk>[] toBytes() {...} |
| } |
| </p> |
| <p> |
| This example shows how that POJO can be converted to a BASE64-encoded string. |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Construct a POJO.</jc> |
| MyPojo myPojo = ...; |
| |
| <jc>// Define a schema.</jc> |
| HttpPartSchema schema = HttpPartSchema.<jsm>create</jsm>().type(<js>"string"</js>).format(<js>"byte"</js>).build(); |
| |
| <jc>// Convert POJO to BASE64-encoded string.</jc> |
| HttpPartSerializer s = OpenApiSerializer.<jsf>DEFAULT</jsf>; |
| String httpPart = s.serialize(schema, myPojo); |
| |
| <jc>// Convert BASE64-encoded string back into a POJO.</jc> |
| HttpPartParser p = OpenApiParser.<jsf>DEFAULT</jsf>; |
| myPojo = p.parse(schema, httpPart, MyPojo.<jk>class</jk>); |
| </p> |
| <p> |
| In addition to defining format, the schema also allows for validations of the serialized form. |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Construct a POJO.</jc> |
| MyPojo myPojo = ...; |
| |
| <jc>// Define a schema.</jc> |
| <jc>// Serialized string must be no smaller than 100 characters.</jc> |
| HttpPartSchema schema = HttpPartSchema.<jsm>create</jsm>().type(<js>"string"</js>).format(<js>"byte"</js>).minLength(100).build(); |
| |
| <jc>// Convert POJO to BASE64-encoded string.</jc> |
| HttpPartSerializer s = OpenApiSerializer.<jsf>DEFAULT</jsf>; |
| String httpPart; |
| <jk>try</jk> { |
| httpPart = s.serialize(schema, myPojo); |
| } <jk>catch</jk> (SchemaValidationException e) { |
| <jc>// Oops, output too small.</jc> |
| } |
| |
| <jc>// Convert BASE64-encoded string back into a POJO.</jc> |
| HttpPartParser p = OpenApiParser.<jsf>DEFAULT</jsf>; |
| <jk>try</jk> { |
| myPojo = p.parse(schema, httpPart, MyPojo.<jk>class</jk>); |
| } <jk>catch</jk> (SchemaValidationException e) { |
| <jc>// Oops, input too small.</jc> |
| } |
| </p> |
| <p> |
| It looks simple, but the implementation is highly sophisticated being able to serialize and parse and validate using complex schemas. |
| </p> |
| <p> |
| The next sections go more into depth on serializing and parsing various POJO types. |
| </p> |
| |