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 * Default reusable instance. 055 */ 056 public static final OpenApi DEFAULT = new OpenApi(); 057 058 /** 059 * Serializes a Java object to an OpenApi output. 060 * 061 * <p> 062 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>output</jv>)</c>. 063 * @param schema The part schema. Can be <jk>null</jk>. 064 * @param object The object to serialize. 065 * @return The output object. 066 * @throws SerializeException If a problem occurred trying to convert the output. 067 */ 068 public static String of(HttpPartSchema schema, Object object) throws SerializeException { 069 return DEFAULT.s.serialize(HttpPartType.ANY, schema, object); 070 } 071 072 /** 073 * Serializes a Java object to an OpenApi string. 074 * 075 * <p> 076 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>)</c>. 077 * 078 * @param object The object to serialize. 079 * @return 080 * The serialized object. 081 * @throws SerializeException If a problem occurred trying to convert the output. 082 */ 083 public static String of(Object object) throws SerializeException { 084 return DEFAULT.write(object); 085 } 086 087 /** 088 * Serializes a Java object to an OpenApi output. 089 * 090 * <p> 091 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>output</jv>)</c>. 092 * 093 * @param object The object to serialize. 094 * @param output 095 * The output object. 096 * <br>Can be any of the following types: 097 * <ul> 098 * <li>{@link Writer} 099 * <li>{@link OutputStream} - Output will be written as UTF-8 encoded stream. 100 * <li>{@link File} - Output will be written as system-default encoded stream. 101 * <li>{@link StringBuilder} - Output will be written to the specified string builder. 102 * </ul> 103 * @return The output object. 104 * @throws SerializeException If a problem occurred trying to convert the output. 105 * @throws IOException Thrown by underlying stream. 106 */ 107 public static Object of(Object object, Object output) throws SerializeException, IOException { 108 DEFAULT.write(object, output); 109 return output; 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 schema The part type schema. Can be <jk>null</jk>. 120 * @param input 121 * The input. 122 * @param type The object type to create. 123 * @return The parsed object. 124 * @throws ParseException Malformed input encountered. 125 * @throws IOException Thrown by underlying stream. 126 */ 127 public static <T> T to(HttpPartSchema schema, String input, Class<T> type) throws ParseException, IOException { 128 return DEFAULT.p.parse(HttpPartType.ANY, schema, input, type); 129 } 130 131 /** 132 * Parses an OpenApi input object to the specified Java type. 133 * 134 * <p> 135 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>. 136 * 137 * @param <T> The class type of the object being created. 138 * @param input 139 * The input. 140 * <br>Can be any of the following types: 141 * <ul> 142 * <li><jk>null</jk> 143 * <li>{@link Reader} 144 * <li>{@link CharSequence} 145 * <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by 146 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 147 * <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by 148 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 149 * <li>{@link File} containing system encoded text (or charset defined by 150 * {@link org.apache.juneau.parser.ReaderParser.Builder#fileCharset(Charset)} property value). 151 * </ul> 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(Object input, Class<T> type) throws ParseException, IOException { 158 return DEFAULT.read(input, type); 159 } 160 161 /** 162 * Parses an OpenApi input object 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 169 * The input. 170 * <br>Can be any of the following types: 171 * <ul> 172 * <li><jk>null</jk> 173 * <li>{@link Reader} 174 * <li>{@link CharSequence} 175 * <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by 176 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 177 * <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by 178 * {@link org.apache.juneau.parser.ReaderParser.Builder#streamCharset(Charset)} property value). 179 * <li>{@link File} containing system encoded text (or charset defined by 180 * {@link org.apache.juneau.parser.ReaderParser.Builder#fileCharset(Charset)} property value). 181 * </ul> 182 * @param type 183 * The object type to create. 184 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 185 * @param args 186 * The type arguments of the class if it's a collection or map. 187 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 188 * <br>Ignored if the main type is not a map or collection. 189 * @return The parsed object. 190 * @throws ParseException Malformed input encountered. 191 * @throws IOException Thrown by underlying stream. 192 * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections. 193 */ 194 public static <T> T to(Object input, Type type, Type...args) throws ParseException, IOException { 195 return DEFAULT.read(input, type, args); 196 } 197 198 /** 199 * Parses an OpenApi input string to the specified type. 200 * 201 * <p> 202 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>. 203 * 204 * @param <T> The class type of the object being created. 205 * @param input The input. 206 * @param type The object type to create. 207 * @return The parsed object. 208 * @throws ParseException Malformed input encountered. 209 */ 210 public static <T> T to(String input, Class<T> type) throws ParseException { 211 return DEFAULT.read(input, type); 212 } 213 214 /** 215 * Parses an OpenApi input string to the specified Java type. 216 * 217 * <p> 218 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>. 219 * 220 * @param <T> The class type of the object to create. 221 * @param input The input. 222 * @param type 223 * The object type to create. 224 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 225 * @param args 226 * The type arguments of the class if it's a collection or map. 227 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 228 * <br>Ignored if the main type is not a map or collection. 229 * @return The parsed object. 230 * @throws ParseException Malformed input encountered. 231 * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections. 232 */ 233 public static <T> T to(String input, Type type, Type...args) throws ParseException { 234 return DEFAULT.read(input, type, args); 235 } 236 237 private final OpenApiSerializer s; 238 239 private final OpenApiParser p; 240 241 /** 242 * Constructor. 243 * 244 * <p> 245 * Uses {@link OpenApiSerializer#DEFAULT} and {@link OpenApiParser#DEFAULT}. 246 */ 247 public OpenApi() { 248 this(OpenApiSerializer.DEFAULT, OpenApiParser.DEFAULT); 249 } 250 251 /** 252 * Constructor. 253 * 254 * @param s 255 * The serializer to use for serializing output. 256 * <br>Must not be <jk>null</jk>. 257 * @param p 258 * The parser to use for parsing input. 259 * <br>Must not be <jk>null</jk>. 260 */ 261 public OpenApi(OpenApiSerializer s, OpenApiParser p) { 262 super(s, p); 263 this.s = s; 264 this.p = p; 265 } 266}