1 package org.apache.directmemory.serialization.protobuf;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import static java.lang.String.format;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.lang.reflect.Method;
27
28 import org.apache.directmemory.serialization.Serializer;
29
30 import com.google.protobuf.GeneratedMessage;
31 import com.google.protobuf.Message;
32
33 public final class ProtobufSerializer
34 implements Serializer
35 {
36
37 private static final String NEW_BUILDER_METHOD = "newBuilder";
38
39
40
41
42 @Override
43 public <T> byte[] serialize( T obj )
44 throws IOException
45 {
46 checkProtobufMessage( obj.getClass() );
47
48 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
49
50 try
51 {
52 ( (Message) obj ).writeTo( baos );
53 }
54 finally
55 {
56 try
57 {
58 baos.close();
59 }
60 catch ( Exception e )
61 {
62
63 }
64 }
65
66 return baos.toByteArray();
67 }
68
69
70
71
72 @Override
73 public <T> T deserialize( byte[] source, Class<T> clazz )
74 throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException
75 {
76 clazz = checkProtobufMessage( clazz );
77
78 try
79 {
80 Method newBuilder = clazz.getMethod( NEW_BUILDER_METHOD );
81
82
83 GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke( clazz );
84
85 @SuppressWarnings( "unchecked" )
86 T deserialized = (T) builder.mergeFrom( source ).build();
87
88 return deserialized;
89 }
90 catch ( Throwable t )
91 {
92 throw new IOException( t );
93 }
94 }
95
96 private static <T> Class<T> checkProtobufMessage( Class<T> clazz )
97 {
98 if ( !Message.class.isAssignableFrom( clazz ) )
99 {
100 throw new IllegalArgumentException( format( "Class %s cannot be serialized via Google Protobuf, it is not a %s",
101 clazz.getName(),
102 Message.class.getName() ) );
103 }
104 return clazz;
105 }
106
107 }