summaryrefslogtreecommitdiff
path: root/trunk/TAO/orbsvcs/examples/ORT/Gateway_i.cpp
blob: f4ce9754556758b5fc3a5674a43671123a3bd509 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//$Id$

#include "Gateway_i.h"

#include "tao/AnyTypeCode/Any.h"
#include "tao/AnyTypeCode/NVList.h"
#include "tao/AnyTypeCode/ExceptionA.h"

#include "tao/IFR_Client/IFR_BasicC.h"

#include "tao/DynamicInterface/Server_Request.h"
#include "tao/DynamicInterface/Request.h"
#include "tao/DynamicInterface/Unknown_User_Exception.h"

#include "tao/ORB.h"
#include "tao/LocalObject.h"

ACE_RCSID (ORT,
           Gateway_i,
           "$Id$")

Gateway_i::
Gateway_i (CORBA::ORB_ptr orb,
           PortableServer::Current_ptr poa_current)
  : orb_ (orb),
    poa_current_ (poa_current)
{
  /// Constructor
}

void
Gateway_i::invoke (CORBA::ServerRequest_ptr request
                   ACE_ENV_ARG_DECL)
{
  PortableServer::ObjectId_var target_id =
    this->poa_current_->get_object_id ();

  CORBA::String_var stringified_object_id =
    PortableServer::ObjectId_to_string (target_id.in ());

  CORBA::Object_var target_object =
    this->orb_->string_to_object (stringified_object_id.in ()
                                  ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  // Use the IfR interfaces to query the NVList for this object...
  CORBA::InterfaceDef_var target_interface =
    target_object->_get_interface (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_CHECK;

  if (CORBA::is_nil (target_interface.in ()))
    {
      ///
    }

  // This is the target operation...
  CORBA::String_var operation_name =
    request->operation ();

  CORBA::Contained_var contained_operation =
    target_interface->lookup (operation_name.in ());

  CORBA::OperationDef_var operation =
    CORBA::OperationDef::_narrow (contained_operation.in ());

  // Save the result typecode...
  CORBA::TypeCode_var result_typecode =
    operation.in ()->result (ACE_ENV_SINGLE_ARG_PARAMETER);
  ACE_CHECK;

  CORBA::ParDescriptionSeq_var parameters =
    operation.in ()->params ();

  // Build the NVList based on the info from the IfR
  CORBA::NVList_ptr arguments;
  this->orb_->create_list (parameters->length (),
                           arguments
                           ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  CORBA::Flags flags = 0;

  CORBA::ULong length = parameters->length ();

  CORBA::ULong i = 0;

  for (i = 0; i < length; ++i)
    {
      switch (parameters[i].mode)
        {
        case CORBA::PARAM_IN:
          flags = CORBA::ARG_IN;
          break;
        case CORBA::PARAM_OUT:
          flags = CORBA::ARG_OUT;
          break;
        case CORBA::PARAM_INOUT:
          flags = CORBA::ARG_INOUT;
          break;
        }
    }

  for (i = 0; i != length; ++i)
    {
      CORBA::Any any;
      any._tao_set_typecode (parameters[i].type.in ());

      arguments->add_value (parameters[i].name,
                            any,
                            flags
                            ACE_ENV_ARG_PARAMETER);
      ACE_CHECK;
    }

  // Extract the values of the arguments from the DSI ServerRequest
  request->arguments (arguments ACE_ENV_ARG_PARAMETER);

  // Use the NVList (with values) to create a DII Request...
  CORBA::Request_var dii_request;

  CORBA::NamedValue *named_value = 0;

  this->orb_->create_named_value (named_value
                                  ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  CORBA::ContextList *context_list = 0;
  CORBA::ExceptionList *exceptions = 0;

  target_object->_create_request (CORBA::Context::_nil (),
                                  operation_name.in (),
                                  arguments,
                                  named_value, /* Result */
                                  exceptions,
                                  context_list, /* Context List */
                                  dii_request.inout (),
                                  CORBA::Flags (0)
                                  ACE_ENV_ARG_PARAMETER);
  ACE_CHECK;

  // Set the return type...
  dii_request->set_return_type (result_typecode.in ());

  ACE_TRY
    {
      // Make the DII request
      dii_request->invoke (ACE_ENV_SINGLE_ARG_PARAMETER);
      ACE_TRY_CHECK;

      // At this point the NVList contains all the out and inout
      // arguments, but we need to extract the return value...
    }
  ACE_CATCH (CORBA::UnknownUserException, user_ex)
    {
      // Pass the exception back to the server request...
      request->set_exception (user_ex.exception ());
      return;
    }
  ACE_CATCH (CORBA::SystemException, sys_ex)
    {
      CORBA::Any any;
      any <<= sys_ex;
      // Pass the exception back to the server request...
      request->set_exception (any);
      return;
    }
  ACE_CATCHANY;
  ACE_ENDTRY;

  request->set_result (dii_request->return_value ());
  // Using the same NVList for both the DSI Server Request and the DII
  // Request takes care of the out and inout arguments (whew!)
}

CORBA::RepositoryId
Gateway_i::_primary_interface (const PortableServer::ObjectId &,
                               PortableServer::POA_ptr
                               ACE_ENV_ARG_DECL_NOT_USED)
{
  return 0;
}