Salome HOME
CCAR: add a check to see if the CORBA object exists (non_existent())
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_StudyBuilder.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  File   : SALOMEDSImpl_StudyBuilder.cxx
23 //  Author : Sergey RUIN
24 //  Module : SALOME
25 //
26 #include "SALOMEDSImpl_Attributes.hxx"
27 #include "SALOMEDSImpl_Study.hxx"
28 #include "SALOMEDSImpl_StudyBuilder.hxx"
29 #include "SALOMEDSImpl_SObject.hxx"
30 #include "SALOMEDSImpl_SComponent.hxx"
31 #include "SALOMEDSImpl_Tool.hxx"
32 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
33
34 #include "DF_ChildIterator.hxx"
35 #include "DF_Label.hxx"
36
37 #include <HDFOI.hxx>
38 #include <stdlib.h> 
39 #include <string.h> 
40
41 using namespace std;
42
43 #define USE_CASE_LABEL_TAG            2
44 #define DIRECTORYID                   16661
45 #define FILELOCALID                   26662 
46
47 static void Translate_persistentID_to_IOR(DF_Label& Lab, SALOMEDSImpl_Driver* driver, bool isMultiFile, bool isASCII);
48
49 //============================================================================
50 /*! Function : constructor
51  *  Purpose  :
52  */
53 //============================================================================
54 SALOMEDSImpl_StudyBuilder::SALOMEDSImpl_StudyBuilder(const SALOMEDSImpl_Study* theOwner)
55 {
56    _errorCode = "";
57   _callbackOnAdd=NULL;
58   _callbackOnRemove = NULL;
59    _study = (SALOMEDSImpl_Study*)theOwner;
60    _doc = _study->GetDocument();
61 }
62
63 //============================================================================
64 /*! Function : destructor
65  *  Purpose  :
66  */
67 //============================================================================
68 SALOMEDSImpl_StudyBuilder::~SALOMEDSImpl_StudyBuilder()
69 {}
70
71 //============================================================================
72 /*! Function : NewComponent
73  *  Purpose  : Create a new component (Scomponent)
74  */
75 //============================================================================
76 SALOMEDSImpl_SComponent SALOMEDSImpl_StudyBuilder::NewComponent(const string& DataType)
77 {
78   _errorCode = "";
79   CheckLocked();
80
81   SALOMEDSImpl_SComponent sco;
82
83   if(DataType.size() == 0) return sco;
84
85   //Always create component under main label.
86   DF_Label L  = _doc->Main();
87
88   DF_Label NL = L.NewChild();
89
90   SALOMEDSImpl_AttributeComment::Set(NL, DataType);
91
92   SALOMEDSImpl_SComponent so =  _study->GetSComponent (NL);
93
94   if(_callbackOnAdd) _callbackOnAdd->OnAddSObject(so);
95
96   _doc->SetModified(true);
97
98   return so;
99 }
100
101 //============================================================================
102 /*! Function : DefineComponentInstance
103  *  Purpose  : Add IOR attribute of a Scomponent
104  */
105 //============================================================================
106 bool SALOMEDSImpl_StudyBuilder::DefineComponentInstance(const SALOMEDSImpl_SComponent& aComponent,
107                                                         const string& IOR)
108 {
109    _errorCode = "";
110
111   CheckLocked();
112   if(!aComponent || IOR.empty()) {
113     _errorCode = "Invalid arguments";
114     return false;
115   }
116   //add IOR definition 
117   SALOMEDSImpl_AttributeIOR::Set(aComponent.GetLabel(), IOR);  
118
119   return true;
120 }
121
122 //============================================================================
123 /*! Function : RemoveComponent
124  *  Purpose  : Delete a Scomponent
125  */
126 //============================================================================
127 bool SALOMEDSImpl_StudyBuilder::RemoveComponent(const SALOMEDSImpl_SComponent& aComponent)
128 {
129    _errorCode = "";
130   CheckLocked();
131   return RemoveObject(aComponent);
132 }
133
134 //============================================================================
135 /*! Function : NewObject
136  *  Purpose  : Create a new SObject
137  */
138 //============================================================================
139 SALOMEDSImpl_SObject SALOMEDSImpl_StudyBuilder::NewObject(const SALOMEDSImpl_SObject& theFatherObject)
140 {
141   _errorCode = "";
142   CheckLocked();
143
144   //Find label of father
145   DF_Label Lab = theFatherObject.GetLabel();
146   
147   //Create a new label
148   DF_Label NewLab = Lab.NewChild();
149   
150   SALOMEDSImpl_SObject so = _study->GetSObject(NewLab);
151   if(_callbackOnAdd) _callbackOnAdd->OnAddSObject(so);
152
153   _doc->SetModified(true);  
154   return so;
155 }
156
157 //============================================================================
158 /*! Function : NewObjectToTag
159  *  Purpose  :
160  */
161 //============================================================================
162 SALOMEDSImpl_SObject SALOMEDSImpl_StudyBuilder::NewObjectToTag(const SALOMEDSImpl_SObject& theFatherObject,
163                                                         const int theTag)
164 {
165   _errorCode = "";
166   CheckLocked();
167   //Find label of father
168   DF_Label Lab = theFatherObject.GetLabel();
169
170   //Create or find label
171   DF_Label NewLab = Lab.FindChild(theTag, 1);
172
173   SALOMEDSImpl_SObject so = _study->GetSObject(NewLab);
174
175   if(_callbackOnAdd) _callbackOnAdd->OnAddSObject(so);
176
177   _doc->SetModified(true);  
178   return so;
179 }
180
181 //============================================================================
182 /*! Function : RemoveObject
183  *  Purpose  :
184  */
185 //============================================================================
186 bool SALOMEDSImpl_StudyBuilder::RemoveObject(const SALOMEDSImpl_SObject& anObject)
187 {
188    _errorCode = "";
189   CheckLocked();
190   if(!anObject) {
191     _errorCode = "Null object";
192     return false;
193   }
194
195   if(_callbackOnRemove) _callbackOnRemove->OnRemoveSObject(anObject);
196
197   DF_Label Lab = anObject.GetLabel();
198
199   SALOMEDSImpl_AttributeReference* aReference = NULL;
200   if ((aReference=(SALOMEDSImpl_AttributeReference*)Lab.FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
201     SALOMEDSImpl_AttributeTarget* aTarget = NULL;
202     if ((aTarget=(SALOMEDSImpl_AttributeTarget*)aReference->Get().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID())))
203       aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
204   }
205
206   SALOMEDSImpl_AttributeIOR* anAttr = NULL; //Remove from IORLabel map
207   if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
208     _study->DeleteIORLabelMapItem(anAttr->Value());
209   }
210
211   Lab.ForgetAllAttributes();
212  
213   _doc->SetModified(true);  
214     
215   return true;
216 }
217
218 //============================================================================
219 /*! Function : RemoveObjectWithChildren
220  *  Purpose  :
221  */
222 //============================================================================
223 bool SALOMEDSImpl_StudyBuilder::RemoveObjectWithChildren(const SALOMEDSImpl_SObject& anObject)
224 {
225    _errorCode = "";
226   CheckLocked();
227   if(!anObject) {
228     _errorCode = "Null object";
229     return false;
230   }
231
232   if(_callbackOnRemove) _callbackOnRemove->OnRemoveSObject(anObject);
233
234   DF_Label Lab = anObject.GetLabel();
235
236   SALOMEDSImpl_AttributeReference* aReference = NULL;
237   if ((aReference=(SALOMEDSImpl_AttributeReference*)Lab.FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
238     SALOMEDSImpl_AttributeTarget* aTarget = NULL;
239     if ((aTarget=(SALOMEDSImpl_AttributeTarget*)aReference->Get().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID())))
240       aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
241   }
242   SALOMEDSImpl_AttributeIOR* anAttr = NULL; //Remove from IORLabel map
243   if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
244     _study->DeleteIORLabelMapItem(anAttr->Value());
245   }
246
247   DF_ChildIterator it(Lab, true);
248   for(;it.More();it.Next()) {
249     DF_Label aLabel = it.Value();
250     if ((aReference=(SALOMEDSImpl_AttributeReference*)aLabel.FindAttribute(SALOMEDSImpl_AttributeReference::GetID()))) {
251       SALOMEDSImpl_AttributeTarget* aTarget = NULL;
252       if ((aTarget=(SALOMEDSImpl_AttributeTarget*)aReference->Get().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID())))
253         aTarget->Remove(SALOMEDSImpl_Study::SObject(aLabel));
254     }
255     SALOMEDSImpl_AttributeIOR* anAttr = NULL; //Remove from IORLabel map
256     if ((anAttr=(SALOMEDSImpl_AttributeIOR*)aLabel.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
257       _study->DeleteIORLabelMapItem(anAttr->Value());
258     }
259   }
260
261   Lab.ForgetAllAttributes(true);
262
263   _doc->SetModified(true);  
264   
265   return true;
266 }
267
268 //============================================================================
269 /*! Function : LoadWith
270  *  Purpose  : 
271  */
272 //============================================================================
273 bool SALOMEDSImpl_StudyBuilder::LoadWith(const SALOMEDSImpl_SComponent& anSCO,
274                                          SALOMEDSImpl_Driver* aDriver) 
275 {
276   _errorCode = "";
277
278   DF_Label Lab = anSCO.GetLabel();
279   SALOMEDSImpl_AttributePersistentRef* Att = NULL;
280
281   //Find the current Url of the study  
282   if ((Att=(SALOMEDSImpl_AttributePersistentRef*)_doc->Main().FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {
283     int aLocked = _study->GetProperties()->IsLocked();
284     if (aLocked) _study->GetProperties()->SetLocked(false);
285
286     std::string Res(Att->Value());
287     string aHDFPath(Res);
288
289     SALOMEDSImpl_AttributeComment* type = NULL;
290     std::string DataType;
291     if ((type=(SALOMEDSImpl_AttributeComment*)Lab.FindAttribute(SALOMEDSImpl_AttributeComment::GetID())))
292       DataType = type->Value();
293
294     // associate the driver to the SComponent
295     if(aDriver == NULL) {
296       _errorCode = "Driver is null";
297       return false;
298     }
299
300     // mpv 06.03.2003: SAL1927 - if component data if already loaded, it is not necessary to do it again
301     SALOMEDSImpl_AttributeIOR* attrIOR = NULL;
302     if ((attrIOR=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
303       if (aLocked) _study->GetProperties()->SetLocked(true);
304       return true;
305     }
306
307     DefineComponentInstance (anSCO, aDriver->GetIOR());
308
309     string aHDFUrl;
310     bool isASCII = false;
311     if (HDFascii::isASCII(aHDFPath.c_str())) {
312       isASCII = true;
313       aHDFUrl = HDFascii::ConvertFromASCIIToHDF(aHDFPath.c_str());
314       aHDFUrl += "hdf_from_ascii.hdf";
315     } else {
316       aHDFUrl = aHDFPath;
317     }
318
319     //Open the Study HDF file 
320     HDFfile *hdf_file = new HDFfile((char*)aHDFUrl.c_str()); 
321
322     char aMultifileState[2];
323     char ASCIIfileState[2];
324     try {
325       string scoid = anSCO.GetID();
326       hdf_file->OpenOnDisk(HDF_RDONLY);
327       HDFgroup *hdf_group = new HDFgroup("DATACOMPONENT",hdf_file);
328       hdf_group->OpenOnDisk();
329       HDFgroup *hdf_sco_group = new HDFgroup((char*)scoid.c_str(), hdf_group);
330       hdf_sco_group->OpenOnDisk();
331
332       unsigned char* aStreamFile = NULL;
333       int aStreamSize = 0;
334
335       if (hdf_sco_group->ExistInternalObject("FILE_STREAM")) {
336         HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group);
337         hdf_dataset->OpenOnDisk();
338         aStreamSize = hdf_dataset->GetSize();
339         aStreamFile  = new unsigned char[aStreamSize];
340         if(aStreamFile == NULL) throw HDFexception("Unable to open dataset FILE_STREAM");
341         hdf_dataset->ReadFromDisk(aStreamFile);
342         hdf_dataset->CloseOnDisk();
343         hdf_dataset = 0;
344       } else
345         aStreamFile = NULL;
346
347       HDFdataset *multifile_hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group);
348       multifile_hdf_dataset->OpenOnDisk();
349       multifile_hdf_dataset->ReadFromDisk(aMultifileState);
350
351       HDFdataset *ascii_hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group);
352       ascii_hdf_dataset->OpenOnDisk();
353       ascii_hdf_dataset->ReadFromDisk(ASCIIfileState);
354
355       string aDir = SALOMEDSImpl_Tool::GetDirFromPath(Res);
356
357       bool aResult = (ASCIIfileState[0]=='A')?
358         aDriver->LoadASCII(anSCO, aStreamFile, aStreamSize, aDir.c_str(), aMultifileState[0]=='M'):
359         aDriver->Load(anSCO, aStreamFile, aStreamSize, aDir.c_str(), aMultifileState[0]=='M');
360
361       if(aStreamFile != NULL) delete []aStreamFile; 
362
363       if(!aResult) {
364         RemoveAttribute( anSCO, "AttributeIOR" );
365
366         _errorCode = "Can't load component";
367         throw HDFexception("Unable to load component");
368       }
369
370       //if(aDir != NULL) delete []aDir;
371
372       multifile_hdf_dataset->CloseOnDisk();
373       multifile_hdf_dataset = 0;
374       ascii_hdf_dataset->CloseOnDisk();
375       ascii_hdf_dataset = 0;
376
377       hdf_sco_group->CloseOnDisk();
378       hdf_sco_group = 0;
379       hdf_group->CloseOnDisk();
380       hdf_group = 0;
381       hdf_file->CloseOnDisk();
382       delete hdf_file;
383
384       if (isASCII) {
385         vector<string> aFilesToRemove;
386         aFilesToRemove.push_back("hdf_from_ascii.hdf");
387         SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl),
388                                                 aFilesToRemove, true);
389       }      
390     }
391     catch (HDFexception) {
392       delete hdf_file;
393
394       if (isASCII) {
395         vector<string> aFilesToRemove;
396         aFilesToRemove.push_back(aHDFUrl);
397         SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
398       }
399
400       if (aLocked) _study->GetProperties()->SetLocked(true);
401       _errorCode = "No persistent file";   
402       return false;
403     }
404
405     try {
406       Translate_persistentID_to_IOR (Lab, aDriver, aMultifileState[0]=='M', ASCIIfileState[0] == 'A');
407     } catch(...) {
408       _errorCode = "Can not convert persistent IDs to IORs";
409       return false;
410     }
411
412     if (aLocked) _study->GetProperties()->SetLocked(true);
413   } else {
414     _errorCode = "No persistent file";   
415   }
416
417   return true;
418 }
419
420
421 //============================================================================
422 /*! Function : Load
423  *  Purpose  : 
424  */
425 //============================================================================
426 bool SALOMEDSImpl_StudyBuilder::Load(const SALOMEDSImpl_SObject& sco)
427 {
428   _errorCode = "Not implemented";
429   return false;
430 }
431
432 //============================================================================
433 /*! Function : FindOrCreateAttribute
434  *  Purpose  : Add attribute of given type to SObject, if there is attribute of such type, returns
435  *  existing one
436  */
437 //============================================================================
438 DF_Attribute* SALOMEDSImpl_StudyBuilder::FindOrCreateAttribute(const SALOMEDSImpl_SObject& anObject, 
439                                                                const string& aTypeOfAttribute)
440 {
441   _errorCode = "";
442   if(!anObject) {
443     _errorCode = "Invalid arguments";
444     return NULL;
445   }
446
447   DF_Label Lab = anObject.GetLabel();
448   if(Lab.IsNull()) {
449     _errorCode = "Null label";
450     return NULL;
451   }
452
453   _doc->SetModified(true);  
454
455   //The macro adds all necessary checks for standardly behaiving attributes
456   __FindOrCreateAttributeForBuilder
457
458  
459   //Add checks for TreeNode and UserID attributes  
460   if (strncmp(aTypeOfAttribute.c_str(), "AttributeTreeNode",17) == 0 ) {
461     
462     string aTreeNodeGUID;
463     if (strcmp(aTypeOfAttribute.c_str(), "AttributeTreeNode") == 0) {
464       aTreeNodeGUID = SALOMEDSImpl_AttributeTreeNode::GetDefaultTreeID();
465     } else {
466       aTreeNodeGUID = aTypeOfAttribute.substr(21, aTypeOfAttribute.size()); // create tree node GUID by name
467     }
468     SALOMEDSImpl_AttributeTreeNode* anAttr = NULL;
469     if (!(anAttr=(SALOMEDSImpl_AttributeTreeNode*)Lab.FindAttribute(aTreeNodeGUID))) {
470       CheckLocked();
471       anAttr = SALOMEDSImpl_AttributeTreeNode::Set(Lab, aTreeNodeGUID);
472     }
473     return anAttr;
474   }
475
476   if (strncmp(aTypeOfAttribute.c_str(), "AttributeUserID",15) == 0 ) {
477     std::string aUserGUID;
478     if (strcmp(aTypeOfAttribute.c_str(), "AttributeUserID") == 0) {
479       aUserGUID = SALOMEDSImpl_AttributeUserID::DefaultID();
480     } else {
481       aUserGUID = aTypeOfAttribute.substr(15, aTypeOfAttribute.size()); // create tree node GUID by name
482     }
483     SALOMEDSImpl_AttributeUserID* anAttr = NULL;
484     if (!(anAttr=(SALOMEDSImpl_AttributeUserID*)Lab.FindAttribute(aUserGUID))) {
485       CheckLocked();
486       anAttr = SALOMEDSImpl_AttributeUserID::Set(Lab, aUserGUID);
487     }
488     return anAttr;
489   }
490   _errorCode = "Can not create an attribute";
491
492   return NULL;
493 }
494
495 //============================================================================
496 /*! Function : FindAttribute
497  *  Purpose  : Find attribute of given type assigned SObject, returns Standard_True if it is found
498  */
499 //============================================================================
500
501 bool SALOMEDSImpl_StudyBuilder::FindAttribute(const SALOMEDSImpl_SObject& anObject, 
502                                               DF_Attribute*& anAttribute, 
503                                               const string& aTypeOfAttribute)
504 {
505   _errorCode = "";
506   if(!anObject) {
507     _errorCode = "Invalid arguments";
508     return false;
509   }
510   DF_Label Lab = anObject.GetLabel();
511   if ((anAttribute=Lab.FindAttribute(SALOMEDSImpl_SObject::GetGUID(aTypeOfAttribute)))) {
512     // commented out because NO MODIFICATION is done to attributes when calling FindAttribute()
513     // _doc->Modify();  
514     return true;
515   }
516   return false;
517 }
518
519 //============================================================================
520 /*! Function : RemoveAttribute
521  *  Purpose  : Remove attribute of given type assigned SObject
522  */
523 //============================================================================
524
525 bool SALOMEDSImpl_StudyBuilder::RemoveAttribute(const SALOMEDSImpl_SObject& anObject, 
526                                                 const string& aTypeOfAttribute)
527 {
528   _errorCode = "";
529   CheckLocked();
530   if(!anObject) {
531     _errorCode = "Invalid arguments";
532     return false;
533   }
534   DF_Label Lab = anObject.GetLabel();
535   
536   if (aTypeOfAttribute == string("AttributeIOR")) { // Remove from IORLabel map
537     SALOMEDSImpl_AttributeIOR* anAttr = NULL;
538     if ((anAttr=(SALOMEDSImpl_AttributeIOR*)Lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
539       _study->DeleteIORLabelMapItem(anAttr->Value());
540     }
541   }
542
543   Lab.ForgetAttribute (SALOMEDSImpl_SObject::GetGUID(aTypeOfAttribute));
544     
545   _doc->SetModified(true);  
546     
547   return true;
548 }
549
550 //============================================================================
551 /*! Function : Addreference
552  *  Purpose  : 
553  */
554 //============================================================================
555 bool SALOMEDSImpl_StudyBuilder::Addreference(const SALOMEDSImpl_SObject& me, 
556                                              const SALOMEDSImpl_SObject& theReferencedObject)
557 {
558   _errorCode = "";
559   if(!me || !theReferencedObject) {
560    _errorCode = "Invalid arguments";
561    return false;
562   }
563   CheckLocked();
564   DF_Label Lab = me.GetLabel();
565   DF_Label RefLab = theReferencedObject.GetLabel();
566   SALOMEDSImpl_AttributeReference::Set(Lab,RefLab);
567
568   SALOMEDSImpl_AttributeTarget::Set(RefLab)->Add(SALOMEDSImpl_Study::SObject(Lab));
569
570   if(_callbackOnRemove && Lab.IsDescendant(_doc->Main())) _callbackOnRemove->OnRemoveSObject(me);
571   
572   return true;
573 }
574
575 //============================================================================
576 /*! Function : RemoveReference
577  *  Purpose  : 
578  */
579 //============================================================================
580 bool SALOMEDSImpl_StudyBuilder::RemoveReference(const SALOMEDSImpl_SObject& me)
581 {
582   _errorCode = "";
583   SALOMEDSImpl_SObject theReferencedObject;
584   
585   if(!me.ReferencedObject(theReferencedObject)) return false;  //No reference is found
586   
587   CheckLocked();
588   DF_Label Lab = me.GetLabel();
589
590   //SRN: 30 Aug, 2004 : fix from Ecole l'ete version 
591
592   DF_Label RefLab = theReferencedObject.GetLabel();
593        
594   SALOMEDSImpl_AttributeTarget* aTarget = NULL;
595   if((aTarget=(SALOMEDSImpl_AttributeTarget*)RefLab.FindAttribute(SALOMEDSImpl_AttributeTarget::GetID()))) {
596     aTarget->Remove(SALOMEDSImpl_Study::SObject(Lab));
597   }
598   
599   Lab.ForgetAttribute(SALOMEDSImpl_AttributeReference::GetID());  
600   
601   _doc->SetModified(true);  
602   
603   return true;
604 }
605
606
607
608 //============================================================================
609 /*! Function : AddDirectory
610  *  Purpose  : adds a new directory with a path = thePath
611  */
612 //============================================================================
613 bool SALOMEDSImpl_StudyBuilder::AddDirectory(const string& thePath) 
614 {
615   _errorCode = "";
616   CheckLocked();
617   if(thePath.empty()) {
618     _errorCode = "Invalid path";
619     return false;
620   }
621
622   string aPath(thePath), aContext(""), aFatherPath;
623   DF_Label aLabel;
624   SALOMEDSImpl_SObject anObject;
625
626   try { 
627     anObject = _study->FindObjectByPath(thePath); //Check if the directory already exists
628   }
629   catch(...) { }
630
631   if(anObject) {
632     _errorCode = "StudyNameAlreadyUsed";
633     return false; 
634   }
635
636   if(aPath[0] != '/') { //Relative path 
637     aPath.insert(aPath.begin(), '/');
638     aPath = _study->GetContext() + aPath;
639   }
640
641   vector<string> vs = SALOMEDSImpl_Tool::splitString(aPath, '/');
642   if(vs.size() == 1) 
643     aFatherPath = "/";
644   else {
645     for(int i = 0, len = vs.size()-1; i<len; i++) { 
646       aFatherPath += "/";
647       aFatherPath += vs[i];
648     }
649   }
650
651   try { 
652     anObject = _study->FindObjectByPath(aFatherPath); //Check if the father directory exists
653   }
654   catch(...) { ; }
655   if(!anObject) {
656     _errorCode = "StudyInvalidDirectory";
657     return false; 
658   }
659
660   SALOMEDSImpl_SObject aNewObject = NewObject(anObject);
661   aLabel = aNewObject.GetLabel();
662   if(aLabel.IsNull()) {
663     _errorCode = "StudyInvalidComponent";
664     return false;
665   }
666
667   SALOMEDSImpl_AttributeName::Set(aLabel, vs.back());
668
669   //Set LocalID attribute to identify the directory object
670   SALOMEDSImpl_AttributeLocalID::Set(aLabel, DIRECTORYID);
671   
672   _doc->SetModified(true); 
673   
674   return true;
675 }
676
677
678 //============================================================================
679 /*! Function : SetGUID
680  *  Purpose  : 
681  */
682 //============================================================================
683 bool SALOMEDSImpl_StudyBuilder::SetGUID(const SALOMEDSImpl_SObject& anObject, 
684                                         const string& theGUID)
685 {
686   _errorCode = "";
687   CheckLocked();
688   if(!anObject) {
689     _errorCode = "Invalid arguments";
690     return false;
691   }
692
693   DF_Label aLabel = anObject.GetLabel();
694   SALOMEDSImpl_AttributeUserID::Set(aLabel, theGUID);
695
696   _doc->SetModified(true);  
697
698   return true;
699 }
700
701 //============================================================================
702 /*! Function : IsGUID
703  *  Purpose  : 
704  */
705 //============================================================================
706 bool SALOMEDSImpl_StudyBuilder::IsGUID(const SALOMEDSImpl_SObject& anObject, 
707                                        const string& theGUID)
708 {
709   _errorCode = "";
710   if(!anObject) {
711     _errorCode = "Invalid arguments";
712     return false;
713   }
714   DF_Label aLabel = anObject.GetLabel();
715   return aLabel.IsAttribute(theGUID);
716 }
717
718
719 //============================================================================
720 /*! Function : NewCommand
721  *  Purpose  : 
722  */
723 //============================================================================
724 void SALOMEDSImpl_StudyBuilder::NewCommand()
725 {
726   _errorCode = "";
727
728   // mpv: for SAL2114 - unset "lock changed" flag at the operation start
729   _study->GetProperties()->IsLockChanged(true);
730
731   //Not implemented
732 }
733
734 //============================================================================
735 /*! Function : CommitCommand
736  *  Purpose  : 
737  */
738 //============================================================================
739 void SALOMEDSImpl_StudyBuilder::CommitCommand()
740 {
741   _errorCode = "";
742   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
743   if (anAttr->IsLocked() && !anAttr->IsLockChanged(true)) {
744     _errorCode = "LockProtection";
745     throw LockProtection("LockProtection");
746   } else {
747     int aModif = anAttr->GetModified();
748     if (aModif < 0) aModif = 1000; // if user make undo and then - new transaction "modify" will never be zero
749     anAttr->SetModified(aModif+1);
750   }
751   
752
753   //Not implemented
754   _doc->SetModified(true);  
755 }
756
757 //============================================================================
758 /*! Function : HasOpenCommand
759  *  Purpose  : 
760  */
761 //============================================================================
762 bool SALOMEDSImpl_StudyBuilder::HasOpenCommand()
763 {
764   _errorCode = "";
765
766   //Not implememnted
767   return false;
768 }
769
770 //============================================================================
771 /*! Function : AbortCommand
772  *  Purpose  : 
773  */
774 //============================================================================
775 void SALOMEDSImpl_StudyBuilder::AbortCommand()
776 {
777   _errorCode = "";
778   //Not implemented    
779 }
780
781 //============================================================================
782 /*! Function : Undo
783  *  Purpose  : 
784  */
785 //============================================================================
786 void SALOMEDSImpl_StudyBuilder::Undo()
787 {
788   //Not implemented
789   _errorCode = "";
790   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
791   if (anAttr->IsLocked()) {
792     _errorCode = "LockProtection";
793     throw LockProtection("LockProtection");
794   } else {
795     anAttr->SetModified(anAttr->GetModified()-1);
796   }
797
798   _doc->SetModified(true);  
799 }
800
801 //============================================================================
802 /*! Function : Redo
803  *  Purpose  : 
804  */
805 //============================================================================
806 void SALOMEDSImpl_StudyBuilder::Redo() 
807 {
808   _errorCode = "";
809   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
810   if (anAttr->IsLocked()) {
811     _errorCode = "LockProtection";
812     throw LockProtection("LockProtection");
813   } else {
814     anAttr->SetModified(anAttr->GetModified()+1);
815   }
816
817   //Not implemented
818
819   _doc->SetModified(true);  
820 }
821
822 //============================================================================
823 /*! Function : GetAvailableUndos
824  *  Purpose  : 
825  */
826 //============================================================================
827 bool SALOMEDSImpl_StudyBuilder::GetAvailableUndos()
828 {
829   _errorCode = "";
830   return false;
831 }
832
833 //============================================================================
834 /*! Function : GetAvailableRedos
835  *  Purpose  : 
836  */
837 //============================================================================
838 bool  SALOMEDSImpl_StudyBuilder::GetAvailableRedos()
839 {
840   _errorCode = "";
841   return false;
842 }
843
844 //============================================================================
845 /*! Function : UndoLimit
846  *  Purpose  : 
847  */
848 //============================================================================
849 int  SALOMEDSImpl_StudyBuilder::UndoLimit()
850 {
851   _errorCode = "";
852   return 1;
853 }
854
855 //============================================================================
856 /*! Function : UndoLimit
857  *  Purpose  : 
858  */
859 //============================================================================
860 void SALOMEDSImpl_StudyBuilder::UndoLimit(int n)
861 {
862   _errorCode = "";
863   CheckLocked();
864   //Not implemented
865 }
866
867 //============================================================================
868 /*! Function : SetOnAddSObject
869  *  Purpose  : 
870  */
871 //============================================================================
872 SALOMEDSImpl_Callback*
873 SALOMEDSImpl_StudyBuilder::SetOnAddSObject(const SALOMEDSImpl_Callback* theCallback)
874 {
875   _errorCode = "";
876   SALOMEDSImpl_Callback* aRet = _callbackOnAdd;
877   _callbackOnAdd = (SALOMEDSImpl_Callback*)theCallback;
878   return aRet;
879 }
880
881 //============================================================================
882 /*! Function : SetOnNewSObject
883  *  Purpose  : 
884  */
885 //============================================================================
886 SALOMEDSImpl_Callback* 
887 SALOMEDSImpl_StudyBuilder::SetOnRemoveSObject(const SALOMEDSImpl_Callback* theCallback)
888 {
889   _errorCode = "";
890   SALOMEDSImpl_Callback* aRet = _callbackOnRemove;
891   _callbackOnRemove = (SALOMEDSImpl_Callback*)theCallback;
892   return aRet;
893 }
894
895 //============================================================================
896 /*! Function : CheckLocked
897  *  Purpose  : 
898  */
899 //============================================================================
900 void SALOMEDSImpl_StudyBuilder::CheckLocked()
901 {
902   _errorCode = "";
903   if (HasOpenCommand()) return;
904   SALOMEDSImpl_AttributeStudyProperties* anAttr = _study->GetProperties();
905   if (anAttr->IsLocked()) {
906     _errorCode = "LockProtection";
907     throw LockProtection("LockProtection");
908   }
909 }
910
911 //============================================================================
912 /*! Function : SetName
913  *  Purpose  : 
914  */
915 //============================================================================
916 bool SALOMEDSImpl_StudyBuilder::SetName(const SALOMEDSImpl_SObject& theSO, 
917                                         const string& theValue)
918 {
919   _errorCode = "";
920   CheckLocked();
921   if(!theSO) {
922     _errorCode = "Invalid arguments";
923     return false;
924   }
925   SALOMEDSImpl_AttributeName::Set(theSO.GetLabel(), theValue);
926
927   _doc->SetModified(true);  
928
929   return true;
930 }
931
932 //============================================================================
933 /*! Function : SetComment
934  *  Purpose  : 
935  */
936 //============================================================================
937 bool SALOMEDSImpl_StudyBuilder::SetComment(const SALOMEDSImpl_SObject& theSO, 
938                                            const string& theValue)
939 {
940   _errorCode = "";
941   CheckLocked();
942   if(!theSO) {
943     _errorCode = "Invalid arguments";
944     return false;
945   }
946   SALOMEDSImpl_AttributeComment::Set(theSO.GetLabel(), theValue);
947
948   _doc->SetModified(true);  
949
950   return true;
951 }
952
953 //============================================================================
954 /*! Function : SetIOR
955  *  Purpose  : 
956  */
957 //============================================================================
958 bool SALOMEDSImpl_StudyBuilder::SetIOR(const SALOMEDSImpl_SObject& theSO, 
959                                        const string& theValue)
960 {
961   _errorCode = "";
962   CheckLocked();
963   if(!theSO) {
964     _errorCode = "Invalid arguments";
965     return false;
966   }
967   SALOMEDSImpl_AttributeIOR::Set(theSO.GetLabel(), theValue);
968
969   _doc->SetModified(true);  
970
971   return true;
972 }
973
974
975 //============================================================================
976 /*! Function : Translate_persistentID_to_IOR
977  *  Purpose  :
978  */
979 //============================================================================
980 static void Translate_persistentID_to_IOR(DF_Label& Lab, SALOMEDSImpl_Driver* driver, bool isMultiFile, bool isASCII)
981 {
982   if(driver == NULL) return;
983   DF_ChildIterator  itchild (Lab);
984   
985   for (; itchild.More(); itchild.Next()) {
986     DF_Label current = itchild.Value();
987     SALOMEDSImpl_AttributePersistentRef* Att = NULL;
988     if ((Att=(SALOMEDSImpl_AttributePersistentRef*)current.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {  
989
990       SALOMEDSImpl_AttributeLocalID* anID = NULL;
991       if ((anID=(SALOMEDSImpl_AttributeLocalID*)current.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) 
992         if (anID->Value() == FILELOCALID) continue;   //SRN: This attribute store a file name, skip it 
993
994       string persist_ref = Att->Value();
995       SALOMEDSImpl_SObject so = SALOMEDSImpl_Study::SObject(current);
996       string ior_string = driver->LocalPersistentIDToIOR(so, 
997                                                          persist_ref, 
998                                                          isMultiFile, 
999                                                          isASCII);
1000       SALOMEDSImpl_AttributeIOR::Set (current, ior_string); 
1001      
1002     }
1003     Translate_persistentID_to_IOR (current, driver, isMultiFile, isASCII);
1004   }
1005 }
1006