Salome HOME
Synchronize adm files
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_StudyManager_i.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SALOMEDS_StudyManager_i.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26 //
27 #include "utilities.h"
28 #include "SALOME_LifeCycleCORBA.hxx"
29 #include "SALOMEDS_StudyManager_i.hxx"
30 #include "SALOMEDS_Study_i.hxx"
31 #include "SALOMEDS_SComponent_i.hxx"
32 #include "SALOMEDS_Driver_i.hxx"
33 #include "SALOMEDS_SimanStudy_i.hxx"
34 #include "SALOMEDS.hxx"
35
36 #include "SALOMEDSImpl_Study.hxx"
37 #include "SALOMEDSImpl_SObject.hxx"
38 #include "SALOMEDSImpl_SComponent.hxx"
39 #include "SALOMEDSImpl_AttributeIOR.hxx"
40
41 #include "Utils_CorbaException.hxx"
42 #include "Utils_ExceptHandlers.hxx"
43 #include "Basics_Utils.hxx"
44 #include "SALOME_GenericObj_i.hh"
45
46 #include <sstream>
47 #include <vector>
48 #include <map>
49
50 #ifdef WIN32
51 #include <process.h>
52 #else
53 #include <sys/types.h>
54 #include <unistd.h>
55 #endif
56
57 UNEXPECT_CATCH(SalomeException,SALOME::SALOME_Exception);
58 UNEXPECT_CATCH(LockProtection, SALOMEDS::StudyBuilder::LockProtection);
59
60 static SALOMEDS_Driver_i* GetDriver(const SALOMEDSImpl_SObject& theObject, CORBA::ORB_ptr orb);
61
62 static std::map<int, PortableServer::POA_ptr> _mapOfPOA;
63
64 //============================================================================
65 /*! Function : SALOMEDS_StudyManager_i
66  *  Purpose  : SALOMEDS_StudyManager_i constructor
67  */
68 //============================================================================
69 SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr thePOA)
70 {
71   _orb = CORBA::ORB::_duplicate(orb);
72   _poa = PortableServer::POA::_duplicate(thePOA);
73   _name_service = new SALOME_NamingService(_orb);
74   // Study directory creation in the naming service : to register all
75   // open studies in the session
76   _name_service->Create_Directory("/Study");
77   _impl = new SALOMEDSImpl_StudyManager;
78   _factory = new SALOMEDS_DriverFactory_i(_orb);
79 }
80
81 //============================================================================
82 /*! Function : ~SALOMEDS_StudyManager_i
83  *  Purpose  : SALOMEDS_StudyManager_i destructor
84  */
85 //============================================================================
86 SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
87 {
88   // Destroy directory to register open studies
89   _name_service->Destroy_Directory("/Study");
90   delete _name_service;
91   delete _factory;
92   delete _impl;
93   delete SALOMEDS_SimanStudy_i::GetSimanServant(_orb);
94 }
95
96 //============================================================================
97 /*! Function : register_name
98  *  Purpose  : Register the study Manager in the naming service under the
99  *             context name
100  */
101 //============================================================================
102 void SALOMEDS_StudyManager_i::register_name(const char * name)
103 {
104   SALOMEDS::StudyManager_var aManager(_this());
105   _name_service->Register(aManager.in(), name);
106 }
107
108
109 //============================================================================
110 /*! Function : NewStudy
111  *  Purpose  : Create a New Study of name study_name
112  */
113 //============================================================================
114 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name)
115      throw(SALOME::SALOME_Exception)
116 {
117   SALOMEDS::Locker lock;
118
119 #ifndef ALLOW_MULTI_STUDIES
120   std::vector<SALOMEDSImpl_Study*> anOpened = _impl->GetOpenStudies();
121   int aLength = anOpened.size();
122
123   if(aLength)
124     {
125       MESSAGE("There is already an active study in this session. Launch a new session, or close the study");
126       THROW_SALOME_CORBA_EXCEPTION("Problem on New Study.\nThere is already an active study in this session.\nLaunch a new session, or close the study", SALOME::BAD_PARAM)
127     }
128 #endif // !ALLOW_MULTI_STUDIES
129
130   SALOMEDSImpl_Study* aStudyImpl = _impl->NewStudy(study_name);
131   if(!aStudyImpl) {
132     MESSAGE("NewStudy : Error : " << _impl->GetErrorCode());
133     return SALOMEDS::Study::_nil();
134   }
135
136   MESSAGE("NewStudy : Creating the CORBA servant holding it... ");
137
138   SALOMEDS_Study_i *Study_servant = SALOMEDS_Study_i::GetStudyServant(aStudyImpl, _orb);
139   PortableServer::ObjectId_var servantid = _poa->activate_object(Study_servant); // to use poa registered in _mapOfPOA
140   SALOMEDS::Study_var Study = Study_servant->_this();
141
142   // Register study in the naming service
143   // Path to acces the study
144   if(!_name_service->Change_Directory("/Study"))
145       MESSAGE( "Unable to access the study directory" )
146   else
147       _name_service->Register(Study, study_name);
148
149   // Assign the value of the IOR in the study->root
150   CORBA::String_var IORStudy = _orb->object_to_string(Study);
151
152   aStudyImpl->SetTransientReference((char*)IORStudy.in());
153
154   _mapOfPOA[Study->StudyId()] = _poa;
155
156   return Study._retn();
157 }
158
159 //============================================================================
160 /*! Function : Open
161  *  Purpose  : Open a Study from it's persistent reference
162  */
163 //============================================================================
164 SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
165      throw(SALOME::SALOME_Exception)
166 {
167   SALOMEDS::Locker lock;
168
169   Unexpect aCatch(SalomeException);
170   MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
171
172   #ifndef ALLOW_MULTI_STUDIES
173   std::vector<SALOMEDSImpl_Study*> anOpened = _impl->GetOpenStudies();
174   int aLength = anOpened.size();
175
176   if(aLength)
177     {
178       MESSAGE("There is already an active study in this session. Launch a new session, or close the study.");
179       THROW_SALOME_CORBA_EXCEPTION("Problem on Open Study.\nThere is already an active study in this session.\nLaunch a new session, or close the study.", SALOME::BAD_PARAM)
180     }
181 #endif // ;ALLOW_MULTI_STUDIES
182
183   SALOMEDSImpl_Study* aStudyImpl = _impl->Open(std::string(aUrl));
184
185   if ( !aStudyImpl )
186     THROW_SALOME_CORBA_EXCEPTION("Impossible to Open study from file", SALOME::BAD_PARAM)
187
188   MESSAGE("Open : Creating the CORBA servant holding it... ");
189
190   // Temporary aStudyUrl in place of study name
191   SALOMEDS_Study_i * Study_servant = SALOMEDS_Study_i::GetStudyServant(aStudyImpl, _orb);
192   PortableServer::ObjectId_var servantid = _poa->activate_object(Study_servant); // to use poa register in _mapOfPOA
193   SALOMEDS::Study_var Study = Study_servant->_this();
194
195   // Assign the value of the IOR in the study->root
196   CORBA::String_var IORStudy = _orb->object_to_string(Study);
197   aStudyImpl->SetTransientReference((char*)IORStudy.in());
198
199   _mapOfPOA[Study->StudyId()] = _poa;
200
201   // Register study in the naming service
202   // Path to acces the study
203   if(!_name_service->Change_Directory("/Study")) MESSAGE( "Unable to access the study directory" )
204   else _name_service->Register(Study, aStudyImpl->Name().c_str());
205
206   return Study._retn();
207 }
208
209
210
211 //============================================================================
212 /*! Function : Close
213  *  Purpose  : Close a study.
214  *             If the study hasn't been saved, ask the user to confirm the
215  *             close action without saving
216  */
217 //============================================================================
218 void SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
219 {
220   SALOMEDS::Locker lock;
221
222   if(aStudy->_is_nil()) return;
223
224   // Destroy study name in the naming service
225   if(_name_service->Change_Directory("/Study")){
226     CORBA::String_var aString(aStudy->Name());
227     _name_service->Destroy_Name(aString.in());
228   }
229
230   SALOMEDS::unlock();
231   aStudy->Close();
232   SALOMEDS::lock();
233
234   //remove study servant
235   PortableServer::POA_ptr poa=GetPOA(aStudy);
236   PortableServer::ServantBase* aservant=poa->reference_to_servant(aStudy);
237   PortableServer::ObjectId_var anObjectId = poa->servant_to_id(aservant);
238   poa->deactivate_object(anObjectId.in());
239   aservant->_remove_ref(); // decrement for the call to reference_to_servant
240   aservant->_remove_ref(); // to delete the object
241 }
242
243 //============================================================================
244 /*! Function : Save
245  *  Purpose  : Save a Study to it's persistent reference
246  */
247 //============================================================================
248 CORBA::Boolean SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
249 {
250   SALOMEDS::Locker lock;
251
252   if(aStudy->_is_nil()) {
253     MESSAGE("Save error: Study is null");
254     return false;
255   }
256
257   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
258   return _impl->Save(aStudyImpl, _factory, theMultiFile);
259 }
260
261 CORBA::Boolean SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
262 {
263   SALOMEDS::Locker lock;
264
265   if(aStudy->_is_nil()) {
266     MESSAGE("SaveASCII error: Study is null");
267     return false;
268   }
269
270   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
271   return _impl->SaveASCII(aStudyImpl, _factory, theMultiFile);
272 }
273
274 //=============================================================================
275 /*! Function : SaveAs
276  *  Purpose  : Save a study to the persistent reference aUrl
277  */
278 //============================================================================
279 CORBA::Boolean SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
280 {
281   SALOMEDS::Locker lock;
282
283   if(aStudy->_is_nil()) {
284     MESSAGE("SaveASCII error: Study is null");
285     return false;
286   }
287
288   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
289   return _impl->SaveAs(std::string(aUrl), aStudyImpl, _factory, theMultiFile);
290 }
291
292 CORBA::Boolean SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
293 {
294   SALOMEDS::Locker lock;
295
296   if(aStudy->_is_nil()) {
297     MESSAGE("SaveASCII error: Study is null");
298     return false;
299   }
300
301   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
302   return _impl->SaveAsASCII(std::string(aUrl), aStudyImpl, _factory, theMultiFile);
303 }
304
305 //============================================================================
306 /*! Function : GetOpenStudies
307  *  Purpose  : Get name list of open studies in the session
308  */
309 //============================================================================
310 SALOMEDS::ListOfOpenStudies*  SALOMEDS_StudyManager_i::GetOpenStudies()
311 {
312   SALOMEDS::Locker lock;
313
314   std::vector<SALOMEDSImpl_Study*> anOpened = _impl->GetOpenStudies();
315   int aLength = anOpened.size();
316
317   SALOMEDS::ListOfOpenStudies_var _list_open_studies = new SALOMEDS::ListOfOpenStudies;
318   _list_open_studies->length(aLength);
319
320   if(!aLength)
321     {
322       MESSAGE("No active study in this session");
323     }
324   else
325     {
326       for (unsigned int ind=0; ind < aLength; ind++)
327         {
328           _list_open_studies[ind] = CORBA::string_dup(anOpened[ind]->Name().c_str());
329           SCRUTE(_list_open_studies[ind]) ;
330         }
331     }
332   return _list_open_studies._retn();
333 }
334
335 //============================================================================
336 /*! Function : GetStudyByName
337  *  Purpose  : Get a study from its name
338  */
339 //============================================================================
340 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName)
341 {
342   SALOMEDS::Locker lock;
343
344   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByName(std::string(aStudyName));
345
346   if (!aStudyImpl)
347   {
348     MESSAGE(_impl->GetErrorCode().c_str());
349     return SALOMEDS::Study::_nil();
350   }
351
352   SALOMEDS_Study_i* aStudy_servant = SALOMEDS_Study_i::GetStudyServant(aStudyImpl, _orb);
353   return aStudy_servant->_this();
354 }
355
356 //============================================================================
357 /*! Function : GetStudyByID
358  *  Purpose  : Get a study from its ID
359  */
360 //============================================================================
361 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID)
362 {
363   SALOMEDS::Locker lock;
364
365   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudyID);
366
367   if (!aStudyImpl)
368   {
369     MESSAGE(_impl->GetErrorCode().c_str());
370     return SALOMEDS::Study::_nil();
371   }
372
373   SALOMEDS_Study_i* aStudy_servant = SALOMEDS_Study_i::GetStudyServant(aStudyImpl, _orb);
374   return aStudy_servant->_this();
375 }
376
377
378 //============================================================================
379 /*! Function : CanCopy
380  *  Purpose  :
381  */
382 //============================================================================
383 CORBA::Boolean SALOMEDS_StudyManager_i::CanCopy(SALOMEDS::SObject_ptr theObject)
384 {
385   SALOMEDS::Locker lock;
386
387   SALOMEDS::Study_var aStudy = theObject->GetStudy();
388   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
389   CORBA::String_var anID = theObject->GetID();
390   SALOMEDSImpl_SObject anObject = aStudyImpl->GetSObject(anID.in());
391
392   SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
393   bool ret = _impl->CanCopy(anObject, aDriver);
394   delete aDriver;
395   return ret;
396 }
397
398 //============================================================================
399 /*! Function : Copy
400  *  Purpose  :
401  */
402 //============================================================================
403 CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject)
404 {
405   SALOMEDS::Locker lock;
406
407   SALOMEDS::Study_var aStudy = theObject->GetStudy();
408   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
409   CORBA::String_var anID = theObject->GetID();
410   SALOMEDSImpl_SObject anObject = aStudyImpl->GetSObject(anID.in());
411
412   SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
413   bool ret = _impl->Copy(anObject, aDriver);
414   delete aDriver;
415   return ret;
416 }
417
418 //============================================================================
419 /*! Function : CanPaste
420  *  Purpose  :
421  */
422 //============================================================================
423 CORBA::Boolean SALOMEDS_StudyManager_i::CanPaste(SALOMEDS::SObject_ptr theObject)
424 {
425   SALOMEDS::Locker lock;
426
427   SALOMEDS::Study_var aStudy = theObject->GetStudy();
428   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
429   CORBA::String_var anID = theObject->GetID();
430   SALOMEDSImpl_SObject anObject = aStudyImpl->GetSObject(anID.in());
431
432   SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
433   bool ret = _impl->CanPaste(anObject, aDriver);
434   delete aDriver;
435   return ret;
436 }
437
438 //============================================================================
439 /*! Function : Paste
440  *  Purpose  :
441  */
442 //============================================================================
443 SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theObject)
444      throw(SALOMEDS::StudyBuilder::LockProtection)
445 {
446   SALOMEDS::Locker lock;
447
448   Unexpect aCatch(LockProtection);
449   SALOMEDS::Study_var aStudy = theObject->GetStudy();
450
451   SALOMEDSImpl_Study* aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
452   CORBA::String_var anID = theObject->GetID();
453   SALOMEDSImpl_SObject anObject = aStudyImpl->GetSObject(anID.in());
454   SALOMEDSImpl_SObject aNewSO;
455
456   try {
457     SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
458     aNewSO =  _impl->Paste(anObject, aDriver);
459     delete aDriver;
460   }
461   catch (...) {
462     throw SALOMEDS::StudyBuilder::LockProtection();
463   }
464
465   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aNewSO, _orb);
466   return so._retn();
467 }
468
469
470 SALOMEDS_Driver_i* GetDriver(const SALOMEDSImpl_SObject& theObject, CORBA::ORB_ptr orb)
471 {
472   SALOMEDS_Driver_i* driver = NULL;
473
474   SALOMEDSImpl_SComponent aSCO = theObject.GetFatherComponent();
475   if(!aSCO.IsNull()) {
476     std::string IOREngine = aSCO.GetIOR();
477     if(!IOREngine.empty()) {
478       CORBA::Object_var obj = orb->string_to_object(IOREngine.c_str());
479       Engines::EngineComponent_var Engine = Engines::EngineComponent::_narrow(obj) ;
480       driver = new SALOMEDS_Driver_i(Engine, orb);
481     }
482   }
483
484   return driver;
485 }
486
487 PortableServer::POA_ptr SALOMEDS_StudyManager_i::GetPOA(const SALOMEDS::Study_ptr theStudy) {
488   if (_mapOfPOA.find(theStudy->StudyId()) != _mapOfPOA.end()) return _mapOfPOA[theStudy->StudyId()];
489   return PortableServer::POA::_nil();
490 }
491
492 CORBA::Long SALOMEDS_StudyManager_i::getPID()
493
494 #ifdef WIN32
495   return (CORBA::Long)_getpid();
496 #else
497   return (CORBA::Long)getpid();
498 #endif
499 }
500
501 void SALOMEDS_StudyManager_i::ShutdownWithExit()
502 {
503   exit( EXIT_SUCCESS );
504 }
505
506 //============================================================================
507 /*! Function : GetSimanStudy
508  *  Purpose  : Retruns the created or cashed SimanStudy
509  */
510 //============================================================================
511 SALOMEDS::SimanStudy_ptr SALOMEDS_StudyManager_i::GetSimanStudy()
512 {
513   SALOMEDS::Locker lock;
514
515   SALOMEDS_SimanStudy_i* aSiman_servant = SALOMEDS_SimanStudy_i::GetSimanServant(_orb);
516   return aSiman_servant->_this();
517 }
518
519 //===========================================================================
520 //   PRIVATE FUNCTIONS
521 //===========================================================================
522 CORBA::LongLong SALOMEDS_StudyManager_i::GetLocalImpl(const char* theHostname, CORBA::Long thePID, CORBA::Boolean& isLocal)
523 {
524 #ifdef WIN32
525   long pid = (long)_getpid();
526 #else
527   long pid = (long)getpid();
528 #endif
529   isLocal = (strcmp(theHostname, Kernel_Utils::GetHostname().c_str()) == 0 && pid == thePID)?1:0;
530   return reinterpret_cast<CORBA::LongLong>(_impl);
531 }
532
533 //===========================================================================
534 namespace SALOMEDS
535 {
536   PortableServer::ServantBase_var
537   GetServant(CORBA::Object_ptr theObject, PortableServer::POA_ptr thePOA)
538   {
539     if(CORBA::is_nil(theObject))
540       return NULL;
541     try{
542       return thePOA->reference_to_servant(theObject);
543     }catch(...){
544       return NULL;
545     }
546   }
547
548 }
549
550 //===========================================================================