Salome HOME
Added @BOOST_CPPFLAGS@
[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 = true;
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 GetSComponent(theLabel.Entry());
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   SALOMEDSImpl_SObject aSO;
1076   string anEntry = theLabel.Entry();
1077   if(_mapOfSO.find(anEntry) != _mapOfSO.end())
1078     aSO = _mapOfSO[anEntry];
1079   else {
1080     aSO = SALOMEDSImpl_SObject(theLabel);
1081     _mapOfSO[anEntry] = aSO;
1082   }
1083
1084   return aSO;
1085 }
1086
1087 //============================================================================
1088 /*! Function : GetAttribute
1089  *  Purpose  :
1090  */
1091 //============================================================================
1092 DF_Attribute* SALOMEDSImpl_Study::GetAttribute(const string& theEntry,
1093                                                const string& theType)
1094 {
1095   SALOMEDSImpl_SObject aSO = GetSObject(theEntry);
1096   DF_Attribute* anAttr;
1097   aSO.FindAttribute(anAttr, theType);
1098   return anAttr;
1099 }
1100
1101 //============================================================================
1102 /*! Function : DumpStudy
1103  *  Purpose  :
1104  */
1105 //============================================================================
1106 bool SALOMEDSImpl_Study::DumpStudy(const string& thePath,
1107                                    const string& theBaseName,
1108                                    bool isPublished,
1109                                    SALOMEDSImpl_DriverFactory* theFactory)
1110 {
1111   _errorCode = "";
1112
1113   if(theFactory == NULL) {
1114     _errorCode = "Null factory for creation of Engines";
1115     return false;
1116   }
1117
1118   vector<string> aSeq;
1119   string aCompType, aFactoryType;
1120
1121   //Build a list of all components in the Study
1122   SALOMEDSImpl_SComponentIterator itcomponent = NewComponentIterator();
1123
1124   for (; itcomponent.More(); itcomponent.Next()) {
1125     SALOMEDSImpl_SComponent sco = itcomponent.Value();
1126     aCompType = sco.ComponentDataType();
1127     //GEOM and MED are independent components
1128     if (aCompType == "GEOM" || aCompType == "MED")
1129       aSeq.insert(aSeq.begin(), aCompType);
1130     else
1131       aSeq.push_back(aCompType);
1132   }
1133
1134 #ifdef WIN32
1135   string aFileName =
1136     thePath + string("\\") + theBaseName + string(".py");
1137 #else
1138   string aFileName =
1139     thePath + string("/")  + theBaseName + string(".py");
1140 #endif
1141
1142   //Create a file that will contain a main Study script
1143   fstream fp;
1144   fp.open(aFileName.c_str(), ios::out);
1145
1146 #ifdef WIN32
1147   bool isOpened = fp.is_open();
1148 #else
1149   bool isOpened = fp.rdbuf()->is_open();
1150 #endif
1151
1152   if(!isOpened) {
1153     _errorCode = string("Can't create a file ")+aFileName;
1154     return false;
1155   }
1156
1157   string aBatchModeScript = "salome";
1158
1159   //Output to the main Study script required Python modules import,
1160   //set sys.path and add a creation of the study.
1161   fp << GetDumpStudyComment() << endl << endl;
1162   fp << "import sys" << endl;
1163   fp << "import " << aBatchModeScript << endl << endl;
1164
1165   fp << aBatchModeScript << ".salome_init()" << endl << endl;
1166
1167   fp << "sys.path.insert( 0, \'" << thePath << "\')" << endl << endl;
1168
1169
1170   //Check if it's necessary to dump visual parameters
1171   bool isDumpVisuals = SALOMEDSImpl_IParameters::isDumpPython(this);
1172   int lastSavePoint = -1;
1173   if(isDumpVisuals) {
1174     lastSavePoint = SALOMEDSImpl_IParameters::getLastSavePoint(this);
1175     if(lastSavePoint > 0) {
1176       fp << SALOMEDSImpl_IParameters::getStudyScript(this, lastSavePoint) << endl << endl;
1177     }
1178   }
1179   
1180
1181   vector<string> aSeqOfFileNames;
1182
1183   //Iterate all components and create the componponents specific scripts.
1184   bool isOk = true;
1185   int aLength = aSeq.size();
1186   for(int i = 1; i <= aLength; i++) {
1187
1188     aCompType = aSeq[i-1];
1189     SALOMEDSImpl_SComponent sco = FindComponent(aCompType);
1190     SALOMEDSImpl_Driver* aDriver = NULL;
1191     // if there is an associated Engine call its method for saving
1192     string IOREngine;
1193     try {
1194       if (!sco.ComponentIOR(IOREngine)) {
1195         if (!aCompType.empty()) {
1196
1197           aDriver = theFactory->GetDriverByType(aCompType);
1198
1199           if (aDriver != NULL) {
1200             SALOMEDSImpl_StudyBuilder* SB = NewBuilder();
1201             if(!SB->LoadWith(sco, aDriver)) {
1202               _errorCode = SB->GetErrorCode();
1203               return false;
1204             }
1205           }
1206           else continue;
1207         }
1208       }
1209       else {
1210         aDriver = theFactory->GetDriverByIOR(IOREngine);
1211       }
1212     } catch(...) {
1213       _errorCode = "Can not restore information to dump it";
1214       return false;
1215     }
1216
1217     if(aDriver == NULL) continue;
1218
1219     bool isValidScript;
1220     long aStreamLength  = 0;
1221     SALOMEDSImpl_TMPFile* aStream = aDriver->DumpPython(this, isPublished, isValidScript, aStreamLength);
1222     if ( !isValidScript )
1223       isOk = false;
1224
1225     //Create a file that will contain the component specific script
1226     fstream fp2;
1227 #ifdef WIN32
1228     aFileName=thePath+string("\\");
1229 #else
1230     aFileName=thePath+string("/");
1231 #endif
1232     string aScriptName;
1233     aScriptName += theBaseName;
1234     aScriptName += "_";
1235     aScriptName += aCompType;
1236
1237     aFileName += aScriptName+ string(".py");
1238     aSeqOfFileNames.push_back(aFileName);
1239
1240     fp2.open(aFileName.c_str(), ios::out);
1241
1242 #ifdef WIN32
1243     isOpened = fp2.is_open();
1244 #else
1245     isOpened = fp2.rdbuf()->is_open();
1246 #endif
1247
1248     if(!isOpened) {
1249       _errorCode = string("Can't create a file ")+aFileName;
1250       SALOMEDSImpl_Tool::RemoveTemporaryFiles(thePath, aSeqOfFileNames, false);
1251       return false;
1252     }
1253
1254     //Output the Python script generated by the component in the newly created file.
1255     fp2 << aStream->Data();
1256     fp2.close();
1257
1258     if(aStream) delete aStream;
1259
1260     //Add to the main script a call to RebuildData of the generated by the component the Python script
1261     fp << "import " << aScriptName << endl;
1262     fp << aScriptName << ".RebuildData(" << aBatchModeScript << ".myStudy)" << endl;
1263   }
1264
1265   fp << endl;
1266   fp << "if salome.sg.hasDesktop():" << endl;
1267   fp << "\tsalome.sg.updateObjBrowser(1)" << endl;
1268
1269   if(isDumpVisuals) { //Output the call to Session's method restoreVisualState
1270     fp << "\tiparameters.getSession().restoreVisualState(1)" << endl;
1271   }
1272
1273
1274   fp.close();
1275   return isOk;
1276 }
1277
1278 //=======================================================================
1279 //function : GetDumpStudyComment
1280 //purpose  : return a header comment for a DumpStudy script
1281 //=======================================================================
1282
1283 string SALOMEDSImpl_Study::GetDumpStudyComment(const char* theComponentName)
1284 {
1285   string txt
1286     ("### This file is generated by SALOME automatically by dump python functionality");
1287   if ( theComponentName )
1288     txt += string(" of ") + (char*) theComponentName + " component";
1289   return txt;
1290 }
1291
1292 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1293             fstream& fp,
1294             const string& Tab,
1295             SALOMEDSImpl_Study* theStudy);
1296
1297 //============================================================================
1298 /*! Function : dump
1299  *  Purpose  :
1300  */
1301 //============================================================================
1302 void SALOMEDSImpl_Study::dump(const string& theFileName)
1303 {
1304   //Create a file that will contain a main Study script
1305   fstream fp;
1306   fp.open(theFileName.c_str(), ios::out);
1307
1308 #ifdef WIN32
1309   bool isOpened = fp.is_open();
1310 #else
1311   bool isOpened = fp.rdbuf()->is_open();
1312 #endif
1313
1314   if(!isOpened) {
1315     _errorCode = string("Can't create a file ")+theFileName;
1316     cout << "### SALOMEDSImpl_Study::dump Error: " << _errorCode << endl;
1317     return;
1318   }
1319
1320   SALOMEDSImpl_SObject aSO = FindObjectID("0:1");
1321   fp << "0:1" << endl;
1322   SALOMEDSImpl_ChildIterator Itr = NewChildIterator(aSO);
1323   string aTab("   ");
1324   for(; Itr.More(); Itr.Next()) {
1325     dumpSO(Itr.Value(), fp, aTab, this);
1326   }
1327
1328   fp.close();
1329 }
1330
1331
1332 void dumpSO(const SALOMEDSImpl_SObject& theSO,
1333             fstream& fp,
1334             const string& Tab,
1335             SALOMEDSImpl_Study* theStudy)
1336 {
1337   string aTab(Tab), anID(theSO.GetID());
1338   fp << aTab << anID << endl;
1339   vector<DF_Attribute*> attribs = theSO.GetLabel().GetAttributes();
1340   for(int i = 0; i<attribs.size(); i++) {
1341     SALOMEDSImpl_GenericAttribute* anAttr = dynamic_cast<SALOMEDSImpl_GenericAttribute*>(attribs[i]);
1342
1343     if(!anAttr) {
1344       continue;
1345     }
1346
1347     string aType = anAttr->GetClassType();
1348     fp << Tab << "  -- " << aType;
1349
1350     if(aType == string("AttributeReal")) {
1351       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReal*>(anAttr)->Value();
1352     }
1353     else if(aType == string("AttributeInteger")) {
1354       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeInteger*>(anAttr)->Value();
1355     }
1356     else if(aType ==  string("AttributeName")) {
1357       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeName*>(anAttr)->Value();
1358     }
1359     else if(aType == string("AttributeComment")) {
1360       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeComment*>(anAttr)->Value();
1361     }
1362     else if(aType == string("AttributeReference")) {
1363       fp << " : " << dynamic_cast<SALOMEDSImpl_AttributeReference*>(anAttr)->Save();
1364     }
1365     fp << endl;
1366   }
1367
1368   SALOMEDSImpl_ChildIterator Itr = theStudy->NewChildIterator(theSO);
1369   string aNewTab("   ");
1370   aNewTab+=aTab;
1371   for(; Itr.More(); Itr.Next()) {
1372     dumpSO(Itr.Value(), fp, aNewTab, theStudy);
1373   }
1374
1375   return;
1376 }
1377
1378 void SALOMEDSImpl_Study::Modify()
1379 {
1380   _errorCode = "";
1381   _doc->SetModified(true);
1382 }
1383
1384 //============================================================================
1385 /*! Function : 
1386  *  Purpose  :
1387  */
1388 //============================================================================
1389 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetCommonParameters(const char* theID, int theSavePoint)
1390 {
1391   if (theSavePoint < 0) return NULL;
1392   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1393   SALOMEDSImpl_SObject so = FindComponent((char*)theID);
1394   if (!so) so = builder->NewComponent((char*)theID);
1395   SALOMEDSImpl_AttributeParameter* attParam = NULL;
1396
1397   if (theSavePoint > 0) { // Try to find SObject that contains attribute parameter ...
1398     DF_Label savePointLabel = so.GetLabel().FindChild( theSavePoint, /*create=*/0 );
1399     if ( !savePointLabel.IsNull() )
1400       so = GetSObject( savePointLabel );
1401     else // ... if it does not exist - create a new one
1402       so = builder->NewObjectToTag( so, theSavePoint );
1403   }
1404
1405   DF_Attribute* A;
1406   if (so) {
1407     builder->FindAttribute(so, A, "AttributeParameter");
1408     if ( !A ) { // first call of GetCommonParameters on "Interface Applicative" component
1409       A = builder->FindOrCreateAttribute(so, "AttributeParameter"); 
1410     }
1411     attParam = dynamic_cast<SALOMEDSImpl_AttributeParameter*>( A );
1412   }
1413   return attParam;
1414 }
1415
1416 //============================================================================
1417 /*! Function : 
1418  *  Purpose  :
1419  */
1420 //============================================================================
1421 SALOMEDSImpl_AttributeParameter* SALOMEDSImpl_Study::GetModuleParameters(const char* theID, 
1422                                                                          const char* theModuleName,
1423                                                                          int theSavePoint)
1424 {
1425   if(theSavePoint <= 0) return NULL;
1426   SALOMEDSImpl_AttributeParameter* main_ap = GetCommonParameters(theID, theSavePoint);
1427   SALOMEDSImpl_SObject main_so = main_ap->GetSObject();
1428   SALOMEDSImpl_AttributeParameter* par = NULL;
1429
1430   SALOMEDSImpl_ChildIterator it = NewChildIterator(main_so);
1431   string moduleName(theModuleName);
1432   for(; it.More(); it.Next()) {
1433     SALOMEDSImpl_SObject so(it.Value());
1434     if((par=(SALOMEDSImpl_AttributeParameter*)so.GetLabel().FindAttribute(SALOMEDSImpl_AttributeParameter::GetID()))) {
1435       if(!par->IsSet("AP_MODULE_NAME", (Parameter_Types)3)) continue; //3 -> PT_STRING
1436       if(par->GetString("AP_MODULE_NAME") == moduleName) return par;
1437     }
1438   }
1439
1440   SALOMEDSImpl_StudyBuilder* builder = NewBuilder();
1441   SALOMEDSImpl_SObject so = builder->NewObject(main_so);
1442   par  = dynamic_cast<SALOMEDSImpl_AttributeParameter*>(builder->FindOrCreateAttribute(so, "AttributeParameter"));
1443   par->SetString("AP_MODULE_NAME", moduleName);
1444   return par;
1445 }
1446
1447 //============================================================================
1448 /*! Function : SetStudyLock
1449  *  Purpose  :
1450  */
1451 //============================================================================
1452 void SALOMEDSImpl_Study::SetStudyLock(const char* theLockerID)
1453 {
1454   _lockers.push_back(theLockerID);
1455 }
1456
1457 //============================================================================
1458 /*! Function : IsStudyLocked
1459  *  Purpose  :
1460  */
1461 //============================================================================
1462 bool SALOMEDSImpl_Study::IsStudyLocked()
1463 {
1464   return (_lockers.size() > 0);
1465 }
1466
1467 //============================================================================
1468 /*! Function : UnLockStudy
1469  *  Purpose  :
1470  */
1471 //============================================================================
1472 void SALOMEDSImpl_Study::UnLockStudy(const char* theLockerID)
1473 {
1474   vector<string>::iterator vsI = _lockers.begin();
1475   int length = _lockers.size();
1476   bool isFound = false;
1477   string id(theLockerID);
1478   for(int i = 0; i<length; i++, vsI++) {
1479     if(id == _lockers[i]) {
1480       isFound = true;;
1481       break;
1482     }
1483   }
1484   if(isFound) _lockers.erase(vsI);
1485 }
1486   
1487 //============================================================================
1488 /*! Function : GetLockerID
1489  *  Purpose  :
1490  */
1491 //============================================================================
1492 vector<string> SALOMEDSImpl_Study::GetLockerID()
1493 {
1494   return _lockers;
1495 }
1496
1497 //============================================================================
1498 /*! Function : EnableUseCaseAutoFilling
1499  *  Purpose  :
1500  */
1501 //============================================================================
1502 void SALOMEDSImpl_Study::EnableUseCaseAutoFilling(bool isEnabled)
1503
1504   _errorCode = ""; _autoFill = isEnabled; 
1505   if(isEnabled) {
1506     _builder->SetOnAddSObject(_cb);
1507     _builder->SetOnRemoveSObject(_cb);
1508   }
1509   else {
1510     _builder->SetOnAddSObject(NULL);
1511     _builder->SetOnRemoveSObject(NULL);
1512   }
1513 }
1514
1515 //============================================================================
1516 /*! Function : GetIORs
1517  *  Purpose  :
1518  */
1519 //============================================================================
1520 vector<string> SALOMEDSImpl_Study::GetIORs()
1521 {
1522   vector<string> anIORs;
1523   map<string, DF_Label>::const_iterator MI;
1524   for(MI = myIORLabels.begin(); MI!=myIORLabels.end(); MI++)
1525     anIORs.push_back(MI->first);
1526
1527   return anIORs;
1528 }