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