Salome HOME
PR: lib forgotten in case without ihm
[modules/yacs.git] / src / SALOMEDS / SALOMEDS_StudyBuilder_i.cxx
1 //  SALOME SALOMEDS : data structure of SALOME and sources of Salome data server 
2 //
3 //  Copyright (C) 2003  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. 
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : SALOMEDS_StudyBuilder_i.cxx
25 //  Author : Yves FRICAUD
26 //  Module : SALOME
27 //  $Header$
28
29 #include "SALOMEDS_StudyBuilder_i.hxx"
30 #include "SALOMEDS_StudyManager_i.hxx"
31 #include "SALOMEDS_Study_i.hxx"
32
33 #include "SALOMEDS_SObject_i.hxx"
34 #include "SALOMEDS_SComponent_i.hxx"
35
36 #include "SALOMEDS_TargetAttribute.hxx"
37 #include "SALOMEDS_IORAttribute.hxx"
38 #include "SALOMEDS_PersRefAttribute.hxx"
39 #include "SALOMEDS_LocalIDAttribute.hxx"
40 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
41
42 #include "SALOMEDS_Tool.hxx"
43
44 #include "Utils_CorbaException.hxx"
45 #include "Utils_ExceptHandlers.hxx"
46
47 #include <TDF_ChildIterator.hxx>
48 #include <TDF_Label.hxx>
49 #include <TDataStd_Name.hxx>
50 #include <TDataStd_Comment.hxx>
51 #include <TDataStd_UAttribute.hxx>
52 #include <TDataStd_Real.hxx>
53 #include <TDF_Tool.hxx>
54 #include <TDF_Reference.hxx>
55 #include <TDF_Data.hxx>
56 #include <TDataStd_ChildNodeIterator.hxx>
57 #include <TDF_ListIteratorOfAttributeList.hxx>
58
59 #include <HDFOI.hxx>
60 #include <stdlib.h> 
61
62 #define USE_CASE_LABEL_TAG            2
63 #define DIRECTORYID 16661
64 #define FILELOCALID 26662 
65
66 #include "utilities.h"
67
68 using namespace std;
69
70 UNEXPECT_CATCH(SBSalomeException, SALOME::SALOME_Exception);
71 UNEXPECT_CATCH(SBLockProtection, SALOMEDS::StudyBuilder::LockProtection);
72
73 //============================================================================
74 /*! Function : constructor
75  *  Purpose  :
76  */
77 //============================================================================
78 SALOMEDS_StudyBuilder_i::SALOMEDS_StudyBuilder_i(SALOMEDS_Study_i* theStudy,
79                                                  const Handle(TDocStd_Document)& theDocument):
80   _study(theStudy),
81   _doc(theDocument)
82 {
83 }
84
85 //============================================================================
86 /*! Function : destructor
87  *  Purpose  :
88  */
89 //============================================================================
90 SALOMEDS_StudyBuilder_i::~SALOMEDS_StudyBuilder_i()
91 {
92 }
93
94
95 //============================================================================
96 CORBA::ORB_var SALOMEDS_StudyBuilder_i::GetORB() const
97 {
98   return _study->GetORB();
99 }
100
101
102 //============================================================================
103 PortableServer::POA_var SALOMEDS_StudyBuilder_i::GetPOA() const
104 {
105   return _study->GetPOA();
106 }
107
108
109 //============================================================================
110 /*! Function : NewComponent
111  *  Purpose  : Create a new component (Scomponent)
112  */
113 //============================================================================
114 SALOMEDS::SComponent_ptr 
115 SALOMEDS_StudyBuilder_i::NewComponent(const char* DataType)
116 {
117   CheckLocked();
118   //Always create component under main label.
119   TDF_Label L  = _doc->Main();
120
121   // YFR DEBUG : 13/02/2002 TDF_Label NL = L.NewChild();
122   
123   Standard_Integer imax = 0;
124   for (TDF_ChildIterator it(L); it.More(); it.Next()) {
125     if (it.Value().Tag() > imax)
126       imax = it.Value().Tag();
127   }
128   imax++;
129   TDF_Label NL = L.FindChild(imax);
130
131    TDataStd_Comment::Set(NL,Standard_CString(DataType));
132    //  TDataStd_Comment::Set(NL,Standard_CString(CORBA::string_dup(DataType)));
133
134   SALOMEDS::SComponent_var aSComponent = SALOMEDS_SComponent_i::NewRef(_study,NL); 
135
136   OnAddSObject(aSComponent);
137
138   return aSComponent._retn();
139 }
140
141 //============================================================================
142 /*! Function : DefineComponentInstance
143  *  Purpose  : Add IOR attribute of a Scomponent
144  */
145 //============================================================================
146 void SALOMEDS_StudyBuilder_i::DefineComponentInstance(SALOMEDS::SComponent_ptr theComponent,
147                                                       CORBA::Object_ptr theObject)
148 {
149   CheckLocked();
150
151   if(CORBA::is_nil(theComponent) || CORBA::is_nil(theObject))
152     return;
153
154   //Find label
155   TDF_Label Lab;
156   CORBA::String_var aString = theComponent->GetID();
157   TDF_Tool::Label(_doc->GetData(),const_cast<char*>(aString.in()),Lab);
158
159   //add theObject definition 
160   aString = GetORB()->object_to_string(theObject);
161   SALOMEDS_IORAttribute::Set(Lab,const_cast<char*>(aString.in()),GetORB());
162 }
163
164 //============================================================================
165 /*! Function : RemoveComponent
166  *  Purpose  : Delete a Scomponent
167  */
168 //============================================================================
169 void 
170 SALOMEDS_StudyBuilder_i::RemoveComponent(SALOMEDS::SComponent_ptr theComponent)
171 {
172   CheckLocked();
173   RemoveObject(theComponent);
174 }
175
176 //============================================================================
177 /*! Function : NewObject
178  *  Purpose  : Create a new SObject
179  */
180 //============================================================================
181 SALOMEDS::SObject_ptr 
182 SALOMEDS_StudyBuilder_i::NewObject(SALOMEDS::SObject_ptr theFatherObject)
183 {
184   CheckLocked();
185
186   if(CORBA::is_nil(theFatherObject)) 
187     return SALOMEDS::SObject::_nil();
188
189   //Find label of father
190   TDF_Label aLabel;
191   TCollection_AsciiString anEntry;
192   
193   CORBA::String_var aFatherID = theFatherObject->GetID();
194   TDF_Tool::Label(_doc->GetData(),aFatherID,aLabel);
195
196   //Create a new label
197   //YFR DEBUG : 13/02/2002  TDF_Label NewLab = Lab.NewChild();
198   Standard_Integer imax = 0;
199   for (TDF_ChildIterator it(aLabel); it.More(); it.Next()) {
200     if (it.Value().Tag() > imax)
201       imax = it.Value().Tag();
202   }
203   imax++;
204   TDF_Label aNewLabel = aLabel.FindChild(imax);
205   
206   SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(_study,aNewLabel); 
207
208   OnAddSObject(aSObject);
209
210   return aSObject._retn();
211 }
212
213 //============================================================================
214 /*! Function : NewObjectToTag
215  *  Purpose  :
216  */
217 //============================================================================
218 SALOMEDS::SObject_ptr 
219 SALOMEDS_StudyBuilder_i::NewObjectToTag(SALOMEDS::SObject_ptr theFatherObject,
220                                         CORBA::Long theTag)
221 {
222   CheckLocked();
223
224   if(CORBA::is_nil(theFatherObject)) 
225     return SALOMEDS::SObject::_nil();
226
227   //Find label of father
228   TDF_Label Lab;
229   CORBA::String_var aFatherID = theFatherObject->GetID();
230   TDF_Tool::Label(_doc->GetData(),aFatherID,Lab);
231
232   //Create or find label
233   TDF_Label aNewLab = Lab.FindChild(theTag,1);
234
235   SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(_study,aNewLab); 
236
237   OnAddSObject(aSObject);
238
239   return aSObject._retn();
240 }
241
242 //============================================================================
243 /*! Function : RemoveObject
244  *  Purpose  :
245  */
246 //============================================================================
247 void SALOMEDS_StudyBuilder_i::RemoveObject(SALOMEDS::SObject_ptr theSObject)
248 {
249   CheckLocked();
250
251   if(CORBA::is_nil(theSObject))
252     return;
253
254   OnRemoveSObject(theSObject);
255
256   TDF_Label Lab;
257   CORBA::String_var aString(theSObject->GetID());
258   TDF_Tool::Label(_doc->GetData(),const_cast<char*>(aString.in()),Lab);
259
260   Handle(TDF_Reference) aReference;
261   if(Lab.FindAttribute(TDF_Reference::GetID(),aReference)){
262     Handle(SALOMEDS_TargetAttribute) aTarget;
263     if(aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
264       aTarget->Remove(Lab);
265   }
266
267   Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
268   if (Lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr)){
269     SALOMEDS::Study_ptr aStudy = SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB());
270     aStudy->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
271   }
272
273   Lab.ForgetAllAttributes();
274 }
275
276 //============================================================================
277 /*! Function : RemoveObjectWithChildren
278  *  Purpose  :
279  */
280 //============================================================================
281 void SALOMEDS_StudyBuilder_i::RemoveObjectWithChildren(SALOMEDS::SObject_ptr theSObject)
282 {
283   CheckLocked();
284
285   if(CORBA::is_nil(theSObject))
286     return;
287
288   OnRemoveSObject(theSObject);
289
290   TDF_Label Lab;
291   CORBA::String_var aString(theSObject->GetID());
292   TDF_Tool::Label(_doc->GetData(),aString,Lab);
293
294   Handle(TDF_Reference) aReference;
295   if (Lab.FindAttribute(TDF_Reference::GetID(), aReference)) {
296     Handle(SALOMEDS_TargetAttribute) aTarget;
297     if (aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
298       aTarget->Remove(Lab);
299   }
300
301   Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
302   if (Lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr)){
303     SALOMEDS::Study_ptr aStudy = SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB());
304     aStudy->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
305   }
306
307   TDF_ChildIterator it(Lab, Standard_True);
308   for(;it.More();it.Next()) {
309     TDF_Label aLabel = it.Value();
310
311     if (aLabel.FindAttribute(TDF_Reference::GetID(), aReference)) {
312       Handle(SALOMEDS_TargetAttribute) aTarget;
313       if (aReference->Get().FindAttribute(SALOMEDS_TargetAttribute::GetID(),aTarget))
314         aTarget->Remove(aLabel);
315     }
316
317     Handle(SALOMEDS_IORAttribute) anAttr; // postponed removing of CORBA objects
318     if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr)){
319       SALOMEDS::Study_ptr aStudy = SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB());
320       aStudy->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
321     }
322   }
323
324   Lab.ForgetAllAttributes(Standard_True);
325 }
326
327 //============================================================================
328 /*! Function : Translate_persistentID_to_IOR
329  *  Purpose  :
330  */
331 //============================================================================
332 static void  Translate_persistentID_to_IOR(TDF_Label theLabel,
333                                            SALOMEDS::Driver_ptr theDriver,
334                                            CORBA::ORB_ptr theORB,
335                                            SALOMEDS_Study_i* theStudy,
336                                            CORBA::Boolean theIsMultiFile,
337                                            CORBA::Boolean theIsASCII)
338 {
339   if(CORBA::is_nil(theDriver))
340     return;
341
342   for (TDF_ChildIterator  aChildIter (theLabel); aChildIter.More(); aChildIter.Next()){
343     TDF_Label aCurrentLabel = aChildIter.Value();
344     Handle(TDF_Attribute) anAttr;
345     if(aCurrentLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(),anAttr)){
346       Handle(SALOMEDS_LocalIDAttribute) anID;
347       if (aCurrentLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(),anID)) 
348         if (anID->Get() == FILELOCALID) continue;        //SRN: This attribute store a file name, skip it 
349
350       TCollection_ExtendedString res = Handle(TDataStd_Comment)::DownCast(anAttr)->Get();
351       TCollection_AsciiString ch(res);
352       
353       SALOMEDS::SObject_var aSObject = SALOMEDS_SObject_i::NewRef(theStudy,aCurrentLabel); 
354
355       CORBA::String_var anIOR = 
356         theDriver->LocalPersistentIDToIOR(aSObject,ch.ToCString(),theIsMultiFile,theIsASCII);
357       SALOMEDS_IORAttribute::Set (aCurrentLabel,const_cast<char*>(anIOR.in()),theORB); 
358     }
359
360     Translate_persistentID_to_IOR(aCurrentLabel,theDriver,theORB,theStudy,theIsMultiFile,theIsASCII);
361   }
362 }
363
364 //============================================================================
365 /*! Function : LoadWith
366  *  Purpose  : 
367  */
368 //============================================================================
369
370 //============================================================================
371 void SALOMEDS_StudyBuilder_i::LoadWith(SALOMEDS::SComponent_ptr theSComponent, 
372                                        SALOMEDS::Driver_ptr theDriver) 
373   throw(SALOME::SALOME_Exception)
374 {
375   Unexpect aCatch(SBSalomeException);
376
377   if(CORBA::is_nil(theSComponent))
378     return;
379
380   TDF_Label Lab;
381   CORBA::String_var aString = theSComponent->GetID();
382   TDF_Tool::Label(_doc->GetData(),const_cast<char*>(aString.in()),Lab);
383   
384   //Find the current Url of the study  
385   Handle(TDF_Attribute) Att;
386   if (_doc->Main().FindAttribute(SALOMEDS_PersRefAttribute::GetID(),Att)) {
387     if(CORBA::is_nil(theDriver))
388       return;
389
390     int aLocked = theSComponent->GetStudy()->GetProperties()->IsLocked();
391     if(aLocked) 
392       theSComponent->GetStudy()->GetProperties()->SetLocked(false);
393     
394     // mpv 06.03.2003: SAL1927 - if component data if already loaded, it is not necessary to do it again
395     if (Lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), Att)) {
396       if(aLocked) 
397         theSComponent->GetStudy()->GetProperties()->SetLocked(true);
398       return;
399     }
400     DefineComponentInstance (theSComponent,theDriver);
401     
402     TCollection_AsciiString aHDFPath(Handle(TDataStd_Comment)::DownCast(Att)->Get());
403     
404     bool isASCII = false;
405     std::ostringstream anURLStream;
406     if(HDFascii::isASCII(aHDFPath.ToCString())){
407       isASCII = true;
408       auto_ptr<char> aResultPath(HDFascii::ConvertFromASCIIToHDF(aHDFPath.ToCString()));
409       anURLStream<<aResultPath.get()<<"hdf_from_ascii.hdf";
410     } else {
411       anURLStream<<aHDFPath.ToCString();
412     }
413     std::string aHDFUrl = anURLStream.str();
414
415     //Open the Study HDF file 
416     auto_ptr<HDFfile> hdf_file(new HDFfile(const_cast<char*>(aHDFUrl.c_str())));
417     
418     char aMultifileState[2];
419     char ASCIIfileState[2];
420     try {
421       CORBA::String_var scoid = theSComponent->GetID();
422       hdf_file->OpenOnDisk(HDF_RDONLY);
423       HDFgroup *hdf_group = new HDFgroup("DATACOMPONENT",hdf_file.get());
424       hdf_group->OpenOnDisk();
425       HDFgroup *hdf_sco_group = new HDFgroup(scoid, hdf_group);
426       hdf_sco_group->OpenOnDisk();
427         
428       SALOMEDS::TMPFile_var aStreamFile;
429       if (hdf_sco_group->ExistInternalObject("FILE_STREAM")) {
430         HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group);
431         hdf_dataset->OpenOnDisk();
432         int aStreamSize = hdf_dataset->GetSize();
433         unsigned char* aBuffer = new unsigned char[aStreamSize];
434         if(aBuffer == NULL) 
435           throw HDFexception("Unable to open dataset FILE_STREAM");
436         hdf_dataset->ReadFromDisk(aBuffer);
437         aStreamFile = new SALOMEDS::TMPFile(aStreamSize, aStreamSize, aBuffer, 1);
438         hdf_dataset->CloseOnDisk();
439         hdf_dataset = 0;
440       } else 
441         aStreamFile = new SALOMEDS::TMPFile(0);
442       
443       HDFdataset *multifile_hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group);
444       multifile_hdf_dataset->OpenOnDisk();
445       multifile_hdf_dataset->ReadFromDisk(aMultifileState);
446       
447       HDFdataset *ascii_hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group);
448       ascii_hdf_dataset->OpenOnDisk();
449       ascii_hdf_dataset->ReadFromDisk(ASCIIfileState);
450       
451       // set path without file name from URL 
452       std::string aDir(aHDFPath.ToCString());
453       aDir.substr(0,aDir.find('/'));
454       
455       CORBA::Boolean aResult = (ASCIIfileState[0]=='A')?
456         theDriver->LoadASCII(theSComponent, aStreamFile.in(), aDir.c_str(), aMultifileState[0]=='M'):
457           theDriver->Load(theSComponent, aStreamFile.in(), aDir.c_str(), aMultifileState[0]=='M');
458       if(!aResult) {
459         RemoveAttribute( theSComponent, "AttributeIOR" );
460         if (isASCII) {
461           SALOMEDS::ListOfFileNames_var aFilesToRemove = new SALOMEDS::ListOfFileNames;
462           aFilesToRemove->length(1);
463           std::string aDir = SALOMEDS_Tool::GetDirFromPath(aHDFUrl);
464           aFilesToRemove[0] = CORBA::string_dup(&aHDFUrl[strlen(aDir.c_str())]);
465           SALOMEDS_Tool::RemoveTemporaryFiles(aDir,aFilesToRemove,true);
466         }
467         MESSAGE("Can't load component");
468         THROW_SALOME_CORBA_EXCEPTION("Unable to load component data",SALOME::BAD_PARAM);
469       }
470       
471       multifile_hdf_dataset->CloseOnDisk();
472       multifile_hdf_dataset = 0;
473       ascii_hdf_dataset->CloseOnDisk();
474       ascii_hdf_dataset = 0;
475       hdf_sco_group->CloseOnDisk();
476       hdf_sco_group = 0;
477       hdf_group->CloseOnDisk();
478       hdf_group = 0;
479       hdf_file->CloseOnDisk();
480       
481       if (isASCII) {
482         SALOMEDS::ListOfFileNames_var aFilesToRemove = new SALOMEDS::ListOfFileNames;
483         aFilesToRemove->length(1);
484         std::string aDir = SALOMEDS_Tool::GetDirFromPath(aHDFUrl);
485         aFilesToRemove[0] = CORBA::string_dup(&aHDFUrl[strlen(aDir.c_str())]);
486         SALOMEDS_Tool::RemoveTemporaryFiles(aDir,aFilesToRemove,true);
487       }
488     }
489     catch (HDFexception) {
490       INFOS("No persistent file Name");
491       if (isASCII) {
492         SALOMEDS::ListOfFileNames_var aFilesToRemove = new SALOMEDS::ListOfFileNames;
493         aFilesToRemove->length(1);
494         std::string aDir = SALOMEDS_Tool::GetDirFromPath(aHDFUrl);
495         aFilesToRemove[0] = CORBA::string_dup(&aHDFUrl[strlen(aDir.c_str())]);
496         SALOMEDS_Tool::RemoveTemporaryFiles(aDir,aFilesToRemove,true);
497       }
498       if(aLocked)
499         theSComponent->GetStudy()->GetProperties()->SetLocked(true);
500       THROW_SALOME_CORBA_EXCEPTION("No persistent file Name found",SALOME::BAD_PARAM);
501     }
502     
503     try {
504       Translate_persistentID_to_IOR(Lab,theDriver,GetORB(),_study, aMultifileState[0]=='M', ASCIIfileState[0] == 'A');
505     } catch (SALOME::SALOME_Exception) {
506       INFOS("Can't translate PersRef to IOR");
507       if (aLocked) 
508         theSComponent->GetStudy()->GetProperties()->SetLocked(true);
509       THROW_SALOME_CORBA_EXCEPTION("Unable to convert component persistent data to the transient",SALOME::BAD_PARAM);
510       //        throw HDFexception("Unable to load component data");
511     }
512     if(aLocked)
513       theSComponent->GetStudy()->GetProperties()->SetLocked(true);
514   } else
515     MESSAGE("No persistent file Name");
516 }
517
518
519 //============================================================================
520 /*! Function : Load
521  *  Purpose  : 
522  */
523 //============================================================================
524 void SALOMEDS_StudyBuilder_i::Load(SALOMEDS::SObject_ptr sco)
525 {
526   MESSAGE ( "This function is not yet implemented");
527 }
528
529 //============================================================================
530 /*! Function : FindOrCreateAttribute
531  *  Purpose  : Add attribute of given type to SObject, if there is attribute of such type, returns
532  *  existing one
533  */
534 //============================================================================
535 SALOMEDS::GenericAttribute_ptr 
536 SALOMEDS_StudyBuilder_i::FindOrCreateAttribute(SALOMEDS::SObject_ptr theObject, 
537                                                const char* theTypeOfAttribute)
538 {
539   if(!CORBA::is_nil(theObject)){
540     PortableServer::POA_var aPOA = GetPOA();
541     PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theObject,aPOA);
542     if(aServant.in() != NULL){
543       if(SALOMEDS_SObject_i* anSObject = dynamic_cast<SALOMEDS_SObject_i*>(aServant.in())){
544         return anSObject->FindOrCreateAttribute(theTypeOfAttribute);
545       }
546     }
547   }
548   return SALOMEDS::GenericAttribute::_nil();
549 }
550
551 //============================================================================
552 /*! Function : FindAttribute
553  *  Purpose  : Find attribute of given type assigned SObject, returns Standard_True if it is found
554  */
555 //============================================================================
556
557 CORBA::Boolean SALOMEDS_StudyBuilder_i::FindAttribute(SALOMEDS::SObject_ptr theObject, 
558                                                       SALOMEDS::GenericAttribute_out theAttr, 
559                                                       const char* theTypeOfAttribute)
560 {
561   if(!CORBA::is_nil(theObject)){
562     PortableServer::ServantBase_var aServant = SALOMEDS::GetServant(theObject,GetPOA());
563     if(aServant.in() != NULL){
564       if(SALOMEDS_SObject_i* anSObject = dynamic_cast<SALOMEDS_SObject_i*>(aServant.in())){
565         return anSObject->FindAttribute(theAttr,theTypeOfAttribute);
566       }
567     }
568   }
569   return Standard_False;
570 }
571
572 //============================================================================
573 /*! Function : RemoveAttribute
574  *  Purpose  : Remove attribute of given type assigned SObject
575  */
576 //============================================================================
577
578 void SALOMEDS_StudyBuilder_i::RemoveAttribute(SALOMEDS::SObject_ptr theSObject, 
579                                               const char* aTypeOfAttribute)
580 {
581   CheckLocked();
582
583   if(CORBA::is_nil(theSObject))
584     return;
585
586   TDF_Label Lab;
587   CORBA::String_var anobid = theSObject->GetID();
588   TDF_Tool::Label(_doc->GetData(),anobid,Lab);
589   
590   if (strcmp(aTypeOfAttribute, "AttributeIOR") == 0) { // postponed removing of CORBA objects
591     Handle(SALOMEDS_IORAttribute) anAttr;
592     if (Lab.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttr))
593       SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB())->AddPostponed(TCollection_AsciiString(anAttr->Get()).ToCString());
594     else return;
595   }
596
597   Lab.ForgetAttribute(SALOMEDS::GetGUID(aTypeOfAttribute));
598 }
599
600 //============================================================================
601 /*! Function : Addreference
602  *  Purpose  : 
603  */
604 //============================================================================
605 void 
606 SALOMEDS_StudyBuilder_i::Addreference(SALOMEDS::SObject_ptr me, 
607                                       SALOMEDS::SObject_ptr theReferencedObject)
608 {
609   CheckLocked();
610   if(CORBA::is_nil(me) || CORBA::is_nil(theReferencedObject))
611     return;
612
613   TDF_Label Lab;
614   CORBA::String_var meid = me->GetID();
615   TDF_Tool::Label(_doc->GetData(),meid,Lab);  
616
617   TDF_Label RefLab;
618   CORBA::String_var roid = theReferencedObject->GetID();
619   TDF_Tool::Label(_doc->GetData(),roid,RefLab);
620
621   TDF_Reference::Set(Lab,RefLab);
622   SALOMEDS_TargetAttribute::Set(RefLab)->Append(Lab);
623
624   if(Lab.IsDescendant(_doc->Main())) 
625     OnRemoveSObject(me);
626 }
627
628 //============================================================================
629 /*! Function : RemoveReference
630  *  Purpose  : 
631  */
632 //============================================================================
633 void SALOMEDS_StudyBuilder_i::RemoveReference(SALOMEDS::SObject_ptr me)
634 {
635   SALOMEDS::SObject_var theReferencedObject;
636   if(!me->ReferencedObject(theReferencedObject)) return;  //No reference is found
637
638   if(CORBA::is_nil(me) || CORBA::is_nil(theReferencedObject))
639     return;
640
641   CheckLocked();
642   TDF_Label Lab;
643   CORBA::String_var meid = me->GetID();
644   TDF_Tool::Label(_doc->GetData(),meid,Lab);  
645
646   Lab.ForgetAttribute(TDF_Reference::GetID());  
647
648   TDF_Label RefLab;  
649   CORBA::String_var roid = theReferencedObject->GetID();
650   TDF_Tool::Label(_doc->GetData(),roid,RefLab);
651
652   RemoveAttribute(theReferencedObject, "AttributeTarget");
653 }
654
655
656
657 //============================================================================
658 /*! Function : AddDirectory
659  *  Purpose  : adds a new directory with a path = thePath
660  */
661 //============================================================================
662 void SALOMEDS_StudyBuilder_i::AddDirectory(const char* thePath) 
663 {
664   CheckLocked();
665   if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
666
667   TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext(""), aFatherPath;
668   Handle(TDataStd_Name) aName;
669   TDF_Label aLabel;
670   SALOMEDS::SObject_var anObject = SALOMEDS_SObject_i::NewRef(_study,_doc->Main()); 
671   SALOMEDS::Study_var aStudy = anObject->GetStudy();
672
673   try { 
674     anObject = aStudy->FindObjectByPath(thePath); //Check if the directory already exists
675   }
676   catch(...) { }
677
678   if(!anObject->_is_nil()) throw SALOMEDS::Study::StudyNameAlreadyUsed(); 
679
680   if(aPath.Value(1) != '/') { //Relative path 
681     aPath.Prepend('/');
682     aPath = TCollection_AsciiString(aStudy->GetContext()) + aPath;
683   }
684
685   TCollection_AsciiString aToken = aPath.Token("/", 1);
686   if(aToken.Length() == 0) aFatherPath = "/";
687
688   int i = 1;  
689   while(aToken.Length() != 0) {
690     if(aPath.Token("/", i+1).Length() > 0) {
691       aFatherPath += "/";
692       aFatherPath += aToken;
693     }
694     aToken = aPath.Token("/", ++i);
695   }
696
697   anObject = SALOMEDS::SObject::_nil();
698   try { 
699     anObject = aStudy->FindObjectByPath(aFatherPath.ToCString()); //Check if the father directory exists
700   }
701   catch(...) { ; }
702   if(anObject->_is_nil()) 
703     throw SALOMEDS::Study::StudyInvalidDirectory(); 
704
705   SALOMEDS::SObject_var aNewObject = NewObject(anObject);
706   TDF_Tool::Label(_doc->GetData(), aNewObject->GetID(), aLabel);
707   if(aLabel.IsNull()) {
708     MESSAGE("### NULL label");
709     throw SALOMEDS::Study::StudyInvalidComponent();      
710   }
711
712   TDataStd_Name::Set(aLabel, aPath.Token("/", i-1));
713
714   //Set LocalID attribute to identify the directory object
715   SALOMEDS::GenericAttribute_var anAttr = FindOrCreateAttribute(aNewObject, "AttributeLocalID");
716   SALOMEDS::AttributeLocalID_var aPersRef = SALOMEDS::AttributeLocalID::_narrow(anAttr);
717   if(aPersRef->_is_nil()) 
718     throw SALOMEDS::Study::StudyInvalidDirectory();
719
720   aPersRef->SetValue(DIRECTORYID);
721 }
722
723
724 //============================================================================
725 /*! Function : SetGUID
726  *  Purpose  : 
727  */
728 //============================================================================
729 void SALOMEDS_StudyBuilder_i::SetGUID(SALOMEDS::SObject_ptr anObject, const char* theGUID)
730 {
731   CheckLocked();
732
733   if(CORBA::is_nil(anObject))
734     return;
735
736   TDF_Label aLabel;
737   CORBA::String_var anEntry = anObject->GetID();
738   TDF_Tool::Label(_doc->GetData(), anEntry, aLabel);
739   TDataStd_UAttribute::Set(aLabel, (char*)theGUID);
740 }
741
742 //============================================================================
743 /*! Function : IsGUID
744  *  Purpose  : 
745  */
746 //============================================================================
747 bool SALOMEDS_StudyBuilder_i::IsGUID(SALOMEDS::SObject_ptr anObject, const char* theGUID)
748 {
749   if(CORBA::is_nil(anObject))
750     return false;
751
752   TDF_Label aLabel;
753   CORBA::String_var anEntry = anObject->GetID();
754   TDF_Tool::Label(_doc->GetData(), anEntry, aLabel);
755   return aLabel.IsAttribute((char*)theGUID);
756 }
757
758
759 //============================================================================
760 /*! Function : NewCommand
761  *  Purpose  : 
762  */
763 //============================================================================
764 void SALOMEDS_StudyBuilder_i::NewCommand()
765 {
766   // mpv: for SAL2114 - unset "lock changed" flag at the operation start
767   Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
768   if (!_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(), anAttr)) {
769     anAttr = new SALOMEDS_StudyPropertiesAttribute;
770     _doc->Main().AddAttribute(anAttr);
771   }
772   anAttr->IsLockChanged(true);
773   
774   _doc->NewCommand();
775 }
776
777 //============================================================================
778 /*! Function : CommitCommand
779  *  Purpose  : 
780  */
781 //============================================================================
782 void SALOMEDS_StudyBuilder_i::CommitCommand() throw (SALOMEDS::StudyBuilder::LockProtection)
783 {
784   Unexpect aCatch(SBLockProtection);
785   Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
786   if (!_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(), anAttr)) {
787     anAttr = new SALOMEDS_StudyPropertiesAttribute;
788     _doc->Main().AddAttribute(anAttr);
789   }
790   if (anAttr->IsLocked() && !anAttr->IsLockChanged(true)) {
791     MESSAGE("Locked document modification !!!");
792     AbortCommand();
793     throw SALOMEDS::StudyBuilder::LockProtection();
794   } else {
795     SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB())->RemovePostponed(_doc->GetUndoLimit());
796
797     int aModif = anAttr->GetModified();
798     if (aModif < 0) aModif = 1000; // if user make undo and then - new transaction "modify" will never be zero
799     anAttr->SetModified(aModif+1);
800     _doc->CommitCommand();
801   }
802 }
803
804 //============================================================================
805 /*! Function : HasOpenCommand
806  *  Purpose  : 
807  */
808 //============================================================================
809 CORBA::Boolean SALOMEDS_StudyBuilder_i::HasOpenCommand()
810 {
811   return _doc->HasOpenCommand();
812 }
813
814 //============================================================================
815 /*! Function : AbortCommand
816  *  Purpose  : 
817  */
818 //============================================================================
819 void SALOMEDS_StudyBuilder_i::AbortCommand()
820 {
821   SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB())->UndoPostponed(0);
822   
823   _doc->AbortCommand();
824 }
825
826 //============================================================================
827 /*! Function : Undo
828  *  Purpose  : 
829  */
830 //============================================================================
831 void SALOMEDS_StudyBuilder_i::Undo() throw (SALOMEDS::StudyBuilder::LockProtection)
832 {
833   Unexpect aCatch(SBLockProtection);
834   Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
835   if (!_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(), anAttr)) {
836     anAttr = new SALOMEDS_StudyPropertiesAttribute;
837     _doc->Main().AddAttribute(anAttr);
838     }
839   if (anAttr->IsLocked()) {
840     MESSAGE("Locked document modification !!!");
841     throw SALOMEDS::StudyBuilder::LockProtection();
842   } else {
843     SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB())->UndoPostponed(1);
844     _doc->Undo();
845     anAttr->SetModified(anAttr->GetModified()-1);
846   }
847 }
848
849 //============================================================================
850 /*! Function : Redo
851  *  Purpose  : 
852  */
853 //============================================================================
854 void SALOMEDS_StudyBuilder_i::Redo() throw (SALOMEDS::StudyBuilder::LockProtection)
855 {
856   Unexpect aCatch(SBLockProtection);
857   Handle(SALOMEDS_StudyPropertiesAttribute) anAttr;
858   if (!_doc->Main().FindAttribute(SALOMEDS_StudyPropertiesAttribute::GetID(), anAttr)) {
859     anAttr = new SALOMEDS_StudyPropertiesAttribute;
860     _doc->Main().AddAttribute(anAttr);
861   }
862   
863   if (anAttr->IsLocked()) {
864     MESSAGE("Locked document modification !!!");
865     throw SALOMEDS::StudyBuilder::LockProtection();
866   } else {
867     _doc->Redo();
868     SALOMEDS_Study_i::GetStudy(_doc->Main(),GetORB())->UndoPostponed(-1);
869     anAttr->SetModified(anAttr->GetModified()+1);
870   }
871  }
872
873 //============================================================================
874 /*! Function : GetAvailableUndos
875  *  Purpose  : 
876  */
877 //============================================================================
878 CORBA::Boolean SALOMEDS_StudyBuilder_i::GetAvailableUndos()
879 {
880   return _doc->GetAvailableUndos();
881 }
882
883 //============================================================================
884 /*! Function : GetAvailableRedos
885  *  Purpose  : 
886  */
887 //============================================================================
888 CORBA::Boolean  SALOMEDS_StudyBuilder_i::GetAvailableRedos()
889 {
890   return _doc->GetAvailableRedos();
891 }
892
893 //============================================================================
894 /*! Function : UndoLimit
895  *  Purpose  : 
896  */
897 //============================================================================
898 CORBA::Long  SALOMEDS_StudyBuilder_i::UndoLimit()
899 {
900   return _doc->GetUndoLimit();
901 }
902
903 //============================================================================
904 /*! Function : UndoLimit
905  *  Purpose  : 
906  */
907 //============================================================================
908 void  SALOMEDS_StudyBuilder_i::UndoLimit(CORBA::Long n)
909 {
910   CheckLocked();
911   _doc->SetUndoLimit (n);
912 }
913
914 //============================================================================
915 /*! Function : SetOnAddSObject
916  *  Purpose  : 
917  */
918 //============================================================================
919 SALOMEDS::Callback_ptr SALOMEDS_StudyBuilder_i::SetOnAddSObject(SALOMEDS::Callback_ptr theCallback)
920 {
921   return _study->SetOnAddSObject(theCallback);
922 }
923
924 void SALOMEDS_StudyBuilder_i::OnAddSObject(SALOMEDS::SObject_ptr theObject)
925 {
926   _study->OnAddSObject(theObject);
927 }
928
929 //============================================================================
930 /*! Function : SetOnNewSObject
931  *  Purpose  : 
932  */
933 //============================================================================
934 SALOMEDS::Callback_ptr SALOMEDS_StudyBuilder_i::SetOnRemoveSObject(SALOMEDS::Callback_ptr theCallback)
935 {
936   return _study->SetOnRemoveSObject(theCallback);
937 }
938
939 void SALOMEDS_StudyBuilder_i::OnRemoveSObject(SALOMEDS::SObject_ptr theObject)
940 {
941   _study->OnRemoveSObject(theObject);
942 }
943
944 //============================================================================
945 /*! Function : CheckLocked
946  *  Purpose  : 
947  */
948 //============================================================================
949 void SALOMEDS_StudyBuilder_i::CheckLocked() throw (SALOMEDS::StudyBuilder::LockProtection) {
950   _study->CheckLocked();
951 }
952
953 //============================================================================
954 /*! Function : SetName
955  *  Purpose  : 
956  */
957 //============================================================================
958 void SALOMEDS_StudyBuilder_i::SetName(SALOMEDS::SObject_ptr theSO, const char* theValue)
959      throw(SALOMEDS::StudyBuilder::LockProtection)
960 {
961   Unexpect aCatch(SBLockProtection);
962   CheckLocked();
963
964   if(CORBA::is_nil(theSO))
965     return;
966
967   //Find label
968   TDF_Label aLabel;
969   CORBA::String_var aSOID = theSO->GetID();
970   TDF_Tool::Label(_doc->GetData(), aSOID, aLabel);
971   TDataStd_Name::Set(aLabel, (char*)theValue);
972 }
973
974 //============================================================================
975 /*! Function : SetComment
976  *  Purpose  : 
977  */
978 //============================================================================
979 void SALOMEDS_StudyBuilder_i::SetComment(SALOMEDS::SObject_ptr theSO, const char* theValue)
980  throw(SALOMEDS::StudyBuilder::LockProtection)
981 {
982   Unexpect aCatch(SBLockProtection);
983   CheckLocked();
984
985   if(CORBA::is_nil(theSO))
986     return;
987
988    //Find label
989   TDF_Label aLabel;
990   CORBA::String_var aSOID = theSO->GetID();
991   TDF_Tool::Label(_doc->GetData(), aSOID, aLabel);
992   TDataStd_Comment::Set(aLabel, (char*)theValue);
993 }
994
995 //============================================================================
996 /*! Function : SetIOR
997  *  Purpose  : 
998  */
999 //============================================================================
1000 void SALOMEDS_StudyBuilder_i::SetIOR(SALOMEDS::SObject_ptr theSO, const char* theValue)
1001  throw(SALOMEDS::StudyBuilder::LockProtection)
1002 {
1003   Unexpect aCatch(SBLockProtection);
1004   CheckLocked();
1005
1006   if(CORBA::is_nil(theSO))
1007     return;
1008
1009   //Find label
1010   TDF_Label aLabel;
1011   CORBA::String_var aSOID = theSO->GetID();
1012   TDF_Tool::Label(_doc->GetData(), aSOID, aLabel);
1013   SALOMEDS_IORAttribute::Set(aLabel, TCollection_ExtendedString((char*)theValue),GetORB());
1014 }