From: David Reiss Date: Fri, 21 Nov 2008 21:55:52 +0000 (+0000) Subject: THRIFT-142. java: Better handling of required fields X-Git-Tag: 0.2.0~401 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=fd71808e35af5ba82a29320abfcbc30ef7fc6b87;p=common%2Fthrift.git 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 3c71d9e9..5606f81a 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -885,6 +885,17 @@ void t_java_generator::generate_java_struct_reader(ofstream& out, 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 @@ void t_java_generator::generate_java_struct_writer(ofstream& out, const vector& fields = tstruct->get_members(); vector::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;