in compiler/cpp/src/thrift/generate/t_java_generator.cc [3770:3982]
void t_java_generator::generate_process_async_function(t_service* tservice, t_function* tfunction) {
string argsname = tfunction->get_name() + "_args";
string resultname = tfunction->get_name() + "_result";
if (tfunction->is_oneway()) {
resultname = "org.apache.thrift.TBase";
}
string resulttype = type_name(tfunction->get_returntype(), true);
(void)tservice;
// Open class
indent(f_service_) << "public static class " << make_valid_java_identifier(tfunction->get_name())
<< "<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, "
<< argsname << ", " << resulttype << ", " << resultname << "> {" << '\n';
indent_up();
indent(f_service_) << "public " << make_valid_java_identifier(tfunction->get_name()) << "() {" << '\n';
indent(f_service_) << " super(\"" << tfunction->get_name() << "\");" << '\n';
indent(f_service_) << "}" << '\n' << '\n';
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public " << resultname << " getEmptyResultInstance() {" << '\n';
if (tfunction->is_oneway()) {
indent(f_service_) << " return null;" << '\n';
}
else {
indent(f_service_) << " return new " << resultname << "();" << '\n';
}
indent(f_service_) << "}" << '\n' << '\n';
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public " << argsname << " getEmptyArgsInstance() {" << '\n';
indent(f_service_) << " return new " << argsname << "();" << '\n';
indent(f_service_) << "}" << '\n' << '\n';
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public org.apache.thrift.async.AsyncMethodCallback<" << resulttype
<< "> getResultHandler(final "
"org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, "
"final int seqid) {"
<< '\n';
indent_up();
indent(f_service_) << "final org.apache.thrift.AsyncProcessFunction fcall = this;" << '\n';
indent(f_service_) << "return new org.apache.thrift.async.AsyncMethodCallback<" << resulttype
<< ">() { " << '\n';
indent_up();
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public void onComplete(" << resulttype << " o) {" << '\n';
indent_up();
if (!tfunction->is_oneway()) {
indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n';
if (!tfunction->get_returntype()->is_void()) {
indent(f_service_) << "result.success = o;" << '\n';
// Set isset on success field
if (!type_can_be_null(tfunction->get_returntype())) {
indent(f_service_) << "result.set" << get_cap_name("success") << get_cap_name("isSet")
<< "(true);" << '\n';
}
}
indent(f_service_) << "try {" << '\n';
indent(f_service_)
<< " fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);"
<< '\n';
indent(f_service_) << "} catch (org.apache.thrift.transport.TTransportException e) {" << '\n';
indent_up();
f_service_ << indent()
<< "_LOGGER.error(\"TTransportException writing to internal frame buffer\", e);"
<< '\n'
<< indent() << "fb.close();" << '\n';
indent_down();
indent(f_service_) << "} catch (java.lang.Exception e) {" << '\n';
indent_up();
f_service_ << indent() << "_LOGGER.error(\"Exception writing to internal frame buffer\", e);"
<< '\n'
<< indent() << "onError(e);" << '\n';
indent_down();
indent(f_service_) << "}" << '\n';
}
indent_down();
indent(f_service_) << "}" << '\n';
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public void onError(java.lang.Exception e) {" << '\n';
indent_up();
if (tfunction->is_oneway()) {
indent(f_service_) << "if (e instanceof org.apache.thrift.transport.TTransportException) {"
<< '\n';
indent_up();
f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << '\n'
<< indent() << "fb.close();" << '\n';
indent_down();
indent(f_service_) << "} else {" << '\n';
indent_up();
f_service_ << indent() << "_LOGGER.error(\"Exception inside oneway handler\", e);" << '\n';
indent_down();
indent(f_service_) << "}" << '\n';
} else {
indent(f_service_) << "byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;" << '\n';
indent(f_service_) << "org.apache.thrift.TSerializable msg;" << '\n';
indent(f_service_) << resultname << " result = new " << resultname << "();" << '\n';
t_struct* xs = tfunction->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
if (xceptions.size() > 0) {
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
if (x_iter == xceptions.begin())
f_service_ << indent();
string type = type_name((*x_iter)->get_type(), false, false);
string name = (*x_iter)->get_name();
f_service_ << "if (e instanceof " << type << ") {" << '\n';
indent_up();
f_service_ << indent() << "result." << make_valid_java_identifier(name) << " = (" << type << ") e;" << '\n'
<< indent() << "result.set" << get_cap_name(name) << get_cap_name("isSet")
<< "(true);" << '\n'
<< indent() << "msg = result;" << '\n';
indent_down();
indent(f_service_) << "} else ";
}
} else {
indent(f_service_);
}
f_service_ << "if (e instanceof org.apache.thrift.transport.TTransportException) {" << '\n';
indent_up();
f_service_ << indent() << "_LOGGER.error(\"TTransportException inside handler\", e);" << '\n'
<< indent() << "fb.close();" << '\n'
<< indent() << "return;" << '\n';
indent_down();
indent(f_service_) << "} else if (e instanceof org.apache.thrift.TApplicationException) {"
<< '\n';
indent_up();
f_service_ << indent() << "_LOGGER.error(\"TApplicationException inside handler\", e);" << '\n'
<< indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << '\n'
<< indent() << "msg = (org.apache.thrift.TApplicationException)e;" << '\n';
indent_down();
indent(f_service_) << "} else {" << '\n';
indent_up();
f_service_ << indent() << "_LOGGER.error(\"Exception inside handler\", e);" << '\n'
<< indent() << "msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;" << '\n'
<< indent()
<< "msg = new "
"org.apache.thrift.TApplicationException(org.apache.thrift."
"TApplicationException.INTERNAL_ERROR, e.getMessage());"
<< '\n';
indent_down();
f_service_ << indent() << "}" << '\n'
<< indent() << "try {" << '\n'
<< indent() << " fcall.sendResponse(fb,msg,msgType,seqid);" << '\n'
<< indent() << "} catch (java.lang.Exception ex) {" << '\n'
<< indent() << " _LOGGER.error(\"Exception writing to internal frame buffer\", ex);"
<< '\n'
<< indent() << " fb.close();" << '\n'
<< indent() << "}" << '\n';
}
indent_down();
indent(f_service_) << "}" << '\n';
indent_down();
indent(f_service_) << "};" << '\n';
indent_down();
indent(f_service_) << "}" << '\n' << '\n';
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public boolean isOneway() {" << '\n';
indent(f_service_) << " return " << ((tfunction->is_oneway()) ? "true" : "false") << ";" << '\n';
indent(f_service_) << "}" << '\n' << '\n';
indent(f_service_) << java_override_annotation() << '\n';
indent(f_service_) << "public void start(I iface, " << argsname
<< " args, org.apache.thrift.async.AsyncMethodCallback<" << resulttype
<< "> resultHandler) throws org.apache.thrift.TException {" << '\n';
indent_up();
// Generate the function call
t_struct* arg_struct = tfunction->get_arglist();
const std::vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator f_iter;
f_service_ << indent();
f_service_ << "iface." << get_rpc_method_name(tfunction->get_name()) << "(";
bool first = true;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (first) {
first = false;
} else {
f_service_ << ", ";
}
f_service_ << "args." << make_valid_java_identifier((*f_iter)->get_name());
}
if (!first)
f_service_ << ",";
f_service_ << "resultHandler";
f_service_ << ");" << '\n';
indent_down();
indent(f_service_) << "}";
// Close function
f_service_ << '\n';
// Close class
indent_down();
f_service_ << indent() << "}" << '\n' << '\n';
}