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.marshall.marshaller; 018 019import org.apache.juneau.marshall.msgpack.*; 020import java.io.*; 021import java.lang.reflect.*; 022import org.apache.juneau.marshall.parser.*; 023import org.apache.juneau.marshall.serializer.*; 024import org.apache.juneau.marshall.stream.*; 025 026/** 027 * A pairing of a {@link MsgPackSerializer} and {@link MsgPackParser} into a single class with convenience to/of methods. 028 * 029 * <p> 030 * The general idea is to combine a single serializer and parser inside a simplified API for serializing and parsing POJOs. 031 * 032 * <h5 class='figure'>Examples:</h5> 033 * <p class='bjava'> 034 * <jc>// Using instance.</jc> 035 * MsgPack <jv>msgPack</jv> = <jk>new</jk> MsgPack(); 036 * MyPojo <jv>myPojo</jv> = <jv>msgPack</jv>.read(<jv>bytes</jv>, MyPojo.<jk>class</jk>); 037 * <jk>byte</jk>[] <jv>bytes</jv> = <jv>msgPack</jv>.write(<jv>myPojo</jv>); 038 * </p> 039 * <p class='bjava'> 040 * <jc>// Using DEFAULT instance.</jc> 041 * MyPojo <jv>myPojo</jv> = MsgPack.<jsf>DEFAULT</jsf>.read(<jv>bytes</jv>, MyPojo.<jk>class</jk>); 042 * <jk>byte</jk>[] <jv>bytes</jv> = MsgPack.<jsf>DEFAULT</jsf>.write(<jv>myPojo</jv>); 043 * </p> 044 * 045 * <p class='bjava'> 046 * <jc>// Using static shortcuts.</jc> 047 * MyPojo <jv>myPojo</jv> = MsgPack.<jsm>to</jsm>(<jv>bytes</jv>, MyPojo.<jk>class</jk>); 048 * <jk>byte</jk>[] <jv>bytes</jv> = MsgPack.<jsm>of</jsm>(<jv>myPojo</jv>); 049 * </p> 050 * 051 * <h5 class='section'>See Also:</h5><ul> 052 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshallers">Marshallers</a> 053 * </ul> 054 */ 055@SuppressWarnings({ 056 "resource" // Cursor shortcut methods return Closeables owned by the caller; Eclipse JDT @Owning warning is by design. 057}) 058public class MsgPack extends StreamMarshaller { 059 060 /** 061 * Default reusable instance. 062 */ 063 public static final MsgPack DEFAULT = new MsgPack(); 064 065 /** 066 * Serializes a POJO to a <code><jk>byte</jk>[]</code> using the {@link #DEFAULT} marshaller. 067 * 068 * <p> 069 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>)</c>. 070 * 071 * @param object The object to serialize. 072 * @return The serialized object. 073 * @throws SerializeException If a problem occurred trying to convert the output. 074 */ 075 public static byte[] of(Object object) throws SerializeException { 076 return DEFAULT.write(object); 077 } 078 079 /** 080 * Parses an input into the specified object type using the {@link #DEFAULT} marshaller. 081 * 082 * <p> 083 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>. 084 * 085 * @param <T> The class type of the object being created. 086 * @param input The input. 087 * @param type The object type to create. 088 * @return The parsed object. 089 * @throws ParseException Malformed input encountered. 090 */ 091 public static <T> T to(byte[] input, Class<T> type) throws ParseException { 092 return DEFAULT.read(input, type); 093 } 094 095 /** 096 * Parses an input into the specified parameterized object type using the {@link #DEFAULT} marshaller. 097 * 098 * <p> 099 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>. 100 * 101 * @param <T> The class type of the object to create. 102 * @param input The input. 103 * @param type The object type to create. 104 * @param args The type arguments of the class if it's a collection or map. 105 * @return The parsed object. 106 * @throws ParseException Malformed input encountered. 107 */ 108 public static <T> T to(byte[] input, Type type, Type... args) throws ParseException { 109 return DEFAULT.read(input, type, args); 110 } 111 112 /** 113 * Parses the contents of an {@link InputStream} into the specified object type using the {@link #DEFAULT} marshaller. 114 * 115 * <p> 116 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c> that catches any 117 * {@link IOException} from the underlying stream and rethrows it as an unchecked {@link ParseException}, so the 118 * caller is not burdened with a checked exception. 119 * 120 * @param <T> The class type of the object being created. 121 * @param input The input stream. 122 * @param type The object type to create. 123 * @return The parsed object. 124 * @throws ParseException Malformed input encountered or an I/O error occurred on the underlying stream. 125 */ 126 public static <T> T to(InputStream input, Class<T> type) throws ParseException { 127 try { 128 return DEFAULT.read(input, type); 129 } catch (IOException e) { 130 throw new ParseException(e); 131 } 132 } 133 134 /** 135 * Parses the contents of an {@link InputStream} into the specified parameterized object type using the {@link #DEFAULT} marshaller. 136 * 137 * <p> 138 * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c> that catches any 139 * {@link IOException} from the underlying stream and rethrows it as an unchecked {@link ParseException}, so the 140 * caller is not burdened with a checked exception. 141 * 142 * @param <T> The class type of the object to create. 143 * @param input The input stream. 144 * @param type The object type to create. 145 * @param args The type arguments of the class if it's a collection or map. 146 * @return The parsed object. 147 * @throws ParseException Malformed input encountered or an I/O error occurred on the underlying stream. 148 */ 149 public static <T> T to(InputStream input, Type type, Type... args) throws ParseException { 150 try { 151 return DEFAULT.read(input, type, args); 152 } catch (IOException e) { 153 throw new ParseException(e); 154 } 155 } 156 157 /** 158 * Serializes a POJO to the specified {@link OutputStream} using the {@link #DEFAULT} marshaller. 159 * 160 * <p> 161 * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>, <jv>output</jv>)</c> that catches any 162 * {@link IOException} from the underlying stream and rethrows it as an unchecked {@link SerializeException}, so the 163 * caller is not burdened with a checked exception. 164 * 165 * @param object The object to serialize. 166 * @param output The output stream to serialize to. 167 * @throws SerializeException If a problem occurred trying to convert the output or an I/O error occurred on the underlying stream. 168 */ 169 public static void of(Object object, OutputStream output) throws SerializeException { 170 try { 171 DEFAULT.write(object, output); 172 } catch (IOException e) { 173 throw new SerializeException(e); 174 } 175 } 176 177 /** 178 * Opens a low-level {@link TokenReader} cursor over the specified input using the {@link #DEFAULT} marshaller. 179 * 180 * <p> 181 * A shortcut for calling <c><jsf>DEFAULT</jsf>.readTokens(<jv>input</jv>)</c>. 182 * 183 * @param input The input. 184 * @return A new {@link TokenReader}. 185 * @throws IOException If a problem occurred opening the underlying input. 186 */ 187 public static TokenReader toTokens(Object input) throws IOException { 188 return DEFAULT.readTokens(input); 189 } 190 191 /** 192 * Opens a low-level {@link TokenWriter} generator over the specified output using the {@link #DEFAULT} marshaller. 193 * 194 * <p> 195 * A shortcut for calling <c><jsf>DEFAULT</jsf>.writeTokens(<jv>output</jv>)</c>. 196 * 197 * @param output The output. 198 * @return A new {@link TokenWriter}. 199 * @throws IOException If a problem occurred opening the underlying output. 200 */ 201 public static TokenWriter ofTokens(Object output) throws IOException { 202 return DEFAULT.writeTokens(output); 203 } 204 205 /** 206 * Opens a low-level {@link RecordReader} cursor over the specified input using the {@link #DEFAULT} marshaller. 207 * 208 * <p> 209 * A shortcut for calling <c><jsf>DEFAULT</jsf>.readRecords(<jv>input</jv>)</c>. 210 * 211 * @param input The input. 212 * @return A new {@link RecordReader}. 213 * @throws IOException If a problem occurred opening the underlying input. 214 */ 215 public static RecordReader toRecords(Object input) throws IOException { 216 return DEFAULT.readRecords(input); 217 } 218 219 /** 220 * Opens a low-level {@link RecordWriter} cursor over the specified output using the {@link #DEFAULT} marshaller. 221 * 222 * <p> 223 * A shortcut for calling <c><jsf>DEFAULT</jsf>.writeRecords(<jv>output</jv>)</c>. 224 * 225 * @param output The output. 226 * @return A new {@link RecordWriter}. 227 * @throws IOException If a problem occurred opening the underlying output. 228 */ 229 public static RecordWriter ofRecords(Object output) throws IOException { 230 return DEFAULT.writeRecords(output); 231 } 232 233 /** 234 * Opens a {@link RecordReader} that yields each element of a top-level wire array using the {@link #DEFAULT} marshaller. 235 * 236 * <p> 237 * A shortcut for calling <c><jsf>DEFAULT</jsf>.readArrayRecords(<jv>input</jv>)</c>. 238 * 239 * @param input The input. 240 * @return A new {@link RecordReader}. 241 * @throws IOException If a problem occurred opening the underlying input. 242 */ 243 public static RecordReader toArrayRecords(Object input) throws IOException { 244 return DEFAULT.readArrayRecords(input); 245 } 246 247 /** 248 * Opens a {@link RecordWriter} that wraps each written value as one element of a top-level wire array using the {@link #DEFAULT} marshaller. 249 * 250 * <p> 251 * A shortcut for calling <c><jsf>DEFAULT</jsf>.writeArrayRecords(<jv>output</jv>)</c>. 252 * 253 * @param output The output. 254 * @return A new {@link RecordWriter}. 255 * @throws IOException If a problem occurred opening the underlying output. 256 */ 257 public static RecordWriter ofArrayRecords(Object output) throws IOException { 258 return DEFAULT.writeArrayRecords(output); 259 } 260 261 /** 262 * Constructor. 263 * 264 * <p> 265 * Uses {@link MsgPackSerializer#DEFAULT} and {@link MsgPackParser#DEFAULT}. 266 */ 267 public MsgPack() { 268 this(MsgPackSerializer.DEFAULT, MsgPackParser.DEFAULT); 269 } 270 271 /** 272 * Constructor. 273 * 274 * @param s 275 * The serializer to use for serializing output. 276 * <br>Must not be <jk>null</jk>. 277 * @param p 278 * The parser to use for parsing input. 279 * <br>Must not be <jk>null</jk>. 280 */ 281 public MsgPack(MsgPackSerializer s, MsgPackParser p) { 282 super(s, p); 283 } 284}