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