Salome HOME
Fix on [Bug PAL7750] Regression of UNDO in GEOM
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_Study_i.cxx
index be15994347673fc38892da5a5296114cb5d3b016..1f8e0aa75067bc52597819a1a6e0a3bb702dd13a 100644 (file)
 //  Module : SALOME
 //  $Header$
 
-using namespace std;
-#include "utilities.h"
-#include "SALOMEDS_Study_i.hxx"
-
-#include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
-#include <TColStd_SequenceOfExtendedString.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <TCollection_ExtendedString.hxx>
 #include <TDataStd_ChildNodeIterator.hxx>
 #include <TDocStd_Application.hxx>
 #include <TDocStd_Owner.hxx>
 #include <CDM_Document.hxx>
 #include <CDM_Application.hxx>
 #include <TDF_ChildIDIterator.hxx>
-#include <SALOME_GenericObj_i.hh>
+
+#include <TColStd_SequenceOfExtendedString.hxx>
+#include <TCollection_ExtendedString.hxx>
+#include <TCollection_AsciiString.hxx>
+
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_ListOfInteger.hxx>
+
+#include "SALOMEDS_Study_i.hxx"
+
+#include "SALOMEDS_StudyManager_i.hxx"
+#include "SALOMEDS_Callback_i.hxx"
+
+#include "SALOMEDS_SComponent_i.hxx"
+#include "SALOMEDS_SObject_i.hxx"
+
+#include "SALOMEDS_StudyBuilder_i.hxx"
+#include "SALOMEDS_ChildIterator_i.hxx"
+
+#include "SALOMEDS_UseCaseBuilder_i.hxx"
+#include "SALOMEDS_SComponentIterator_i.hxx"
+
+#include "SALOME_GenericObj_i.hh"
 #include "SALOMEDS_LocalIDAttribute.hxx"
 #include "SALOMEDS_PersRefAttribute.hxx"
-#include "SALOMEDS_UseCaseIterator_i.hxx"
 
+#include "SALOMEDS_StudyPropertiesAttribute.hxx"
+#include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
+
+#include "utilities.h"
 
 #define DIRECTORYID 16661
 #define FILEID "FILE: "
 #define FILELOCALID 26662 
 
+using namespace std;
+
+bool operator<(const TDF_Label& theLeft, const TDF_Label& theRight)
+{
+  TColStd_ListOfInteger aTagLeftList;
+  TDF_Tool::TagList(theLeft,aTagLeftList);
+  TColStd_ListIteratorOfListOfInteger anLeftIter(aTagLeftList);
+  
+  TColStd_ListOfInteger aTagRightList;
+  TDF_Tool::TagList(theRight,aTagRightList);
+  TColStd_ListIteratorOfListOfInteger anRightIter(aTagRightList);
+  
+  for(;;){
+    Standard_Boolean aLeftMore = anLeftIter.More();
+    Standard_Boolean aRightMore = anRightIter.More();
+    
+    if(!aLeftMore && !aRightMore)
+      return Standard_False;
+    
+    if(!aLeftMore)
+      return Standard_True;
+    
+    if(!aRightMore)
+      return Standard_False;
+    
+    Standard_Integer aLeftTag = anLeftIter.Value();
+    anLeftIter.Next();
+    
+    Standard_Integer aRightTag = anRightIter.Value();
+    anRightIter.Next();
+    
+    if(aLeftTag == aRightTag)
+      continue;
+    
+    return aLeftTag < aRightTag;
+  }
+  
+  return Standard_False;
+}
+
+  
 //============================================================================
 /*! Function : SALOMEDS_Study_i
  *  Purpose  : SALOMEDS_Study_i constructor
  */
 //============================================================================
-SALOMEDS_Study_i::SALOMEDS_Study_i(const Handle(TDocStd_Document) doc,
-                                  CORBA::ORB_ptr                 orb,
-                                  const char* study_name)
+SALOMEDS_Study_i::SALOMEDS_Study_i(SALOMEDS_StudyManager_i* theStudyManager,
+                                  const Handle(TDocStd_Document)& theDoc,
+                                  const char* theStudyName):
+  _StudyManager(theStudyManager),
+  _doc(theDoc),
+  _isSaved(false),
+  _URL(NULL),
+  _StudyId(-1),
+  _autoFill(true),
+  myNbUndos(0)
 {
-  _orb = CORBA::ORB::_duplicate(orb);
-  _doc = doc;
-  _name = new char[strlen(study_name) +1];
-  strcpy(_name,study_name);
-  _isSaved = false ;
-  _URL = NULL;
-  _StudyId = -1;
-  _autoFill = true;
+  _UseCaseBuilder = new SALOMEDS_UseCaseBuilder_i(this,_doc);
+  SALOMEDS::UseCaseBuilder_var aUseCaseBuilder = _UseCaseBuilder->_this();
+
+  _Builder = new SALOMEDS_StudyBuilder_i(this,_doc);
+  SALOMEDS::StudyBuilder_var aStudyBuilder = _Builder->_this(); 
+
+  SALOMEDS_Callback_i* aCallBackServant = new SALOMEDS_Callback_i(aUseCaseBuilder);
+  _callbackOnAdd = aCallBackServant->_this();
+  _callbackOnRemove = _callbackOnAdd;
+
+  _name = new char[strlen(theStudyName) +1];
+  strcpy(_name,theStudyName);
   myNbPostponed.Append(0);
-  myNbUndos = 0;
 }
   
 //============================================================================
@@ -82,6 +150,96 @@ SALOMEDS_Study_i::~SALOMEDS_Study_i()
   delete [] _URL ;
 }  
 
+//============================================================================
+CORBA::ORB_var SALOMEDS_Study_i::GetORB() const
+{
+  return _StudyManager->GetORB();
+}
+
+//============================================================================
+PortableServer::POA_var SALOMEDS_Study_i::GetPOA() const
+{
+  return _StudyManager->GetPOA();
+}
+
+
+SALOMEDS_SObject_i* 
+SALOMEDS_Study_i::DownCast(SALOMEDS::SObject_ptr theSObject) const
+{
+  if(!CORBA::is_nil(theSObject)){
+    PortableServer::POA_var aPOA = GetPOA();
+    PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theSObject,aPOA);
+    if(aServant.in())
+      return dynamic_cast<SALOMEDS_SObject_i*>(aServant.in());
+  }
+  return NULL;
+}
+
+//============================================================================
+/*! Function : SetOnAddSObject
+ *  Purpose  : 
+ */
+//============================================================================
+SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
+{
+  SALOMEDS::Callback_var aRet = _callbackOnAdd;
+  _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
+  return aRet._retn();
+}
+
+//============================================================================
+/*! Function : SetOnNewSObject
+ *  Purpose  : 
+ */
+//============================================================================
+SALOMEDS::Callback_ptr SALOMEDS_Study_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
+{
+  SALOMEDS::Callback_var aRet = _callbackOnRemove;
+  _callbackOnAdd = SALOMEDS::Callback::_duplicate(theCallback);
+  return aRet._retn();
+}
+
+//============================================================================
+void SALOMEDS_Study_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
+{
+  if(!CORBA::is_nil(_callbackOnAdd.in()))
+    _callbackOnAdd->OnAddSObject(theObject);
+}
+
+//============================================================================
+void SALOMEDS_Study_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
+{
+  if(!CORBA::is_nil(_callbackOnRemove.in()))
+    _callbackOnRemove->OnRemoveSObject(theObject);
+}
+
+//============================================================================
+void SALOMEDS_Study_i::CheckLocked()
+{
+  if(_doc->HasOpenCommand()) 
+    return;
+
+  Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
+  if(_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(),anAttr))
+    if(anAttr->IsLocked())
+      throw SALOMEDS::StudyBuilder::LockProtection();
+}
+
+
+//============================================================================
+char* SALOMEDS_Study_i::ConvertObjectToIOR(CORBA::Object_ptr theObject)
+{
+  return GetORB()->object_to_string(theObject); 
+}
+
+
+//============================================================================
+CORBA::Object_ptr SALOMEDS_Study_i::ConvertIORToObject(const char* theIOR) 
+{ 
+  return GetORB()->string_to_object(theIOR); 
+}
+
+
 //============================================================================
 /*! Function : GetPersistentReference
  *  Purpose  : Get persistent reference of study (idem URL())
@@ -128,27 +286,21 @@ CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
  *  Purpose  : Find a Component with ComponentDataType = aComponentName
  */
 //============================================================================
-SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponent (const char* aComponentName)
+SALOMEDS::SComponent_ptr 
+SALOMEDS_Study_i::FindComponent(const char* theComponentName)
 {
-  bool _find = false;
-  Standard_CString name;
-  SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
-  SALOMEDS::SComponent_var compo;
-
-  for (; itcomp->More(); itcomp->Next()) {
-    SALOMEDS::SComponent_var SC = itcomp->Value();
-    name = SC->ComponentDataType();
-    //ED if ( TCollection_AsciiString(name).IsEqual(TCollection_AsciiString(strdup(aComponentName))) ) {
-    if(strcmp(aComponentName,name) == 0){
-      _find = true;
-      return SALOMEDS::SComponent::_narrow(SC); 
+  bool anIsFound = false;
+  SALOMEDS::SComponent_var aSComponent;
+  SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
+  for(; aComponentIter.More() && !anIsFound; aComponentIter.Next()){
+    SALOMEDS::SComponent_var aSComp = aComponentIter.Value();
+    CORBA::String_var aName = aSComp->ComponentDataType();
+    if(strcmp(theComponentName,aName.in()) == 0){
+      aSComponent = aSComp;
+      anIsFound = true;
     }
   }
-  if(!_find)
-    {
-      return SALOMEDS::SComponent::_nil();
-    }
-  return compo;
+  return aSComponent._retn();
 }
 
 //============================================================================
@@ -164,9 +316,9 @@ SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponen
   char *ID;
   SALOMEDS::SComponent_ptr compo;
 
-  SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
-  for (; itcomp->More(); itcomp->Next()) {
-    SALOMEDS::SComponent_var SC = itcomp->Value();
+  SALOMEDS_SComponentIterator_i itcomp(this,_doc);
+  for (; itcomp.More(); itcomp.Next()) {
+    SALOMEDS::SComponent_var SC = itcomp.Value();
     ID = SC->GetID();
     if(strcmp(aComponentID,ID)==0)
       {
@@ -187,34 +339,29 @@ SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponen
  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
  */
 //============================================================================
-SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* anObjectName)
+SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* theObjectName)
 {
   // Iterate to all components defined in the study
   // After testing the component name, iterate in all objects defined under
   // components (function _FindObject)
-  bool _find = false;
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  SALOMEDS::SComponentIterator_var it = NewComponentIterator();
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SComponent_var SC = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (SC->FindAttribute(anAttr,"AttributeName")) 
-       {
-         SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
-         CORBA::String_var Val = Name->Value();
-         if (strcmp(Val, anObjectName) == 0)
-           {
-             _find = true;
-             RefSO = SALOMEDS::SObject::_narrow(SC);
-           }
-       }
-       if (!_find) RefSO =  _FindObject(SC,anObjectName, _find);
+  bool aIsFound = false;
+  SALOMEDS::SObject_var aRefSO;
+  SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
+  for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
+    TDF_Label aLab = aComponentIter.GetValue();
+    Handle(TDataStd_Name) anAttr;
+    if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectName) == 0){
+       aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab)._retn();
+       aIsFound = true;
       }
+    }
+    if(!aIsFound) 
+      aRefSO = _FindObject(aLab,theObjectName,aIsFound);
   }
-  return RefSO;
+
+  return aRefSO._retn();
 }
 
 //============================================================================
@@ -228,10 +375,10 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
   TDF_Label Lab;
   TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab);
   
-  if (Lab.IsNull()) return SALOMEDS::SObject::_nil();
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (Lab,_orb);
-  SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-  return so;
+  if (Lab.IsNull()) 
+    return SALOMEDS::SObject::_nil();
+
+  return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
 
 }
 
@@ -246,11 +393,10 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
   TDF_Label Lab;
   TDF_Tool::Label(_doc->GetData(), (char*)anObjectID, Lab, Standard_True);
   
-  if (Lab.IsNull()) return SALOMEDS::SObject::_nil();
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (Lab,_orb);
-  SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-  return so;
+  if (Lab.IsNull()) 
+    return SALOMEDS::SObject::_nil();
 
+  return SALOMEDS_SObject_i::NewRef(this,Lab)._retn();
 }
 
 //============================================================================
@@ -259,54 +405,44 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::CreateObjectID(const char* anObjectID)
  *           : with ComponentDataType = aComponentName
  */
 //============================================================================
-SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
-                                                                   const char* aComponentName )
+SALOMEDS::Study::ListOfSObject* 
+SALOMEDS_Study_i::FindObjectByName(const char* theObjectName,
+                                  const char* theComponentName)
 {
-  SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
-  listSO->length(0);
-  
-  SALOMEDS::SComponent_ptr compo = FindComponent(aComponentName) ;
-  if ( compo->_is_nil() ) {
-    MESSAGE ("In FindObjectByName() :  Component named " << aComponentName << " not found ");
-    return listSO._retn();
+  SALOMEDS::Study::ListOfSObject_var aListOfSObj = new SALOMEDS::Study::ListOfSObject ;
+  aListOfSObj->length(0);
+
+  SALOMEDS::SComponent_ptr aSComponent = FindComponent(theComponentName) ;
+  if(aSComponent->_is_nil()){
+    MESSAGE ("In FindObjectByName() :  Component named " << theComponentName << " not found ");
+    return aListOfSObj._retn();
   }
 
   // Iterate on each object and subobject of the component
   // If objectName is found add it to the list of SObjects 
-  char *name;
-  char *childName ;
-  SALOMEDS::SObject_ptr addSO = SALOMEDS::SObject::_nil();
-
-  CORBA::String_var compoId = compo->GetID();
-  SALOMEDS::ChildIterator_var it = NewChildIterator(compo);
-  int length = 0 ;
-  for ( ; it->More();it->Next() ) {
-    
-    SALOMEDS::SObject_var CSO = it->Value();
-    SALOMEDS::GenericAttribute_var anAttr;
-    SALOMEDS::AttributeName_var    aName;
-    if ( CSO->FindAttribute(anAttr, "AttributeName") ) {
-      aName = SALOMEDS::AttributeName::_narrow(anAttr);
-      name = aName->Value();
-      if ( strcmp( name, anObjectName ) == 0) {
-       addSO = SALOMEDS::SObject::_narrow(CSO);
+  TDF_Label aLabel;
+  CORBA::String_var anEntry = aSComponent->GetID();
+  TDF_Tool::Label(_doc->GetData(),const_cast<char*>(anEntry.in()),aLabel);
+  
+  int aLength = 0 ;
+  SALOMEDS::SObject_var aRefSO;
+  TDF_ChildIterator aChildIter(aLabel,true);
+  for(; aChildIter.More(); aChildIter.Next()){
+    TDF_Label aLab = aChildIter.Value();
+    Handle(TDataStd_Name) anAttr;
+    if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectName) == 0){
+       aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab)._retn();
        /* add to list */
-       length++ ;
-       listSO->length(length);
-       listSO[length-1] = addSO ;
-      }
-      
-      /* looks also for eventual children */
-      bool found = false ;
-      addSO = _FindObject( CSO, anObjectName, found ) ;
-      if( found) {
-       length++ ;
-       listSO->length(length);
-       listSO[length-1] = addSO ;
+       aLength++ ;
+       aListOfSObj->length(aLength);
+       aListOfSObj[aLength-1] = aRefSO;
       }
     }
   }
-  return listSO._retn() ;
+
+  return aListOfSObj._retn() ;
 }
 
 
@@ -316,47 +452,48 @@ SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char*
  *  Purpose  : Find an Object with IOR = anObjectIOR
  */
 //============================================================================
-SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* anObjectIOR)
+SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* theObjectIOR)
 {
   // firstly searching in the datamap for optimization
-  CORBA::String_var anIOR = CORBA::string_dup(anObjectIOR);
-  if (myIORLabels.IsBound(TCollection_ExtendedString(anIOR))) {
-    SALOMEDS_SObject_i* aResult = new SALOMEDS_SObject_i(myIORLabels.Find(TCollection_ExtendedString(anIOR)),_orb);
+  char* anIOR = const_cast<char*>(theObjectIOR);
+  if(myIORLabels.IsBound(anIOR)){
+    TDF_Label aLabel = myIORLabels.Find(anIOR);
+    TSObjectHolder aSObjectHolder = SALOMEDS_SObject_i::New(this,aLabel);
+    SALOMEDS_SObject_i* aSObjectPtr = aSObjectHolder.first;
+    SALOMEDS::SObject_var aSObject = aSObjectHolder.second;
     // 11 oct 2002: forbidden attributes must be checked here
     SALOMEDS::GenericAttribute_var anAttr;
-    if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
-      myIORLabels.UnBind(TCollection_ExtendedString(anIOR));
-    } else return aResult->_this();
+    if(!aSObjectPtr->FindAttribute(anAttr,"AttributeIOR")){
+      myIORLabels.UnBind(anIOR);
+    }else{
+      return aSObject._retn();
+    }
   }
+
   // Iterate to all components defined in the study
   // After testing the component name, iterate in all objects defined under
   // components (function _FindObject)
-  bool _find = false;
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  SALOMEDS::SComponentIterator_var it = NewComponentIterator();
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SComponent_var SC = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (SC->FindAttribute(anAttr,"AttributeIOR")) 
-       {
-         SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-          CORBA::String_var Val = IOR->Value();
-         if (strcmp(Val, anObjectIOR) == 0)
-           {
-             _find = true;
-             RefSO = SALOMEDS::SObject::_narrow(SC);
-           }
-       }
-       if (!_find) 
-         RefSO =  _FindObjectIOR(SC,anObjectIOR, _find);
+  bool aIsFound = false;
+  SALOMEDS::SObject_var aRefSO;
+  SALOMEDS_SComponentIterator_i aComponentIter(this,_doc);
+  for(; aComponentIter.More() && !aIsFound; aComponentIter.Next()){
+    TDF_Label aLab = aComponentIter.GetValue();
+    Handle(SALOMEDS_IORAttribute) anAttr;
+    if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectIOR) == 0){
+       aRefSO = SALOMEDS_SComponent_i::NewRef(this,aLab);
+       aIsFound = true;
       }
+    }
+    if(!aIsFound) 
+      aRefSO = _FindObjectIOR(aLab,theObjectIOR,aIsFound);
   }
-  if (!RefSO->_is_nil()) MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
 
-  return RefSO;
+  if(!aRefSO->_is_nil()) 
+    MESSAGE("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
+
+  return aRefSO._retn();
 }
 
 //============================================================================
@@ -372,9 +509,7 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
   bool isRelative = false;
 
   if(aLength == 0) {  //Empty path - return the current context
-    SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_current, _orb);
-    aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-    return aSO._retn();
+    return SALOMEDS_SObject_i::NewRef(this,_current)._retn();
   }
 
   if(aPath.Value(1) != '/')  //Relative path 
@@ -390,9 +525,7 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
   }
   else {
     if(aPath.Length() == 1 && aPath.Value(1) == '/') {    //Root
-      SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_doc->Main(), _orb);
-      aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
-      return aSO._retn();
+      return SALOMEDS_SObject_i::NewRef(this,_doc->Main())._retn();
     }
     anIterator.Initialize(_doc->Main(), Standard_False);
   }
@@ -408,9 +541,7 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
        if(anAttr->Get() == aToken) {
          aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
          if(aToken.Length() == 0) {  //The searched label is found (no part of the path is left)
-             SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (aLabel, _orb);
-             aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-             return aSO._retn();
+           return SALOMEDS_SObject_i::NewRef(this,aLabel)._retn();
          }
 
          anIterator.Initialize(aLabel, Standard_False);
@@ -433,18 +564,22 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
 {
   TCollection_AsciiString aPath("");
-  if(CORBA::is_nil(theObject)) return CORBA::string_dup(aPath.ToCString());
+  if(CORBA::is_nil(theObject)) 
+    return CORBA::string_dup(aPath.ToCString());
 
   SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
   if(anObject->_is_nil()) {
-    anObject = FindObjectIOR(_orb->object_to_string(theObject));
-    if(anObject->_is_nil()) return CORBA::string_dup(aPath.ToCString());
+    CORBA::String_var anIOR = GetORB()->object_to_string(theObject);
+    anObject = FindObjectIOR(anIOR);
+    if(anObject->_is_nil()) 
+      return CORBA::string_dup(aPath.ToCString());
   }
 
   SALOMEDS::GenericAttribute_var anAttr;
   if(anObject->FindAttribute(anAttr, "AttributeName")) {
     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
-    if(anAttr->_is_nil()) return CORBA::string_dup(aPath.ToCString());
+    if(anAttr->_is_nil()) 
+      return CORBA::string_dup(aPath.ToCString());
     TCollection_AsciiString aValue(aName->Value());
     aValue.Prepend("/");
     aValue += aPath;
@@ -474,7 +609,7 @@ void SALOMEDS_Study_i::SetContext(const char* thePath)
 {
   if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
   TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
-  bool isInvalid = false, isFound = false;
+  bool isInvalid = false;
   SALOMEDS::SObject_var aSO;
   
   if(aPath.Value(1) != '/') { //Relative path 
@@ -509,10 +644,11 @@ void SALOMEDS_Study_i::SetContext(const char* thePath)
 //============================================================================
 char* SALOMEDS_Study_i::GetContext() 
 {
-  if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();   
-  SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_current, _orb);
-  SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
-  return GetObjectPath(aSO._retn());
+  if(_current.IsNull()) 
+    throw SALOMEDS::Study::StudyInvalidContext();   
+
+  SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(this,_current);
+  return GetObjectPath(aSObject);
 }
 
 //============================================================================
@@ -663,53 +799,66 @@ SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theCont
  *  Purpose  : Create a ChildIterator from an SObject
  */
 //============================================================================
-SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
+SALOMEDS::ChildIterator_ptr 
+SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr theSObject)
 {
-  //Convert aSO->GetID in TDF_Label.
-  TDF_Label Lab;
-  TDF_Tool::Label(_doc->GetData(), aSO->GetID(), Lab);
-
-  //Create iterator
-  SALOMEDS_ChildIterator_i* it_servant = new SALOMEDS_ChildIterator_i(Lab,_orb);
-  SALOMEDS::ChildIterator_var it = SALOMEDS::ChildIterator::_narrow(it_servant->_this()); 
+  SALOMEDS_ChildIterator_i* aServant = 
+    new SALOMEDS_ChildIterator_i(GetChildIterator(theSObject));
 
-  return it;
+  return aServant->_this();
 }
 
+SALOMEDS_ChildIterator_i 
+SALOMEDS_Study_i::GetChildIterator(SALOMEDS::SObject_ptr theSObject)
+{
+  TDF_Label aLab;
+  TDF_Tool::Label(_doc->GetData(),theSObject->GetID(),aLab);
+  return SALOMEDS_ChildIterator_i(this,aLab);
+}
 
 //============================================================================
 /*! Function : NewComponentIterator
  *  Purpose  : Create a SComponentIterator
  */
 //============================================================================
-SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
+SALOMEDS::SComponentIterator_ptr 
+SALOMEDS_Study_i::NewComponentIterator()
+{
+  SALOMEDS_SComponentIterator_i* aServant = 
+    new SALOMEDS_SComponentIterator_i(GetComponentIterator());
+
+  return aServant->_this();
+}
+
+SALOMEDS_SComponentIterator_i 
+SALOMEDS_Study_i::GetComponentIterator()
 {
-  SALOMEDS_SComponentIterator_i* it_servant = new SALOMEDS_SComponentIterator_i(_doc,_orb);
-  SALOMEDS::SComponentIterator_var it = SALOMEDS::SComponentIterator::_narrow(it_servant->_this()); 
-  return it;
+  return SALOMEDS_SComponentIterator_i(this,_doc);
 }
 
+//============================================================================
+/*! Function : GetUseCaseBuilder
+ *  Purpose  : Returns a UseCase builder
+ */
+//============================================================================
+SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder() 
+{
+  return _UseCaseBuilder->_this();
+}
 
 //============================================================================
 /*! Function : NewBuilder
  *  Purpose  : Create a StudyBuilder
  */
 //============================================================================
+SALOMEDS_StudyBuilder_i* SALOMEDS_Study_i::GetBuilder()
+{
+  return _Builder;
+}
 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
 {
-  SALOMEDS_StudyBuilder_i* it_servant = new SALOMEDS_StudyBuilder_i(_doc,_orb);
-  SALOMEDS::StudyBuilder_var it = SALOMEDS::StudyBuilder::_narrow(it_servant->_this()); 
-
-  if(_autoFill) {
-    SALOMEDS_Callback_i* callback = new SALOMEDS_Callback_i(GetUseCaseBuilder(), _orb);
-    SALOMEDS::Callback_var cb = SALOMEDS::Callback::_narrow(callback->_this()); 
-
-    it->SetOnAddSObject(cb);
-    it->SetOnRemoveSObject(cb);
-  }
-
-  return it;
-
+  return GetBuilder()->_this();
 }
  
 //============================================================================
@@ -810,35 +959,28 @@ void SALOMEDS_Study_i::URL(const char* url)
  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
  */
 //============================================================================
-SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
-                                                   const char* anObjectName, 
-                                                   bool& _find)
+SALOMEDS::SObject_ptr 
+SALOMEDS_Study_i::_FindObject(TDF_Label theLabel,
+                             const char* theObjectName, 
+                             bool& theIsFound)
 {
+  theIsFound = false;
   // Iterate on each objects and subobjects of the component
   // If objectName find, stop the loop and get the object reference
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  CORBA::String_var soid = SO->GetID();
-  SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SObject_var CSO = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (CSO->FindAttribute(anAttr,"AttributeName")) 
-       {
-         SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
-          CORBA::String_var Val = Name->Value();
-         if (strcmp(Val, anObjectName) == 0)
-           {
-             RefSO = SALOMEDS::SObject::_narrow(CSO);
-             _find = true;
-           }
-       }
-       if (!_find) RefSO =  _FindObject(CSO, anObjectName, _find);
+  SALOMEDS::SObject_var aRefSO;
+  TDF_ChildIterator aChildIter(theLabel,true);
+  for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
+    TDF_Label aLab = aChildIter.Value();
+    Handle(TDataStd_Name) anAttr;
+    if(aLab.FindAttribute(TDataStd_Name::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectName) == 0){
+       aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
+       theIsFound = true;
       }
+    }
   }
-  return RefSO;
+  return aRefSO._retn();
 }
 
 //============================================================================
@@ -847,34 +989,26 @@ SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
  */
 //============================================================================
 SALOMEDS::SObject_ptr 
-SALOMEDS_Study_i::_FindObjectIOR(SALOMEDS::SObject_ptr SO,
-                             const char* anObjectIOR, 
-                             bool& _find)
+SALOMEDS_Study_i::_FindObjectIOR(TDF_Label theLabel,
+                                const char* theObjectIOR, 
+                                bool& theIsFound)
 {
   // Iterate on each objects and subobjects of the component
   // If objectName find, stop the loop and get the object reference
-  SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
-
-  SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
-  for (; it->More();it->Next()){
-    if(!_find)
-      {
-       SALOMEDS::SObject_var CSO = it->Value();
-       SALOMEDS::GenericAttribute_var anAttr;
-       if (CSO->FindAttribute(anAttr,"AttributeIOR")) 
-       {
-         SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
-          CORBA::String_var Val = IOR->Value();
-         if (strcmp(Val, anObjectIOR) == 0)
-           {
-             RefSO = SALOMEDS::SObject::_narrow(CSO);
-             _find = true;
-           }
-       }
-       if (!_find) RefSO =  _FindObjectIOR(CSO, anObjectIOR, _find);
+  SALOMEDS::SObject_var aRefSO;
+  TDF_ChildIterator aChildIter(theLabel,true);
+  for(; aChildIter.More() && !theIsFound; aChildIter.Next()){
+    TDF_Label aLab = aChildIter.Value();
+    Handle(SALOMEDS_IORAttribute) anAttr;
+    if(aLab.FindAttribute(SALOMEDS_IORAttribute::GetID(),anAttr)){
+      TCollection_AsciiString aString(anAttr->Get());
+      if(strcmp(aString.ToCString(),theObjectIOR) == 0){
+       aRefSO = SALOMEDS_SObject_i::NewRef(this,aLab);
+       theIsFound = true;
       }
+    }
   }
-  return RefSO;
+  return aRefSO._retn();
 }
 
 CORBA::Short SALOMEDS_Study_i::StudyId()
@@ -896,25 +1030,11 @@ void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry)
   myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
 }
 
-SALOMEDS::Study_ptr SALOMEDS_Study_i::GetStudy(const TDF_Label theLabel, CORBA::ORB_ptr orb) {
-  Handle(SALOMEDS_IORAttribute) Att;
-  if (theLabel.Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
-    char* IOR = CORBA::string_dup(TCollection_AsciiString(Att->Get()).ToCString());
-    CORBA::Object_var obj = orb->string_to_object(IOR);
-    SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
-    ASSERT(!CORBA::is_nil(aStudy));
-    return SALOMEDS::Study::_duplicate(aStudy);
-  } else {
-    MESSAGE("GetStudy: Problem to get study");
-  }
-  return SALOMEDS::Study::_nil();
-}
-
-void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
+void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute) {
   TCollection_AsciiString aString;
-  TDF_Tool::Entry(theAttribute->Label(), aString);
-  GetStudy(theAttribute->Label(), orb)->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(),
-                                                         aString.ToCString());
+  TDF_Tool::Entry(theAttribute->Label(),aString);
+  TCollection_AsciiString aValue(theAttribute->Get());
+  UpdateIORLabelMap(aValue.ToCString(),aString.ToCString());
 }
 
 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
@@ -928,9 +1048,12 @@ SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObj
 }
 
 
-SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
-  SALOMEDS::GenericAttribute_ptr anAttr =  NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
-                                                                              "AttributeStudyProperties");
+SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties(){
+  SALOMEDS::SObject_var aSObject = FindObjectID("0:1");
+
+  SALOMEDS::GenericAttribute_var anAttr =  
+    GetBuilder()->FindOrCreateAttribute(aSObject,"AttributeStudyProperties");
+
   return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
 }
 
@@ -968,19 +1091,6 @@ SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
 
 
 
-//============================================================================
-/*! Function : GetUseCaseBuilder
- *  Purpose  : Returns a UseCase builder
- */
-//============================================================================
-SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder() 
-{
-  SALOMEDS_UseCaseBuilder_i* _caseBuilder = new SALOMEDS_UseCaseBuilder_i(_doc, _orb);
-  SALOMEDS::UseCaseBuilder_var aBuilder = SALOMEDS::UseCaseBuilder::_narrow(_caseBuilder->_this());
-  return aBuilder._retn();
-}
-
-
 //============================================================================
 /*! Function : Close
  *  Purpose  : 
@@ -988,10 +1098,11 @@ SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder()
 //============================================================================
 void SALOMEDS_Study_i::Close()
 {
-  SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
+  SALOMEDS_SComponentIterator_i itcomponent(this,_doc);
 
-  for (; itcomponent->More(); itcomponent->Next()) {
-    SALOMEDS::SComponent_var sco = itcomponent->Value();
+  const CORBA::ORB_var& anORB = GetORB();
+  for (; itcomponent.More(); itcomponent.Next()) {
+    SALOMEDS::SComponent_var sco = itcomponent.Value();
          
     MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
     // if there is an associated Engine call its method for closing
@@ -999,7 +1110,7 @@ void SALOMEDS_Study_i::Close()
     if (sco->ComponentIOR(IOREngine)) {
       // we have found the associated engine to write the data 
       MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
-      CORBA::Object_var obj = _orb->string_to_object(IOREngine);
+      CORBA::Object_var obj = anORB->string_to_object(IOREngine);
       if (!CORBA::is_nil(obj)) {
        SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
        
@@ -1025,13 +1136,13 @@ void SALOMEDS_Study_i::Close()
  */
  //============================================================================
 void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
-  if (!NewBuilder()->HasOpenCommand()) return;
+  if (!GetBuilder()->HasOpenCommand()) return;
   try {
-    CORBA::Object_var obj = _orb->string_to_object(theIOR);
+    CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
     if (!CORBA::is_nil(obj)) {
       SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
       if (!CORBA::is_nil(aGeneric)) {
-       TCollection_AsciiString anIOR((char*)theIOR);
+       TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
        anIOR.Prepend("d");
        myPostponedIORs.Append(anIOR); // add prefix: deleted
        myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
@@ -1041,13 +1152,13 @@ void SALOMEDS_Study_i::AddPostponed(const char* theIOR) {
 }
 
 void SALOMEDS_Study_i::AddCreatedPostponed(const char* theIOR) {
-  if (!NewBuilder()->HasOpenCommand()) return;
+  if (!GetBuilder()->HasOpenCommand()) return;
   try {
-    CORBA::Object_var obj = _orb->string_to_object(theIOR);
+    CORBA::Object_var obj = GetORB()->string_to_object(theIOR);
     if (!CORBA::is_nil(obj)) {
       SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj) ;
       if (!CORBA::is_nil(aGeneric)) {
-       TCollection_AsciiString anIOR((char*)theIOR);
+       TCollection_AsciiString anIOR(const_cast<char*>(theIOR));
        anIOR.Prepend("c");
        myPostponedIORs.Append(anIOR); // add prefix: created
        myNbPostponed.SetValue(myNbPostponed.Length(), myNbPostponed.Last() + 1);
@@ -1068,6 +1179,7 @@ void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
   int aUndoLimit = theUndoLimit;
   if (theUndoLimit < 0) aUndoLimit = 0;
 
+  const CORBA::ORB_var& anORB = GetORB();
   if (myNbUndos > 0) { // remove undone
     anOld = 0;
     for(anIndex = 1; anIndex < myNbPostponed.Length() - myNbUndos; anIndex++)
@@ -1077,7 +1189,7 @@ void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
     for(anIndex = anOld + 1; anIndex <= aNew; anIndex++) {
       TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
       if (anIOR.Value(1) == 'c') {
-       CORBA::Object_var obj = _orb->string_to_object(anIOR.Split(1).ToCString());
+       CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
        SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
        if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
       }
@@ -1095,7 +1207,7 @@ void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
     for(anIndex = 1; anIndex <= anOld; anIndex++) {
       TCollection_AsciiString anIOR = myPostponedIORs(anIndex);
       if (anIOR.Value(1) == 'd') {
-       CORBA::Object_var obj = _orb->string_to_object(anIOR.Split(1).ToCString());
+       CORBA::Object_var obj = anORB->string_to_object(anIOR.Split(1).ToCString());
        SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
        if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
       }
@@ -1110,7 +1222,7 @@ void SALOMEDS_Study_i::RemovePostponed(const CORBA::Long theUndoLimit) {
       Handle(SALOMEDS_IORAttribute) anAttr = Handle(SALOMEDS_IORAttribute)::DownCast(anIter.Value());
       CORBA::String_var anIOR = CORBA::string_dup(TCollection_AsciiString(anAttr->Get()).ToCString());
       try {
-       CORBA::Object_var obj = _orb->string_to_object(anIOR);
+       CORBA::Object_var obj = anORB->string_to_object(anIOR);
        SALOME::GenericObj_var aGeneric = SALOME::GenericObj::_narrow(obj);
        if (!CORBA::is_nil(aGeneric)) aGeneric->Destroy();
       } catch (...) {}