void t_java_generator::generate_process_async_function()

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';
}