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.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@719727 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 3c71d9e..5606f81 100644
--- a/compiler/cpp/src/generate/t_java_generator.cc
+++ b/compiler/cpp/src/generate/t_java_generator.cc
@@ -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;