From: Mark Slee Date: Mon, 5 Feb 2007 21:52:08 +0000 (+0000) Subject: Adding XSD attribute support X-Git-Tag: 0.2.0~1498 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=21135c300bd4418365981e930d3aeba6f290fb5b;p=common%2Fthrift.git Adding XSD attribute support Reviewed By: dave git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664974 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc index 903aac08..936156ba 100644 --- a/compiler/cpp/src/generate/t_php_generator.cc +++ b/compiler/cpp/src/generate/t_php_generator.cc @@ -844,9 +844,14 @@ void t_php_generator::generate_service_rest(t_service* tservice) { f_service_ << "class " << service_name_ << "Rest" << extends_if << " {" << endl; indent_up(); + + if (extends.empty()) { + f_service_ << + indent() << "protected $impl_;" << endl << + endl; + } + f_service_ << - indent() << "private $impl_;" << endl << - endl << indent() << "public function __construct($impl) {" << endl << indent() << " $this->impl_ = $impl;" << endl << indent() << "}" << endl << @@ -865,8 +870,9 @@ void t_php_generator::generate_service_rest(t_service* tservice) { while (atype->is_typedef()) { atype = ((t_typedef*)atype)->get_type(); } + string req = "$request['" + (*a_iter)->get_name() + "']"; f_service_ << - indent() << "$" << (*a_iter)->get_name() << " = $request['" << (*a_iter)->get_name() << "'];" << endl; + indent() << "$" << (*a_iter)->get_name() << " = isset(" << req << ") ? " << req << " : null;" << endl; if (atype->is_string() && ((t_base_type*)atype)->is_string_list()) { f_service_ << diff --git a/compiler/cpp/src/generate/t_rb_generator.cc b/compiler/cpp/src/generate/t_rb_generator.cc index 4636e43e..d89bbb06 100644 --- a/compiler/cpp/src/generate/t_rb_generator.cc +++ b/compiler/cpp/src/generate/t_rb_generator.cc @@ -514,7 +514,6 @@ void t_rb_generator::generate_service(t_service* tservice) { generate_service_client(tservice); generate_service_server(tservice); generate_service_helpers(tservice); - generate_service_remote(tservice); indent_down(); f_service_ << "end" << endl << @@ -749,143 +748,6 @@ void t_rb_generator::generate_service_client(t_service* tservice) { indent(f_service_) << "end" << endl << endl; } -/** - * Generates a command line tool for making remote requests - * - * @param tservice The service to generate a remote for. - */ -void t_rb_generator::generate_service_remote(t_service* tservice) { - vector functions = tservice->get_functions(); - vector::iterator f_iter; - - string f_remote_name = string(T_RB_DIR)+"/"+service_name_+"-remote"; - ofstream f_remote; - f_remote.open(f_remote_name.c_str()); - - f_remote << - "#!/usr/bin/ruby" << endl << - rb_autogen_comment() << endl << - "import sys" << endl << - "import pprint" << endl << - "from thrift.transport import TTransport" << endl << - "from thrift.transport import TSocket" << endl << - "from thrift.protocol import TBinaryProtocol" << endl << - endl; - - f_remote << - "import " << service_name_ << endl << - "from " << program_name_ << "_types import *" << endl << - endl; - - f_remote << - "if len(sys.argv) <= 1 or sys.argv[1] == '--help':" << endl << - " print ''" << endl << - " print 'Usage: ' + sys.argv[0] + ' [-h host:port] [-f[ramed]] function [arg1,[arg2...]]'" << endl << - " print ''" << endl << - " print 'Functions:'" << endl; - for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - f_remote << - " print ' " << (*f_iter)->get_returntype()->get_name() << " " << (*f_iter)->get_name() << "("; - t_struct* arg_struct = (*f_iter)->get_arglist(); - const std::vector& args = arg_struct->get_members(); - vector::const_iterator a_iter; - int num_args = args.size(); - bool first = true; - for (int i = 0; i < num_args; ++i) { - if (first) { - first = false; - } else { - f_remote << ", "; - } - f_remote << - args[i]->get_type()->get_name() << " " << args[i]->get_name(); - } - f_remote << ")'" << endl; - } - f_remote << - " print ''" << endl << - " sys.exit(0)" << endl << - endl; - - f_remote << - "pp = pprint.PrettyPrinter(indent = 2)" << endl << - "host = 'localhost'" << endl << - "port = 9090" << endl << - "framed = False" << endl << - "argi = 1" << endl << - endl << - "if sys.argv[1] == '-h':" << endl << - " parts = sys.argv[2].split(':') " << endl << - " host = parts[0]" << endl << - " port = int(parts[1])" << endl << - " argi = 3" << endl << - endl << - "if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':" << endl << - " framed = True" << endl << - " argi += 1" << endl << - endl << - "cmd = sys.argv[argi]" << endl << - "args = sys.argv[argi+1:]" << endl << - endl << - "socket = TSocket.TSocket(host, port)" << endl << - "if framed:" << endl << - " transport = TTransport.TFramedTransport(socket)" << endl << - "else:" << endl << - " transport = TTransport.TBufferedTransport(socket)" << endl << - "protocol = TBinaryProtocol.TBinaryProtocol(transport)" << endl << - "client = " << service_name_ << ".Client(protocol)" << endl << - "transport.open()" << endl << - endl; - - // Generate the dispatch methods - bool first = true; - - for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { - if (first) { - first = false; - } else { - f_remote << "el"; - } - - t_struct* arg_struct = (*f_iter)->get_arglist(); - const std::vector& args = arg_struct->get_members(); - vector::const_iterator a_iter; - int num_args = args.size(); - - f_remote << - "if cmd == '" << (*f_iter)->get_name() << "':" << endl << - " if len(args) != " << num_args << ":" << endl << - " print '" << (*f_iter)->get_name() << " requires " << num_args << " args'" << endl << - " sys.exit(1)" << endl << - " pp.pprint(client." << (*f_iter)->get_name() << "("; - for (int i = 0; i < num_args; ++i) { - if (args[i]->get_type()->is_string()) { - f_remote << "args[" << i << "],"; - } else { - f_remote << "eval(args[" << i << "]),"; - } - } - f_remote << "))" << endl; - - f_remote << endl; - } - - f_remote << "transport.close()" << endl; - - // Close service file - f_remote.close(); - - // Make file executable, love that bitwise OR action - chmod(f_remote_name.c_str(), - S_IRUSR | - S_IWUSR | - S_IXUSR | - S_IRGRP | - S_IXGRP | - S_IROTH | - S_IXOTH); -} - /** * Generates a service server definition. * diff --git a/compiler/cpp/src/generate/t_rb_generator.h b/compiler/cpp/src/generate/t_rb_generator.h index bb74db67..97c08343 100644 --- a/compiler/cpp/src/generate/t_rb_generator.h +++ b/compiler/cpp/src/generate/t_rb_generator.h @@ -57,7 +57,6 @@ class t_rb_generator : public t_oop_generator { void generate_service_helpers (t_service* tservice); void generate_service_interface (t_service* tservice); void generate_service_client (t_service* tservice); - void generate_service_remote (t_service* tservice); void generate_service_server (t_service* tservice); void generate_process_function (t_service* tservice, t_function* tfunction); diff --git a/compiler/cpp/src/generate/t_xsd_generator.cc b/compiler/cpp/src/generate/t_xsd_generator.cc index 7f53f9f5..49550b15 100644 --- a/compiler/cpp/src/generate/t_xsd_generator.cc +++ b/compiler/cpp/src/generate/t_xsd_generator.cc @@ -48,7 +48,7 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_optional() || xsd_all, false); + generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_attrs(), (*m_iter)->get_xsd_optional() || xsd_all); } indent_down(); @@ -66,46 +66,80 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { void t_xsd_generator::generate_element(ostream& out, string name, t_type* ttype, + vector attrs, bool optional, bool list_element) { string sminOccurs = (optional || list_element) ? " minOccurs=\"0\"" : ""; string smaxOccurs = list_element ? " maxOccurs=\"unbounded\"" : ""; - string soptional = sminOccurs + smaxOccurs; if (ttype->is_void() || ttype->is_list()) { indent(out) << "" << endl; indent_up(); - if (ttype->is_void()) { + if (attrs.size() == 0 && ttype->is_void()) { indent(out) << "" << endl; - } else if (ttype->is_list()) { - indent(out) << "" << endl; - indent_up(); - indent(out) << "" << endl; + } else { + indent(out) << + "" << endl; indent_up(); - string subname; - t_type* subtype = ((t_list*)ttype)->get_elem_type(); - if (subtype->is_base_type() || subtype->is_container()) { - subname = name + "_elt"; - } else { - subname = type_name(subtype); + + vector::iterator a_iter; + for (a_iter = attrs.begin(); a_iter != attrs.end(); ++a_iter) { + indent(out) << "" << endl; + } + + if (ttype->is_list()) { + indent(out) << "" << endl; + indent(out) << "" << endl; + indent_up(); + string subname; + t_type* subtype = ((t_list*)ttype)->get_elem_type(); + if (subtype->is_base_type() || subtype->is_container()) { + subname = name + "_elt"; + } else { + subname = type_name(subtype); + } + f_php_ << "$GLOBALS['" << program_->get_name() << "_xsd_elt_" << name << "'] = '" << subname << "';" << endl; + generate_element(out, subname, subtype, vector(), false, true); + indent_down(); + indent(out) << "" << endl; } - f_php_ << "$GLOBALS['" << program_->get_name() << "_xsd_elt_" << name << "'] = '" << subname << "';" << endl; - generate_element(out, subname, subtype, false, true); - indent_down(); - indent(out) << "" << endl; - indent(out) << "" << endl; indent_down(); - indent(out) << "" << endl; + indent(out) << + "" << endl; } indent_down(); indent(out) << "" << endl; } else { - indent(out) << - "" << endl; + if (attrs.size() == 0) { + indent(out) << + "" << endl; + } else { + // Wow, all this work for a SIMPLE TYPE with attributes?!?!?! + indent(out) << "" << endl; + indent_up(); + indent(out) << "" << endl; + indent_up(); + indent(out) << "" << endl; + indent_up(); + indent(out) << "" << endl; + indent_up(); + vector::iterator a_iter; + for (a_iter = attrs.begin(); a_iter != attrs.end(); ++a_iter) { + indent(out) << "" << endl; + } + indent_down(); + indent(out) << "" << endl; + indent_down(); + indent(out) << "" << endl; + indent_down(); + indent(out) << "" << endl; + indent_down(); + indent(out) << "" << endl; + } } } @@ -140,7 +174,7 @@ void t_xsd_generator::generate_service(t_service* tservice) { for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) { string elemname = (*f_iter)->get_name() + "_response"; t_type* returntype = (*f_iter)->get_returntype(); - generate_element(f_xsd_, elemname, returntype, false, false); + generate_element(f_xsd_, elemname, returntype); f_xsd_ << endl; t_struct* xs = (*f_iter)->get_xceptions(); @@ -153,7 +187,7 @@ void t_xsd_generator::generate_service(t_service* tservice) { map::iterator ax_iter; for (ax_iter = all_xceptions.begin(); ax_iter != all_xceptions.end(); ++ax_iter) { - generate_element(f_xsd_, ax_iter->first, ax_iter->second, false, false); + generate_element(f_xsd_, ax_iter->first, ax_iter->second); } // Close the XSD document diff --git a/compiler/cpp/src/generate/t_xsd_generator.h b/compiler/cpp/src/generate/t_xsd_generator.h index 04136704..7a602835 100644 --- a/compiler/cpp/src/generate/t_xsd_generator.h +++ b/compiler/cpp/src/generate/t_xsd_generator.h @@ -40,7 +40,7 @@ class t_xsd_generator : public t_generator { private: - void generate_element(std::ostream& out, std::string name, t_type* ttype, bool optional, bool list_element); + void generate_element(std::ostream& out, std::string name, t_type* ttype, std::vector attrs=std::vector(), bool optional=false, bool list_element=false); std::string ns(std::string in, std::string ns) { return ns + ":" + in; diff --git a/compiler/cpp/src/parse/t_field.h b/compiler/cpp/src/parse/t_field.h index 03d4ba7e..090426a7 100644 --- a/compiler/cpp/src/parse/t_field.h +++ b/compiler/cpp/src/parse/t_field.h @@ -39,6 +39,14 @@ class t_field { return key_; } + void set_value(t_const_value* value) { + value_ = value; + } + + t_const_value* get_value() { + return value_; + } + void set_xsd_optional(bool xsd_optional) { xsd_optional_ = xsd_optional; } @@ -47,12 +55,12 @@ class t_field { return xsd_optional_; } - void set_value(t_const_value* value) { - value_ = value; + void add_xsd_attr(std::string attr) { + xsd_attrs_.push_back(attr); } - t_const_value* get_value() { - return value_; + const std::vector& get_xsd_attrs() { + return xsd_attrs_; } const std::string& get_doc() const { @@ -75,6 +83,7 @@ class t_field { t_const_value* value_; bool xsd_optional_; + std::vector xsd_attrs_; std::string doc_; bool has_doc_; diff --git a/compiler/cpp/src/thriftl.ll b/compiler/cpp/src/thriftl.ll index 5450ad29..5486adac 100644 --- a/compiler/cpp/src/thriftl.ll +++ b/compiler/cpp/src/thriftl.ll @@ -64,6 +64,7 @@ sliteral ("'"[^']*"'") "xsd_all" { return tok_xsd_all; } "xsd_optional" { return tok_xsd_optional; } "xsd_namespace" { return tok_xsd_namespace; } +"xsd_attrs" { return tok_xsd_attrs; } "include" { return tok_include; } "void" { return tok_void; } diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy index 9c389962..a53d0023 100644 --- a/compiler/cpp/src/thrifty.yy +++ b/compiler/cpp/src/thrifty.yy @@ -71,6 +71,7 @@ int y_field_val = -1; %token tok_xsd_all %token tok_xsd_optional %token tok_xsd_namespace +%token tok_xsd_attrs /** * Base datatype keywords @@ -154,6 +155,7 @@ int y_field_val = -1; %type Async %type XsdAll %type XsdOptional +%type XsdAttributes %type CppType %type DocTextOptional @@ -515,6 +517,16 @@ XsdOptional: $$ = false; } +XsdAttributes: + tok_xsd_attrs tok_identifier + { + $$ = $2; + } +| + { + $$ = NULL; + } + Xception: tok_xception tok_identifier '{' FieldList '}' { @@ -619,11 +631,11 @@ FieldList: } Field: - DocTextOptional FieldIdentifier FieldType tok_identifier FieldValue XsdOptional CommaOrSemicolonOptional + DocTextOptional FieldIdentifier FieldType tok_identifier FieldValue XsdOptional XsdAttributes CommaOrSemicolonOptional { pdebug("tok_int_constant : Field -> FieldType tok_identifier"); if ($2 < 0) { - pwarning(2, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $3); + pwarning(2, "No field key specified for %s, resulting protocol may have conflicts or not be backwards compatible!\n", $4); } $$ = new t_field($3, $4, $2); if ($5 != NULL) { @@ -634,6 +646,9 @@ Field: if ($1 != NULL) { $$->set_doc($1); } + if ($7 != NULL) { + $$->add_xsd_attr($7); + } } FieldIdentifier: