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