Do not generate write code for null fields in Java

Summary: It will make null pointer exceptions!

Reviewed By: martin, alex


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664923 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
index ea2d22a..d8c1459 100644
--- a/compiler/cpp/src/generate/t_java_generator.cc
+++ b/compiler/cpp/src/generate/t_java_generator.cc
@@ -479,6 +479,13 @@
     indent() << "oprot.writeStructBegin(struct);" << endl;
 
   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    bool null_allowed = type_can_be_null((*f_iter)->get_type());
+    if (null_allowed) {
+      out <<
+        indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl;
+      indent_up();
+    }
+
     out <<
       indent() << "field.name = \"" << (*f_iter)->get_name() << "\";" << endl <<
       indent() << "field.type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl <<
@@ -491,6 +498,11 @@
     // Write field closer
     indent(out) <<
       "oprot.writeFieldEnd();" << endl;
+    
+    if (null_allowed) {
+      indent_down();
+      indent(out) << "}" << endl;
+    }
   }
   // Write the struct map
   out <<
@@ -541,6 +553,13 @@
       "(this.__isset." << (*f_iter)->get_name() << ") {" << endl;
     indent_up();
 
+    bool null_allowed = type_can_be_null((*f_iter)->get_type());
+    if (null_allowed) {
+      out <<
+        indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl;
+      indent_up();
+    }
+
     out <<
       indent() << "field.name = \"" << (*f_iter)->get_name() << "\";" << endl <<
       indent() << "field.type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl <<
@@ -554,6 +573,11 @@
     indent(out) <<
       "oprot.writeFieldEnd();" << endl;
 
+    if (null_allowed) {
+      indent_down();
+      indent(out) << "}" << endl;
+    }
+
     indent_down();
     indent(out) << "}";
   }
diff --git a/compiler/cpp/src/generate/t_java_generator.h b/compiler/cpp/src/generate/t_java_generator.h
index b21c76a..35748e5 100644
--- a/compiler/cpp/src/generate/t_java_generator.h
+++ b/compiler/cpp/src/generate/t_java_generator.h
@@ -129,6 +129,19 @@
   std::string argument_list(t_struct* tstruct);
   std::string type_to_enum(t_type* ttype);
 
+  bool type_can_be_null(t_type* ttype) {
+    while (ttype->is_typedef()) {
+      ttype = ((t_typedef*)ttype)->get_type();
+    }
+
+    return
+      ttype->is_container() || 
+      ttype->is_struct() ||
+      ttype->is_xception() ||
+      (ttype->is_base_type() && (((t_base_type*)ttype)->get_base() == t_base_type::TYPE_STRING));
+  }
+
+
  private:
 
   /**