From 1121b47c09470a454a28a46825f92ef29c4dc273 Mon Sep 17 00:00:00 2001 From: Bryan Duxbury Date: Thu, 11 Aug 2011 18:50:58 +0000 Subject: [PATCH] THRIFT-169. java: Pluggable Serializers THRIFT-1239. java: TupleProtocol- An extremely compact, temporary protocol This monster commit is the combination of the two above tickets, providing a new serialization framework and the first new consumer in one go. Patch: Armaan Sarkar git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1156728 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/generate/t_java_generator.cc | 1140 +++++++++-------- .../thrift/protocol/TCompactProtocol.java | 2 +- .../org/apache/thrift/protocol/TProtocol.java | 9 + .../thrift/protocol/TTupleProtocol.java | 97 ++ .../src/org/apache/thrift/scheme/IScheme.java | 29 + .../apache/thrift/scheme/SchemeFactory.java | 25 + .../apache/thrift/scheme/StandardScheme.java | 25 + .../org/apache/thrift/scheme/TupleScheme.java | 25 + lib/java/test/org/apache/thrift/Fixtures.java | 80 +- .../thrift/protocol/TestTTupleProtocol.java | 24 + 10 files changed, 910 insertions(+), 546 deletions(-) create mode 100644 lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java create mode 100644 lib/java/src/org/apache/thrift/scheme/IScheme.java create mode 100644 lib/java/src/org/apache/thrift/scheme/SchemeFactory.java create mode 100644 lib/java/src/org/apache/thrift/scheme/StandardScheme.java create mode 100644 lib/java/src/org/apache/thrift/scheme/TupleScheme.java create mode 100644 lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index f9ed5e29..f3686553 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -37,12 +37,12 @@ using namespace std; * */ class t_java_generator : public t_oop_generator { - public: +public: t_java_generator( - t_program* program, - const std::map& parsed_options, - const std::string& option_string) - : t_oop_generator(program) + t_program* program, + const std::map& parsed_options, + const std::string& option_string) + : t_oop_generator(program) { (void) option_string; std::map::const_iterator iter; @@ -65,7 +65,7 @@ class t_java_generator : public t_oop_generator { iter = parsed_options.find("java5"); java5_ = (iter != parsed_options.end()); if (java5_) { - android_legacy_ = true; + android_legacy_ = true; } out_dir_base_ = (bean_style_ ? "gen-javabean" : "gen-java"); @@ -125,7 +125,7 @@ class t_java_generator : public t_oop_generator { std::string get_cap_name(std::string name); std::string generate_isset_check(t_field* field); std::string generate_isset_check(std::string field); - void generate_isset_set(ofstream& out, t_field* field); + void generate_isset_set(ofstream& out, t_field* field, std::string prefix); std::string isset_field_id(t_field* field); void generate_service_interface (t_service* tservice); @@ -151,13 +151,23 @@ class t_java_generator : public t_oop_generator { void generate_union_comparisons(ofstream& out, t_struct* tstruct); void generate_union_hashcode(ofstream& out, t_struct* tstruct); + void generate_scheme_map(ofstream& out, t_struct* tstruct); + void generate_standard_writer(ofstream& out, t_struct* tstruct); + void generate_standard_reader(ofstream& out, t_struct* tstruct); + void generate_java_struct_standard_scheme(ofstream& out, t_struct* tstruct); + + void generate_java_struct_tuple_scheme(ofstream& out, t_struct* tstruct); + void generate_java_struct_tuple_reader(ofstream& out, t_struct* tstruct); + void generate_java_struct_tuple_writer(ofstream& out, t_struct* tstruct); + /** * Serialization constructs */ void generate_deserialize_field (std::ofstream& out, t_field* tfield, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_deserialize_struct (std::ofstream& out, t_struct* tstruct, @@ -165,23 +175,28 @@ class t_java_generator : public t_oop_generator { void generate_deserialize_container (std::ofstream& out, t_type* ttype, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_deserialize_set_element (std::ofstream& out, t_set* tset, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_deserialize_map_element (std::ofstream& out, t_map* tmap, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_deserialize_list_element (std::ofstream& out, t_list* tlist, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_serialize_field (std::ofstream& out, t_field* tfield, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_serialize_struct (std::ofstream& out, t_struct* tstruct, @@ -189,20 +204,24 @@ class t_java_generator : public t_oop_generator { void generate_serialize_container (std::ofstream& out, t_type* ttype, - std::string prefix=""); + std::string prefix="", + bool has_metadata = true); void generate_serialize_map_element (std::ofstream& out, t_map* tmap, std::string iter, - std::string map); + std::string map, + bool has_metadata = true); void generate_serialize_set_element (std::ofstream& out, t_set* tmap, - std::string iter); + std::string iter, + bool has_metadata = true); void generate_serialize_list_element (std::ofstream& out, t_list* tlist, - std::string iter); + std::string iter, + bool has_metadata = true); void generate_java_doc (std::ofstream& out, t_field* field); @@ -270,7 +289,6 @@ class t_java_generator : public t_oop_generator { bool gen_hash_code_; bool android_legacy_; bool java5_; - }; @@ -327,6 +345,11 @@ string t_java_generator::java_type_imports() { return string() + hash_builder + + "import org.apache.thrift.scheme.IScheme;\n" + + "import org.apache.thrift.scheme.SchemeFactory;\n" + + "import org.apache.thrift.scheme.StandardScheme;\n\n" + + "import org.apache.thrift.scheme.TupleScheme;\n" + + "import org.apache.thrift.protocol.TTupleProtocol;\n" + "import java.util.List;\n" + "import java.util.ArrayList;\n" + "import java.util.Map;\n" + @@ -433,14 +456,14 @@ void t_java_generator::generate_enum(t_enum* tenum) { indent(f_enum) << "case " << value << ":" << endl; indent(f_enum) << " return " << (*c_iter)->get_name() << ";" << endl; } - + indent(f_enum) << "default:" << endl; indent(f_enum) << " return null;" << endl; indent_down(); indent(f_enum) << "}" << endl; - + indent_down(); indent(f_enum) << "}" << endl; @@ -482,8 +505,7 @@ void t_java_generator::generate_consts(std::vector consts) { false); } indent_down(); - indent(f_consts) << - "}" << endl; + indent(f_consts) << "}" << endl; f_consts.close(); } @@ -592,33 +614,33 @@ string t_java_generator::render_const_value(ofstream& out, t_type* type, t_const if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { - case t_base_type::TYPE_STRING: - render << '"' << get_escaped_string(value) << '"'; - break; - case t_base_type::TYPE_BOOL: - render << ((value->get_integer() > 0) ? "true" : "false"); - break; - case t_base_type::TYPE_BYTE: - render << "(byte)" << value->get_integer(); - break; - case t_base_type::TYPE_I16: - render << "(short)" << value->get_integer(); - break; - case t_base_type::TYPE_I32: - render << value->get_integer(); - break; - case t_base_type::TYPE_I64: - render << value->get_integer() << "L"; - break; - case t_base_type::TYPE_DOUBLE: - if (value->get_type() == t_const_value::CV_INTEGER) { - render << "(double)" << value->get_integer(); - } else { - render << value->get_double(); - } - break; - default: - throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); + case t_base_type::TYPE_STRING: + render << '"' << get_escaped_string(value) << '"'; + break; + case t_base_type::TYPE_BOOL: + render << ((value->get_integer() > 0) ? "true" : "false"); + break; + case t_base_type::TYPE_BYTE: + render << "(byte)" << value->get_integer(); + break; + case t_base_type::TYPE_I16: + render << "(short)" << value->get_integer(); + break; + case t_base_type::TYPE_I32: + render << value->get_integer(); + break; + case t_base_type::TYPE_I64: + render << value->get_integer() << "L"; + break; + case t_base_type::TYPE_DOUBLE: + if (value->get_type() == t_const_value::CV_INTEGER) { + render << "(double)" << value->get_integer(); + } else { + render << value->get_double(); + } + break; + default: + throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { render << type->get_program()->get_namespace("java") << "." << value->get_identifier_with_parent(); @@ -670,7 +692,7 @@ void t_java_generator::generate_java_struct(t_struct* tstruct, f_struct << autogen_comment() << java_package() << - java_type_imports(); + java_type_imports(); generate_java_struct_definition(f_struct, tstruct, @@ -732,7 +754,7 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { f_struct << endl; generate_union_is_set_methods(f_struct, tstruct); - + f_struct << endl; generate_union_comparisons(f_struct, tstruct); @@ -751,6 +773,10 @@ void t_java_generator::generate_java_union(t_struct* tstruct) { f_struct << endl; + // generate_java_struct_standard_scheme(f_struct, tstruct); + + f_struct << endl; + scope_down(f_struct); f_struct.close(); @@ -797,7 +823,7 @@ void t_java_generator::generate_union_constructor(ofstream& out, t_struct* tstru void t_java_generator::generate_union_getters_and_setters(ofstream& out, t_struct* tstruct) { const vector& members = tstruct->get_members(); vector::const_iterator m_iter; - + bool first = true; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (first) { @@ -911,7 +937,7 @@ void t_java_generator::generate_check_type(ofstream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - + indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; indent(out) << " if (value instanceof " << type_name(field->get_type(), true, false, true) << ") {" << endl; indent(out) << " break;" << endl; @@ -921,13 +947,13 @@ void t_java_generator::generate_check_type(ofstream& out, t_struct* tstruct) { << "', but got \" + value.getClass().getSimpleName());" << endl; // do the real check here } - + indent(out) << "default:" << endl; indent(out) << " throw new IllegalArgumentException(\"Unknown field id \" + setField);" << endl; indent_down(); indent(out) << "}" << endl; - + indent_down(); indent(out) << "}" << endl; } @@ -949,7 +975,7 @@ void t_java_generator::generate_read_value(ofstream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - + indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; indent_up(); indent(out) << "if (field.type == " << constant_name(field->get_name()) << "_FIELD_DESC.type) {" << endl; @@ -997,16 +1023,16 @@ void t_java_generator::generate_write_value(ofstream& out, t_struct* tstruct) { for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { t_field* field = (*m_iter); - + indent(out) << "case " << constant_name(field->get_name()) << ":" << endl; indent_up(); indent(out) << type_name(field->get_type(), true, false) << " " << field->get_name() << " = (" << type_name(field->get_type(), true, false) << ")value_;" << endl; - generate_serialize_field(out, field, ""); + generate_serialize_field(out, field, "", false); indent(out) << "return;" << endl; indent_down(); } - + indent(out) << "default:" << endl; indent(out) << " throw new IllegalStateException(\"Cannot write union with unknown field \" + setField_);" << endl; @@ -1015,8 +1041,6 @@ void t_java_generator::generate_write_value(ofstream& out, t_struct* tstruct) { indent_down(); - - indent(out) << "}" << endl; } @@ -1024,7 +1048,7 @@ void t_java_generator::generate_get_field_desc(ofstream& out, t_struct* tstruct) indent(out) << "@Override" << endl; indent(out) << "protected org.apache.thrift.protocol.TField getFieldDesc(_Fields setField) {" << endl; indent_up(); - + const vector& members = tstruct->get_members(); vector::const_iterator m_iter; @@ -1134,7 +1158,7 @@ void t_java_generator::generate_java_struct_definition(ofstream &out, indent(out) << "public " << (is_final ? "final " : "") << - (in_class ? "static " : "") << "class " << tstruct->get_name() << " "; + (in_class ? "static " : "") << "class " << tstruct->get_name() << " "; if (is_exception) { out << "extends Exception "; @@ -1157,6 +1181,10 @@ void t_java_generator::generate_java_struct_definition(ofstream &out, out << endl; + generate_scheme_map(out, tstruct); + + out << endl; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { if (bean_style_ || private_members_) { indent(out) << "private "; @@ -1178,7 +1206,11 @@ void t_java_generator::generate_java_struct_definition(ofstream &out, indent(out) << "// isset id assignments" << endl; int i = 0; + int optionals = 0; for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() == t_field::T_OPTIONAL) { + optionals++; + } if (!type_can_be_null((*m_iter)->get_type())) { indent(out) << "private static final int " << isset_field_id(*m_iter) << " = " << i << ";" << endl; @@ -1189,8 +1221,15 @@ void t_java_generator::generate_java_struct_definition(ofstream &out, if (i > 0) { indent(out) << "private BitSet __isset_bit_vector = new BitSet(" << i << ");" << endl; } - - out << endl; + if (optionals > 0) { + std::string output_string = "private _Fields optionals[] = {"; + for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { + if ((*m_iter)->get_req() == t_field::T_OPTIONAL) { + output_string = output_string + "_Fields." + constant_name((*m_iter)->get_name()) + ","; + } + } + indent(out) << output_string.substr(0, output_string.length() - 1) << "};" << endl; + } } generate_java_meta_data_map(out, tstruct); @@ -1238,9 +1277,10 @@ void t_java_generator::generate_java_struct_definition(ofstream &out, if ((*m_iter)->get_req() != t_field::T_OPTIONAL) { indent(out) << "this." << (*m_iter)->get_name() << " = " << (*m_iter)->get_name() << ";" << endl; - generate_isset_set(out, (*m_iter)); + generate_isset_set(out, (*m_iter), ""); } } + indent_down(); indent(out) << "}" << endl << endl; } @@ -1313,6 +1353,9 @@ void t_java_generator::generate_java_struct_definition(ofstream &out, generate_java_struct_write_object(out, tstruct); generate_java_struct_read_object(out, tstruct); + generate_java_struct_standard_scheme(out, tstruct); + generate_java_struct_tuple_scheme(out, tstruct); + scope_down(out); out << endl; } @@ -1366,15 +1409,15 @@ void t_java_generator::generate_java_struct_equality(ofstream& out, out << indent() << "boolean this_present_" << name << " = " - << this_present << ";" << endl << + << this_present << ";" << endl << indent() << "boolean that_present_" << name << " = " - << that_present << ";" << endl << + << that_present << ";" << endl << indent() << "if (" << "this_present_" << name - << " || that_present_" << name << ") {" << endl; + << " || that_present_" << name << ") {" << endl; indent_up(); out << indent() << "if (!(" << "this_present_" << name - << " && that_present_" << name << "))" << endl << + << " && that_present_" << name << "))" << endl << indent() << " return false;" << endl; if (t->is_base_type() && ((t_base_type*)t)->is_binary()) { @@ -1478,105 +1521,18 @@ void t_java_generator::generate_java_struct_compare_to(ofstream& out, t_struct* */ void t_java_generator::generate_java_struct_reader(ofstream& out, t_struct* tstruct) { - out << - indent() << "public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {" << endl; + indent(out) << "public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {" << endl; indent_up(); - - const vector& fields = tstruct->get_members(); - vector::const_iterator f_iter; - - // Declare stack tmp variables and read struct header - out << - indent() << "org.apache.thrift.protocol.TField field;" << endl << - indent() << "iprot.readStructBegin();" << endl; - - // Loop over reading in fields - indent(out) << - "while (true)" << endl; - scope_up(out); - - // Read beginning field marker - indent(out) << - "field = iprot.readFieldBegin();" << endl; - - // Check for field STOP marker and break - indent(out) << - "if (field.type == org.apache.thrift.protocol.TType.STOP) { " << endl; - indent_up(); - indent(out) << - "break;" << endl; - indent_down(); - indent(out) << - "}" << endl; - - // Switch statement on the field we are reading - indent(out) << "switch (field.id) {" << endl; - - indent_up(); - - // Generate deserialization code for known cases - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - indent(out) << - "case " << (*f_iter)->get_key() << ": // " << constant_name((*f_iter)->get_name()) << endl; - indent_up(); - indent(out) << - "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; - indent_up(); - - generate_deserialize_field(out, *f_iter, "this."); - generate_isset_set(out, *f_iter); - indent_down(); - out << - indent() << "} else { " << endl << - indent() << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << endl << - indent() << "}" << endl << - indent() << "break;" << endl; - indent_down(); - } - - indent(out) << "default:" << endl; - indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);" << endl; - - indent_down(); - indent(out) << "}" << endl; - - // Read field end marker - indent(out) << - "iprot.readFieldEnd();" << endl; - - indent_down(); - indent(out) << "}" << endl; - - out << - indent() << "iprot.readStructEnd();" << endl; - - // in non-beans style, check for required fields of primitive type - // (which can be checked here but not in the general validate method) - if (!bean_style_){ - out << endl << indent() << "// check for required fields of primitive type, which can't be checked in the validate method" << endl; - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { - out << - indent() << "if (!" << generate_isset_check(*f_iter) << ") {" << endl << - indent() << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" << (*f_iter)->get_name() << "' was not found in serialized data! Struct: \" + toString());" << endl << - indent() << "}" << endl; - } - } - } - - // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl; - + indent(out) << "schemes.get(iprot.getScheme()).getScheme().read(iprot, this);" << endl; indent_down(); - out << - indent() << "}" << endl << - endl; + indent(out) << "}" << endl << + endl; } // generates java method to perform various checks // (e.g. check that all required fields are set) void t_java_generator::generate_java_validator(ofstream& out, - t_struct* tstruct){ + t_struct* tstruct){ indent(out) << "public void validate() throws org.apache.thrift.TException {" << endl; indent_up(); @@ -1614,59 +1570,12 @@ void t_java_generator::generate_java_validator(ofstream& out, */ void t_java_generator::generate_java_struct_writer(ofstream& out, t_struct* tstruct) { - out << - indent() << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {" << endl; + indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {" << endl; indent_up(); - - string name = tstruct->get_name(); - const vector& fields = tstruct->get_sorted_members(); - vector::const_iterator f_iter; - - // performs various checks (e.g. check that all required fields are set) - indent(out) << "validate();" << endl << endl; - - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << 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(); - } - bool optional = (*f_iter)->get_req() == t_field::T_OPTIONAL; - if (optional) { - indent(out) << "if (" << generate_isset_check((*f_iter)) << ") {" << endl; - indent_up(); - } - - indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) << "_FIELD_DESC);" << endl; - - // Write field contents - generate_serialize_field(out, *f_iter, "this."); - - // Write field closer - indent(out) << - "oprot.writeFieldEnd();" << endl; - - if (optional) { - indent_down(); - indent(out) << "}" << endl; - } - if (null_allowed) { - indent_down(); - indent(out) << "}" << endl; - } - } - // Write the struct map - out << - indent() << "oprot.writeFieldStop();" << endl << - indent() << "oprot.writeStructEnd();" << endl; + indent(out) << "schemes.get(oprot.getScheme()).getScheme().write(oprot, this);" << endl; indent_down(); - out << - indent() << "}" << endl << - endl; + indent(out) << " }" << endl << endl; } /** @@ -1679,53 +1588,12 @@ void t_java_generator::generate_java_struct_writer(ofstream& out, */ void t_java_generator::generate_java_struct_result_writer(ofstream& out, t_struct* tstruct) { - out << - indent() << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {" << endl; + indent(out) << "public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {" << endl; indent_up(); - - string name = tstruct->get_name(); - const vector& fields = tstruct->get_sorted_members(); - vector::const_iterator f_iter; - - indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl; - - bool first = true; - for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - if (first) { - first = false; - out << - endl << - indent() << "if "; - } else { - out << " else if "; - } - - out << "(this." << generate_isset_check(*f_iter) << ") {" << endl; - - indent_up(); - - indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) << "_FIELD_DESC);" << endl; - - // Write field contents - generate_serialize_field(out, *f_iter, "this."); - - // Write field closer - indent(out) << - "oprot.writeFieldEnd();" << endl; - - indent_down(); - indent(out) << "}"; - } - // Write the struct map - out << - endl << - indent() << "oprot.writeFieldStop();" << endl << - indent() << "oprot.writeStructEnd();" << endl; - + indent(out) << "schemes.get(oprot.getScheme()).getScheme().write(oprot, this);" << endl; + indent_down(); - out << - indent() << "}" << endl << - endl; + indent(out) << " }" << endl << endl; } void t_java_generator::generate_java_struct_field_by_id(ofstream& out, t_struct* tstruct) { @@ -1764,7 +1632,6 @@ void t_java_generator::generate_reflection_setters(ostringstream& out, t_type* t } void t_java_generator::generate_generic_field_getters_setters(std::ofstream& out, t_struct* tstruct) { - std::ostringstream getter_stream; std::ostringstream setter_stream; @@ -1861,7 +1728,6 @@ void t_java_generator::generate_java_bean_boilerplate(ofstream& out, } if (type->is_set() || type->is_list()) { - t_type* element_type; if (type->is_set()) { element_type = ((t_set*)type)->get_elem_type(); @@ -1895,7 +1761,6 @@ void t_java_generator::generate_java_bean_boilerplate(ofstream& out, indent(out) << "this." << field_name << ".add(elem);" << endl; indent_down(); indent(out) << "}" << endl << endl; - } else if (type->is_map()) { // Put to map t_type* key_type = ((t_map*)type)->get_key_type(); @@ -1968,9 +1833,8 @@ void t_java_generator::generate_java_bean_boilerplate(ofstream& out, } out << " set" << cap_name << "(" << type_name(type) << " " << field_name << ") {" << endl; indent_up(); - indent(out) << "this." << field_name << " = " << field_name << ";" << - endl; - generate_isset_set(out, field); + indent(out) << "this." << field_name << " = " << field_name << ";" << endl; + generate_isset_set(out, field, ""); if (!bean_style_) { indent(out) << "return this;" << endl; } @@ -2053,13 +1917,13 @@ void t_java_generator::generate_java_struct_tostring(ofstream& out, indent(out) << "} else {" << endl; indent_up(); } - + if (field->get_type()->is_base_type() && ((t_base_type*)(field->get_type()))->is_binary()) { indent(out) << "org.apache.thrift.TBaseHelper.toString(this." << field->get_name() << ", sb);" << endl; } else { indent(out) << "sb.append(this." << (*f_iter)->get_name() << ");" << endl; } - + if (can_be_null) { indent_down(); indent(out) << "}" << endl; @@ -2077,8 +1941,7 @@ void t_java_generator::generate_java_struct_tostring(ofstream& out, indent() << "return sb.toString();" << endl; indent_down(); - indent(out) << "}" << endl << - endl; + indent(out) << "}" << endl << endl; } /** @@ -2217,9 +2080,7 @@ void t_java_generator::generate_service(t_service* tservice) { java_package() << java_type_imports(); - f_service_ << - "public class " << service_name_ << " {" << endl << - endl; + f_service_ << "public class " << service_name_ << " {" << endl << endl; indent_up(); // Generate the three main parts of the service @@ -2332,11 +2193,9 @@ void t_java_generator::generate_service_client(t_service* tservice) { indent_down(); indent(f_service_) << "}" << endl << endl; - indent(f_service_) << - "public Client(org.apache.thrift.protocol.TProtocol prot)" << endl; + indent(f_service_) << "public Client(org.apache.thrift.protocol.TProtocol prot)" << endl; scope_up(f_service_); - indent(f_service_) << - "super(prot, prot);" << endl; + indent(f_service_) << "super(prot, prot);" << endl; scope_down(f_service_); f_service_ << endl; @@ -2352,11 +2211,9 @@ void t_java_generator::generate_service_client(t_service* tservice) { string funname = (*f_iter)->get_name(); // Open function - indent(f_service_) << - "public " << function_signature(*f_iter) << endl; + indent(f_service_) << "public " << function_signature(*f_iter) << endl; scope_up(f_service_); - indent(f_service_) << - "send_" << funname << "("; + indent(f_service_) << "send_" << funname << "("; // Get the struct of function call params t_struct* arg_struct = (*f_iter)->get_arglist(); @@ -2401,8 +2258,7 @@ void t_java_generator::generate_service_client(t_service* tservice) { indent(f_service_) << argsname << " args = new " << argsname << "();" << endl; for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) { - f_service_ << - indent() << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" << (*fld_iter)->get_name() << ");" << endl; + indent(f_service_) << "args.set" << get_cap_name((*fld_iter)->get_name()) << "(" << (*fld_iter)->get_name() << ");" << endl; } indent(f_service_) << "sendBase(\"" << funname << "\", args);" << endl; @@ -2447,8 +2303,7 @@ void t_java_generator::generate_service_client(t_service* tservice) { // If you get here it's an exception, unless a void function if ((*f_iter)->get_returntype()->is_void()) { - indent(f_service_) << - "return;" << endl; + indent(f_service_) << "return;" << endl; } else { f_service_ << indent() << "throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, \"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl; @@ -2461,8 +2316,7 @@ void t_java_generator::generate_service_client(t_service* tservice) { } indent_down(); - indent(f_service_) << - "}" << endl; + indent(f_service_) << "}" << endl; } void t_java_generator::generate_service_async_client(t_service* tservice) { @@ -2715,8 +2569,7 @@ void t_java_generator::generate_process_function(t_service* tservice, // Try block for a function with exceptions if (xceptions.size() > 0) { - f_service_ << - indent() << "try {" << endl; + f_service_ << indent() << "try {" << endl; indent_up(); } @@ -2729,8 +2582,7 @@ void t_java_generator::generate_process_function(t_service* tservice, if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) { f_service_ << "result.success = "; } - f_service_ << - "iface." << tfunction->get_name() << "("; + f_service_ << "iface." << tfunction->get_name() << "("; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { @@ -2744,8 +2596,7 @@ void t_java_generator::generate_process_function(t_service* tservice, // Set isset on success field if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void() && !type_can_be_null(tfunction->get_returntype())) { - f_service_ << - indent() << "result.set" << get_cap_name("success") << get_cap_name("isSet") << "(true);" << endl; + indent(f_service_) << "result.set" << get_cap_name("success") << get_cap_name("isSet") << "(true);" << endl; } if (!tfunction->is_oneway() && xceptions.size() > 0) { @@ -2779,9 +2630,7 @@ void t_java_generator::generate_process_function(t_service* tservice, // Close class indent_down(); - f_service_ << - indent() << "}" << endl << - endl; + f_service_ << indent() << "}" << endl << endl; } /** @@ -2792,12 +2641,11 @@ void t_java_generator::generate_process_function(t_service* tservice, */ void t_java_generator::generate_deserialize_field(ofstream& out, t_field* tfield, - string prefix) { + string prefix, bool has_metadata) { t_type* type = get_true_type(tfield->get_type()); if (type->is_void()) { - throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + - prefix + tfield->get_name(); + throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name(); } string name = prefix + tfield->get_name(); @@ -2807,15 +2655,15 @@ void t_java_generator::generate_deserialize_field(ofstream& out, (t_struct*)type, name); } else if (type->is_container()) { - generate_deserialize_container(out, type, name); + generate_deserialize_container(out, type, name, has_metadata); } else if (type->is_base_type()) { indent(out) << name << " = iprot."; + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { case t_base_type::TYPE_VOID: - throw "compiler error: cannot serialize void field in a struct: " + - name; + throw "compiler error: cannot serialize void field in a struct: " + name; break; case t_base_type::TYPE_STRING: if (((t_base_type*)type)->is_binary()) { @@ -2870,7 +2718,8 @@ void t_java_generator::generate_deserialize_struct(ofstream& out, */ void t_java_generator::generate_deserialize_container(ofstream& out, t_type* ttype, - string prefix) { + string prefix, bool has_metadata) { + scope_up(out); string obj; @@ -2883,19 +2732,32 @@ void t_java_generator::generate_deserialize_container(ofstream& out, obj = tmp("_list"); } - // Declare variables, read header - if (ttype->is_map()) { - indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = iprot.readMapBegin();" << endl; - } else if (ttype->is_set()) { - indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = iprot.readSetBegin();" << endl; - } else if (ttype->is_list()) { - indent(out) << "org.apache.thrift.protocol.TList " << obj << " = iprot.readListBegin();" << endl; + if (has_metadata) { + // Declare variables, read header + if (ttype->is_map()) { + indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = iprot.readMapBegin();" << endl; + } else if (ttype->is_set()) { + indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = iprot.readSetBegin();" << endl; + } else if (ttype->is_list()) { + indent(out) << "org.apache.thrift.protocol.TList " << obj << " = iprot.readListBegin();" << endl; + } + } else { + // Declare variables, read header + if (ttype->is_map()) { + indent(out) << "org.apache.thrift.protocol.TMap " << obj << " = new org.apache.thrift.protocol.TMap(" << + type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << "iprot.readI32());" << endl; + } else if (ttype->is_set()) { + indent(out) << "org.apache.thrift.protocol.TSet " << obj << " = new org.apache.thrift.protocol.TSet(" << + type_to_enum(((t_set*)ttype)->get_elem_type()) << ", iprot.readI32());" << endl; + } else if (ttype->is_list()) { + indent(out) << "org.apache.thrift.protocol.TList " << obj << " = new org.apache.thrift.protocol.TList(" << + type_to_enum(((t_set*)ttype)->get_elem_type()) << ", iprot.readI32());" << endl; + } } - indent(out) - << prefix << " = new " << type_name(ttype, false, true) - // size the collection correctly - << "(" + indent(out) << prefix << " = new " << type_name(ttype, false, true); + // size the collection correctly + out << "(" << (ttype->is_list() ? "" : "2*" ) << obj << ".size" << ");" << endl; @@ -2907,52 +2769,50 @@ void t_java_generator::generate_deserialize_container(ofstream& out, i << " < " << obj << ".size" << "; " << "++" << i << ")" << endl; - scope_up(out); - - if (ttype->is_map()) { - generate_deserialize_map_element(out, (t_map*)ttype, prefix); - } else if (ttype->is_set()) { - generate_deserialize_set_element(out, (t_set*)ttype, prefix); - } else if (ttype->is_list()) { - generate_deserialize_list_element(out, (t_list*)ttype, prefix); - } - - scope_down(out); + scope_up(out); - // Read container end if (ttype->is_map()) { - indent(out) << "iprot.readMapEnd();" << endl; + generate_deserialize_map_element(out, (t_map*)ttype, prefix, has_metadata); } else if (ttype->is_set()) { - indent(out) << "iprot.readSetEnd();" << endl; + generate_deserialize_set_element(out, (t_set*)ttype, prefix, has_metadata); } else if (ttype->is_list()) { - indent(out) << "iprot.readListEnd();" << endl; + generate_deserialize_list_element(out, (t_list*)ttype, prefix, has_metadata); } scope_down(out); -} - + + if (has_metadata) { + // Read container end + if (ttype->is_map()) { + indent(out) << "iprot.readMapEnd();" << endl; + } else if (ttype->is_set()) { + indent(out) << "iprot.readSetEnd();" << endl; + } else if (ttype->is_list()) { + indent(out) << "iprot.readListEnd();" << endl; + } + } + scope_down(out); +} + /** * Generates code to deserialize a map */ void t_java_generator::generate_deserialize_map_element(ofstream& out, t_map* tmap, - string prefix) { + string prefix, bool has_metadata) { string key = tmp("_key"); string val = tmp("_val"); t_field fkey(tmap->get_key_type(), key); t_field fval(tmap->get_val_type(), val); - indent(out) << - declare_field(&fkey) << endl; - indent(out) << - declare_field(&fval) << endl; + indent(out) << declare_field(&fkey) << endl; + indent(out) << declare_field(&fval) << endl; - generate_deserialize_field(out, &fkey); - generate_deserialize_field(out, &fval); + generate_deserialize_field(out, &fkey, "", has_metadata); + generate_deserialize_field(out, &fval, "", has_metadata); - indent(out) << - prefix << ".put(" << key << ", " << val << ");" << endl; + indent(out) << prefix << ".put(" << key << ", " << val << ");" << endl; } /** @@ -2960,17 +2820,15 @@ void t_java_generator::generate_deserialize_map_element(ofstream& out, */ void t_java_generator::generate_deserialize_set_element(ofstream& out, t_set* tset, - string prefix) { + string prefix, bool has_metadata) { string elem = tmp("_elem"); t_field felem(tset->get_elem_type(), elem); - indent(out) << - declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << endl; - generate_deserialize_field(out, &felem); + generate_deserialize_field(out, &felem, "", has_metadata); - indent(out) << - prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << endl; } /** @@ -2978,20 +2836,17 @@ void t_java_generator::generate_deserialize_set_element(ofstream& out, */ void t_java_generator::generate_deserialize_list_element(ofstream& out, t_list* tlist, - string prefix) { + string prefix, bool has_metadata) { string elem = tmp("_elem"); t_field felem(tlist->get_elem_type(), elem); - indent(out) << - declare_field(&felem) << endl; + indent(out) << declare_field(&felem) << endl; - generate_deserialize_field(out, &felem); + generate_deserialize_field(out, &felem, "", has_metadata); - indent(out) << - prefix << ".add(" << elem << ");" << endl; + indent(out) << prefix << ".add(" << elem << ");" << endl; } - /** * Serializes a field of any type. * @@ -3000,13 +2855,12 @@ void t_java_generator::generate_deserialize_list_element(ofstream& out, */ void t_java_generator::generate_serialize_field(ofstream& out, t_field* tfield, - string prefix) { + string prefix, bool has_metadata) { t_type* type = get_true_type(tfield->get_type()); // Do nothing for void types if (type->is_void()) { - throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + - prefix + tfield->get_name(); + throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name(); } if (type->is_struct() || type->is_xception()) { @@ -3016,51 +2870,49 @@ void t_java_generator::generate_serialize_field(ofstream& out, } else if (type->is_container()) { generate_serialize_container(out, type, - prefix + tfield->get_name()); + prefix + tfield->get_name(), has_metadata); } else if (type->is_enum()){ indent(out) << "oprot.writeI32(" << prefix + tfield->get_name() << ".getValue());" << endl; } else if (type->is_base_type()) { string name = prefix + tfield->get_name(); - indent(out) << - "oprot."; + indent(out) << "oprot."; if (type->is_base_type()) { - t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); + t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { - case t_base_type::TYPE_VOID: - throw - "compiler error: cannot serialize void field in a struct: " + name; - break; - case t_base_type::TYPE_STRING: - if (((t_base_type*)type)->is_binary()) { - out << "writeBinary(" << name << ");"; - } else { - out << "writeString(" << name << ");"; - } - break; - case t_base_type::TYPE_BOOL: - out << "writeBool(" << name << ");"; - break; - case t_base_type::TYPE_BYTE: - out << "writeByte(" << name << ");"; - break; - case t_base_type::TYPE_I16: - out << "writeI16(" << name << ");"; - break; - case t_base_type::TYPE_I32: - out << "writeI32(" << name << ");"; - break; - case t_base_type::TYPE_I64: - out << "writeI64(" << name << ");"; - break; - case t_base_type::TYPE_DOUBLE: - out << "writeDouble(" << name << ");"; - break; - default: - throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); + case t_base_type::TYPE_VOID: + throw "compiler error: cannot serialize void field in a struct: " + name; + break; + case t_base_type::TYPE_STRING: + if (((t_base_type*)type)->is_binary()) { + out << "writeBinary(" << name << ");"; + } else { + out << "writeString(" << name << ");"; + } + break; + case t_base_type::TYPE_BOOL: + out << "writeBool(" << name << ");"; + break; + case t_base_type::TYPE_BYTE: + out << "writeByte(" << name << ");"; + break; + case t_base_type::TYPE_I16: + out << "writeI16(" << name << ");"; + break; + case t_base_type::TYPE_I32: + out << "writeI32(" << name << ");"; + break; + case t_base_type::TYPE_I64: + out << "writeI64(" << name << ");"; + break; + case t_base_type::TYPE_DOUBLE: + out << "writeDouble(" << name << ");"; + break; + default: + throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); } } else if (type->is_enum()) { - out << "writeI32(" << name << ");"; + out << "writeI32(struct." << name << ");"; } out << endl; } else { @@ -3081,8 +2933,7 @@ void t_java_generator::generate_serialize_struct(ofstream& out, t_struct* tstruct, string prefix) { (void) tstruct; - out << - indent() << prefix << ".write(oprot);" << endl; + out << indent() << prefix << ".write(oprot);" << endl; } /** @@ -3093,25 +2944,29 @@ void t_java_generator::generate_serialize_struct(ofstream& out, */ void t_java_generator::generate_serialize_container(ofstream& out, t_type* ttype, - string prefix) { + string prefix, bool has_metadata) { scope_up(out); - if (ttype->is_map()) { - indent(out) << - "oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(" << - type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << - type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << - prefix << ".size()));" << endl; - } else if (ttype->is_set()) { - indent(out) << - "oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(" << - type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << - prefix << ".size()));" << endl; - } else if (ttype->is_list()) { - indent(out) << - "oprot.writeListBegin(new org.apache.thrift.protocol.TList(" << - type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << - prefix << ".size()));" << endl; + if (has_metadata) { + if (ttype->is_map()) { + indent(out) << + "oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(" << + type_to_enum(((t_map*)ttype)->get_key_type()) << ", " << + type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << + prefix << ".size()));" << endl; + } else if (ttype->is_set()) { + indent(out) << + "oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(" << + type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " << + prefix << ".size()));" << endl; + } else if (ttype->is_list()) { + indent(out) << + "oprot.writeListBegin(new org.apache.thrift.protocol.TList(" << + type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << + prefix << ".size()));" << endl; + } + } else { + indent(out) << "oprot.writeI32(" << prefix << ".size());" << endl; } string iter = tmp("_iter"); @@ -3139,23 +2994,22 @@ void t_java_generator::generate_serialize_container(ofstream& out, out << endl; scope_up(out); if (ttype->is_map()) { - generate_serialize_map_element(out, (t_map*)ttype, iter, prefix); + generate_serialize_map_element(out, (t_map*)ttype, iter, prefix, has_metadata); } else if (ttype->is_set()) { - generate_serialize_set_element(out, (t_set*)ttype, iter); + generate_serialize_set_element(out, (t_set*)ttype, iter, has_metadata); } else if (ttype->is_list()) { - generate_serialize_list_element(out, (t_list*)ttype, iter); + generate_serialize_list_element(out, (t_list*)ttype, iter, has_metadata); } scope_down(out); - if (ttype->is_map()) { - indent(out) << - "oprot.writeMapEnd();" << endl; - } else if (ttype->is_set()) { - indent(out) << - "oprot.writeSetEnd();" << endl; - } else if (ttype->is_list()) { - indent(out) << - "oprot.writeListEnd();" << endl; + if (has_metadata) { + if (ttype->is_map()) { + indent(out) << "oprot.writeMapEnd();" << endl; + } else if (ttype->is_set()) { + indent(out) << "oprot.writeSetEnd();" << endl; + } else if (ttype->is_list()) { + indent(out) << "oprot.writeListEnd();" << endl; + } } scope_down(out); @@ -3167,12 +3021,12 @@ void t_java_generator::generate_serialize_container(ofstream& out, void t_java_generator::generate_serialize_map_element(ofstream& out, t_map* tmap, string iter, - string map) { + string map, bool has_metadata) { (void) map; t_field kfield(tmap->get_key_type(), iter + ".getKey()"); - generate_serialize_field(out, &kfield, ""); + generate_serialize_field(out, &kfield, "", has_metadata); t_field vfield(tmap->get_val_type(), iter + ".getValue()"); - generate_serialize_field(out, &vfield, ""); + generate_serialize_field(out, &vfield, "", has_metadata); } /** @@ -3180,9 +3034,10 @@ void t_java_generator::generate_serialize_map_element(ofstream& out, */ void t_java_generator::generate_serialize_set_element(ofstream& out, t_set* tset, - string iter) { + string iter, + bool has_metadata) { t_field efield(tset->get_elem_type(), iter); - generate_serialize_field(out, &efield, ""); + generate_serialize_field(out, &efield, "", has_metadata); } /** @@ -3190,9 +3045,10 @@ void t_java_generator::generate_serialize_set_element(ofstream& out, */ void t_java_generator::generate_serialize_list_element(ofstream& out, t_list* tlist, - string iter) { + string iter, + bool has_metadata) { t_field efield(tlist->get_elem_type(), iter); - generate_serialize_field(out, &efield, ""); + generate_serialize_field(out, &efield, "", has_metadata); } /** @@ -3217,8 +3073,8 @@ string t_java_generator::type_name(t_type* ttype, bool in_container, bool in_ini prefix = "Map"; } return prefix + (skip_generic ? "" : "<" + - type_name(tmap->get_key_type(), true) + "," + - type_name(tmap->get_val_type(), true) + ">"); + type_name(tmap->get_key_type(), true) + "," + + type_name(tmap->get_val_type(), true) + ">"); } else if (ttype->is_set()) { t_set* tset = (t_set*) ttype; if (in_init) { @@ -3260,28 +3116,28 @@ string t_java_generator::base_type_name(t_base_type* type, t_base_type::t_base tbase = type->get_base(); switch (tbase) { - case t_base_type::TYPE_VOID: - return "void"; - case t_base_type::TYPE_STRING: - if (type->is_binary()) { - return "ByteBuffer"; - } else { - return "String"; - } - case t_base_type::TYPE_BOOL: - return (in_container ? "Boolean" : "boolean"); - case t_base_type::TYPE_BYTE: - return (in_container ? "Byte" : "byte"); - case t_base_type::TYPE_I16: - return (in_container ? "Short" : "short"); - case t_base_type::TYPE_I32: - return (in_container ? "Integer" : "int"); - case t_base_type::TYPE_I64: - return (in_container ? "Long" : "long"); - case t_base_type::TYPE_DOUBLE: - return (in_container ? "Double" : "double"); - default: - throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); + case t_base_type::TYPE_VOID: + return "void"; + case t_base_type::TYPE_STRING: + if (type->is_binary()) { + return "ByteBuffer"; + } else { + return "String"; + } + case t_base_type::TYPE_BOOL: + return (in_container ? "Boolean" : "boolean"); + case t_base_type::TYPE_BYTE: + return (in_container ? "Byte" : "byte"); + case t_base_type::TYPE_I16: + return (in_container ? "Short" : "short"); + case t_base_type::TYPE_I32: + return (in_container ? "Integer" : "int"); + case t_base_type::TYPE_I64: + return (in_container ? "Long" : "long"); + case t_base_type::TYPE_DOUBLE: + return (in_container ? "Double" : "double"); + default: + throw "compiler error: no Java name for base type " + t_base_type::t_base_name(tbase); } } @@ -3302,25 +3158,24 @@ string t_java_generator::declare_field(t_field* tfield, bool init) { } else if (ttype->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base(); switch (tbase) { - case t_base_type::TYPE_VOID: - throw "NO T_VOID CONSTRUCT"; - case t_base_type::TYPE_STRING: - result += " = null"; - break; - case t_base_type::TYPE_BOOL: - result += " = false"; - break; - case t_base_type::TYPE_BYTE: - case t_base_type::TYPE_I16: - case t_base_type::TYPE_I32: - case t_base_type::TYPE_I64: - result += " = 0"; - break; - case t_base_type::TYPE_DOUBLE: - result += " = (double)0"; - break; - } - + case t_base_type::TYPE_VOID: + throw "NO T_VOID CONSTRUCT"; + case t_base_type::TYPE_STRING: + result += " = null"; + break; + case t_base_type::TYPE_BOOL: + result += " = false"; + break; + case t_base_type::TYPE_BYTE: + case t_base_type::TYPE_I16: + case t_base_type::TYPE_I32: + case t_base_type::TYPE_I64: + result += " = 0"; + break; + case t_base_type::TYPE_DOUBLE: + result += " = (double)0"; + break; + } } else if (ttype->is_enum()) { result += " = 0"; } else if (ttype->is_container()) { @@ -3360,11 +3215,11 @@ string t_java_generator::function_signature(t_function* tfunction, } /** - * Renders a function signature of the form 'void name(args, resultHandler)' - * - * @params tfunction Function definition - * @return String of rendered function definition - */ + * Renders a function signature of the form 'void name(args, resultHandler)' + * + * @params tfunction Function definition + * @return String of rendered function definition + */ string t_java_generator::function_signature_async(t_function* tfunction, bool use_base_method, string prefix) { std::string arglist = async_function_call_arglist(tfunction, use_base_method, true); @@ -3457,22 +3312,22 @@ string t_java_generator::type_to_enum(t_type* type) { if (type->is_base_type()) { t_base_type::t_base tbase = ((t_base_type*)type)->get_base(); switch (tbase) { - case t_base_type::TYPE_VOID: - throw "NO T_VOID CONSTRUCT"; - case t_base_type::TYPE_STRING: - return "org.apache.thrift.protocol.TType.STRING"; - case t_base_type::TYPE_BOOL: - return "org.apache.thrift.protocol.TType.BOOL"; - case t_base_type::TYPE_BYTE: - return "org.apache.thrift.protocol.TType.BYTE"; - case t_base_type::TYPE_I16: - return "org.apache.thrift.protocol.TType.I16"; - case t_base_type::TYPE_I32: - return "org.apache.thrift.protocol.TType.I32"; - case t_base_type::TYPE_I64: - return "org.apache.thrift.protocol.TType.I64"; - case t_base_type::TYPE_DOUBLE: - return "org.apache.thrift.protocol.TType.DOUBLE"; + case t_base_type::TYPE_VOID: + throw "NO T_VOID CONSTRUCT"; + case t_base_type::TYPE_STRING: + return "org.apache.thrift.protocol.TType.STRING"; + case t_base_type::TYPE_BOOL: + return "org.apache.thrift.protocol.TType.BOOL"; + case t_base_type::TYPE_BYTE: + return "org.apache.thrift.protocol.TType.BYTE"; + case t_base_type::TYPE_I16: + return "org.apache.thrift.protocol.TType.I16"; + case t_base_type::TYPE_I32: + return "org.apache.thrift.protocol.TType.I32"; + case t_base_type::TYPE_I64: + return "org.apache.thrift.protocol.TType.I64"; + case t_base_type::TYPE_DOUBLE: + return "org.apache.thrift.protocol.TType.DOUBLE"; } } else if (type->is_enum()) { return "org.apache.thrift.protocol.TType.I32"; @@ -3525,9 +3380,9 @@ string t_java_generator::constant_name(string name) { void t_java_generator::generate_java_docstring_comment(ofstream &out, string contents) { generate_docstring_comment(out, - "/**\n", - " * ", contents, - " */\n"); + "/**\n", + " * ", contents, + " */\n"); } void t_java_generator::generate_java_doc(ofstream &out, @@ -3568,9 +3423,9 @@ void t_java_generator::generate_java_doc(ofstream &out, } } generate_docstring_comment(out, - "/**\n", - " * ", ss.str(), - " */\n"); + "/**\n", + " * ", ss.str(), + " */\n"); } } @@ -3580,9 +3435,9 @@ void t_java_generator::generate_deep_copy_container(ofstream &out, std::string s t_container* container = (t_container*)type; std::string source_name; if (source_name_p2 == "") - source_name = source_name_p1; + source_name = source_name_p1; else - source_name = source_name_p1 + "." + source_name_p2; + source_name = source_name_p1 + "." + source_name_p2; indent(out) << type_name(type, true, false) << " " << result_name << " = new " << type_name(container, false, true) << "();" << endl; @@ -3654,8 +3509,7 @@ void t_java_generator::generate_deep_copy_container(ofstream &out, std::string s generate_deep_copy_non_container(out, iterator_element_name, "temp_binary_element", elem_type); out << ";" << endl; indent(out) << result_name << ".add(temp_binary_element);" << endl; - } - else{ + } else{ indent(out) << result_name << ".add("; generate_deep_copy_non_container(out, iterator_element_name, result_name, elem_type); out << ");" << endl; @@ -3695,9 +3549,9 @@ std::string t_java_generator::generate_isset_check(std::string field_name) { return "is" + get_cap_name("set") + get_cap_name(field_name) + "()"; } -void t_java_generator::generate_isset_set(ofstream& out, t_field* field) { +void t_java_generator::generate_isset_set(ofstream& out, t_field* field, string prefix) { if (!type_can_be_null(field->get_type())) { - indent(out) << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);" << endl; + indent(out) << prefix << "set" << get_cap_name(field->get_name()) << get_cap_name("isSet") << "(true);" << endl; } } @@ -3712,7 +3566,7 @@ std::string t_java_generator::get_enum_class_name(t_type* type) { void t_java_generator::generate_struct_desc(ofstream& out, t_struct* tstruct) { indent(out) << - "private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct(\"" << tstruct->get_name() << "\");" << endl; + "private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct(\"" << tstruct->get_name() << "\");" << endl; } void t_java_generator::generate_field_descs(ofstream& out, t_struct* tstruct) { @@ -3728,6 +3582,14 @@ void t_java_generator::generate_field_descs(ofstream& out, t_struct* tstruct) { } } +void t_java_generator::generate_scheme_map(ofstream& out, t_struct* tstruct) { + indent(out) << "private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>();" << endl; + indent(out) << "static {" << endl; + indent(out) << " schemes.put(StandardScheme.class, new " << tstruct->get_name() << "StandardSchemeFactory());" << endl; + indent(out) << " schemes.put(TupleScheme.class, new " << tstruct->get_name() << "TupleSchemeFactory());" << endl; + indent(out) << "}" << endl; +} + void t_java_generator::generate_field_name_constants(ofstream& out, t_struct* tstruct) { indent(out) << "/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */" << endl; indent(out) << "public enum _Fields implements org.apache.thrift.TFieldIdEnum {" << endl; @@ -3830,7 +3692,7 @@ bool t_java_generator::has_bit_vector(t_struct* tstruct) { void t_java_generator::generate_java_struct_clear(std::ofstream& out, t_struct* tstruct) { if (!java5_) { - indent(out) << "@Override" << endl; + indent(out) << "@Override" << endl; } indent(out) << "public void clear() {" << endl; @@ -3906,6 +3768,274 @@ void t_java_generator::generate_java_struct_read_object(ofstream& out, t_struct* indent(out) << "}" << endl << endl; } +void t_java_generator::generate_standard_reader(ofstream& out, t_struct* tstruct) { + out << + indent() << "public void read(org.apache.thrift.protocol.TProtocol iprot, " << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl; + indent_up(); + + const vector& fields = tstruct->get_members(); + vector::const_iterator f_iter; + + // Declare stack tmp variables and read struct header + out << + indent() << "org.apache.thrift.protocol.TField schemeField;" << endl << + indent() << "iprot.readStructBegin();" << endl; + + // Loop over reading in fields + indent(out) << "while (true)" << endl; + scope_up(out); + + // Read beginning field marker + indent(out) << "schemeField = iprot.readFieldBegin();" << endl; + + // Check for field STOP marker and break + indent(out) << "if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { " << endl; + indent_up(); + indent(out) << "break;" << endl; + indent_down(); + indent(out) << "}" << endl; + + // Switch statement on the field we are reading + indent(out) << "switch (schemeField.id) {" << endl; + + indent_up(); + + // Generate deserialization code for known cases + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + indent(out) << + "case " << (*f_iter)->get_key() << ": // " << constant_name((*f_iter)->get_name()) << endl; + indent_up(); + indent(out) << + "if (schemeField.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl; + indent_up(); + + generate_deserialize_field(out, *f_iter, "struct.", false); + indent(out) << "struct." << "set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") << "(true);" << endl; + indent_down(); + out << + indent() << "} else { " << endl << + indent() << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);" << endl << + indent() << "}" << endl << + indent() << "break;" << endl; + indent_down(); + } + + indent(out) << "default:" << endl; + indent(out) << " org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);" << endl; + + indent_down(); + indent(out) << "}" << endl; + + // Read field end marker + indent(out) << "iprot.readFieldEnd();" << endl; + + indent_down(); + indent(out) << "}" << endl; + + out << + indent() << "iprot.readStructEnd();" << endl; + + // in non-beans style, check for required fields of primitive type + // (which can be checked here but not in the general validate method) + if (!bean_style_){ + out << endl << indent() << "// check for required fields of primitive type, which can't be checked in the validate method" << endl; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) { + out << + indent() << "if (!struct." << generate_isset_check(*f_iter) << ") {" << endl << + indent() << " throw new org.apache.thrift.protocol.TProtocolException(\"Required field '" << (*f_iter)->get_name() << "' was not found in serialized data! Struct: \" + toString());" << endl << + indent() << "}" << endl; + } + } + } + + // performs various checks (e.g. check that all required fields are set) + indent(out) << "struct.validate();" << endl; + + indent_down(); + out << indent() << "}" << endl; +} + +void t_java_generator::generate_standard_writer(ofstream& out, t_struct* tstruct) { + indent_up(); + out << + indent() << "public void write(org.apache.thrift.protocol.TProtocol oprot, " << + tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl; + indent_up(); + const vector& fields = tstruct->get_sorted_members(); + vector::const_iterator f_iter; + + // performs various checks (e.g. check that all required fields are set) + indent(out) << "struct.validate();" << endl << endl; + + indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << 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 (struct." << (*f_iter)->get_name() << " != null) {" << endl; + indent_up(); + } + bool optional = (*f_iter)->get_req() == t_field::T_OPTIONAL; + if (optional) { + indent(out) << "if (" << "struct." << generate_isset_check((*f_iter)) << ") {" << endl; + indent_up(); + } + + indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name()) << "_FIELD_DESC);" << endl; + + // Write field contents + generate_serialize_field(out, *f_iter, "struct.", false); + + // Write field closer + indent(out) << "oprot.writeFieldEnd();" << endl; + + if (optional) { + indent_down(); + indent(out) << "}" << endl; + } + if (null_allowed) { + indent_down(); + indent(out) << "}" << endl; + } + } + // Write the struct map + out << + indent() << "oprot.writeFieldStop();" << endl << + indent() << "oprot.writeStructEnd();" << endl; + + indent_down(); + out << indent() << "}" << endl << endl; + indent_down(); +} + +void t_java_generator::generate_java_struct_standard_scheme(ofstream& out, t_struct* tstruct){ + indent(out) << "private static class " << tstruct->get_name() << "StandardSchemeFactory implements SchemeFactory {" << endl; + indent_up(); + indent(out) << "public " << tstruct->get_name() << "StandardScheme getScheme() {" << endl; + indent_up(); + indent(out) << "return new " << tstruct->get_name() << "StandardScheme();" << endl; + indent_down(); + indent(out) << "}" << endl; + indent_down(); + indent(out) << "}" << endl << endl; + + out << indent() << "private static class " << tstruct->get_name() << "StandardScheme extends StandardScheme<" << tstruct->get_name() << "> {" << endl << endl; + indent_up(); + generate_standard_reader(out, tstruct); + indent_down(); + out << endl; + generate_standard_writer(out, tstruct); + + out << + indent() << "}" << endl << + endl; +} + +void t_java_generator::generate_java_struct_tuple_reader(ofstream& out, t_struct* tstruct) { + indent(out) << "@Override" << endl; + indent(out) << "public void read(org.apache.thrift.protocol.TProtocol prot, " << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl; + indent_up(); + indent(out) << "TTupleProtocol iprot = (TTupleProtocol) prot;" << endl; + int optional_count = 0; + const vector& fields = tstruct->get_members(); + vector::const_iterator f_iter; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { + optional_count++; + } + if ((*f_iter)->get_req() == t_field::T_REQUIRED) { + generate_deserialize_field(out, (*f_iter), "struct.", false); + indent(out) << "struct.set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") << "(true);" << endl; + } + } + if (optional_count > 0) { + indent(out) << "BitSet incoming = iprot.readBitSet(" << optional_count << ");" << endl; + int i = 0; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { + indent(out) << "if (incoming.get(" << i << ")) {" << endl; + indent_up(); + generate_deserialize_field(out, (*f_iter), "struct.", false); + indent(out) << "struct.set" << get_cap_name((*f_iter)->get_name()) << get_cap_name("isSet") << "(true);" << endl; + indent_down(); + indent(out) << "}" << endl; + i++; + } + } + } + indent_down(); + indent(out) << "}" << endl; +} + +void t_java_generator::generate_java_struct_tuple_writer(ofstream& out, t_struct* tstruct) { + indent(out) << "@Override" << endl; + indent(out) << "public void write(org.apache.thrift.protocol.TProtocol prot, " << tstruct->get_name() << " struct) throws org.apache.thrift.TException {" << endl; + indent_up(); + indent(out) << "TTupleProtocol oprot = (TTupleProtocol) prot;" << endl; + + const vector& fields = tstruct->get_members(); + vector::const_iterator f_iter; + bool has_optional = false; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { + has_optional = true; + } + if ((*f_iter)->get_req() == t_field::T_REQUIRED) { + generate_serialize_field(out, (*f_iter), "struct.", false); + } + } + if (has_optional) { + indent(out) << "BitSet optionals = new BitSet();" << endl; + int i = 0; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { + indent(out) << "if (struct." << generate_isset_check((*f_iter)) << ") {" << endl; + indent_up(); + indent(out) << "optionals.set(" << i << ");" << endl; + indent_down(); + indent(out) << "}" << endl; + i++; + } + } + + indent(out) << "oprot.writeBitSet(optionals);" << endl; + int j = 0; + for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { + if ((*f_iter)->get_req() == t_field::T_OPTIONAL || (*f_iter)->get_req() == t_field::T_OPT_IN_REQ_OUT) { + indent(out) << "if (struct." << generate_isset_check(*f_iter) << ") {" << endl; + indent_up(); + generate_serialize_field(out, (*f_iter), "struct.", false); + indent_down(); + indent(out) << "}" << endl; + j++; + } + } + } + indent_down(); + indent(out) << "}" << endl; +} + +void t_java_generator::generate_java_struct_tuple_scheme(ofstream& out, t_struct* tstruct){ + indent(out) << "private static class " << tstruct->get_name() << "TupleSchemeFactory implements SchemeFactory {" << endl; + indent_up(); + indent(out) << "public " << tstruct->get_name() << "TupleScheme getScheme() {" << endl; + indent_up(); + indent(out) << "return new " << tstruct->get_name() << "TupleScheme();" << endl; + indent_down(); + indent(out) << "}" << endl; + indent_down(); + indent(out) << "}" << endl << endl; + out << indent() << "private static class " << tstruct->get_name() << "TupleScheme extends TupleScheme<" << tstruct->get_name() << "> {" << endl << endl; + indent_up(); + generate_java_struct_tuple_writer(out, tstruct); + out << endl; + generate_java_struct_tuple_reader(out, tstruct); + indent_down(); + out << indent() << "}" << 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" diff --git a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java index d3b1636c..3b1d8869 100755 --- a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java +++ b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java @@ -36,7 +36,7 @@ import org.apache.thrift.transport.TTransport; * fields, nested structures, short strings and collections, and low-value i32 * and i64 fields you have, the more benefit you'll see. */ -public final class TCompactProtocol extends TProtocol { +public class TCompactProtocol extends TProtocol { private final static TStruct ANONYMOUS_STRUCT = new TStruct(""); private final static TField TSTOP = new TField("", TType.STOP, (short)0); diff --git a/lib/java/src/org/apache/thrift/protocol/TProtocol.java b/lib/java/src/org/apache/thrift/protocol/TProtocol.java index 16fac64f..0e96368d 100644 --- a/lib/java/src/org/apache/thrift/protocol/TProtocol.java +++ b/lib/java/src/org/apache/thrift/protocol/TProtocol.java @@ -22,6 +22,8 @@ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import org.apache.thrift.TException; +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.StandardScheme; import org.apache.thrift.transport.TTransport; /** @@ -150,4 +152,11 @@ public abstract class TProtocol { * be implemented for stateful protocols. */ public void reset() {} + + /** + * Scheme accessor + */ + public Class getScheme() { + return StandardScheme.class; + } } diff --git a/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java b/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java new file mode 100644 index 00000000..5e9a14e6 --- /dev/null +++ b/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.thrift.protocol; + +import java.util.BitSet; + +import org.apache.thrift.TException; +import org.apache.thrift.scheme.IScheme; +import org.apache.thrift.scheme.TupleScheme; +import org.apache.thrift.transport.TTransport; + +public final class TTupleProtocol extends TCompactProtocol { + public static class Factory implements TProtocolFactory { + public Factory() {} + + public TProtocol getProtocol(TTransport trans) { + return new TTupleProtocol(trans); + } + } + + public TTupleProtocol(TTransport transport) { + super(transport); + } + + @Override + public Class getScheme() { + return TupleScheme.class; + } + + public void writeBitSet(BitSet bs) throws TException { + byte[] bytes = toByteArray(bs); + for (byte b : bytes) { + writeByte(b); + } + } + + public BitSet readBitSet(int i) throws TException { + int length = (int) Math.ceil(i/8.0); + byte[] bytes = new byte[length]; + for (int j = 0; j < length; j++) { + bytes[j] = readByte(); + } + BitSet bs = fromByteArray(bytes); + return bs; + } + + /** + * Returns a bitset containing the values in bytes. The byte-ordering must be + * big-endian. + */ + public static BitSet fromByteArray(byte[] bytes) { + BitSet bits = new BitSet(); + for (int i = 0; i < bytes.length * 8; i++) { + if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) { + bits.set(i); + } + } + return bits; + } + + /** + * Returns a byte array of at least length 1. The most significant bit in the + * result is guaranteed not to be a 1 (since BitSet does not support sign + * extension). The byte-ordering of the result is big-endian which means the + * most significant bit is in element 0. The bit at index 0 of the bit set is + * assumed to be the least significant bit. + * + * @param bits + * @return + */ + public static byte[] toByteArray(BitSet bits) { + byte[] bytes = new byte[bits.length() / 8 + 1]; + for (int i = 0; i < bits.length(); i++) { + if (bits.get(i)) { + bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8); + } + } + return bytes; + } + +} diff --git a/lib/java/src/org/apache/thrift/scheme/IScheme.java b/lib/java/src/org/apache/thrift/scheme/IScheme.java new file mode 100644 index 00000000..aa355070 --- /dev/null +++ b/lib/java/src/org/apache/thrift/scheme/IScheme.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.thrift.scheme; + +import org.apache.thrift.TBase; + +public interface IScheme { + + public void read(org.apache.thrift.protocol.TProtocol iproto, T struct) throws org.apache.thrift.TException; + + public void write(org.apache.thrift.protocol.TProtocol oproto, T struct) throws org.apache.thrift.TException; + +} diff --git a/lib/java/src/org/apache/thrift/scheme/SchemeFactory.java b/lib/java/src/org/apache/thrift/scheme/SchemeFactory.java new file mode 100644 index 00000000..006a6680 --- /dev/null +++ b/lib/java/src/org/apache/thrift/scheme/SchemeFactory.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.thrift.scheme; + +public interface SchemeFactory { + + public S getScheme(); + +} diff --git a/lib/java/src/org/apache/thrift/scheme/StandardScheme.java b/lib/java/src/org/apache/thrift/scheme/StandardScheme.java new file mode 100644 index 00000000..ffab04db --- /dev/null +++ b/lib/java/src/org/apache/thrift/scheme/StandardScheme.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.thrift.scheme; + +import org.apache.thrift.TBase; + +public abstract class StandardScheme implements IScheme { + +} diff --git a/lib/java/src/org/apache/thrift/scheme/TupleScheme.java b/lib/java/src/org/apache/thrift/scheme/TupleScheme.java new file mode 100644 index 00000000..365242b1 --- /dev/null +++ b/lib/java/src/org/apache/thrift/scheme/TupleScheme.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.thrift.scheme; + +import org.apache.thrift.TBase; + +public abstract class TupleScheme implements IScheme { + +} diff --git a/lib/java/test/org/apache/thrift/Fixtures.java b/lib/java/test/org/apache/thrift/Fixtures.java index d759bb0d..b591a956 100644 --- a/lib/java/test/org/apache/thrift/Fixtures.java +++ b/lib/java/test/org/apache/thrift/Fixtures.java @@ -37,7 +37,7 @@ public class Fixtures { public static final Nesting nesting; public static final HolyMoley holyMoley; public static final CompactProtoTestStruct compactProtoTestStruct; - + private static final byte[] kUnicodeBytes = { (byte)0xd3, (byte)0x80, (byte)0xe2, (byte)0x85, (byte)0xae, (byte)0xce, (byte)0x9d, (byte)0x20, (byte)0xd0, (byte)0x9d, (byte)0xce, (byte)0xbf, @@ -52,79 +52,79 @@ public class Fixtures { static { try { oneOfEach = new OneOfEach(); - oneOfEach.im_true = true; - oneOfEach.im_false = false; - oneOfEach.a_bite = (byte) 0xd6; - oneOfEach.integer16 = 27000; - oneOfEach.integer32 = 1 << 24; - oneOfEach.integer64 = (long) 6000 * 1000 * 1000; - oneOfEach.double_precision = Math.PI; - oneOfEach.some_characters = "JSON THIS! \"\1"; - oneOfEach.zomg_unicode = new String(kUnicodeBytes, "UTF-8"); - oneOfEach.base64 = ByteBuffer.wrap("base64".getBytes()); + oneOfEach.setIm_true(true); + oneOfEach.setIm_false(false); + oneOfEach.setA_bite((byte) 0xd6); + oneOfEach.setInteger16((short)27000); + oneOfEach.setInteger32(1 << 24); + oneOfEach.setInteger64((long) 6000 * 1000 * 1000); + oneOfEach.setDouble_precision(Math.PI); + oneOfEach.setSome_characters("JSON THIS! \"\1"); + oneOfEach.setZomg_unicode(new String(kUnicodeBytes, "UTF-8")); + oneOfEach.setBase64(ByteBuffer.wrap("base64".getBytes())); // byte, i16, and i64 lists are populated by default constructor Bonk bonk = new Bonk(); - bonk.type = 31337; - bonk.message = "I am a bonk... xor!"; + bonk.setType(31337); + bonk.setMessage("I am a bonk... xor!"); nesting = new Nesting(bonk, oneOfEach); holyMoley = new HolyMoley(); - holyMoley.big = new ArrayList(); - holyMoley.big.add(new OneOfEach(oneOfEach)); - holyMoley.big.add(nesting.my_ooe); - holyMoley.big.get(0).a_bite = (byte) 0x22; - holyMoley.big.get(1).a_bite = (byte) 0x23; + ArrayList big = new ArrayList(); + big.add(new OneOfEach(oneOfEach)); + big.add(nesting.my_ooe); + holyMoley.setBig(big); + holyMoley.getBig().get(0).setA_bite((byte) 0x22); + holyMoley.getBig().get(0).setA_bite((byte) 0x23); - holyMoley.contain = new HashSet>(); + holyMoley.setContain(new HashSet>()); ArrayList stage1 = new ArrayList(2); stage1.add("and a one"); stage1.add("and a two"); - holyMoley.contain.add(stage1); + holyMoley.getContain().add(stage1); stage1 = new ArrayList(3); stage1.add("then a one, two"); stage1.add("three!"); stage1.add("FOUR!!"); - holyMoley.contain.add(stage1); + holyMoley.getContain().add(stage1); stage1 = new ArrayList(0); - holyMoley.contain.add(stage1); + holyMoley.getContain().add(stage1); ArrayList stage2 = new ArrayList(); - holyMoley.bonks = new HashMap>(); + holyMoley.setBonks(new HashMap>()); // one empty - holyMoley.bonks.put("zero", stage2); - + holyMoley.getBonks().put("zero", stage2); + // one with two stage2 = new ArrayList(); Bonk b = new Bonk(); - b.type = 1; - b.message = "Wait."; + b.setType(1); + b.setMessage("Wait."); stage2.add(b); b = new Bonk(); - b.type = 2; - b.message = "What?"; + b.setType(2); + b.setMessage("What?"); stage2.add(b); - holyMoley.bonks.put("two", stage2); - + holyMoley.getBonks().put("two", stage2); + // one with three stage2 = new ArrayList(); b = new Bonk(); - b.type = 3; - b.message = "quoth"; + b.setType(3); + b.setMessage("quoth"); b = new Bonk(); - b.type = 4; - b.message = "the raven"; + b.setType(4); + b.setMessage("the raven"); b = new Bonk(); - b.type = 5; - b.message = "nevermore"; - holyMoley.bonks.put("three", stage2); + b.setType(5); + b.setMessage("nevermore"); + holyMoley.getBonks().put("three", stage2); // superhuge compact proto test struct compactProtoTestStruct = new CompactProtoTestStruct(thrift.test.Constants.COMPACT_TEST); - compactProtoTestStruct.a_binary = ByteBuffer.wrap(new byte[]{0,1,2,3,4,5,6,7,8}); + compactProtoTestStruct.setA_binary(ByteBuffer.wrap(new byte[]{0,1,2,3,4,5,6,7,8})); } catch (Exception e) { throw new RuntimeException(e); } } - } diff --git a/lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java b/lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java new file mode 100644 index 00000000..948df9f6 --- /dev/null +++ b/lib/java/test/org/apache/thrift/protocol/TestTTupleProtocol.java @@ -0,0 +1,24 @@ +package org.apache.thrift.protocol; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.thrift.TException; +import org.apache.thrift.transport.TMemoryBuffer; +import org.apache.thrift.transport.TMemoryInputTransport; + +import thrift.test.Complex; +import thrift.test.Simple; + +public class TestTTupleProtocol extends ProtocolTestBase { + + @Override + protected boolean canBeUsedNaked() { + return false; + } + + @Override + protected TProtocolFactory getFactory() { + return new TTupleProtocol.Factory(); + } +} -- 2.17.1