Salome HOME
Initialisation de la base KERNEL avec la version operationnelle de KERNEL_SRC issue...
[modules/kernel.git] / src / Session / InquireServersQThread.cxx
1 using namespace std;
2 // File:        InquireServersQThread.cxx
3 // Created:     Mon Oct 21 17:26:42 2002
4 // Author:      Vasily RUSYAEV <vrv@nnov.matra-dtv.fr>
5 // Project      SALOME
6
7 #include "InquireServersQThread.h"
8
9 #include <qlabel.h>
10 #include <qpushbutton.h>
11 #include <qabstractlayout.h> 
12 #include <qlayout.h>
13 #include <qevent.h> 
14 #include <qfont.h> 
15 #include <qmessagebox.h> 
16 #include <qdir.h>
17 #include <qfileinfo.h>
18 #include <qstringlist.h>
19
20 //VRV: porting on Qt 3.0.5
21 #if QT_VERSION >= 0x030005
22 #include <qdesktopwidget.h> 
23 #endif
24 //VRV: porting on Qt 3.0.5
25
26 #include <qsize.h> 
27
28 #include <SALOMEconfig.h>
29
30 #include "Utils_ORB_INIT.hxx"
31 #include "Utils_SINGLETON.hxx"
32 #include "SALOME_NamingService.hxx"
33 #include "utilities.h"
34 #include "OpUtil.hxx"
35
36 #include CORBA_CLIENT_HEADER(SALOME_Session)
37 #include CORBA_CLIENT_HEADER(SALOME_Registry)
38 #include CORBA_CLIENT_HEADER(SALOMEDS)
39 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
40 #include CORBA_CLIENT_HEADER(SALOME_Component)
41
42 #define MARGIN_SIZE  5
43 #define SPACING_SIZE 3
44
45 static QString findFile( QString filename );
46 static QString addSlash( const QString& path );
47
48 InquireServersGUI::InquireServersGUI()
49      : QVBox(0, "SFA splash", Qt::WDestructiveClose | Qt::WStyle_Customize | Qt::WStyle_NoBorder )
50 {
51   myThread = new InquireServersQThread(this);
52
53   // 1. Polish the appearance
54   setMargin( MARGIN_SIZE );
55   setSpacing( SPACING_SIZE );
56   setFrameStyle( QFrame::Plain | QFrame::Box );
57   setLineWidth( 2 );
58   setMinimumSize( 200, 150 );
59
60   // 2. Splash image
61   QFrame* frm = new QFrame( this );
62   frm->setFrameStyle( QFrame::Box | QFrame::Raised );
63   QHBoxLayout* frmLayout = new QHBoxLayout( frm );
64   frmLayout->setMargin( MARGIN_SIZE );
65   QLabel* splash = 0;
66   splash = new QLabel( frm, "splash" );
67   frmLayout->addWidget( splash );
68   // setting pixmap
69   QString path = findFile( "Application-Splash.png" );
70   splash->setPixmap( QPixmap( path )  );
71   
72   // 3. Progress bar
73   myPrgBar = new QProgressBar( this, "QProgressBar" );
74   myPrgBar->setFixedWidth( splash->pixmap()->isNull() ? 180 : splash->sizeHint().width() );
75   //Sets the total number of steps . 
76   myPrgBar->setTotalSteps ( myThread->getInquiredServers() );
77   myPrgBar->setProgress( 0 );
78
79   // 4. Info label
80   QWidget* aWgt1 = new QWidget( this );
81   QHBoxLayout* aHBoxLayout1 = new QHBoxLayout( aWgt1 );
82   myLabel = new QLabel( tr( "Loading:" ), aWgt1 );
83   myLabel->setFixedWidth( splash->pixmap()->isNull() ? 180 : splash->sizeHint().width() );
84   myLabel->setAlignment( AlignLeft );
85   QFont theFont = myLabel->font();
86   theFont.setBold(true);
87   myLabel->setFont( theFont );
88   aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
89   aHBoxLayout1->addWidget( myLabel );
90   aHBoxLayout1->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum ) );
91
92   // 5. <Cancel> button
93   QWidget* aWgt = new QWidget( this );
94   QHBoxLayout* aHBoxLayout = new QHBoxLayout( aWgt );
95   QPushButton* myCancelBtn = new QPushButton( tr( "Cancel" ), aWgt );
96   connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( ClickOnCancel() ) ) ;
97   aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum )  );
98   aHBoxLayout->addWidget( myCancelBtn );
99   aHBoxLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum )  );
100
101   //Center widget
102 #if QT_VERSION >= 0x030005
103   QDesktopWidget *d = QApplication::desktop();
104 #else
105   QWidget *d = QApplication::desktop();
106 #endif
107 //VRV: porting on Qt 3.0.5
108
109   int w = d->width();         // returns desktop width
110   int h = d->height();        // returns desktop height
111   QSize mySize = sizeHint (); // returns widget size
112   int Xc = ( w - mySize.width() )  / 2;
113   int Yc = ( h - mySize.height() ) / 2;
114   move( Xc, Yc );
115
116   myThread->start();
117 }
118
119 InquireServersGUI::~InquireServersGUI()
120 {
121   delete myThread;
122 }
123
124 void InquireServersGUI::getArgs( int& _argc, char *** _argv)
125 {
126   _argc = qApp->argc();
127   *_argv = qApp->argv();
128 }
129
130 //=================================================================================
131 // function : ClickOnCancel()
132 // purpose  : cancel loading of SALOME
133 //=================================================================================
134 void InquireServersGUI::ClickOnCancel()
135 {
136   //it's necessary to stop asking servers
137   myThread->stop();
138   //Also we should send QCloseEvent in order to close this widget (and remove from screen) 
139   //QThread::postEvent ( this, new QCloseEvent() );
140   qApp->exit(1);
141 }
142
143 void InquireServersGUI::closeEvent ( QCloseEvent * pe)
144 {
145   //default implementation calls e->accept(), which hides this widget. 
146   //See the QCloseEvent documentation for more details.
147   pe->accept();
148   QApplication::flushX ();
149   QApplication::syncX ();
150   qApp->exit();
151 }
152
153 void InquireServersGUI::customEvent( QCustomEvent* pe )
154 {
155   switch( pe->type() )
156     {
157         case InquireEvent::ProgressEvent:
158         {
159             int* value = ( int* )(( InquireEvent*)pe)->data();
160             myPrgBar->setProgress( *value );
161             break;
162         }
163         case InquireEvent::ProgressEventLabel:
164         {
165             QString* myString = ( QString* )(( InquireEvent*)pe)->data();
166             myLabel->setText( *myString );
167             break;
168         }
169         case InquireEvent::ProgressEventError:
170         {
171             QString* myErrDesc = ( QString* )(( InquireEvent*)pe)->data();
172             QString  appName = "SALOME Professional";
173             QString  error = "An internal error occurred.\n"+ *myErrDesc + "\n";
174             QMessageBox myMsgBox(appName,error,QMessageBox::Critical,QMessageBox::Ok,QMessageBox::NoButton,
175                                         QMessageBox::NoButton,0,"MY",TRUE,WStyle_DialogBorder|WStyle_StaysOnTop);
176             myMsgBox.exec();
177             ClickOnCancel();
178             break;
179         }
180       default:
181         {
182           ;
183         }
184     }
185 }
186
187 int InquireServersGUI::getExitStatus()
188 {
189   myThread->getExitStatus();
190 }
191
192 InquireServersQThread::InquireServersQThread( InquireServersGUI* r )
193      : receiver(r),  myExitStatus(0)
194 {
195   char* cenv;
196
197   IsChecking = true;
198   myServersCount = 8;
199   //how many times we should repeat attempts to get response from all needed for launching SALOME servers
200   myRepeat = 30; // default value, user can change it by setting CSF_RepeatServerRequest env.variable
201   cenv = getenv( "CSF_RepeatServerRequest" );
202   if ( cenv ) {
203     int val = atoi( cenv );
204     if ( val > 0 )
205       myRepeat = val;
206   }
207   //define delay time between two attempts
208   myDelay = 1000000; // 1 second
209   QString str = "Loading: ";
210   myMessages[0] = "Checking naming service...";
211   myMessages[1] = str + "SALOME_Registry_Server" + "...";
212   myMessages[2] = str + "SALOMEDS_Server" + "...";
213   myMessages[3] = str + "SALOME_ModuleCatalog_Server" + "...";
214   myMessages[4] = str + "SALOME_Session_Server" + "...";
215   myMessages[5] = str + "SALOME_Container FactoryServer" + "...";
216   myMessages[6] = str + "SALOME_ContainerPy.py FactoryServerPy" + "...";
217   myMessages[7] = str + "SALOME_Container SuperVisionContainer" + "...";
218
219   r->getArgs( _argc, &_argv);
220
221 }
222
223 void InquireServersQThread::run()
224 {
225 while (IsChecking)
226   {
227     for (int i=1; i<=myServersCount; i++)
228       {
229         QString *message = new QString(myMessages[i-1]);
230         QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventLabel, message ) );
231         QThread::usleep(200000);
232         QString *errMsg;
233         bool result = AskServer(i,&errMsg);
234         if (result)
235           {
236             QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEvent, new int( i ) ) );
237             if (i==myServersCount)
238               {
239                 IsChecking = false;
240                 //myExitStatus should be 0 because all servers exist and work
241                 myExitStatus = 0;
242                 //we should send QCloseEvent in order to close this widget (and remove from screen) 
243                 QThread::postEvent ( receiver , new QCloseEvent() );
244               }
245           }
246         else
247           {
248             QThread::postEvent( receiver, new InquireEvent( ( QEvent::Type )InquireEvent::ProgressEventError, errMsg ) );
249             //myExitStatus should be 1 because we didn't receive response from server
250             myExitStatus = 1;
251             return;
252           }
253       }
254   }
255 }
256
257 bool InquireServersQThread::AskServer(int iteration, QString ** errMessage)
258 {
259   ASSERT(iteration<=myServersCount);
260   //will be set true if we get response from server
261   bool IsPassed = false;
262   QString errDescription;
263   switch (iteration)
264     {
265     case 1:
266       //First checking - existence of Naming Service
267       for (int i = myRepeat; i ; i--)
268         {
269           try
270             {
271               CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
272               CORBA::Object_var obj = orb->resolve_initial_references("NameService");
273               CosNaming::NamingContext_var _root_context = CosNaming::NamingContext::_narrow(obj);
274               if (CORBA::is_nil(_root_context))
275                 continue;
276               else
277                 IsPassed = true;
278               break;
279             }
280           catch(CORBA::COMM_FAILURE&)
281             {
282               MESSAGE("CORBA::COMM_FAILURE: unable to contact the naming service");
283             }
284           catch(...)
285             {
286               MESSAGE("Unknown Exception: unable to contact the naming service");
287             }
288           QThread::usleep(myDelay);
289         }
290       if (!IsPassed)
291         *errMessage = new QString("unable to contact the naming service");
292       break;
293     case 2:
294       //checking - existence of SALOME_Registry_Server
295     case 3:
296       //checking - existence of SALOMEDS_Server
297     case 4:
298       //checking - existence of SALOME_ModuleCatalog_Server
299     case 5:
300       //checking - existence of SALOME_Session_Server
301     case 6:
302       //checking - existence of SALOME_Container FactoryServer
303     case 7:
304       //checking - existence of SALOME_ContainerPy.py FactoryServerPy
305     case 8:
306       //checking - existence of SALOME_Container SuperVisionContainer
307       IsPassed = pingServer(iteration, errDescription);
308       if (!IsPassed)
309         *errMessage = new QString(errDescription);
310       break;
311     }
312 return IsPassed;
313 }
314
315 bool InquireServersQThread::pingServer(int iteration, QString& errMessage)
316 {
317   ASSERT(iteration<=myServersCount);
318   bool result = false;
319   QString errorDescr;
320   for (int i = myRepeat; i ; i--)
321     {
322       try
323         {
324           CORBA::ORB_var orb = CORBA::ORB_init(_argc,_argv) ;
325           SALOME_NamingService &NS = *SINGLETON_<SALOME_NamingService>::Instance() ;
326           ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
327           NS.init_orb( orb ) ;
328           switch (iteration)
329             {
330             case 2:
331               {
332                 CORBA::Object_var obj = NS.Resolve("/Registry");
333                 Registry::Components_var registry = Registry::Components::_narrow(obj) ;
334                 if (!CORBA::is_nil(registry))
335                   {
336                     MESSAGE("/Registry is found");
337                     registry->ping();
338                     result = true;
339                     MESSAGE("Registry was activated");
340                     return result;
341                   }
342               }
343               break;
344             case 3:
345               {
346                 CORBA::Object_var obj = NS.Resolve("/myStudyManager");
347                 SALOMEDS::StudyManager_var studyManager = SALOMEDS::StudyManager::_narrow(obj) ;
348                 if (!CORBA::is_nil(studyManager))
349                   {
350                     MESSAGE("/myStudyManager is found");
351                     studyManager->ping();
352                     result = true;
353                     MESSAGE("StudyManager was activated");
354                     return result;
355                   }
356               }
357               break;
358             case 4:
359               {
360                 CORBA::Object_var obj = NS.Resolve("Kernel/ModulCatalog");
361                 SALOME_ModuleCatalog::ModuleCatalog_var catalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj) ;
362                 if (!CORBA::is_nil(catalog))
363                   {
364                     MESSAGE("/Kernel/ModulCatalog is found");
365                     catalog->ping();
366                     result = true;
367                     MESSAGE("ModuleCatalog was activated");
368                     return result;
369                   }
370               }
371               break;
372             case 5:
373               {
374                 CORBA::Object_var obj = NS.Resolve("Kernel/Session");
375                 SALOME::Session_var session = SALOME::Session::_narrow(obj) ;
376                 if (!CORBA::is_nil(session))
377                   {
378                     MESSAGE("/Kernel/Session is found");
379                     session->ping();
380                     result = true;
381                     MESSAGE("SALOME_Session was activated");
382                     return result;
383                   }
384               }
385               break;
386             case 6:
387               {
388                 string hostname = GetHostname();
389                 string containerName = "/Containers/";
390                 containerName += hostname;
391                 containerName += "/FactoryServer";
392
393                 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
394                 Engines::Container_var FScontainer = Engines::Container::_narrow(obj) ;
395                 if (!CORBA::is_nil(FScontainer))
396                   {
397                     FScontainer->ping();
398                     result = true;
399                     MESSAGE("FactoryServer container was activated");
400                     return result;
401                   }
402               }
403               break;
404             case 7:
405               {
406                 string hostname = GetHostname();
407                 string containerName = "/Containers/";
408                 containerName += hostname;
409                 containerName += "/FactoryServerPy";
410                 
411                 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
412                 Engines::Container_var FSPcontainer = Engines::Container::_narrow(obj) ;
413                 if (!CORBA::is_nil(FSPcontainer))
414                   {
415                     FSPcontainer->ping();
416                     result = true;
417                     MESSAGE("FactoryServerPy container was activated");
418                     return result;
419                   }
420               }
421               break;
422             case 8:
423               {
424                 string hostname = GetHostname();
425                 string containerName = "/Containers/";
426                 containerName += hostname;
427                 containerName += "/SuperVisionContainer";
428                 
429                 CORBA::Object_var obj = NS.Resolve(containerName.c_str());
430                 Engines::Container_var SVcontainer = Engines::Container::_narrow(obj) ;
431                 if (!CORBA::is_nil(SVcontainer))
432                   {
433                     SVcontainer->ping();
434                     result = true;
435                     MESSAGE("SuperVisionContainer container was activated");
436                     return result;
437                   }
438               }
439               break;
440             }
441          }
442       catch (ServiceUnreachable&)
443         {
444           MESSAGE("Caught exception: Naming Service Unreachable");
445           errorDescr = "Caught exception: Naming Service Unreachable";
446         }
447       catch (CORBA::COMM_FAILURE&)
448         {
449           MESSAGE("Caught CORBA::SystemException CommFailure.");
450           errorDescr = "Caught CORBA::SystemException CommFailure";
451         }
452       catch (CORBA::SystemException&)
453         {
454           MESSAGE("Caught CORBA::SystemException.");
455           errorDescr = "Caught CORBA::SystemException";
456         }
457       catch (CORBA::Exception&)
458         {
459           MESSAGE("Caught CORBA::Exception.");
460           errorDescr = "Caught CORBA::Exception";
461         }
462       catch (...)
463         {
464           MESSAGE("Caught unknown exception.");
465           errorDescr = "Caught unknown exception";
466         }
467       QThread::usleep(myDelay);
468     }
469   if (!result)
470     {
471       QString serverName;
472       switch (iteration)
473         {
474         case 2:
475           serverName = "SALOME_Registry_Server is not loaded. ";
476           break;
477         case 3:
478           serverName = "SALOMEDS_Server is not loaded. ";
479           break;
480         case 4:
481           serverName = "SALOME_ModuleCatalog_Server is not loaded. ";
482           break;
483         case 5:
484           serverName = "SALOME_Session_Server is not loaded. ";
485           break;
486         case 6:
487           serverName = "SALOME_Container FactoryServer is not loaded. ";
488           break;
489         case 7:
490           serverName = "SALOME_ContainerPy.py FactoryServerPy is not loaded. ";
491           break;
492         case 8:
493           serverName = "SALOME_Container SuperVisionContainer is not loaded. ";
494           break;
495         }
496       errMessage = serverName + errorDescr;
497     }
498   return result;
499 }
500
501 static const char* SEPARATOR    = ":";
502
503 QString findFile( QString filename )
504 {
505   QString dir;
506   char* cenv;
507   
508   // Try CSF_ResourcesDefaults env.var directory ( or directory list )
509   cenv = getenv( "CSF_ResourcesDefaults" );
510   if ( cenv ) {
511     dir.sprintf( "%s", cenv );
512     if ( !dir.isEmpty() ) {
513       QStringList dirList = QStringList::split( SEPARATOR, dir, false ); // skip empty entries
514       for ( int i = 0; i < dirList.count(); i++ ) {
515         QFileInfo fileInfo( addSlash( dirList[ i ] ) + filename );
516         if ( fileInfo.isFile() && fileInfo.exists() )
517           return fileInfo.filePath();
518       }
519     }
520   }
521   // Try ${HOME}/.salome/resources directory
522   cenv = getenv( "HOME" );
523   if ( cenv ) {
524     dir.sprintf( "%s", cenv );
525     if ( !dir.isEmpty() ) {
526       dir = addSlash(dir) ;
527       dir = dir + ".salome" ;
528       dir = addSlash(dir) ;
529       dir = dir + "resources" ;
530       dir = addSlash(dir) ;
531       QFileInfo fileInfo( dir + filename );
532       if ( fileInfo.isFile() && fileInfo.exists() )
533         return fileInfo.filePath();
534     }
535   }
536   // Try ${SALOME_SITE_DIR}/share/salome/resources directory
537   cenv = getenv( "SALOME_SITE_DIR" );
538   if ( cenv ) {
539     dir.sprintf( "%s", cenv );
540     if ( !dir.isEmpty() ) {
541       dir = addSlash(dir) ;
542       dir = dir + "share" ;
543       dir = addSlash(dir) ;
544       dir = dir + "salome" ;
545       dir = addSlash(dir) ;
546       dir = dir + "resources" ;
547       dir = addSlash(dir) ;
548       QFileInfo fileInfo( dir + filename );
549       if ( fileInfo.isFile() && fileInfo.exists() )
550         return fileInfo.filePath();
551     }
552   }
553   // Try ${SALOME_ROOT_DIR}/share/salome/resources directory
554   cenv = getenv( "SALOME_ROOT_DIR" );
555   if ( cenv ) {
556     dir.sprintf( "%s", cenv );
557     if ( !dir.isEmpty() ) {
558       dir = addSlash(dir) ;
559       dir = dir + "share" ;
560       dir = addSlash(dir) ;
561       dir = dir + "salome" ;
562       dir = addSlash(dir) ;
563       dir = dir + "resources" ;
564       dir = addSlash(dir) ;
565       QFileInfo fileInfo( dir + filename );
566       if ( fileInfo.isFile() && fileInfo.exists() )
567         return fileInfo.filePath();
568     }
569   }
570   return filename;
571 }
572 QString addSlash( const QString& path )
573 {
574   if (!path.isNull()) {
575 #ifdef WNT
576     QChar slash ('\\');
577 #else
578     QChar slash ('/');
579 #endif
580     if ( path.at(path.length()-1) != slash )
581       return path + slash;
582   }
583   return path;
584 }