Salome HOME
Merge remote-tracking branch 'origin/vsr/fix_single_study_pb' into pre/fix_single_study
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_Study_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_Study_i.cxx
24 //  Author : Sergey RUIN
25 //  Module : SALOME
26 //
27 #include "utilities.h"
28 #include "SALOMEDS_Study_i.hxx"
29 #include "SALOMEDS_StudyManager_i.hxx"
30 #include "SALOMEDS_UseCaseIterator_i.hxx"
31 #include "SALOMEDS_GenericAttribute_i.hxx"
32 #include "SALOMEDS_AttributeStudyProperties_i.hxx"
33 #include "SALOMEDS_AttributeParameter_i.hxx"
34 #include "SALOMEDS_ChildIterator_i.hxx"
35 #include "SALOMEDS_Driver_i.hxx"
36 #include "SALOMEDS.hxx"
37
38 #include "SALOMEDSImpl_SObject.hxx"
39 #include "SALOMEDSImpl_SComponent.hxx"
40 #include "SALOMEDSImpl_UseCaseBuilder.hxx"
41 #include "SALOMEDSImpl_AttributeStudyProperties.hxx"
42 #include "SALOMEDSImpl_AttributeParameter.hxx"
43 #include "SALOMEDSImpl_ChildIterator.hxx"
44 #include "SALOMEDSImpl_IParameters.hxx"
45 #include "SALOMEDSImpl_Callback.hxx"
46
47 #include "DF_Label.hxx"
48 #include "DF_Attribute.hxx"
49
50 #include "Basics_Utils.hxx"
51
52 #ifdef WIN32
53 #include <process.h>
54 #else
55 #include <sys/types.h>
56 #include <unistd.h>
57 #endif
58
59 namespace SALOMEDS
60 {
61   class Notifier: public SALOMEDSImpl_AbstractCallback
62   {
63   public:
64     Notifier(CORBA::ORB_ptr orb)
65     {
66       _orb = CORBA::ORB::_duplicate(orb);
67     }
68
69     //============================================================================
70     /*! Function : addSO_Notification
71      *  Purpose  : This function tells all the observers that a SO has been added
72      */
73     //============================================================================
74
75     virtual bool addSO_Notification(const SALOMEDSImpl_SObject& theSObject)
76     {
77       std::string anID=theSObject.GetID();
78       const char* cID=anID.c_str();
79       for (ObsListIter it (myObservers.begin()); it != myObservers.end(); ++it)
80       {
81         it->first->notifyObserverID(cID,1);
82       }
83       return true; // NGE return always true but can be modified if needed
84     }
85
86     //============================================================================
87     /*! Function : removeSO_Notification
88      *  Purpose  : This function tells all the observers that a SO has been removed
89      */
90     //============================================================================
91
92     virtual bool removeSO_Notification(const SALOMEDSImpl_SObject& theSObject)
93     {
94       std::string anID=theSObject.GetID();
95       const char* cID=anID.c_str();
96       for (ObsListIter it (myObservers.begin()); it != myObservers.end(); ++it)
97       {
98         it->first->notifyObserverID(cID,2);
99       }
100       return true; // NGE return always true but can be modified if needed
101     }
102
103     //============================================================================
104     /*! Function : modifySO_Notification
105      *  Purpose  : This function tells all the observers that a SO has been modified
106      */
107     //============================================================================
108
109     virtual bool modifySO_Notification(const SALOMEDSImpl_SObject& theSObject, int reason)
110     {
111       for (ObsListIter it (myObservers.begin()); it != myObservers.end(); ++it)
112       {
113         if(it->second)
114         {
115           std::string anID=theSObject.GetID();
116           const char* cID=anID.c_str();
117           it->first->notifyObserverID(cID,reason);
118         }
119       }
120       return true; // NGE return always true but can be modified if needed
121     }
122
123     //============================================================================
124     /*! Function : modifyNB_Notification
125      *  Purpose  : This function tells all the observers that 
126      *             a NoteBook variable has been added/modified/removed.
127      */
128     //============================================================================
129     
130     virtual bool modifyNB_Notification(const char* theVarName)
131     {
132       for (ObsListIter it (myObservers.begin()); it != myObservers.end(); ++it)
133         {
134           it->first->notifyObserverID(theVarName,6);
135         }
136       return true; // NGE return always true but can be modified if needed
137     }
138
139     //============================================================================
140     /*! Function : attach
141      *  Purpose  : register an Observer
142      */
143     //============================================================================
144
145     virtual void attach(SALOMEDS::Observer_ptr theObs, bool modify)
146     {
147       myObservers.push_back(std::make_pair(SALOMEDS::Observer::_duplicate(theObs),modify));
148     }
149
150     //============================================================================
151     /*! Function : detach
152      *  Purpose  : unregister an Observer
153      */
154     //============================================================================
155
156     virtual void detach(SALOMEDS::Observer_ptr theObs)
157     {
158       for (ObsListIter it (myObservers.begin()); it != myObservers.end(); ++it)
159       {
160         if ( it->first->_is_equivalent(theObs) ) {
161           myObservers.erase( it );
162           break;
163         }
164       }
165     }
166
167   private:
168     typedef std::list< std::pair< SALOMEDS::Observer_var, bool > > ObsList;
169     typedef ObsList::iterator ObsListIter;
170     ObsList myObservers;
171     CORBA::ORB_var                    _orb;
172   };
173
174   class GenObjRegister: public SALOMEDSImpl_AbstractCallback
175   {
176   public:
177     GenObjRegister(CORBA::ORB_ptr orb)
178     {
179       _orb = CORBA::ORB::_duplicate(orb);
180     }
181     virtual void RegisterGenObj  (const std::string& theIOR)
182     {
183       try
184       {
185         CORBA::Object_var obj = _orb->string_to_object(theIOR.c_str());
186         if ( obj->_non_existent() ) return;
187         SALOME::GenericObj_var gobj = SALOME::GenericObj::_narrow(obj);
188         if(! CORBA::is_nil(gobj) )
189         {
190           gobj->Register();
191         }
192       }
193       catch(const CORBA::Exception& e)
194       {
195       }
196     }
197     virtual void UnRegisterGenObj(const std::string& theIOR)
198     {
199       try
200       {
201         CORBA::Object_var obj = _orb->string_to_object(theIOR.c_str());
202         if ( obj->_non_existent() ) return;
203         SALOME::GenericObj_var gobj = SALOME::GenericObj::_narrow(obj);
204         if(! CORBA::is_nil(gobj) )
205         {
206           gobj->UnRegister();
207         }
208       }
209       catch(const CORBA::Exception& e)
210       {
211       }
212     }
213
214   private:
215     CORBA::ORB_var _orb;
216   };
217
218 } // namespace SALOMEDS
219
220 std::map<SALOMEDSImpl_Study* , SALOMEDS_Study_i*> SALOMEDS_Study_i::_mapOfStudies;
221
222 //============================================================================
223 /*! Function : SALOMEDS_Study_i
224  *  Purpose  : SALOMEDS_Study_i constructor
225  */
226 //============================================================================
227 SALOMEDS_Study_i::SALOMEDS_Study_i(SALOMEDSImpl_Study* theImpl,
228                                    CORBA::ORB_ptr      orb)
229 {
230   _orb            = CORBA::ORB::_duplicate(orb);
231   _impl           = theImpl;
232   _builder        = new SALOMEDS_StudyBuilder_i(_impl->NewBuilder(), _orb);  
233   _notifier       = new SALOMEDS::Notifier(_orb);
234   _genObjRegister = new SALOMEDS::GenObjRegister(_orb);
235
236   theImpl->setNotifier(_notifier);
237   theImpl->setGenObjRegister( _genObjRegister );
238 }
239   
240 //============================================================================
241 /*! Function : ~SALOMEDS_Study_i
242  *  Purpose  : SALOMEDS_Study_i destructor
243  */
244 //============================================================================
245 SALOMEDS_Study_i::~SALOMEDS_Study_i()
246 {
247   //delete the builder servant
248   PortableServer::POA_var poa=_builder->_default_POA();
249   PortableServer::ObjectId_var anObjectId = poa->servant_to_id(_builder);
250   poa->deactivate_object(anObjectId.in());
251   _builder->_remove_ref();
252   
253   _impl->setNotifier(0);
254   delete _notifier;
255   delete _genObjRegister;
256   //delete implementation
257   delete _impl;
258   _mapOfStudies.erase(_impl);
259 }  
260
261 //============================================================================
262 /*! Function : GetPersistentReference
263  *  Purpose  : Get persistent reference of study (idem URL())
264  */
265 //============================================================================
266 char* SALOMEDS_Study_i::GetPersistentReference()
267 {
268   SALOMEDS::Locker lock; 
269   return CORBA::string_dup(_impl->GetPersistentReference().c_str());
270 }
271 //============================================================================
272 /*! Function : GetTransientReference
273  *  Purpose  : Get IOR of the Study (registred in OCAF document in doc->Root)
274  */
275 //============================================================================
276 char* SALOMEDS_Study_i::GetTransientReference()
277 {
278   SALOMEDS::Locker lock; 
279   return CORBA::string_dup(_impl->GetTransientReference().c_str()); 
280 }
281
282 //============================================================================
283 /*! Function : IsEmpty
284  *  Purpose  : Detect if study is empty
285  */
286 //============================================================================
287 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
288 {
289   SALOMEDS::Locker lock; 
290   return _impl->IsEmpty();
291 }
292
293 //============================================================================
294 /*! Function : FindComponent
295  *  Purpose  : Find a Component with ComponentDataType = aComponentName
296  */
297 //============================================================================
298 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponent (const char* aComponentName)
299 {
300   SALOMEDS::Locker lock; 
301   
302   SALOMEDSImpl_SComponent aCompImpl = _impl->FindComponent(std::string(aComponentName));
303   if(aCompImpl.IsNull()) return SALOMEDS::SComponent::_nil();
304
305   SALOMEDS::SComponent_var sco = SALOMEDS_SComponent_i::New (aCompImpl, _orb);
306   return sco._retn();
307 }
308
309 //============================================================================
310 /*! Function : FindComponentID
311  *  Purpose  : Find a Component from it's ID
312  */
313 //============================================================================
314 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
315 {
316   SALOMEDS::Locker lock; 
317   
318   SALOMEDSImpl_SComponent aCompImpl = _impl->FindComponentID(std::string((char*)aComponentID));
319   if(aCompImpl.IsNull()) return SALOMEDS::SComponent::_nil();
320
321   SALOMEDS::SComponent_var sco = SALOMEDS_SComponent_i::New (aCompImpl, _orb);
322   return sco._retn();
323 }
324
325 //============================================================================
326 /*! Function : FindObject
327  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
328  */
329 //============================================================================
330 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* anObjectName)
331 {
332   SALOMEDS::Locker lock; 
333
334   SALOMEDSImpl_SObject aSO = _impl->FindObject(std::string((char*)anObjectName));
335   if(aSO.IsNull()) return SALOMEDS::SObject::_nil();
336
337   if(aSO.IsComponent()) {
338     SALOMEDSImpl_SComponent aSCO = aSO;
339     SALOMEDS::SComponent_var sco = SALOMEDS_SComponent_i::New (aSCO, _orb);
340     return sco._retn();
341   }
342    
343   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aSO, _orb);
344  
345  return so._retn();
346 }
347
348 //============================================================================
349 /*! Function : FindObjectID
350  *  Purpose  : Find an Object with ID = anObjectID
351  */
352 //============================================================================
353 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
354 {
355   SALOMEDS::Locker lock; 
356
357   SALOMEDSImpl_SObject aSO = _impl->FindObjectID(std::string((char*)anObjectID));
358   if(aSO.IsNull()) return SALOMEDS::SObject::_nil();
359   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aSO, _orb);
360   return so._retn();
361 }
362
363 //============================================================================
364 /*! Function : CreateObjectID
365  *  Purpose  : Creates an Object with ID = anObjectID
366  */
367 //============================================================================
368 SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
369 {
370   SALOMEDS::Locker lock; 
371
372   if(!anObjectID || strlen(anObjectID) == 0) return SALOMEDS::SObject::_nil();
373
374   SALOMEDSImpl_SObject aSO = _impl->CreateObjectID((char*)anObjectID);
375   if(aSO.IsNull()) return SALOMEDS::SObject::_nil();
376
377   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aSO, _orb);
378   return so._retn();
379 }
380
381 //============================================================================
382 /*! Function : FindObjectByName
383  *  Purpose  : Find Objects with SALOMEDS::Name = anObjectName in a Component
384  *           : with ComponentDataType = aComponentName
385  */
386 //============================================================================
387 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
388                                                                     const char* aComponentName )
389 {
390   SALOMEDS::Locker lock; 
391
392   std::vector<SALOMEDSImpl_SObject> aSeq = _impl->FindObjectByName(std::string((char*)anObjectName),
393                                                                std::string((char*)aComponentName));
394   int aLength = aSeq.size();
395   SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
396   listSO->length(aLength);
397   for(int i = 0; i<aLength; i++) {
398     SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aSeq[i], _orb);
399     listSO[i] = so ;
400   }
401   return listSO._retn() ;
402 }
403
404 //============================================================================
405 /*! Function : FindObjectIOR
406  *  Purpose  : Find an Object with IOR = anObjectIOR
407  */
408 //============================================================================
409 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* anObjectIOR)
410 {
411   SALOMEDS::Locker lock; 
412
413   SALOMEDSImpl_SObject aSO = _impl->FindObjectIOR(std::string((char*)anObjectIOR));
414   if(aSO.IsNull()) return SALOMEDS::SObject::_nil();
415
416   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aSO, _orb);
417   return so._retn();
418 }
419
420 //============================================================================
421 /*! Function : FindObjectByPath
422  *  Purpose  : Find an Object by its path = thePath
423  */
424 //============================================================================
425 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
426 {
427   SALOMEDS::Locker lock; 
428
429   SALOMEDSImpl_SObject aSO = _impl->FindObjectByPath(std::string((char*)thePath));
430   if(aSO.IsNull()) return SALOMEDS::SObject::_nil();
431
432   SALOMEDS::SObject_var so = SALOMEDS_SObject_i::New (aSO, _orb);
433   return so._retn();
434 }
435
436 //============================================================================
437 /*! Function : GetObjectPath
438  *  Purpose  : 
439  */
440 //============================================================================
441 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
442 {
443   SALOMEDS::Locker lock; 
444
445   std::string aPath("");
446   if(CORBA::is_nil(theObject)) return CORBA::string_dup(aPath.c_str());
447   SALOMEDSImpl_SObject aSO;
448   SALOMEDS::SObject_var aSObj = SALOMEDS::SObject::_narrow(theObject);
449
450   if(!CORBA::is_nil(aSObj)) {
451     aSO = _impl->FindObjectID(aSObj->GetID());
452   }
453   else {
454     aSO  = _impl->FindObjectIOR(_orb->object_to_string(theObject));
455   }
456    
457   if(aSO.IsNull()) return CORBA::string_dup(aPath.c_str());
458   
459   aPath = _impl->GetObjectPath(aSO);
460   return  CORBA::string_dup(aPath.c_str());
461 }
462
463
464 //============================================================================
465 /*! Function : SetContext
466  *  Purpose  : Sets the current context
467  */
468 //============================================================================
469 void SALOMEDS_Study_i::SetContext(const char* thePath) 
470 {
471   SALOMEDS::Locker lock; 
472
473   _impl->SetContext(std::string((char*)thePath));
474   if(_impl->IsError() && _impl->GetErrorCode() == "InvalidContext") 
475     throw SALOMEDS::Study::StudyInvalidContext();  
476 }
477
478 //============================================================================
479 /*! Function : GetContext
480  *  Purpose  : Gets the current context
481  */
482 //============================================================================
483 char* SALOMEDS_Study_i::GetContext() 
484 {
485   SALOMEDS::Locker lock; 
486   
487   if(!_impl->HasCurrentContext()) throw SALOMEDS::Study::StudyInvalidContext();   
488   return CORBA::string_dup(_impl->GetContext().c_str());
489 }
490
491 //============================================================================
492 /*! Function : GetObjectNames
493  *  Purpose  : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
494  */
495 //============================================================================
496 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) 
497 {
498   SALOMEDS::Locker lock; 
499
500   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
501
502   if (strlen(theContext) == 0 && !_impl->HasCurrentContext())
503     throw SALOMEDS::Study::StudyInvalidContext();
504
505   std::vector<std::string> aSeq = _impl->GetObjectNames(std::string((char*)theContext));
506   if (_impl->GetErrorCode() == "InvalidContext")
507     throw SALOMEDS::Study::StudyInvalidContext();
508
509   int aLength = aSeq.size();
510   aResult->length(aLength);
511   for (int anIndex = 0; anIndex < aLength; anIndex++) {
512     aResult[anIndex] = CORBA::string_dup(aSeq[anIndex].c_str());
513   }
514
515   return aResult._retn();
516 }
517
518 //============================================================================
519 /*! Function : GetDirectoryNames
520  *  Purpose  : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
521  */
522 //============================================================================
523 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) 
524 {
525   SALOMEDS::Locker lock; 
526
527   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
528
529   if (strlen(theContext) == 0 && !_impl->HasCurrentContext())
530     throw SALOMEDS::Study::StudyInvalidContext();
531
532   std::vector<std::string> aSeq = _impl->GetDirectoryNames(std::string((char*)theContext));
533   if (_impl->GetErrorCode() == "InvalidContext")
534     throw SALOMEDS::Study::StudyInvalidContext();
535
536   int aLength = aSeq.size();
537   aResult->length(aLength);
538   for (int anIndex = 0; anIndex < aLength; anIndex++) {
539     aResult[anIndex] = CORBA::string_dup(aSeq[anIndex].c_str());
540   }
541
542   return aResult._retn();
543 }
544
545 //============================================================================
546 /*! Function : GetFileNames
547  *  Purpose  : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
548  */
549 //============================================================================
550 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) 
551 {
552   SALOMEDS::Locker lock; 
553
554   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
555
556   if (strlen(theContext) == 0 && !_impl->HasCurrentContext())
557     throw SALOMEDS::Study::StudyInvalidContext();
558
559   std::vector<std::string> aSeq = _impl->GetFileNames(std::string((char*)theContext));
560   if (_impl->GetErrorCode() == "InvalidContext")
561     throw SALOMEDS::Study::StudyInvalidContext();
562
563   int aLength = aSeq.size();
564   aResult->length(aLength);
565   for (int anIndex = 0; anIndex < aLength; anIndex++) {
566     aResult[anIndex] = CORBA::string_dup(aSeq[anIndex].c_str());
567   }
568
569   return aResult._retn();
570 }
571
572 //============================================================================
573 /*! Function : GetComponentNames
574  *  Purpose  : method to get all components names
575  *  SRN:       Note, theContext can be any, it doesn't matter
576  */
577 //============================================================================
578 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) 
579 {
580   SALOMEDS::Locker lock; 
581
582   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
583
584   std::vector<std::string> aSeq = _impl->GetComponentNames(std::string((char*)theContext));
585
586   int aLength = aSeq.size();
587   aResult->length(aLength);
588   for(int anIndex = 0; anIndex < aLength; anIndex++) {
589     aResult[anIndex] = CORBA::string_dup(aSeq[anIndex].c_str());
590   }
591
592   return aResult._retn();
593 }
594
595 //============================================================================
596 /*! Function : NewChildIterator
597  *  Purpose  : Create a ChildIterator from an SObject
598  */
599 //============================================================================
600 SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr theSO)
601 {
602   SALOMEDS::Locker lock; 
603
604   CORBA::String_var anID=theSO->GetID();
605   SALOMEDSImpl_SObject aSO = _impl->GetSObject(anID.in());
606   SALOMEDSImpl_ChildIterator anItr(aSO);
607
608   //Create iterator
609   SALOMEDS_ChildIterator_i* it_servant = new SALOMEDS_ChildIterator_i(anItr, _orb);
610
611   return it_servant->_this();
612 }
613
614
615 //============================================================================
616 /*! Function : NewComponentIterator
617  *  Purpose  : Create a SComponentIterator
618  */
619 //============================================================================
620 SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
621 {
622   SALOMEDS::Locker lock; 
623   SALOMEDS_SComponentIterator_i* _it = new SALOMEDS_SComponentIterator_i(_impl->NewComponentIterator(), _orb);
624   _it->Init();
625   return _it->_this();
626 }
627
628
629 //============================================================================
630 /*! Function : NewBuilder
631  *  Purpose  : Create a StudyBuilder
632  */
633 //============================================================================
634 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
635 {
636   SALOMEDS::Locker lock; 
637   return _builder->_this();
638 }
639  
640 //============================================================================
641 /*! Function : Name
642  *  Purpose  : get study name
643  */
644 //============================================================================
645 char* SALOMEDS_Study_i::Name()
646 {
647   SALOMEDS::Locker lock; 
648   return CORBA::string_dup(_impl->Name().c_str());
649 }
650
651 //============================================================================
652 /*! Function : Name
653  *  Purpose  : set study name
654  */
655 //============================================================================
656 void SALOMEDS_Study_i::Name(const char* name)
657 {
658   SALOMEDS::Locker lock;  
659   _impl->Name(std::string(name));
660 }
661
662 //============================================================================
663 /*! Function : IsSaved
664  *  Purpose  : get if study has been saved
665  */
666 //============================================================================
667 CORBA::Boolean  SALOMEDS_Study_i::IsSaved()
668 {
669   SALOMEDS::Locker lock; 
670   return _impl->IsSaved();
671 }
672
673 //============================================================================
674 /*! Function : IsSaved
675  *  Purpose  : set if study has been saved
676  */
677 //============================================================================
678 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
679 {
680   SALOMEDS::Locker lock; 
681   _impl->IsSaved(save);
682 }
683
684 //============================================================================
685 /*! Function : IsModified
686  *  Purpose  : Detect if a Study has been modified since it has been saved
687  */
688 //============================================================================
689 CORBA::Boolean  SALOMEDS_Study_i::IsModified()
690 {
691   SALOMEDS::Locker lock; 
692   return _impl->IsModified();
693 }
694
695 //============================================================================
696 /*! Function : Modified
697  *  Purpose  : Sets a Modified flag of a Study to True
698  */
699 //============================================================================
700 void  SALOMEDS_Study_i::Modified()
701 {
702   SALOMEDS::Locker lock; 
703   return _impl->Modify();
704 }
705
706
707 //============================================================================
708 /*! Function : URL
709  *  Purpose  : get URL of the study (persistent reference of the study)
710  */
711 //============================================================================
712 char* SALOMEDS_Study_i::URL()
713 {
714   SALOMEDS::Locker lock; 
715   return CORBA::string_dup(_impl->URL().c_str());
716 }
717
718 //============================================================================
719 /*! Function : URL
720  *  Purpose  : set URL of the study (persistent reference of the study)
721  */
722 //============================================================================
723 void SALOMEDS_Study_i::URL(const char* url)
724 {
725   SALOMEDS::Locker lock; 
726   _impl->URL(std::string((char*)url));
727 }
728
729
730 CORBA::Short SALOMEDS_Study_i::StudyId()
731 {
732   SALOMEDS::Locker lock; 
733   return _impl->StudyId();
734 }
735
736 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
737
738   SALOMEDS::Locker lock; 
739   _impl->StudyId(id);
740 }
741
742 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) 
743 {
744   SALOMEDS::Locker lock; 
745   _impl->UpdateIORLabelMap(std::string((char*)anIOR), std::string((char*)anEntry));
746 }
747
748 SALOMEDS::Study_ptr SALOMEDS_Study_i::GetStudy(const DF_Label& theLabel, CORBA::ORB_ptr orb) 
749 {
750   SALOMEDS::Locker lock; 
751
752   SALOMEDSImpl_AttributeIOR* Att = NULL;
753   if ((Att=(SALOMEDSImpl_AttributeIOR*)theLabel.Root().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))){
754     char* IOR = CORBA::string_dup(Att->Value().c_str());
755     CORBA::Object_var obj = orb->string_to_object(IOR);
756     SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
757     ASSERT(!CORBA::is_nil(aStudy));
758     return SALOMEDS::Study::_duplicate(aStudy);
759   } else {
760     MESSAGE("GetStudy: Problem to get study");
761   }
762   return SALOMEDS::Study::_nil();
763 }
764
765 SALOMEDS_Study_i* SALOMEDS_Study_i::GetStudyServant(SALOMEDSImpl_Study* aStudyImpl, CORBA::ORB_ptr orb)
766 {
767   if (_mapOfStudies.find(aStudyImpl) != _mapOfStudies.end()) 
768     return _mapOfStudies[aStudyImpl];
769   else
770     {
771       SALOMEDS_Study_i *Study_servant = new SALOMEDS_Study_i(aStudyImpl, orb);
772       _mapOfStudies[aStudyImpl]=Study_servant;
773       return Study_servant;
774     }
775 }
776
777 void SALOMEDS_Study_i::IORUpdated(SALOMEDSImpl_AttributeIOR* theAttribute) 
778 {
779   SALOMEDS::Locker lock; 
780   SALOMEDSImpl_Study::IORUpdated(theAttribute);
781 }
782
783 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) 
784 {
785   SALOMEDS::Locker lock; 
786
787   SALOMEDS::GenericAttribute_ptr aTarget;
788   if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
789     return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
790   }
791   SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
792   aList->length(0);
793   return aList;
794 }
795
796
797 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() 
798 {
799   SALOMEDS::Locker lock; 
800   
801   SALOMEDSImpl_AttributeStudyProperties* anAttr = _impl->GetProperties();
802   SALOMEDS_AttributeStudyProperties_i* SP = new SALOMEDS_AttributeStudyProperties_i(anAttr, _orb);
803   return SP->AttributeStudyProperties::_this();
804 }
805
806 char* SALOMEDS_Study_i::GetLastModificationDate() 
807 {
808   SALOMEDS::Locker lock; 
809   return CORBA::string_dup(_impl->GetLastModificationDate().c_str());
810 }
811
812 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() 
813 {
814   SALOMEDS::Locker lock; 
815   
816   std::vector<std::string> aSeq = _impl->GetModificationsDate();
817   int aLength = aSeq.size();
818   SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
819   aDates->length(aLength);
820
821   for(int anIndex = 0; anIndex < aLength; anIndex++) {
822     aDates[anIndex] = CORBA::string_dup(aSeq[anIndex].c_str());
823   }
824   return aDates._retn();
825 }
826
827
828
829 //============================================================================
830 /*! Function : GetUseCaseBuilder
831  *  Purpose  : Returns a UseCase builder
832  */
833 //============================================================================
834 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder() 
835 {
836   SALOMEDS::Locker lock; 
837   SALOMEDS_UseCaseBuilder_i* UCBuilder = new SALOMEDS_UseCaseBuilder_i(_impl->GetUseCaseBuilder(), _orb);
838   return UCBuilder->_this();
839 }
840
841
842 //============================================================================
843 /*! Function : Close
844  *  Purpose  : 
845  */
846 //============================================================================
847 void SALOMEDS_Study_i::Close()
848 {
849   SALOMEDS::Locker lock; 
850
851   RemovePostponed(-1);
852
853   SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
854   for (; itcomponent->More(); itcomponent->Next()) {
855     SALOMEDS::SComponent_var sco = itcomponent->Value();
856     CORBA::String_var compodatatype=sco->ComponentDataType();
857     MESSAGE ( "Look for an engine for data type :"<< compodatatype);
858     // if there is an associated Engine call its method for closing
859     CORBA::String_var IOREngine;
860     if (sco->ComponentIOR(IOREngine)) {
861       // we have found the associated engine to write the data 
862       MESSAGE ( "We have found an engine for data type :"<< compodatatype);
863       //_narrow can throw a corba exception
864       try
865         {
866           CORBA::Object_var obj = _orb->string_to_object(IOREngine);
867           if (!CORBA::is_nil(obj)) 
868             {
869               SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
870               if (!anEngine->_is_nil()) 
871                 { 
872                   SALOMEDS::unlock();
873                   anEngine->Close(sco);
874                   SALOMEDS::lock();
875                 }
876             }
877         } 
878       catch (CORBA::Exception&) 
879         {/*pass*/ }
880     }
881     sco->UnRegister();
882   }
883
884   //Does not need any more this iterator
885   itcomponent->UnRegister();
886
887
888   _impl->Close();
889 }
890
891 //============================================================================
892 /*! Function : AddPostponed
893  *  Purpose  : 
894  */
895  //============================================================================
896 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) 
897 {
898   SALOMEDS::Locker lock; 
899   //Not implemented
900 }
901
902 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) 
903 {
904   SALOMEDS::Locker lock; 
905   //Not implemented
906 }
907
908 //============================================================================
909 /*! Function : RemovePostponed
910  *  Purpose  : 
911  */
912 //============================================================================
913 #ifndef WIN32
914 void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long /*theUndoLimit*/) 
915 #else
916 void SALOMEDS_Study_i::RemovePostponed(CORBA::Long /*theUndoLimit*/) 
917 #endif
918 {  
919   SALOMEDS::Locker lock; 
920
921   std::vector<std::string> anIORs = _impl->GetIORs();
922   int i, aSize = (int)anIORs.size();
923
924   for(i = 0; i < aSize; i++) {
925     try {
926       CORBA::Object_var obj = _orb->string_to_object(anIORs[i].c_str());
927       SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
928           //rnv: To avoid double deletion of the Salome Generic Objects:
929           //rnv: 1. First decrement of the reference count in the SALOMEDSImpl_AttributeIOR::~SALOMEDSImpl_AttributeIOR();
930           //rnv: 2. Second decrement of the reference count in the next string : aGeneric->UnRegister();
931       //if (!CORBA::is_nil(aGeneric)) aGeneric->UnRegister();
932     } catch (...) {}
933   }
934
935   //Not implemented
936 }
937
938 //============================================================================
939 /*! Function : UndoPostponed
940  *  Purpose  : 
941  */
942 //============================================================================
943 #ifndef WIN32
944 void SALOMEDS_Study_i::UndoPostponed(const CORBA::Long theWay) 
945 #else
946 void SALOMEDS_Study_i::UndoPostponed(CORBA::Long theWay) 
947 #endif
948 {
949   SALOMEDS::Locker lock; 
950   //Not implemented
951 }
952
953
954 //============================================================================
955 /*! Function : DumpStudy
956  *  Purpose  : 
957  */
958 //============================================================================
959 CORBA::Boolean SALOMEDS_Study_i::DumpStudy(const char* thePath, 
960                                            const char* theBaseName, 
961                                            CORBA::Boolean isPublished,
962                                            CORBA::Boolean isMultiFile)
963 {
964   SALOMEDS::Locker lock; 
965
966   std::string aPath((char*)thePath), aBaseName((char*)theBaseName);
967   SALOMEDS_DriverFactory_i* factory = new SALOMEDS_DriverFactory_i(_orb);
968   CORBA::Boolean ret = _impl->DumpStudy(aPath, aBaseName, isPublished, isMultiFile, factory);
969   delete factory;
970   return ret;
971 }
972
973 //============================================================================
974 /*! Function : GetCommonParameters
975  *  Purpose  : 
976  */
977 //============================================================================
978 SALOMEDS::AttributeParameter_ptr SALOMEDS_Study_i::GetCommonParameters(const char* theID, CORBA::Long theSavePoint)
979 {
980   SALOMEDS::Locker lock; 
981   
982   SALOMEDSImpl_AttributeParameter* anAttr = _impl->GetCommonParameters(theID, theSavePoint);
983   SALOMEDS_AttributeParameter_i* SP = new SALOMEDS_AttributeParameter_i(anAttr, _orb);
984   return SP->AttributeParameter::_this();
985 }
986  
987 //============================================================================
988 /*! Function : GetCommonModuleParameters
989  *  Purpose  : 
990  */
991 //============================================================================
992 SALOMEDS::AttributeParameter_ptr SALOMEDS_Study_i::GetModuleParameters(const char* theID, 
993                                                                        const char* theModuleName, 
994                                                                        CORBA::Long theSavePoint)
995 {
996   SALOMEDS::Locker lock; 
997   
998   SALOMEDSImpl_AttributeParameter* anAttr = _impl->GetModuleParameters(theID, theModuleName, theSavePoint);
999   SALOMEDS_AttributeParameter_i* SP = new SALOMEDS_AttributeParameter_i(anAttr, _orb);
1000   return SP->AttributeParameter::_this();
1001 }
1002
1003 //============================================================================
1004 /*! Function : SetStudyLock
1005  *  Purpose  : 
1006  */
1007 //============================================================================
1008 void SALOMEDS_Study_i::SetStudyLock(const char* theLockerID)
1009 {
1010   SALOMEDS::Locker lock; 
1011   _impl->SetStudyLock(theLockerID);
1012 }
1013
1014 //============================================================================
1015 /*! Function : IsStudyLocked
1016  *  Purpose  : 
1017  */
1018 //============================================================================
1019 bool SALOMEDS_Study_i::IsStudyLocked()
1020 {
1021   SALOMEDS::Locker lock; 
1022   return _impl->IsStudyLocked();
1023 }
1024
1025 //============================================================================
1026 /*! Function : UnLockStudy
1027  *  Purpose  : 
1028  */
1029 //============================================================================
1030 void SALOMEDS_Study_i::UnLockStudy(const char* theLockerID)
1031 {
1032   SALOMEDS::Locker lock; 
1033   _impl->UnLockStudy(theLockerID);
1034 }
1035
1036 //============================================================================
1037 /*! Function : GetLockerID
1038  *  Purpose  : 
1039  */
1040 //============================================================================
1041 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetLockerID()
1042 {
1043   SALOMEDS::Locker lock; 
1044
1045   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
1046
1047   std::vector<std::string> aSeq = _impl->GetLockerID();
1048
1049   int aLength = aSeq.size();
1050   aResult->length(aLength);
1051   for(int anIndex = 0; anIndex < aLength; anIndex++) {
1052     aResult[anIndex] = CORBA::string_dup(aSeq[anIndex].c_str());
1053   }
1054   return aResult._retn();
1055 }
1056 //============================================================================
1057 /*! Function : SetReal
1058  *  Purpose  : 
1059  */
1060 //============================================================================
1061 void SALOMEDS_Study_i::SetReal(const char* theVarName, CORBA::Double theValue)
1062 {
1063   _impl->SetVariable(std::string(theVarName), 
1064                      theValue,
1065                      SALOMEDSImpl_GenericVariable::REAL_VAR);
1066   if(_notifier)
1067     _notifier->modifyNB_Notification(theVarName);
1068 }
1069
1070 //============================================================================
1071 /*! Function : SetInteger
1072  *  Purpose  : 
1073  */
1074 //============================================================================
1075 void SALOMEDS_Study_i::SetInteger(const char* theVarName, CORBA::Long theValue)
1076 {
1077   _impl->SetVariable(std::string(theVarName), 
1078                      theValue,
1079                      SALOMEDSImpl_GenericVariable::INTEGER_VAR);
1080   if(_notifier)
1081     _notifier->modifyNB_Notification(theVarName);
1082 }
1083
1084 //============================================================================
1085 /*! Function : SetBoolean
1086  *  Purpose  : 
1087  */
1088 //============================================================================
1089 void SALOMEDS_Study_i::SetBoolean(const char* theVarName, CORBA::Boolean theValue)
1090 {
1091   _impl->SetVariable(std::string(theVarName), 
1092                      theValue,
1093                      SALOMEDSImpl_GenericVariable::BOOLEAN_VAR);
1094   if(_notifier)
1095     _notifier->modifyNB_Notification(theVarName);
1096 }
1097
1098 //============================================================================
1099 /*! Function : SetString
1100  *  Purpose  : 
1101  */
1102 //============================================================================
1103 void SALOMEDS_Study_i::SetString(const char* theVarName, const char* theValue)
1104 {
1105   _impl->SetStringVariable(std::string(theVarName), 
1106                            theValue,
1107                            SALOMEDSImpl_GenericVariable::STRING_VAR);
1108   if(_notifier)
1109     _notifier->modifyNB_Notification(theVarName);
1110 }
1111
1112 //============================================================================
1113 /*! Function : SetStringAsDouble
1114  *  Purpose  : 
1115  */
1116 //============================================================================
1117 void SALOMEDS_Study_i::SetStringAsDouble(const char* theVarName, CORBA::Double theValue)
1118 {
1119   _impl->SetStringVariableAsDouble(std::string(theVarName), 
1120                                    theValue,
1121                                    SALOMEDSImpl_GenericVariable::STRING_VAR);
1122 }
1123
1124 //============================================================================
1125 /*! Function : GetReal
1126  *  Purpose  : 
1127  */
1128 //============================================================================
1129 CORBA::Double SALOMEDS_Study_i::GetReal(const char* theVarName)
1130 {
1131   return _impl->GetVariableValue(std::string(theVarName));
1132 }
1133
1134 //============================================================================
1135 /*! Function : GetInteger
1136  *  Purpose  : 
1137  */
1138 //============================================================================
1139 CORBA::Long SALOMEDS_Study_i::GetInteger(const char* theVarName)
1140 {
1141   return (int)_impl->GetVariableValue(std::string(theVarName));
1142 }
1143
1144 //============================================================================
1145 /*! Function : GetBoolean
1146  *  Purpose  : 
1147  */
1148 //============================================================================
1149 CORBA::Boolean SALOMEDS_Study_i::GetBoolean(const char* theVarName)
1150 {
1151   return (bool)_impl->GetVariableValue(std::string(theVarName));
1152 }
1153
1154 //============================================================================
1155 /*! Function : GetString
1156  *  Purpose  : 
1157  */
1158 //============================================================================
1159 char* SALOMEDS_Study_i::GetString(const char* theVarName)
1160 {
1161   return CORBA::string_dup(_impl->GetStringVariableValue(std::string(theVarName)).c_str());
1162 }
1163
1164 //============================================================================
1165 /*! Function : IsReal
1166  *  Purpose  : 
1167  */
1168 //============================================================================
1169 CORBA::Boolean SALOMEDS_Study_i::IsReal(const char* theVarName)
1170 {
1171   return _impl->IsTypeOf(std::string(theVarName),
1172                          SALOMEDSImpl_GenericVariable::REAL_VAR);
1173 }
1174
1175 //============================================================================
1176 /*! Function : IsInteger
1177  *  Purpose  : 
1178  */
1179 //============================================================================
1180 CORBA::Boolean SALOMEDS_Study_i::IsInteger(const char* theVarName)
1181 {
1182   return _impl->IsTypeOf(std::string(theVarName),
1183                          SALOMEDSImpl_GenericVariable::INTEGER_VAR);
1184 }
1185
1186 //============================================================================
1187 /*! Function : IsBoolean
1188  *  Purpose  : 
1189  */
1190 //============================================================================
1191 CORBA::Boolean SALOMEDS_Study_i::IsBoolean(const char* theVarName)
1192 {
1193   return _impl->IsTypeOf(std::string(theVarName),
1194                          SALOMEDSImpl_GenericVariable::BOOLEAN_VAR);
1195 }
1196
1197 //============================================================================
1198 /*! Function : IsString
1199  *  Purpose  : 
1200  */
1201 //============================================================================
1202 CORBA::Boolean SALOMEDS_Study_i::IsString(const char* theVarName)
1203 {
1204   return _impl->IsTypeOf(std::string(theVarName),
1205                          SALOMEDSImpl_GenericVariable::STRING_VAR);
1206 }
1207
1208 //============================================================================
1209 /*! Function : IsVariable
1210  *  Purpose  : 
1211  */
1212 //============================================================================
1213 CORBA::Boolean SALOMEDS_Study_i::IsVariable(const char* theVarName)
1214 {
1215   return _impl->IsVariable(std::string(theVarName));
1216 }
1217
1218 //============================================================================
1219 /*! Function : GetVariableNames
1220  *  Purpose  : 
1221  */
1222 //============================================================================
1223 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetVariableNames()
1224 {
1225   std::vector<std::string> aVarNames = _impl->GetVariableNames();
1226   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
1227   
1228   int aLen = aVarNames.size();
1229   aResult->length(aLen);
1230   
1231   for (int anInd = 0; anInd < aLen; anInd++)
1232     aResult[anInd] = CORBA::string_dup(aVarNames[anInd].c_str());
1233   
1234   return aResult._retn();
1235 }
1236
1237 //============================================================================
1238 /*! Function : RemoveVariable
1239  *  Purpose  : 
1240  */
1241 //============================================================================
1242 CORBA::Boolean SALOMEDS_Study_i::RemoveVariable(const char* theVarName)
1243 {
1244   CORBA::Boolean res = _impl->RemoveVariable(std::string(theVarName));
1245   if(res && _notifier)
1246     _notifier->modifyNB_Notification(theVarName);
1247   return res;
1248 }
1249
1250 //============================================================================
1251 /*! Function : RenameVariable
1252  *  Purpose  : 
1253  */
1254 //============================================================================
1255 CORBA::Boolean SALOMEDS_Study_i::RenameVariable(const char* theVarName, const char* theNewVarName)
1256 {
1257   CORBA::Boolean res = _impl->RenameVariable(std::string(theVarName), std::string(theNewVarName));
1258   if(res && _notifier)
1259     _notifier->modifyNB_Notification(theVarName);
1260   return res;
1261 }
1262
1263 //============================================================================
1264 /*! Function : IsVariableUsed
1265  *  Purpose  : 
1266  */
1267 //============================================================================
1268 CORBA::Boolean SALOMEDS_Study_i::IsVariableUsed(const char* theVarName)
1269 {
1270   return _impl->IsVariableUsed(std::string(theVarName));
1271 }
1272
1273
1274 //============================================================================
1275 /*! Function : ParseVariables
1276  *  Purpose  : 
1277  */
1278 //============================================================================
1279 SALOMEDS::ListOfListOfStrings* SALOMEDS_Study_i::ParseVariables(const char* theVarName)
1280 {
1281   std::vector< std::vector<std::string> > aSections = _impl->ParseVariables(std::string(theVarName));
1282
1283   SALOMEDS::ListOfListOfStrings_var aResult = new SALOMEDS::ListOfListOfStrings;
1284
1285   int aSectionsLen = aSections.size();
1286   aResult->length(aSectionsLen);
1287
1288   for (int aSectionInd = 0; aSectionInd < aSectionsLen; aSectionInd++) {
1289     std::vector<std::string> aVarNames = aSections[aSectionInd];
1290
1291     SALOMEDS::ListOfStrings_var aList = new SALOMEDS::ListOfStrings;
1292
1293     int aLen = aVarNames.size();
1294     aList->length(aLen);
1295
1296     for (int anInd = 0; anInd < aLen; anInd++)
1297       aList[anInd] = CORBA::string_dup(aVarNames[anInd].c_str());
1298
1299     aResult[aSectionInd] = aList;
1300   }
1301
1302   return aResult._retn();
1303 }
1304
1305 //============================================================================
1306 /*! Function : GetDefaultScript
1307  *  Purpose  : 
1308  */
1309 //============================================================================
1310 char* SALOMEDS_Study_i::GetDefaultScript(const char* theModuleName, const char* theShift)
1311 {
1312   SALOMEDS::Locker lock; 
1313
1314   std::string script = SALOMEDSImpl_IParameters::getDefaultScript(_impl, theModuleName, theShift);
1315   return CORBA::string_dup(script.c_str());
1316 }
1317
1318 //============================================================================
1319 /*! Function : EnableUseCaseAutoFilling
1320  *  Purpose  : 
1321  */
1322 //============================================================================
1323 void SALOMEDS_Study_i::EnableUseCaseAutoFilling(CORBA::Boolean isEnabled) 
1324
1325   _impl->EnableUseCaseAutoFilling(isEnabled); 
1326   SALOMEDSImpl_StudyBuilder* builder = _builder->GetImpl();
1327   if(builder) {
1328     if(isEnabled) {
1329       builder->SetOnAddSObject(_impl->GetCallback());
1330       builder->SetOnRemoveSObject(_impl->GetCallback());
1331     }
1332     else {
1333       builder->SetOnAddSObject(NULL);
1334       builder->SetOnRemoveSObject(NULL);
1335     }
1336   }
1337 }
1338
1339 //============================================================================
1340 /*! Function : attach
1341  *  Purpose  : This function attach an observer to the study
1342  */
1343 //============================================================================
1344 void SALOMEDS_Study_i::attach(SALOMEDS::Observer_ptr theObs,CORBA::Boolean modify)
1345 {
1346   if(_notifier)
1347     static_cast<SALOMEDS::Notifier*>(_notifier)->attach(theObs,modify);
1348 }
1349
1350
1351 //============================================================================
1352 /*! Function : detach
1353  *  Purpose  : This function detaches an observer from the study
1354  */
1355 //============================================================================
1356 void SALOMEDS_Study_i::detach(SALOMEDS::Observer_ptr theObs)
1357 {
1358   if(_notifier)
1359     static_cast<SALOMEDS::Notifier*>(_notifier)->detach(theObs);
1360 }
1361
1362 //===========================================================================
1363 //   PRIVATE FUNCTIONS
1364 //===========================================================================
1365 CORBA::LongLong SALOMEDS_Study_i::GetLocalImpl(const char* theHostname, CORBA::Long thePID, CORBA::Boolean& isLocal)
1366 {
1367 #ifdef WIN32
1368   long pid = (long)_getpid();
1369 #else
1370   long pid = (long)getpid();
1371 #endif  
1372   isLocal = (strcmp(theHostname, Kernel_Utils::GetHostname().c_str()) == 0 && pid == thePID)?1:0;
1373   return reinterpret_cast<CORBA::LongLong>(_impl);
1374 }