Salome HOME
PR: merge from branch BR_auto_V310 tag mergefrom_OCC_development_for_3_2_0a2_10mar06
[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/
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 <TColStd_HArray1OfCharacter.hxx>
38 #include <TCollection_ExtendedString.hxx>
39 #include <TCollection_AsciiString.hxx>
40
41 #include "Utils_CorbaException.hxx"
42
43 #include <strstream>
44 #include <map>
45 using namespace std;
46
47 #ifdef WIN32
48 #include <process.h>
49 #else
50 #include <sys/types.h>
51 #include <unistd.h>
52 #endif
53
54 #include "OpUtil.hxx"
55
56 #include "SALOME_GenericObj_i.hh"
57
58 #include "Utils_ExceptHandlers.hxx"
59
60 UNEXPECT_CATCH(SalomeException,SALOME::SALOME_Exception);
61 UNEXPECT_CATCH(LockProtection, SALOMEDS::StudyBuilder::LockProtection);
62
63 static SALOMEDS_Driver_i* GetDriver(const Handle(SALOMEDSImpl_SObject)& theObject, CORBA::ORB_ptr orb);
64
65 static std::map<int, PortableServer::POA_ptr> _mapOfPOA;
66
67 //============================================================================
68 /*! Function : SALOMEDS_StudyManager_i
69  *  Purpose  : SALOMEDS_StudyManager_i constructor
70  */
71 //============================================================================
72 SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb, PortableServer::POA_ptr thePOA)
73 {
74   _orb = CORBA::ORB::_duplicate(orb);
75   _poa = PortableServer::POA::_duplicate(thePOA);
76   _name_service = new SALOME_NamingService(_orb);
77   // Study directory creation in the naming service : to register all
78   // open studies in the session
79   _name_service->Create_Directory("/Study");
80   _impl = new SALOMEDSImpl_StudyManager;
81   _factory = new SALOMEDS_DriverFactory_i(_orb);
82 }
83
84 //============================================================================
85 /*! Function : ~SALOMEDS_StudyManager_i
86  *  Purpose  : SALOMEDS_StudyManager_i destructor
87  */
88 //============================================================================
89 SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
90 {
91   // Destroy directory to register open studies
92   _name_service->Destroy_Directory("/Study");
93   delete _factory;
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(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 {
116   SALOMEDS::Locker lock;
117
118   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->NewStudy(TCollection_AsciiString((char*)study_name));
119   if(aStudyImpl.IsNull()) {
120     MESSAGE("NewStudy : Error : " << _impl->GetErrorCode());
121     return SALOMEDS::Study::_nil();
122   }
123
124   MESSAGE("NewStudy : Creating the CORBA servant holding it... ");
125
126   SALOMEDS_Study_i *Study_servant = new SALOMEDS_Study_i(aStudyImpl, _orb);
127   SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
128
129   // Register study in the naming service
130   // Path to acces the study
131   if(!_name_service->Change_Directory("/Study"))
132       MESSAGE( "Unable to access the study directory" )
133   else
134       _name_service->Register(Study, study_name);
135
136   // Assign the value of the IOR in the study->root
137   const char*  IORStudy = _orb->object_to_string(Study);
138
139   aStudyImpl->SetTransientReference((char*)IORStudy);
140
141   _mapOfPOA[Study->StudyId()] = _poa;
142
143   return Study;
144 }
145
146 //============================================================================
147 /*! Function : Open
148  *  Purpose  : Open a Study from it's persistent reference
149  */
150 //============================================================================
151 SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
152      throw(SALOME::SALOME_Exception)
153 {
154   SALOMEDS::Locker lock;
155
156   Unexpect aCatch(SalomeException);
157   MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
158
159   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->Open(TCollection_AsciiString((char*)aUrl));
160
161   MESSAGE("Open : Creating the CORBA servant holding it... ");
162
163   // Temporary aStudyUrl in place of study name
164   SALOMEDS_Study_i * Study_servant = new SALOMEDS_Study_i(aStudyImpl, _orb);
165   SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
166
167   // Assign the value of the IOR in the study->root
168   CORBA::String_var IORStudy = _orb->object_to_string(Study);
169   aStudyImpl->SetTransientReference((char*)IORStudy);
170
171   // Register study in the naming service
172   // Path to acces the study
173   if(!_name_service->Change_Directory("/Study")) MESSAGE( "Unable to access the study directory" )
174   else _name_service->Register(Study, CORBA::string_dup(aStudyImpl->Name().ToCString()));
175
176   return Study;
177 }
178
179
180
181 //============================================================================
182 /*! Function : Close
183  *  Purpose  : Close a study.
184  *             If the study hasn't been saved, ask the user to confirm the
185  *             close action without saving
186  */
187 //============================================================================
188 void SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
189 {
190   SALOMEDS::Locker lock;
191
192   if(aStudy->_is_nil()) return;
193
194   // Destroy study name in the naming service
195   if(_name_service->Change_Directory("/Study")){
196     CORBA::String_var aString(aStudy->Name());
197     _name_service->Destroy_Name(aString.in());
198   }
199
200   SALOMEDS::unlock();
201   aStudy->Close();
202   SALOMEDS::lock();
203 }
204
205 //============================================================================
206 /*! Function : Save
207  *  Purpose  : Save a Study to it's persistent reference
208  */
209 //============================================================================
210 CORBA::Boolean SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
211 {
212   SALOMEDS::Locker lock;
213
214   if(aStudy->_is_nil()) {
215     MESSAGE("Save error: Study is null");
216     return false;
217   }
218
219   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
220   return _impl->Save(aStudyImpl, _factory, theMultiFile);
221 }
222
223 CORBA::Boolean SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
224 {
225   SALOMEDS::Locker lock;
226
227   if(aStudy->_is_nil()) {
228     MESSAGE("SaveASCII error: Study is null");
229     return false;
230   }
231
232   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
233   return _impl->SaveASCII(aStudyImpl, _factory, theMultiFile);
234 }
235
236 //=============================================================================
237 /*! Function : SaveAs
238  *  Purpose  : Save a study to the persistent reference aUrl
239  */
240 //============================================================================
241 CORBA::Boolean SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
242 {
243   SALOMEDS::Locker lock;
244
245   if(aStudy->_is_nil()) {
246     MESSAGE("SaveASCII error: Study is null");
247     return false;
248   }
249
250   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
251   return _impl->SaveAs(TCollection_AsciiString((char*)aUrl), aStudyImpl, _factory, theMultiFile);
252 }
253
254 CORBA::Boolean SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
255 {
256   SALOMEDS::Locker lock;
257
258   if(aStudy->_is_nil()) {
259     MESSAGE("SaveASCII error: Study is null");
260     return false;
261   }
262
263   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
264   return _impl->SaveAsASCII(TCollection_AsciiString((char*)aUrl), aStudyImpl, _factory, theMultiFile);
265 }
266
267 //============================================================================
268 /*! Function : GetOpenStudies
269  *  Purpose  : Get name list of open studies in the session
270  */
271 //============================================================================
272 SALOMEDS::ListOfOpenStudies*  SALOMEDS_StudyManager_i::GetOpenStudies()
273 {
274   SALOMEDS::Locker lock;
275
276   Handle(TColStd_HSequenceOfTransient) anOpened = _impl->GetOpenStudies();
277   int aLength = anOpened->Length();
278
279   SALOMEDS::ListOfOpenStudies_var _list_open_studies = new SALOMEDS::ListOfOpenStudies;
280   _list_open_studies->length(aLength);
281
282   if(!aLength)
283     {
284       MESSAGE("No active study in this session");
285     }
286   else
287     {
288       for (unsigned int ind=1; ind <= aLength; ind++)
289         {
290           Handle(SALOMEDSImpl_Study) aStudy = Handle(SALOMEDSImpl_Study)::DownCast(anOpened->Value(ind));
291           _list_open_studies[ind-1] = CORBA::string_dup(aStudy->Name().ToCString());
292           SCRUTE(_list_open_studies[ind-1]) ;
293         }
294     }
295   return _list_open_studies._retn();
296 }
297
298 //============================================================================
299 /*! Function : GetStudyByName
300  *  Purpose  : Get a study from its name
301  */
302 //============================================================================
303 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName)
304 {
305   SALOMEDS::Locker lock;
306
307   Handle(SALOMEDSImpl_Study) aStudyImpl =
308     _impl->GetStudyByName(TCollection_AsciiString((char*)aStudyName));
309
310   if (aStudyImpl.IsNull())
311   {
312     MESSAGE(_impl->GetErrorCode().ToCString());
313     return SALOMEDS::Study::_nil();
314   }
315
316   SALOMEDS_Study_i* aStudy_servant = new SALOMEDS_Study_i(aStudyImpl, _orb);
317   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(aStudy_servant->_this());
318
319   return aStudy._retn();
320 }
321
322 //============================================================================
323 /*! Function : GetStudyByID
324  *  Purpose  : Get a study from its ID
325  */
326 //============================================================================
327 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID)
328 {
329   SALOMEDS::Locker lock;
330
331   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudyID);
332
333   if (aStudyImpl.IsNull())
334   {
335     MESSAGE(_impl->GetErrorCode().ToCString());
336     return SALOMEDS::Study::_nil();
337   }
338
339   SALOMEDS_Study_i* aStudy_servant = new SALOMEDS_Study_i(aStudyImpl, _orb);
340   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(aStudy_servant->_this());
341
342   return aStudy._retn();
343 }
344
345
346 //============================================================================
347 /*! Function : CanCopy
348  *  Purpose  :
349  */
350 //============================================================================
351 CORBA::Boolean SALOMEDS_StudyManager_i::CanCopy(SALOMEDS::SObject_ptr theObject)
352 {
353   SALOMEDS::Locker lock;
354
355   SALOMEDS::Study_var aStudy = theObject->GetStudy();
356   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
357   Handle(SALOMEDSImpl_SObject) anObject = aStudyImpl->GetSObject((char*)theObject->GetID());
358
359   SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
360   bool ret = _impl->CanCopy(anObject, aDriver);
361   delete aDriver;
362   return ret;
363 }
364
365 //============================================================================
366 /*! Function : Copy
367  *  Purpose  :
368  */
369 //============================================================================
370 CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject)
371 {
372   SALOMEDS::Locker lock;
373
374   SALOMEDS::Study_var aStudy = theObject->GetStudy();
375   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
376   Handle(SALOMEDSImpl_SObject) anObject = aStudyImpl->GetSObject((char*)theObject->GetID());
377
378   SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
379   bool ret = _impl->Copy(anObject, aDriver);
380   delete aDriver;
381   return ret;
382 }
383
384 //============================================================================
385 /*! Function : CanPaste
386  *  Purpose  :
387  */
388 //============================================================================
389 CORBA::Boolean SALOMEDS_StudyManager_i::CanPaste(SALOMEDS::SObject_ptr theObject)
390 {
391   SALOMEDS::Locker lock;
392
393   SALOMEDS::Study_var aStudy = theObject->GetStudy();
394   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
395   Handle(SALOMEDSImpl_SObject) anObject = aStudyImpl->GetSObject((char*)theObject->GetID());
396
397   SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
398   bool ret = _impl->CanPaste(anObject, aDriver);
399   delete aDriver;
400   return ret;
401 }
402
403 //============================================================================
404 /*! Function : Paste
405  *  Purpose  :
406  */
407 //============================================================================
408 SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theObject)
409      throw(SALOMEDS::StudyBuilder::LockProtection)
410 {
411   SALOMEDS::Locker lock;
412
413   Unexpect aCatch(LockProtection);
414   SALOMEDS::Study_var aStudy = theObject->GetStudy();
415
416   Handle(SALOMEDSImpl_Study) aStudyImpl = _impl->GetStudyByID(aStudy->StudyId());
417   Handle(SALOMEDSImpl_SObject) anObject = aStudyImpl->GetSObject((char*)theObject->GetID());
418   Handle(SALOMEDSImpl_SObject) aNewSO;
419
420   try {
421     SALOMEDS_Driver_i* aDriver = GetDriver(anObject, _orb);
422     aNewSO =  _impl->Paste(anObject, aDriver);
423     delete aDriver;
424   }
425   catch (...) {
426     throw SALOMEDS::StudyBuilder::LockProtection();
427   }
428
429   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aNewSO, _orb);
430   return so._retn();
431 }
432
433
434 SALOMEDS_Driver_i* GetDriver(const Handle(SALOMEDSImpl_SObject)& theObject, CORBA::ORB_ptr orb)
435 {
436   SALOMEDS_Driver_i* driver = NULL;
437
438   Handle(SALOMEDSImpl_SComponent) aSCO = theObject->GetFatherComponent();
439   if(!aSCO.IsNull()) {
440     TCollection_AsciiString IOREngine = aSCO->GetIOR();
441     if(!IOREngine.IsEmpty()) {
442       CORBA::Object_var obj = orb->string_to_object(IOREngine.ToCString());
443       SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
444       driver = new SALOMEDS_Driver_i(Engine, orb);
445     }
446   }
447
448   return driver;
449 }
450
451 PortableServer::POA_ptr SALOMEDS_StudyManager_i::GetPOA(const SALOMEDS::Study_ptr theStudy) {
452   if (_mapOfPOA.find(theStudy->StudyId()) != _mapOfPOA.end()) return _mapOfPOA[theStudy->StudyId()];
453   return PortableServer::POA::_nil();
454 }
455
456 //===========================================================================
457 //   PRIVATE FUNCTIONS
458 //===========================================================================
459 CORBA::Long SALOMEDS_StudyManager_i::GetLocalImpl(const char* theHostname, CORBA::Long thePID, CORBA::Boolean& isLocal)
460 {
461 #ifdef WIN32
462   long pid = (long)_getpid();
463 #else
464   long pid = (long)getpid();
465 #endif
466   isLocal = (strcmp(theHostname, GetHostname().c_str()) == 0 && pid == thePID)?1:0;
467   SALOMEDSImpl_StudyManager* aManager = _impl.operator->();
468   return ((long)aManager);
469 }
470
471 //===========================================================================
472 namespace SALOMEDS
473 {
474 /*
475   CORBA::Object_var
476   GetObject(const TDF_Label& theLabel, CORBA::ORB_ptr theORB)
477   {
478     try {
479       Handle(SALOMEDS_IORAttribute) anAttr;
480       if(theLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr))
481         return theORB->string_to_object(TCollection_AsciiString(anAttr->Get()).ToCString());
482     }catch(...){
483     }
484     return CORBA::Object::_nil();
485   }
486 */
487
488   PortableServer::ServantBase_var
489   GetServant(CORBA::Object_ptr theObject, PortableServer::POA_ptr thePOA)
490   {
491     if(CORBA::is_nil(theObject))
492       return NULL;
493     try{
494       return thePOA->reference_to_servant(theObject);
495     }catch(...){
496       return NULL;
497     }
498   }
499
500 }
501
502 //===========================================================================