001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.marshaller; 014 015import java.io.*; 016import java.lang.reflect.*; 017import java.nio.charset.*; 018 019import org.apache.juneau.*; 020import org.apache.juneau.httppart.*; 021import org.apache.juneau.oapi.*; 022import org.apache.juneau.parser.*; 023import org.apache.juneau.serializer.*; 024 025/** 026 * A pairing of a {@link OpenApiSerializer} and {@link OpenApiParser} into a single class with convenience read/write methods. 027 * 028 * <p> 029 * The general idea is to combine a single serializer and parser inside a simplified API for reading and writing POJOs. 030 * 031 * <h5 class='figure'>Examples:</h5> 032 * <p class='bjava'> 033 * <jc>// Using instance.</jc> 034 * OpenApi <jv>oapi</jv> = <jk>new</jk> OpenApi(); 035 * MyPojo <jv>myPojo</jv> = <jv>oapi</jv>.read(<jv>string</jv>, MyPojo.<jk>class</jk>); 036 * String <jv>string</jv> = <jv>oapi</jv>.write(<jv>myPojo</jv>); 037 * </p> 038 * <p class='bjava'> 039 * <jc>// Using DEFAULT instance.</jc> 040 * MyPojo <jv>myPojo</jv> = OpenApi.<jsf>DEFAULT</jsf>.read(<jv>string</jv>, MyPojo.<jk>class</jk>); 041 * String <jv>string</jv> = OpenApi.<jsf>DEFAULT</jsf>.write(<jv>myPojo</jv>); 042 * </p> 043 * 044 * <h5 class='section'>See Also:</h5><ul> 045 * <li class='link'><a class="doclink" href="../../../../index.html#jm.Marshallers">Marshallers</a> 046 * </ul> 047 */ 048public class OpenApi extends CharMarshaller { 049 050 //----------------------------------------------------------------------------------------------------------------- 051 // Static 052 //----------------------------------------------------------------------------------------------------------------- 053 054 /** 055 * Default reusable instance. 056 */ 057 public static final OpenApi DEFAULT = new OpenApi(); 058 059 //----------------------------------------------------------------------------------------------------------------- 060 // Instance 061 //----------------------------------------------------------------------------------------------------------------- 062 063 private final OpenApiSerializer s; 064 private final OpenApiParser p; 065 066 /** 067 * Constructor. 068 * 069 * @param s 070 * The serializer to use for serializing output. 071 * <br>Must not be <jk>null</jk>. 072 * @param p 073 * The parser to use for parsing input. 074 * <br>Must not be <jk>null</jk>. 075 */ 076 public OpenApi(OpenApiSerializer s, OpenApiParser p) { 077 super(s, p); 078 this.s = s; 079 this.p = p; 080 } 081 082 /** 083 * Constructor. 084 * 085 * <p> 086 * Uses {@link OpenApiSerializer#DEFAULT} and {@link OpenApiParser#DEFAULT}. 087 */ 088 public OpenApi() { 089 this(OpenApiSerializer.DEFAULT, OpenApiParser.DEFAULT); 090 } 091 092 /** 093 * Parses an OpenApi input string to the specified type. 094 * 095 * <p> 096 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>. 097 * 098 * @param <T> The class type of the object being created. 099 * @param input The input. 100 * @param type The object type to create. 101 * @return The parsed object. 102 * @throws ParseException Malformed input encountered. 103 */ 104 public static <T> T to(String input, Class<T> type) throws ParseException { 105 return DEFAULT.read(input, type); 106 } 107 108 /** 109 * Parses an OpenApi input object to the specified Java type. 110 * 111 * <p> 112 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>. 113 * 114 * @param <T> The class type of the object being created. 115 * @param input 116 * The input. 117 * <br>Can be any of the following types: 118 * <ul> 119 * <li><jk>null</jk> 120 * <li>{@link Reader} 121 * <li>{@link CharSequence} 122 * <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by 123 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 124 * <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by 125 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 126 * <li>{@link File} containing system encoded text (or charset defined by 127 * {@link org.apache.juneau.parser.ReaderParser.Builder#fileCharset(Charset)} property value). 128 * </ul> 129 * @param type The object type to create. 130 * @return The parsed object. 131 * @throws ParseException Malformed input encountered. 132 * @throws IOException Thrown by underlying stream. 133 */ 134 public static <T> T to(Object input, Class<T> type) throws ParseException, IOException { 135 return DEFAULT.read(input, type); 136 } 137 138 /** 139 * Parses an OpenApi input object to the specified Java type. 140 * 141 * <p> 142 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>. 143 * 144 * @param <T> The class type of the object being created. 145 * @param schema The part type schema. Can be <jk>null</jk>. 146 * @param input 147 * The input. 148 * @param type The object type to create. 149 * @return The parsed object. 150 * @throws ParseException Malformed input encountered. 151 * @throws IOException Thrown by underlying stream. 152 */ 153 public static <T> T to(HttpPartSchema schema, String input, Class<T> type) throws ParseException, IOException { 154 return DEFAULT.p.parse(HttpPartType.ANY, schema, input, type); 155 } 156 157 /** 158 * Parses an OpenApi input string to the specified Java type. 159 * 160 * <p> 161 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>. 162 * 163 * @param <T> The class type of the object to create. 164 * @param input The input. 165 * @param type 166 * The object type to create. 167 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 168 * @param args 169 * The type arguments of the class if it's a collection or map. 170 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 171 * <br>Ignored if the main type is not a map or collection. 172 * @return The parsed object. 173 * @throws ParseException Malformed input encountered. 174 * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections. 175 */ 176 public static <T> T to(String input, Type type, Type...args) throws ParseException { 177 return DEFAULT.read(input, type, args); 178 } 179 180 /** 181 * Parses an OpenApi input object to the specified Java type. 182 * 183 * <p> 184 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>. 185 * 186 * @param <T> The class type of the object to create. 187 * @param input 188 * The input. 189 * <br>Can be any of the following types: 190 * <ul> 191 * <li><jk>null</jk> 192 * <li>{@link Reader} 193 * <li>{@link CharSequence} 194 * <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by 195 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 196 * <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by 197 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 198 * <li>{@link File} containing system encoded text (or charset defined by 199 * {@link org.apache.juneau.parser.ReaderParser.Builder#fileCharset(Charset)} property value). 200 * </ul> 201 * @param type 202 * The object type to create. 203 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 204 * @param args 205 * The type arguments of the class if it's a collection or map. 206 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 207 * <br>Ignored if the main type is not a map or collection. 208 * @return The parsed object. 209 * @throws ParseException Malformed input encountered. 210 * @throws IOException Thrown by underlying stream. 211 * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections. 212 */ 213 public static <T> T to(Object input, Type type, Type...args) throws ParseException, IOException { 214 return DEFAULT.read(input, type, args); 215 } 216 217 /** 218 * Serializes a Java object to an OpenApi string. 219 * 220 * <p> 221 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>)</c>. 222 * 223 * @param object The object to serialize. 224 * @return 225 * The serialized object. 226 * @throws SerializeException If a problem occurred trying to convert the output. 227 */ 228 public static String of(Object object) throws SerializeException { 229 return DEFAULT.write(object); 230 } 231 232 /** 233 * Serializes a Java object to an OpenApi output. 234 * 235 * <p> 236 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>output</jv>)</c>. 237 * 238 * @param object The object to serialize. 239 * @param output 240 * The output object. 241 * <br>Can be any of the following types: 242 * <ul> 243 * <li>{@link Writer} 244 * <li>{@link OutputStream} - Output will be written as UTF-8 encoded stream. 245 * <li>{@link File} - Output will be written as system-default encoded stream. 246 * <li>{@link StringBuilder} - Output will be written to the specified string builder. 247 * </ul> 248 * @return The output object. 249 * @throws SerializeException If a problem occurred trying to convert the output. 250 * @throws IOException Thrown by underlying stream. 251 */ 252 public static Object of(Object object, Object output) throws SerializeException, IOException { 253 DEFAULT.write(object, output); 254 return output; 255 } 256 257 /** 258 * Serializes a Java object to an OpenApi output. 259 * 260 * <p> 261 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>output</jv>)</c>. 262 * @param schema The part schema. Can be <jk>null</jk>. 263 * @param object The object to serialize. 264 * @return The output object. 265 * @throws SerializeException If a problem occurred trying to convert the output. 266 */ 267 public static String of(HttpPartSchema schema, Object object) throws SerializeException { 268 return DEFAULT.s.serialize(HttpPartType.ANY, schema, object); 269 } 270}