Salome HOME
This commit was generated by cvs2git to create tag 'V1_4_0b1'.
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_StudyManager_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_StudyManager_i.cxx
25 //  Author : Yves FRICAUD 
26 //  Module : SALOME
27 //  $Header$
28
29 using namespace std;
30 #include "utilities.h"
31 #include "SALOME_LifeCycleCORBA.hxx"
32 #include "SALOMEDS_StudyManager_i.hxx"
33 #include "SALOMEDS_Study_i.hxx"
34 #include "SALOMEDS_SComponent_i.hxx"
35
36 #include "SALOMEDS_IORAttribute.hxx"
37 #include "SALOMEDS_PersRefAttribute.hxx"
38 #include "SALOMEDS_Tool.hxx"
39
40 #include <TDF_Label.hxx>
41 #include <TDataStd_Name.hxx>
42 #include <TDataStd_Comment.hxx>
43 #include <TDataStd_TreeNode.hxx>
44 #include <TDataStd_UAttribute.hxx> 
45 #include <TDF_Tool.hxx>
46 #include <TDF_Reference.hxx>
47 #include <TDF_Data.hxx>
48 #include <TDF_RelocationTable.hxx>
49 #include <TDF_AttributeIterator.hxx>
50 //  #include <TDocStd_Owner.hxx>
51 #include <TColStd_HArray1OfCharacter.hxx>
52 #include <TCollection_ExtendedString.hxx>
53 #include "HDFexplorer.hxx"
54 #include "SALOMEDS_SequenceOfRealAttribute.hxx"
55 #include "SALOMEDS_SequenceOfIntegerAttribute.hxx"
56 #include <TColStd_HSequenceOfReal.hxx>
57 #include <TColStd_HSequenceOfInteger.hxx>
58 #include "SALOMEDS_PixMapAttribute.hxx"
59 #include "SALOMEDS_DrawableAttribute.hxx"
60 #include "SALOMEDS_SelectableAttribute.hxx"
61 #include "SALOMEDS_ExpandableAttribute.hxx"
62 #include "SALOMEDS_OpenedAttribute.hxx"
63 #include "SALOMEDS_TextColorAttribute.hxx"
64 #include "SALOMEDS_TextHighlightColorAttribute.hxx"
65 #include "SALOMEDS_LocalIDAttribute.hxx"
66 #include "SALOMEDS_TargetAttribute.hxx"
67 #include "SALOMEDS_TableOfIntegerAttribute.hxx"
68 #include "SALOMEDS_TableOfRealAttribute.hxx"
69 #include "SALOMEDS_TableOfStringAttribute.hxx"
70 #include "SALOMEDS_StudyPropertiesAttribute.hxx"
71 #include "SALOMEDS_PythonObjectAttribute.hxx"
72 #include <OSD_Process.hxx>
73 #include <Quantity_Date.hxx>
74
75 #include "Utils_CorbaException.hxx"
76
77 #include <strstream>
78
79 #include <SALOME_GenericObj_i.hh>
80
81 #define USE_CASE_LABEL_ID             "0:2"
82 #define AUTO_SAVE_GUID                "128268A3-71C9-4036-89B1-F81BD6A4FCF2"
83 #define AUTO_SAVE_TAG                 "0:8"
84 #define AUTO_SAVE_TIME_OUT_IN_SECONDS 1200
85 //===========================================================================
86 //Function : LoadAttributes
87 //===========================================================================
88 static void ReadAttributes(Handle(TDF_Data)& DF,
89                            TDF_Label& Lab, 
90                            HDFdataset* hdf_dataset)
91 {
92   hdf_dataset->OpenOnDisk();
93   
94   if (hdf_dataset->GetType() == HDF_STRING) {
95
96     if (!strncmp(hdf_dataset->GetName(),"AttributeTreeNode",17)) {
97       MESSAGE("Create a Attribute :     AttributeTreeNode");
98       char current_strings[5][hdf_dataset->GetSize()/5];
99       hdf_dataset->ReadFromDisk(current_strings);
100
101       MESSAGE("Create an Attribute :     AttributeTreeNode"); 
102       Standard_GUID aGUID(current_strings[4]);
103       Handle(TDataStd_TreeNode) aNewNode = TDataStd_TreeNode::Set(Lab,aGUID);
104       TDF_Label aLabel;
105       Handle(TDataStd_TreeNode) aNode;
106       if (current_strings[0][0]) {
107         TDF_Tool::Label(DF,current_strings[0],aLabel,1);
108         if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
109         aNewNode->SetFather(aNode);
110       }
111       if (current_strings[1][0]) {
112         TDF_Tool::Label(DF,current_strings[1],aLabel,1);
113        if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
114         aNewNode->SetPrevious(aNode);
115       }
116       if (current_strings[2][0]) {
117         TDF_Tool::Label(DF,current_strings[2],aLabel,1);
118         if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
119         aNewNode->SetNext(aNode);
120       }
121       if (current_strings[3][0]) {
122         TDF_Tool::Label(DF,current_strings[3],aLabel,1);
123         if (!aLabel.FindAttribute(aGUID,aNode)) aNode = TDataStd_TreeNode::Set(aLabel,aGUID);
124         aNewNode->SetFirst(aNode);
125       }
126     } else {
127
128       int size =  hdf_dataset->GetSize();
129       char* current_string = new char[size];
130       hdf_dataset->ReadFromDisk(current_string);
131
132       if (!strcmp(hdf_dataset->GetName(),"COMPONENTDATATYPE")) {      
133         MESSAGE("Create a OCAF Attribute :    COMPONENTDATATYPE");
134         TDataStd_Comment::Set         (Lab,current_string); 
135       }
136       else if (!strcmp(hdf_dataset->GetName(),"AttributeComment")) {
137         MESSAGE("Create an Attribute :     AttributeComment"); 
138         TDataStd_Comment::Set         (Lab,current_string); 
139       }
140       else if (!strcmp(hdf_dataset->GetName(),"AttributeName")) {
141         MESSAGE("Create an  Attribute :     AttributeName");       
142         TDataStd_Name::Set            (Lab,current_string);
143       }
144       else if (!strcmp(hdf_dataset->GetName(),"AttributePersistentRef")) { 
145         MESSAGE("Create an Attribute :     AttributePersistentRef"); 
146         SALOMEDS_PersRefAttribute::Set(Lab,current_string);
147       }
148       else if (!strcmp(hdf_dataset->GetName(),"Reference")) {
149         MESSAGE("Create a OCAF Attribute :     Reference"); 
150         TDF_Label RefLab;
151         TDF_Tool::Label(DF,current_string,RefLab,1);
152         TDF_Reference::Set(Lab,RefLab);
153         SALOMEDS_TargetAttribute::Set(RefLab)->Append(Lab);
154       }
155       else if (!strcmp(hdf_dataset->GetName(),"AttributeReal")) {
156         MESSAGE("Create a Attribute :     AttributeReal");
157         char * err = NULL;
158         CORBA::Double r =  strtod(current_string, &err);
159         SCRUTE(r);
160         if (err == current_string) {
161           MESSAGE("AtttributeReal : conversion impossible");
162         }
163         else TDataStd_Real::Set (Lab,r);
164       }
165       else if (!strcmp(hdf_dataset->GetName(),"AttributeInteger")) {
166         MESSAGE("Create a Attribute :     AttributeInteger");
167         CORBA::Long r =  atol(current_string);
168         SCRUTE(r);
169         TDataStd_Integer::Set (Lab,r);
170       }
171       else if (!strcmp(hdf_dataset->GetName(),"AttributePixMap")) {
172         MESSAGE("Create an  Attribute :     AttributePixMap");       
173         SALOMEDS_PixMapAttribute::Set (Lab,current_string);
174       }
175       else if (!strcmp(hdf_dataset->GetName(),"AttributeDrawable")) {
176         MESSAGE("Create a Attribute :     DrawableAttribute");
177         CORBA::Long r =  atol(current_string);
178         SCRUTE(r);
179         SALOMEDS_DrawableAttribute::Set (Lab,r);
180       }
181       else if (!strcmp(hdf_dataset->GetName(),"AttributeSelectable")) {
182         MESSAGE("Create a Attribute :     AttributeSelectable");
183         CORBA::Long r =  atol(current_string);
184         SCRUTE(r);
185         SALOMEDS_SelectableAttribute::Set (Lab,r);
186       }
187       else if (!strcmp(hdf_dataset->GetName(),"AttributeExpandable")) {
188         MESSAGE("Create a Attribute :     AttributeExpandable");
189         CORBA::Long r =  atol(current_string);
190         SCRUTE(r);
191         SALOMEDS_ExpandableAttribute::Set (Lab,r);
192       }
193       else if (!strcmp(hdf_dataset->GetName(),"AttributeOpened")) {
194         MESSAGE("Create a Attribute :     AttributeOpened");
195         CORBA::Long r =  atol(current_string);
196         SCRUTE(r);
197         SALOMEDS_OpenedAttribute::Set (Lab,r);
198       }
199       else if (!strcmp(hdf_dataset->GetName(),"AttributeLocalID")) {
200         MESSAGE("Create a Attribute :     AttributeLocalID");
201         CORBA::Long r =  atol(current_string);
202         SCRUTE(r);
203         SALOMEDS_LocalIDAttribute::Set (Lab,r);
204       }
205       else if (!strncmp(hdf_dataset->GetName(),"AttributeUserID",15)) {
206         MESSAGE("Create an  Attribute :     AttributeUserID");       
207         TDataStd_UAttribute::Set       (Lab,Standard_GUID(current_string));
208       }
209       else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfInteger")) {
210         MESSAGE("Create a Attribute :     AttributeTableOfInteger");
211         int size = hdf_dataset->GetSize();
212         Handle(SALOMEDS_TableOfIntegerAttribute) Attr = SALOMEDS_TableOfIntegerAttribute::Set(Lab);
213         unsigned char* aBuffer = new unsigned char[size];
214         if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfInteger");
215         hdf_dataset->ReadFromDisk(aBuffer);
216         SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
217         istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
218         Attr->RestoreFromString(aStream);
219       }
220       else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfReal")) {
221         MESSAGE("Create a Attribute :     AttributeTableOfReal");
222         int size = hdf_dataset->GetSize();
223         Handle(SALOMEDS_TableOfRealAttribute) Attr = SALOMEDS_TableOfRealAttribute::Set(Lab);
224         unsigned char* aBuffer = new unsigned char[size];
225         if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfReal");
226         hdf_dataset->ReadFromDisk(aBuffer);
227         SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
228         istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
229         Attr->RestoreFromString(aStream);
230       }
231       else if (!strcmp(hdf_dataset->GetName(),"AttributeTableOfString")) {
232         MESSAGE("Create a Attribute :     AttributeTableOfString");
233         int size = hdf_dataset->GetSize();
234         Handle(SALOMEDS_TableOfStringAttribute) Attr = SALOMEDS_TableOfStringAttribute::Set(Lab);
235         unsigned char* aBuffer = new unsigned char[size];
236         if(aBuffer == NULL) throw HDFexception("Unable to open dataset AttributeTableOfString");
237         hdf_dataset->ReadFromDisk(aBuffer);
238         SALOMEDS::TMPFile_var aTMPFile = new SALOMEDS::TMPFile(size, size, aBuffer, 1);
239         istrstream aStream((char*)&aTMPFile[0], aTMPFile->length());
240         Attr->RestoreFromString(aStream);
241       }
242       else if (!strcmp(hdf_dataset->GetName(),"AttributeStudyProperties")) {
243         MESSAGE("Create an  Attribute :     AttributeStudyProperties");     
244 //      MESSAGE("current string :"<<current_string);
245         Handle(SALOMEDS_StudyPropertiesAttribute) aProp = SALOMEDS_StudyPropertiesAttribute::Set (Lab);
246         switch (current_string[0]) {
247         case 'f': aProp->SetCreationMode(1);break;
248         case 'c': aProp->SetCreationMode(2);break;
249         }
250
251         int anIndex;
252         for(anIndex = 2; anIndex + 2 < size ;) {
253           char str[10];
254           Standard_Integer aMinute, aHour, aDay, aMonth, aYear;
255           str[0] = current_string[anIndex++];
256           str[1] = current_string[anIndex++];
257           str[2] = 0;
258           aMinute = atoi(str);
259           str[0] = current_string[anIndex++];
260           str[1] = current_string[anIndex++];
261           aHour =  atoi(str);
262           str[0] = current_string[anIndex++];
263           str[1] = current_string[anIndex++];
264           aDay =  atoi(str);
265           str[0] = current_string[anIndex++];
266           str[1] = current_string[anIndex++];
267           aMonth =  atoi(str);
268           str[0] = current_string[anIndex++];
269           str[1] = current_string[anIndex++];
270           str[2] = current_string[anIndex++];
271           str[3] = current_string[anIndex++];
272           str[4] = 0;
273           aYear = atoi(str);
274           aProp->SetModificationDate(aMinute,aHour,aDay,aMonth,aYear);
275
276           int aNameSize;
277           for(aNameSize = 0; current_string[anIndex+aNameSize]!=1; aNameSize++);
278           char *aName = new char[aNameSize+1];
279           strncpy(aName, &(current_string[anIndex]), aNameSize);
280           aName[aNameSize] = 0;
281           aProp->SetUserName(TCollection_ExtendedString(aName));
282           delete(aName);
283           anIndex += aNameSize + 1;
284           if (current_string[1] == 'l') {
285             aProp->SetLocked(Standard_True);
286             aProp->IsLockChanged(true);
287           }
288           aProp->SetModified(0);
289         }
290       }
291       else if (!strcmp(hdf_dataset->GetName(),"AttributePythonObject")) {
292         MESSAGE("Create an  Attribute :     AttributePythonObject");       
293         Handle(SALOMEDS_PythonObjectAttribute) anObj = SALOMEDS_PythonObjectAttribute::Set(Lab);
294         Standard_Boolean aScript = (current_string[0] == 's')?Standard_True:Standard_False;
295         anObj->SetObject((char *)(current_string+1), aScript);
296       }
297       else {
298         MESSAGE(hdf_dataset->GetName());
299         MESSAGE("LoadAttributes: unknown types");
300       }
301     }
302   }
303   if (hdf_dataset->GetType() == HDF_FLOAT64) {
304     if (!strcmp(hdf_dataset->GetName(),"AttributeSequenceOfReal")) {
305       MESSAGE("Create a Attribute :     AttributeSequenceOfReal");
306       int size = hdf_dataset->GetSize();
307       hdf_float64* val = new hdf_float64[size];
308       hdf_dataset->ReadFromDisk(val);
309       Handle(TColStd_HSequenceOfReal) SeqReal = new TColStd_HSequenceOfReal;
310       for (Standard_Integer i = 0; i < size; i++) {
311         SeqReal->Append(val[i]);
312 //          MESSAGE( val[i] << " restored"   );
313       }
314       SALOMEDS_SequenceOfRealAttribute::Set (Lab);
315       Handle(SALOMEDS_SequenceOfRealAttribute) Attr;
316       Handle(TDF_Attribute) Att;
317       Lab.FindAttribute(SALOMEDS_SequenceOfRealAttribute::GetID(),Att);
318       Attr = Handle(SALOMEDS_SequenceOfRealAttribute)::DownCast(Att);
319       Attr->Assign(SeqReal);
320     } else
321     if (!strcmp(hdf_dataset->GetName(),"AttributeTextColor")) {
322       MESSAGE("Create a Attribute :     AttributeTextColor");
323       hdf_float64 val[3];
324       hdf_dataset->ReadFromDisk(val);
325       Handle(SALOMEDS_TextColorAttribute) TC = new SALOMEDS_TextColorAttribute;
326       Lab.AddAttribute(TC); 
327       TC->SetValue(1, val[0]);
328       TC->SetValue(2, val[1]);
329       TC->SetValue(3, val[2]);
330     } else
331     if (!strcmp(hdf_dataset->GetName(),"AttributeTextHighlightColor")) {
332       MESSAGE("Create a Attribute :     AttributeTextHighlightColor");
333       hdf_float64 val[3];
334       hdf_dataset->ReadFromDisk(val);
335       Handle(SALOMEDS_TextHighlightColorAttribute) TC = new SALOMEDS_TextHighlightColorAttribute;
336       Lab.AddAttribute(TC); 
337       TC->SetValue(1, val[0]);
338       TC->SetValue(2, val[1]);
339       TC->SetValue(3, val[2]);
340     }else {
341       MESSAGE(hdf_dataset->GetName());
342       MESSAGE("LoadAttributes: unknown types");
343     }
344   }
345   if (hdf_dataset->GetType() == HDF_INT32) {
346     if (!strcmp(hdf_dataset->GetName(),"AttributeSequenceOfInteger")) {
347       MESSAGE("Create a OCAF Attribute :     AttributeSequenceOfInteger");
348       int size = hdf_dataset->GetSize();
349       hdf_int32* val = new hdf_int32[size];
350       hdf_dataset->ReadFromDisk(val);
351       Handle(TColStd_HSequenceOfInteger) SeqInt = new TColStd_HSequenceOfInteger;
352       for (Standard_Integer i = 0; i < size; i++) {
353         SeqInt->Append(val[i]);
354 //          MESSAGE( val[i] << " restored"   );
355       }
356       SALOMEDS_SequenceOfIntegerAttribute::Set (Lab);
357       Handle(SALOMEDS_SequenceOfIntegerAttribute) Attr;
358       Handle(TDF_Attribute) Att;
359       Lab.FindAttribute(SALOMEDS_SequenceOfIntegerAttribute::GetID(),Att);
360       Attr = Handle(SALOMEDS_SequenceOfIntegerAttribute)::DownCast(Att);
361       Attr->Assign(SeqInt);
362     } 
363     else {
364       MESSAGE(hdf_dataset->GetName());
365       MESSAGE("LoadAttributes: unknown types");
366     }
367   }
368   hdf_dataset->CloseOnDisk();
369 }
370
371 //============================================================================
372 //Function : Translate_IOR_to_persistentID
373 //============================================================================
374 static void Translate_IOR_to_persistentID (SALOMEDS::Study_ptr        study,
375                                            SALOMEDS::StudyBuilder_ptr SB,
376                                            SALOMEDS::SObject_ptr      so,
377                                            SALOMEDS::Driver_ptr       engine,
378                                            CORBA::Boolean             isMultiFile,
379                                            CORBA::Boolean             isASCII)
380 {
381   MESSAGE("In Translate_IOR_to_persistentID");
382   SALOMEDS::ChildIterator_var itchild = study->NewChildIterator(so);
383   CORBA::String_var ior_string;
384   char* persistent_string = 0;
385   char *curid=0;
386
387   for (; itchild->More(); itchild->Next()) {
388     SALOMEDS::SObject_var current = itchild->Value();
389     SCRUTE(current->GetID());
390     SALOMEDS::GenericAttribute_var SObj;
391     if (current->FindAttribute(SObj, "AttributeIOR")) {
392       SALOMEDS::AttributeIOR_var IOR = SALOMEDS::AttributeIOR::_narrow(SObj);
393       ior_string = IOR->Value();
394       SCRUTE(ior_string);
395       
396       persistent_string = engine->IORToLocalPersistentID (current,ior_string,isMultiFile, isASCII);
397       
398 //       SB->AddAttribute (current, SALOMEDS::PersistentRef,persistent_string);
399       SALOMEDS::AttributePersistentRef_var Pers = SALOMEDS::AttributePersistentRef::_narrow(SB->FindOrCreateAttribute (current, "AttributePersistentRef"));
400       Pers->SetValue(persistent_string);
401       SCRUTE(persistent_string);
402       curid = current->GetID();
403       MESSAGE("Translate " << curid <<
404               " to Persistent string "<<persistent_string);
405       persistent_string = 0;
406       curid = 0;
407     }
408     Translate_IOR_to_persistentID (study,SB,current,engine,isMultiFile, isASCII);
409   }
410   CORBA::string_free(persistent_string);
411   CORBA::string_free(curid);
412 }
413
414 //============================================================================
415 //Function : BuildlTree
416 //============================================================================
417 static void BuildTree  (Handle(TDF_Data)& DF,HDFgroup* hdf_current_group)
418 {
419   hdf_current_group->OpenOnDisk();
420   
421   TDF_Label Lab;
422   Standard_CString Entry = hdf_current_group->GetName();
423   if (strcmp(Entry,"STUDY_STRUCTURE") == 0) {
424     MESSAGE("find the root of the document");
425     Lab =  DF->Root().FindChild(1,Standard_True);
426   }
427   else {
428     TDF_Tool::Label  (DF,Entry,Lab,1);
429     MESSAGE("BuildTree : Create a new label"<<Entry);
430   }
431   char name[HDF_NAME_MAX_LEN+1];
432   Standard_Integer nbsons = hdf_current_group->nInternalObjects(); 
433   
434   for (Standard_Integer i=0; i<nbsons; i++) {
435     hdf_current_group->InternalObjectIndentify(i,name);
436     if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
437     hdf_object_type type = hdf_current_group->InternalObjectType(name);
438
439     if  (type == HDF_DATASET) {
440       MESSAGE("--> Dataset: Internal Object Name : " << name);
441       HDFdataset* new_dataset = new HDFdataset(name,hdf_current_group);
442       ReadAttributes   (DF,Lab,new_dataset);      
443       new_dataset = 0; // will be deleted by father destructor
444
445     }
446     else if (type == HDF_GROUP)   {
447       MESSAGE( "--> Group: Internal Object Name : " << name);
448       HDFgroup* new_group = new HDFgroup(name,hdf_current_group);
449       BuildTree (DF,new_group);
450       new_group = 0; // will be deleted by father destructor
451     }
452   }
453   hdf_current_group->CloseOnDisk();
454 }
455
456
457 //============================================================================
458 /*! Function : SALOMEDS_StudyManager_i
459  *  Purpose  : SALOMEDS_StudyManager_i constructor 
460  */
461 //============================================================================
462 SALOMEDS_StudyManager_i::SALOMEDS_StudyManager_i(CORBA::ORB_ptr orb) 
463
464   _orb = CORBA::ORB::_duplicate(orb);
465   _OCAFApp = new SALOMEDS_OCAFApplication();  
466   _name_service = new SALOME_NamingService(_orb);
467   // Study directory creation in the naming service : to register all
468   // open studies in the session
469   _name_service->Create_Directory("/Study");
470   _IDcounter = 0;
471 }
472
473 //============================================================================
474 /*! Function : ~SALOMEDS_StudyManager_i
475  *  Purpose  : SALOMEDS_StudyManager_i destructor
476  */
477 //============================================================================
478 SALOMEDS_StudyManager_i::~SALOMEDS_StudyManager_i()
479 {
480   // Destroy directory to register open studies
481   _name_service->Destroy_Directory("/Study");
482   // Destroy OCAF document
483   delete &_OCAFApp;
484 }
485
486 //============================================================================
487 /*! Function : register_name
488  *  Purpose  : Register the study Manager in the naming service under the  
489  *             context name
490  */
491 //============================================================================
492 void SALOMEDS_StudyManager_i::register_name(char * name) {
493   SALOMEDS::StudyManager_ptr g = SALOMEDS::StudyManager::_narrow(_this());
494   _name_service->Register(g, name);
495 }
496
497
498 //============================================================================
499 /*! Function : NewStudy
500  *  Purpose  : Create a New Study of name study_name
501  */
502 //============================================================================
503 SALOMEDS::Study_ptr SALOMEDS_StudyManager_i::NewStudy(const char* study_name) 
504 {
505   Handle(TDocStd_Document) Doc;
506   _OCAFApp->NewDocument("SALOME_STUDY",Doc); 
507
508   MESSAGE("NewStudy : Creating the CORBA servant holding it... ");
509   SALOMEDS_Study_i *Study_servant = new SALOMEDS_Study_i(Doc,_orb,study_name); 
510   SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this());
511
512   //Study->StudyId( _OCAFApp->NbDocuments() ); 
513   _IDcounter++;
514   Study->StudyId( _IDcounter );
515
516   // Register study in the naming service
517   // Path to acces the study
518   if(!_name_service->Change_Directory("/Study")) 
519       MESSAGE( "Unable to access the study directory" )
520   else
521       _name_service->Register(Study, study_name);
522
523   // Assign the value of the IOR in the study->root
524   const char*  IORStudy = _orb->object_to_string(Study);
525   SALOMEDS_IORAttribute::Set(Doc->Main().Root(),TCollection_ExtendedString(strdup(IORStudy)),_orb);
526
527   // set Study properties
528   SALOMEDS::AttributeStudyProperties_ptr aProp = Study->GetProperties();
529   OSD_Process aProcess;
530   Quantity_Date aDate = aProcess.SystemDate();
531   aProp->SetCreationDate(CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
532                          CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
533   aProp->SetCreationMode("from scratch");
534   aProp->SetUserName(aProcess.UserName().ToCString());
535
536   return Study;
537 }
538
539 //============================================================================
540 /*! Function : Open
541  *  Purpose  : Open a Study from it's persistent reference
542  */
543 //============================================================================
544 SALOMEDS::Study_ptr  SALOMEDS_StudyManager_i::Open(const char* aUrl)
545      throw(SALOME::SALOME_Exception)
546 {
547   MESSAGE("Begin of SALOMEDS_StudyManager_i::Open");
548   // open the HDFFile 
549   HDFfile *hdf_file =0;         
550   HDFgroup *hdf_group_study_structure =0;
551
552   char* aHDFUrl;
553   bool isASCII = false;
554   if (HDFascii::isASCII(aUrl)) {
555     isASCII = true;
556     char* aResultPath = HDFascii::ConvertFromASCIIToHDF(aUrl);
557     aHDFUrl = new char[strlen(aResultPath) + 19];
558     sprintf(aHDFUrl, "%shdf_from_ascii.hdf", aResultPath);
559     delete(aResultPath);
560   } else {
561     aHDFUrl = strdup(aUrl);
562   }
563
564   hdf_file = new HDFfile(aHDFUrl);
565   try {
566     hdf_file->OpenOnDisk(HDF_RDONLY);// mpv: was RDWR, but opened file can be write-protected too
567   }
568   catch (HDFexception)
569     {
570 //        MESSAGE( "HDFexception ! " );
571 //        cerr << "HDFexception ! " << endl;
572       delete aHDFUrl;
573       char eStr[strlen(aUrl)+17];
574       sprintf(eStr,"Can't open file %s",aUrl);
575       THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
576       
577     } 
578   MESSAGE("Open : Creating the CORBA servant holding it... ");
579
580   // Temporary aStudyUrl in place of study name
581   Handle(TDocStd_Document) Doc;
582   _OCAFApp->NewDocument("SALOME_STUDY",Doc); 
583
584   SALOMEDS_Study_i * Study_servant = new SALOMEDS_Study_i(Doc, _orb, aUrl);  
585   SALOMEDS::Study_var Study = SALOMEDS::Study::_narrow(Study_servant->_this()); 
586
587   //  Study->StudyId( _OCAFApp->NbDocuments() ); 
588   _IDcounter++;
589   Study->StudyId( _IDcounter );
590
591   // Assign the value of the URL in the study object
592   Study->URL (aUrl);
593   SCRUTE(aUrl);
594
595   // Assign the value of the IOR in the study->root
596   CORBA::String_var IORStudy = _orb->object_to_string(Study);
597   SALOMEDS_IORAttribute::Set(Doc->Main().Root(),
598                              TCollection_ExtendedString(CORBA::string_dup(IORStudy)),_orb);
599
600   SALOMEDS_PersRefAttribute::Set(Doc->Main(),strdup(aUrl)); 
601
602   if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
603     delete aHDFUrl;
604     MESSAGE("SALOMEDS_StudyManager::Open : the study is empty");
605     return Study;
606   }
607
608   //Create  the Structure of the OCAF Document
609   hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
610
611   Handle(TDF_Data) DF = Doc->GetData();
612
613   try {
614     BuildTree (DF,hdf_group_study_structure);
615   }
616   catch (HDFexception)
617     {
618 //        MESSAGE( "HDFexception ! " );
619 //        cerr << "HDFexception ! " << endl;
620       delete aHDFUrl;
621       char eStr[strlen(aUrl)+17];
622       sprintf(eStr,"Can't open file %s",aUrl);
623       THROW_SALOME_CORBA_EXCEPTION(CORBA::string_dup(eStr),SALOME::BAD_PARAM);
624     } 
625   
626   hdf_file->CloseOnDisk();
627
628   // Register study in the naming service
629   // Path to acces the study
630   if(!_name_service->Change_Directory("/Study")) MESSAGE( "Unable to access the study directory" )
631   else _name_service->Register(Study, CORBA::string_dup(Study->Name()));
632
633
634   if (isASCII) {
635     SALOMEDS::ListOfFileNames_var aFilesToRemove = new SALOMEDS::ListOfFileNames;
636     aFilesToRemove->length(1);
637     aFilesToRemove[0] = strdup(&(aHDFUrl[strlen(SALOMEDS_Tool::GetDirFromPath(aHDFUrl))]));
638     SALOMEDS_Tool::RemoveTemporaryFiles(SALOMEDS_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
639   }
640   delete aHDFUrl;
641   delete hdf_file; // all related hdf objects will be deleted
642   return Study;
643 }
644
645
646
647 //============================================================================
648 /*! Function : Close
649  *  Purpose  : Close a study.
650  *             If the study hasn't been saved, ask the user to confirm the
651  *             close action without saving 
652  */
653 //============================================================================
654 void  SALOMEDS_StudyManager_i::Close(SALOMEDS::Study_ptr aStudy)
655 {
656   if(aStudy->_is_nil()) return;
657   
658   aStudy->RemovePostponed(-1);
659   
660   // Destroy study name in the naming service
661   if(_name_service->Change_Directory("/Study")) 
662     _name_service->Destroy_Name(aStudy->Name());
663   
664   aStudy->Close();
665 }
666
667 //============================================================================
668 /*! Function : Save
669  *  Purpose  : Save a Study to it's persistent reference
670  */
671 //============================================================================
672 void SALOMEDS_StudyManager_i::Save(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
673 {
674   CORBA::String_var url = aStudy->URL();
675   if (url==NULL)
676     MESSAGE( "No path specified to save the study. Nothing done")
677   else
678     {
679       _SaveAs(url,aStudy, theMultiFile, false);
680     }
681 }
682
683 void SALOMEDS_StudyManager_i::SaveASCII(SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
684 {
685   CORBA::String_var url = aStudy->URL();
686   if (url==NULL)
687     MESSAGE( "No path specified to save the study. Nothing done")
688   else
689     {
690       _SaveAs(url,aStudy, theMultiFile, true);
691     }
692 }
693
694 //=============================================================================
695 /*! Function : SaveAs
696  *  Purpose  : Save a study to the persistent reference aUrl
697  */
698 //============================================================================
699 void SALOMEDS_StudyManager_i::SaveAs(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
700 {
701   _SaveAs(aUrl,aStudy,theMultiFile, false);
702
703 }
704
705 void SALOMEDS_StudyManager_i::SaveAsASCII(const char* aUrl, SALOMEDS::Study_ptr aStudy, CORBA::Boolean theMultiFile)
706 {
707   _SaveAs(aUrl,aStudy,theMultiFile, true);
708 }
709
710 //============================================================================
711 /*! Function : GetOpenStudies
712  *  Purpose  : Get name list of open studies in the session
713  */
714 //============================================================================
715 SALOMEDS::ListOfOpenStudies*  SALOMEDS_StudyManager_i::GetOpenStudies()
716 {
717   // MESSAGE("Begin of GetOpenStudies");
718   SALOMEDS::ListOfOpenStudies_var _list_open_studies = new SALOMEDS::ListOfOpenStudies;
719   _list_open_studies->length(0);
720   vector<string> _list ;
721
722   if(!_name_service->Change_Directory("/Study"))
723     {
724       MESSAGE("No active study in this session");
725     }
726   else
727     {
728       _list = _name_service->list_directory();
729       _list_open_studies->length(_list.size());
730       for (unsigned int ind=0; ind < _list.size();ind++)
731         {
732           _list_open_studies[ind]=CORBA::string_dup(_list[ind].c_str());
733           SCRUTE(_list_open_studies[ind]) ;
734         }
735     }
736   return _list_open_studies._retn();
737 }
738
739 //============================================================================
740 /*! Function : GetStudyByName
741  *  Purpose  : Get a study from its name
742  */
743 //============================================================================
744 SALOMEDS::Study_ptr  
745 SALOMEDS_StudyManager_i::GetStudyByName(const char* aStudyName) 
746 {
747   SALOMEDS::Study_var Study;
748
749   // Go to study directory and look for aStudyName
750   if(!_name_service->Change_Directory("/Study"))
751     {
752       MESSAGE("No active study in this session");
753       ASSERT(false); // Stop here...
754     }
755   
756 //   const char *theStudyName = this->_SubstituteSlash(aStudyName);
757   const char* theStudyName = CORBA::string_dup(aStudyName);
758
759   if(_name_service->Find(theStudyName)>0)
760     {
761     // Study found
762     CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
763     Study = SALOMEDS::Study::_narrow(obj);
764     MESSAGE("Study " << theStudyName << " found in the naming service");
765     }
766   else  
767     {
768       Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
769       MESSAGE("Study " << theStudyName << " not found in the naming service");
770     }
771   return Study;
772 }
773
774 //============================================================================
775 /*! Function : GetStudyByID
776  *  Purpose  : Get a study from its ID
777  */
778 //============================================================================
779 SALOMEDS::Study_ptr  
780 SALOMEDS_StudyManager_i::GetStudyByID(CORBA::Short aStudyID) 
781 {
782   SALOMEDS::Study_var Study;
783   vector<string> _list ;
784
785   if(!_name_service->Change_Directory("/Study"))
786     {
787       MESSAGE("No active study in this session");
788     }
789   else
790     {
791       _list = _name_service->list_directory();
792       for (unsigned int ind=0; ind < _list.size();ind++)
793         {
794           const char* theStudyName = CORBA::string_dup(_list[ind].c_str());
795           MESSAGE ( "GetStudyByID = " << theStudyName )
796
797           if(_name_service->Find(theStudyName)>0) {
798             CORBA::Object_ptr obj= _name_service->Resolve(theStudyName) ;
799             Study = SALOMEDS::Study::_narrow(obj);
800
801             MESSAGE ( " aStudyID : " << aStudyID << "-" << Study->StudyId() )
802
803             if ( aStudyID == Study->StudyId() ) {
804               MESSAGE("Study with studyID = " << aStudyID << " found in the naming service");
805               return Study;
806             }
807           } else {
808             Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
809             MESSAGE("Study " << theStudyName << " not found in the naming service");
810           }
811         }
812       Study = SALOMEDS::Study::_narrow( CORBA::Object::_nil()); 
813     }
814   return Study;
815 }
816 //============================================================================
817 /*! Function : SaveAttributes
818  *  Purpose  : Save attributes for object
819  */
820 //============================================================================
821 static void SaveAttributes(SALOMEDS::SObject_ptr SO, HDFgroup *hdf_group_sobject) {
822   HDFdataset *hdf_dataset = 0;
823   hdf_size size[1];
824   hdf_int32 name_len = 0;
825   SALOMEDS::GenericAttribute_var SObj;
826   if(SO->FindAttribute(SObj, "AttributeComment"))
827     {
828       SALOMEDS::AttributeComment_var Comment = SALOMEDS::AttributeComment::_narrow(SObj);
829         CORBA::String_var Val = Comment->Value();
830         name_len = (hdf_int32) strlen(Val);
831         size[0] = name_len +1 ; 
832         hdf_dataset = new HDFdataset("AttributeComment",hdf_group_sobject,HDF_STRING,size,1);
833         hdf_dataset->CreateOnDisk();
834         hdf_dataset->WriteOnDisk(Val);
835         MESSAGE("attribute comment " <<  Val << " wrote on file");
836         hdf_dataset->CloseOnDisk();
837         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
838       }
839   // Attribute  SALOMEDS::PersistentRef
840   if(SO->FindAttribute(SObj, "AttributePersistentRef"))
841     {
842       SALOMEDS::AttributePersistentRef_var PersRef = SALOMEDS::AttributePersistentRef::_narrow(SObj);
843         CORBA::String_var Val = PersRef->Value();
844         name_len = (hdf_int32) strlen(Val);
845         size[0] = name_len +1 ; 
846         hdf_dataset = new HDFdataset("AttributePersistentRef",hdf_group_sobject,HDF_STRING,size,1);
847         hdf_dataset->CreateOnDisk();
848         hdf_dataset->WriteOnDisk(Val);
849         MESSAGE("attribute persistentref " <<  Val << " wrote on file");
850         hdf_dataset->CloseOnDisk();
851         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
852       }
853   // Attribute  SALOMEDS::Name
854   if(SO->FindAttribute(SObj, "AttributeName"))
855     {
856       SALOMEDS::AttributeName_var NameRef = SALOMEDS::AttributeName::_narrow(SObj);
857         CORBA::String_var Val = NameRef->Value();
858         name_len = (hdf_int32) strlen(Val);
859         size[0] = name_len +1 ; 
860         hdf_dataset = new HDFdataset("AttributeName",hdf_group_sobject,HDF_STRING,size,1);
861         hdf_dataset->CreateOnDisk();
862         hdf_dataset->WriteOnDisk(Val);
863         MESSAGE("attribute name " <<  Val << " wrote on file");
864         hdf_dataset->CloseOnDisk();
865         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
866       }
867   if(SO->FindAttribute(SObj, "AttributeReal"))
868     {
869       char RealVal[25];
870       SALOMEDS::AttributeReal_var RealRef = SALOMEDS::AttributeReal::_narrow(SObj);
871       sprintf(RealVal, "%f", RealRef->Value());
872       name_len = (hdf_int32) strlen(RealVal);
873       size[0] = name_len +1 ; 
874       hdf_dataset = new HDFdataset("AttributeReal",hdf_group_sobject,HDF_STRING,size,1);
875       hdf_dataset->CreateOnDisk();
876       hdf_dataset->WriteOnDisk(RealVal);
877       MESSAGE("attribute Real " <<  RealVal << " wrote on file");
878       hdf_dataset->CloseOnDisk();
879       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
880     }
881   if(SO->FindAttribute(SObj, "AttributeInteger"))
882     {
883       char IntVal[25];
884       SALOMEDS::AttributeInteger_var IntRef = SALOMEDS::AttributeInteger::_narrow(SObj);
885       sprintf(IntVal, "%d", IntRef->Value());
886       name_len = (hdf_int32) strlen(IntVal);
887       size[0] = name_len +1 ; 
888       hdf_dataset = new HDFdataset("AttributeInteger",hdf_group_sobject,HDF_STRING,size,1);
889       hdf_dataset->CreateOnDisk();
890       hdf_dataset->WriteOnDisk(IntVal);
891       MESSAGE("attribute Real " <<  IntVal << " wrote on file");
892       hdf_dataset->CloseOnDisk();
893       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
894     }     
895   
896   if(SO->FindAttribute(SObj, "AttributeSequenceOfReal"))
897     {
898       SALOMEDS::AttributeSequenceOfReal_var RealSeq = SALOMEDS::AttributeSequenceOfReal::_narrow(SObj);
899         size[0] = RealSeq->Length();
900         SALOMEDS::DoubleSeq_var DS = RealSeq->CorbaSequence();
901         hdf_dataset = new HDFdataset("AttributeSequenceOfReal",hdf_group_sobject,HDF_FLOAT64,size,1);
902         hdf_dataset->CreateOnDisk();
903         hdf_float64 *data = new hdf_float64[RealSeq->Length()];
904         for (Standard_Integer i = 0; i < RealSeq->Length(); i++) {
905           MESSAGE("Value =  " << i << " = " << DS[i]  << " wrote on file");
906           data[i] = DS[i];
907         }
908         hdf_dataset->WriteOnDisk(data);
909         //               delete data;
910         hdf_dataset->CloseOnDisk();
911         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
912       }
913   if(SO->FindAttribute(SObj, "AttributeSequenceOfInteger"))
914     {
915       SALOMEDS::AttributeSequenceOfInteger_var IntSeq = SALOMEDS::AttributeSequenceOfInteger::_narrow(SObj);
916         size[0] = IntSeq->Length();
917         SALOMEDS::LongSeq_var LS = IntSeq->CorbaSequence();
918         hdf_dataset = new HDFdataset("AttributeSequenceOfInteger",hdf_group_sobject,HDF_INT32,size,1);
919         hdf_dataset->CreateOnDisk();
920         hdf_int32 *data = new hdf_int32[IntSeq->Length()];
921         for (Standard_Integer i = 0; i < IntSeq->Length(); i++) {
922           MESSAGE("Value =  " << i << " = " << LS[i]  << " wrote on file");
923           data[i] = LS[i];
924         }
925         hdf_dataset->WriteOnDisk(data);
926         hdf_dataset->CloseOnDisk();
927         //               delete data;
928         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
929       }
930     if(SO->FindAttribute(SObj, "AttributeDrawable"))
931     {
932       char IntVal[25];
933       SALOMEDS::AttributeDrawable_var DrRef = SALOMEDS::AttributeDrawable::_narrow(SObj);
934       sprintf(IntVal, "%d", DrRef->IsDrawable());
935       name_len = (hdf_int32) strlen(IntVal);
936       size[0] = name_len +1 ; 
937       hdf_dataset = new HDFdataset("AttributeDrawable",hdf_group_sobject,HDF_STRING,size,1);
938       hdf_dataset->CreateOnDisk();
939       hdf_dataset->WriteOnDisk(IntVal);
940       MESSAGE("attribute Drawable " <<  IntVal << " wrote on file");
941       hdf_dataset->CloseOnDisk();
942       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
943     }     
944   if(SO->FindAttribute(SObj, "AttributeSelectable"))
945     {
946       char IntVal[25];
947       SALOMEDS::AttributeSelectable_var SelRef = SALOMEDS::AttributeSelectable::_narrow(SObj);
948       sprintf(IntVal, "%d", SelRef->IsSelectable());
949       name_len = (hdf_int32) strlen(IntVal);
950       size[0] = name_len +1 ; 
951       hdf_dataset = new HDFdataset("AttributeSelectable",hdf_group_sobject,HDF_STRING,size,1);
952       hdf_dataset->CreateOnDisk();
953       hdf_dataset->WriteOnDisk(IntVal);
954       MESSAGE("attribute Selectable " <<  IntVal << " wrote on file");
955       hdf_dataset->CloseOnDisk();
956       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
957     }     
958   if(SO->FindAttribute(SObj, "AttributeExpandable"))
959     {
960       char IntVal[25];
961       SALOMEDS::AttributeExpandable_var ExRef = SALOMEDS::AttributeExpandable::_narrow(SObj);
962       sprintf(IntVal, "%d", ExRef->IsExpandable());
963       name_len = (hdf_int32) strlen(IntVal);
964       size[0] = name_len +1 ; 
965       hdf_dataset = new HDFdataset("AttributeExpandable",hdf_group_sobject,HDF_STRING,size,1);
966       hdf_dataset->CreateOnDisk();
967       hdf_dataset->WriteOnDisk(IntVal);
968       MESSAGE("attribute Expandable " <<  IntVal << " wrote on file");
969       hdf_dataset->CloseOnDisk();
970       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
971     }     
972   if(SO->FindAttribute(SObj, "AttributeOpened"))
973     {
974       char IntVal[25];
975       SALOMEDS::AttributeOpened_var OpRef = SALOMEDS::AttributeOpened::_narrow(SObj);
976       sprintf(IntVal, "%d", OpRef->IsOpened());
977       name_len = (hdf_int32) strlen(IntVal);
978       size[0] = name_len +1 ; 
979       hdf_dataset = new HDFdataset("AttributeOpened",hdf_group_sobject,HDF_STRING,size,1);
980       hdf_dataset->CreateOnDisk();
981       hdf_dataset->WriteOnDisk(IntVal);
982       MESSAGE("attribute Opened " <<  IntVal << " wrote on file");
983       hdf_dataset->CloseOnDisk();
984       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
985     }     
986   if(SO->FindAttribute(SObj, "AttributeTextColor"))
987     {
988       SALOMEDS::AttributeTextColor_var TextRef = SALOMEDS::AttributeTextColor::_narrow(SObj);
989       size[0] = 3;
990       hdf_float64 data[3];
991       SALOMEDS::Color C = TextRef->TextColor();
992       data[0] = C.R;
993       data[1] = C.G;
994       data[2] = C.B;
995       hdf_dataset = new HDFdataset("AttributeTextColor",hdf_group_sobject,HDF_FLOAT64,size,1);
996       hdf_dataset->CreateOnDisk();
997       hdf_dataset->WriteOnDisk(data);
998       MESSAGE("attribute  AttributeTextColor wrote on file");
999       hdf_dataset->CloseOnDisk();
1000       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1001     }     
1002     if(SO->FindAttribute(SObj, "AttributeTextHighlightColor"))
1003     {
1004       SALOMEDS::AttributeTextHighlightColor_var TextRef = SALOMEDS::AttributeTextHighlightColor::_narrow(SObj);
1005       size[0] = 3;
1006       hdf_float64 data[3];
1007       SALOMEDS::Color C = TextRef->TextHighlightColor();
1008       data[0] = C.R;
1009       data[1] = C.G;
1010       data[2] = C.B;
1011       hdf_dataset = new HDFdataset("AttributeTextHighlightColor",hdf_group_sobject,HDF_FLOAT64,size,1);
1012       hdf_dataset->CreateOnDisk();
1013       hdf_dataset->WriteOnDisk(data);
1014       MESSAGE("attribute  AttributeTextHighlightColor wrote on file");
1015       hdf_dataset->CloseOnDisk();
1016       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1017     }     
1018   if(SO->FindAttribute(SObj, "AttributePixMap"))
1019     {
1020       SALOMEDS::AttributePixMap_var PMRef = SALOMEDS::AttributePixMap::_narrow(SObj);
1021       if (PMRef->HasPixMap()) {
1022         CORBA::String_var Val = PMRef->GetPixMap();
1023         name_len = (hdf_int32) strlen(Val);
1024         size[0] = name_len +1 ; 
1025         hdf_dataset = new HDFdataset("AttributePixMap",hdf_group_sobject,HDF_STRING,size,1);
1026         hdf_dataset->CreateOnDisk();
1027         hdf_dataset->WriteOnDisk(Val);
1028           MESSAGE("attribute PixMap " <<  Val << " wrote on file");
1029         hdf_dataset->CloseOnDisk();
1030         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1031       }
1032     }
1033   if(SO->FindAttribute(SObj, "AttributeLocalID"))
1034     {
1035       char IntVal[25];
1036       SALOMEDS::AttributeLocalID_var LIDRef = SALOMEDS::AttributeLocalID::_narrow(SObj);
1037       sprintf(IntVal, "%d", LIDRef->Value());
1038       name_len = (hdf_int32) strlen(IntVal);
1039       size[0] = name_len +1 ; 
1040       hdf_dataset = new HDFdataset("AttributeLocalID",hdf_group_sobject,HDF_STRING,size,1);
1041       hdf_dataset->CreateOnDisk();
1042       hdf_dataset->WriteOnDisk(IntVal);
1043       hdf_dataset->CloseOnDisk();
1044       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1045       MESSAGE("attribute  AttributeLocalID wrote on file");
1046     }     
1047   if(SO->FindAttribute(SObj, "AttributeTableOfInteger"))
1048     {
1049       SALOMEDS::AttributeTableOfInteger_var IntTab = SALOMEDS::AttributeTableOfInteger::_narrow(SObj);
1050       SALOMEDS::TMPFile_var aStream = IntTab->SaveToFile();
1051       
1052       hdf_size aHDFSize[1];
1053       aHDFSize[0] = aStream->length();
1054       
1055       HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfInteger",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
1056       hdf_dataset->CreateOnDisk();
1057       hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1058       hdf_dataset->CloseOnDisk();
1059       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1060       
1061       MESSAGE("attribute  AttributeTableOfInteger wrote on file");
1062     }
1063   if(SO->FindAttribute(SObj, "AttributeTableOfReal"))
1064     {
1065       SALOMEDS::AttributeTableOfReal_var RealTab = SALOMEDS::AttributeTableOfReal::_narrow(SObj);
1066       SALOMEDS::TMPFile_var aStream = RealTab->SaveToFile();
1067       
1068       hdf_size aHDFSize[1];
1069       aHDFSize[0] = aStream->length();
1070       
1071       HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfReal",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
1072       hdf_dataset->CreateOnDisk();
1073       hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1074       hdf_dataset->CloseOnDisk();
1075       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1076
1077       MESSAGE("attribute  AttributeTableOfReal wrote on file")
1078     }
1079   if(SO->FindAttribute(SObj, "AttributeTableOfString"))
1080     {
1081       SALOMEDS::AttributeTableOfString_var StrTab = SALOMEDS::AttributeTableOfString::_narrow(SObj);
1082       SALOMEDS::TMPFile_var aStream = StrTab->SaveToFile();
1083       
1084       hdf_size aHDFSize[1];
1085       aHDFSize[0] = aStream->length();
1086       
1087       HDFdataset *hdf_dataset = new HDFdataset("AttributeTableOfString",hdf_group_sobject, HDF_STRING, aHDFSize, 1);
1088       hdf_dataset->CreateOnDisk();
1089       hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1090       hdf_dataset->CloseOnDisk();
1091       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1092
1093       MESSAGE("attribute  AttributeTableOfString wrote on file")
1094     }
1095   if(SO->FindAttribute(SObj, "AttributePythonObject"))
1096     {
1097       SALOMEDS::AttributePythonObject_var anObj = SALOMEDS::AttributePythonObject::_narrow(SObj);
1098       char* aSeq = CORBA::string_dup(anObj->GetObject());
1099       int aLen = strlen(aSeq);
1100       char* aString = new char[aLen+2];
1101       aString[0] = anObj->IsScript()?'s':'n';
1102       for(int i = 0; i < aLen; i++) aString[i+1] = aSeq[i];
1103       aString[aLen+1] = 0;
1104       size[0] = aLen+2 ; 
1105       hdf_dataset = new HDFdataset("AttributePythonObject",hdf_group_sobject,HDF_STRING,size,1);
1106       hdf_dataset->CreateOnDisk();
1107       hdf_dataset->WriteOnDisk(aString);
1108       hdf_dataset->CloseOnDisk();
1109       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1110       MESSAGE("attribute  AttributePythonObject wrote on file");
1111     }     
1112
1113 // Reference
1114   SALOMEDS::SObject_var RefSO;
1115   if(SO->ReferencedObject(RefSO))
1116     {
1117       CORBA::String_var attribute_reference = strdup(RefSO->GetID());
1118       name_len = (hdf_int32) strlen(attribute_reference);
1119       size[0] = name_len +1 ; 
1120       hdf_dataset = new HDFdataset("Reference",hdf_group_sobject,HDF_STRING,size,1);
1121       hdf_dataset->CreateOnDisk();
1122       hdf_dataset->WriteOnDisk(attribute_reference);
1123       MESSAGE("attribute reference " <<  attribute_reference << " wrote on file");
1124       hdf_dataset->CloseOnDisk();
1125       hdf_dataset =0; // will be deleted by father hdf object destructor
1126     }
1127
1128 // TreeNodeAttributes with not constant GUID
1129   SALOMEDS::ListOfAttributes_var anAttrList = SO->GetAllAttributes();
1130   int anIndex, aLength = anAttrList->length();
1131   for(anIndex = 0; anIndex<aLength; anIndex++) {
1132     SALOMEDS::AttributeUserID_var UAttr = SALOMEDS::AttributeUserID::_narrow(anAttrList[anIndex]);
1133     if (!UAttr->_is_nil()) {
1134       char* Val = UAttr->Value();
1135       name_len = (hdf_int32) strlen(Val);
1136       size[0] = name_len + 1;
1137       char* aDataSetName = new char[60];
1138       sprintf(aDataSetName, "AttributeUserID_%s",Val);
1139       hdf_dataset = new HDFdataset(aDataSetName,hdf_group_sobject,HDF_STRING,size,1);
1140       hdf_dataset->CreateOnDisk();
1141       hdf_dataset->WriteOnDisk(Val);
1142       MESSAGE("attribute UesrID " <<  Val << " wrote on file");
1143       hdf_dataset->CloseOnDisk();
1144       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1145       delete(aDataSetName);
1146       continue;
1147     }
1148
1149     SALOMEDS::AttributeTreeNode_var TNRef = SALOMEDS::AttributeTreeNode::_narrow(anAttrList[anIndex]);
1150     if (!TNRef->_is_nil()) {
1151       hdf_size TNsize[2];
1152       int maxSize,index;
1153       CORBA::String_var Val[5];
1154       
1155       if (TNRef->HasFather()) Val[0] = TNRef->GetFather()->Label(); else Val[0] = "\0";
1156       maxSize = strlen(Val[0]);
1157       if (TNRef->HasPrevious()) Val[1] = TNRef->GetPrevious()->Label(); else Val[1] = "\0";
1158       maxSize = Max(maxSize,strlen(Val[1]));
1159       if (TNRef->HasNext()) Val[2] = TNRef->GetNext()->Label(); else Val[2] = "\0";
1160       maxSize = Max(maxSize,strlen(Val[2]));
1161       if (TNRef->HasFirst()) Val[3] = TNRef->GetFirst()->Label(); else Val[3] = "\0";
1162       maxSize = Max(maxSize,strlen(Val[3]));
1163       Val[4] = TNRef->GetTreeID();
1164       maxSize = Max(maxSize,strlen(Val[4]));
1165       
1166       TNsize[0]=5;
1167       TNsize[1]=maxSize+1;
1168       char Data[5][maxSize+1];
1169       for(index=0;index<5;index++) {
1170         strcpy(Data[index],Val[index]);
1171         for(int a = strlen(Data[index]) + 1; a < maxSize; a++) Data[index][a] = ' '; // mpv: for ASCII format
1172       }
1173       
1174       char* aDataSetName = new char[60];
1175       sprintf(aDataSetName, "AttributeTreeNodeGUID%s",TNRef->GetTreeID());
1176       hdf_dataset = new HDFdataset(aDataSetName,hdf_group_sobject,HDF_STRING,TNsize,2);
1177       hdf_dataset->CreateOnDisk();
1178       hdf_dataset->WriteOnDisk(Data);
1179       hdf_dataset->CloseOnDisk();
1180       hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1181       MESSAGE("attribute AttributeTreeNode with various GUID wrote on file:");
1182       MESSAGE(aDataSetName);
1183       delete(aDataSetName);
1184     }
1185   }
1186 }
1187
1188 //=============================================================================
1189 /*! Function : _SaveProperties
1190  *  Purpose  : save the study properties in HDF file
1191  */
1192 //============================================================================
1193 void SALOMEDS_StudyManager_i::_SaveProperties(SALOMEDS::Study_ptr aStudy, HDFgroup *hdf_group) {
1194   HDFdataset *hdf_dataset = 0;
1195   hdf_size size[1];
1196   hdf_int32 name_len;
1197
1198   // add modifications list (user and date of save)
1199   SALOMEDS::AttributeStudyProperties_ptr aProp = aStudy->GetProperties();
1200   SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
1201 //    SB->NewCommand();
1202   int aLocked = aProp->IsLocked();
1203   if (aLocked) aProp->SetLocked(Standard_False);
1204   OSD_Process aProcess;
1205   Quantity_Date aDate = aProcess.SystemDate();
1206   aProp->SetModification(aProcess.UserName().ToCString(),
1207                          CORBA::Long(aDate.Minute()), CORBA::Long(aDate.Hour()), CORBA::Long(aDate.Day()),
1208                          CORBA::Long(aDate.Month()), CORBA::Long(aDate.Year()));
1209   if (aLocked) aProp->SetLocked(Standard_True);
1210 //    SB->CommitCommand();
1211   
1212
1213   SALOMEDS::StringSeq_var aNames;
1214   SALOMEDS::LongSeq_var aMinutes, aHours, aDays, aMonths, aYears;
1215   aProp->GetModificationsList(aNames , aMinutes ,aHours, aDays, aMonths, aYears, true);
1216   int aLength, anIndex;
1217   for(aLength = 0, anIndex = aNames->length() - 1; anIndex >= 0; anIndex--) aLength += strlen(aNames[anIndex]) + 1;
1218
1219   // string length: 1 byte = locked flag, 1 byte = modified flag, (12 + name length + 1) for each name and date, "zero" byte
1220   char* aProperty = new char[3 + aLength + 12 * aNames->length()];
1221
1222   sprintf(aProperty,"%c%c",
1223           (strlen(aProp->GetCreationMode()) != 0)?aProp->GetCreationMode()[0]:'0',
1224           (aProp->IsLocked())?'l':'u');
1225
1226   aLength = aNames->length();
1227   int a = 2;
1228   for(anIndex = 0; anIndex  < aLength; anIndex++) {
1229     sprintf(&(aProperty[a]),"%2d%2d%2d%2d%4d%s",
1230             (int)(aMinutes[anIndex]),
1231             (int)(aHours[anIndex]),
1232             (int)(aDays[anIndex]),
1233             (int)(aMonths[anIndex]),
1234             (int)(aYears[anIndex]),
1235             (char*)aNames[anIndex]);
1236     a = strlen(aProperty);
1237     aProperty[a++] = 1;
1238   }
1239   aProperty[a] = 0;
1240
1241   name_len = (hdf_int32) a;
1242 //    MESSAGE("*** Property: "<<aProperty);
1243   size[0] = name_len + 1 ; 
1244   hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1);
1245   hdf_dataset->CreateOnDisk();
1246   hdf_dataset->WriteOnDisk(aProperty);
1247   MESSAGE("attribute StudyProperties " <<  aProperty << " wrote on file");
1248   hdf_dataset->CloseOnDisk();
1249   hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1250   delete(aProperty);
1251   aProp->SetModified(0);
1252 }
1253
1254 //=============================================================================
1255 /*! Function : _SaveAs
1256  *  Purpose  : save the study in HDF file
1257  */
1258 //============================================================================
1259 void SALOMEDS_StudyManager_i::_SaveAs(const char* aUrl, 
1260                                       SALOMEDS::Study_ptr aStudy,
1261                                       CORBA::Boolean theMultiFile,
1262                                       CORBA::Boolean theASCII)
1263 {
1264   // HDF File will be composed of differents part :
1265   // * For each ComponentDataType, all data created by the component
1266   //   Informations in data group hdf_group_datacomponent
1267   // * Study Structure -> Exactly what is contained in OCAF document
1268   //   Informations in data group hdf_group_study_structure
1269
1270   HDFfile *hdf_file=0;         
1271   HDFgroup *hdf_group_study_structure =0;
1272   HDFgroup *hdf_sco_group =0;
1273   HDFgroup *hdf_sco_group2 =0;
1274
1275   HDFgroup *hdf_group_datacomponent =0;
1276   HDFdataset *hdf_dataset =0;
1277   HDFattribute *hdf_attribute=0;
1278   hdf_size size[1];
1279   hdf_int32 name_len = 0;
1280   char *component_name = 0;
1281   char *attribute_name = 0;
1282   char *attribute_comment = 0;
1283   char *attribute_persistentref = 0;
1284
1285   int aLocked = aStudy->GetProperties()->IsLocked();
1286   if (aLocked) aStudy->GetProperties()->SetLocked(false);
1287
1288   SALOMEDS::StudyBuilder_var SB= aStudy->NewBuilder();
1289
1290   ASSERT(!CORBA::is_nil(aStudy));
1291   try
1292     {
1293       // mpv 15.12.2003: for saving components we have to load all data from all modules
1294
1295       SALOMEDS::SComponentIterator_var itcomponent1 = aStudy->NewComponentIterator();
1296       for (; itcomponent1->More(); itcomponent1->Next())
1297         {
1298           SALOMEDS::SComponent_var sco = itcomponent1->Value();
1299           // if there is an associated Engine call its method for saving
1300           CORBA::String_var IOREngine;
1301           try {
1302             
1303             if (!sco->ComponentIOR(IOREngine)) {
1304               SALOMEDS::GenericAttribute_var aGeneric;
1305               SALOMEDS::AttributeName_var aName;
1306               if(sco->FindAttribute(aGeneric, "AttributeName"))
1307                 aName = SALOMEDS::AttributeName::_narrow(aGeneric);
1308
1309               if (!aName->_is_nil()) {
1310                 
1311                 CORBA::String_var aCompType = aName->Value();
1312
1313                 
1314                 CORBA::String_var aFactoryType;
1315                 if (strcmp(aCompType, "SUPERV") == 0) aFactoryType = "SuperVisionContainer";
1316                 else aFactoryType = "FactoryServer";
1317                 
1318                 Engines::Component_var aComp =
1319                   SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component(aFactoryType, aCompType);
1320                 
1321                 if (aComp->_is_nil()) {
1322                   Engines::Component_var aComp =
1323                     SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServerPy", aCompType);
1324                 }
1325                 
1326                 if (!aComp->_is_nil()) {
1327                   SALOMEDS::Driver_var aDriver = SALOMEDS::Driver::_narrow(aComp);
1328                   if (!CORBA::is_nil(aDriver)) {
1329                     SB->LoadWith(sco, aDriver);
1330                   }
1331                 }
1332               }
1333             }
1334           } catch(...) {
1335             MESSAGE("Can not restore information to resave it");
1336             return;
1337           }
1338         }
1339
1340
1341
1342       CORBA::String_var anOldName = aStudy->Name();
1343       aStudy->URL(aUrl);
1344
1345       // To change for Save 
1346       // Do not have to do a new file but just a Open??? Rewrite all informations after erasing evrything??
1347       hdf_file = new HDFfile((char *)aUrl);
1348       hdf_file->CreateOnDisk();
1349       MESSAGE("File " << aUrl << " created");
1350
1351       //-----------------------------------------------------------------------
1352       // 1 - Create a groupe for each SComponent and Update the PersistanceRef
1353       //-----------------------------------------------------------------------
1354       hdf_group_datacomponent = new HDFgroup("DATACOMPONENT",hdf_file);
1355       hdf_group_datacomponent->CreateOnDisk();
1356
1357       SALOMEDS::SComponentIterator_var itcomponent = aStudy->NewComponentIterator();
1358       
1359       //SRN: Added 17 Nov, 2003
1360       SALOMEDS::SObject_var anAutoSaveSO = aStudy->FindObjectID(AUTO_SAVE_TAG);
1361       //SRN: End
1362
1363       for (; itcomponent->More(); itcomponent->Next())
1364         {
1365           SALOMEDS::SComponent_var sco = itcomponent->Value();
1366           
1367           CORBA::String_var scoid = sco->GetID();
1368           hdf_sco_group = new HDFgroup(scoid,hdf_group_datacomponent);
1369           hdf_sco_group->CreateOnDisk();
1370
1371           CORBA::String_var componentDataType = sco->ComponentDataType();
1372           MESSAGE ( "Look for  an engine for data type :"<< componentDataType);
1373
1374           //SRN: Added 17 Nov 2003: If there is a specified attribute, the component peforms a special save       
1375           if(!CORBA::is_nil(anAutoSaveSO) && SB->IsGUID(sco, AUTO_SAVE_GUID)) {     
1376        
1377             SALOMEDS::GenericAttribute_var aGeneric;
1378             SALOMEDS::AttributeTableOfString_var aTable;
1379             if(anAutoSaveSO->FindAttribute(aGeneric, "AttributeTableOfString")) {
1380               aTable = SALOMEDS::AttributeTableOfString::_narrow(aGeneric);
1381               Standard_Integer nbRows = aTable->GetNbRows(), k, aTimeOut = 0;
1382               if(nbRows > 0 && aTable->GetNbColumns() > 1) {    
1383
1384                 SALOMEDS::StringSeq_var aRow;
1385                 for(k=1; k<=nbRows; k++) {
1386                   aRow = aTable->GetRow(k);
1387                   if (strcmp(aRow[0], componentDataType) == 0) {
1388                     CORBA::String_var anEntry = CORBA::string_dup(aRow[1]);
1389                     SALOMEDS::SObject_var aCompSpecificSO = aStudy->FindObjectID(anEntry);
1390                     if(!CORBA::is_nil(aCompSpecificSO)) {
1391                       SALOMEDS::AttributeInteger_var anInteger;
1392                       if(aCompSpecificSO->FindAttribute(aGeneric, "AttributeInteger")) {
1393                         anInteger = SALOMEDS::AttributeInteger::_narrow(aGeneric);
1394                         anInteger->SetValue(-1);
1395                         while(anInteger->Value() < 0) { sleep(2); if(++aTimeOut > AUTO_SAVE_TIME_OUT_IN_SECONDS) break; }
1396                       }  // if(aCompSpecificSO->FindAttribute(anInteger, "AttributeInteger"))
1397                     }  // if(!CORBA::is_nil(aCompSpecificSO)) 
1398                   }  // if (strcmp(aRow[0], componentDataType) == 0)
1399                 }  // for
1400
1401               }  // if(nbRows > 0 && aTable->GetNbColumns() > 1)
1402
1403             }  // if(anAutoSaveSO->FindAttribute(aTable, "AttributeTableOfString")
1404
1405           }  // if(SB->IsGUID(AUTO_SAVE_GUID)
1406
1407           //SRN: End
1408
1409           CORBA::String_var IOREngine;
1410           if (sco->ComponentIOR(IOREngine))
1411             {
1412               // we have found the associated engine to write the data 
1413               MESSAGE ( "We have found an engine for data type :"<< componentDataType);
1414               CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1415               SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1416               
1417               if (!CORBA::is_nil(Engine))
1418                 {
1419                   MESSAGE ( "Save the data of type:"<< componentDataType);
1420                   MESSAGE("Engine :"<<Engine->ComponentDataType());
1421
1422                   SALOMEDS::TMPFile_var aStream;
1423
1424                   if (theASCII) aStream = Engine->SaveASCII(sco,SALOMEDS_Tool::GetDirFromPath(aUrl),theMultiFile);
1425                   else aStream = Engine->Save(sco,SALOMEDS_Tool::GetDirFromPath(aUrl),theMultiFile);
1426
1427                   HDFdataset *hdf_dataset;
1428                   hdf_size aHDFSize[1];
1429                   if(aStream->length() > 0) {  //The component saved some auxiliary files, then put them into HDF file 
1430
1431                     aHDFSize[0] = aStream->length();
1432                       
1433                     HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
1434                     hdf_dataset->CreateOnDisk();
1435                     hdf_dataset->WriteOnDisk((unsigned char*) &aStream[0]);  //Save the stream in the HDF file
1436                     hdf_dataset->CloseOnDisk();
1437                   }
1438                   // store multifile state
1439                   aHDFSize[0] = 2;
1440                   hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
1441                   hdf_dataset->CreateOnDisk();
1442                   hdf_dataset->WriteOnDisk((void*)(theMultiFile?"M":"S")); // save: multi or single
1443                   hdf_dataset->CloseOnDisk();
1444                   hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor                
1445
1446                   // store ASCII state
1447                   aHDFSize[0] = 2;
1448                   hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
1449                   hdf_dataset->CreateOnDisk();
1450                   hdf_dataset->WriteOnDisk((void*)(theASCII?"A":"B")); // save: ASCII or BINARY
1451                   hdf_dataset->CloseOnDisk();
1452                   hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor                
1453
1454                   Translate_IOR_to_persistentID (aStudy,SB,sco,Engine,theMultiFile, theASCII);
1455                   MESSAGE("After Translate_IOR_to_persistentID");
1456                   
1457                   // Creation of the persistance reference  attribute
1458                 }
1459             }
1460           hdf_sco_group->CloseOnDisk();
1461           hdf_sco_group=0; // will be deleted by hdf_group_datacomponent destructor
1462         }
1463       hdf_group_datacomponent->CloseOnDisk();
1464       hdf_group_datacomponent =0;  // will be deleted by hdf_file destructor
1465
1466
1467       //-----------------------------------------------------------------------
1468       //3 - Write the Study Structure
1469       //-----------------------------------------------------------------------
1470       hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
1471       hdf_group_study_structure->CreateOnDisk();
1472
1473       // save component attributes
1474       SALOMEDS::SComponentIterator_var itcomp = aStudy->NewComponentIterator();
1475       for (; itcomp->More(); itcomp->Next()) 
1476         {
1477           SALOMEDS::SComponent_var SC = itcomp->Value();
1478           
1479           CORBA::String_var scid = SC->GetID();
1480           hdf_sco_group2 = new HDFgroup(scid,hdf_group_study_structure);
1481           hdf_sco_group2->CreateOnDisk();
1482           SaveAttributes(SC, hdf_sco_group2);
1483           // ComponentDataType treatment
1484           component_name = SC->ComponentDataType();
1485           MESSAGE("Component data type " << component_name << " treated");
1486           
1487           name_len = (hdf_int32) strlen(component_name);
1488           size[0] = name_len +1 ; 
1489           hdf_dataset = new HDFdataset("COMPONENTDATATYPE",hdf_sco_group2,HDF_STRING,size,1);
1490           hdf_dataset->CreateOnDisk();
1491           hdf_dataset->WriteOnDisk(component_name);
1492           MESSAGE("component name " <<  component_name << " wrote on file");
1493           hdf_dataset->CloseOnDisk();
1494           hdf_dataset=0; //will be deleted by hdf_sco_group destructor
1495           _SaveObject(aStudy, SC, hdf_sco_group2);
1496           hdf_sco_group2->CloseOnDisk();
1497           hdf_sco_group2=0; // will be deleted by hdf_group_study_structure destructor
1498           CORBA::string_free(component_name);       
1499         }
1500       //-----------------------------------------------------------------------
1501       //4 - Write the Study UseCases Structure
1502       //-----------------------------------------------------------------------
1503       SALOMEDS::SObject_var aSO = aStudy->FindObjectID(USE_CASE_LABEL_ID);
1504       if (!aSO->_is_nil()) {
1505         HDFgroup *hdf_soo_group = new HDFgroup(USE_CASE_LABEL_ID,hdf_group_study_structure);
1506         hdf_soo_group->CreateOnDisk();
1507         SaveAttributes(aSO, hdf_soo_group);
1508         _SaveObject(aStudy, aSO, hdf_soo_group);
1509         MESSAGE("Use cases data structure writed");
1510         hdf_soo_group->CloseOnDisk();
1511         hdf_soo_group=0; // will be deleted by hdf_group_study_structure destructor
1512       }
1513
1514       if (aLocked) aStudy->GetProperties()->SetLocked(true);
1515       //-----------------------------------------------------------------------
1516       //5 - Write the Study Properties
1517       //-----------------------------------------------------------------------
1518       name_len = (hdf_int32) strlen(aStudy->Name());
1519       size[0] = name_len +1 ; 
1520       hdf_dataset = new HDFdataset("STUDY_NAME",hdf_group_study_structure,HDF_STRING,size,1);
1521       hdf_dataset->CreateOnDisk();
1522       CORBA::String_var studid = aStudy->Name();
1523       hdf_dataset->WriteOnDisk(studid);
1524       MESSAGE("study name " << studid << " wrote on file");
1525       hdf_dataset->CloseOnDisk();
1526       hdf_dataset=0; // will be deleted by hdf_group_study_structure destructor
1527
1528       _SaveProperties(aStudy, hdf_group_study_structure);
1529
1530       hdf_group_study_structure->CloseOnDisk();
1531       hdf_file->CloseOnDisk();
1532
1533       _name_service->Change_Directory("/Study");
1534       _name_service->Destroy_Name(anOldName);
1535       _name_service->Register(aStudy, aStudy->Name());
1536
1537       aStudy->IsSaved(true);
1538       hdf_group_study_structure =0; // will be deleted by hdf_file destructor
1539       delete hdf_file; // recursively deletes all hdf objects...
1540     }
1541   catch (HDFexception)
1542     {
1543       MESSAGE( "HDFexception ! " )
1544     }
1545   if (theASCII) { // save file in ASCII format
1546     HDFascii::ConvertFromHDFToASCII(aUrl, true);
1547   }
1548 }
1549
1550 //============================================================================
1551 /*! Function : _SaveObject
1552  *  Purpose  :
1553  */
1554 //============================================================================
1555 void SALOMEDS_StudyManager_i::_SaveObject(SALOMEDS::Study_ptr aStudy, 
1556                                           SALOMEDS::SObject_ptr SC, 
1557                                           HDFgroup *hdf_group_datatype)
1558 {
1559   // Write in group hdf_group_datatype all informations of SObject SC
1560   // Iterative function to parse all SObjects under a SComponent
1561   SALOMEDS::SObject_var RefSO;
1562   HDFgroup *hdf_group_sobject = 0;
1563   HDFdataset *hdf_dataset = 0;
1564   hdf_size size[1];
1565   hdf_int32 name_len = 0;
1566
1567   SALOMEDS::ChildIterator_var itchild = aStudy->NewChildIterator(SC);
1568   for (; itchild->More(); itchild->Next()) 
1569     {
1570       SALOMEDS::SObject_var SO = itchild->Value();
1571
1572       // mpv: don't save empty labels
1573       if (SO->GetAllAttributes()->length() == 0) {
1574         SALOMEDS::ChildIterator_var subchild = aStudy->NewChildIterator(SC);
1575         if (!subchild->More()) {
1576           continue;
1577         }
1578         subchild->InitEx(true);
1579         bool anEmpty = true;
1580         for (; subchild->More() && anEmpty; subchild->Next()) 
1581           if (subchild->Value()->GetAllAttributes()->length() != 0) anEmpty = false;
1582         if (anEmpty) {
1583           continue;
1584         }
1585       }
1586
1587       CORBA::String_var scoid = strdup(SO->GetID());
1588       hdf_group_sobject = new HDFgroup(scoid,hdf_group_datatype);
1589       hdf_group_sobject->CreateOnDisk();
1590       SaveAttributes(SO, hdf_group_sobject);
1591       _SaveObject(aStudy,SO, hdf_group_sobject);
1592       hdf_group_sobject->CloseOnDisk();
1593       hdf_group_sobject =0; // will be deleted by father hdf object destructor
1594
1595     }
1596 }
1597
1598 //============================================================================
1599 /*! Function : _SubstituteSlash
1600  *  Purpose  :
1601  */
1602 //============================================================================
1603
1604 const char *SALOMEDS_StudyManager_i::_SubstituteSlash(const char *aUrl)
1605 {
1606   ASSERT(1==0);
1607   TCollection_ExtendedString theUrl(CORBA::string_dup(aUrl));
1608   Standard_ExtCharacter val1 = ToExtCharacter('/');
1609   Standard_ExtCharacter val2 = ToExtCharacter(':');
1610   theUrl.ChangeAll(val1,val2);
1611   TCollection_AsciiString ch(theUrl);
1612   return strdup(ch.ToCString());
1613 }
1614
1615 //============================================================================
1616 /*! Function : CanCopy
1617  *  Purpose  : 
1618  */
1619 //============================================================================
1620 CORBA::Boolean SALOMEDS_StudyManager_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
1621   SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1622   if (aComponent->_is_nil()) return false;
1623   if (aComponent == theObject) return false;
1624
1625   CORBA::String_var IOREngine;
1626   if (!aComponent->ComponentIOR(IOREngine)) return false;
1627
1628   CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1629   SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1630   if (CORBA::is_nil(Engine)) return false;
1631   Standard_Boolean a = Engine->CanCopy(theObject);
1632   return a;
1633 }
1634
1635 //============================================================================
1636 /*! Function : GetDocumentOfStudy
1637  *  Purpose  : 
1638  */
1639 //============================================================================
1640 Handle(TDocStd_Document) SALOMEDS_StudyManager_i::GetDocumentOfStudy(SALOMEDS::Study_ptr theStudy) {
1641   int a;
1642   int aNbDocs = _OCAFApp->NbDocuments(); 
1643   Handle(TDocStd_Document) aDocument;  
1644   for(a = 1; a <= aNbDocs ; a++) {
1645     _OCAFApp->GetDocument(a, aDocument);
1646     if (!aDocument.IsNull()) {
1647       SALOMEDS_SObject_i *  aSOServant = new SALOMEDS_SObject_i (aDocument->Main(),_orb);
1648       SALOMEDS::SObject_var aSO = SALOMEDS::SObject::_narrow(aSOServant->_this()); 
1649       SALOMEDS::Study_var aStudy = aSO->GetStudy();
1650       if(CORBA::is_nil(aStudy)) continue;  //The clipboard document ( hopefully :) )
1651       if (aStudy->StudyId() == theStudy->StudyId()) break;
1652       aDocument.Nullify();
1653     }
1654   }
1655
1656   return aDocument;
1657 }
1658
1659 //============================================================================
1660 /*! Function : CopyLabel
1661  *  Purpose  : 
1662  */
1663 //============================================================================
1664 void SALOMEDS_StudyManager_i::CopyLabel(const SALOMEDS::Study_ptr theSourceStudy,
1665                                         const SALOMEDS::Driver_ptr theEngine,
1666                                         const Standard_Integer theSourceStartDepth,
1667                                         const TDF_Label& theSource,
1668                                         const TDF_Label& theDestinationMain) {
1669   int a;
1670   TDF_Label aTargetLabel = theDestinationMain;
1671   TDF_Label aAuxTargetLabel = theDestinationMain.Father().FindChild(2);
1672   for(a = theSource.Depth() - theSourceStartDepth; a > 0 ; a--) {
1673     TDF_Label aSourceLabel = theSource;
1674     for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
1675     aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
1676     aAuxTargetLabel = aAuxTargetLabel.FindChild(aSourceLabel.Tag());
1677   }
1678   // iterate attributes
1679   TDF_AttributeIterator anAttrIterator(theSource);
1680   Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable();
1681   for(; anAttrIterator.More(); anAttrIterator.Next()) {
1682     Handle(TDF_Attribute) anAttr = anAttrIterator.Value();
1683     if (!Handle(TDataStd_TreeNode)::DownCast(anAttr).IsNull()) continue; // never copy tree node attribute
1684     if (!Handle(SALOMEDS_TargetAttribute)::DownCast(anAttr).IsNull()) continue; // and target attribute
1685     
1686     if (!Handle(TDF_Reference)::DownCast(anAttr).IsNull()) { // reference copied as Comment in auxiliary tree
1687       TDF_Label aReferenced = Handle(TDF_Reference)::DownCast(anAttr)->Get();
1688       TCollection_AsciiString anEntry;
1689       TDF_Tool::Entry(aReferenced, anEntry);
1690       // store the value of name attribute of referenced label
1691       Handle(TDataStd_Name) aNameAttribute;
1692       if (aReferenced.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) {
1693         anEntry += " ";
1694         anEntry += aNameAttribute->Get();
1695       }
1696       TDataStd_Comment::Set(aAuxTargetLabel, TCollection_ExtendedString(anEntry));
1697       continue;
1698     }
1699     
1700     if (!Handle(SALOMEDS_IORAttribute)::DownCast(anAttr).IsNull()) { // IOR => ID and TMPFile of Engine
1701       TCollection_AsciiString anEntry;
1702       TDF_Tool::Entry(theSource, anEntry);
1703       SALOMEDS::SObject_var aSO = theSourceStudy->FindObjectID(strdup(anEntry.ToCString()));
1704 //        if (theEngine->CanCopy(aSO)) {
1705         CORBA::Long anObjID;
1706 //      TCollection_ExtendedString aResStr(strdup((char*)(theEngine->CopyFrom(aSO, anObjID))));
1707           SALOMEDS::TMPFile_var aStream = theEngine->CopyFrom(aSO, anObjID);
1708           int aLen = aStream->length();
1709           TCollection_ExtendedString aResStr("");
1710           for(a = 0; a < aLen; a++) {
1711             aResStr += TCollection_ExtendedString(ToExtCharacter((Standard_Character)aStream[a]));
1712           }
1713           TDataStd_Integer::Set(aAuxTargetLabel, anObjID);
1714           TDataStd_Name::Set(aAuxTargetLabel, aResStr);
1715 //        }
1716       continue;
1717     }
1718     Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
1719     aTargetLabel.AddAttribute(aNewAttribute);
1720     anAttr->Paste(aNewAttribute, aRT);
1721 //      aRT->SetRelocation(anAttr, aNewAttribute);
1722   }
1723 }
1724
1725 //============================================================================
1726 /*! Function : Copy
1727  *  Purpose  :
1728  */
1729 //============================================================================
1730 CORBA::Boolean SALOMEDS_StudyManager_i::Copy(SALOMEDS::SObject_ptr theObject) {
1731   // adoptation for alliances datamodel copy: without IOR attributes !!!
1732   bool aStructureOnly; // copy only SObjects and attributes without component help
1733   SALOMEDS::GenericAttribute_var anAttribute;
1734   aStructureOnly = !theObject->FindAttribute(anAttribute, "AttributeIOR");
1735
1736   // get component-engine
1737   SALOMEDS::Study_var aStudy = theObject->GetStudy();
1738
1739   SALOMEDS::Driver_var Engine;
1740   if (!aStructureOnly) {
1741     SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1742     CORBA::String_var IOREngine;
1743     if (!aComponent->ComponentIOR(IOREngine)) return false;
1744
1745     CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1746     Engine = SALOMEDS::Driver::_narrow(obj) ;
1747   }
1748   // CAF document of current study usage
1749   Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
1750   if (aDocument.IsNull()) return false;
1751   // create new document for clipboard
1752   Handle(TDocStd_Document) aTargetDocument;
1753   _OCAFApp->NewDocument("SALOME_STUDY", aTargetDocument);
1754   // set component data type to the name attribute of root label
1755   if (!aStructureOnly) {
1756     TDataStd_Comment::Set(aTargetDocument->Main().Root(),
1757                           TCollection_ExtendedString(strdup(Engine->ComponentDataType())));
1758   }
1759   // set to the Root label integer attribute: study id
1760   TDataStd_Integer::Set(aTargetDocument->Main().Root(), aStudy->StudyId());
1761   // iterate all theObject's label children
1762   TDF_Label aStartLabel;
1763   char* aStartID = strdup(theObject->GetID());
1764   TDF_Tool::Label(aDocument->GetData(), aStartID, aStartLabel);
1765   Standard_Integer aSourceStartDepth = aStartLabel.Depth();
1766   
1767   // copy main source label
1768   CopyLabel(aStudy, Engine, aSourceStartDepth, aStartLabel, aTargetDocument->Main());
1769
1770   // copy all subchildren of the main source label (all levels)
1771   TDF_ChildIterator anIterator(aStartLabel, Standard_True);
1772   for(; anIterator.More(); anIterator.Next()) {
1773     CopyLabel(aStudy, Engine, aSourceStartDepth, anIterator.Value(), aTargetDocument->Main());
1774   }
1775   // done: free old clipboard document and 
1776   if (!_clipboard.IsNull()) {
1777 //      Handle(TDocStd_Owner) anOwner;
1778 //      if (_clipboard->Main().Root().FindAttribute(TDocStd_Owner::GetID(), anOwner)) {
1779 //        Handle(TDocStd_Document) anEmptyDoc;
1780 //        anOwner->SetDocument(anEmptyDoc);
1781 //      }
1782     _OCAFApp->Close(_clipboard);
1783   }
1784   _clipboard = aTargetDocument;
1785
1786   return true;
1787 }
1788 //============================================================================
1789 /*! Function : CanPaste
1790  *  Purpose  :
1791  */
1792 //============================================================================
1793 CORBA::Boolean SALOMEDS_StudyManager_i::CanPaste(SALOMEDS::SObject_ptr theObject) {
1794   if (_clipboard.IsNull()) return false;
1795
1796   Handle(TDataStd_Comment) aCompName;
1797   if (!_clipboard->Main().Root().FindAttribute(TDataStd_Comment::GetID(), aCompName)) return false;
1798   Handle(TDataStd_Integer) anObjID;
1799   if (!_clipboard->Main().Father().FindChild(2).FindAttribute(TDataStd_Integer::GetID(), anObjID))
1800     return false;
1801
1802   SALOMEDS::SComponent_var aComponent = theObject->GetFatherComponent();
1803   if (aComponent->_is_nil()) return false;
1804   
1805   CORBA::String_var IOREngine;
1806   if (!aComponent->ComponentIOR(IOREngine)) return false;
1807   
1808   CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1809   SALOMEDS::Driver_var Engine = SALOMEDS::Driver::_narrow(obj) ;
1810   if (CORBA::is_nil(Engine)) return false;
1811   return Engine->CanPaste(strdup(TCollection_AsciiString(aCompName->Get()).ToCString()), anObjID->Get());
1812 }
1813 //============================================================================
1814 /*! Function : PasteLabel
1815  *  Purpose  :
1816  */
1817 //============================================================================
1818 TDF_Label SALOMEDS_StudyManager_i::PasteLabel(const SALOMEDS::Study_ptr theDestinationStudy,
1819                                               const SALOMEDS::Driver_ptr theEngine,
1820                                               const TDF_Label& theSource,
1821                                               const TDF_Label& theDestinationStart,
1822                                               const int theCopiedStudyID,
1823                                               const bool isFirstElement) {
1824
1825   // get corresponding source, target and auxiliary labels
1826   TDF_Label aTargetLabel = theDestinationStart;
1827   TDF_Label aAuxSourceLabel = theSource.Root().FindChild(2);
1828   int a;
1829   if (!isFirstElement) {
1830     for(a = theSource.Depth() - 1; a > 0 ; a--) {
1831       TDF_Label aSourceLabel = theSource;
1832       for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
1833       aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
1834       aAuxSourceLabel = aAuxSourceLabel.FindChild(aSourceLabel.Tag());
1835     }
1836   }
1837
1838   // check auxiliary label for TMPFile => IOR
1839   Handle(TDataStd_Name) aNameAttribute;
1840   if (aAuxSourceLabel.FindAttribute(TDataStd_Name::GetID(), aNameAttribute)) {
1841     Handle(TDataStd_Integer) anObjID;
1842
1843     aAuxSourceLabel.FindAttribute(TDataStd_Integer::GetID(), anObjID);
1844     Handle(TDataStd_Comment) aComponentName;
1845     theSource.Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
1846     CORBA::String_var aCompName = strdup(TCollection_AsciiString(aComponentName->Get()).ToCString());
1847
1848     if (theEngine->CanPaste(aCompName, anObjID->Get())) {
1849       SALOMEDS::TMPFile_var aTMPFil = new SALOMEDS::TMPFile();
1850       TCollection_ExtendedString aTMPStr = aNameAttribute->Get();
1851       int aLen = aTMPStr.Length();
1852       aTMPFil->length(aLen);
1853       for(a = 0; a < aLen; a++) {
1854         aTMPFil[a] = ToCharacter(aTMPStr.Value(a+1));
1855       }
1856 //        char* aTMPStr = strdup(TCollection_AsciiString(aNameAttribute->Get()).ToCString());
1857 //        int aLen = strlen(aTMPStr);
1858 //        SALOMEDS::TMPFile aTMPFil(aLen, aLen, (CORBA::Octet*)aTMPStr, 1);
1859       
1860       TCollection_AsciiString anEntry;
1861       TDF_Tool::Entry(aTargetLabel, anEntry);
1862       SALOMEDS::SObject_var aPastedSO = theDestinationStudy->FindObjectID(strdup(anEntry.ToCString()));
1863       if (isFirstElement) {
1864         SALOMEDS::SObject_var aDestSO =
1865           theEngine->PasteInto(aTMPFil.in(),
1866                                anObjID->Get(),
1867                                aPastedSO->GetFatherComponent());
1868         TDF_Tool::Label(theDestinationStart.Data(), aDestSO->GetID(), aTargetLabel);
1869       } else theEngine->PasteInto(aTMPFil.in(),anObjID->Get(),aPastedSO);
1870     }
1871   }
1872
1873   // iterate attributes
1874   TDF_AttributeIterator anAttrIterator(theSource);
1875   Handle(TDF_RelocationTable) aRT = new TDF_RelocationTable();
1876   for(; anAttrIterator.More(); anAttrIterator.Next()) {
1877     Handle(TDF_Attribute) anAttr = anAttrIterator.Value();
1878     if (aTargetLabel.FindAttribute(anAttr->ID(), anAttr)) {
1879       aTargetLabel.ForgetAttribute(anAttr->ID());
1880       anAttr = anAttrIterator.Value();
1881     }
1882     Handle(TDF_Attribute) aNewAttribute = anAttr->NewEmpty();
1883     aTargetLabel.AddAttribute(aNewAttribute);
1884     anAttr->Paste(aNewAttribute, aRT);
1885 //      aRT->SetRelocation(anAttr, aNewAttribute);
1886   }
1887   // check auxiliary label for Comment => reference or name attribute of the referenced object
1888   Handle(TDataStd_Comment) aCommentAttribute;
1889   if (aAuxSourceLabel.FindAttribute(TDataStd_Comment::GetID(), aCommentAttribute)) {
1890     char * anEntry = new char[aCommentAttribute->Get().Length() + 1];
1891     strcpy(anEntry, TCollection_AsciiString(aCommentAttribute->Get()).ToCString());
1892     char* aNameStart = strchr(anEntry, ' ');
1893     if (aNameStart) {
1894       *aNameStart = '\0';
1895       aNameStart++;
1896     }
1897     if (theCopiedStudyID == theDestinationStudy->StudyId()) { // if copy to the same study, reanimate reference
1898       TDF_Label aRefLabel;
1899       TDF_Tool::Label(aTargetLabel.Data(), anEntry, aRefLabel);
1900       TDF_Reference::Set(aTargetLabel, aRefLabel);
1901       SALOMEDS_TargetAttribute::Set(aRefLabel)->Append(aTargetLabel); // target attributes structure support
1902     } else {
1903       if (aNameStart) TDataStd_Name::Set(aTargetLabel, aNameStart);
1904       else TDataStd_Name::Set(aTargetLabel, TCollection_ExtendedString("Reference to:")+anEntry);
1905     }
1906     delete(anEntry);
1907   }
1908
1909   return aTargetLabel;
1910 }
1911 //============================================================================
1912 /*! Function : Paste
1913  *  Purpose  :
1914  */
1915 //============================================================================
1916 SALOMEDS::SObject_ptr SALOMEDS_StudyManager_i::Paste(SALOMEDS::SObject_ptr theObject)
1917      throw(SALOMEDS::StudyBuilder::LockProtection)
1918 {
1919   SALOMEDS::Study_var aStudy = theObject->GetStudy();
1920
1921   // if study is locked, then paste can't be done
1922   if (aStudy->GetProperties()->IsLocked())
1923     throw SALOMEDS::StudyBuilder::LockProtection();
1924
1925   // if there is no component name, then paste only SObjects and attributes: without component help
1926   Handle(TDataStd_Comment) aComponentName;
1927   bool aStructureOnly = !_clipboard->Main().Root().FindAttribute(TDataStd_Comment::GetID(), aComponentName);
1928
1929   // get copied study ID
1930   Handle(TDataStd_Integer) aStudyIDAttribute;
1931   if (!_clipboard->Main().Root().FindAttribute(TDataStd_Integer::GetID(), aStudyIDAttribute))
1932     return SALOMEDS::SObject::_nil();
1933   int aCStudyID = aStudyIDAttribute->Get();
1934
1935   // get component-engine
1936   SALOMEDS::Driver_var Engine;
1937   SALOMEDS::SComponent_var aComponent;
1938   if (!aStructureOnly) {
1939     aComponent = theObject->GetFatherComponent();
1940     CORBA::String_var IOREngine;
1941     if (!aComponent->ComponentIOR(IOREngine)) return SALOMEDS::SObject::_nil();
1942     CORBA::Object_var obj = _orb->string_to_object(IOREngine);
1943     Engine = SALOMEDS::Driver::_narrow(obj) ;
1944   }
1945
1946   // CAF document of current study usage
1947   Handle(TDocStd_Document) aDocument = GetDocumentOfStudy(aStudy);
1948   if (aDocument.IsNull()) return SALOMEDS::SObject::_nil();
1949   // fill root inserted SObject
1950   TDF_Label aStartLabel;
1951   if (aStructureOnly) {
1952     TDF_Label anObjectLabel;
1953     TDF_Tool::Label(aDocument->GetData(), theObject->GetID(), anObjectLabel);
1954     aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), anObjectLabel, aCStudyID, false);
1955   } else {
1956     TDF_Label aComponentLabel;
1957     TDF_Tool::Label(aDocument->GetData(), aComponent->GetID(), aComponentLabel);
1958     aStartLabel = PasteLabel(aStudy, Engine, _clipboard->Main(), aComponentLabel, aCStudyID, true);
1959   }
1960
1961   // paste all sublebels
1962   TDF_ChildIterator anIterator(_clipboard->Main(), Standard_True);
1963   for(; anIterator.More(); anIterator.Next()) {
1964     PasteLabel(aStudy, Engine, anIterator.Value(), aStartLabel, aCStudyID, false);
1965   }
1966
1967   SALOMEDS_SObject_i *  so_servant = new SALOMEDS_SObject_i (aStartLabel, _orb);
1968   SALOMEDS::SObject_var so = SALOMEDS::SObject::_narrow(so_servant->_this()); 
1969
1970   return so._retn();
1971 }