Back to index

salome-kernel  6.5.0
SALOMEDSImpl_StudyManager.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  File   : SALOMEDSImpl_StudyManager.cxx
00024 //  Author : Sergey RUIN
00025 //  Module : SALOME
00026 //
00027 #include "SALOMEDSImpl_StudyManager.hxx"
00028 
00029 #include "DF_ChildIterator.hxx"
00030 #include "HDFexplorer.hxx"
00031 #include "Basics_Utils.hxx"
00032 
00033 //Warning undef of Ascii Winwows define
00034 #ifdef WIN32
00035 # undef GetUserName
00036 #endif
00037 
00038 #include "SALOMEDSImpl_Attributes.hxx"
00039 #include "SALOMEDSImpl_Tool.hxx"
00040 #include "SALOMEDSImpl_SComponent.hxx"
00041 #include "SALOMEDSImpl_GenericAttribute.hxx"
00042 #include "SALOMEDSImpl_ScalarVariable.hxx"
00043 #include <map>
00044 
00045 #include "HDFOI.hxx"
00046 #include <iostream>
00047 #include <stdlib.h>
00048 #include <string.h>
00049 
00050 #define USE_CASE_LABEL_ID                       "0:2"
00051 
00052 static void SaveAttributes(const SALOMEDSImpl_SObject& SO, HDFgroup *hdf_group_sobject);
00053 static void ReadAttributes(SALOMEDSImpl_Study*, const SALOMEDSImpl_SObject&, HDFdataset* );
00054 static void BuildTree (SALOMEDSImpl_Study*, HDFgroup*);
00055 static void Translate_IOR_to_persistentID (const SALOMEDSImpl_SObject&,
00056                                            SALOMEDSImpl_Driver*, bool isMultiFile, bool isASCII);
00057 static void ReadNoteBookVariables(SALOMEDSImpl_Study* theStudy, HDFgroup* theGroup);
00058 
00059 //============================================================================
00063 //============================================================================
00064 SALOMEDSImpl_StudyManager::SALOMEDSImpl_StudyManager()
00065 {
00066   _errorCode = "";
00067   _appli = new DF_Application();
00068   _IDcounter = 0;
00069   _clipboard = _appli->NewDocument("SALOME_STUDY");
00070 }
00071 
00072 //============================================================================
00076 //============================================================================
00077 SALOMEDSImpl_StudyManager::~SALOMEDSImpl_StudyManager()
00078 {
00079   _appli->Close(_clipboard);
00080   // Destroy application
00081   delete _appli;    
00082 }
00083 
00084 
00085 //============================================================================
00089 //==================================================T==========================
00090 SALOMEDSImpl_Study* SALOMEDSImpl_StudyManager::NewStudy(const std::string& study_name)
00091 {
00092   _errorCode = "";
00093 
00094   DF_Document* Doc = _appli->NewDocument("SALOME_STUDY");
00095 
00096   SALOMEDSImpl_Study* Study = new SALOMEDSImpl_Study(Doc, study_name);
00097 
00098   _IDcounter++;
00099   Study->StudyId( _IDcounter );
00100 
00101   // set Study properties
00102   SALOMEDSImpl_AttributeStudyProperties* aProp = Study->GetProperties();
00103   
00104   int month=0,day=0,year=0,hh=0,mn=0,ss=0;
00105   SALOMEDSImpl_Tool::GetSystemDate(year, month, day, hh, mn, ss);
00106   aProp->SetModification(SALOMEDSImpl_Tool::GetUserName(),
00107                          mn, hh, day, month, year);
00108   aProp->SetCreationMode(1);  //"from scratch"
00109 
00110   return Study;
00111 }
00112 
00113 //============================================================================
00117 //============================================================================
00118 SALOMEDSImpl_Study* SALOMEDSImpl_StudyManager::Open(const std::string& aUrl)
00119 {
00120   // Set "C" locale temporarily to avoid possible localization problems
00121   Kernel_Utils::Localizer loc;
00122 
00123   _errorCode = "";
00124 
00125   // open the HDFFile
00126   HDFfile *hdf_file =0;
00127   HDFgroup *hdf_group_study_structure =0;
00128   HDFgroup *hdf_notebook_vars = 0; 
00129 
00130   char* aC_HDFUrl;
00131   std::string aHDFUrl;
00132   bool isASCII = false;
00133   if (HDFascii::isASCII(aUrl.c_str())) {
00134     isASCII = true;
00135     char* aResultPath = HDFascii::ConvertFromASCIIToHDF(aUrl.c_str());
00136     if ( !aResultPath )
00137       return NULL;
00138     aC_HDFUrl = new char[strlen(aResultPath) + 19];
00139     sprintf(aC_HDFUrl, "%shdf_from_ascii.hdf", aResultPath);
00140     delete [] (aResultPath);
00141     aHDFUrl = aC_HDFUrl;
00142     delete [] aC_HDFUrl;
00143   } else {
00144     aHDFUrl = aUrl;
00145   }
00146 
00147   
00148   hdf_file = new HDFfile((char*)aHDFUrl.c_str());
00149   try {
00150     hdf_file->OpenOnDisk(HDF_RDONLY);// mpv: was RDWR, but opened file can be write-protected too
00151   }
00152   catch (HDFexception)
00153   {
00154     char *eStr;
00155     eStr = new char[strlen(aUrl.c_str())+17];
00156     sprintf(eStr,"Can't open file %s",aUrl.c_str());
00157     delete [] eStr;
00158     _errorCode = std::string(eStr);
00159     return NULL;
00160   }
00161   
00162   // Temporary aStudyUrl in place of study name
00163   DF_Document* Doc = _appli->NewDocument("SALOME_STUDY");
00164 
00165   SALOMEDSImpl_Study* Study = new SALOMEDSImpl_Study(Doc, aUrl);
00166 
00167   _IDcounter++;
00168   Study->StudyId( _IDcounter );
00169 
00170   // Assign the value of the URL in the study object
00171   Study->URL (aUrl);
00172 
00173   SALOMEDSImpl_AttributePersistentRef::Set(Doc->Main(), aUrl);
00174 
00175   if (!hdf_file->ExistInternalObject("STUDY_STRUCTURE")) {
00176      _errorCode = "Study is empty";
00177     return Study;
00178   }
00179 
00180   //Create  the Structure of the Document
00181   hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
00182 
00183   try {
00184     BuildTree (Study, hdf_group_study_structure);
00185   }
00186   catch (HDFexception)
00187   {
00188     char *eStr = new char [strlen(aUrl.c_str())+17];
00189     sprintf(eStr,"Can't open file %s", aUrl.c_str());
00190     _errorCode = std::string(eStr);
00191     return NULL;
00192   }
00193   
00194   //Read and create notebook variables 
00195   if(hdf_file->ExistInternalObject("NOTEBOOK_VARIABLES")) {
00196     hdf_notebook_vars  = new HDFgroup("NOTEBOOK_VARIABLES",hdf_file);
00197     ReadNoteBookVariables(Study,hdf_notebook_vars);
00198     hdf_notebook_vars =0; //will be deleted by hdf_sco_group destructor
00199   }
00200 
00201   hdf_file->CloseOnDisk();
00202   hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
00203   
00204   if (isASCII) {
00205     std::vector<std::string> aFilesToRemove;
00206     aFilesToRemove.push_back("hdf_from_ascii.hdf");
00207     SALOMEDSImpl_Tool::RemoveTemporaryFiles(SALOMEDSImpl_Tool::GetDirFromPath(aHDFUrl), aFilesToRemove, true);
00208   }
00209 
00210   delete hdf_file; // all related hdf objects will be deleted
00211 
00212   return Study;
00213 }
00214 
00215 
00216 
00217 //============================================================================
00224 //============================================================================
00225 void  SALOMEDSImpl_StudyManager::Close(SALOMEDSImpl_Study* aStudy)
00226 {
00227   _errorCode = "";
00228 
00229   if(!aStudy) {
00230     _errorCode = "Study is null";
00231     return;
00232   }
00233 
00234   aStudy->Close();
00235   DF_Document* doc=aStudy->GetDocument();
00236   _appli->Close(doc);
00237 }
00238 
00239 //============================================================================
00243 //============================================================================
00244 bool SALOMEDSImpl_StudyManager::Save(SALOMEDSImpl_Study* aStudy,
00245                                      SALOMEDSImpl_DriverFactory* aFactory,
00246                                      bool theMultiFile)
00247 {
00248   _errorCode = "";
00249 
00250   std::string url = aStudy->URL();
00251   if (url.empty()) {
00252     _errorCode = "No path specified to save the study. Nothing done";
00253     return false;
00254   }
00255   else {
00256     return Impl_SaveAs(url,aStudy, aFactory, theMultiFile, false);
00257   }
00258 
00259   return false;
00260 }
00261 
00262 bool SALOMEDSImpl_StudyManager::SaveASCII(SALOMEDSImpl_Study* aStudy,
00263                                           SALOMEDSImpl_DriverFactory* aFactory,
00264                                           bool theMultiFile)
00265 {
00266   _errorCode = "";
00267 
00268   std::string url = aStudy->URL();
00269   if (url.empty()) {
00270     _errorCode = "No path specified to save the study. Nothing done";
00271     return false;
00272   }
00273   else {
00274     return Impl_SaveAs(url,aStudy, aFactory, theMultiFile, true);
00275   }
00276 
00277   return false;
00278 }
00279 
00280 //=============================================================================
00284 //============================================================================
00285 bool SALOMEDSImpl_StudyManager::SaveAs(const std::string& aUrl,
00286                                        SALOMEDSImpl_Study* aStudy,
00287                                        SALOMEDSImpl_DriverFactory* aFactory,
00288                                        bool theMultiFile)
00289 {
00290   _errorCode = "";
00291   return Impl_SaveAs(aUrl,aStudy, aFactory, theMultiFile, false);
00292 }
00293 
00294 bool SALOMEDSImpl_StudyManager::SaveAsASCII(const std::string& aUrl,
00295                                             SALOMEDSImpl_Study* aStudy,
00296                                             SALOMEDSImpl_DriverFactory* aFactory,
00297                                             bool theMultiFile)
00298 {
00299   _errorCode = "";
00300   return Impl_SaveAs(aUrl,aStudy, aFactory, theMultiFile, true);
00301 }
00302 
00303 //============================================================================
00307 //============================================================================
00308 std::vector<SALOMEDSImpl_Study*> SALOMEDSImpl_StudyManager::GetOpenStudies()
00309 {
00310   _errorCode = "";
00311   std::vector<SALOMEDSImpl_Study*> aList;
00312 
00313   int nbDocs = _appli->NbDocuments();
00314 
00315   if(nbDocs == 0) {
00316     _errorCode = "No active study in this session";
00317     return aList;
00318   }
00319   else {
00320     SALOMEDSImpl_Study* aStudy;
00321     std::vector<int> ids = _appli->GetDocumentIDs();
00322     for (int i = 0, len = ids.size(); i<len; i++) {
00323       DF_Document* D = _appli->GetDocument(ids[i]);
00324       if(D == _clipboard) continue;
00325       aStudy = SALOMEDSImpl_Study::GetStudy(D->Main());
00326       if(!aStudy) continue;
00327       aList.push_back(aStudy);
00328     }
00329   }
00330 
00331   return aList;
00332 }
00333 
00334 //============================================================================
00338 //============================================================================
00339 SALOMEDSImpl_Study* SALOMEDSImpl_StudyManager::GetStudyByName
00340                                    (const std::string& aStudyName)
00341 {
00342   _errorCode = "";
00343   int nbDocs = _appli->NbDocuments();
00344 
00345   if (nbDocs == 0) {
00346     _errorCode = "No active study in this session";
00347     return NULL;
00348   }
00349   else {
00350     std::vector<SALOMEDSImpl_Study*> studies = GetOpenStudies();
00351     for (int i = 0, len = studies.size(); i<len; i++) {
00352       if (studies[i]->Name() == aStudyName) return studies[i];
00353     }
00354   }
00355 
00356   _errorCode = std::string("Found no study with the name ") + aStudyName;
00357   return NULL;
00358 }
00359 
00360 //============================================================================
00364 //============================================================================
00365 SALOMEDSImpl_Study* SALOMEDSImpl_StudyManager::GetStudyByID(int aStudyID)
00366 {
00367   _errorCode = "";
00368   int nbDocs = _appli->NbDocuments();
00369 
00370   if (nbDocs == 0) {
00371     _errorCode = "No active study in this session";
00372     return NULL;
00373   }
00374   else {
00375     std::vector<SALOMEDSImpl_Study*> studies = GetOpenStudies();
00376     for (int i = 0, len = studies.size(); i<len; i++) {
00377       if (studies[i]->StudyId() == aStudyID) return studies[i];
00378     }
00379   }
00380 
00381   _errorCode = "Found no study with the given ID";
00382   return NULL;
00383 }
00384 
00385 //=============================================================================
00389 //============================================================================
00390 bool SALOMEDSImpl_StudyManager::Impl_SaveProperties(SALOMEDSImpl_Study* aStudy,
00391                                                     HDFgroup *hdf_group)
00392 {
00393   _errorCode = "";
00394 
00395   HDFdataset *hdf_dataset = 0;
00396   hdf_size size[1];
00397   hdf_int32 name_len;
00398 
00399   // add modifications list (user and date of save)
00400   SALOMEDSImpl_AttributeStudyProperties* aProp = aStudy->GetProperties();
00401   int aLocked = aProp->IsLocked();
00402   if (aLocked) aProp->SetLocked(false);
00403 
00404   int month=0,day=0,year=0,hh=0,mn=0,ss=0;
00405   SALOMEDSImpl_Tool::GetSystemDate(year, month, day, hh, mn, ss);
00406   aProp->SetModification(SALOMEDSImpl_Tool::GetUserName(),
00407                          mn, hh, day, month, year);
00408 
00409   if (aLocked) aProp->SetLocked(true);
00410 
00411   std::vector<std::string> aNames;
00412   std::vector<int> aMinutes, aHours, aDays, aMonths, aYears;
00413 
00414   aProp->GetModifications(aNames, aMinutes, aHours, aDays, aMonths, aYears);
00415 
00416   std::string units = aProp->GetUnits();
00417   std::string comment = aProp->GetComment();
00418 
00419   int aLength = 0, anIndex, i, unitsSize = 0, commentSize = 0;
00420   for(i=1; i<=aNames.size(); i++)
00421     aLength += aNames[i-1].size() + 1;
00422   
00423   unitsSize = units.size();
00424   commentSize = comment.size();
00425 
00426   //string format:
00427   //locked flag, modified flag,
00428   //minutes, hours, day, months, year, user name, char(1), 
00429   //minutes, hours, day, months, year, user name, char(1),
00430   //.....................................................,
00431   //.....................................................,
00432   //.....................................................,
00433   //minutes, hours, day, months, year, user name, char(1), char(30) <- !!!! used to define end of section with modifications !!!!
00434   //units, char(1), comment, char(0)
00435 
00436   //string length: 1 byte = locked flag, 1 byte = modified flag, (12 + name length + 1) for each name and date, 1 byte (char(30) section delimeter)
00437   // unit length + 1, comment length, "zero" byte
00438   
00439   char* aProperty = new char[3 + aLength + 12 * aNames.size() + 1 + unitsSize + 1 + commentSize ];
00440 
00441 
00442   sprintf(aProperty,"%c%c", (char)aProp->GetCreationMode(),  (aProp->IsLocked())?'l':'u');
00443 
00444   aLength = aNames.size();
00445   int a = 2;
00446   for(anIndex = 0; anIndex<aLength; anIndex++) {
00447     sprintf(&(aProperty[a]),"%2d%2d%2d%2d%4d%s",
00448             (int)(aMinutes[anIndex]),
00449             (int)(aHours[anIndex]),
00450             (int)(aDays[anIndex]),
00451             (int)(aMonths[anIndex]),
00452             (int)(aYears[anIndex]),
00453             aNames[anIndex].c_str());
00454     a = strlen(aProperty);
00455     aProperty[a++] = 1;
00456   }
00457 
00458   //Write delimeter of the section to define end of the modifications section
00459   aProperty[a++] = 30;
00460 
00461   //Write units if need
00462   if(units.size() > 0) {
00463     sprintf(&(aProperty[a]),"%s",units.c_str());
00464     a = strlen(aProperty);
00465   }
00466 
00467   aProperty[a++] = 1;
00468 
00469   //Write comments if need
00470   if(comment.size() > 0) {
00471     sprintf(&(aProperty[a]),"%s",comment.c_str());
00472     a = strlen(aProperty);
00473     a++;
00474   }
00475 
00476   aProperty[a] = 0;
00477   
00478   name_len = (hdf_int32) a;
00479   size[0] = name_len + 1 ;
00480   hdf_dataset = new HDFdataset("AttributeStudyProperties",hdf_group,HDF_STRING,size,1);
00481   hdf_dataset->CreateOnDisk();
00482   hdf_dataset->WriteOnDisk(aProperty);
00483   hdf_dataset->CloseOnDisk();
00484   hdf_dataset=0; //will be deleted by hdf_sco_group destructor
00485   delete [] aProperty;
00486   
00487   aProp->SetModified(0);
00488   return true;
00489 }
00490 
00491 //=============================================================================
00495 //============================================================================
00496 bool SALOMEDSImpl_StudyManager::Impl_SaveAs(const std::string& aStudyUrl,
00497                                             SALOMEDSImpl_Study* aStudy,
00498                                             SALOMEDSImpl_DriverFactory* aFactory,
00499                                             bool theMultiFile,
00500                                             bool theASCII)
00501 {
00502   // Set "C" locale temporarily to avoid possible localization problems
00503   Kernel_Utils::Localizer loc;
00504 
00505   // HDF File will be composed of differents part :
00506   // * For each ComponentDataType, all data created by the component
00507   //   Informations in data group hdf_group_datacomponent
00508   // * Study Structure -> Exactly what is contained in Document
00509   //   Informations in data group hdf_group_study_structure
00510 
00511   _errorCode = "";
00512 
00513   HDFfile *hdf_file=0;
00514   HDFgroup *hdf_group_study_structure =0;
00515   HDFgroup *hdf_sco_group =0;
00516   HDFgroup *hdf_sco_group2 =0;
00517   HDFgroup *hdf_notebook_vars =0; 
00518   HDFgroup *hdf_notebook_var  = 0;
00519 
00520   HDFgroup *hdf_group_datacomponent =0;
00521   HDFdataset *hdf_dataset =0;
00522   hdf_size size[1];
00523   hdf_int32 name_len = 0;
00524   std::string component_name;
00525 
00526   if(!aStudy) {
00527     _errorCode = "Study is null";
00528     return false;
00529   }
00530 
00531   // Store previous URL
00532   std::string anOldName = aStudy->Name();
00533 
00534   //Create a temporary url to which the study is saved 
00535   std::string aUrl = SALOMEDSImpl_Tool::GetTmpDir() + SALOMEDSImpl_Tool::GetNameFromPath(aStudyUrl);
00536 
00537   int aLocked = aStudy->GetProperties()->IsLocked();
00538   if (aLocked) aStudy->GetProperties()->SetLocked(false);
00539 
00540   SALOMEDSImpl_StudyBuilder* SB= aStudy->NewBuilder();
00541   std::map<std::string, SALOMEDSImpl_Driver*> aMapTypeDriver;
00542 
00543   try
00544     {
00545       // mpv 15.12.2003: for saving components we have to load all data from all modules
00546       SALOMEDSImpl_SComponentIterator itcomponent1 = aStudy->NewComponentIterator();
00547       for (; itcomponent1.More(); itcomponent1.Next())
00548         {
00549           SALOMEDSImpl_SComponent sco = itcomponent1.Value();
00550           // if there is an associated Engine call its method for saving
00551           std::string IOREngine;
00552           try {
00553             if (!sco.ComponentIOR(IOREngine)) {
00554               std::string aCompType = sco.GetComment();
00555               if (!aCompType.empty()) {
00556 
00557                 SALOMEDSImpl_Driver* aDriver = aFactory->GetDriverByType(aCompType);
00558                 aMapTypeDriver[aCompType] = aDriver;
00559 
00560                 if (aDriver != NULL) {
00561                   if(!SB->LoadWith(sco, aDriver)) {
00562                     _errorCode = SB->GetErrorCode();
00563                     return false;
00564                   }
00565                 }
00566               }
00567             }
00568           } catch(...) {
00569             _errorCode = "Can not restore information to resave it";
00570             return false;
00571           }
00572         }
00573 
00574       // VSR: set URL to new file name
00575       // VSR: remember to set previous name if save operation fails
00576       aStudy->URL(aStudyUrl);
00577 
00578       // To change for Save
00579       // Do not have to do a new file but just a Open??? Rewrite all informations after erasing evrything??
00580       hdf_file = new HDFfile((char*)aUrl.c_str());
00581       hdf_file->CreateOnDisk();
00582 
00583       //-----------------------------------------------------------------------
00584       // 1 - Create a groupe for each SComponent and Update the PersistanceRef
00585       //-----------------------------------------------------------------------
00586       hdf_group_datacomponent = new HDFgroup("DATACOMPONENT",hdf_file);
00587       hdf_group_datacomponent->CreateOnDisk();
00588 
00589       SALOMEDSImpl_SComponentIterator itcomponent = aStudy->NewComponentIterator();
00590 
00591       for (; itcomponent.More(); itcomponent.Next())
00592         {
00593           SALOMEDSImpl_SComponent sco = itcomponent.Value();
00594 
00595           std::string scoid = sco.GetID();
00596           hdf_sco_group = new HDFgroup((char*)scoid.c_str(), hdf_group_datacomponent);
00597           hdf_sco_group->CreateOnDisk();
00598 
00599           std::string componentDataType = sco.ComponentDataType();
00600           std::string IOREngine;
00601           if (sco.ComponentIOR(IOREngine))
00602             {
00603               SALOMEDSImpl_Driver* Engine = NULL;
00604               if(aMapTypeDriver.find(componentDataType) != aMapTypeDriver.end()) {
00605                 // we have found the associated engine to write the data
00606                 Engine = aMapTypeDriver[componentDataType];
00607               }
00608               else {
00609                 Engine = aFactory->GetDriverByIOR(IOREngine);
00610               }
00611 
00612               if (Engine != NULL)
00613                 {
00614                   SALOMEDSImpl_TMPFile* aStream = NULL;
00615                   long length = 0;
00616 
00617                   if (theASCII) aStream = Engine->SaveASCII(sco,
00618                                                             SALOMEDSImpl_Tool::GetDirFromPath(aUrl),
00619                                                             length,
00620                                                             theMultiFile);
00621                   else aStream = Engine->Save(sco,
00622                                               SALOMEDSImpl_Tool::GetDirFromPath(aUrl),
00623                                               length,
00624                                               theMultiFile);
00625                   HDFdataset *hdf_dataset;
00626                   hdf_size aHDFSize[1]; 
00627                   if(length > 0) {  //The component saved some auxiliary files, then put them into HDF file
00628 
00629                     aHDFSize[0] = length;
00630 
00631                     HDFdataset *hdf_dataset = new HDFdataset("FILE_STREAM", hdf_sco_group, HDF_STRING, aHDFSize, 1);
00632                     hdf_dataset->CreateOnDisk();
00633                     hdf_dataset->WriteOnDisk(aStream->Data());  //Save the stream in the HDF file
00634                     hdf_dataset->CloseOnDisk();
00635                   }
00636 
00637                   if(aStream) delete aStream;
00638 
00639                   // store multifile state
00640                   aHDFSize[0] = 2;
00641                   hdf_dataset = new HDFdataset("MULTIFILE_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
00642                   hdf_dataset->CreateOnDisk();
00643                   hdf_dataset->WriteOnDisk((void*)(theMultiFile?"M":"S")); // save: multi or single
00644                   hdf_dataset->CloseOnDisk();
00645                   hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor
00646                   // store ASCII state
00647                   aHDFSize[0] = 2;
00648                   hdf_dataset = new HDFdataset("ASCII_STATE", hdf_sco_group, HDF_STRING, aHDFSize, 1);
00649                   hdf_dataset->CreateOnDisk();
00650                   hdf_dataset->WriteOnDisk((void*)(theASCII?"A":"B")); // save: ASCII or BINARY
00651                   hdf_dataset->CloseOnDisk();
00652                   hdf_dataset=0; //will be deleted by hdf_sco_AuxFiles destructor
00653                   // Creation of the persistance reference  attribute
00654                   Translate_IOR_to_persistentID (sco, Engine, theMultiFile, theASCII);
00655                 }
00656             }
00657           hdf_sco_group->CloseOnDisk();
00658           hdf_sco_group=0; // will be deleted by hdf_group_datacomponent destructor
00659         }
00660       hdf_group_datacomponent->CloseOnDisk();
00661       hdf_group_datacomponent =0;  // will be deleted by hdf_file destructor
00662 
00663       //-----------------------------------------------------------------------
00664       //3 - Write the Study Structure
00665       //-----------------------------------------------------------------------
00666       hdf_group_study_structure = new HDFgroup("STUDY_STRUCTURE",hdf_file);
00667       hdf_group_study_structure->CreateOnDisk();
00668       // save component attributes
00669       SALOMEDSImpl_SComponentIterator itcomp = aStudy->NewComponentIterator();
00670       for (; itcomp.More(); itcomp.Next())
00671         {
00672           SALOMEDSImpl_SComponent SC = itcomp.Value();
00673           std::string scid = SC.GetID();
00674           hdf_sco_group2 = new HDFgroup((char*)scid.c_str(), hdf_group_study_structure);
00675           hdf_sco_group2->CreateOnDisk();
00676           SaveAttributes(SC, hdf_sco_group2);
00677           // ComponentDataType treatment
00678           component_name = SC.ComponentDataType();
00679           name_len = (hdf_int32)component_name.length();
00680           size[0] = name_len +1 ;
00681           hdf_dataset = new HDFdataset("COMPONENTDATATYPE",hdf_sco_group2,HDF_STRING,size,1);
00682           hdf_dataset->CreateOnDisk();
00683           hdf_dataset->WriteOnDisk((char*)component_name.c_str());
00684           hdf_dataset->CloseOnDisk();
00685           hdf_dataset=0; //will be deleted by hdf_sco_group destructor
00686           Impl_SaveObject(SC, hdf_sco_group2);
00687           hdf_sco_group2->CloseOnDisk();
00688           hdf_sco_group2=0; // will be deleted by hdf_group_study_structure destructor
00689         }
00690       //-----------------------------------------------------------------------
00691       //4 - Write the Study UseCases Structure
00692       //-----------------------------------------------------------------------
00693       SALOMEDSImpl_SObject aSO = aStudy->FindObjectID(USE_CASE_LABEL_ID);
00694       if (aSO) {
00695         HDFgroup *hdf_soo_group = new HDFgroup(USE_CASE_LABEL_ID,hdf_group_study_structure);
00696         hdf_soo_group->CreateOnDisk();
00697         SaveAttributes(aSO, hdf_soo_group);
00698         Impl_SaveObject(aSO, hdf_soo_group);
00699         hdf_soo_group->CloseOnDisk();
00700         hdf_soo_group=0; // will be deleted by hdf_group_study_structure destructor
00701       }
00702       //-----------------------------------------------------------------------
00703       //5 - Write the NoteBook Variables
00704       //-----------------------------------------------------------------------
00705 
00706       //5.1 Create group to store all note book variables
00707       hdf_notebook_vars = new HDFgroup("NOTEBOOK_VARIABLES",hdf_file);
00708       hdf_notebook_vars->CreateOnDisk();
00709       
00710       std::string varValue;
00711       std::string varType;
00712       std::string varIndex;
00713 
00714       for(int i=0 ;i < aStudy->myNoteBookVars.size(); i++ ){
00715         // For each variable create HDF group
00716         hdf_notebook_var = new HDFgroup((char*)aStudy->myNoteBookVars[i]->Name().c_str(),hdf_notebook_vars);
00717         hdf_notebook_var->CreateOnDisk();
00718 
00719         // Save Variable type
00720         varType = aStudy->myNoteBookVars[i]->SaveType();
00721         name_len = (hdf_int32) varType.length();
00722         size[0] = name_len +1 ;
00723         hdf_dataset = new HDFdataset("VARIABLE_TYPE",hdf_notebook_var,HDF_STRING,size,1);
00724         hdf_dataset->CreateOnDisk();
00725         hdf_dataset->WriteOnDisk((char*)varType.c_str());
00726         hdf_dataset->CloseOnDisk();
00727         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
00728         
00729         char buffer[256];
00730         sprintf(buffer,"%d",i);
00731         varIndex= std::string(buffer);
00732         name_len = (hdf_int32) varIndex.length();
00733         size[0] = name_len +1 ;
00734         hdf_dataset = new HDFdataset("VARIABLE_INDEX",hdf_notebook_var,HDF_STRING,size,1);
00735         hdf_dataset->CreateOnDisk();
00736         hdf_dataset->WriteOnDisk((char*)varIndex.c_str());
00737         hdf_dataset->CloseOnDisk();
00738         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
00739         
00740         
00741         // Save Variable value
00742         varValue = aStudy->myNoteBookVars[i]->Save();
00743         name_len = (hdf_int32) varValue.length();
00744         size[0] = name_len +1 ;
00745         hdf_dataset = new HDFdataset("VARIABLE_VALUE",hdf_notebook_var,HDF_STRING,size,1);
00746         hdf_dataset->CreateOnDisk();
00747         hdf_dataset->WriteOnDisk((char*)varValue.c_str());
00748         hdf_dataset->CloseOnDisk();
00749         hdf_dataset=0; //will be deleted by hdf_sco_group destructor
00750         hdf_notebook_var->CloseOnDisk();
00751         hdf_notebook_var = 0; //will be deleted by hdf_sco_group destructor
00752       }
00753       hdf_notebook_vars->CloseOnDisk();
00754       hdf_notebook_vars = 0; //will be deleted by hdf_sco_group destructor
00755         
00756       if (aLocked) aStudy->GetProperties()->SetLocked(true);
00757       //-----------------------------------------------------------------------
00758       //6 - Write the Study Properties
00759       //-----------------------------------------------------------------------
00760       std::string study_name = aStudy->Name();
00761       name_len = (hdf_int32) study_name.size();
00762       size[0] = name_len +1 ;
00763       hdf_dataset = new HDFdataset("STUDY_NAME",hdf_group_study_structure,HDF_STRING,size,1);
00764       hdf_dataset->CreateOnDisk();
00765       hdf_dataset->WriteOnDisk((char*)study_name.c_str());
00766       hdf_dataset->CloseOnDisk();
00767       hdf_dataset=0; // will be deleted by hdf_group_study_structure destructor
00768 
00769       Impl_SaveProperties(aStudy, hdf_group_study_structure);
00770       hdf_group_study_structure->CloseOnDisk();
00771       hdf_file->CloseOnDisk();
00772 
00773       hdf_group_study_structure =0; // will be deleted by hdf_file destructor
00774       delete hdf_file; // recursively deletes all hdf objects...
00775     }
00776   catch (HDFexception)
00777     {
00778       _errorCode = "HDFexception ! ";
00779       aStudy->URL( anOldName ); // VSR: restore previous url if operation is failed
00780       return false;
00781     }
00782   catch(std::exception& exc)
00783     {
00784       _errorCode = const_cast<char*>(exc.what());
00785       aStudy->URL( anOldName ); // VSR: restore previous url if operation is failed
00786       return false;
00787     }
00788   catch(...)
00789     {
00790       _errorCode = "Unknown exception ! ";
00791       aStudy->URL( anOldName ); // VSR: restore previous url if operation is failed
00792       return false;
00793     }
00794   if (theASCII) { // save file in ASCII format
00795     HDFascii::ConvertFromHDFToASCII(aUrl.c_str(), true);
00796   }
00797   
00798   //Now it's necessary to copy files from the temporary directory to the user defined directory.
00799 
00800   //      The easiest way to get a list of file in the temporary directory
00801 
00802   std::string aCmd, aTmpFileDir = SALOMEDSImpl_Tool::GetTmpDir();
00803   std::string aTmpFile = aTmpFileDir +"files";
00804   std::string aStudyTmpDir = SALOMEDSImpl_Tool::GetDirFromPath(aUrl);
00805 
00806 #ifdef WIN32
00807   aCmd = "dir /B \"" + aStudyTmpDir +"\" > " + aTmpFile;
00808 #else
00809   aCmd ="ls -1 \"" + aStudyTmpDir +"\" > " + aTmpFile;
00810 #endif
00811   system(aCmd.c_str());
00812 
00813   //       Iterate and move files in the temporary directory
00814   FILE* fp = fopen(aTmpFile.c_str(), "rb");
00815   if(!fp) {
00816     aStudy->URL( anOldName ); // VSR: restore previous url if operation is failed
00817     return false;
00818   }
00819   char* buffer = new char[2047];
00820   int errors = 0;
00821   while(!feof(fp) && !errors) {
00822     if((fgets(buffer, 2046, fp)) == NULL) break;
00823     size_t aLen = strlen(buffer);
00824     if(buffer[aLen-1] == '\n') buffer[aLen-1] = char(0);
00825 #ifdef WIN32
00826     aCmd = "move /Y \"" + aStudyTmpDir + std::string(buffer) + "\" \"" + SALOMEDSImpl_Tool::GetDirFromPath(aStudyUrl) +"\"";
00827 #else 
00828     aCmd = "mv -f \"" + aStudyTmpDir + std::string(buffer) + "\" \"" + SALOMEDSImpl_Tool::GetDirFromPath(aStudyUrl)+"\"";
00829 #endif
00830     errors = system(aCmd.c_str());
00831   }
00832 
00833   delete []buffer;
00834   fclose(fp);
00835 
00836   //       Perform cleanup
00837 #ifdef WIN32
00838   DeleteFileA(aTmpFile.c_str());
00839 #else 
00840   unlink(aTmpFile.c_str());
00841 #endif
00842 
00843 #ifdef WIN32
00844   RemoveDirectoryA(aTmpFileDir.c_str());
00845   RemoveDirectoryA(aStudyTmpDir.c_str());
00846 #else
00847   rmdir(aTmpFileDir.c_str());
00848   rmdir(aStudyTmpDir.c_str());
00849 #endif
00850 
00851   if ( !errors ) {
00852     // VSR: finally, if all is done without errors, mark study as Saved
00853     aStudy->IsSaved(true);
00854   }
00855 
00856   return !errors;
00857 }
00858 
00859 //============================================================================
00863 //============================================================================
00864 bool SALOMEDSImpl_StudyManager::Impl_SaveObject(const SALOMEDSImpl_SObject& SC,
00865                                                 HDFgroup *hdf_group_datatype)
00866 {
00867   _errorCode = "";
00868 
00869   // Write in group hdf_group_datatype all informations of SObject SC
00870   // Iterative function to parse all SObjects under a SComponent
00871 
00872   HDFgroup *hdf_group_sobject = 0;
00873 
00874   DF_ChildIterator itchild(SC.GetLabel());
00875   for (; itchild.More(); itchild.Next())
00876     {
00877 
00878       // mpv: don't save empty labels
00879       std::vector<DF_Attribute*> attr = itchild.Value().GetAttributes();
00880       if (attr.size() == 0) {  //No attributes on the label
00881         DF_ChildIterator subchild(itchild.Value());
00882         if (!subchild.More()) {
00883           continue;
00884         }
00885         subchild.Init(itchild.Value(), true);
00886         bool anEmpty = true;
00887         for (; subchild.More() && anEmpty; subchild.Next()) {
00888           std::vector<DF_Attribute*> attr2 = subchild.Value().GetAttributes();
00889           if (attr2.size()) {
00890             anEmpty = false;  //There are attributes on the child label
00891             break;
00892           }
00893         }
00894         if (anEmpty) continue;
00895       }
00896 
00897       SALOMEDSImpl_SObject SO = SALOMEDSImpl_Study::SObject(itchild.Value());
00898 
00899       std::string scoid = SO.GetID();
00900       hdf_group_sobject = new HDFgroup(scoid.c_str(), hdf_group_datatype);
00901       hdf_group_sobject->CreateOnDisk();
00902       SaveAttributes(SO, hdf_group_sobject);
00903       Impl_SaveObject(SO, hdf_group_sobject);
00904       hdf_group_sobject->CloseOnDisk();
00905       hdf_group_sobject =0; // will be deleted by father hdf object destructor
00906     }
00907 
00908   return true;
00909 }
00910 
00911 //============================================================================
00915 //============================================================================
00916 std::string SALOMEDSImpl_StudyManager::Impl_SubstituteSlash(const std::string& aUrl)
00917 {
00918   _errorCode = "";
00919 
00920   std::string theUrl(aUrl);
00921   for(int i = 0; i<theUrl.size(); i++)
00922     if(theUrl[i] == '/') theUrl[i] = ':';
00923   return theUrl;
00924 }
00925 
00926 //============================================================================
00930 //============================================================================
00931 DF_Document* SALOMEDSImpl_StudyManager::GetDocumentOfStudy(SALOMEDSImpl_Study* theStudy)
00932 {
00933   _errorCode = "";
00934   return theStudy->_doc;
00935 }
00936 
00937 //============================================================================
00941 //============================================================================
00942 bool SALOMEDSImpl_StudyManager::CanCopy(const SALOMEDSImpl_SObject& theObject,
00943                                         SALOMEDSImpl_Driver* theEngine)
00944 {
00945   _errorCode = "";
00946   SALOMEDSImpl_SComponent aComponent = theObject.GetFatherComponent();
00947   if (!aComponent) return false;
00948   if (aComponent.GetLabel() == theObject.GetLabel()) return false;
00949   std::string IOREngine;
00950   if (!aComponent.ComponentIOR(IOREngine)) return false;
00951   if (theEngine == NULL) return false;
00952   return theEngine->CanCopy(theObject);
00953 }
00954 
00955 //============================================================================
00959 //============================================================================
00960 bool SALOMEDSImpl_StudyManager::CopyLabel(SALOMEDSImpl_Study* theSourceStudy,
00961                                           SALOMEDSImpl_Driver* theEngine,
00962                                           const int theSourceStartDepth,
00963                                           const DF_Label& theSource,
00964                                           const DF_Label& theDestinationMain)
00965 {
00966   _errorCode = "";
00967 
00968   int a;
00969   DF_Label aTargetLabel = theDestinationMain;
00970   DF_Label aAuxTargetLabel = theDestinationMain.Father().FindChild(2);
00971   for(a = theSource.Depth() - theSourceStartDepth; a > 0 ; a--) {
00972     DF_Label aSourceLabel = theSource;
00973     for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
00974     aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
00975     aAuxTargetLabel = aAuxTargetLabel.FindChild(aSourceLabel.Tag());
00976   }
00977   // iterate attributes
00978   std::vector<DF_Attribute*> attrList = theSource.GetAttributes();
00979   for(int i = 0, len = attrList.size(); i<len; i++) {
00980     DF_Attribute* anAttr = attrList[i];
00981     std::string type = SALOMEDSImpl_GenericAttribute::Impl_GetType(anAttr);
00982     if (type.substr(0, 17) == std::string("AttributeTreeNode")) continue; // never copy tree node attribute
00983     if (type == std::string("AttributeTarget")) continue; // and target attribute
00984 
00985     if (type == std::string("AttributeReference")) { // reference copied as Comment in aux tree
00986       DF_Label aReferenced = dynamic_cast<SALOMEDSImpl_AttributeReference*>(anAttr)->Get();
00987       std::string anEntry = aReferenced.Entry();
00988       // store the value of name attribute of referenced label
00989       SALOMEDSImpl_AttributeName* aNameAttribute;
00990       if ((aNameAttribute=(SALOMEDSImpl_AttributeName*)aReferenced.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) {
00991         anEntry += " ";
00992         anEntry += aNameAttribute->Value();
00993       }
00994       SALOMEDSImpl_AttributeComment::Set(aAuxTargetLabel, anEntry);
00995       continue;
00996     }
00997 
00998     if (type == std::string("AttributeIOR")) { // IOR => ID and TMPFile of Engine
00999       std::string anEntry = theSource.Entry();
01000       SALOMEDSImpl_SObject aSO = theSourceStudy->FindObjectID(anEntry);
01001       int anObjID;
01002       long aLen;
01003       SALOMEDSImpl_TMPFile* aStream = theEngine->CopyFrom(aSO, anObjID, aLen);
01004       std::string aResStr("");
01005       for(a = 0; a < aLen; a++) {
01006         aResStr += (char)(aStream->Get(a));
01007       }
01008 
01009       if(aStream) delete aStream;
01010 
01011       SALOMEDSImpl_AttributeInteger::Set(aAuxTargetLabel, anObjID);
01012       SALOMEDSImpl_AttributeName::Set(aAuxTargetLabel, aResStr);
01013       continue;
01014     }
01015     DF_Attribute* aNewAttribute = anAttr->NewEmpty();
01016     aTargetLabel.AddAttribute(aNewAttribute);
01017     anAttr->Paste(aNewAttribute);
01018   }
01019 
01020   return true;
01021 }
01022 
01023 //============================================================================
01027 //============================================================================
01028 bool SALOMEDSImpl_StudyManager::Copy(const SALOMEDSImpl_SObject& theObject,
01029                                      SALOMEDSImpl_Driver* theEngine)
01030 {
01031   _errorCode = "";
01032 
01033   // adoptation for alliances datamodel copy: without IOR attributes !!!
01034   bool aStructureOnly; // copy only SObjects and attributes without component help
01035   aStructureOnly = !theObject.GetLabel().IsAttribute(SALOMEDSImpl_AttributeIOR::GetID());
01036 
01037   // get component-engine
01038   SALOMEDSImpl_Study* aStudy = theObject.GetStudy();
01039 
01040   // CAF document of current study usage
01041   DF_Document* aDocument = GetDocumentOfStudy(aStudy);
01042   if (!aDocument) {
01043     _errorCode = "Document is null";
01044     return false;
01045   }
01046 
01047   //Clear the clipboard
01048   _clipboard->Main().Root().ForgetAllAttributes(true);
01049   _appli->Close(_clipboard);
01050   _clipboard = _appli->NewDocument("SALOME_STUDY");
01051 
01052   // set component data type to the name attribute of root label
01053   if (!aStructureOnly) {
01054     SALOMEDSImpl_AttributeComment::Set(_clipboard->Main().Root(),
01055                                        theEngine->ComponentDataType());
01056   }
01057   // set to the Root label integer attribute: study id
01058   SALOMEDSImpl_AttributeInteger::Set(_clipboard->Main().Root(), aStudy->StudyId());
01059   // iterate all theObject's label children
01060   DF_Label aStartLabel = theObject.GetLabel();
01061   int aSourceStartDepth = aStartLabel.Depth();
01062 
01063   // copy main source label
01064   CopyLabel(aStudy, theEngine, aSourceStartDepth, aStartLabel, _clipboard->Main());
01065 
01066   // copy all subchildren of the main source label (all levels)
01067   DF_ChildIterator anIterator(aStartLabel, true);
01068   for(; anIterator.More(); anIterator.Next()) {
01069     CopyLabel(aStudy, theEngine, aSourceStartDepth, anIterator.Value(), _clipboard->Main());
01070   }
01071 
01072   return true;
01073 }
01074 //============================================================================
01078 //============================================================================
01079 bool SALOMEDSImpl_StudyManager::CanPaste(const SALOMEDSImpl_SObject& theObject,
01080                                          SALOMEDSImpl_Driver* theEngine)
01081 {
01082   _errorCode = "";
01083 
01084   if (!_clipboard) {
01085     _errorCode = "Clipboard is null";
01086     return false;
01087   }
01088 
01089   SALOMEDSImpl_AttributeComment* aCompName = NULL;
01090   if (!(aCompName=(SALOMEDSImpl_AttributeComment*)_clipboard->Main().Root().FindAttribute(SALOMEDSImpl_AttributeComment::GetID()))) {
01091     _errorCode = "Clipboard has no component type";
01092     return false;
01093   }
01094   SALOMEDSImpl_AttributeInteger* anObjID;
01095   if (!(anObjID=(SALOMEDSImpl_AttributeInteger*)_clipboard->Main().Father().FindChild(2).FindAttribute(SALOMEDSImpl_AttributeInteger::GetID()))) {
01096     _errorCode = "Clipboard has no object id";
01097     return false;
01098   }
01099   SALOMEDSImpl_SComponent aComponent = theObject.GetFatherComponent();
01100   if (!aComponent) {
01101     _errorCode = "Object doesn't belong to component";
01102     return false;
01103   }
01104 
01105   std::string IOREngine;
01106   if (!aComponent.ComponentIOR(IOREngine)) {
01107     _errorCode = "component has no IOR";
01108     return false;
01109   }
01110   return theEngine->CanPaste(aCompName->Value(), anObjID->Value());
01111 }
01112 
01113 //============================================================================
01117 //============================================================================
01118 DF_Label SALOMEDSImpl_StudyManager::PasteLabel(SALOMEDSImpl_Study* theDestinationStudy,
01119                                                SALOMEDSImpl_Driver* theEngine,
01120                                                const DF_Label& theSource,
01121                                                const DF_Label& theDestinationStart,
01122                                                const int theCopiedStudyID,
01123                                                const bool isFirstElement)
01124 {
01125   _errorCode = "";
01126 
01127   // get corresponding source, target and auxiliary labels
01128   DF_Label aTargetLabel = theDestinationStart;
01129 
01130   DF_Label aAuxSourceLabel = theSource.Root().FindChild(2);
01131   int a;
01132   if (!isFirstElement) {
01133     for(a = theSource.Depth() - 1; a > 0 ; a--) {
01134       DF_Label aSourceLabel = theSource;
01135       for(int aNbFather = 1; aNbFather < a; aNbFather++) aSourceLabel = aSourceLabel.Father();
01136       aTargetLabel = aTargetLabel.FindChild(aSourceLabel.Tag());
01137       aAuxSourceLabel = aAuxSourceLabel.FindChild(aSourceLabel.Tag());
01138     }
01139     SALOMEDSImpl_SObject so = theDestinationStudy->GetSObject(aTargetLabel);
01140     theDestinationStudy->addSO_Notification(so);
01141   }
01142 
01143   // check auxiliary label for TMPFile => IOR
01144   SALOMEDSImpl_AttributeName* aNameAttribute = NULL;
01145   if ((aNameAttribute=(SALOMEDSImpl_AttributeName*)aAuxSourceLabel.FindAttribute(SALOMEDSImpl_AttributeName::GetID()))) {
01146     SALOMEDSImpl_AttributeInteger* anObjID = (SALOMEDSImpl_AttributeInteger*)aAuxSourceLabel.FindAttribute(SALOMEDSImpl_AttributeInteger::GetID());
01147     SALOMEDSImpl_AttributeComment* aComponentName = (SALOMEDSImpl_AttributeComment*)theSource.Root().FindAttribute(SALOMEDSImpl_AttributeComment::GetID());
01148     std::string aCompName = aComponentName->Value();
01149 
01150     if (theEngine->CanPaste(aCompName, anObjID->Value())) {
01151       std::string aTMPStr = aNameAttribute->Value();
01152       int aLen = aTMPStr.size();
01153       unsigned char* aStream = NULL;
01154       if(aLen > 0) {
01155         aStream = new unsigned char[aLen+10];
01156         for(a = 0; a < aLen; a++) {
01157           aStream[a] = aTMPStr[a];
01158         }
01159       }
01160 
01161       std::string anEntry = aTargetLabel.Entry();
01162       SALOMEDSImpl_SObject aPastedSO = theDestinationStudy->FindObjectID(anEntry);
01163 
01164       if (isFirstElement) {
01165         std::string aDestEntry = theEngine->PasteInto(aStream,
01166                                                  aLen,
01167                                                  anObjID->Value(),
01168                                                  aPastedSO.GetFatherComponent());
01169         aTargetLabel = DF_Label::Label(theDestinationStart, aDestEntry);
01170       } else
01171         theEngine->PasteInto(aStream, aLen, anObjID->Value(), aPastedSO);
01172 
01173       if(aStream != NULL) delete []aStream;
01174     }
01175   }
01176 
01177   // iterate attributes
01178   std::vector<DF_Attribute*> attrList = theSource.GetAttributes();
01179   for(int i = 0, len = attrList.size(); i<len; i++) {
01180     DF_Attribute* anAttr = attrList[i];
01181     if (aTargetLabel.FindAttribute(anAttr->ID())) {
01182       aTargetLabel.ForgetAttribute(anAttr->ID());
01183     }
01184     DF_Attribute* aNewAttribute = anAttr->NewEmpty();
01185     aTargetLabel.AddAttribute(aNewAttribute);
01186     anAttr->Paste(aNewAttribute);
01187   }
01188 
01189   // check auxiliary label for Comment => reference or name attribute of the referenced object
01190   SALOMEDSImpl_AttributeComment* aCommentAttribute = NULL;
01191   if ((aCommentAttribute=(SALOMEDSImpl_AttributeComment*)aAuxSourceLabel.FindAttribute(SALOMEDSImpl_AttributeComment::GetID()))) {
01192     char * anEntry = new char[aCommentAttribute->Value().size() + 1];
01193     strcpy(anEntry, std::string(aCommentAttribute->Value()).c_str());
01194     char* aNameStart = strchr(anEntry, ' ');
01195     if (aNameStart) {
01196       *aNameStart = '\0';
01197       aNameStart++;
01198     }
01199     if (theCopiedStudyID == theDestinationStudy->StudyId()) { // if copy to the same study, reanimate reference
01200       DF_Label aRefLabel = DF_Label::Label(aTargetLabel, anEntry);
01201       SALOMEDSImpl_AttributeReference::Set(aTargetLabel, aRefLabel);
01202       // target attributes structure support
01203       SALOMEDSImpl_AttributeTarget::Set(aRefLabel)->Add(SALOMEDSImpl_Study::SObject(aTargetLabel));
01204     } else {
01205       if (aNameStart) SALOMEDSImpl_AttributeName::Set(aTargetLabel, aNameStart);
01206       else SALOMEDSImpl_AttributeName::Set(aTargetLabel, std::string("Reference to:")+anEntry);
01207     }
01208     delete [] anEntry;
01209   }
01210 
01211   return aTargetLabel;
01212 }
01213 
01214 //============================================================================
01218 //============================================================================
01219 SALOMEDSImpl_SObject SALOMEDSImpl_StudyManager::Paste(const SALOMEDSImpl_SObject& theObject,
01220                                                SALOMEDSImpl_Driver* theEngine)
01221 {
01222   _errorCode = "";
01223 
01224   SALOMEDSImpl_SObject so;
01225   SALOMEDSImpl_Study* aStudy = theObject.GetStudy();
01226 
01227   // if study is locked, then paste can't be done
01228   if (aStudy->GetProperties()->IsLocked()) {
01229     _errorCode = "LockProtection";
01230     throw LockProtection("LockProtection");
01231   }
01232 
01233   // if there is no component name, then paste only SObjects and attributes: without component help
01234   SALOMEDSImpl_AttributeComment* aComponentName = NULL;
01235   bool aStructureOnly = !(aComponentName=(SALOMEDSImpl_AttributeComment*)_clipboard->Main().Root().FindAttribute(SALOMEDSImpl_AttributeComment::GetID()));
01236 
01237   // get copied study ID
01238   SALOMEDSImpl_AttributeInteger* aStudyIDAttribute = NULL;
01239   if (!(aStudyIDAttribute=(SALOMEDSImpl_AttributeInteger*)_clipboard->Main().Root().FindAttribute(SALOMEDSImpl_AttributeInteger::GetID()))) {
01240     _errorCode = "No study ID was found";
01241     return so;
01242   }
01243   int aCStudyID = aStudyIDAttribute->Value();
01244 
01245   // CAF document of current study usage
01246   DF_Document* aDocument = GetDocumentOfStudy(aStudy);
01247   if (!aDocument) {
01248     _errorCode = "Document is null";
01249     return so;
01250   }
01251 
01252   SALOMEDSImpl_SComponent aComponent = theObject.GetFatherComponent();
01253 
01254   // fill root inserted SObject
01255   DF_Label aStartLabel;
01256   if (aStructureOnly) {
01257     DF_Label anObjectLabel = DF_Label::Label(aDocument->Main(), theObject.GetID());
01258     aStartLabel = PasteLabel(aStudy, theEngine, _clipboard->Main(), anObjectLabel, aCStudyID, false);
01259   } else {
01260     DF_Label aComponentLabel = DF_Label::Label(aDocument->Main(), aComponent.GetID());
01261     aStartLabel = PasteLabel(aStudy, theEngine, _clipboard->Main(), aComponentLabel, aCStudyID, true);
01262   }
01263 
01264   // paste all sublebels
01265   DF_ChildIterator anIterator(_clipboard->Main(), true);
01266   for(; anIterator.More(); anIterator.Next()) {
01267     PasteLabel(aStudy, theEngine, anIterator.Value(), aStartLabel, aCStudyID, false);
01268   }
01269 
01270   return SALOMEDSImpl_Study::SObject(aStartLabel);
01271 }
01272 
01273 //#######################################################################################################
01274 //#                                     STATIC PRIVATE FUNCTIONS
01275 //#######################################################################################################
01276 
01277 //============================================================================
01281 //============================================================================
01282 static void SaveAttributes(const SALOMEDSImpl_SObject& aSO, HDFgroup *hdf_group_sobject)
01283 {
01284   hdf_size size[1];
01285   std::vector<DF_Attribute*> attrList = aSO.GetLabel().GetAttributes();
01286   DF_Attribute* anAttr = NULL;
01287   for(int i = 0, len = attrList.size(); i<len; i++) {
01288     anAttr = attrList[i];
01289     //The following attributes are not supposed to be written to the file
01290     std::string type = SALOMEDSImpl_GenericAttribute::Impl_GetType(anAttr);
01291     if(type == std::string("AttributeIOR")) continue; //IOR attribute is not saved
01292     std::string aSaveStr =anAttr->Save();
01293     //cout << "Saving: " << aSO.GetID() << " type: "<< type<<"|" << endl;
01294     size[0] = (hdf_int32) strlen(aSaveStr.c_str()) + 1;
01295     HDFdataset *hdf_dataset = new HDFdataset((char*)type.c_str(), hdf_group_sobject, HDF_STRING,size, 1);
01296     hdf_dataset->CreateOnDisk();
01297     hdf_dataset->WriteOnDisk((char*)aSaveStr.c_str());
01298     hdf_dataset->CloseOnDisk();
01299     hdf_dataset=0; //will be deleted by hdf_sco_group destructor
01300   }
01301 }
01302 
01303 //===========================================================================
01304 //Function : ReadAttributes
01305 //===========================================================================
01306 static void ReadAttributes(SALOMEDSImpl_Study* theStudy,
01307                            const SALOMEDSImpl_SObject& aSO,
01308                            HDFdataset* hdf_dataset)
01309 {
01310   hdf_dataset->OpenOnDisk();
01311 
01312   DF_Attribute* anAttr = NULL;
01313   char* current_string = new char[hdf_dataset->GetSize()+1];
01314   hdf_dataset->ReadFromDisk(current_string);
01315   //cout << "Reading attr type = " << hdf_dataset->GetName() << "  SO = " << aSO.GetID() << endl;
01316   if (!strcmp(hdf_dataset->GetName(),"COMPONENTDATATYPE")) {
01317     anAttr = theStudy->NewBuilder()->FindOrCreateAttribute(aSO, "AttributeComment");
01318   } else if (!strcmp(hdf_dataset->GetName(),"AttributeReference") ||
01319              !strcmp(hdf_dataset->GetName(),"Reference")) { // Old format maintainance
01320     theStudy->NewBuilder()->Addreference(aSO, theStudy->CreateObjectID(current_string));
01321     delete [] (current_string);
01322     hdf_dataset->CloseOnDisk();
01323     return;
01324   } else {
01325     anAttr = theStudy->NewBuilder()->FindOrCreateAttribute(aSO, hdf_dataset->GetName());
01326   }
01327   
01328   if (anAttr) {
01329     anAttr->Load(current_string);
01330   }
01331   
01332   delete [] (current_string);
01333   hdf_dataset->CloseOnDisk();
01334 }
01335 
01336 //============================================================================
01337 //Function : BuildlTree
01338 //============================================================================
01339 static void BuildTree (SALOMEDSImpl_Study* theStudy, HDFgroup* hdf_current_group)
01340 {
01341   hdf_current_group->OpenOnDisk();
01342   SALOMEDSImpl_SObject aSO;
01343   char* Entry = hdf_current_group->GetName();
01344   if (strcmp(Entry,"STUDY_STRUCTURE") == 0) {
01345     aSO = theStudy->CreateObjectID("0:1");
01346   }
01347   else {
01348     aSO = theStudy->CreateObjectID(Entry);
01349   }
01350 
01351   char name[HDF_NAME_MAX_LEN+1];
01352   int nbsons = hdf_current_group->nInternalObjects();
01353   for (int i=0; i<nbsons; i++) {
01354     hdf_current_group->InternalObjectIndentify(i,name);
01355     if (strncmp(name, "INTERNAL_COMPLEX",16) == 0) continue;
01356     hdf_object_type type = hdf_current_group->InternalObjectType(name);
01357 
01358     if  (type == HDF_DATASET) {
01359       HDFdataset* new_dataset = new HDFdataset(name,hdf_current_group);
01360       ReadAttributes(theStudy,aSO,new_dataset);
01361       new_dataset = 0; // will be deleted by father destructor
01362 
01363     }
01364     else if (type == HDF_GROUP)   {
01365       HDFgroup* new_group = new HDFgroup(name,hdf_current_group);
01366       BuildTree (theStudy, new_group);
01367       new_group = 0; // will be deleted by father destructor
01368     }
01369   }
01370   hdf_current_group->CloseOnDisk();
01371 }
01372 
01373 
01374 //============================================================================
01375 //Function : Translate_IOR_to_persistentID
01376 //============================================================================
01377 static void Translate_IOR_to_persistentID (const SALOMEDSImpl_SObject& so,
01378                                            SALOMEDSImpl_Driver*                engine,
01379                                            bool                                isMultiFile,
01380                                            bool                                isASCII)
01381 {
01382   DF_ChildIterator itchild(so.GetLabel());
01383   std::string ior_string,  persistent_string, curid;
01384 
01385   for (; itchild.More(); itchild.Next()) {
01386     SALOMEDSImpl_SObject current = SALOMEDSImpl_Study::SObject(itchild.Value());
01387     SALOMEDSImpl_AttributeIOR* IOR = NULL;
01388     if ((IOR=(SALOMEDSImpl_AttributeIOR*)current.GetLabel().FindAttribute(SALOMEDSImpl_AttributeIOR::GetID()))) {
01389       ior_string = IOR->Value();
01390 
01391       persistent_string = engine->IORToLocalPersistentID (current, ior_string, isMultiFile, isASCII);
01392       SALOMEDSImpl_AttributePersistentRef::Set(current.GetLabel(), persistent_string);
01393     }
01394     Translate_IOR_to_persistentID (current, engine, isMultiFile, isASCII);
01395   }
01396 }
01397 
01398 void ReadNoteBookVariables(SALOMEDSImpl_Study* theStudy, HDFgroup* theGroup)
01399 {
01400   if(!theGroup)
01401     return;
01402 
01403   HDFgroup* new_group =0;
01404   HDFdataset* new_dataset =0;
01405   
01406   char aVarName[HDF_NAME_MAX_LEN+1];
01407   char *currentVarType = 0;
01408   char *currentVarValue = 0;
01409   char *currentVarIndex = 0;
01410   int order = 0;
01411   //Open HDF group with notebook variables
01412   theGroup->OpenOnDisk();
01413 
01414   //Get Nb of variables
01415   int aNbVars = theGroup->nInternalObjects();
01416 
01417   std::map<int,SALOMEDSImpl_GenericVariable*> aVarsMap;
01418 
01419   for( int iVar=0;iVar < aNbVars;iVar++ ) {
01420     theGroup->InternalObjectIndentify(iVar,aVarName);
01421     hdf_object_type type = theGroup->InternalObjectType(aVarName);
01422     if(type == HDF_GROUP) {
01423 
01424       //Read Variable
01425       new_group = new HDFgroup(aVarName,theGroup);
01426       new_group->OpenOnDisk();
01427 
01428       //Read Type
01429       new_dataset = new HDFdataset("VARIABLE_TYPE",new_group);
01430       new_dataset->OpenOnDisk();
01431       currentVarType = new char[new_dataset->GetSize()+1];
01432       new_dataset->ReadFromDisk(currentVarType);
01433       new_dataset->CloseOnDisk();
01434       new_dataset = 0; //will be deleted by hdf_sco_group destructor
01435 
01436       //Read Order
01437       if(new_group->ExistInternalObject("VARIABLE_INDEX")) {
01438         new_dataset = new HDFdataset("VARIABLE_INDEX",new_group);
01439         new_dataset->OpenOnDisk();
01440         currentVarIndex = new char[new_dataset->GetSize()+1];
01441         new_dataset->ReadFromDisk(currentVarIndex);
01442         new_dataset->CloseOnDisk();
01443         new_dataset = 0; //will be deleted by hdf_sco_group destructor
01444         order = atoi(currentVarIndex);
01445         delete [] currentVarIndex;
01446       }
01447       else
01448         order = iVar;
01449       
01450       //Read Value
01451       new_dataset = new HDFdataset("VARIABLE_VALUE",new_group);
01452       new_dataset->OpenOnDisk();
01453       currentVarValue = new char[new_dataset->GetSize()+1];
01454       new_dataset->ReadFromDisk(currentVarValue);
01455       new_dataset->CloseOnDisk();
01456       new_dataset = 0; //will be deleted by hdf_sco_group destructor
01457 
01458       new_group->CloseOnDisk();
01459       new_group = 0;  //will be deleted by hdf_sco_group destructor
01460       
01461       SALOMEDSImpl_GenericVariable::VariableTypes aVarType =
01462         SALOMEDSImpl_GenericVariable::String2VariableType(std::string(currentVarType));
01463       delete [] currentVarType;
01464 
01465       //Create variable and add it in the study
01466       SALOMEDSImpl_GenericVariable* aVariable = 
01467         new SALOMEDSImpl_ScalarVariable(aVarType,std::string(aVarName));
01468       aVariable->Load(std::string(currentVarValue));
01469          aVarsMap.insert(std::make_pair<int,SALOMEDSImpl_GenericVariable*>(order,aVariable));
01470       delete [] currentVarValue;
01471        }
01472   }
01473   
01474   std::map<int,SALOMEDSImpl_GenericVariable*>::const_iterator it= aVarsMap.begin();
01475   for(;it!=aVarsMap.end();it++)
01476     theStudy->AddVariable((*it).second);
01477   
01478   theGroup->CloseOnDisk();
01479 }