Salome HOME
Update copyrights
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_StudyBuilder.cxx
1 // Copyright (C) 2007-2019  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_StudyBuilder.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26 //
27 #include "utilities.h"
28
29 #include "SALOMEDS_StudyBuilder.hxx"
30
31 #include "SALOMEDS.hxx"
32 #include "SALOMEDS_SObject.hxx"
33 #include "SALOMEDS_SComponent.hxx"
34 #include "SALOMEDS_GenericAttribute.hxx"
35 #include "SALOMEDS_StudyBuilder_i.hxx"
36
37 #include "SALOMEDS_Driver_i.hxx"
38
39 #include "SALOMEDSImpl_SObject.hxx"
40 #include "SALOMEDSImpl_SComponent.hxx"
41 #include "SALOMEDSImpl_GenericAttribute.hxx"
42
43 #include <string>
44 #include <stdexcept>
45
46 #include "DF_Attribute.hxx"
47
48 #include "Utils_CorbaException.hxx"
49 #include "Utils_ORB_INIT.hxx" 
50 #include "Utils_SINGLETON.hxx" 
51
52 pthread_mutex_t SALOMEDS_StudyBuilder::_remoteBuilderMutex;
53
54 SALOMEDS_StudyBuilder::SALOMEDS_StudyBuilder(SALOMEDSImpl_StudyBuilder* theBuilder)
55 {
56   _isLocal = true;
57   _local_impl = theBuilder;
58   _corba_impl = SALOMEDS::StudyBuilder::_nil();
59
60   init_orb();
61 }
62
63 SALOMEDS_StudyBuilder::SALOMEDS_StudyBuilder(SALOMEDS::StudyBuilder_ptr theBuilder)
64 {
65   pthread_mutex_lock( &_remoteBuilderMutex );
66   _isLocal = false;
67   _local_impl = NULL;
68   _corba_impl = SALOMEDS::StudyBuilder::_duplicate(theBuilder);
69
70   init_orb();
71 }
72
73 SALOMEDS_StudyBuilder::~SALOMEDS_StudyBuilder() 
74 {
75   if (!_isLocal) pthread_mutex_unlock( &_remoteBuilderMutex );
76 }
77
78 _PTR(SComponent) SALOMEDS_StudyBuilder::NewComponent(const std::string& ComponentDataType)
79 {
80   SALOMEDSClient_SComponent* aSCO = NULL;
81
82   if (_isLocal) {
83     CheckLocked();
84     SALOMEDS::Locker lock;
85
86     SALOMEDSImpl_SComponent aSCO_impl =_local_impl->NewComponent(ComponentDataType);
87     if(!aSCO_impl) return _PTR(SComponent)(aSCO);
88     aSCO = new SALOMEDS_SComponent(aSCO_impl);
89   }
90   else {
91     SALOMEDS::SComponent_var aSCO_impl = _corba_impl->NewComponent((char*)ComponentDataType.c_str());
92     if(CORBA::is_nil(aSCO_impl)) return _PTR(SComponent)(aSCO);
93     aSCO = new SALOMEDS_SComponent(aSCO_impl);
94   }
95
96   return _PTR(SComponent)(aSCO);
97 }
98
99 void SALOMEDS_StudyBuilder::DefineComponentInstance (const _PTR(SComponent)& theSCO, 
100                                                      const std::string& ComponentIOR)
101 {
102   if(!theSCO) return;
103
104   SALOMEDS_SComponent* aSCO = dynamic_cast<SALOMEDS_SComponent*>(theSCO.get());
105   if (_isLocal) {
106     CheckLocked();
107     SALOMEDS::Locker lock;
108
109     _local_impl->DefineComponentInstance(*(dynamic_cast<SALOMEDSImpl_SComponent*>(aSCO->GetLocalImpl())),
110                                          ComponentIOR);
111   }
112   else {
113     CORBA::Object_var obj = _orb->string_to_object(ComponentIOR.c_str());
114     _corba_impl->DefineComponentInstance(SALOMEDS::SComponent::_narrow(aSCO->GetCORBAImpl()), obj);
115   }
116 }
117
118 void SALOMEDS_StudyBuilder::RemoveComponent(const _PTR(SComponent)& theSCO)
119 {
120   if(!theSCO) return;
121   SALOMEDS_SComponent* aSCO = dynamic_cast<SALOMEDS_SComponent*>(theSCO.get());
122   if (_isLocal) {
123     CheckLocked();
124     SALOMEDS::Locker lock;
125
126     _local_impl->RemoveComponent(*(dynamic_cast<SALOMEDSImpl_SComponent*>(aSCO->GetLocalImpl())));
127   }
128   else _corba_impl->RemoveComponent(SALOMEDS::SComponent::_narrow(aSCO->GetCORBAImpl()));
129 }
130
131 _PTR(SObject) SALOMEDS_StudyBuilder::NewObject(const _PTR(SObject)& theFatherObject)
132 {
133   CheckLocked();
134
135   SALOMEDSClient_SObject* aSO = NULL;
136   SALOMEDS_SObject* father = dynamic_cast< SALOMEDS_SObject*>(theFatherObject.get());
137   if (father == NULL) return _PTR(SObject)(aSO);
138   if (_isLocal) {
139     SALOMEDS::Locker lock;
140
141     SALOMEDSImpl_SObject aSO_impl = _local_impl->NewObject(*(father->GetLocalImpl()));
142     if(!aSO_impl) return _PTR(SObject)(aSO);
143     aSO = new SALOMEDS_SObject(aSO_impl);
144   }
145   else {
146     SALOMEDS::SObject_var aSO_impl = _corba_impl->NewObject(father->GetCORBAImpl());
147     if(CORBA::is_nil(aSO_impl)) return _PTR(SObject)(aSO);
148     aSO = new SALOMEDS_SObject(aSO_impl);
149   }
150
151   return _PTR(SObject)(aSO);
152 }
153
154 _PTR(SObject) SALOMEDS_StudyBuilder::NewObjectToTag(const _PTR(SObject)& theFatherObject, int theTag)
155 {  
156   CheckLocked();
157
158   SALOMEDSClient_SObject* aSO = NULL;
159   SALOMEDS_SObject* father = dynamic_cast< SALOMEDS_SObject*>(theFatherObject.get());
160   if (father == NULL) return _PTR(SObject)(aSO);
161   if (_isLocal) {
162     SALOMEDS::Locker lock;
163
164     SALOMEDSImpl_SObject aSO_impl = _local_impl->NewObjectToTag(*(father->GetLocalImpl()), theTag);
165     if(aSO_impl.IsNull()) return _PTR(SObject)(aSO);
166     aSO = new SALOMEDS_SObject(aSO_impl);
167   }
168   else {
169     SALOMEDS::SObject_var aSO_impl = _corba_impl->NewObjectToTag(father->GetCORBAImpl(), theTag);
170     if(CORBA::is_nil(aSO_impl)) return _PTR(SObject)(aSO);
171     aSO = new SALOMEDS_SObject(aSO_impl);
172   }
173
174   return _PTR(SObject)(aSO);
175 }
176
177 void SALOMEDS_StudyBuilder::LoadWith(const _PTR(SComponent)& theSCO, const std::string& theIOR)
178 {
179   if(!theSCO) return;
180
181   SALOMEDS_SComponent* aSCO = dynamic_cast<SALOMEDS_SComponent*>(theSCO.get());
182   CORBA::Object_var obj = _orb->string_to_object(theIOR.c_str());
183   Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj);
184   SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(obj);
185   
186   if (_isLocal) {
187     SALOMEDS::Locker lock;
188
189     SALOMEDS_Driver_i* drv = new SALOMEDS_Driver_i(anEngine, _orb);    
190     SALOMEDSImpl_SComponent aSCO_impl = *(dynamic_cast<SALOMEDSImpl_SComponent*>(aSCO->GetLocalImpl()));
191     bool isDone = _local_impl->LoadWith(aSCO_impl, drv);
192     delete drv;
193     if(!isDone && _local_impl->IsError()) 
194       THROW_SALOME_CORBA_EXCEPTION(_local_impl->GetErrorCode().c_str(),SALOME::BAD_PARAM);
195   }
196   else {
197     _corba_impl->LoadWith(SALOMEDS::SComponent::_narrow(aSCO->GetCORBAImpl()), aDriver);
198   }
199 }
200
201 void SALOMEDS_StudyBuilder::Load(const _PTR(SObject)& theSCO)
202 {
203   SALOMEDS_SComponent* aSCO = dynamic_cast<SALOMEDS_SComponent*>(theSCO.get());
204   if (_isLocal) _local_impl->Load(*(dynamic_cast<SALOMEDSImpl_SComponent*>(aSCO->GetLocalImpl())));
205   else _corba_impl->Load(SALOMEDS::SComponent::_narrow(aSCO->GetCORBAImpl()));
206 }
207
208 void SALOMEDS_StudyBuilder::RemoveObject(const _PTR(SObject)& theSO)
209 {
210   if(!theSO) return;
211
212   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
213   if (_isLocal) {
214     CheckLocked();
215     SALOMEDS::Locker lock;
216
217     _local_impl->RemoveObject(*(aSO->GetLocalImpl()));
218   }
219   else _corba_impl->RemoveObject(aSO->GetCORBAImpl());
220 }
221
222 void SALOMEDS_StudyBuilder::RemoveObjectWithChildren(const _PTR(SObject)& theSO)
223 {
224   if(!theSO) return;
225
226   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
227   if (_isLocal) {
228     CheckLocked();
229     SALOMEDS::Locker lock;
230
231     _local_impl->RemoveObjectWithChildren(*(aSO->GetLocalImpl()));
232   }
233   else _corba_impl->RemoveObjectWithChildren(aSO->GetCORBAImpl());
234 }
235
236 _PTR(GenericAttribute) SALOMEDS_StudyBuilder::FindOrCreateAttribute(const _PTR(SObject)& theSO, 
237                                                                     const std::string& aTypeOfAttribute)
238 {  
239   SALOMEDSClient_GenericAttribute* anAttr = NULL;
240   if(!theSO) return _PTR(GenericAttribute)(anAttr);
241   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
242   if (_isLocal) {
243     SALOMEDS::Locker lock;
244
245     SALOMEDSImpl_GenericAttribute* aGA;
246     try {
247       aGA = dynamic_cast<SALOMEDSImpl_GenericAttribute*>
248         (_local_impl->FindOrCreateAttribute(*(aSO->GetLocalImpl()), aTypeOfAttribute));
249     }
250     catch (...) {
251       throw SALOMEDS::StudyBuilder::LockProtection();
252     }
253     anAttr = SALOMEDS_GenericAttribute::CreateAttribute(aGA);
254   }
255   else {
256     SALOMEDS::GenericAttribute_var aGA =
257       _corba_impl->FindOrCreateAttribute(aSO->GetCORBAImpl(), (char*)aTypeOfAttribute.c_str());
258     anAttr = SALOMEDS_GenericAttribute::CreateAttribute(aGA);
259   }
260
261   return _PTR(GenericAttribute)(anAttr);
262 }
263
264 bool SALOMEDS_StudyBuilder::FindAttribute(const _PTR(SObject)& theSO, 
265                                           _PTR(GenericAttribute)& anAttribute, 
266                                           const std::string& aTypeOfAttribute)
267 {
268   bool ret;
269
270   if(!theSO) return false;
271
272   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
273   if (_isLocal) {
274     SALOMEDS::Locker lock;
275
276     DF_Attribute* anAttr = NULL;
277     ret = _local_impl->FindAttribute(*(aSO->GetLocalImpl()), anAttr, aTypeOfAttribute);
278     if(ret) {
279       SALOMEDSImpl_GenericAttribute* aGA = dynamic_cast<SALOMEDSImpl_GenericAttribute*>(anAttr);
280       anAttribute = _PTR(GenericAttribute)(SALOMEDS_GenericAttribute::CreateAttribute(aGA));
281     }
282   }
283   else {
284     SALOMEDS::GenericAttribute_var aGA;
285     ret = _corba_impl->FindAttribute(aSO->GetCORBAImpl(), aGA.out(), (char*)aTypeOfAttribute.c_str()); 
286     if(ret) anAttribute = _PTR(GenericAttribute)(SALOMEDS_GenericAttribute::CreateAttribute(aGA));
287   }
288
289   return ret;
290 }
291
292 void SALOMEDS_StudyBuilder::RemoveAttribute(const _PTR(SObject)& theSO, const std::string& aTypeOfAttribute)
293 {
294   if(!theSO) return;
295
296   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
297   if (_isLocal) {
298     CheckLocked();
299     SALOMEDS::Locker lock;
300
301     _local_impl->RemoveAttribute(*(aSO->GetLocalImpl()), (char*)aTypeOfAttribute.c_str());
302   }
303   else _corba_impl->RemoveAttribute(aSO->GetCORBAImpl(), (char*)aTypeOfAttribute.c_str());
304 }
305
306 void SALOMEDS_StudyBuilder::Addreference(const _PTR(SObject)& me, const _PTR(SObject)& thereferencedObject)
307 {
308   if(!me || !thereferencedObject) {
309     throw DFexception("Invalid arguments");
310   }
311
312   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(me.get());
313   SALOMEDS_SObject* aRefSO = dynamic_cast<SALOMEDS_SObject*>(thereferencedObject.get());
314   if (_isLocal) {
315     CheckLocked();
316     SALOMEDS::Locker lock;
317
318     _local_impl->Addreference(*(aSO->GetLocalImpl()), *(aRefSO->GetLocalImpl()));
319   }
320   else _corba_impl->Addreference(aSO->GetCORBAImpl(), aRefSO->GetCORBAImpl());
321 }
322
323 void SALOMEDS_StudyBuilder::RemoveReference(const _PTR(SObject)& me)
324 {
325   if(!me) return;
326   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(me.get());
327   if (_isLocal) {
328     CheckLocked();
329     SALOMEDS::Locker lock;
330
331     _local_impl->RemoveReference(*(aSO->GetLocalImpl()));
332   }
333   else _corba_impl->RemoveReference(aSO->GetCORBAImpl());
334 }
335
336 void SALOMEDS_StudyBuilder::SetGUID(const _PTR(SObject)& theSO, const std::string& theGUID)
337 {
338   if(!theSO) return;
339
340   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
341   if (_isLocal) {
342     CheckLocked();
343     SALOMEDS::Locker lock;
344
345     _local_impl->SetGUID(*(aSO->GetLocalImpl()), theGUID);
346   }
347   else _corba_impl->SetGUID(aSO->GetCORBAImpl(), (char*)theGUID.c_str());
348 }
349  
350 bool SALOMEDS_StudyBuilder::IsGUID(const _PTR(SObject)& theSO, const std::string& theGUID)
351 {
352   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
353   bool ret;
354   if (_isLocal) {
355     SALOMEDS::Locker lock;
356
357     ret = _local_impl->IsGUID(*(aSO->GetLocalImpl()), (char*)theGUID.c_str());
358   }
359   else ret = _corba_impl->IsGUID(aSO->GetCORBAImpl(), (char*)theGUID.c_str());
360
361   return ret;
362 }
363
364 void SALOMEDS_StudyBuilder::NewCommand()
365 {
366   if (_isLocal) {
367     SALOMEDS::Locker lock;
368     _local_impl->NewCommand();
369   }
370   else _corba_impl->NewCommand();
371 }
372  
373 void SALOMEDS_StudyBuilder::CommitCommand()
374 {
375   if (_isLocal) {
376     SALOMEDS::Locker lock;
377     try {
378       _local_impl->CommitCommand();
379     }
380     catch(...) {
381       throw SALOMEDS::StudyBuilder::LockProtection();
382     }
383   }
384   else _corba_impl->CommitCommand();
385 }
386
387 bool SALOMEDS_StudyBuilder::HasOpenCommand()
388 {
389   bool ret;
390   if (_isLocal) {
391     SALOMEDS::Locker lock;
392     ret = _local_impl->HasOpenCommand();
393   }
394   else ret = _corba_impl->HasOpenCommand();
395   return ret;
396 }
397
398 void SALOMEDS_StudyBuilder::AbortCommand()
399 {
400   if (_isLocal) {
401     SALOMEDS::Locker lock;
402     _local_impl->AbortCommand();
403   }
404   else _corba_impl->AbortCommand();
405 }
406
407 void SALOMEDS_StudyBuilder::Undo()
408 {
409   if (_isLocal) {
410     SALOMEDS::Locker lock;
411     try {
412       _local_impl->Undo();
413     }
414     catch(...) {
415       throw SALOMEDS::StudyBuilder::LockProtection();
416     }
417   }
418   else _corba_impl->Undo();
419 }
420
421 void SALOMEDS_StudyBuilder::Redo()
422 {
423   if (_isLocal) {
424     SALOMEDS::Locker lock;
425     try {
426       _local_impl->Redo();
427     }
428     catch(...) {
429       throw SALOMEDS::StudyBuilder::LockProtection();
430     }
431   }
432   else _corba_impl->Redo(); 
433 }
434
435 bool SALOMEDS_StudyBuilder::GetAvailableUndos()
436 {
437   bool ret;
438   if (_isLocal) {
439     SALOMEDS::Locker lock;
440     ret = _local_impl->GetAvailableUndos();
441   }
442   else ret = _corba_impl->GetAvailableUndos();
443   return ret;
444 }
445
446 bool SALOMEDS_StudyBuilder::GetAvailableRedos()
447 {
448   bool ret;
449   if (_isLocal) {
450     SALOMEDS::Locker lock;
451     ret = _local_impl->GetAvailableRedos();
452   }
453   else ret = _corba_impl->GetAvailableRedos();
454   return ret; 
455 }
456
457 int SALOMEDS_StudyBuilder::UndoLimit()
458 {
459   int aLimit;
460   if (_isLocal) {
461     SALOMEDS::Locker lock;
462     aLimit = _local_impl->UndoLimit();
463   }
464   else aLimit = _corba_impl->UndoLimit();
465   return aLimit;
466 }
467  
468 void SALOMEDS_StudyBuilder::UndoLimit(int theLimit)
469 {
470   if (_isLocal) {
471     CheckLocked();
472     SALOMEDS::Locker lock;
473
474     _local_impl->UndoLimit(theLimit);
475   }
476   else _corba_impl->UndoLimit(theLimit);
477 }
478  
479 void SALOMEDS_StudyBuilder::CheckLocked()
480 {
481   //There is only local part as CORBA part throws the correct exception
482   if (_isLocal) {
483     SALOMEDS::Locker lock;
484     try {
485       _local_impl->CheckLocked();
486     }
487     catch(...) {
488       throw SALOMEDS::StudyBuilder::LockProtection();
489     }
490   }
491 }
492
493 void SALOMEDS_StudyBuilder::SetName(const _PTR(SObject)& theSO, const std::string& theValue)
494 {
495   if(!theSO) return;
496
497   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
498   if (_isLocal) {
499     CheckLocked();
500     SALOMEDS::Locker lock;
501
502     _local_impl->SetName(*(aSO->GetLocalImpl()), theValue);
503   }
504   else _corba_impl->SetName(aSO->GetCORBAImpl(), (char*)theValue.c_str());
505 }
506
507 void SALOMEDS_StudyBuilder::SetComment(const _PTR(SObject)& theSO, const std::string& theValue)
508 {
509   if(!theSO) return;
510
511   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
512   if (_isLocal) {
513     CheckLocked();
514     SALOMEDS::Locker lock;
515
516     _local_impl->SetComment(*(aSO->GetLocalImpl()), theValue);
517   }
518   else _corba_impl->SetComment(aSO->GetCORBAImpl(), (char*)theValue.c_str());
519 }
520
521 void SALOMEDS_StudyBuilder::SetIOR(const _PTR(SObject)& theSO, const std::string& theValue)
522 {
523   if(!theSO) return;
524
525   SALOMEDS_SObject* aSO = dynamic_cast<SALOMEDS_SObject*>(theSO.get());
526   if (_isLocal) {
527     CheckLocked();
528     SALOMEDS::Locker lock;
529
530     _local_impl->SetIOR(*(aSO->GetLocalImpl()), theValue);
531   }
532   else _corba_impl->SetIOR(aSO->GetCORBAImpl(), (char*)theValue.c_str());
533 }
534
535 SALOMEDS::StudyBuilder_ptr SALOMEDS_StudyBuilder::GetBuilder()
536 {
537   if(_isLocal) {
538     if(!CORBA::is_nil(_corba_impl)) return SALOMEDS::StudyBuilder::_duplicate(_corba_impl);
539     SALOMEDS_StudyBuilder_i* servant = new SALOMEDS_StudyBuilder_i(_local_impl, _orb);
540     SALOMEDS::StudyBuilder_var aBuilder = servant->StudyBuilder::_this();
541     _corba_impl = SALOMEDS::StudyBuilder::_duplicate(aBuilder);
542     return aBuilder._retn();
543   }
544   else {
545     return SALOMEDS::StudyBuilder::_duplicate(_corba_impl);
546   }
547   return SALOMEDS::StudyBuilder::_nil();
548 }
549
550 void SALOMEDS_StudyBuilder::init_orb()
551 {
552   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance();
553   ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()); 
554   _orb = init(0 , 0 );     
555 }