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