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