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.protobuf.*;
020import java.io.*;
021import java.lang.reflect.*;
022import org.apache.juneau.marshall.parser.*;
023import org.apache.juneau.marshall.serializer.*;
024
025/**
026 * A pairing of a {@link ProtobufSerializer} and {@link ProtobufParser} into a single class with convenience read/write
027 * methods.
028 *
029 * <p>
030 * Output is binary (<code><jk>byte</jk>[]</code>) in the Protocol Buffers <b>binary</b> wire format.
031 *
032 * <p>
033 * Distinct from the text-format {@link Prototext} marshaller (<c>text/protobuf</c>):  this marshaller emits the compact,
034 * non-self-describing protobuf binary wire format and requires the target type on read.
035 *
036 * <h5 class='figure'>Examples:</h5>
037 * <p class='bjava'>
038 *    <jc>// Using static convenience methods</jc>
039 *    byte[] <jv>protobuf</jv> = Protobuf.<jsm>of</jsm>(<jv>myBean</jv>);
040 *    MyBean <jv>parsed</jv> = Protobuf.<jsm>to</jsm>(<jv>protobuf</jv>, MyBean.<jk>class</jk>);
041 * </p>
042 * <p class='bjava'>
043 *    <jc>// Using the DEFAULT instance</jc>
044 *    byte[] <jv>protobuf</jv> = Protobuf.<jsf>DEFAULT</jsf>.write(<jv>myBean</jv>);
045 *    MyBean <jv>parsed</jv> = Protobuf.<jsf>DEFAULT</jsf>.read(<jv>protobuf</jv>, MyBean.<jk>class</jk>);
046 * </p>
047 *
048 * <p class='bjava'>
049 * <jc>// Using static shortcuts.</jc>
050 *    MyPojo <jv>myPojo</jv> = Protobuf.<jsm>to</jsm>(<jv>bytes</jv>, MyPojo.<jk>class</jk>);
051 *    <jk>byte</jk>[] <jv>bytes</jv> = Protobuf.<jsm>of</jsm>(<jv>myPojo</jv>);
052 * </p>
053 *
054 * <h5 class='section'>See Also:</h5><ul>
055 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Marshallers">Marshallers</a>
056 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/Protobuf">Protobuf Binary Format Basics</a>
057 * </ul>
058 */
059public class Protobuf extends StreamMarshaller {
060
061   /**
062    * Default reusable instance.
063    */
064   public static final Protobuf DEFAULT = new Protobuf();
065
066   /**
067    * Serializes a POJO to a <code><jk>byte</jk>[]</code> using the {@link #DEFAULT} marshaller.
068    *
069    * <p>
070    * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>)</c>.
071    *
072    * @param object The object to serialize.
073    * @return The serialized object.
074    * @throws SerializeException If a problem occurred trying to convert the output.
075    */
076   public static byte[] of(Object object) throws SerializeException {
077      return DEFAULT.write(object);
078   }
079
080   /**
081    * Parses an input into the specified object type using the {@link #DEFAULT} marshaller.
082    *
083    * <p>
084    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c>.
085    *
086    * @param <T> The class type of the object being created.
087    * @param input The input.
088    * @param type The object type to create.
089    * @return The parsed object.
090    * @throws ParseException Malformed input encountered.
091    */
092   public static <T> T to(byte[] input, Class<T> type) throws ParseException {
093      return DEFAULT.read(input, type);
094   }
095
096   /**
097    * Parses an input into the specified parameterized object type using the {@link #DEFAULT} marshaller.
098    *
099    * <p>
100    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c>.
101    *
102    * @param <T> The class type of the object to create.
103    * @param input The input.
104    * @param type The object type to create.
105    * @param args The type arguments of the class if it's a collection or map.
106    * @return The parsed object.
107    * @throws ParseException Malformed input encountered.
108    */
109   public static <T> T to(byte[] input, Type type, Type... args) throws ParseException {
110      return DEFAULT.read(input, type, args);
111   }
112
113   /**
114    * Parses the contents of an {@link InputStream} into the specified object type using the {@link #DEFAULT} marshaller.
115    *
116    * <p>
117    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>)</c> that catches any
118    * {@link IOException} from the underlying stream and rethrows it as an unchecked {@link ParseException}, so the
119    * caller is not burdened with a checked exception.
120    *
121    * @param <T> The class type of the object being created.
122    * @param input The input stream.
123    * @param type The object type to create.
124    * @return The parsed object.
125    * @throws ParseException Malformed input encountered or an I/O error occurred on the underlying stream.
126    */
127   public static <T> T to(InputStream input, Class<T> type) throws ParseException {
128      try {
129         return DEFAULT.read(input, type);
130      } catch (IOException e) {
131         throw new ParseException(e);
132      }
133   }
134
135   /**
136    * Parses the contents of an {@link InputStream} into the specified parameterized object type using the {@link #DEFAULT} marshaller.
137    *
138    * <p>
139    * A shortcut for calling <c><jsf>DEFAULT</jsf>.read(<jv>input</jv>, <jv>type</jv>, <jv>args</jv>)</c> that catches any
140    * {@link IOException} from the underlying stream and rethrows it as an unchecked {@link ParseException}, so the
141    * caller is not burdened with a checked exception.
142    *
143    * @param <T> The class type of the object to create.
144    * @param input The input stream.
145    * @param type The object type to create.
146    * @param args The type arguments of the class if it's a collection or map.
147    * @return The parsed object.
148    * @throws ParseException Malformed input encountered or an I/O error occurred on the underlying stream.
149    */
150   public static <T> T to(InputStream input, Type type, Type... args) throws ParseException {
151      try {
152         return DEFAULT.read(input, type, args);
153      } catch (IOException e) {
154         throw new ParseException(e);
155      }
156   }
157
158   /**
159    * Serializes a POJO to the specified {@link OutputStream} using the {@link #DEFAULT} marshaller.
160    *
161    * <p>
162    * A shortcut for calling <c><jsf>DEFAULT</jsf>.write(<jv>object</jv>, <jv>output</jv>)</c> that catches any
163    * {@link IOException} from the underlying stream and rethrows it as an unchecked {@link SerializeException}, so the
164    * caller is not burdened with a checked exception.
165    *
166    * @param object The object to serialize.
167    * @param output The output stream to serialize to.
168    * @throws SerializeException If a problem occurred trying to convert the output or an I/O error occurred on the underlying stream.
169    */
170   public static void of(Object object, OutputStream output) throws SerializeException {
171      try {
172         DEFAULT.write(object, output);
173      } catch (IOException e) {
174         throw new SerializeException(e);
175      }
176   }
177
178   /**
179    * Constructor.
180    *
181    * <p>
182    * Uses {@link ProtobufSerializer#DEFAULT} and {@link ProtobufParser#DEFAULT}.
183    */
184   public Protobuf() {
185      this(ProtobufSerializer.DEFAULT, ProtobufParser.DEFAULT);
186   }
187
188   /**
189    * Constructor.
190    *
191    * @param s The serializer to use for serializing output.
192    * @param p The parser to use for parsing input.
193    */
194   public Protobuf(ProtobufSerializer s, ProtobufParser p) {
195      super(s, p);
196   }
197}