THRIFT-1038. java: Generated Java code for structures containing binary fields (or...
authorBryan Duxbury <bryanduxbury@apache.org>
Wed, 26 Jan 2011 22:42:02 +0000 (22:42 +0000)
committerBryan Duxbury <bryanduxbury@apache.org>
Wed, 26 Jan 2011 22:42:02 +0000 (22:42 +0000)
This patch causes Java Serialized Thrift structs to be serialized onto the stream via the Compact Protocol.

Patch: Mathias Herberts

git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1063907 13f79535-47bb-0310-9956-ffa450edef68

compiler/cpp/src/generate/t_java_generator.cc
lib/java/test/org/apache/thrift/TestStruct.java
lib/java/test/org/apache/thrift/TestTUnion.java

index a7904dc..b56d720 100644 (file)
@@ -100,6 +100,8 @@ class t_java_generator : public t_oop_generator {
   void generate_java_struct_writer(std::ofstream& out, t_struct* tstruct);
   void generate_java_struct_tostring(std::ofstream& out, t_struct* tstruct);
   void generate_java_struct_clear(std::ofstream& out, t_struct* tstruct);
+  void generate_java_struct_write_object(std::ofstream& out, t_struct* tstruct);
+  void generate_java_struct_read_object(std::ofstream& out, t_struct* tstruct);
   void generate_java_meta_data_map(std::ofstream& out, t_struct* tstruct);
   void generate_field_value_meta_data(std::ofstream& out, t_type* type);
   std::string get_java_type_string(t_type* type);
@@ -725,6 +727,14 @@ void t_java_generator::generate_java_union(t_struct* tstruct) {
 
   f_struct << endl;
 
+  generate_java_struct_write_object(f_struct, tstruct);
+
+  f_struct << endl;
+
+  generate_java_struct_read_object(f_struct, tstruct);
+
+  f_struct << endl;
+
   scope_down(f_struct);
 
   f_struct.close();
@@ -1261,6 +1271,10 @@ void t_java_generator::generate_java_struct_definition(ofstream &out,
   }
   generate_java_struct_tostring(out, tstruct);
   generate_java_validator(out, tstruct);
+
+  generate_java_struct_write_object(out, tstruct);
+  generate_java_struct_read_object(out, tstruct);
+
   scope_down(out);
   out << endl;
 }
@@ -3957,6 +3971,32 @@ void t_java_generator::generate_java_struct_clear(std::ofstream& out, t_struct*
   indent(out) << "}" << endl << endl;
 }
 
+// generates java method to serialize (in the Java sense) the object
+void t_java_generator::generate_java_struct_write_object(ofstream& out, t_struct* tstruct) {
+  indent(out) << "private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {" << endl;
+  indent(out) << "  try {" << endl;
+  indent(out) << "    write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));" << endl;
+  indent(out) << "  } catch (org.apache.thrift.TException te) {" << endl;
+  indent(out) << "    throw new java.io.IOException(te);" << endl;
+  indent(out) << "  }" << endl;
+  indent(out) << "}" << endl << endl;
+}
+
+// generates java method to serialize (in the Java sense) the object
+void t_java_generator::generate_java_struct_read_object(ofstream& out, t_struct* tstruct) {
+  indent(out) << "private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {" << endl;
+  indent(out) << "  try {" << endl;
+  if (!tstruct->is_union() && has_bit_vector(tstruct)) {
+    indent(out) << "    // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor." << endl;
+    indent(out) << "    __isset_bit_vector = new BitSet(1);" << endl;
+  }
+  indent(out) << "    read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));" << endl;
+  indent(out) << "  } catch (org.apache.thrift.TException te) {" << endl;
+  indent(out) << "    throw new java.io.IOException(te);" << endl;
+  indent(out) << "  }" << endl;
+  indent(out) << "}" << endl << endl;
+}
+
 THRIFT_REGISTER_GENERATOR(java, "Java",
 "    beans:           Members will be private, and setter methods will return void.\n"
 "    private-members: Members will be private, but setter methods will return 'this' like usual.\n"
index 52e4017..61162d9 100644 (file)
  */
 package org.apache.thrift;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
 import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.Map;
@@ -309,4 +314,22 @@ public class TestStruct extends TestCase {
     o.setReq_bin((byte[])null);
     assertNull(o.getReq_bin());
   }
+
+  public void testJavaSerializable() throws Exception {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ObjectOutputStream oos = new ObjectOutputStream(baos);
+    
+    OneOfEach ooe = Fixtures.oneOfEach;
+
+    // Serialize ooe the Java way...
+    oos.writeObject(ooe);
+    byte[] serialized = baos.toByteArray();
+
+    // Attempt to deserialize it
+    ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
+    ObjectInputStream ois = new ObjectInputStream(bais);
+    OneOfEach ooe2 = (OneOfEach) ois.readObject();
+
+    assertEquals(ooe, ooe2);
+  }
 }
index 775db52..a044101 100644 (file)
  */
 package org.apache.thrift;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -200,4 +204,22 @@ public class TestTUnion extends TestCase {
     String expectedString = "<ComparableUnion binary_field:01 02 03>";
     assertEquals(expectedString, cu.toString());
   }
+
+  public void testJavaSerializable() throws Exception {
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    ObjectOutputStream oos = new ObjectOutputStream(baos);
+    
+    TestUnion tu = TestUnion.string_field("string");
+
+    // Serialize tu the Java way...
+    oos.writeObject(tu);
+    byte[] serialized = baos.toByteArray();
+
+    // Attempt to deserialize it
+    ByteArrayInputStream bais = new ByteArrayInputStream(serialized);
+    ObjectInputStream ois = new ObjectInputStream(bais);
+    TestUnion tu2 = (TestUnion) ois.readObject();
+
+    assertEquals(tu, tu2);
+  }
 }