Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / orbsvcs / tests / InterfaceRepo / Application_Test / ifr_dii_client.cpp
blobdfc404651af1c90b5c49db2b0c5138c1de852ea6
1 // -*- C++ -*-
2 #include "ifr_dii_client.h"
3 #include "ace/Get_Opt.h"
5 IFR_DII_Client::IFR_DII_Client (void)
6 : namespace_name (CORBA::string_dup ("warehouse")),
7 interface_name (CORBA::string_dup ("inventory")),
8 op_name (CORBA::string_dup ("getCDinfo")),
9 lookup_by_name_ (false),
10 debug_ (false),
11 ior_output_file_(ACE_TEXT("file://iorfile"))
15 IFR_DII_Client::~IFR_DII_Client (void)
19 int
20 IFR_DII_Client::init (int argc,
21 ACE_TCHAR *argv[])
23 this->orb_ = CORBA::ORB_init (argc, argv);
25 if (this->parse_args (argc, argv) == -1)
27 return -1;
29 // In a reall application, we would get the scoped or
30 // local name from the Interface Repository and use that
31 // to get the object reference of the target via the Naming
32 // Service. Since we're not testing the Naming Service here,
33 // we just use the IOR which is stored in a file by the server.
34 this->target_ = this->orb_->string_to_object (ior_output_file_);
36 if (CORBA::is_nil (this->target_.in ()))
38 ACE_ERROR_RETURN ((
39 LM_ERROR,
40 "Unable to find interface repository in: %s\n", ior_output_file_),
41 -1);
44 return 0;
47 int
48 IFR_DII_Client::run (void)
50 int result = 0;
52 if (this->lookup_by_name_)
54 result = this->lookup_interface_def ();
56 if (result == -1)
58 return -1;
61 else
63 result = this->find_interface_def ();
65 if (result == -1)
67 return (-1);
71 this->get_operation_def ();
73 this->create_dii_request ();
75 this->invoke_and_display ();
77 return 0;
80 int
81 IFR_DII_Client::parse_args (int argc, ACE_TCHAR *argv[])
83 ACE_Get_Opt opts (argc, argv, ACE_TEXT("k:nd"));
84 int c;
86 while ((c = opts ()) != -1)
87 switch (c)
89 case 'd':
90 this->debug_ = true;
91 break;
92 case 'n': // Select lookup by name.
93 this->lookup_by_name_ = true;
94 break;
95 case 'k':
96 this->ior_output_file_ = opts.opt_arg ();
97 break;
99 case '?':
100 default:
101 ACE_ERROR_RETURN ((LM_ERROR,
102 "usage: %s"
103 " [-n]"
104 "\n",
105 argv [0]),
106 -1);
109 return 0;
113 IFR_DII_Client::find_interface_def (void)
115 this->target_def_ =
116 this->target_->_get_interface ();
118 if (CORBA::is_nil (this->target_def_.in ()))
120 ACE_ERROR_RETURN ((LM_ERROR,
121 "Unable to find interface def\n"),
122 -1);
125 return 0;
129 IFR_DII_Client::lookup_interface_def (void)
131 CORBA::Object_var obj =
132 this->orb_->resolve_initial_references ("InterfaceRepository");
134 this->repo_ = CORBA::Repository::_narrow (obj.in ());
136 // Is there a contained object of some kind at any level in the
137 // repository called "warehouse"?
138 CORBA::ContainedSeq_var candidates =
139 this->repo_->lookup_name (this->namespace_name.in (),
140 -1, // Unlimited level recursion.
141 CORBA::dk_all, // Any type of contained object.
142 1); // Exclude parents of interfaces.
144 CORBA::ULong length = candidates->length ();
145 CORBA::Container_var candidate;
146 CORBA::ContainedSeq_var interfaces;
147 CORBA::ULong n_interfaces = 0;
148 CORBA::String_var name;
150 // No point continuing; theres nothing to look at.
151 if (length == 0)
153 return -1;
156 // The length is 1 in this case, but in general, it could
157 // be any length.
158 for (CORBA::ULong i = 0; i < length; ++i)
160 candidate =
161 CORBA::Container::_narrow (candidates[i]);
163 // Is this contained item itself a container?
164 if (!CORBA::is_nil (candidate.in ()))
166 // Does this container contain any interfaces?
167 interfaces = candidate->contents (CORBA::dk_Interface,
168 1); // Exclude parents.
170 n_interfaces = interfaces->length ();
172 // Here we are just getting out of the loop (which
173 // only has length 1 anyway) when we see the first
174 // container that contains at least one interface.
175 // In a real application, we'd probably have a more
176 // useful criterion,
177 if (n_interfaces > 0)
179 break;
184 // The length is 1 in this case, but in general, it could
185 // be any length.
186 for (CORBA::ULong j = 0; j < n_interfaces ; ++j)
188 name = interfaces[j]->name ();
190 if (!ACE_OS::strcmp (name.in (), this->interface_name.in ()))
192 this->target_def_ =
193 CORBA::InterfaceDef::_narrow (interfaces[j]);
196 return 0;
199 void
200 IFR_DII_Client::get_operation_def (void)
202 // What operation(s) does this interface contain?
203 CORBA::ContainedSeq_var operations =
204 this->target_def_->contents (CORBA::dk_Operation,
205 0); // Do not exclude inherited operations.
207 CORBA::ULong n_operations = operations->length ();
208 CORBA::String_var operation_name;
210 // The length is 1 in this case, but in general, it could
211 // be any length.
212 for (CORBA::ULong i = 0; i < n_operations; ++i)
214 operation_name = operations[i]->name ();
216 if (!ACE_OS::strcmp (operation_name.in (), this->op_name.in ()))
218 this->op_ =
219 CORBA::OperationDef::_narrow (operations[i]);
221 break;
226 void
227 IFR_DII_Client::create_dii_request (void)
229 this->req_ = this->target_->_request (this->op_name.in ());
231 this->result_ = this->op_->result ();
233 this->req_->set_return_type (this->result_.in ());
235 CORBA::ParDescriptionSeq_var params =
236 this->op_->params ();
238 CORBA::ULong length = params->length ();
240 // This example of the discovery of parameter information is
241 // purposely contrived for the sake of brevity. A real
242 // application would have more versatile code here, and much
243 // more of it.
244 for (CORBA::ULong i = 0; i < length; ++i)
246 CORBA::TCKind const kind =
247 params[i].type->kind ();
249 switch (params[i].mode)
251 case CORBA::PARAM_IN:
252 if (kind == CORBA::tk_string
253 && ACE_OS::strcmp (params[i].name.in (), "artist") == 0)
255 // The servant will match the substring 'Beatles'.
256 this->req_->add_in_arg (params[i].name.in ()) <<= "the Beatles";
259 break;
260 case CORBA::PARAM_INOUT:
261 if (kind == CORBA::tk_string
262 && ACE_OS::strcmp (params[i].name.in (), "title") == 0)
264 // This isn't the exact title, but the servant will find the
265 // partial match, and return the full, correct title.
266 this->req_->add_inout_arg (params[i].name.in ()) <<= "Sgt. Pepper's";
269 break;
270 case CORBA::PARAM_OUT:
272 if (kind == CORBA::tk_float
273 && ACE_OS::strcmp (params[i].name.in (), "price") == 0)
275 CORBA::Float tmp = -1.0f;
276 CORBA::Any any;
277 any <<= tmp;
279 // The servant will return 0.0 if the title is not found.
280 this->req_->arguments ()->add_value (params[i].name.in (),
281 any,
282 CORBA::ARG_OUT);
285 break;
291 void
292 IFR_DII_Client::invoke_and_display (void)
294 this->req_->invoke ();
296 CORBA::TypeCode_var tc = this->req_->return_value ().type ();
298 CORBA::TCKind const kind = tc->kind ();
300 if (kind == CORBA::tk_boolean)
302 CORBA::NVList_ptr args = this->req_->arguments ();
304 const char *artist = 0;
306 ACE_ASSERT ((*args->item (0)->value () >>= artist) == true);
308 ACE_ASSERT (ACE_OS::strcmp (artist, "the Beatles") == 0);
310 const char *title = 0;
312 ACE_ASSERT ((*args->item (1)->value () >>= title) == true);
314 const char *correct = "Sgt. Pepper's Lonely Hearts Club Band";
315 ACE_ASSERT (ACE_OS::strcmp (title, correct) == 0);
316 ACE_UNUSED_ARG (correct);
318 CORBA::Float price = 0.0f;
320 ACE_ASSERT ((*args->item (2)->value () >>= price) == true);
322 ACE_ASSERT (ACE::is_equal (price, 13.49f));
324 if (this->debug_)
326 ACE_DEBUG ((LM_DEBUG,
327 ACE_TEXT ("%C:\t%C\n")
328 ACE_TEXT ("%C:\t%C\n")
329 ACE_TEXT ("%C:\t$%2.2f\n"),
330 args->item (0)->name (),
331 artist,
332 args->item (1)->name (),
333 title,
334 args->item (2)->name (),
335 price));
338 CORBA::Boolean in_stock = 0;
340 CORBA::Boolean ret_status =
341 (this->req_->return_value () >>= CORBA::Any::to_boolean (in_stock));
342 ACE_UNUSED_ARG (ret_status);
344 ACE_ASSERT (ret_status == 1);
345 ACE_ASSERT (in_stock == 1);
347 if (this->debug_)
349 if (in_stock)
351 ACE_DEBUG ((LM_DEBUG,
352 ACE_TEXT ("status: in stock\n")));
354 else
356 ACE_DEBUG ((LM_DEBUG,
357 ACE_TEXT ("status: out of stock\n")));