From d2655523aba745e917bc0e3762ac11af4b2437a6 Mon Sep 17 00:00:00 2001 From: Mark Slee Date: Tue, 5 Sep 2006 22:09:57 +0000 Subject: [PATCH] Thrift: Change Java/C++ server generation Summary: Servers shouldn't implement iface directly, instead should contain an iface object git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664785 13f79535-47bb-0310-9956-ffa450edef68 --- compiler/cpp/src/generate/t_cpp_generator.cc | 200 +++++----- compiler/cpp/src/generate/t_cpp_generator.h | 2 +- compiler/cpp/src/generate/t_java_generator.cc | 12 +- test/cpp/src/TestServer.cc | 9 +- test/java/src/TestServer.java | 361 +++++++++--------- 5 files changed, 295 insertions(+), 289 deletions(-) diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc index 2cff3fc81..7934f0ca6 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.cc +++ b/compiler/cpp/src/generate/t_cpp_generator.cc @@ -480,8 +480,10 @@ void t_cpp_generator::generate_service(t_service* tservice) { generate_service_interface(tservice); generate_service_helpers(tservice); - generate_service_server(tservice); generate_service_client(tservice); + generate_service_server(tservice); + generate_service_multiface(tservice); + f_service_ << ns_close_ << endl << @@ -536,6 +538,93 @@ void t_cpp_generator::generate_service_interface(t_service* tservice) { "}; " << endl << endl; } +/** + * Generates a multiface, which is a single server that just takes a set + * of objects implementing the interface and calls them all, returning the + * value of the last one to be called. + * + * @param tservice The service to generate a multiserver for. + */ +void t_cpp_generator::generate_service_multiface(t_service* tservice) { + // Generate the dispatch methods + vector functions = tservice->get_functions(); + vector::iterator f_iter; + + string list_type = string("std::vector >"; + + // Generate the header portion + f_header_ << + "class " << service_name_ << "Multiface : " << + "public " << service_name_ << "If {" << endl << + " public: " << endl; + indent_up(); + f_header_ << + indent() << service_name_ << "Multiface(" << list_type << "& ifaces) : _ifaces(ifaces) {}" << endl << + indent() << "virtual ~" << service_name_ << "Multiface() {}" << endl; + indent_down(); + + // Protected data members + f_header_ << + " protected:" << endl; + indent_up(); + f_header_ << + indent() << list_type << "& _ifaces;" << endl; + indent_down(); + + f_header_ << + indent() << " public:" << endl; + indent_up(); + + for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { + t_struct* arglist = (*f_iter)->get_arglist(); + const vector& args = arglist->get_members(); + vector::const_iterator a_iter; + + string call = string("_ifaces[i]->") + (*f_iter)->get_name() + "("; + bool first = true; + for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) { + if (first) { + first = false; + } else { + call += ", "; + } + call += (*a_iter)->get_name(); + } + call += ")"; + + f_header_ << + indent() << function_signature(*f_iter) << " {" << endl; + indent_up(); + f_header_ << + indent() << "uint32_t sz = _ifaces.size();" << endl << + indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl; + if (!(*f_iter)->get_returntype()->is_void()) { + f_header_ << + indent() << " if (i == sz - 1) {" << endl << + indent() << " return " << call << ";" << endl << + indent() << " } else {" << endl << + indent() << " " << call << ";" << endl << + indent() << " }" << endl; + } else { + f_header_ << + indent() << " " << call << ";" << endl; + } + + f_header_ << + indent() << "}" << endl; + + indent_down(); + f_header_ << + indent() << "}" << endl << + endl; + } + + indent_down(); + f_header_ << + indent() << "};" << endl << + endl; +} + /** * Generates a service client definition. * @@ -746,17 +835,16 @@ void t_cpp_generator::generate_service_server(t_service* tservice) { // Generate the header portion f_header_ << "class " << service_name_ << "Server : " << - "public " << service_name_ << "If, " << "public facebook::thrift::TProcessor {" << endl << " public: " << endl; indent_up(); f_header_ << indent() << - service_name_ << "Server(boost::shared_ptr protocol) : " << - "_iprot(protocol), _oprot(protocol) {}" << endl << + service_name_ << "Server(boost::shared_ptr<" << service_name_ << "If> iface, boost::shared_ptr prot) : " << + "_iface(iface), _iprot(prot), _oprot(prot) {}" << endl << indent() << - service_name_ << "Server(boost::shared_ptr iprot, boost::shared_ptr oprot) : " << - "_iprot(iprot), _oprot(oprot) {}" << endl << + service_name_ << "Server(boost::shared_ptr<" << service_name_ << "If> iface, boost::shared_ptr iprot, boost::shared_ptr oprot) : " << + "_iface(iface), _iprot(iprot), _oprot(oprot) {}" << endl << indent() << "bool process(boost::shared_ptr _itrans, " << "boost::shared_ptr _otrans);" << endl << indent() << "virtual ~" << service_name_ << "Server() {}" << endl; @@ -767,6 +855,7 @@ void t_cpp_generator::generate_service_server(t_service* tservice) { " protected:" << endl; indent_up(); f_header_ << + indent() << "boost::shared_ptr<" << service_name_ << "If> _iface;" << endl << indent() << "boost::shared_ptr _iprot;" << endl << indent() << "boost::shared_ptr _oprot;" << endl; indent_down(); @@ -838,109 +927,12 @@ void t_cpp_generator::generate_service_server(t_service* tservice) { "}" << endl << endl; - // Multiserver - generate_service_multiserver(tservice); - // Generate the process subfunctions for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { generate_process_function(tservice, *f_iter); } } -/** - * Generates a multiserver, which is a single server that just takes a set - * of objects implementing the interface and calls them all, returning the - * value of the last one to be called. - * - * @param tservice The service to generate a multiserver for. - */ -void t_cpp_generator::generate_service_multiserver(t_service* tservice) { - // Generate the dispatch methods - vector functions = tservice->get_functions(); - vector::iterator f_iter; - - string list_type = string("std::vector >"; - - // Generate the header portion - f_header_ << - "class " << service_name_ << "MultiServer : " << - "public " << service_name_ << "Server {" << endl << - " public: " << endl; - indent_up(); - f_header_ << - indent() << - service_name_ << "MultiServer(boost::shared_ptr protocol, " << list_type << "& servers) : " << - service_name_ << "Server(protocol), _servers(servers) {}" << endl << - indent() << - service_name_ << "MultiServer(boost::shared_ptr iprot, boost::shared_ptr oprot, " << list_type << "& servers) : " << - service_name_ << "Server(iprot, oprot), _servers(servers) {}" << endl << - indent() << "virtual ~" << service_name_ << "MultiServer() {}" << endl; - indent_down(); - - // Protected data members - f_header_ << - " protected:" << endl; - indent_up(); - f_header_ << - indent() << list_type << "& _servers;" << endl; - indent_down(); - - f_header_ << - indent() << " public:" << endl; - indent_up(); - - for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - t_struct* arglist = (*f_iter)->get_arglist(); - const vector& args = arglist->get_members(); - vector::const_iterator a_iter; - - string call = string("_servers[i]->") + (*f_iter)->get_name() + "("; - bool first = true; - for (a_iter = args.begin(); a_iter != args.end(); ++a_iter) { - if (first) { - first = false; - } else { - call += ", "; - } - call += (*a_iter)->get_name(); - } - call += ")"; - - f_header_ << - indent() << function_signature(*f_iter) << " {" << endl; - indent_up(); - f_header_ << - indent() << "uint32_t sz = _servers.size();" << endl << - indent() << "for (uint32_t i = 0; i < sz; ++i) {" << endl; - if (!(*f_iter)->get_returntype()->is_void()) { - f_header_ << - indent() << " if (i == sz - 1) {" << endl << - indent() << " return " << call << ";" << endl << - indent() << " } else {" << endl << - indent() << " " << call << ";" << endl << - indent() << " }" << endl; - } else { - f_header_ << - indent() << " " << call << ";" << endl; - } - - f_header_ << - indent() << "}" << endl; - - indent_down(); - f_header_ << - indent() << "}" << endl << - endl; - } - - indent_down(); - - f_header_ << - indent() << "};" << endl << - endl; -} - - /** * Generates a struct and helpers for a function. * @@ -1019,7 +1011,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice, f_service_ << "__result.success = "; } f_service_ << - tfunction->get_name() << "("; + "_iface->" << tfunction->get_name() << "("; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { diff --git a/compiler/cpp/src/generate/t_cpp_generator.h b/compiler/cpp/src/generate/t_cpp_generator.h index fd208b683..55c7c2f5d 100644 --- a/compiler/cpp/src/generate/t_cpp_generator.h +++ b/compiler/cpp/src/generate/t_cpp_generator.h @@ -42,10 +42,10 @@ class t_cpp_generator : public t_oop_generator { /** Service-level generation functions */ void generate_service_interface (t_service* tservice); + void generate_service_multiface (t_service* tservice); void generate_service_helpers (t_service* tservice); void generate_service_client (t_service* tservice); void generate_service_server (t_service* tservice); - void generate_service_multiserver(t_service* tservice); void generate_process_function (t_service* tservice, t_function* tfunction); void generate_function_helpers (t_function* tfunction); diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc index 059e6b05c..390c563b5 100644 --- a/compiler/cpp/src/generate/t_java_generator.cc +++ b/compiler/cpp/src/generate/t_java_generator.cc @@ -599,27 +599,29 @@ void t_java_generator::generate_service_server(t_service* tservice) { // Generate the header portion f_service_ << - "public abstract static class Server implements Iface, TProcessor {" << endl; + "public static class Server implements TProcessor {" << endl; indent_up(); indent(f_service_) << - "public Server(TProtocol prot)" << endl; + "public Server(Iface iface, TProtocol prot)" << endl; scope_up(f_service_); indent(f_service_) << - "this(prot, prot);" << endl; + "this(iface, prot, prot);" << endl; scope_down(f_service_); f_service_ << endl; indent(f_service_) << - "public Server(TProtocol iprot, TProtocol oprot)" << endl; + "public Server(Iface iface, TProtocol iprot, TProtocol oprot)" << endl; scope_up(f_service_); f_service_ << + indent() << "_iface = iface;" << endl << indent() << "_iprot = iprot;" << endl << indent() << "_oprot = oprot;" << endl; scope_down(f_service_); f_service_ << endl; f_service_ << + indent() << "private Iface _iface;" << endl << indent() << "private TProtocol _iprot;" << endl << indent() << "private TProtocol _oprot;" << endl << endl; @@ -753,7 +755,7 @@ void t_java_generator::generate_process_function(t_service* tservice, f_service_ << "__result.success = "; } f_service_ << - tfunction->get_name() << "("; + "_iface." << tfunction->get_name() << "("; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { if (first) { diff --git a/test/cpp/src/TestServer.cc b/test/cpp/src/TestServer.cc index 75b88d43f..63a75945d 100644 --- a/test/cpp/src/TestServer.cc +++ b/test/cpp/src/TestServer.cc @@ -19,10 +19,9 @@ using namespace facebook::thrift::server; using namespace thrift::test; -class TestServer : public ThriftTestServer { +class TestHandler : public ThriftTestIf { public: - TestServer(shared_ptr protocol) : - ThriftTestServer(protocol) {} + TestHandler() {} void testVoid() { printf("testVoid()\n"); @@ -339,7 +338,9 @@ int main(int argc, char **argv) { // Dispatcher shared_ptr binaryProtocol(new TBinaryProtocol); - shared_ptr testServer(new TestServer(binaryProtocol)); + shared_ptr testHandler(new TestHandler()); + + shared_ptr testServer(new ThriftTestServer(testHandler, binaryProtocol)); // Options shared_ptr serverOptions(new TServerOptions()); diff --git a/test/java/src/TestServer.java b/test/java/src/TestServer.java index 4e415ae1d..7418cbb23 100644 --- a/test/java/src/TestServer.java +++ b/test/java/src/TestServer.java @@ -16,207 +16,212 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -public class TestServer extends ThriftTest.Server { - public TestServer(TProtocol prot) { - super(prot); - } - - public void testVoid() { - System.out.print("testVoid()\n"); - } +public class TestServer { - public String testString(String thing) { - System.out.print("testString(\"" + thing + "\")\n"); - return thing; - } + public static class TestHandler implements ThriftTest.Iface { - public byte testByte(byte thing) { - System.out.print("testByte(" + thing + ")\n"); - return thing; - } + public TestHandler() {} + + public void testVoid() { + System.out.print("testVoid()\n"); + } - public int testI32(int thing) { - System.out.print("testI32(" + thing + ")\n"); - return thing; - } + public String testString(String thing) { + System.out.print("testString(\"" + thing + "\")\n"); + return thing; + } - public long testI64(long thing) { - System.out.print("testI64(" + thing + ")\n"); - return thing; - } + public byte testByte(byte thing) { + System.out.print("testByte(" + thing + ")\n"); + return thing; + } + + public int testI32(int thing) { + System.out.print("testI32(" + thing + ")\n"); + return thing; + } + + public long testI64(long thing) { + System.out.print("testI64(" + thing + ")\n"); + return thing; + } - public Xtruct testStruct(Xtruct thing) { - System.out.print("testStruct({" + - "\"" + thing.string_thing + "\", " + - thing.byte_thing + ", " + - thing.i32_thing + ", " + - thing.i64_thing + "})\n"); - return thing; - } + public Xtruct testStruct(Xtruct thing) { + System.out.print("testStruct({" + + "\"" + thing.string_thing + "\", " + + thing.byte_thing + ", " + + thing.i32_thing + ", " + + thing.i64_thing + "})\n"); + return thing; + } - public Xtruct2 testNest(Xtruct2 nest) { - Xtruct thing = nest.struct_thing; - System.out.print("testNest({" + - nest.byte_thing + ", {" + - "\"" + thing.string_thing + "\", " + - thing.byte_thing + ", " + - thing.i32_thing + ", " + - thing.i64_thing + "}, " + - nest.i32_thing + "})\n"); - return nest; - } + public Xtruct2 testNest(Xtruct2 nest) { + Xtruct thing = nest.struct_thing; + System.out.print("testNest({" + + nest.byte_thing + ", {" + + "\"" + thing.string_thing + "\", " + + thing.byte_thing + ", " + + thing.i32_thing + ", " + + thing.i64_thing + "}, " + + nest.i32_thing + "})\n"); + return nest; + } - public HashMap testMap(HashMap thing) { - System.out.print("testMap({"); - boolean first = true; - for (int key : thing.keySet()) { - if (first) { - first = false; - } else { - System.out.print(", "); + public HashMap testMap(HashMap thing) { + System.out.print("testMap({"); + boolean first = true; + for (int key : thing.keySet()) { + if (first) { + first = false; + } else { + System.out.print(", "); + } + System.out.print(key + " => " + thing.get(key)); } - System.out.print(key + " => " + thing.get(key)); + System.out.print("})\n"); + return thing; } - System.out.print("})\n"); - return thing; - } - public HashSet testSet(HashSet thing) { - System.out.print("testSet({"); - boolean first = true; - for (int elem : thing) { - if (first) { - first = false; - } else { - System.out.print(", "); + public HashSet testSet(HashSet thing) { + System.out.print("testSet({"); + boolean first = true; + for (int elem : thing) { + if (first) { + first = false; + } else { + System.out.print(", "); + } + System.out.print(elem); } - System.out.print(elem); + System.out.print("})\n"); + return thing; } - System.out.print("})\n"); - return thing; - } - public ArrayList testList(ArrayList thing) { - System.out.print("testList({"); - boolean first = true; - for (int elem : thing) { - if (first) { - first = false; - } else { - System.out.print(", "); + public ArrayList testList(ArrayList thing) { + System.out.print("testList({"); + boolean first = true; + for (int elem : thing) { + if (first) { + first = false; + } else { + System.out.print(", "); + } + System.out.print(elem); } - System.out.print(elem); - } - System.out.print("})\n"); - return thing; - } - - public int testEnum(int thing) { - System.out.print("testEnum(" + thing + ")\n"); - return thing; - } - - public long testTypedef(long thing) { - System.out.print("testTypedef(" + thing + ")\n"); - return thing; - } - - public HashMap> testMapMap(int hello) { - System.out.print("testMapMap(" + hello + ")\n"); - HashMap> mapmap = - new HashMap>(); - - HashMap pos = new HashMap(); - HashMap neg = new HashMap(); - for (int i = 1; i < 5; i++) { - pos.put(i, i); - neg.put(-i, -i); + System.out.print("})\n"); + return thing; } - mapmap.put(4, pos); - mapmap.put(-4, neg); + public int testEnum(int thing) { + System.out.print("testEnum(" + thing + ")\n"); + return thing; + } - return mapmap; - } + public long testTypedef(long thing) { + System.out.print("testTypedef(" + thing + ")\n"); + return thing; + } - public HashMap> testInsanity(Insanity argument) { - System.out.print("testInsanity()\n"); + public HashMap> testMapMap(int hello) { + System.out.print("testMapMap(" + hello + ")\n"); + HashMap> mapmap = + new HashMap>(); + + HashMap pos = new HashMap(); + HashMap neg = new HashMap(); + for (int i = 1; i < 5; i++) { + pos.put(i, i); + neg.put(-i, -i); + } + + mapmap.put(4, pos); + mapmap.put(-4, neg); + + return mapmap; + } + + public HashMap> testInsanity(Insanity argument) { + System.out.print("testInsanity()\n"); - Xtruct hello = new Xtruct(); - hello.string_thing = "Hello2"; - hello.byte_thing = 2; - hello.i32_thing = 2; - hello.i64_thing = 2; + Xtruct hello = new Xtruct(); + hello.string_thing = "Hello2"; + hello.byte_thing = 2; + hello.i32_thing = 2; + hello.i64_thing = 2; - Xtruct goodbye = new Xtruct(); - goodbye.string_thing = "Goodbye4"; - goodbye.byte_thing = (byte)4; - goodbye.i32_thing = 4; - goodbye.i64_thing = (long)4; + Xtruct goodbye = new Xtruct(); + goodbye.string_thing = "Goodbye4"; + goodbye.byte_thing = (byte)4; + goodbye.i32_thing = 4; + goodbye.i64_thing = (long)4; - Insanity crazy = new Insanity(); - crazy.userMap.put(Numberz.EIGHT, (long)8); - crazy.xtructs.add(goodbye); + Insanity crazy = new Insanity(); + crazy.userMap.put(Numberz.EIGHT, (long)8); + crazy.xtructs.add(goodbye); - Insanity looney = new Insanity(); - crazy.userMap.put(Numberz.FIVE, (long)5); - crazy.xtructs.add(hello); + Insanity looney = new Insanity(); + crazy.userMap.put(Numberz.FIVE, (long)5); + crazy.xtructs.add(hello); - HashMap first_map = new HashMap(); - HashMap second_map = new HashMap();; + HashMap first_map = new HashMap(); + HashMap second_map = new HashMap();; - first_map.put(Numberz.TWO, crazy); - first_map.put(Numberz.THREE, crazy); + first_map.put(Numberz.TWO, crazy); + first_map.put(Numberz.THREE, crazy); - second_map.put(Numberz.SIX, looney); + second_map.put(Numberz.SIX, looney); - HashMap> insane = - new HashMap>(); - insane.put((long)1, first_map); - insane.put((long)2, second_map); + HashMap> insane = + new HashMap>(); + insane.put((long)1, first_map); + insane.put((long)2, second_map); - return insane; - } + return insane; + } - public Xtruct testMulti(byte arg0, int arg1, long arg2, HashMap arg3, int arg4, long arg5) { - System.out.print("testMulti()\n"); + public Xtruct testMulti(byte arg0, int arg1, long arg2, HashMap arg3, int arg4, long arg5) { + System.out.print("testMulti()\n"); - Xtruct hello = new Xtruct();; - hello.string_thing = "Hello2"; - hello.byte_thing = arg0; - hello.i32_thing = arg1; - hello.i64_thing = arg2; - return hello; - } - - public void testException(String arg) throws Xception { - System.out.print("testException("+arg+")\n"); - if (arg.equals("Xception")) { - Xception x = new Xception(); - x.errorCode = 1001; - x.message = "This is an Xception"; - throw x; + Xtruct hello = new Xtruct();; + hello.string_thing = "Hello2"; + hello.byte_thing = arg0; + hello.i32_thing = arg1; + hello.i64_thing = arg2; + return hello; } - return; - } - public Xtruct testMultiException(String arg0, String arg1) throws Xception, Xception2 { - System.out.print("testMultiException(" + arg0 + ", " + arg1 + ")\n"); - if (arg0.equals("Xception")) { - Xception x = new Xception(); - x.errorCode = 1001; - x.message = "This is an Xception"; - } else if (arg0.equals("Xception2")) { - Xception2 x = new Xception2(); - x.errorCode = 2002; - x.struct_thing.string_thing = "This is an Xception2"; + public void testException(String arg) throws Xception { + System.out.print("testException("+arg+")\n"); + if (arg.equals("Xception")) { + Xception x = new Xception(); + x.errorCode = 1001; + x.message = "This is an Xception"; + throw x; + } + return; } + + public Xtruct testMultiException(String arg0, String arg1) throws Xception, Xception2 { + System.out.print("testMultiException(" + arg0 + ", " + arg1 + ")\n"); + if (arg0.equals("Xception")) { + Xception x = new Xception(); + x.errorCode = 1001; + x.message = "This is an Xception"; + throw x; + } else if (arg0.equals("Xception2")) { + Xception2 x = new Xception2(); + x.errorCode = 2002; + x.struct_thing = new Xtruct(); + x.struct_thing.string_thing = "This is an Xception2"; + throw x; + } - Xtruct result = new Xtruct(); - result.string_thing = arg1; - return result; - } + Xtruct result = new Xtruct(); + result.string_thing = arg1; + return result; + } + } // class TestHandler public static void main(String [] args) { try { @@ -226,20 +231,26 @@ public class TestServer extends ThriftTest.Server { } // Processor - TBinaryProtocol binaryProtocol = new TBinaryProtocol(); - TestServer testServer = new TestServer(binaryProtocol); + TBinaryProtocol binaryProtocol = + new TBinaryProtocol(); + TestHandler testHandler = + new TestHandler(); + ThriftTest.Server testServer = + new ThriftTest.Server(testHandler, binaryProtocol); // Options - TServer.Options serverOptions = new TServer.Options(); + TServer.Options serverOptions = + new TServer.Options(); // Transport - ServerSocket serverSocket = new ServerSocket(port); - TServerSocket tServerSocket = new TServerSocket(serverSocket); + ServerSocket serverSocket = + new ServerSocket(port); + TServerSocket tServerSocket = + new TServerSocket(serverSocket); // Server - TSimpleServer simpleServer = new TSimpleServer(testServer, - serverOptions, - tServerSocket); + TSimpleServer simpleServer = + new TSimpleServer(testServer, serverOptions, tServerSocket); // Run it System.out.println("Starting the server on port " + port + "...");