Salome HOME
NRI : Remove dependence with VISU.
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_Study_i.cxx
1 using namespace std;
2 //  File      : SALOMEDS_Study_i.cxx
3 //  Created   : Wed Nov 28 16:27:23 2001
4 //  Author    : Yves FRICAUD
5
6 //  Project   : SALOME
7 //  Module    : SALOMEDS
8 //  Copyright : Open CASCADE 2001
9 //  $Header$
10
11 #include "utilities.h"
12 #include "SALOMEDS_Study_i.hxx"
13
14 #include "SALOMEDS_DataMapIteratorOfDataMapStringLabel.hxx"
15 #include <TColStd_SequenceOfExtendedString.hxx>
16 #include <TCollection_AsciiString.hxx>
17 #include <TCollection_ExtendedString.hxx>
18 #include <TDataStd_ChildNodeIterator.hxx>
19 #include <TDocStd_Application.hxx>
20 #include <TDocStd_Owner.hxx>
21 #include <CDM_Document.hxx>
22 #include <CDM_Application.hxx>
23 #include "SALOMEDS_LocalIDAttribute.hxx"
24 #include "SALOMEDS_UseCaseIterator_i.hxx"
25
26
27 #define DIRECTORYID "DIRECTORY:"
28 #define FILEID "FILE: "
29
30 //============================================================================
31 /*! Function : SALOMEDS_Study_i
32  *  Purpose  : SALOMEDS_Study_i constructor
33  */
34 //============================================================================
35 SALOMEDS_Study_i::SALOMEDS_Study_i(const Handle(TDocStd_Document) doc,
36                                    CORBA::ORB_ptr                 orb,
37                                    const char* study_name)
38 {
39   _orb = CORBA::ORB::_duplicate(orb);
40   _doc = doc;
41   _name = new char[strlen(study_name) +1];
42   strcpy(_name,study_name);
43   _isSaved = false ;
44   _URL = NULL;
45   _StudyId = -1;
46   _autoFill = true;
47 }
48   
49 //============================================================================
50 /*! Function : ~SALOMEDS_Study_i
51  *  Purpose  : SALOMEDS_Study_i destructor
52  */
53 //============================================================================
54 SALOMEDS_Study_i::~SALOMEDS_Study_i()
55 {
56   delete [] _name ;
57   delete [] _URL ;
58 }  
59
60 //============================================================================
61 /*! Function : GetPersistentReference
62  *  Purpose  : Get persistent reference of study (idem URL())
63  */
64 //============================================================================
65 char* SALOMEDS_Study_i::GetPersistentReference()
66 {
67   return URL();
68 }
69 //============================================================================
70 /*! Function : GetTransientReference
71  *  Purpose  : Get IOR of the Study (registred in OCAF document in doc->Root)
72  */
73 //============================================================================
74 char* SALOMEDS_Study_i::GetTransientReference()
75 {
76   CORBA::String_var IOR;
77
78   Handle(SALOMEDS_IORAttribute) Att;
79   TDF_Label _lab = _doc->GetData()->Root();
80   if (!_lab.FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
81
82     TCollection_AsciiString ch(Att->Get());
83     IOR = CORBA::string_dup(ch.ToCString());
84   }
85   else IOR = CORBA::string_dup(""); // NULL ?
86
87   return CORBA::string_dup(IOR); 
88 }
89
90 //============================================================================
91 /*! Function : IsEmpty
92  *  Purpose  : Detect if study is empty
93  */
94 //============================================================================
95 CORBA::Boolean SALOMEDS_Study_i::IsEmpty()
96 {
97   if (_doc.IsNull()) return true;
98   return _doc->IsEmpty();
99 }
100
101 //============================================================================
102 /*! Function : FindComponent
103  *  Purpose  : Find a Component with ComponentDataType = aComponentName
104  */
105 //============================================================================
106 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponent (const char* aComponentName)
107 {
108   bool _find = false;
109   Standard_CString name;
110   SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
111   SALOMEDS::SComponent_var compo;
112
113   for (; itcomp->More(); itcomp->Next()) {
114     SALOMEDS::SComponent_var SC = itcomp->Value();
115     name = SC->ComponentDataType();
116     //ED if ( TCollection_AsciiString(name).IsEqual(TCollection_AsciiString(strdup(aComponentName))) ) {
117     if(strcmp(aComponentName,name) == 0){
118       _find = true;
119       return SALOMEDS::SComponent::_narrow(SC); 
120     }
121   }
122   if(!_find)
123     {
124       return SALOMEDS::SComponent::_nil();
125     }
126   return compo;
127 }
128
129 //============================================================================
130 /*! Function : FindComponentID
131  *  Purpose  : Find a Component from it's ID
132  */
133 //============================================================================
134 SALOMEDS::SComponent_ptr SALOMEDS_Study_i::FindComponentID(const char* aComponentID)
135 {
136   // Iterate on each components defined in the study
137   // Get the component ID and compare with aComponentID 
138   bool _find = false;
139   char *ID;
140   SALOMEDS::SComponent_ptr compo;
141
142   SALOMEDS::SComponentIterator_var itcomp = NewComponentIterator();
143   for (; itcomp->More(); itcomp->Next()) {
144     SALOMEDS::SComponent_var SC = itcomp->Value();
145     ID = SC->GetID();
146     if(strcmp(aComponentID,ID)==0)
147       {
148         // ComponentID found
149         _find = true;
150         compo = SALOMEDS::SComponent::_narrow(SC);
151       }
152   }
153   if(!_find)
154     {
155       compo = SALOMEDS::SComponent::_nil();
156     }
157   return compo;
158 }
159
160 //============================================================================
161 /*! Function : FindObject
162  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
163  */
164 //============================================================================
165 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObject(const char* anObjectName)
166 {
167   // Iterate to all components defined in the study
168   // After testing the component name, iterate in all objects defined under
169   // components (function _FindObject)
170   bool _find = false;
171   SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
172
173   SALOMEDS::SComponentIterator_var it = NewComponentIterator();
174   for (; it->More();it->Next()){
175     if(!_find)
176       {
177         SALOMEDS::SComponent_var SC = it->Value();
178         SALOMEDS::GenericAttribute_var anAttr;
179         if (SC->FindAttribute(anAttr,"AttributeName")) 
180         {
181           SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
182           CORBA::String_var Val = Name->Value();
183           if (strcmp(Val, anObjectName) == 0)
184             {
185               _find = true;
186               RefSO = SALOMEDS::SObject::_narrow(SC);
187             }
188         }
189         if (!_find) RefSO =  _FindObject(SC,anObjectName, _find);
190       }
191   }
192   return RefSO;
193 }
194
195 //============================================================================
196 /*! Function : FindObjectID
197  *  Purpose  : Find an Object with ID = anObjectID
198  */
199 //============================================================================
200 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectID(const char* anObjectID)
201 {
202   // Convert aSO->GetID in TDF_Label.
203   TDF_Label Lab;
204   TDF_Tool::Label(_doc->GetData(), strdup(anObjectID), Lab);
205   
206   if (Lab.IsNull()) return SALOMEDS::SObject::_nil();
207   SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (Lab,_orb);
208   SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
209   return so;
210
211 }
212
213 //============================================================================
214 /*! Function : FindObjectByName
215  *  Purpose  : Find Objects with SALOMEDS::Name = anObjectName in a Component
216  *           : with ComponentDataType = aComponentName
217  */
218 //============================================================================
219 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindObjectByName( const char* anObjectName,
220                                                                     const char* aComponentName )
221 {
222   SALOMEDS::Study::ListOfSObject_var listSO = new SALOMEDS::Study::ListOfSObject ;
223   listSO->length(0);
224   
225   SALOMEDS::SComponent_ptr compo = FindComponent(aComponentName) ;
226   if ( compo->_is_nil() ) {
227     MESSAGE ("In FindObjectByName() :  Component named " << aComponentName << " not found ");
228     return listSO._retn();
229   }
230
231   // Iterate on each object and subobject of the component
232   // If objectName is found add it to the list of SObjects 
233   char *name;
234   char *childName ;
235   SALOMEDS::SObject_ptr addSO = SALOMEDS::SObject::_nil();
236
237   CORBA::String_var compoId = compo->GetID();
238   SALOMEDS::ChildIterator_var it = NewChildIterator(compo);
239   int length = 0 ;
240   for ( ; it->More();it->Next() ) {
241     
242     SALOMEDS::SObject_var CSO = it->Value();
243     SALOMEDS::GenericAttribute_var anAttr;
244     SALOMEDS::AttributeName_var    aName;
245     if ( CSO->FindAttribute(anAttr, "AttributeName") ) {
246       aName = SALOMEDS::AttributeName::_narrow(anAttr);
247       name = aName->Value();
248       if ( strcmp( name, anObjectName ) == 0) {
249         addSO = SALOMEDS::SObject::_narrow(CSO);
250         /* add to list */
251         length++ ;
252         listSO->length(length);
253         listSO[length-1] = addSO ;
254       }
255       
256       /* looks also for eventual children */
257       bool found = false ;
258       addSO = _FindObject( CSO, anObjectName, found ) ;
259       if( found) {
260         length++ ;
261         listSO->length(length);
262         listSO[length-1] = addSO ;
263       }
264     }
265   }
266   return listSO._retn() ;
267 }
268
269
270
271 //============================================================================
272 /*! Function : FindObjectIOR
273  *  Purpose  : Find an Object with IOR = anObjectIOR
274  */
275 //============================================================================
276 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectIOR(const char* anObjectIOR)
277 {
278   // firstly searching in the datamap for optimization
279   CORBA::String_var anIOR = CORBA::string_dup(anObjectIOR);
280   if (myIORLabels.IsBound(TCollection_ExtendedString(anIOR))) {
281     SALOMEDS_SObject_i* aResult = new SALOMEDS_SObject_i(myIORLabels.Find(TCollection_ExtendedString(anIOR)),_orb);
282     // 11 oct 2002: forbidden attributes must be checked here
283     SALOMEDS::GenericAttribute_var anAttr;
284     if (!aResult->FindAttribute(anAttr,"AttributeIOR")) {
285       myIORLabels.UnBind(TCollection_ExtendedString(anIOR));
286     } else return aResult->_this();
287   }
288   // Iterate to all components defined in the study
289   // After testing the component name, iterate in all objects defined under
290   // components (function _FindObject)
291   bool _find = false;
292   SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
293
294   SALOMEDS::SComponentIterator_var it = NewComponentIterator();
295   for (; it->More();it->Next()){
296     if(!_find)
297       {
298         SALOMEDS::SComponent_var SC = it->Value();
299         SALOMEDS::GenericAttribute_var anAttr;
300         if (SC->FindAttribute(anAttr,"AttributeIOR")) 
301         {
302           SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
303           CORBA::String_var Val = IOR->Value();
304           if (strcmp(Val, anObjectIOR) == 0)
305             {
306               _find = true;
307               RefSO = SALOMEDS::SObject::_narrow(SC);
308             }
309         }
310         if (!_find) 
311           RefSO =  _FindObjectIOR(SC,anObjectIOR, _find);
312       }
313   }
314   if (!RefSO->_is_nil()) INFOS("SALOMEDS_Study_i::FindObjectIOR: found label with old methods");
315
316   return RefSO;
317 }
318
319 //============================================================================
320 /*! Function : FindObjectByPath
321  *  Purpose  : Find an Object by its path = thePath
322  */
323 //============================================================================
324 SALOMEDS::SObject_ptr SALOMEDS_Study_i::FindObjectByPath(const char* thePath)
325 {
326   TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aToken;
327   SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_nil();
328   int i = 1, aLength = aPath.Length();
329   bool isRelative = false;
330
331   if(aLength == 0) {  //Empty path - return the current context
332     SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_current, _orb);
333     aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
334     return aSO._retn();
335   }
336
337   if(aPath.Value(1) != '/')  //Relative path 
338     isRelative = true;
339
340   TDF_ChildIterator anIterator;
341   TDF_Label aLabel;
342   Handle(TDataStd_Name) anAttr;
343
344   if(isRelative) {
345     if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext(); 
346     anIterator.Initialize(_current, Standard_False);
347   }
348   else {
349     if(aPath.Length() == 1 && aPath.Value(1) == '/') {    //Root
350       SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_doc->Main(), _orb);
351       aSO = SALOMEDS::SObject::_narrow(so_servant->_this());
352       return aSO._retn();
353     }
354     anIterator.Initialize(_doc->Main(), Standard_False);
355   }
356
357   while(i <= aLength) {
358
359     aToken = aPath.Token("/", i);
360     if(aToken.Length() == 0) break;
361
362     for ( ; anIterator.More(); anIterator.Next() ) {
363       aLabel = anIterator.Value();
364       if(aLabel.FindAttribute(TDataStd_Name::GetID(), anAttr)) {
365         if(anAttr->Get() == aToken) {
366           aToken = aPath.Token("/", i+1); //Check if it was the last part of the path
367           if(aToken.Length() == 0) {  //The searched label is found (no part of the path is left)
368               SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (aLabel, _orb);
369               aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
370               return aSO._retn();
371           }
372
373           anIterator.Initialize(aLabel, Standard_False);
374           break;
375         }
376       }
377     }
378
379     i++;
380   }
381
382   return aSO._retn();
383 }
384
385 //============================================================================
386 /*! Function : GetObjectPath
387  *  Purpose  : 
388  */
389 //============================================================================
390 char* SALOMEDS_Study_i::GetObjectPath(CORBA::Object_ptr theObject)
391 {
392   TCollection_AsciiString aPath("");
393   if(CORBA::is_nil(theObject)) return CORBA::string_dup(aPath.ToCString());
394
395   SALOMEDS::SObject_var anObject = SALOMEDS::SObject::_narrow(theObject);
396   if(anObject->_is_nil()) {
397     anObject = FindObjectIOR(_orb->object_to_string(theObject));
398     if(anObject->_is_nil()) return CORBA::string_dup(aPath.ToCString());
399   }
400
401   SALOMEDS::GenericAttribute_var anAttr;
402   if(anObject->FindAttribute(anAttr, "AttributeName")) {
403     SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
404     if(anAttr->_is_nil()) return CORBA::string_dup(aPath.ToCString());
405     TCollection_AsciiString aValue(aName->Value());
406     aValue.Prepend("/");
407     aValue += aPath;
408     aPath = aValue;
409     SALOMEDS::SObject_ptr aFather = anObject->GetFather();
410     if(!aFather->_is_nil()) {
411       TDF_Label aLabel;
412       Handle(TDataStd_Name) aNameAttrib;
413       TDF_Tool::Label(_doc->GetData(), aFather->GetID(), aLabel);
414       if(aLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttrib)) {
415           aValue = GetObjectPath(aFather);
416           aPath = aValue + aPath;
417       }
418     }
419   }
420
421   return  CORBA::string_dup(aPath.ToCString());
422 }
423
424
425 //============================================================================
426 /*! Function : SetContext
427  *  Purpose  : Sets the current context
428  */
429 //============================================================================
430 void SALOMEDS_Study_i::SetContext(const char* thePath) 
431 {
432   if(thePath == NULL || strlen(thePath) == 0) throw SALOMEDS::Study::StudyInvalidDirectory();
433   TCollection_AsciiString aPath(CORBA::string_dup(thePath)), aContext("");
434   bool isInvalid = false, isFound = false;
435   SALOMEDS::SObject_var aSO;
436   
437   if(aPath.Value(1) != '/') { //Relative path 
438     aContext = TCollection_AsciiString(GetContext());
439     aContext += '/';
440     aContext += aPath;
441   }
442   else
443     aContext = aPath;
444   
445   try {
446     aSO = FindObjectByPath(aContext.ToCString());
447   }
448   catch( ... ) {
449     isInvalid = true;
450   }
451
452   if(isInvalid || aSO->_is_nil()) throw SALOMEDS::Study::StudyInvalidContext();
453
454   TDF_Label aLabel;
455   TDF_Tool::Label(_doc->GetData(), aSO->GetID(), aLabel);
456   if(aLabel.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();
457   else
458     _current = aLabel;  //Set the current context
459   
460 }
461
462 //============================================================================
463 /*! Function : GetContext
464  *  Purpose  : Gets the current context
465  */
466 //============================================================================
467 char* SALOMEDS_Study_i::GetContext() 
468 {
469   if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();   
470   SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (_current, _orb);
471   SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(so_servant->_this()); 
472   return GetObjectPath(aSO._retn());
473 }
474
475 //============================================================================
476 /*! Function : GetObjectNames
477  *  Purpose  : method to get all object names in the given context (or in the current context, if 'theContext' is empty)
478  */
479 //============================================================================
480 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetObjectNames(const char* theContext) {
481   TColStd_SequenceOfExtendedString aResultSeq;
482   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
483   TDF_Label aLabel;
484   if (strlen(theContext) == 0) {
485     if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();   
486     aLabel = _current;
487   } else {
488     TDF_Label aTmp = _current;
489     SetContext(theContext);
490     aLabel = _current;
491     _current = aTmp;
492   }
493   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
494   for(; anIter.More(); anIter.Next()) {
495     TDF_Label aLabel = anIter.Value();
496 //      Handle(TDF_Attribute) anAttribute;
497 //      if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
498 //      aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
499     Handle(TDataStd_Name) aName;
500     if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
501 //    }
502   }
503   // fill the result table
504   int anIndex, aLength = aResultSeq.Length();
505   aResult->length(aLength);
506   for(anIndex = 0; anIndex < aLength; anIndex++) {
507     aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
508   }
509   return aResult._retn();
510 }
511
512 //============================================================================
513 /*! Function : GetDirectoryNames
514  *  Purpose  : method to get all directory names in the given context (or in the current context, if 'theContext' is empty)
515  */
516 //============================================================================
517 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetDirectoryNames(const char* theContext) {
518   TColStd_SequenceOfExtendedString aResultSeq;
519   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
520   TDF_Label aLabel;
521   if (strlen(theContext) == 0) {
522     if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();   
523     aLabel = _current;
524   } else {
525     TDF_Label aTmp = _current;
526     SetContext(theContext);
527     aLabel = _current;
528     _current = aTmp;
529   }
530   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate first-level children at all sublevels
531   for(; anIter.More(); anIter.Next()) {
532     TDF_Label aLabel = anIter.Value();
533 //      Handle(TDF_Attribute) anAttribute;
534 //      if (!aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) &&
535 //      !aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
536     Handle(SALOMEDS_PersRefAttribute) anID;
537     if (aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), anID)) {
538       if (anID->Get().Search(TCollection_ExtendedString(DIRECTORYID)) == 1) {
539         Handle(TDataStd_Name) aName;
540         if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) {
541           aResultSeq.Append(aName->Get());
542         }
543       }
544     }
545 //      }
546   }
547   // fill the result table
548   int anIndex, aLength = aResultSeq.Length();
549   aResult->length(aLength);
550   for(anIndex = 0; anIndex < aLength; anIndex++) {
551     aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
552   }
553   return aResult._retn();
554 }
555
556 //============================================================================
557 /*! Function : GetFileNames
558  *  Purpose  : method to get all file names in the given context (or in the current context, if 'theContext' is empty)
559  */
560 //============================================================================
561 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetFileNames(const char* theContext) {
562   TColStd_SequenceOfExtendedString aResultSeq;
563   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
564   TDF_Label aLabel;
565   if (strlen(theContext) == 0) {
566     if(_current.IsNull()) throw SALOMEDS::Study::StudyInvalidContext();   
567     aLabel = _current;
568   } else {
569     TDF_Label aTmp = _current;
570     SetContext(theContext);
571     aLabel = _current;
572     _current = aTmp;
573   }
574   TDF_ChildIterator anIter(aLabel, Standard_False); // iterate all subchildren at all sublevels
575   for(; anIter.More(); anIter.Next()) {
576     TDF_Label aLabel = anIter.Value();
577 //      Handle(TDF_Attribute) anAttribute;
578 //      if (aLabel.FindAttribute(SALOMEDS_IORAttribute::GetID(), anAttribute) ||
579 //      aLabel.FindAttribute(SALOMEDS_LocalIDAttribute::GetID(), anAttribute)) {
580     Handle(SALOMEDS_PersRefAttribute) aName;
581     if (aLabel.FindAttribute(SALOMEDS_PersRefAttribute::GetID(), aName)) {
582       if (aName->Get().Search(TCollection_ExtendedString(FILEID)) == 1) {
583         aResultSeq.Append(aName->Get().Split(strlen(FILEID)));
584       }
585     }
586 //      }
587   }
588   // fill the result table
589   int anIndex, aLength = aResultSeq.Length();
590   aResult->length(aLength);
591   for(anIndex = 0; anIndex < aLength; anIndex++) {
592     aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
593   }
594   return aResult._retn();
595 }
596
597 //============================================================================
598 /*! Function : GetComponentNames
599  *  Purpose  : method to get all components names
600  */
601 //============================================================================
602 SALOMEDS::ListOfStrings* SALOMEDS_Study_i::GetComponentNames(const char* theContext) {
603   TColStd_SequenceOfExtendedString aResultSeq;
604   SALOMEDS::ListOfStrings_var aResult = new SALOMEDS::ListOfStrings;
605   TDF_ChildIterator anIter(_doc->Main(), Standard_False); // iterate all subchildren at first level
606   for(; anIter.More(); anIter.Next()) {
607     TDF_Label aLabel = anIter.Value();
608     Handle(TDataStd_Name) aName;
609     if (aLabel.FindAttribute(TDataStd_Name::GetID(), aName)) aResultSeq.Append(aName->Get());
610   }
611   // fill the result table
612   int anIndex, aLength = aResultSeq.Length();
613   aResult->length(aLength);
614   for(anIndex = 0; anIndex < aLength; anIndex++) {
615     aResult[anIndex] = CORBA::string_dup(TCollection_AsciiString(aResultSeq.Value(anIndex + 1)).ToCString());
616   }
617   return aResult._retn();
618 }
619
620 //============================================================================
621 /*! Function : NewChildIterator
622  *  Purpose  : Create a ChildIterator from an SObject
623  */
624 //============================================================================
625 SALOMEDS::ChildIterator_ptr SALOMEDS_Study_i::NewChildIterator(SALOMEDS::SObject_ptr aSO)
626 {
627   //Convert aSO->GetID in TDF_Label.
628   TDF_Label Lab;
629   TDF_Tool::Label(_doc->GetData(), strdup(aSO->GetID()), Lab);
630
631   //Create iterator
632   SALOMEDS_ChildIterator_i* it_servant = new SALOMEDS_ChildIterator_i(Lab,_orb);
633   SALOMEDS::ChildIterator_var it = SALOMEDS::ChildIterator::_narrow(it_servant->_this()); 
634
635   return it;
636 }
637
638
639 //============================================================================
640 /*! Function : NewComponentIterator
641  *  Purpose  : Create a SComponentIterator
642  */
643 //============================================================================
644 SALOMEDS::SComponentIterator_ptr SALOMEDS_Study_i::NewComponentIterator()
645 {
646   SALOMEDS_SComponentIterator_i* it_servant = new SALOMEDS_SComponentIterator_i(_doc,_orb);
647   SALOMEDS::SComponentIterator_var it = SALOMEDS::SComponentIterator::_narrow(it_servant->_this()); 
648   return it;
649 }
650
651
652 //============================================================================
653 /*! Function : NewBuilder
654  *  Purpose  : Create a StudyBuilder
655  */
656 //============================================================================
657 SALOMEDS::StudyBuilder_ptr SALOMEDS_Study_i::NewBuilder()
658 {
659   SALOMEDS_StudyBuilder_i* it_servant = new SALOMEDS_StudyBuilder_i(_doc,_orb);
660   SALOMEDS::StudyBuilder_var it = SALOMEDS::StudyBuilder::_narrow(it_servant->_this()); 
661
662   if(_autoFill) {
663     SALOMEDS_Callback_i* callback = new SALOMEDS_Callback_i(GetUseCaseBuilder(), _orb);
664     SALOMEDS::Callback_var cb = SALOMEDS::Callback::_narrow(callback->_this()); 
665
666     it->SetOnAddSObject(cb);
667     it->SetOnRemoveSObject(cb);
668   }
669
670   return it;
671
672 }
673  
674 //============================================================================
675 /*! Function : Name
676  *  Purpose  : get study name
677  */
678 //============================================================================
679 char* SALOMEDS_Study_i::Name()
680 {
681   return CORBA::string_dup(_name);
682 }
683
684 //============================================================================
685 /*! Function : Name
686  *  Purpose  : set study name
687  */
688 //============================================================================
689 void SALOMEDS_Study_i::Name(const char* name)
690 {
691   _name = new char[strlen(name) +1];
692   strcpy(_name,name);
693 }
694
695 //============================================================================
696 /*! Function : IsSaved
697  *  Purpose  : get if study has been saved
698  */
699 //============================================================================
700 CORBA::Boolean  SALOMEDS_Study_i::IsSaved()
701 {
702   return _isSaved;
703 }
704
705 //============================================================================
706 /*! Function : IsSaved
707  *  Purpose  : set if study has been saved
708  */
709 //============================================================================
710 void SALOMEDS_Study_i::IsSaved(CORBA::Boolean save)
711 {
712   _isSaved = save;
713 }
714
715 //============================================================================
716 /*! Function : IsModified
717  *  Purpose  : Detect if a Study has been modified since it has been saved
718  */
719 //============================================================================
720 CORBA::Boolean  SALOMEDS_Study_i::IsModified()
721 {
722   // True if is modified and not saved
723   if (_doc->IsModified())
724     if (!_isSaved) return true;
725     else return false;
726   else return false;
727 }
728
729 //============================================================================
730 /*! Function : URL
731  *  Purpose  : get URL of the study (persistent reference of the study)
732  */
733 //============================================================================
734 char* SALOMEDS_Study_i::URL()
735 {
736   return CORBA::string_dup(_URL);
737 }
738
739 //============================================================================
740 /*! Function : URL
741  *  Purpose  : set URL of the study (persistent reference of the study)
742  */
743 //============================================================================
744 void SALOMEDS_Study_i::URL(const char* url)
745 {
746   _URL = new char[strlen(url) +1];
747   strcpy(_URL,url);
748   SCRUTE(_URL);
749 }
750
751
752 //============================================================================
753 /*! Function : _FindObject
754  *  Purpose  : Find an Object with SALOMEDS::Name = anObjectName
755  */
756 //============================================================================
757 SALOMEDS::SObject_ptr SALOMEDS_Study_i::_FindObject(SALOMEDS::SObject_ptr SO,
758                                                     const char* anObjectName, 
759                                                     bool& _find)
760 {
761   // Iterate on each objects and subobjects of the component
762   // If objectName find, stop the loop and get the object reference
763   SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
764
765   CORBA::String_var soid = SO->GetID();
766   SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
767   for (; it->More();it->Next()){
768     if(!_find)
769       {
770         SALOMEDS::SObject_var CSO = it->Value();
771         SALOMEDS::GenericAttribute_var anAttr;
772         if (CSO->FindAttribute(anAttr,"AttributeName")) 
773         {
774           SALOMEDS::AttributeName_var Name = SALOMEDS::AttributeName::_narrow(anAttr);
775           CORBA::String_var Val = Name->Value();
776           if (strcmp(Val, anObjectName) == 0)
777             {
778               RefSO = SALOMEDS::SObject::_narrow(CSO);
779               _find = true;
780             }
781         }
782         if (!_find) RefSO =  _FindObject(CSO, anObjectName, _find);
783       }
784   }
785   return RefSO;
786 }
787
788 //============================================================================
789 /*! Function : _FindObject
790  *  Purpose  : Find an Object with SALOMEDS::IOR = anObjectIOR
791  */
792 //============================================================================
793 SALOMEDS::SObject_ptr 
794 SALOMEDS_Study_i::_FindObjectIOR(SALOMEDS::SObject_ptr SO,
795                               const char* anObjectIOR, 
796                               bool& _find)
797 {
798   // Iterate on each objects and subobjects of the component
799   // If objectName find, stop the loop and get the object reference
800   SALOMEDS::SObject_ptr RefSO = SALOMEDS::SObject::_nil();
801
802   SALOMEDS::ChildIterator_var it = NewChildIterator(SO);
803   for (; it->More();it->Next()){
804     if(!_find)
805       {
806         SALOMEDS::SObject_var CSO = it->Value();
807         SALOMEDS::GenericAttribute_var anAttr;
808         if (CSO->FindAttribute(anAttr,"AttributeIOR")) 
809         {
810           SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
811           CORBA::String_var Val = IOR->Value();
812           if (strcmp(Val, anObjectIOR) == 0)
813             {
814               RefSO = SALOMEDS::SObject::_narrow(CSO);
815               _find = true;
816             }
817         }
818         if (!_find) RefSO =  _FindObjectIOR(CSO, anObjectIOR, _find);
819       }
820   }
821   return RefSO;
822 }
823
824 CORBA::Short SALOMEDS_Study_i::StudyId()
825 {
826   return _StudyId;
827 }
828
829 void SALOMEDS_Study_i::StudyId(CORBA::Short id)
830 {
831   _StudyId = id;
832 }
833
834 void SALOMEDS_Study_i::UpdateIORLabelMap(const char* anIOR,const char* anEntry) {
835   TDF_Label aLabel;
836   CORBA::String_var anEn = CORBA::string_dup(anEntry);
837   CORBA::String_var IOR = CORBA::string_dup(anIOR);
838   TDF_Tool::Label(_doc->GetData(),anEn,aLabel, Standard_True);
839   if (myIORLabels.IsBound(TCollection_ExtendedString(IOR))) myIORLabels.UnBind(TCollection_ExtendedString(IOR));
840   myIORLabels.Bind(TCollection_ExtendedString(IOR), aLabel);
841 }
842
843 void SALOMEDS_Study_i::IORUpdated(const Handle(SALOMEDS_IORAttribute) theAttribute, CORBA::ORB_ptr orb) {
844   // get accorded study first
845   Handle(SALOMEDS_IORAttribute) Att;
846   if (theAttribute->Label().Root().FindAttribute(SALOMEDS_IORAttribute::GetID(),Att)){
847     TCollection_AsciiString ch(Att->Get());
848     char* IOR = CORBA::string_dup(ch.ToCString());
849     CORBA::Object_var obj = orb->string_to_object(IOR);
850     SALOMEDS::Study_ptr aStudy = SALOMEDS::Study::_narrow(obj) ;
851     ASSERT(!CORBA::is_nil(aStudy));
852     TCollection_AsciiString aString;
853     TDF_Tool::Entry(theAttribute->Label(),aString);
854     aStudy->UpdateIORLabelMap(TCollection_AsciiString(theAttribute->Get()).ToCString(), aString.ToCString());
855   } else {
856     INFOS("IORUpdated: Problem to get study");
857     return;
858   }
859 }
860
861 SALOMEDS::Study::ListOfSObject* SALOMEDS_Study_i::FindDependances(SALOMEDS::SObject_ptr anObject) {
862   SALOMEDS::GenericAttribute_ptr aTarget;
863   if (anObject->FindAttribute(aTarget,"AttributeTarget")) {
864     return SALOMEDS::AttributeTarget::_narrow(aTarget)->Get();
865   }
866   SALOMEDS::Study::ListOfSObject* aList = new SALOMEDS::Study::ListOfSObject;
867   aList->length(0);
868   return aList;
869 }
870
871
872 SALOMEDS::AttributeStudyProperties_ptr SALOMEDS_Study_i::GetProperties() {
873   SALOMEDS::GenericAttribute_ptr anAttr =  NewBuilder()->FindOrCreateAttribute(FindObjectID("0:1"),
874                                                                                "AttributeStudyProperties");
875   return SALOMEDS::AttributeStudyProperties::_narrow(anAttr);
876 }
877
878 char* SALOMEDS_Study_i::GetLastModificationDate() {
879   SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
880   SALOMEDS::StringSeq_var aNames;
881   SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
882   aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
883   int aLastIndex = aNames->length() - 1;
884   char aResult[20];
885   sprintf(aResult, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[aLastIndex]),(int)(aMonths[aLastIndex]),
886           (int)(aYears[aLastIndex]), (int)(aHours[aLastIndex]), (int)(aMinutes[aLastIndex]));
887   CORBA::String_var aResStr = CORBA::string_dup(aResult);
888   return aResStr._retn();
889 }
890
891 SALOMEDS::ListOfDates* SALOMEDS_Study_i::GetModificationsDate() {
892   SALOMEDS::AttributeStudyProperties_var aProp = GetProperties();
893   SALOMEDS::StringSeq_var aNames;
894   SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
895   aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, false);
896
897   int anIndex, aLength = aNames->length();
898   SALOMEDS::ListOfDates_var aDates = new SALOMEDS::ListOfDates;
899   aDates->length(aLength);
900
901   for(anIndex = 0; anIndex < aLength; anIndex++) {
902     char aDate[20];
903     sprintf(aDate, "%2.2d/%2.2d/%4.4d %2.2d:%2.2d", (int)(aDays[anIndex]), (int)(aMonths[anIndex]),
904             (int)(aYears[anIndex]), (int)(aHours[anIndex]), (int)(aMinutes[anIndex]));
905     aDates[anIndex] = CORBA::string_dup(aDate);
906   }
907   return aDates._retn();
908 }
909
910
911
912 //============================================================================
913 /*! Function : GetUseCaseBuilder
914  *  Purpose  : Returns a UseCase builder
915  */
916 //============================================================================
917 SALOMEDS::UseCaseBuilder_ptr SALOMEDS_Study_i::GetUseCaseBuilder() 
918 {
919   SALOMEDS_UseCaseBuilder_i* _caseBuilder = new SALOMEDS_UseCaseBuilder_i(_doc, _orb);
920   SALOMEDS::UseCaseBuilder_var aBuilder = SALOMEDS::UseCaseBuilder::_narrow(_caseBuilder->_this());
921   return aBuilder._retn();
922 }
923
924
925 //============================================================================
926 /*! Function : Close
927  *  Purpose  : 
928  */
929 //============================================================================
930 void SALOMEDS_Study_i::Close()
931 {
932   SALOMEDS::SComponentIterator_var itcomponent = NewComponentIterator();
933
934   for (; itcomponent->More(); itcomponent->Next()) {
935     SALOMEDS::SComponent_var sco = itcomponent->Value();
936           
937     MESSAGE ( "Look for an engine for data type :"<< sco->ComponentDataType());
938     // if there is an associated Engine call its method for closing
939     CORBA::String_var IOREngine;
940     if (sco->ComponentIOR(IOREngine)) {
941       // we have found the associated engine to write the data 
942       MESSAGE ( "We have found an engine for data type :"<< sco->ComponentDataType());
943       CORBA::Object_var obj = _orb->string_to_object(IOREngine);
944       SALOMEDS::Driver_var anEngine = SALOMEDS::Driver::_narrow(obj) ;
945               
946       if (!anEngine->_is_nil())  
947         anEngine->Close(sco);
948     }
949   }
950
951   Handle(TDocStd_Application) anApp = Handle(TDocStd_Application)::DownCast(_doc->Application());
952 //    Handle(TDocStd_Owner) anOwner;
953 //    if (_doc->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
954 //      Handle(TDocStd_Document) anEmptyDoc;
955 //      anOwner->SetDocument(anEmptyDoc);
956 //    }
957   if(!anApp.IsNull()) anApp->Close(_doc);
958   _doc.Nullify();
959 }