Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/kernel.git] / src / SALOMEDSImpl / SALOMEDSImpl_Study.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20 //  File   : SALOMEDSImpl_Study.cxx
21 //  Author : Sergey RUIN
22 //  Module : SALOME
23
24
25 #include "SALOMEDSImpl_Study.hxx"
26
27 using namespace std;
28
29 #include "DF_Application.hxx"
30 #include "DF_ChildIterator.hxx"
31
32 #include "SALOMEDSImpl_ChildNodeIterator.hxx"
33 #include "SALOMEDSImpl_Attributes.hxx"
34 #include "SALOMEDSImpl_UseCaseIterator.hxx"
35 #include "SALOMEDSImpl_AttributeReference.hxx"
36 #include "SALOMEDSImpl_StudyHandle.hxx"
37 #include "SALOMEDSImpl_Tool.hxx"
38 #include "SALOMEDSImpl_IParameters.hxx"
39
40 #include <fstream>
41
42 #define DIRECTORYID       16661
43 #define FILELOCALID       26662
44 #define FILEID            "FILE: "
45
46
47 //============================================================================
48 /*! Function : SALOMEDSImpl_Study
49  *  Purpose  : SALOMEDSImpl_Study constructor
50  */
51 //============================================================================
52 SALOMEDSImpl_Study::SALOMEDSImpl_Study(const DF_Document* doc,
53                                        const string& study_name)
54 {
55   _name = study_name;
56   _doc = (DF_Document*)doc;
57   _Saved = false ;
58   _URL = "";
59   _StudyId = -1;
60   _autoFill = false;
61   _errorCode = "";
62   _useCaseBuilder = new SALOMEDSImpl_UseCaseBuilder(_doc);
63   _builder = new SALOMEDSImpl_StudyBuilder(this);
64   _cb = new SALOMEDSImpl_Callback(_useCaseBuilder);
65   //Put on the root label a StudyHandle attribute to store the address of this object
66   //It will be used to retrieve the study object by DF_Label that belongs to the study
67   SALOMEDSImpl_StudyHandle::Set(_doc->Main().Root(), this);
68 }
69
70
71 //============================================================================
72 /*! Function : ~SALOMEDSImpl_Study
73  *  Purpose  : SALOMEDSImpl_Study destructor
74  */
75 //============================================================================
76 SALOMEDSImpl_Study::~SALOMEDSImpl_Study()
77 {}
78
79 //============================================================================
80 /*! Function : GetPersistentReference
81  *  Purpose  : Get persistent reference of study (idem URL())
82  */
83 //============================================================================
84 string SALOMEDSImpl_Study::GetPersistentReference()
85 {
86   _errorCode = "";
87   return URL();
88 }
89 //============================================================================
90 /*! Function : GetTransientReference
91  *  Purpose  : Get IOR of the Study (registred in Document in doc->Root)
92  */
93 //============================================================================
94 string SALOMEDSImpl_Study::GetTransientReference()
95 {
96   _errorCode = "";
97   string IOR = "";
98
99   SALOMEDSImpl_AttributeIOR* Att;
100   DF_Label _lab = _doc->Root();
101   if ((Att=(SALOMEDSImpl_AttributeIOR*)_lab.FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
102     IOR = Att->Value();
103   }
104   else {
105     _errorCode = "IOR is empty";
106   }
107
108   return IOR;
109 }
110
111 void SALOMEDSImpl_Study::SetTransientReference(const string& theIOR)
112 {
113   _errorCode = "";
114
115   SALOMEDSImpl_AttributeStudyProperties* aProp = GetProperties();
116   int aLocked = aProp->IsLocked();
117   if (aLocked) aProp->SetLocked(false);
118
119   // Assign the value of the IOR in the study->root
120   SALOMEDSImpl_AttributeIOR::Set(_doc->Main().Root(), theIOR);
121
122   if (aLocked) aProp->SetLocked(true);
123 }
124
125 //============================================================================
126 /*! Function : IsEmpty
127  *  Purpose  : Detect if study is empty
128  */
129 //============================================================================
130 bool SALOMEDSImpl_Study::IsEmpty()
131 {
132   _errorCode = "";
133   if (!_doc) return true;
134   return _doc->IsEmpty();
135 }
136
137 //============================================================================
138 /*! Function : FindComponent
139  *  Purpose  : Find a Component with ComponentDataType = aComponentName
140  */
141 //============================================================================
142 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::FindComponent (const string& aComponentName)
143 {
144   _errorCode = "";
145   bool _find = false;
146   string name;
147   SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
148   SALOMEDSImpl_SComponent compo;
149
150   for (; itcomp.More(); itcomp.Next()) {
151     SALOMEDSImpl_SComponent SC = itcomp.Value();
152     name = SC.ComponentDataType();
153     if(aComponentName == name) {
154       _find = true;
155       return SC;
156     }
157   }
158
159   if(!_find)
160     {
161       _errorCode = "No component was found";
162       return compo;
163     }
164   return compo;
165 }
166
167 //============================================================================
168 /*! Function : FindComponentID
169  *  Purpose  : Find a Component from it's ID
170  */
171 //============================================================================
172 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::FindComponentID(const string& aComponentID)
173 {
174   _errorCode = "";
175
176   // Iterate on each components defined in the study
177   // Get the component ID and compare with aComponentID
178   bool _find = false;
179   string ID;
180   SALOMEDSImpl_SComponent compo;
181
182   SALOMEDSImpl_SComponentIterator itcomp = NewComponentIterator();
183   for (; itcomp.More(); itcomp.Next()) {
184     SALOMEDSImpl_SComponent SC = itcomp.Value();
185     ID = SC.GetID();
186     if(aComponentID == ID)
187       {
188         // ComponentID found
189         _find = true;
190         compo = SC;
191       }
192   }
193   if(!_find)
194     {
195       _errorCode = "No component was found";
196       compo = compo;
197     }
198
199   return compo;
200 }
201
202 //============================================================================
203 /*! Function : FindObject
204  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
205  */
206 //============================================================================
207 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObject(const string& anObjectName)
208 {
209   _errorCode = "";
210
211   // Iterate to all components defined in the study
212   // After testing the component name, iterate in all objects defined under
213   // components (function _FindObject)
214   bool _find = false;
215   SALOMEDSImpl_SObject RefSO;
216
217   SALOMEDSImpl_SComponentIterator it = NewComponentIterator();
218   for (; it.More();it.Next()){
219     if(!_find)
220       {
221         SALOMEDSImpl_SComponent SC = it.Value();
222         if (SC.GetName() == anObjectName)
223         {
224             _find = true;
225             RefSO = SC;
226
227         }
228         if (!_find) RefSO =  _FindObject(SC, anObjectName, _find);
229       }
230   }
231   if(!RefSO) _errorCode = "No object was found";
232   return RefSO;
233 }
234
235 //============================================================================
236 /*! Function : FindObjectID
237  *  Purpose  : Find an Object with ID = anObjectID
238  */
239 //============================================================================
240 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObjectID(const string& anObjectID)
241 {
242   _errorCode = "";
243   SALOMEDSImpl_SObject so;
244   
245   // Convert aSO->GetID in DF_Label.
246   DF_Label Lab = DF_Label::Label(_doc->Main(), anObjectID, false);
247
248   if (Lab.IsNull()) {
249     _errorCode = "No label was found by ID";
250     return so;
251   }
252   return GetSObject(Lab);
253
254 }
255
256 //============================================================================
257 /*! Function : CreateObjectID
258  *  Purpose  : Creates an Object with ID = anObjectID
259  */
260 //============================================================================
261 SALOMEDSImpl_SObject SALOMEDSImpl_Study::CreateObjectID(const string& anObjectID)
262 {
263   _errorCode = "";
264   SALOMEDSImpl_SObject so;
265
266   // Convert aSO->GetID in DF_Label.
267   DF_Label Lab = DF_Label::Label(_doc->Main(), anObjectID, true);
268
269   if (Lab.IsNull()) {
270     _errorCode = "Can not create a label";
271     return so;
272   }
273   return GetSObject(Lab);
274
275 }
276
277 //============================================================================
278 /*! Function : FindObjectByName
279  *  Purpose  : Find Objects with SALOMEDSImpl_Name = anObjectName in a Component
280  *           : with ComponentDataType = aComponentName
281  */
282 //============================================================================
283 vector<SALOMEDSImpl_SObject> SALOMEDSImpl_Study::FindObjectByName(const string& anObjectName,
284                                                           const string& aComponentName)
285 {
286   _errorCode = "";
287
288   vector<SALOMEDSImpl_SObject> listSO;
289
290   SALOMEDSImpl_SComponent compo = FindComponent(aComponentName) ;
291   if ( !compo ) {
292     _errorCode = "Can not find the component";
293     return listSO;
294   }
295
296   // Iterate on each object and subobject of the component
297   // If objectName is found add it to the list of SObjects
298   string childName ;
299
300   string compoId = compo.GetID();
301   SALOMEDSImpl_ChildIterator it = NewChildIterator(compo);
302   for ( ; it.More(); it.Next() ) {
303
304     SALOMEDSImpl_SObject CSO = it.Value();
305     if ( CSO.GetName() == anObjectName ) {
306         /* add to list */
307         listSO.push_back(CSO) ;
308     }
309
310     /* looks also for eventual children */
311     bool found = false ;
312     CSO = _FindObject( CSO, anObjectName, found ) ;
313     if( found) {
314       listSO.push_back(CSO) ;
315     }
316   }
317
318   return listSO;
319 }
320
321
322
323 //============================================================================
324 /*! Function : FindObjectIOR
325  *  Purpose  : Find an Object with IOR = anObjectIOR
326  */
327 //============================================================================
328 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObjectIOR(const string& anObjectIOR)
329 {
330   _errorCode = "";
331   
332   SALOMEDSImpl_SObject aResult ;
333   
334   // searching in the datamap for optimization
335   if (myIORLabels.find(anObjectIOR) != myIORLabels.end()) {
336     aResult = GetSObject(myIORLabels[anObjectIOR]);
337     // 11 oct 2002: forbidden attributes must be checked here
338     if (!aResult.GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID())) {
339       myIORLabels.erase(anObjectIOR);
340       aResult = SALOMEDSImpl_SObject();  
341     }  
342   }
343   
344   if(!aResult) _errorCode = "No object was found";
345   return aResult;
346 }
347
348 //============================================================================
349 /*! Function : FindObjectByPath
350  *  Purpose  : Find an Object by its path = thePath
351  */
352 //============================================================================
353 SALOMEDSImpl_SObject SALOMEDSImpl_Study::FindObjectByPath(const string& thePath)
354 {
355   _errorCode = "";
356
357   string aPath(thePath), aToken;
358   SALOMEDSImpl_SObject aSO;
359   int aLength = aPath.size();
360   bool isRelative = false;
361
362   if(aLength == 0) {  //Empty path - return the current context
363     return GetSObject(_current);
364   }
365
366   if(aPath[0] != '/')  //Relative path
367     isRelative = true;
368
369   DF_ChildIterator anIterator;
370   DF_Label aLabel;
371   SALOMEDSImpl_AttributeName* anAttr;
372
373   if(isRelative) {
374     if(_current.IsNull()) return aSO;
375     anIterator.Init(_current, false);
376   }
377   else {
378     if(aPath.size() == 1 && aPath[0] == '/') {    //Root
379       return GetSObject(_doc->Main());
380     }
381     anIterator.Init(_doc->Main(), false);
382   }
383
384   vector<string> vs = SALOMEDSImpl_Tool::splitString(aPath, '/');
385   for(int i = 0, len = vs.size(); i<len; i++) {
386
387     aToken = vs[i];
388     if(aToken.size() == 0) break;
389
390     for ( ; anIterator.More(); anIterator.Next() ) {
391       aLabel = anIterator.Value();
392       if((anAttr=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) {
393         if(anAttr->Value() == aToken) {
394           if(i == (len-1)) {  //The searched label is found (no part of the path is left)
395               return GetSObject(aLabel);
396           }
397
398           anIterator.Init(aLabel, false);
399           break;
400         }
401       }
402     }
403
404   }
405
406   if(!aSO) _errorCode = "No object was found";
407   return aSO;
408 }
409
410 //============================================================================
411 /*! Function : GetObjectPath
412  *  Purpose  :
413  */
414 //============================================================================
415 string SALOMEDSImpl_Study::GetObjectPath(const SALOMEDSImpl_SObject& theObject)
416 {
417   _errorCode = "";
418
419   string aPath("");
420   if(!theObject) {
421     _errorCode = "Null object";
422     return aPath;
423   }
424
425   string aName = theObject.GetName();
426   if(!aName.empty() && aName != "" ) {
427     string aValue("/");
428     aValue+=aName;
429     aValue += aPath;
430     aPath = aValue;
431     SALOMEDSImpl_SObject aFather = theObject.GetFather();
432     if(aFather) {
433        aName = aFather.GetName();
434        if(!aName.empty() && aName != "") {
435           aValue = GetObjectPath(aFather);
436           aPath = aValue + aPath;
437        }
438     }
439   }
440
441   return aPath;
442 }
443
444
445 //============================================================================
446 /*! Function : GetObjectPathByIOR
447  *  Purpose  :
448  */
449 //============================================================================
450 string SALOMEDSImpl_Study::GetObjectPathByIOR(const string& theIOR)
451 {
452   _errorCode = "";
453
454   string aPath;
455   SALOMEDSImpl_SObject so = FindObjectIOR(theIOR);
456   if(!so) {
457     _errorCode = "No SObject was found by IOR";
458     return aPath;
459   }
460
461   return GetObjectPath(so);
462 }
463
464
465 //============================================================================
466 /*! Function : SetContext
467  *  Purpose  : Sets the current context
468  */
469 //============================================================================
470 bool SALOMEDSImpl_Study::SetContext(const string& thePath)
471 {
472   _errorCode = "";
473   if(thePath.empty()) {
474     _errorCode = "InvalidPath";
475     return false;
476   }
477
478   string aPath(thePath), aContext("");
479   bool isInvalid = false;
480   SALOMEDSImpl_SObject aSO;
481
482   if(aPath[0] != '/') { //Relative path
483     aContext = GetContext();
484     aContext += '/';
485     aContext += aPath;
486   }
487   else
488     aContext = aPath;
489
490   try {
491     aSO = FindObjectByPath(aContext);
492   }
493   catch( ... ) {
494     isInvalid = true;
495   }
496
497   if(isInvalid || !aSO) {
498     _errorCode = "InvalidContext";
499     return false;
500   }
501
502   DF_Label aLabel = aSO.GetLabel();
503   if(aLabel.IsNull()) {
504     _errorCode = "InvalidContext";
505     return false;
506   }
507   else
508     _current = aLabel;  //Set the current context
509
510   return true;
511 }
512
513 //============================================================================
514 /*! Function : GetContext
515  *  Purpose  : Gets the current context
516  */
517 //============================================================================
518 string SALOMEDSImpl_Study::GetContext()
519 {
520   _errorCode = "";
521
522   if(_current.IsNull()) {
523     _errorCode = "InvaidContext";
524     return "";
525   }
526   SALOMEDSImpl_SObject so = GetSObject(_current);
527   return GetObjectPath(so);
528 }
529
530 //============================================================================
531 /*! Function : GetObjectNames
532  *  Purpose  : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
533  */
534 //============================================================================
535 vector<string> SALOMEDSImpl_Study::GetObjectNames(const string& theContext)
536 {
537   _errorCode = "";
538
539   vector<string> aResultSeq;
540   DF_Label aLabel;
541   if (theContext.empty()) {
542     aLabel = _current;
543   } else {
544     DF_Label aTmp = _current;
545     SetContext(theContext);
546     aLabel = _current;
547     _current = aTmp;
548   }
549   if (aLabel.IsNull()) {
550     _errorCode = "InvalidContext";
551     return aResultSeq;
552   }
553
554   DF_ChildIterator anIter (aLabel, true); // iterate all subchildren at all sublevels
555   for (; anIter.More(); anIter.Next()) {
556     DF_Label aLabel = anIter.Value();
557     SALOMEDSImpl_AttributeName* aName;
558     if ((aName=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) 
559       aResultSeq.push_back(aName->Value());
560   }
561
562   return aResultSeq;
563 }
564
565 //============================================================================
566 /*! Function : GetDirectoryNames
567  *  Purpose  : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
568  */
569 //============================================================================
570 vector<string> SALOMEDSImpl_Study::GetDirectoryNames(const string& theContext)
571 {
572   _errorCode = "";
573
574   vector<string> aResultSeq;
575   DF_Label aLabel;
576   if (theContext.empty()) {
577     aLabel = _current;
578   } else {
579     DF_Label aTmp = _current;
580     SetContext(theContext);
581     aLabel = _current;
582     _current = aTmp;
583   }
584   if (aLabel.IsNull()) {
585     _errorCode = "InvalidContext";
586     return aResultSeq;
587   }
588
589   DF_ChildIterator anIter (aLabel, true); // iterate first-level children at all sublevels
590   for (; anIter.More(); anIter.Next()) {
591     DF_Label aLabel = anIter.Value();
592     SALOMEDSImpl_AttributeLocalID* anID;
593     if ((anID=(SALOMEDSImpl_AttributeLocalID*)aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) {
594       if (anID->Value() == DIRECTORYID) {
595         SALOMEDSImpl_AttributeName* aName;
596         if ((aName=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) {
597           aResultSeq.push_back(aName->Value());
598         }
599       }
600     }
601   }
602
603   return aResultSeq;
604 }
605
606 //============================================================================
607 /*! Function : GetFileNames
608  *  Purpose  : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
609  */
610 //============================================================================
611 vector<string> SALOMEDSImpl_Study::GetFileNames(const string& theContext)
612 {
613   _errorCode = "";
614
615   vector<string> aResultSeq;
616   DF_Label aLabel;
617   if (theContext.empty()) {
618     aLabel = _current;
619   } else {
620     DF_Label aTmp = _current;
621     SetContext(theContext);
622     aLabel = _current;
623     _current = aTmp;
624   }
625   if (aLabel.IsNull()) {
626     _errorCode = "InvalidContext";
627     return aResultSeq;
628   }
629
630   DF_ChildIterator anIter (aLabel, true); // iterate all subchildren at all sublevels
631   for (; anIter.More(); anIter.Next()) {
632     DF_Label aLabel = anIter.Value();
633     SALOMEDSImpl_AttributeLocalID* anID;
634     if ((anID=(SALOMEDSImpl_AttributeLocalID*)aLabel.FindAttribute(SALOMEDSImpl_AttributeLocalID::GetID()))) {
635       if (anID->Value() == FILELOCALID) {
636         SALOMEDSImpl_AttributePersistentRef* aName;
637         if ((aName=(SALOMEDSImpl_AttributePersistentRef*)aLabel.FindAttribute(SALOMEDSImpl_AttributePersistentRef::GetID()))) {
638           std::string aFileName = aName->Value();
639           if (aFileName.size() > 0)
640             aResultSeq.push_back(aFileName.substr(strlen(FILEID), aFileName.size()));
641         }
642       }
643     }
644   }
645
646   return aResultSeq;
647 }
648
649 //============================================================================
650 /*! Function : GetComponentNames
651  *  Purpose  : method to get all components names
652  */
653 //============================================================================
654 vector<string> SALOMEDSImpl_Study::GetComponentNames(const string& theContext)
655 {
656   _errorCode = "";
657
658   vector<string> aResultSeq;
659   DF_ChildIterator anIter(_doc->Main(), false); // iterate all subchildren at first level
660   for(; anIter.More(); anIter.Next()) {
661     DF_Label aLabel = anIter.Value();
662     SALOMEDSImpl_AttributeName* aName;
663     if ((aName=(SALOMEDSImpl_AttributeName*)aLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) 
664       aResultSeq.push_back(aName->Value());
665   }
666
667   return aResultSeq;
668 }
669
670 //============================================================================
671 /*! Function : NewChildIterator
672  *  Purpose  : Create a ChildIterator from an SObject
673  */
674 //============================================================================
675 SALOMEDSImpl_ChildIterator SALOMEDSImpl_Study::NewChildIterator(const SALOMEDSImpl_SObject& aSO)
676 {
677   _errorCode = "";
678   return SALOMEDSImpl_ChildIterator(aSO);
679 }
680
681
682 //============================================================================
683 /*! Function : NewComponentIterator
684  *  Purpose  : Create a SComponentIterator
685  */
686 //============================================================================
687 SALOMEDSImpl_SComponentIterator SALOMEDSImpl_Study::NewComponentIterator()
688 {
689   _errorCode = "";
690   return SALOMEDSImpl_SComponentIterator(_doc);
691 }
692
693
694 //============================================================================
695 /*! Function : NewBuilder
696  *  Purpose  : Create a StudyBuilder
697  */
698 //============================================================================
699 SALOMEDSImpl_StudyBuilder* SALOMEDSImpl_Study::NewBuilder()
700 {
701   _errorCode = "";
702   if(_autoFill) {
703     _builder->SetOnAddSObject(_cb);
704     _builder->SetOnRemoveSObject(_cb);
705   }
706   return _builder;
707
708 }
709
710 //============================================================================
711 /*! Function : Name
712  *  Purpose  : get study name
713  */
714 //============================================================================
715 string SALOMEDSImpl_Study::Name()
716 {
717   _errorCode = "";
718   return _name;
719 }
720
721 //============================================================================
722 /*! Function : Name
723  *  Purpose  : set study name
724  */
725 //============================================================================
726 void SALOMEDSImpl_Study::Name(const string& name)
727 {
728   _errorCode = "";
729   _name = name;
730 }
731
732 //============================================================================
733 /*! Function : IsSaved
734  *  Purpose  : get if study has been saved
735  */
736 //============================================================================
737 bool SALOMEDSImpl_Study::IsSaved()
738 {
739   _errorCode = "";
740   return _Saved;
741 }
742
743 //============================================================================
744 /*! Function : IsSaved
745  *  Purpose  : set if study has been saved
746  */
747 //============================================================================
748 void SALOMEDSImpl_Study::IsSaved(bool save)
749 {
750   _errorCode = "";
751   _Saved = save;
752   if(save) _doc->SetModified(false);
753 }
754
755 //============================================================================
756 /*! Function : IsModified
757  *  Purpose  : Detect if a Study has been modified since it has been saved
758  */
759 //============================================================================
760 bool SALOMEDSImpl_Study::IsModified()
761 {
762   _errorCode = "";
763
764   // True if is modified
765   if (_doc->IsModified()) return true;
766
767   return false;
768 }
769
770 //============================================================================
771 /*! Function : URL
772  *  Purpose  : get URL of the study (persistent reference of the study)
773  */
774 //============================================================================
775 string SALOMEDSImpl_Study::URL()
776 {
777   _errorCode = "";
778   return _URL;
779 }
780
781 //============================================================================
782 /*! Function : URL
783  *  Purpose  : set URL of the study (persistent reference of the study)
784  */
785 //============================================================================
786 void SALOMEDSImpl_Study::URL(const string& url)
787 {
788   _errorCode = "";
789   _URL = url;
790
791   /*jfa: Now name of SALOMEDS study will correspond to name of SalomeApp study
792   string tmp(_URL);
793
794   char *aName = (char*)tmp.ToCString();
795   char *adr = strtok(aName, "/");
796   while (adr)
797     {
798       aName = adr;
799       adr = strtok(NULL, "/");
800     }
801   Name(aName);*/
802   Name(url);
803 }
804
805
806 //============================================================================
807 /*! Function : _FindObject
808  *  Purpose  : Find an Object with SALOMEDSImpl_Name = anObjectName
809  */
810 //============================================================================
811 SALOMEDSImpl_SObject SALOMEDSImpl_Study::_FindObject(const SALOMEDSImpl_SObject& SO,
812                                                              const string& theObjectName,
813                                                              bool& _find)
814 {
815   SALOMEDSImpl_SObject RefSO;
816   if(!SO) return RefSO;
817
818   // Iterate on each objects and subobjects of the component
819   // If objectName find, stop the loop and get the object reference
820   SALOMEDSImpl_AttributeName* anAttr;
821
822   string soid = SO.GetID();
823   DF_ChildIterator it(SO.GetLabel());
824   for (; it.More(); it.Next()){
825     if(!_find)
826       {
827         if ((anAttr=(SALOMEDSImpl_AttributeName*)it.Value().FindAttribute(SALOMEDSImpl_AttributeName::GetID())))
828         {
829           string Val(anAttr->Value());
830           if (Val == theObjectName)
831             {
832               RefSO = GetSObject(it.Value());
833               _find = true;
834             }
835         }
836         if (!_find) RefSO = _FindObject(GetSObject(it.Value()), theObjectName, _find);
837       }
838   }
839   return RefSO;
840 }
841
842 //============================================================================
843 /*! Function : _FindObjectIOR
844  *  Purpose  : Find an Object with SALOMEDSImpl_IOR = anObjectIOR
845  */
846 //============================================================================
847 SALOMEDSImpl_SObject
848 SALOMEDSImpl_Study::_FindObjectIOR(const SALOMEDSImpl_SObject& SO,
849                                    const string& theObjectIOR,
850                                    bool& _find)
851 {
852   SALOMEDSImpl_SObject RefSO, aSO;
853   if(!SO) return RefSO;
854
855   // Iterate on each objects and subobjects of the component
856   // If objectName find, stop the loop and get the object reference
857   SALOMEDSImpl_AttributeIOR* anAttr;
858
859   DF_ChildIterator it(SO.GetLabel());
860   for (; it.More();it.Next()){
861     if(!_find)
862       {
863         if ((anAttr=(SALOMEDSImpl_AttributeIOR*)it.Value().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID())))
864         {
865           string Val(anAttr->Value());
866           if (Val == theObjectIOR)
867             {
868               RefSO = GetSObject(it.Value());
869               _find = true;
870             }
871         }
872         aSO = GetSObject(it.Value());
873         if (!_find) RefSO =  _FindObjectIOR(aSO, theObjectIOR, _find);
874       }
875   }
876   return RefSO;
877 }
878
879 bool SALOMEDSImpl_Study::IsLocked()
880 {
881   _errorCode = "";
882   return GetProperties()->IsLocked();
883 }
884
885 int SALOMEDSImpl_Study::StudyId()
886 {
887   _errorCode = "";
888   return _StudyId;
889 }
890
891 void SALOMEDSImpl_Study::StudyId(int id)
892 {
893   _errorCode = "";
894   _StudyId = id;
895 }
896
897 void SALOMEDSImpl_Study::UpdateIORLabelMap(const string& anIOR,const string& anEntry)
898 {
899   _errorCode = "";
900   DF_Label aLabel = DF_Label::Label(_doc->Main(), anEntry, true);
901   if (myIORLabels.find(anIOR) != myIORLabels.end()) myIORLabels.erase(anIOR);
902   myIORLabels[anIOR] = aLabel;
903 }
904
905 SALOMEDSImpl_Study* SALOMEDSImpl_Study::GetStudy(const DF_Label& theLabel)
906 {
907   SALOMEDSImpl_StudyHandle* Att;
908   if ((Att=(SALOMEDSImpl_StudyHandle*)theLabel.Root().FindAttribute(SALOMEDSImpl_StudyHandle::GetID()))) {
909     return Att->Get();
910   }
911   return NULL;
912 }
913
914 SALOMEDSImpl_SObject SALOMEDSImpl_Study::SObject(const DF_Label& theLabel)
915 {
916   return GetStudy(theLabel)->GetSObject(theLabel);
917 }
918
919 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::SComponent(const DF_Label& theLabel)
920 {
921   return GetStudy(theLabel)->GetSComponent(theLabel);
922 }
923
924
925 void SALOMEDSImpl_Study::IORUpdated(const SALOMEDSImpl_AttributeIOR* theAttribute)
926 {
927   string aString = theAttribute->Label().Entry();
928   GetStudy(theAttribute->Label())->UpdateIORLabelMap(theAttribute->Value(), aString);
929 }
930
931 vector<SALOMEDSImpl_SObject> SALOMEDSImpl_Study::FindDependances(const SALOMEDSImpl_SObject& anObject)
932 {
933   _errorCode = "";
934   vector<SALOMEDSImpl_SObject> aSeq;
935
936   SALOMEDSImpl_AttributeTarget* aTarget;
937   if ((aTarget=(SALOMEDSImpl_AttributeTarget*)anObject.GetLabel().FindAttribute(SALOMEDSImpl_AttributeTarget::GetID()))) {
938     return aTarget->Get();
939   }
940
941   return aSeq;
942 }
943
944
945 SALOMEDSImpl_AttributeStudyProperties* SALOMEDSImpl_Study::GetProperties()
946 {
947   _errorCode = "";
948   return SALOMEDSImpl_AttributeStudyProperties::Set(_doc->Main());
949 }
950
951 string SALOMEDSImpl_Study::GetLastModificationDate()
952 {
953   _errorCode = "";
954   SALOMEDSImpl_AttributeStudyProperties* aProp = GetProperties();
955
956   vector<string> aNames;
957   vector<int> aMinutes, aHours, aDays, aMonths, aYears;
958   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
959
960   int aLastIndex = aNames.size()-1;
961   char aResult[20];
962   sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
963           (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]), (int)(aYears[aLastIndex]),
964           (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
965   string aResStr (aResult);
966   return aResStr;
967 }
968
969 vector<string> SALOMEDSImpl_Study::GetModificationsDate()
970 {
971   _errorCode = "";
972   SALOMEDSImpl_AttributeStudyProperties* aProp = GetProperties();
973
974   vector<string> aNames;
975   vector<int> aMinutes, aHours, aDays, aMonths, aYears;
976   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
977
978   int anIndex, aLength = aNames.size();
979   vector<string> aDates;
980
981   for (anIndex = 1; anIndex < aLength; anIndex++) {
982     char aDate[20];
983     sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d",
984             (int)(aDays[anIndex]), (int)(aMonths[anIndex]), (int)(aYears[anIndex]),
985             (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
986     aDates.push_back(aDate);
987   }
988   return aDates;
989 }
990
991
992
993 //============================================================================
994 /*! Function : GetUseCaseBuilder
995  *  Purpose  : Returns a UseCase builder
996  */
997 //============================================================================
998 SALOMEDSImpl_UseCaseBuilder* SALOMEDSImpl_Study::GetUseCaseBuilder()
999 {
1000   _errorCode = "";
1001   return _useCaseBuilder;
1002 }
1003
1004
1005 //============================================================================
1006 /*! Function : Close
1007  *  Purpose  :
1008  */
1009 //============================================================================
1010 void SALOMEDSImpl_Study::Close()
1011 {
1012   _errorCode = "";
1013   _doc->GetApplication()->Close(_doc);
1014   _doc = NULL;
1015   _mapOfSO.clear();
1016   _mapOfSCO.clear();
1017 }
1018
1019
1020 //============================================================================
1021 /*! Function : GetSComponent
1022  *  Purpose  :
1023  */
1024 //============================================================================
1025 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::GetSComponent(const string& theEntry)
1026 {
1027   SALOMEDSImpl_SComponent aSCO;
1028   if(_mapOfSCO.find(theEntry) != _mapOfSCO.end())
1029     aSCO = _mapOfSCO[theEntry];
1030   else {
1031     DF_Label aLabel = DF_Label::Label(_doc->Main(), theEntry);
1032     aSCO = SALOMEDSImpl_SComponent(aLabel);
1033     _mapOfSCO[theEntry] = aSCO;
1034   }
1035
1036   return aSCO;
1037 }
1038
1039 //============================================================================
1040 /*! Function : GetSComponent
1041  *  Purpose  :
1042  */
1043 //============================================================================
1044 SALOMEDSImpl_SComponent SALOMEDSImpl_Study::GetSComponent(const DF_Label& theLabel)
1045 {
1046   return SALOMEDSImpl_SComponent(theLabel);
1047 }
1048
1049 //============================================================================
1050 /*! Function : GetSObject
1051  *  Purpose  :
1052  */
1053 //============================================================================
1054 SALOMEDSImpl_SObject SALOMEDSImpl_Study::GetSObject(const string& theEntry)
1055 {
1056   SALOMEDSImpl_SObject aSO;
1057   if(_mapOfSO.find(theEntry) != _mapOfSO.end())
1058     aSO = _mapOfSO[theEntry];
1059   else {
1060     DF_Label aLabel = DF_Label::Label(_doc->Main(), theEntry);
1061     aSO = SALOMEDSImpl_SObject(aLabel);
1062     _mapOfSO[theEntry] = aSO;
1063   }
1064
1065   return aSO;
1066 }
1067
1068 //============================================================================
1069 /*! Function : GetSObject
1070  *  Purpose  :
1071  */
1072 //============================================================================
1073 SALOMEDSImpl_SObject SALOMEDSImpl_Study::GetSObject(const DF_Label& theLabel)
1074 {
1075   return SALOMEDSImpl_SObject(theLabel);
1076 }
1077
1078 //============================================================================
1079 /*! Function : GetAttribute
1080  *  Purpose  :
1081  */
1082 //============================================================================
1083 DF_Attribute* SALOMEDSImpl_Study::GetAttribute(const string& theEntry,
1084                                                const string& theType)
1085 {
1086   SALOMEDSImpl_SObject aSO = GetSObject(theEntry);
1087   DF_Attribute* anAttr;
1088   aSO.FindAttribute(anAttr, theType);
1089   return anAttr;
1090 }
1091
1092 //============================================================================
1093 /*! Function : DumpStudy
1094  *  Purpose  :
1095  */
1096 //============================================================================
1097 bool SALOMEDSImpl_Study::DumpStudy(const string& thePath,
1098                                    const string& theBaseName,
1099                                    bool isPublished,
1100                                    SALOMEDSImpl_DriverFactory* theFactory)
1101 {
1102   _errorCode = "";
1103
1104   if(theFactory == NULL) {
1105     _errorCode = "Null factory for creation of Engines";
1106     return false;
1107   }
1108
1109   vector<string> aSeq;
1110   string aCompType, aFactoryType;
1111
1112   //Build a list of all components in the Study
1113   SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1114
1115   for (; itcomponent.More(); itcomponent.Next()) {
1116     SALOMEDSImpl_SComponent sco = itcomponent.Value();
1117     aCompType = sco.ComponentDataType();
1118     //GEOM and MED are independent components
1119     if (aCompType == "GEOM" || aCompType == "MED")
1120       aSeq.insert(aSeq.begin(), aCompType);
1121     else
1122       aSeq.push_back(aCompType);
1123   }
1124
1125 #ifdef WIN32
1126   string aFileName =
1127     thePath + string("\\") + theBaseName + string(".py");
1128 #else
1129   string aFileName =
1130     thePath + string("/")  + theBaseName + string(".py");
1131 #endif
1132
1133   //Create a file that will contain a main Study script
1134   fstream fp;
1135   fp.open(aFileName.c_str(), ios::out);
1136
1137 #ifdef WIN32
1138   bool isOpened = fp.is_open();
1139 #else
1140   bool isOpened = fp.rdbuf()->is_open();
1141 #endif
1142
1143   if(!isOpened) {
1144     _errorCode = string("Can't create a file ")+aFileName;
1145     return false;
1146   }
1147
1148   string aBatchModeScript = "salome";
1149
1150   //Output to the main Study script required Python modules import,
1151   //set sys.path and add a creation of the study.
1152   fp << GetDumpStudyComment() << endl << endl;
1153   fp << "import sys" << endl;
1154   fp << "import " << aBatchModeScript << endl << endl;
1155
1156   fp << aBatchModeScript << ".salome_init()" << endl << endl;
1157
1158   fp << "sys.path.insert( 0, \'" << thePath << "\')" << endl << endl;
1159
1160
1161   //Check if it's necessary to dump visual parameters
1162   bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1163   int lastSavePoint = -1;
1164   if(isDumpVisuals) {
1165     lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1166     if(lastSavePoint > 0) {
1167       fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1168     }
1169   }
1170   
1171
1172   vector<string> aSeqOfFileNames;
1173
1174   //Iterate all components and create the componponents specific scripts.
1175   bool isOk = true;
1176   int aLength = aSeq.size();
1177   for(int i = 1; i <= aLength; i++) {
1178
1179     aCompType = aSeq[i-1];
1180     SALOMEDSImpl_SComponent sco = FindComponent(aCompType);
1181     SALOMEDSImpl_Driver* aDriver = NULL;
1182     // if there is an associated Engine call its method for saving
1183     string IOREngine;
1184     try {
1185       if (!sco.ComponentIOR(IOREngine)) {
1186         if (!aCompType.empty()) {
1187
1188           aDriver = theFactory->GetDriverByType(aCompType);
1189
1190           if (aDriver != NULL) {
1191             SALOMEDSImpl_StudyBuilder* SB = NewBuilder();
1192             if(!SB->LoadWith(sco, aDriver)) {
1193               _errorCode = SB->GetErrorCode();
1194               return false;
1195             }
1196           }
1197           else continue;
1198         }
1199       }
1200       else {
1201         aDriver = theFactory->GetDriverByIOR(IOREngine);
1202       }
1203     } catch(...) {
1204       _errorCode = "Can not restore information to dump it";
1205       return false;
1206     }
1207
1208     if(aDriver == NULL) continue;
1209
1210     bool isValidScript;
1211     long aStreamLength  = 0;
1212     SALOMEDSImpl_TMPFile* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1213     if ( !isValidScript )
1214       isOk = false;
1215
1216     //Create a file that will contain the component specific script
1217     fstream fp2;
1218 #ifdef WIN32
1219     aFileName=thePath+string("\\");
1220 #else
1221     aFileName=thePath+string("/");
1222 #endif
1223     string aScriptName;
1224     aScriptName += theBaseName;
1225     aScriptName += "_";
1226     aScriptName += aCompType;
1227
1228     aFileName += aScriptName+ string(".py");
1229     aSeqOfFileNames.push_back(aFileName);
1230
1231     fp2.open(aFileName.c_str(), ios::out);
1232
1233 #ifdef WIN32
1234     isOpened = fp2.is_open();
1235 #else
1236     isOpened = fp2.rdbuf()->is_open();
1237 #endif
1238
1239     if(!isOpened) {
1240       _errorCode = string("Can't create a file ")+aFileName;
1241       SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1242       return false;
1243     }
1244
1245     //Output the Python script generated by the component in the newly created file.
1246     fp2 << aStream->Data();
1247     fp2.close();
1248
1249     if(aStream) delete aStream;
1250
1251     //Add to the main script a call to RebuildData of the generated by the component the Python script
1252     fp << "import " << aScriptName << endl;
1253     fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1254   }
1255
1256   fp << endl;
1257   fp << "if salome.sg.hasDesktop():" << endl;
1258   fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1259
1260   if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1261     fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1262   }
1263
1264
1265   fp.close();
1266   return isOk;
1267 }
1268
1269 //=======================================================================
1270 //function : GetDumpStudyComment
1271 //purpose  : return a header comment for a DumpStudy script
1272 //=======================================================================
1273
1274 string SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1275 {
1276   string txt
1277     ("### This file is generated by SALOME automatically by dump python functionality");
1278   if ( theComponentName )
1279     txt += string(" of ") + (char*) theComponentName + " component";
1280   return txt;
1281 }
1282
1283 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1284             fstream& fp,
1285             const string& Tab,
1286             SALOMEDSImpl_Study* theStudy);
1287
1288 //============================================================================
1289 /*! Function : dump
1290  *  Purpose  :
1291  */
1292 //============================================================================
1293 void SALOMEDSImpl_Study::dump(const string& theFileName)
1294 {
1295   //Create a file that will contain a main Study script
1296   fstream fp;
1297   fp.open(theFileName.c_str(), ios::out);
1298
1299 #ifdef WIN32
1300   bool isOpened = fp.is_open();
1301 #else
1302   bool isOpened = fp.rdbuf()->is_open();
1303 #endif
1304
1305   if(!isOpened) {
1306     _errorCode = string("Can't create a file ")+theFileName;
1307     cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1308     return;
1309   }
1310
1311   SALOMEDSImpl_SObject aSO = FindObjectID("0:1");
1312   fp << "0:1" << endl;
1313   SALOMEDSImpl_ChildIterator Itr = NewChildIterator(aSO);
1314   string aTab("   ");
1315   for(; Itr.More(); Itr.Next()) {
1316     dumpSO(Itr.Value(), fp, aTab, this);
1317   }
1318
1319   fp.close();
1320 }
1321
1322
1323 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1324             fstream& fp,
1325             const string& Tab,
1326             SALOMEDSImpl_Study* theStudy)
1327 {
1328   string aTab(Tab), anID(theSO.GetID());
1329   fp << aTab << anID << endl;
1330   vector<DF_Attribute*> attribs = theSO.GetLabel().GetAttributes();
1331   for(int i = 0; i<attribs.size(); i++) {
1332     SALOMEDSImpl_GenericAttribute* anAttr = dynamic_cast<SALOMEDSImpl_GenericAttribute*>(attribs[i]);
1333
1334     if(!anAttr) {
1335       continue;
1336     }
1337
1338     string aType = anAttr->GetClassType();
1339     fp << Tab << "  -- " << aType;
1340
1341     if(aType == string("AttributeReal")) {
1342       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReal*>(anAttr)->Value();
1343     }
1344     else if(aType == string("AttributeInteger")) {
1345       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeInteger*>(anAttr)->Value();
1346     }
1347     else if(aType ==  string("AttributeName")) {
1348       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeName*>(anAttr)->Value();
1349     }
1350     else if(aType == string("AttributeComment")) {
1351       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeComment*>(anAttr)->Value();
1352     }
1353     else if(aType == string("AttributeReference")) {
1354       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReference*>(anAttr)->Save();
1355     }
1356     fp << endl;
1357   }
1358
1359   SALOMEDSImpl_ChildIterator Itr = theStudy->NewChildIterator(theSO);
1360   string aNewTab("   ");
1361   aNewTab+=aTab;
1362   for(; Itr.More(); Itr.Next()) {
1363     dumpSO(Itr.Value(), fp, aNewTab, theStudy);
1364   }
1365
1366   return;
1367 }
1368
1369 void SALOMEDSImpl_Study::Modify()
1370 {
1371   _errorCode = "";
1372   _doc->SetModified(true);
1373 }
1374
1375 //============================================================================
1376 /*! Function : 
1377  *  Purpose  :
1378  */
1379 //============================================================================
1380 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1381 {
1382   if (theSavePoint < 0) return NULL;
1383   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1384   SALOMEDSImpl_SObject so = FindComponent((char*)theID);
1385   if (!so) so = builder->NewComponent((char*)theID);
1386   SALOMEDSImpl_AttributeParameter* attParam = NULL;
1387
1388   if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1389     DF_Label savePointLabel = so.GetLabel().FindChild( theSavePoint, /*create=*/0 );
1390     if ( !savePointLabel.IsNull() )
1391       so = GetSObject( savePointLabel );
1392     else // ... if it does not exist - create a new one
1393       so = builder->NewObjectToTag( so, theSavePoint );
1394   }
1395
1396   DF_Attribute* A;
1397   if (so) {
1398     builder->FindAttribute(so, A, "AttributeParameter");
1399     if ( !A ) { // first call of GetCommonParameters on "Interface Applicative" component
1400       A = builder->FindOrCreateAttribute(so, "AttributeParameter"); 
1401     }
1402     attParam = dynamic_cast<SALOMEDSImpl_AttributeParameter*>( A );
1403   }
1404   return attParam;
1405 }
1406
1407 //============================================================================
1408 /*! Function : 
1409  *  Purpose  :
1410  */
1411 //============================================================================
1412 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetModuleParameters(const char* theID, 
1413                                                                          const char* theModuleName,
1414                                                                          int theSavePoint)
1415 {
1416   if(theSavePoint <= 0) return NULL;
1417   SALOMEDSImpl_AttributeParameter* main_ap = GetCommonParameters(theID, theSavePoint);
1418   SALOMEDSImpl_SObject main_so = main_ap->GetSObject();
1419   SALOMEDSImpl_AttributeParameter* par = NULL;
1420
1421   SALOMEDSImpl_ChildIterator it = NewChildIterator(main_so);
1422   string moduleName(theModuleName);
1423   for(; it.More(); it.Next()) {
1424     SALOMEDSImpl_SObject so(it.Value());
1425     if((par=(SALOMEDSImpl_AttributeParameter*)so.GetLabel().FindAttribute(SALOMEDSImpl_AttributeParameter::GetID()))) {
1426       if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1427       if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1428     }
1429   }
1430
1431   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1432   SALOMEDSImpl_SObject so = builder->NewObject(main_so);
1433   par  = dynamic_cast<SALOMEDSImpl_AttributeParameter*>(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1434   par->SetString("AP_MODULE_NAME", moduleName);
1435   return par;
1436 }
1437
1438 //============================================================================
1439 /*! Function : SetStudyLock
1440  *  Purpose  :
1441  */
1442 //============================================================================
1443 void SALOMEDSImpl_Study::SetStudyLock(const char* theLockerID)
1444 {
1445   _lockers.push_back(theLockerID);
1446 }
1447
1448 //============================================================================
1449 /*! Function : IsStudyLocked
1450  *  Purpose  :
1451  */
1452 //============================================================================
1453 bool SALOMEDSImpl_Study::IsStudyLocked()
1454 {
1455   return (_lockers.size() > 0);
1456 }
1457
1458 //============================================================================
1459 /*! Function : UnLockStudy
1460  *  Purpose  :
1461  */
1462 //============================================================================
1463 void SALOMEDSImpl_Study::UnLockStudy(const char* theLockerID)
1464 {
1465   vector<string>::iterator vsI = _lockers.begin();
1466   int length = _lockers.size();
1467   bool isFound = false;
1468   string id(theLockerID);
1469   for(int i = 0; i<length; i++, vsI++) {
1470     if(id == _lockers[i]) {
1471       isFound = true;;
1472       break;
1473     }
1474   }
1475   if(isFound) _lockers.erase(vsI);
1476 }
1477   
1478 //============================================================================
1479 /*! Function : GetLockerID
1480  *  Purpose  :
1481  */
1482 //============================================================================
1483 vector<string> SALOMEDSImpl_Study::GetLockerID()
1484 {
1485   return _lockers;
1486 }
1487
1488 //============================================================================
1489 /*! Function : EnableUseCaseAutoFilling
1490  *  Purpose  :
1491  */
1492 //============================================================================
1493 void SALOMEDSImpl_Study::EnableUseCaseAutoFilling(bool isEnabled)
1494
1495   _errorCode = ""; _autoFill = isEnabled; 
1496   if(isEnabled) {
1497     _builder->SetOnAddSObject(_cb);
1498     _builder->SetOnRemoveSObject(_cb);
1499   }
1500   else {
1501     _builder->SetOnAddSObject(NULL);
1502     _builder->SetOnRemoveSObject(NULL);
1503   }
1504 }
1505
1506 //============================================================================
1507 /*! Function : GetIORs
1508  *  Purpose  :
1509  */
1510 //============================================================================
1511 vector<string> SALOMEDSImpl_Study::GetIORs()
1512 {
1513   vector<string> anIORs;
1514   map<string, DF_Label>::const_iterator MI;
1515   for(MI = myIORLabels.begin(); MI!=myIORLabels.end(); MI++)
1516     anIORs.push_back(MI->first);
1517
1518   return anIORs;
1519 }