Salome HOME
26ca3255fba9d9b6dcd73911c00d8e1db0b99c63
[modules/yacs.git] / src / yacsloader / Test / echoSrv.cxx
1 // Copyright (C) 2006-2022  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <time.h>
21 #include <pthread.h>
22 #ifdef WIN32
23 #include <windows.h>
24 #define sleep _sleep
25 #else
26 #include <unistd.h>
27 #endif
28
29 #include <echo.hh>
30
31 #include <iostream>
32
33 //#define _DEVDEBUG_
34 #include "YacsTrace.hxx"
35
36 using namespace std;
37
38 CORBA::ORB_var orb;
39 static CORBA::Boolean bindObjectToName(CORBA::ORB_ptr, CORBA::Object_ptr,const char*);
40
41 static ostream& operator<<(ostream& os, const CORBA::Exception& e)
42 {
43   CORBA::Any tmp;
44   tmp<<= e;
45   CORBA::TypeCode_var tc = tmp.type();
46   const char *p = tc->name();
47   if ( *p != '\0' ) {
48     os<<p;
49   }
50   else  {
51     os << tc->id();
52   }
53   return os;
54 }
55
56 class Obj_i : public POA_eo::Obj, public PortableServer::RefCountServantBase
57 {
58 public:
59   inline Obj_i() {}
60   virtual ~Obj_i() {}
61   CORBA::Long echoLong(CORBA::Long i);
62 };
63
64 class C_i : public POA_eo::C, public PortableServer::RefCountServantBase
65 {
66 public:
67   inline C_i() {}
68   virtual ~C_i() {}
69   CORBA::Long echoLong(CORBA::Long i);
70 };
71
72 class D_i : public POA_eo::D, public PortableServer::RefCountServantBase
73 {
74 public:
75   inline D_i() {}
76   virtual ~D_i() {}
77   CORBA::Long echoLong(CORBA::Long i);
78   CORBA::Long echoLong2(CORBA::Long i);
79 };
80
81 class E_i : public POA_eo::E, public PortableServer::RefCountServantBase
82 {
83 public:
84   inline E_i() {}
85   virtual ~E_i() {}
86   CORBA::Long echoLong(CORBA::Long i);
87   CORBA::Long echoLong2(CORBA::Long i);
88 };
89
90 class Echo_i : public POA_eo::Echo,
91                public PortableServer::RefCountServantBase
92 {
93 public:
94   inline Echo_i() {}
95   virtual ~Echo_i() {}
96   virtual char* echoString(const char* mesg);
97   virtual CORBA::Boolean echoBoolean(CORBA::Boolean b);
98   CORBA::Long echoLong(CORBA::Long i);
99   void echoDouble(CORBA::Double i,CORBA::Double& j) ;
100   void echoDoubleVec(const eo::DoubleVec& i,eo::DoubleVec_out j) ;
101   void echoDoubleVecVec(const eo::DoubleVecVec&, eo::DoubleVecVec_out);
102   void echoIntVec(const eo::IntVec&, eo::IntVec_out);
103   void echoStrVec(const eo::StrVec&, eo::StrVec_out);
104   void echoBoolVec(const eo::BoolVec&, eo::BoolVec_out);
105   void echoObjectVec(const eo::ObjectVec&, eo::ObjectVec_out);
106   void echoObj2(eo::Obj_ptr , eo::Obj_out);
107   void echoD(eo::D_ptr , eo::D_out);
108   void echoC(eo::C_ptr , eo::C_out);
109   void echoObjectVecVec(const eo::ObjectVecVec&, eo::ObjectVecVec_out);
110
111   eo::Obj_ptr echoObj(CORBA::Long i, eo::Obj_ptr o, CORBA::Long j, eo::Obj_out oo);
112   void createObj(CORBA::Long i, eo::Obj_out oo);
113   void createC(eo::C_out oo);
114   void echoAll(CORBA::Double d,CORBA::Long l,const char * m,eo::Obj_ptr o,CORBA::Double& dd,CORBA::Long& ll,CORBA::String_out s,eo::Obj_out oo);
115   void sleepLong(CORBA::Double time1,CORBA::Double& time2) ;
116   virtual eo::S2* echoStruct(const eo::S2&);
117   virtual eo::S3* echoStruct2(const eo::S3&);
118   virtual void shutdown();
119   virtual PortableServer::POA_ptr _default_POA();
120 protected:
121   int _ctr;
122   pthread_mutex_t _mutex;
123 };
124
125 //Implementation Echo
126 PortableServer::POA_ptr Echo_i::_default_POA()
127 {
128   _ctr =0;
129   pthread_mutex_init(&_mutex, NULL);
130   PortableServer::POA_var root_poa=PortableServer::POA::_the_root_poa();
131   try{
132     return PortableServer::POA::_duplicate(root_poa->find_POA("shortcut",0));
133   }
134   catch(...){
135     //return PortableServer::POA::_duplicate(root_poa);
136     return root_poa._retn();
137   }
138 }
139
140
141 void Echo_i::shutdown()
142 {
143   // Shutdown the ORB (but do not wait for completion).  This also
144   // causes the main thread to unblock from CORBA::ORB::run().
145   orb->shutdown(0);
146 }
147
148 char* Echo_i::echoString(const char* mesg)
149 {
150   DEBTRACE("Echo_i::echoString " << mesg);
151   return CORBA::string_dup(mesg);
152 }
153
154 CORBA::Boolean Echo_i::echoBoolean(CORBA::Boolean b ) 
155 {
156   DEBTRACE("Echo_i::echoBoolean " << b);
157   return b;
158 }
159
160 void Echo_i::echoDouble(CORBA::Double i,CORBA::Double& j ) {
161   DEBTRACE("Echo_i::echoDouble " << i);
162   j=i+1;
163 }
164
165 void Echo_i::echoIntVec(const eo::IntVec& in, eo::IntVec_out out)
166 {
167   DEBTRACE("Echo_i::echoIntVec " << in.length());
168   for(int i=0;i<in.length(); i++){
169     DEBTRACE(in[i]);
170   };
171   out=new eo::IntVec(in);
172 }
173
174 void Echo_i::echoStrVec(const eo::StrVec& in, eo::StrVec_out out)
175 {
176   DEBTRACE("Echo_i::echoStrVec " << in.length());
177   for(int i=0;i<in.length(); i++){
178     DEBTRACE(in[i]);
179   }
180   out=new eo::StrVec(in);
181 }
182
183 void Echo_i::echoBoolVec(const eo::BoolVec& in, eo::BoolVec_out out)
184 {
185   DEBTRACE("Echo_i::echoBoolVec " << in.length());
186   for(int i=0;i<in.length(); i++){
187     DEBTRACE(in[i]);
188   };
189   out=new eo::BoolVec(in);
190 }
191
192 void Echo_i::echoObjectVec(const eo::ObjectVec& in, eo::ObjectVec_out out)
193 {
194   DEBTRACE("Echo_i::echoObjectVec " << in.length());
195   for(int i=0;i<in.length(); i++){
196     DEBTRACE(in[i]->_PD_repoId);
197   };
198   out=new eo::ObjectVec(in);
199 }
200
201 void Echo_i::echoObjectVecVec(const eo::ObjectVecVec& in, eo::ObjectVecVec_out out)
202 {
203   DEBTRACE("Echo_i::echoObjectVecVec " << in.length());
204   for(int i=0;i< in.length(); i++){
205     for(int j=0;j< in[i].length(); j++){
206       DEBTRACE(in[i][j]->_PD_repoId);
207     };
208   };
209   out=new eo::ObjectVecVec(in);
210 }
211
212 void Echo_i::echoDoubleVec(const eo::DoubleVec& in,eo::DoubleVec_out out ) 
213 {
214   DEBTRACE("Echo_i::echoDoubleVec " << in.length());
215   for(int i=0;i<in.length(); i++){
216     DEBTRACE(in[i]);
217   };
218   out=new eo::DoubleVec(in);
219 }
220
221 void Echo_i::echoDoubleVecVec(const eo::DoubleVecVec& in, eo::DoubleVecVec_out out)
222 {
223   DEBTRACE("Echo_i::echoDoubleVecVec " << in.length());
224   for(int i=0;i< in.length(); i++){
225     for(int j=0;j< in[i].length(); j++){
226       DEBTRACE(in[i][j]);
227     };
228   };
229   out=new eo::DoubleVecVec(in);
230 }
231
232 CORBA::Long Echo_i::echoLong(CORBA::Long i )
233 {
234   DEBTRACE("Echo_i::echoLong " << i);
235   if(i < 0) {
236     eo::ExceptionStruct es;
237     es.type = eo::COMM;
238     es.text = "error Socket exception";
239     throw eo::SALOME_Exception(es);
240   }
241
242   CORBA::Long j=i+1;
243   return j;
244 }
245
246 void Echo_i::echoC(eo::C_ptr o,eo::C_out oo){
247   DEBTRACE("Echo_i::echoC ");
248   o->echoLong(10);
249   oo=eo::C::_duplicate(o); 
250 }
251
252 void Echo_i::echoD(eo::D_ptr o,eo::D_out oo){
253   DEBTRACE("Echo_i::echoD ");
254   o->echoLong2(10);
255   //oo=eo::D::_duplicate(o); 
256   D_i* myD = new D_i();
257   oo=myD->_this();
258   myD->_remove_ref();
259 }
260
261 void Echo_i::echoObj2(eo::Obj_ptr o,eo::Obj_out oo){
262   DEBTRACE("Echo_i::echoObj2 ");
263   o->echoLong(10);
264   oo=eo::Obj::_duplicate(o); 
265 }
266
267 eo::Obj_ptr Echo_i::echoObj(CORBA::Long i ,eo::Obj_ptr o,CORBA::Long j,eo::Obj_out oo){
268   DEBTRACE("Echo_i::echoObj " << i << "," << j );
269   oo=eo::Obj::_duplicate(o); 
270   return eo::Obj::_duplicate(o); 
271 }
272
273 void Echo_i::createObj(CORBA::Long i ,eo::Obj_out oo){
274   DEBTRACE("Echo_i::createObj " << i);
275   Obj_i* myobj = new Obj_i();
276   CORBA::Object_var myref = myobj->_this();
277   oo = eo::Obj::_narrow(myref);
278   myobj->_remove_ref();
279 }
280
281 void Echo_i::createC(eo::C_out oo){
282   DEBTRACE("Echo_i::createC ");
283   C_i* myobj = new C_i();
284   CORBA::Object_var myref = myobj->_this();
285   oo = eo::C::_narrow(myref);
286   myobj->_remove_ref();
287 }
288
289 void Echo_i::echoAll(CORBA::Double d,CORBA::Long l,const char * m,eo::Obj_ptr o,CORBA::Double& dd,CORBA::Long& ll,CORBA::String_out s,eo::Obj_out oo)
290 {
291   DEBTRACE("Echo_i::echoAll " << d << "," << l << "," << m);
292   dd=d;
293   ll=l;
294   s=CORBA::string_dup(m);
295   oo=eo::Obj::_duplicate(o); 
296 };
297
298 void Echo_i::sleepLong(CORBA::Double time1, CORBA::Double& time2)
299 {
300   DEBTRACE("Echo_i::sleepLong");
301   pthread_mutex_lock(&_mutex);
302   int num = _ctr++;
303   pthread_mutex_unlock(&_mutex);
304   DEBTRACE("Echo_i::sleepLong start " << num);
305   unsigned int t=(unsigned int) time1;
306   sleep(t);
307   DEBTRACE("Echo_i::sleepLong stop  " << num);
308   time2 = time1;
309 }
310
311 eo::S2* Echo_i::echoStruct(const eo::S2& s)
312 {
313   DEBTRACE("Echo_i::echoStruct " << s.s.x << " " << s.s.y);
314   eo::S1 s1;
315   s1.x=10.;
316   s1.y=2;
317   eo::S2* s2=new eo::S2;
318   s2->s=s1;
319   return s2;
320 }
321
322 eo::S3* Echo_i::echoStruct2(const eo::S3& s)
323 {
324   DEBTRACE("Echo_i::echoStruct " << s.x << " " << s.y);
325   if( !CORBA::is_nil(s.ob) ) 
326     {
327       std::cerr << s.ob->echoLong(10) << std::endl;
328     }
329   eo::S3* s2=new eo::S3;
330   s2->x=10.;
331   s2->y=2;
332   return s2;
333 }
334
335 //Implementation Obj
336 CORBA::Long Obj_i::echoLong(CORBA::Long i ){
337   DEBTRACE("Obj_i::echoLong " << i );
338   CORBA::Long j=i+1;
339   return j;
340 }
341
342 //Implementation C
343 CORBA::Long C_i::echoLong(CORBA::Long i ){
344   DEBTRACE("C_i::echoLong " << i);
345   CORBA::Long j=i+5;
346   return j;
347 }
348
349 //Implementation D
350 CORBA::Long D_i::echoLong2(CORBA::Long i ){
351   DEBTRACE("D_i::echoLong " << i);
352   CORBA::Long j=i+10;
353   return j;
354 }
355 CORBA::Long D_i::echoLong(CORBA::Long i ){
356   DEBTRACE("D_i::echoLong " << i);
357   CORBA::Long j=i+1;
358   return j;
359 }
360
361 //Implementation E
362 CORBA::Long E_i::echoLong2(CORBA::Long i ){
363   DEBTRACE("E_i::echoLong " << i);
364   CORBA::Long j=i+20;
365   return j;
366 }
367 CORBA::Long E_i::echoLong(CORBA::Long i ){
368   DEBTRACE("E_i::echoLong " << i);
369   CORBA::Long j=i+15;
370   return j;
371 }
372
373 eo::Echo_var myechoref;
374
375 int main(int argc, char** argv)
376 {
377   try {
378     orb = CORBA::ORB_init(argc, argv);
379
380     {
381       CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");
382       PortableServer::POA_var root_poa = PortableServer::POA::_narrow(obj);
383       // POA manager
384       PortableServer::POAManager_var poa_man = root_poa->the_POAManager();
385       poa_man->activate();
386
387       // Create a new POA with the shortcut policy
388       /*
389       CORBA::PolicyList pl2;
390       pl2.length(2);
391       CORBA::Any v;
392       v <<= omniPolicy::LOCAL_CALLS_SHORTCUT;
393       pl2[0] = orb->create_policy(omniPolicy::LOCAL_SHORTCUT_POLICY_TYPE, v);
394       pl2[1] = root_poa->create_implicit_activation_policy(PortableServer::IMPLICIT_ACTIVATION);
395       PortableServer::POA_var shortcut_poa = root_poa->create_POA("shortcut", poa_man, pl2);
396       */
397
398       // Create and activate servant
399       Echo_i* myecho = new Echo_i();
400       // Obtain a reference to the object
401       CORBA::Object_var obj2 = myecho->_this();
402       myechoref = eo::Echo::_narrow(obj2);
403       // Decrement the reference count of the object implementation, so
404       // that it will be properly cleaned up when the POA has determined
405       // that it is no longer needed.
406       myecho->_remove_ref();
407
408       // print the reference as a stringified IOR.
409       CORBA::String_var sior(orb->object_to_string(obj2));
410       DEBTRACE("'" << (char*)sior << "'");
411
412       if( !bindObjectToName(orb, myechoref,"Echo") ) return 1;
413
414       //create object C and register it in naming service
415       C_i* myC = new C_i();
416       CORBA::Object_var obj3 =myC->_this();
417       eo::C_var myCref=eo::C::_narrow(obj3);
418       myC->_remove_ref();
419       if( !bindObjectToName(orb, myCref,"C") ) return 1;
420
421       //create object D and register it in naming service
422       D_i* myD = new D_i();
423       CORBA::Object_var obj4=myD->_this();
424       eo::D_var myDref=eo::D::_narrow(obj4);
425       myD->_remove_ref();
426       if( !bindObjectToName(orb, myDref,"D") ) return 1;
427
428       //create object Obj and register it in naming service
429       Obj_i* myObj = new Obj_i();
430       CORBA::Object_var obj5=myObj->_this();
431       eo::Obj_var myObjref=eo::Obj::_narrow(obj5);
432       myObj->_remove_ref();
433       if( !bindObjectToName(orb, myObjref,"Obj") ) return 1;
434     }
435     orb->run();
436     std::cout << "Returned from orb->run()." << std::endl;
437     orb->destroy();
438   }
439   catch(CORBA::SystemException&) {
440     DEBTRACE("Caught CORBA::SystemException.");
441   }
442   catch(CORBA::Exception& ex) {
443     DEBTRACE("Caught CORBA::Exception." << ex);
444   }
445   catch(omniORB::fatalException& fe) {
446     DEBTRACE("Caught omniORB::fatalException:");
447     DEBTRACE("  file: " << fe.file());
448     DEBTRACE("  line: " << fe.line());
449     DEBTRACE("  mesg: " << fe.errmsg());
450   }
451   catch(...) {
452     DEBTRACE("Caught unknown exception." );
453   }
454
455   return 0;
456 }
457
458
459 //////////////////////////////////////////////////////////////////////
460
461 static CORBA::Boolean
462 bindObjectToName(CORBA::ORB_ptr orb, CORBA::Object_ptr objref,const char *name)
463 {
464   CosNaming::NamingContext_var rootContext;
465
466   try {
467     // Obtain a reference to the root context of the Name service:
468     CORBA::Object_var obj;
469     obj = orb->resolve_initial_references("NameService");
470
471     // Narrow the reference returned.
472     rootContext = CosNaming::NamingContext::_narrow(obj);
473     if( CORBA::is_nil(rootContext) ) {
474       DEBTRACE("Failed to narrow the root naming context.");
475       return 0;
476     }
477   }
478   catch(CORBA::ORB::InvalidName& ex) {
479     // This should not happen!
480     DEBTRACE("Service required is invalid [does not exist]." );
481     return 0;
482   }
483
484   try {
485     // Bind a context called "test" to the root context:
486
487     CosNaming::Name contextName;
488     contextName.length(1);
489     contextName[0].id   = (const char*) "test";       // string copied
490     contextName[0].kind = (const char*) "my_context"; // string copied
491     // Note on kind: The kind field is used to indicate the type
492     // of the object. This is to avoid conventions such as that used
493     // by files (name.type -- e.g. test.ps = postscript etc.)
494
495     CosNaming::NamingContext_var testContext;
496     try {
497       // Bind the context to root.
498       testContext = rootContext->bind_new_context(contextName);
499     }
500     catch(CosNaming::NamingContext::AlreadyBound& ex) {
501       // If the context already exists, this exception will be raised.
502       // In this case, just resolve the name and assign testContext
503       // to the object returned:
504       CORBA::Object_var obj;
505       obj = rootContext->resolve(contextName);
506       testContext = CosNaming::NamingContext::_narrow(obj);
507       if( CORBA::is_nil(testContext) ) {
508         DEBTRACE("Failed to narrow naming context.");
509         return 0;
510       }
511     }
512
513     // Bind objref with name Echo to the testContext:
514     CosNaming::Name objectName;
515     objectName.length(1);
516     objectName[0].id   = name;   // string copied
517     objectName[0].kind = (const char*) "Object"; // string copied
518
519     try {
520       testContext->bind(objectName, objref);
521     }
522     catch(CosNaming::NamingContext::AlreadyBound& ex) {
523       testContext->rebind(objectName, objref);
524     }
525     // Note: Using rebind() will overwrite any Object previously bound
526     //       to /test/Echo with obj.
527     //       Alternatively, bind() can be used, which will raise a
528     //       CosNaming::NamingContext::AlreadyBound exception if the name
529     //       supplied is already bound to an object.
530
531     // Amendment: When using OrbixNames, it is necessary to first try bind
532     // and then rebind, as rebind on it's own will throw a NotFoundexception if
533     // the Name has not already been bound. [This is incorrect behaviour -
534     // it should just bind].
535   }
536   catch(CORBA::COMM_FAILURE& ex) {
537     DEBTRACE("Caught system exception COMM_FAILURE -- unable to contact the "
538              << "naming service.");
539     return 0;
540   }
541   catch(CORBA::SystemException&) {
542     DEBTRACE("Caught a CORBA::SystemException while using the naming service.");
543     return 0;
544   }
545
546   return 1;
547 }
548