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}