Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / examples / Simple / Simple_util.cpp
blob3958418597aa62f601545bb67d0de536febc599b
1 #ifndef SIMPLE_UTIL_C
2 #define SIMPLE_UTIL_C
4 #include "Simple_util.h"
5 #include "tao/IORTable/IORTable.h"
6 #include "tao/debug.h"
7 #include "ace/OS_NS_stdio.h"
8 #include "ace/OS_NS_unistd.h"
9 #include "ace/OS_NS_string.h"
10 #include "ace/OS_NS_fcntl.h"
12 // Constructor.
13 template <class Servant>
14 Server<Servant>::Server ()
15 : servant_ (0)
16 , ior_output_file_ (0)
17 , naming_ (0)
18 , ins_ (0)
20 Servant *tmp = 0;
21 ACE_NEW_THROW_EX (tmp,
22 Servant (),
23 CORBA::NO_MEMORY ());
24 this->servant_ = tmp;
27 // Parse the command-line arguments and set options.
28 template <class Servant> int
29 Server<Servant>::parse_args ()
31 ACE_Get_Opt get_opts (this->argc_, this->argv_,
32 ACE_TEXT ("do:ni:"), 1, 0,
33 ACE_Get_Opt::REQUIRE_ORDER);
34 int c = 0;
36 while ((c = get_opts ()) != -1)
37 switch (c)
39 case 'd': // debug flag.
40 TAO_debug_level++;
41 break;
42 case 'o': // output the IOR to a file.
43 this->ior_output_file_ = get_opts.opt_arg ();
44 break;
45 case 'n': //Use naming service
46 this->naming_ = 1;
47 break;
48 case 'i': // For Testing the InterOperable Naming Service.
49 this->ins_ = get_opts.opt_arg ();
50 break;
51 case 'h': // display help for use of the server.
52 default:
53 ACE_ERROR_RETURN ((LM_ERROR,
54 ACE_TEXT ("usage: %s")
55 ACE_TEXT (" [-d (debug)]")
56 ACE_TEXT (" [-o] <ior_output_file>")
57 ACE_TEXT (" [-n (use naming service)]")
58 ACE_TEXT (" [-i] <InterOperable Naming Service simple object key>")
59 ACE_TEXT (" [-h (help)]")
60 ACE_TEXT ("\n"),
61 this->argv_ [0]),
62 -1);
65 // Indicates successful parsing of command line.
66 return 0;
69 // Add the ObjectID:IOR mapping to the IOR table of
70 // the ORB. Ignore this method if you are not testing for
71 // the InterOperable Naming Service.
72 template <class Servant> int
73 Server<Servant>::test_for_ins (const char *ior)
75 CORBA::ORB_var orb = this->orb_manager_.orb ();
77 if (TAO_debug_level > 0)
78 ACE_DEBUG ((LM_DEBUG,
79 ACE_TEXT ("Adding (KEY:IOR) %s:%C\n"),
80 this->ins_,
81 ior));
83 try
85 CORBA::Object_var table_object =
86 orb->resolve_initial_references ("IORTable");
88 IORTable::Table_var adapter =
89 IORTable::Table::_narrow (table_object.in ());
90 if (CORBA::is_nil (adapter.in ()))
92 ACE_ERROR_RETURN ((LM_ERROR,
93 ACE_TEXT ("Nil IORTable\n")),
94 -1);
97 adapter->bind (ACE_TEXT_ALWAYS_CHAR (this->ins_), ior);
99 catch (const CORBA::Exception& ex)
101 ex._tao_print_exception ("ERROR: test_for_ins failed\n");
102 return -1;
105 return 0;
108 // Initialize the server.
109 template <class Servant> int
110 Server<Servant>::init (const char *servant_name,
111 int argc,
112 ACE_TCHAR *argv[])
114 // Call the init of <TAO_ORB_Manager> to initialize the ORB and
115 // create a child POA under the root POA.
116 if (this->orb_manager_.init_child_poa (argc,
117 argv,
118 "child_poa") == -1)
119 ACE_ERROR_RETURN ((LM_ERROR,
120 ACE_TEXT ("%p\n"),
121 ACE_TEXT ("init_child_poa")),
122 -1);
124 this->argc_ = argc;
125 this->argv_ = argv;
127 int retval = this->parse_args ();
129 if (retval != 0)
130 return retval;
132 CORBA::ORB_var orb = this->orb_manager_.orb ();
134 // Stash our ORB pointer for later reference.
135 this->servant_->orb (orb.in ());
137 if (this->naming_ == 1)
139 // Call naming service
140 if (this->register_name (servant_name) == -1)
141 ACE_ERROR_RETURN ((LM_ERROR,
142 ACE_TEXT ("\n Naming Service\n")),
143 -1);
145 return 0;
148 // Activate the servant in its own child POA.
150 // Make sure that you check for failures here via the try?!
153 CORBA::String_var str =
154 this->orb_manager_.activate_under_child_poa (servant_name,
155 this->servant_.in ());
157 ACE_DEBUG ((LM_DEBUG,
158 ACE_TEXT ("The IOR is: <%C>\n"),
159 str.in ()));
161 if (this->ins_ && this->test_for_ins (str.in ()) != 0)
162 ACE_ERROR_RETURN ((LM_ERROR,
163 ACE_TEXT ("test_for_ins (): failed\n")),
164 -1);
166 if (this->ior_output_file_)
168 FILE *fh = ACE_OS::fopen (this->ior_output_file_, "w");
169 if (fh == 0)
170 ACE_ERROR_RETURN ((LM_ERROR,
171 ACE_TEXT ("Unable to open %s for writing (%p)\n"),
172 this->ior_output_file_,
173 ACE_TEXT ("fopen")),
174 -1);
175 ACE_OS::fprintf (fh, "%s", str.in ());
176 ACE_OS::fclose (fh);
179 catch (const CORBA::Exception& ex)
181 ex._tao_print_exception ("\tException in activation of POA");
182 return -1;
185 return 0;
188 template <class Servant>int
189 Server<Servant>::run ()
191 // Run the main event loop for the ORB.
192 if (this->orb_manager_.run () == -1)
193 ACE_ERROR_RETURN ((LM_ERROR,
194 ACE_TEXT ("Server_i::run")),
195 -1);
197 return 0;
200 template <class Servant> int
201 Server<Servant>::register_name (const char *name)
203 CORBA::ORB_var orb = this->orb_manager_.orb ();
205 if (this->naming_client_.init (orb.in ()) == -1)
206 return -1;
208 // create the name for the naming service
209 CosNaming::Name bindName;
210 bindName.length (1);
211 bindName[0].id = CORBA::string_dup (name);
213 // (re)Bind the object.
216 CORBA::Object_var object = servant_->_this ();
218 this->orb_manager_.activate_poa_manager ();
220 naming_client_->rebind (bindName,
221 object.in());
223 // Test for INS.
224 if (this->ins_)
226 CORBA::String_var ior =
227 orb->object_to_string (object.in ());
228 if (this->test_for_ins (ior.in ()) != 0)
229 ACE_ERROR_RETURN ((LM_ERROR,
230 ACE_TEXT ("test_for_ins (): failed\n")),
231 -1);
234 catch (const CosNaming::NamingContext::AlreadyBound&)
236 ACE_ERROR_RETURN ((LM_ERROR,
237 ACE_TEXT ("Unable to bind %C\n"),
238 name),
239 -1);
242 return 0;
245 // Constructor.
246 template <class ServerInterface>
247 Client<ServerInterface>::Client ()
248 : ior_ ("")
249 , do_shutdown_ (0)
253 // Reads the Server ior from a file
254 template <class ServerInterface> int
255 Client<ServerInterface>::read_ior (ACE_TCHAR *filename)
257 // Open the file for reading.
258 ACE_HANDLE f_handle = ACE_OS::open (filename, 0);
260 if (f_handle == ACE_INVALID_HANDLE)
261 ACE_ERROR_RETURN ((LM_ERROR,
262 ACE_TEXT ("Unable to open %s for writing (%p)\n"),
263 filename,
264 ACE_TEXT ("open")),
265 -1);
267 ACE_Read_Buffer ior_buffer (f_handle, true);
268 char *data = ior_buffer.read ();
270 if (data == 0)
271 ACE_ERROR_RETURN ((LM_ERROR,
272 ACE_TEXT ("Unable to read ior (%p)\n"),
273 ACE_TEXT ("read")),
274 -1);
276 this->ior_ = data;
277 ior_buffer.alloc ()->free (data);
279 ACE_OS::close (f_handle);
281 return 0;
284 // Parses the command line arguments and returns an error status.
285 template <class ServerInterface> int
286 Client<ServerInterface>::parse_args ()
288 ACE_Get_Opt get_opts (argc_, argv_,
289 ACE_TEXT ("df:nk:x"), 1, 0,
290 ACE_Get_Opt::REQUIRE_ORDER);
291 int c = 0;
292 int result = 0;
294 while ((c = get_opts ()) != -1)
295 switch (c)
297 case 'd': // debug flag
298 TAO_debug_level++;
299 break;
300 case 'k': // ior provide on command line
301 this->ior_ = ACE_TEXT_ALWAYS_CHAR(get_opts.opt_arg ());
302 break;
303 case 'n': // Use naming service
304 this->naming_ = 1;
305 break;
306 case 'f': // read the IOR from the file.
307 result = this->read_ior (get_opts.opt_arg ());
308 if (result < 0)
309 ACE_ERROR_RETURN ((LM_ERROR,
310 ACE_TEXT ("Unable to read ior from %s (%p)\n"),
311 get_opts.opt_arg (),
312 ACE_TEXT ("read_ior")),
313 -1);
314 break;
315 case 'x': // read the flag for shutting down
316 this->do_shutdown_ = 1;
317 break;
318 case 'h': // display help for use of the client.
319 ACE_ERROR_RETURN ((LM_ERROR,
320 ACE_TEXT ("usage: %s")
321 ACE_TEXT (" [-d (debug)]")
322 ACE_TEXT (" [-k] <ior>")
323 ACE_TEXT (" [-f] <ior_output_file>")
324 ACE_TEXT (" [-n (use naming service)]")
325 ACE_TEXT (" [-x (shutdown server)]")
326 ACE_TEXT (" [-h (help)]")
327 ACE_TEXT ("\n"),
328 this->argv_ [0]),
329 -1);
332 // Indicates successful parsing of command line.
333 return 0;
336 template <class ServerInterface>
337 Client<ServerInterface>::~Client ()
339 this->orb_->destroy ();
342 template <class ServerInterface> int
343 Client<ServerInterface>::init (const char *name,
344 int argc,
345 ACE_TCHAR **argv)
347 this->argc_ = argc;
348 this->argv_ = argv;
352 // Retrieve the ORB.
353 this->orb_ = CORBA::ORB_init (this->argc_, this->argv_);
355 // Parse command line and verify parameters.
356 if (this->parse_args () == -1)
357 return -1;
359 if (this->ior_.length () != 0)
361 CORBA::Object_var server_object =
362 this->orb_->string_to_object (this->ior_.c_str ());
364 if (CORBA::is_nil (server_object.in ()))
365 ACE_ERROR_RETURN ((LM_ERROR,
366 ACE_TEXT ("invalid ior <%C>\n"),
367 this->ior_.c_str ()),
368 -1);
369 this->server_ = ServerInterface::_narrow (server_object.in ());
370 if (CORBA::is_nil (this->server_.in ()))
372 ACE_ERROR_RETURN ((LM_ERROR,
373 ACE_TEXT ("Nil Server\n")),
374 -1);
377 else if (this->naming_ == 1)
379 // No IOR specified. Use the Naming Service
380 ACE_DEBUG((LM_DEBUG,
381 ACE_TEXT ("Using the Naming Service\n")));
382 int retv = this->obtain_initial_references (name);
383 if (retv ==-1)
384 return -1;
386 else
387 ACE_ERROR_RETURN ((LM_ERROR,
388 ACE_TEXT ("no ior or naming options specified\n")),
389 -1);
391 catch (const CORBA::Exception& ex)
393 ex._tao_print_exception ("Client_i::init");
394 return -1;
397 return 0;
400 template <class ServerInterface> int
401 Client<ServerInterface>::obtain_initial_references (const char *name)
405 // Initialize the naming services.
406 if (naming_client_.init (orb_.in ()) != 0)
407 ACE_ERROR_RETURN ((LM_ERROR,
408 ACE_TEXT ("[CLIENT] Process/Thread Id : (%P/%t) Unable to initialize ")
409 ACE_TEXT ("the TAO_Naming_Client.\n")),
410 -1);
412 CosNaming::Name server_name (1);
413 server_name.length (1);
414 server_name[0].id =
415 CORBA::string_dup (name);
416 CORBA::Object_var obj =
417 naming_client_->resolve (server_name);
419 this->server_ = ServerInterface::_narrow (obj.in ());
420 if (CORBA::is_nil (this->server_.in ()))
422 ACE_ERROR_RETURN ((LM_ERROR,
423 ACE_TEXT ("Nil Server\n")),
424 -1);
427 catch (const CORBA::Exception& ex)
429 ex._tao_print_exception ("Client::obtain_initial_references");
430 return -1;
433 return 0;
436 template <class ServerInterface> int
437 Client<ServerInterface>::do_shutdown ()
439 // Returns the shutdwon flag
440 return this->do_shutdown_;
443 template <class ServerInterface> void
444 Client<ServerInterface>::do_shutdown (int flag)
446 // Fills the flag
447 this->do_shutdown_ = flag;
450 #endif /* SIMPLE_UTIL_C */