Author: dreiss
Date: Fri Nov 21 13:55:52 2008
New Revision: 719727

URL: http://svn.apache.org/viewvc?rev=719727&view=rev
Log:
THRIFT-142. java: Better handling of required fields

- On reading, behave the same way as the C++ code:
  throw an exception if a required field is missing.
- In addition, throw an exception if a required field is missing
  when writing.  For the JavaBeans code, this means that __isset
  is false (because it is maintained automatically).  For non-beans
  code, this means that the field is null.  Non-nullable fields are
  not checked in non-beans code.

Modified:
    incubator/thrift/trunk/compiler/cpp/src/generate/t_java_generator.cc

Modified: incubator/thrift/trunk/compiler/cpp/src/generate/t_java_generator.cc
URL: 
http://svn.apache.org/viewvc/incubator/thrift/trunk/compiler/cpp/src/generate/t_java_generator.cc?rev=719727&r1=719726&r2=719727&view=diff
==============================================================================
--- incubator/thrift/trunk/compiler/cpp/src/generate/t_java_generator.cc 
(original)
+++ incubator/thrift/trunk/compiler/cpp/src/generate/t_java_generator.cc Fri 
Nov 21 13:55:52 2008
@@ -885,6 +885,17 @@
     out <<
       indent() << "iprot.readStructEnd();" << endl;
 
+    // check to make sure all required fields are set
+    out << endl << indent() << "// check for required fields" << endl;
+    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+      if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
+        out <<
+          indent() << "if (!__isset." << (*f_iter)->get_name() << ") {" << 
endl <<
+          indent() << "  throw new TProtocolException(\"Required field '" << 
(*f_iter)->get_name() << "' was not found in serialized data!\");" << endl <<
+          indent() << "}" << endl;
+      }
+    }
+
   indent_down();
   out <<
     indent() << "}" << endl <<
@@ -906,6 +917,28 @@
   const vector<t_field*>& fields = tstruct->get_members();
   vector<t_field*>::const_iterator f_iter;
 
+  // check for required fields
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    t_field* field = (*f_iter);
+    if (field->get_req() == t_field::T_REQUIRED) {
+      if (bean_style_) {
+        indent(out) << "if (!__isset." << field->get_name() << ") {" << endl;
+        indent(out) << "  throw new TProtocolException(\"Required field '" << 
field->get_name() << "' was not present!\");" << endl;
+        indent(out) << "}" << endl;
+      } else {
+        if (type_can_be_null(field->get_type())) {
+          indent(out) << "if (" << field->get_name() << " == null) {" << endl;
+          indent(out) << "  throw new TProtocolException(\"Required field '" 
<< field->get_name() << "' was not present!\");" << endl;
+          indent(out) << "}" << endl;
+        } else {
+          indent(out) << "// alas, we cannot check '" << field->get_name() << 
"' because it's a primitive and you chose the non-beans generator." << endl;
+        }
+      }
+    }
+  }
+
+  out << endl << endl;
+
   indent(out) << "TStruct struct = new TStruct(\"" << name << "\");" << endl;
   indent(out) << "oprot.writeStructBegin(struct);" << endl;
 


Reply via email to