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