Back to index

salome-med  6.5.0
Med_Gen_Driver_i.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 //  MED MED : implemetation of MED idl descriptions
00024 //  File   : Med_Gen_Driver_i.cxx
00025 //  Author : Paul RASCLE, EDF
00026 //  Module : MED
00027 //
00028 #include "Med_Gen_Driver_i.hxx"
00029 
00030 #include "MEDMEM_Mesh_i.hxx"
00031 #include "MEDMEM_Med_i.hxx"
00032 #include "MEDMEM_FieldTemplate_i.hxx"
00033 #include "MEDMEM_Support_i.hxx"
00034 
00035 #include "MEDMEM_Mesh.hxx"
00036 #include "MEDMEM_Field.hxx"
00037 #include "MEDMEM_MedMeshDriver.hxx"
00038 #include "MEDMEM_MedFieldDriver.hxx"
00039 #include "MEDMEM_define.hxx"
00040 #include "MEDMEM_DriversDef.hxx"
00041 
00042 
00043 #include "Utils_SINGLETON.hxx"
00044 #include "OpUtil.hxx"
00045 #include "Utils_CorbaException.hxx"
00046 #include "utilities.h"
00047 
00048 #include "SALOMEDS_Tool.hxx"
00049 
00050 #include <string>
00051 #include <map>
00052 
00053 #include <HDFascii.hxx>
00054 
00055 using namespace MEDMEM;
00056 
00057 // Initialisation des variables statiques
00058 map<string, MEDMEM::MED_i*> Med_Gen_Driver_i::_MedCorbaObj;
00059 
00060 //=============================================================================
00064 //=============================================================================
00065 Med_Gen_Driver_i::Med_Gen_Driver_i()
00066 {
00067   MESSAGE("Med_Gen_Driver_i::Med_Gen_Driver_i");
00068 }
00069 
00070 //=============================================================================
00074 //=============================================================================
00075 Med_Gen_Driver_i::Med_Gen_Driver_i(CORBA::ORB_ptr orb)
00076 {
00077   MESSAGE("activate object");
00078   _driver_orb = CORBA::ORB::_duplicate(orb);
00079 
00080   // get a NamingService interface
00081   _NS = SINGLETON_<SALOME_NamingService>::Instance();
00082   ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting());
00083   _NS->init_orb( _driver_orb );
00084 }
00085 
00086 //=============================================================================
00090 //=============================================================================
00091 Med_Gen_Driver_i::~Med_Gen_Driver_i()
00092 {
00093   MESSAGE("Med_Gen_Driver_i::~Med_Gen_Driver_i");
00094 }
00095 
00096 //=============================================================================
00102 //=============================================================================
00103 MEDMEM::MED_i* Med_Gen_Driver_i::GetMED(SALOMEDS::SComponent_ptr theComponent)
00104 {
00105   // we have a separate MED_i for each component in a study
00106   SALOMEDS::Study_var study = theComponent->GetStudy();
00107   ostringstream os;
00108   os << study->StudyId() << "_" << theComponent->Tag();
00109   string mapKey = os.str();
00110 
00111   MED_i* med_i;
00112   map <string, MEDMEM::MED_i*>::iterator id_med;
00113   id_med = _MedCorbaObj.find( mapKey );
00114   if ( id_med == _MedCorbaObj.end() )
00115     _MedCorbaObj[ mapKey ] = med_i = new MED_i();
00116   else
00117     med_i = id_med->second;
00118   return med_i;
00119 }
00120 
00121 //=============================================================================
00125 //=============================================================================
00126 namespace {
00127 
00128   // names to use instead of true and false
00129   enum { SAVE = 1, RESTORE = 0, ASCII = 1, NON_ASCII = 0 };
00130 
00131   //================================================================================
00140   //================================================================================
00141   pair<string,string> getPersistanceDirAndFileName(SALOMEDS::SComponent_ptr theComponent,
00142                                                    const char*              theURL,
00143                                                    const bool               isMultiFile,
00144                                                    const bool               isSave)
00145   {
00146     string path, file;
00147     CORBA::String_var compName = theComponent->ComponentDataType();
00148     if (isMultiFile) {
00149       // file constantly holding data
00150       path = theURL;
00151       SALOMEDS::Study_var study = theComponent->GetStudy();
00152       file = SALOMEDS_Tool::GetNameFromPath( study->URL() );
00153       file += string( "_" ) + string( compName ) + ".med";
00154     }
00155     else {
00156       // temporary file
00157       path = SALOMEDS_Tool::GetTmpDir();
00158       if ( strcmp( "MED", compName ) != 0 )
00159         file = string( compName ) + "_"; // not MED
00160       file += "tmp.med";
00161     }
00162     return make_pair ( path, file );
00163   }
00164 
00165   //================================================================================
00174   //================================================================================
00175   SALOMEDS::TMPFile* saveStudy (SALOMEDS::SComponent_ptr theComponent,
00176                                 const char*              theURL,
00177                                 bool                     isMultiFile,
00178                                 bool                     isAscii)
00179   {
00180     // Write all MEDMEM objects in one med file because of problems with
00181     // reference to external mesh when writting field in a separate file.
00182     // Actually, writting is OK, but when reading a field, its support
00183     // is updated using mesh data missing in the file being read
00184 
00185     // If arises a problem of meshes or other objects having equal names,
00186     // the solution can be in renaming them using study entry before writting
00187     // and renaming back during restoration, real names will be stored in
00188     // LocalPersistentID's for example
00189 
00190     if (CORBA::is_nil(theComponent)) {
00191       SALOMEDS::TMPFile_var aStreamFile;
00192       return aStreamFile._retn();
00193     }
00194 
00195     SALOMEDS::Study_var study = theComponent->GetStudy();
00196 
00197     pair<string,string> aDir_aFileName =
00198       getPersistanceDirAndFileName(theComponent, theURL, isMultiFile, SAVE );
00199     string& aPath     = aDir_aFileName.first;
00200     string& aBaseName = aDir_aFileName.second;
00201     string aFile      = aPath + aBaseName;
00202 
00203     SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
00204     aSeq->length(1);
00205     aSeq[0] = CORBA::string_dup(aBaseName.c_str());
00206 
00207     if (isMultiFile) { // remove existing file
00208       //cout << "-----------------Remove " << aPath<< ", "<<aBaseName << endl;
00209       SALOMEDS_Tool::RemoveTemporaryFiles(aPath.c_str(), aSeq.in(), true);
00210     }
00211 
00212     // First save fields and their meshes and then not saved meshes
00213 
00214     set< ::MEDMEM::GMESH* > savedMeshes;
00215     {
00216       SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(theComponent);
00217       anIter->InitEx(1);
00218       for (; anIter->More(); anIter->Next()) {
00219         SALOMEDS::SObject_var aSO = anIter->Value();
00220         SALOME_MED::FIELD_var myField = SALOME_MED::FIELD::_narrow( aSO->GetObject() );
00221         if (! CORBA::is_nil(myField)) {
00222           long driverId = myField->addDriver(SALOME_MED::MED_DRIVER,
00223                                              aFile.c_str(),
00224                                              myField->getName());
00225           myField->write(driverId,"");
00226           // save mesh
00227           SALOME_MED::SUPPORT_var sup = myField->getSupport();
00228           if ( !sup->_is_nil() ) {
00229             SALOME_MED::GMESH_var mesh = sup->getMesh();
00230             if ( !mesh->_is_nil() ) {
00231               CORBA::Long corbaID = mesh->getCorbaIndex();
00232               ::MEDMEM::GMESH* gmesh = GMESH_i::meshMap[ int(corbaID) ];
00233               if ( savedMeshes.insert( gmesh ).second ) {
00234                 long driverId = mesh->addDriver(SALOME_MED::MED_DRIVER,
00235                                                 aFile.c_str(),
00236                                                 mesh->getName());
00237                 mesh->write(driverId,"");
00238               }
00239             }
00240           }
00241         }
00242       }
00243     }
00244 
00245     {
00246       SALOMEDS::ChildIterator_var anIter = study->NewChildIterator(theComponent);
00247       anIter->InitEx(1);
00248       for (; anIter->More(); anIter->Next()) {
00249         SALOMEDS::SObject_var aSO = anIter->Value();
00250         SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow( aSO->GetObject() );
00251         if (! CORBA::is_nil(myMesh)) {
00252           CORBA::Long corbaID = myMesh->getCorbaIndex();
00253           ::MEDMEM::GMESH* gmesh = GMESH_i::meshMap[ int(corbaID) ];
00254           if ( savedMeshes.insert( gmesh ).second ) {
00255             long driverId = myMesh->addDriver(SALOME_MED::MED_DRIVER,
00256                                               aFile.c_str(),
00257                                               myMesh->getName());
00258             myMesh->write(driverId,"");
00259           }
00260         }
00261       }
00262     }
00263 
00264     if ( isAscii )
00265       HDFascii::ConvertFromHDFToASCII( aFile.c_str(), true);
00266 
00267     // Convert a file to the byte stream
00268     SALOMEDS::TMPFile_var aStreamFile;
00269     aStreamFile = SALOMEDS_Tool::PutFilesToStream(aPath.c_str(), aSeq.in(), isMultiFile);
00270 
00271     // Remove a tmp file and directory
00272     if (!isMultiFile) {
00273       //cout << "-----------------Remove " << aPath<< ", "<<aBaseName << endl;
00274       SALOMEDS_Tool::RemoveTemporaryFiles(aPath.c_str(), aSeq.in(), true);
00275     }
00276     // Return the created byte stream
00277     return aStreamFile._retn();
00278   } // end of saveStudy()
00279 
00280   //================================================================================
00289   //================================================================================
00290   void loadStudy (SALOMEDS::SComponent_ptr theComponent,
00291                   const SALOMEDS::TMPFile& theStream,
00292                   const char*              theURL,
00293                   CORBA::Boolean           isMultiFile,
00294                   CORBA::Boolean           isASCII)
00295   {
00296     SALOMEDS::Study_var study = theComponent->GetStudy();
00297 
00298     // Get file name
00299     pair<string,string> aDir_aFileName = getPersistanceDirAndFileName
00300       (theComponent, theURL, isMultiFile, RESTORE);
00301     string& aPath     = aDir_aFileName.first;
00302     string& aBaseName = aDir_aFileName.second;
00303     string aFile      = aPath + aBaseName;
00304 
00305     SALOMEDS::ListOfFileNames_var aSeq =
00306       SALOMEDS_Tool::PutStreamToFiles(theStream, aPath.c_str(), isMultiFile);
00307 
00308     string aASCIIPath, aASCIIFile;
00309     if (isASCII)
00310     {
00311       aASCIIPath = HDFascii::ConvertFromASCIIToHDF(aFile.c_str());
00312       aASCIIFile = "hdf_from_ascii.hdf";
00313       aFile = aASCIIPath + aASCIIFile;
00314     }
00315 
00316     MED_i* med_i = Med_Gen_Driver_i::GetMED(theComponent);
00317     SALOME_MED::MED_var med = med_i->_this();
00318 
00319     // Read all meshes with supports and all fields
00320     try
00321     {
00322       //cout << "-----------------Filename " << aFile << endl;
00323       med_i->initWithFieldType(study, MED_DRIVER, aFile, true);
00324 
00325       // publishing must be done by initWithFieldType according to <persistence> flag
00326       med_i->addInStudy(study, med, theComponent, 0);
00327     }
00328     catch (const std::exception & ex)
00329     {
00330       MESSAGE("Exception Interceptee : ");
00331       SCRUTE(ex.what());
00332       THROW_SALOME_CORBA_EXCEPTION("Unable to read a hdf file",SALOME::BAD_PARAM);
00333     }
00334 
00335     // Remove tmp files
00336     bool keepTmpFiles = getenv( "MEDPERSIST_KEEP_TMP_FILES" ); // DEBUG
00337     if ( keepTmpFiles )
00338       cout << "TMP FILE: " << aFile << endl;
00339     if ( !isMultiFile && !keepTmpFiles ) {
00340       aSeq->length(1);
00341       aSeq[0]=CORBA::string_dup(aBaseName.c_str());
00342       SALOMEDS_Tool::RemoveTemporaryFiles(aPath.c_str(), aSeq.in(), true);
00343     }
00344     if (isASCII)
00345     {
00346       aSeq->length(1);
00347       aSeq[0] = CORBA::string_dup(aASCIIFile.c_str());
00348       //cout << "-----------------Remove " << aASCIIPath<< ", "<<aASCIIFile << endl;
00349       SALOMEDS_Tool::RemoveTemporaryFiles(aASCIIPath.c_str(), aSeq, true);
00350     }
00351   } // end loadStudy()
00352 
00353   //================================================================================
00361   //================================================================================
00362   void getFieldNameAndDtIt (const char*   aLocalPersistentID,
00363                             string &      aFieldName,
00364                             CORBA::Long & aNumOrdre,
00365                             CORBA::Long & anIterNumber)
00366   {
00367     //     aLocalPersistentID(("_MEDFIELD_"+ myField->getName() +
00368     //                       "_ORDRE_"+a.str()+
00369     //                       "_ITER_"+b.str()+".med"
00370     int aLPIdLen = strlen(aLocalPersistentID);
00371     const int _MEDFIELD_Len = strlen("_MEDFIELD_");
00372     const int _ORDRE_Len    = strlen("_ORDRE_");
00373     const int _ITER_Len     = strlen("_ITER_");
00374 
00375     // Get field name: look for _ORDRE_ in aLocalPersistentID
00376     int aFieldNameLen = 0, aFieldNameBeg = _MEDFIELD_Len, _ORDRE_Beg;
00377     for ( _ORDRE_Beg = aFieldNameBeg; _ORDRE_Beg < aLPIdLen; ++aFieldNameLen,++_ORDRE_Beg )
00378       if ( strncmp( &aLocalPersistentID[ _ORDRE_Beg ], "_ORDRE_", _ORDRE_Len ) == 0 )
00379         break;
00380     aFieldName = string( &(aLocalPersistentID[aFieldNameBeg]), aFieldNameLen);
00381 
00382     // Get orderNumber
00383     int anOrderNumberBeg = _ORDRE_Beg + _ORDRE_Len;
00384     aNumOrdre = atoi( & aLocalPersistentID[ anOrderNumberBeg ]);
00385 
00386     // Get iterationNumber: look for _ITER_ in aLocalPersistentID
00387     int _ITER_Beg = anOrderNumberBeg;
00388     for ( ; _ITER_Beg < aLPIdLen; ++_ITER_Beg )
00389       if ( strncmp( &aLocalPersistentID[ _ITER_Beg ], "_ITER_", _ITER_Len ) == 0 )
00390         break;
00391     anIterNumber = atoi( & aLocalPersistentID[ _ITER_Beg + _ITER_Len ]);
00392   }
00393 
00394   //================================================================================
00404   //================================================================================
00405   bool getSupportData (string aLocalPersistentID,
00406                        string & type,
00407                        string & name,
00408                        string & mesh,
00409                        string & entity)
00410   {
00411     // aLocalPersistentID contains:
00412     // _MED_[FAMILY|GROUP|SUPPORT]/support_name/ENS_MAA/mesh_name/ENTITY/entity
00413     string::size_type slash1Pos = aLocalPersistentID.find("/");
00414     if ( slash1Pos == aLocalPersistentID.npos ) return false;
00415     string::size_type ens_maaPos = aLocalPersistentID.find("/ENS_MAA/", slash1Pos);
00416     if ( ens_maaPos == aLocalPersistentID.npos ) return false;
00417     string::size_type entityPos = aLocalPersistentID.find("/ENTITY/", ens_maaPos);
00418     if ( entityPos == aLocalPersistentID.npos ) return false;
00419 
00420     string::size_type medSize = strlen("_MED_");
00421     string::size_type ens_maaSize = strlen("/ENS_MAA/");
00422     string::size_type entitySize = strlen("/ENTITY/");
00423 
00424     type = aLocalPersistentID.substr( medSize, slash1Pos - medSize );
00425     name = aLocalPersistentID.substr( slash1Pos + 1, ens_maaPos - slash1Pos - 1);
00426     mesh = aLocalPersistentID.substr( ens_maaPos + ens_maaSize,
00427                                       entityPos - ens_maaPos - ens_maaSize);
00428     entity = aLocalPersistentID.substr( entityPos + entitySize );
00429 //     cout << aLocalPersistentID << endl
00430 //          << " type: " << type
00431 //          << " name: " << name
00432 //          << " mesh: " << mesh
00433 //          << " entity: " << entity << endl;
00434     return true;
00435   }
00436 } // no name namespace
00437 
00438 //================================================================================
00446 //================================================================================
00447 SALOMEDS::TMPFile* Med_Gen_Driver_i::Save (SALOMEDS::SComponent_ptr theComponent,
00448                                            const char* theURL,
00449                                            bool isMultiFile)
00450 {
00451   return saveStudy ( theComponent, theURL, isMultiFile, NON_ASCII );
00452 }
00453 
00454 //================================================================================
00462 //================================================================================
00463 SALOMEDS::TMPFile* Med_Gen_Driver_i::SaveASCII (SALOMEDS::SComponent_ptr theComponent,
00464                                                 const char* theURL,
00465                                                 bool isMultiFile)
00466 {
00467   return saveStudy ( theComponent, theURL, isMultiFile, ASCII );
00468 }
00469 
00470 //=============================================================================
00474 //=============================================================================
00475 
00476 CORBA::Boolean Med_Gen_Driver_i::Load (SALOMEDS::SComponent_ptr theComponent,
00477                                        const SALOMEDS::TMPFile& theStream,
00478                                        const char* theURL,
00479                                        bool isMultiFile)
00480 {
00481   loadStudy ( theComponent, theStream, theURL, isMultiFile, NON_ASCII );
00482 
00483   return true;
00484 }
00485 
00486 CORBA::Boolean Med_Gen_Driver_i::LoadASCII (SALOMEDS::SComponent_ptr theComponent,
00487                                             const SALOMEDS::TMPFile& theStream,
00488                                             const char* theURL,
00489                                             bool isMultiFile)
00490 {
00491   loadStudy ( theComponent, theStream, theURL, isMultiFile, ASCII );
00492   return true;
00493 }
00494 
00495 //=============================================================================
00499 //=============================================================================
00500 void Med_Gen_Driver_i::Close (SALOMEDS::SComponent_ptr theComponent)
00501 {
00502   MESSAGE("Med_Gen_Driver_i::Close");
00503   SALOMEDS::SObject_var aMedMeshFather = theComponent->GetStudy()->FindObject("MEDMESH");
00504   if (!CORBA::is_nil(aMedMeshFather)) {
00505     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedMeshFather);
00506     for(; anIter->More(); anIter->Next()) {
00507       SALOMEDS::SObject_var aSO = anIter->Value();
00508       SALOMEDS::GenericAttribute_var anAttr;
00509       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
00510         CORBA::Object_var myIOR =
00511           _driver_orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
00512         SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
00513         // here must call method destroy of myMesh, but it not implemented yet
00514       }
00515     }
00516   }
00517 }
00518 
00519 //=============================================================================
00523 //=============================================================================
00524 char* Med_Gen_Driver_i::IORToLocalPersistentID (SALOMEDS::SObject_ptr theSObject,
00525                                                 const char* IORString,
00526                                                 CORBA::Boolean isMultiFile,
00527                                                 CORBA::Boolean isASCII)
00528 {
00529   SCRUTE(IORString);
00530 
00531   if (string(IORString).size()==0) return CORBA::string_dup("_MED");
00532   // Well, we know where put object (_saveFilename) and we know object (IORString)
00533   // cast object :
00534   CORBA::Object_var myIOR = _driver_orb->string_to_object(IORString);
00535 
00536   // MED
00537   SALOME_MED::MED_var myMed = SALOME_MED::MED::_narrow(myIOR);
00538   if (! CORBA::is_nil(myMed))
00539   {
00540     string str_MedName="_MED Objet Med + /OBJ_MED/";
00541     return CORBA::string_dup(str_MedName.c_str());
00542   }
00543 
00544   // MESH
00545   SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
00546   if (! CORBA::is_nil(myMesh))
00547   {
00548     CORBA::String_var aName((string("_MEDMESH_")+ myMesh->getName() + ".med").c_str());
00549     return aName._retn();
00550   }
00551 
00552   // SUPPORT
00553   SALOME_MED::SUPPORT_var mySupport = SALOME_MED::SUPPORT::_narrow(myIOR);
00554   if (! CORBA::is_nil(mySupport))
00555   {
00556     string type, str_SupportName;
00557     SALOME_MED::FAMILY_var family = SALOME_MED::FAMILY::_narrow(myIOR);
00558     if ( !family->_is_nil() )
00559       type = "_MED_FAMILY";
00560     else {
00561       SALOME_MED::GROUP_var grp = SALOME_MED::GROUP::_narrow(myIOR);
00562       if ( !grp->_is_nil() )
00563         type = "_MED_GROUP";
00564       else
00565         type = "_MED_SUPPORT";
00566     }
00567     try  {
00568       ostringstream os;
00569       os << type << "/" << mySupport->getName();
00570       os << "/ENS_MAA/" << mySupport->getMesh()->getName();
00571       os << "/ENTITY/" << mySupport->getEntity();
00572       str_SupportName = os.str();
00573     }
00574     catch(...) {
00575       MESSAGE("Unable to save the support");
00576       THROW_SALOME_CORBA_EXCEPTION("Unable to save Field in Med"\
00577                                    ,SALOME::INTERNAL_ERROR);
00578     }
00579     return CORBA::string_dup(str_SupportName.c_str());
00580   }
00581 
00582   SALOME_MED::FIELD_var myField = SALOME_MED::FIELD::_narrow(myIOR);
00583   if (! CORBA::is_nil(myField))
00584   {
00585     string str_FieldName;
00586     ostringstream a,b;
00587     a<< myField->getOrderNumber();
00588     b<< myField->getIterationNumber();
00589     CORBA::String_var aName((string("_MEDFIELD_")+ myField->getName() +
00590                              string("_ORDRE_")+a.str()+
00591                              string("_ITER_")+b.str() +
00592                              ".med").c_str());
00593     return aName._retn();
00594   }
00595 
00596   //THROW_SALOME_CORBA_EXCEPTION("Unable to save IOR",SALOME::BAD_PARAM);
00597   return CORBA::string_dup("_MED");
00598 }
00599 
00600 //=============================================================================
00604 //=============================================================================
00605 char* Med_Gen_Driver_i::LocalPersistentIDToIOR (SALOMEDS::SObject_ptr theSObject,
00606                                                 const char* aLocalPersistentID,
00607                                                 CORBA::Boolean isMultiFile,
00608                                                 CORBA::Boolean isASCII)
00609   throw(SALOME::SALOME_Exception)
00610 {
00611   // all object are restored in Load() if their name in study coincides
00612   // with a default one generated by object.addInStudy(...)
00613   CORBA::String_var ior = theSObject->GetIOR();
00614   bool restoredByLoad = ( ior.in() && strlen( ior ) > 0 );
00615 
00616   if ( !restoredByLoad )
00617   {
00618     CORBA::Object_var object;
00619     SALOMEDS::SComponent_var component = theSObject->GetFatherComponent();
00620     MED_i* med_i = Med_Gen_Driver_i::GetMED(component);
00621     SALOME_MED::MED_var med = med_i->_this();
00622 
00623     // MED
00624     if (strcmp(aLocalPersistentID, "_MED Objet Med + /OBJ_MED/") == 0)
00625     {
00626       //object = med;
00627       object = SALOME_MED::MED::_duplicate(med);
00628     }
00629     // MESH
00630     else if (strncmp(aLocalPersistentID, "_MEDMESH_",9) == 0)
00631     {
00632       int aMeshNameLen = strlen(aLocalPersistentID) - 12;
00633       string aMeshName( &(aLocalPersistentID[9]), aMeshNameLen);
00634       aMeshName[aMeshNameLen-1] = 0;
00635       try {
00636         object = med->getMeshByName( aMeshName.c_str() );
00637         if ( CORBA::is_nil( object )) {
00638           aMeshName = healName( aMeshName );
00639           object = med->getMeshByName( aMeshName.c_str() );
00640         }
00641       }
00642       catch (const std::exception & ex) {
00643         SCRUTE(ex.what());
00644         THROW_SALOME_CORBA_EXCEPTION("Unable to find a mesh by name in this file",
00645                                      SALOME::INTERNAL_ERROR);
00646       }
00647     }
00648     // FIELD
00649     else if (strncmp(aLocalPersistentID, "_MEDFIELD_",10) == 0)
00650     {
00651       // Field Name
00652       string aFieldName;
00653       CORBA::Long aNumOrdre, anIterNumber;
00654       getFieldNameAndDtIt( aLocalPersistentID, aFieldName, aNumOrdre, anIterNumber );
00655       // Get a field that is already read
00656       try {
00657         object = med->getField( aFieldName.c_str(), anIterNumber, aNumOrdre );
00658         if ( CORBA::is_nil( object )) {
00659           aFieldName = healName( aFieldName );
00660           object = med->getField( aFieldName.c_str(), anIterNumber, aNumOrdre );
00661         }
00662       }
00663       catch (const std::exception & ex) {
00664         SCRUTE(ex.what());
00665         THROW_SALOME_CORBA_EXCEPTION("Unable to find a field by name in this file",
00666                                      SALOME::INTERNAL_ERROR);
00667       }
00668     }
00669     // SUPPORT?
00670     else {
00671       string type, name, meshName, entity;
00672       if ( getSupportData( aLocalPersistentID, type, name, meshName, entity ))
00673       {
00674         MED_EN::medEntityMesh medEntity( atoi( entity.c_str() ));
00675 
00676         if ( type == "SUPPORT" ) {
00677           try {
00678             object = med_i->getSupport( meshName, medEntity );
00679             if ( CORBA::is_nil( object )) {
00680               meshName = healName( meshName );
00681               object = med_i->getSupport( meshName, medEntity );
00682             }
00683           }
00684           catch (const std::exception & ex) {
00685             SCRUTE(ex.what());
00686             THROW_SALOME_CORBA_EXCEPTION("Unable to find support in this file",
00687                                          SALOME::INTERNAL_ERROR);
00688           }
00689         }
00690         else {
00691           SALOME_MED::GMESH_var mesh;
00692           try {
00693             mesh = med->getMeshByName( meshName.c_str() );
00694             if ( mesh->_is_nil() ) {
00695               meshName = healName( meshName );
00696               mesh = med->getMeshByName( meshName.c_str() );
00697             }
00698           }
00699           catch (const std::exception & ex) {
00700             SCRUTE(ex.what());
00701             THROW_SALOME_CORBA_EXCEPTION("Unable to find mesh in this file",
00702                                          SALOME::INTERNAL_ERROR);
00703           }
00704           if ( !mesh->_is_nil() ) {
00705             string healedName = healName( name );
00706             try {
00707               if ( type == "FAMILY" ) {
00708                 SALOME_MED::Family_array_var families = mesh->getFamilies( medEntity );
00709                 for ( int i = 0; CORBA::is_nil(object) && i <= (int)families->length(); ++i )
00710                   if ( families[ i ]->getName() == name ||
00711                        families[ i ]->getName() == healedName )
00712                     object = SALOME_MED::FAMILY::_duplicate( families[ i ]);
00713               }
00714               else {
00715                 SALOME_MED::Group_array_var groups = mesh->getGroups( medEntity );
00716                 for ( int i = 0; CORBA::is_nil(object) && i <= (int)groups->length(); ++i )
00717                   if ( groups[ i ]->getName() == name ||
00718                        groups[ i ]->getName() == healedName )
00719                     object = SALOME_MED::GROUP::_duplicate( groups[ i ]);
00720               }
00721             }
00722             catch (const std::exception & ex) {
00723               SCRUTE(ex.what());
00724               THROW_SALOME_CORBA_EXCEPTION("Unable to find support in this file",
00725                                            SALOME::INTERNAL_ERROR);
00726             }
00727           }
00728         }
00729       }
00730     }
00731     if ( !CORBA::is_nil(object) )
00732       ior = _driver_orb->object_to_string( object );
00733     else
00734       THROW_SALOME_CORBA_EXCEPTION("Unable to find the object in this file",
00735                                    SALOME::INTERNAL_ERROR);
00736 
00737   } // !restoredByLoad
00738 
00739   return ior._retn();
00740 }
00741 
00742 //=============================================================================
00746 //=============================================================================
00747 bool Med_Gen_Driver_i::CanPublishInStudy (CORBA::Object_ptr theIOR)
00748 {
00749   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(theIOR);
00750   if ( !aMesh->_is_nil())
00751     return true;
00752   SALOME_MED::FIELD_var aField = SALOME_MED::FIELD::_narrow(theIOR);
00753   if ( !aField->_is_nil())
00754     return true;
00755   //SALOME_MED::SUPPORT_var aSupport = SALOME_MED::SUPPORT::_narrow(theIOR);
00756   //if ( !aSupport->_is_nil())
00757   //  return true;
00758   return false;
00759 }
00760 
00761 //=============================================================================
00765 //=============================================================================
00766 SALOMEDS::SObject_ptr Med_Gen_Driver_i::PublishInStudy (SALOMEDS::Study_ptr theStudy,
00767                                                         SALOMEDS::SObject_ptr theSObject,
00768                                                         CORBA::Object_ptr theObject,
00769                                                         const char* theName)
00770   throw (SALOME::SALOME_Exception)
00771 {
00772   SALOMEDS::SObject_var aResultSO;
00773 
00774   if (CORBA::is_nil(theObject)) return aResultSO;
00775   if (theStudy->_is_nil()) return aResultSO;
00776 
00777   SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
00778   SALOMEDS::SComponent_var aFather = theStudy->FindComponent(ComponentDataType());
00779 
00780   if (aFather->_is_nil()) {
00781     aFather = aBuilder->NewComponent(ComponentDataType());
00782     if (aFather->_is_nil()) return aResultSO;
00783 
00784     SALOMEDS::GenericAttribute_var anAttr = aBuilder->FindOrCreateAttribute(aFather, "AttributeName");
00785     SALOMEDS::AttributeName_var    aName = SALOMEDS::AttributeName::_narrow(anAttr);
00786     //NRI    aName->SetValue("MED");
00787 
00788     CORBA::Object_var objVarN = _NS->Resolve("/Kernel/ModulCatalog");
00789     SALOME_ModuleCatalog::ModuleCatalog_var Catalogue =
00790       SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
00791     SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent(ComponentDataType());
00792     if (!Comp->_is_nil()) {
00793       aName->SetValue(Comp->componentusername());
00794     }
00795 
00796     aBuilder->DefineComponentInstance(aFather, GetComponentInstance());
00797   }
00798 
00799   if (CORBA::is_nil(theSObject)) {
00800     SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(theObject);
00801     if (!aMesh->_is_nil()) {
00802       aMesh->addInStudy(theStudy, aMesh);
00803     }
00804     else {
00805       SALOME_MED::FIELD_var aField = SALOME_MED::FIELD::_narrow(theObject);
00806       if (!aField->_is_nil()) {
00807         aField->addInStudyToComponent(aFather, aField);
00808       }
00809       //else {
00810       //  SALOME_MED::SUPPORT_var aSupport = SALOME_MED::SUPPORT::_narrow(theObject);
00811       //  if (!aSupport->_is_nil())
00812       //    aSupport->addInStudy(theStudy, aSupport);
00813       //}
00814     }
00815     aResultSO = theStudy->FindObjectIOR(_driver_orb->object_to_string(theObject));
00816   } else {
00817     //if (!theSObject->ReferencedObject(aResultSO))
00818     //  THROW_SALOME_CORBA_EXCEPTION("Publish in study MED object error",SALOME::BAD_PARAM);
00819   }
00820   //aBuilder->Addreference(theObject, aResultSO);
00821   return aResultSO._retn();
00822 }
00823 
00824 //=============================================================================
00828 //=============================================================================
00829 CORBA::Boolean Med_Gen_Driver_i::CanCopy (SALOMEDS::SObject_ptr theObject)
00830 {
00831   // Try to retrieve known by MED component mesh by given IOR
00832   SALOMEDS::GenericAttribute_var anAttr;
00833   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
00834   try {
00835     CORBA::Object_var anObj =
00836       _driver_orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
00837     SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
00838     // If the object is null one it can't be copied: return false
00839     if (aMesh->_is_nil()) return false;
00840   } catch(...) {
00841     return false;
00842   }
00843   return true;
00844 }
00845 
00846 //=============================================================================
00850 //=============================================================================
00851 SALOMEDS::TMPFile* Med_Gen_Driver_i::CopyFrom (SALOMEDS::SObject_ptr theObject,
00852                                                CORBA::Long& theObjectID)
00853 {
00854   // Declare a sequence of the byte to store the copied object
00855   SALOMEDS::TMPFile_var aStreamFile;
00856 
00857   // Try to get GEOM_Shape object by given SObject
00858   SALOMEDS::GenericAttribute_var anAttr;
00859   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return new SALOMEDS::TMPFile(0);
00860   CORBA::String_var anIOR = CORBA::string_dup(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
00861   CORBA::Object_var anObj = _driver_orb->string_to_object(anIOR);
00862   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
00863   if (aMesh->_is_nil()) return new SALOMEDS::TMPFile(0);
00864 
00865   // Get a temporary directory to store a temporary file
00866   CORBA::String_var aTmpDir = SALOMEDS_Tool::GetTmpDir().c_str();
00867   // Create a list to store names of created files
00868   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
00869   aSeq->length(1);
00870   aSeq[0] = CORBA::string_dup(aMesh->getName());
00871   char* aFullName = new char[strlen(aTmpDir)+strlen(aSeq[0])+1];
00872   strcpy(aFullName, aTmpDir);
00873   strcpy(aFullName+strlen(aTmpDir), aSeq[0]);
00874 
00875   long driverId = aMesh->addDriver(SALOME_MED::MED_DRIVER,aFullName , aMesh->getName());
00876   aMesh->write(driverId,"");
00877 
00878   //  aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.c_str(), aSeq.in(), false);
00879   char* aFullName1 = new char[strlen(aTmpDir)+1];
00880   strcpy(aFullName1, aTmpDir);
00881   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aFullName1, aSeq.in(), false);
00882   //  SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
00883   SALOMEDS_Tool::RemoveTemporaryFiles(aFullName1, aSeq.in(), true);
00884 
00885   // Assign an ID = 1 the the type SALOME_MED::MESH
00886   theObjectID = 1;
00887 
00888   return aStreamFile._retn();
00889 }
00890 
00891 //=============================================================================
00895 //=============================================================================
00896 CORBA::Boolean Med_Gen_Driver_i::CanPaste (const char* theComponentName, CORBA::Long theObjectID)
00897 {
00898   // The MED component can paste only objects copied by MED component
00899   // and with the object type = 1 (mesh)
00900   if (strcmp(theComponentName, ComponentDataType()) != 0 || theObjectID != 1) return false;
00901   return true;
00902 }
00903 
00904 //=============================================================================
00908 //=============================================================================
00909 SALOMEDS::SObject_ptr Med_Gen_Driver_i::PasteInto (const SALOMEDS::TMPFile& theStream,
00910                                                    CORBA::Long theObjectID,
00911                                                    SALOMEDS::SObject_ptr theObject)
00912 {
00913   SALOMEDS::SObject_var aResultSO = SALOMEDS::SObject::_duplicate(theObject);
00914   if (theStream.length() == 0) return aResultSO._retn();
00915 
00916   SALOMEDS::Study_var aStudy = theObject->GetStudy();
00917 
00918   CORBA::String_var aTmpDir = CORBA::string_dup(SALOMEDS_Tool::GetTmpDir().c_str());
00919   char* aFullName2 = new char[strlen(aTmpDir)+1];
00920   strcpy(aFullName2,aTmpDir);
00921   //  SALOMEDS::ListOfFileNames_var aSeq = SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir, false);
00922   SALOMEDS::ListOfFileNames_var aSeq = SALOMEDS_Tool::PutStreamToFiles(theStream, aFullName2, false);
00923   CORBA::String_var aMeshName = CORBA::string_dup(aSeq[0]);
00924   char* aFullName = new char[strlen(aTmpDir)+strlen(aMeshName)+1];
00925   strcpy(aFullName, aTmpDir);
00926   strcpy(aFullName+strlen(aTmpDir), aMeshName);
00927 
00928   MESH * myMesh= new MESH();
00929   //  myMesh->setName(aMeshName.c_str());
00930   char* aFullMeshName = new char[strlen(aMeshName)+1];
00931   strcpy(aFullMeshName,aMeshName);
00932   myMesh->setName(aFullMeshName);
00933   MED_MESH_RDONLY_DRIVER myMeshDriver(aFullName, myMesh);
00934   try {
00935     myMeshDriver.setMeshName(aFullMeshName);
00936     myMeshDriver.open();
00937   } catch (const std::exception & ex) {
00938     MESSAGE("Exception Interceptee : ");
00939     SCRUTE(ex.what());
00940     return aResultSO._retn();
00941   };
00942   try {
00943     myMeshDriver.read();
00944     MESSAGE("apres read");
00945     myMeshDriver.close();
00946   } catch (const std::exception & ex) {
00947     MESSAGE("Exception Interceptee : ");
00948     SCRUTE(ex.what());
00949     return aResultSO._retn();
00950   };
00951   // set new mesh name, becouse now there are no possibility to operate meshes with the same names
00952 //    srand((unsigned int)time(NULL));
00953   int aRND = rand(); //Get a random number to present a name of a copied mesh
00954   char aCopiedMeshName[127];
00955   sprintf(aCopiedMeshName,"MESH_COPY_%d",aRND);
00956   myMesh->setName(aCopiedMeshName);
00957   MESH_i * meshi = new MESH_i(myMesh);
00958   SALOME_MED::MESH_ptr mesh = meshi->_this();
00959   // add the mesh object in study
00960   meshi->addInStudy(aStudy,mesh);
00961   // get the IOR attribute of just added mesh
00962   CORBA::String_var anIORString = _driver_orb->object_to_string(mesh);
00963   aResultSO = aStudy->FindObjectIOR(anIORString);
00964 
00965   char * aFullName1 = new char[strlen(aTmpDir)+1];
00966   strcpy(aFullName1,aTmpDir);
00967   //  SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
00968   SALOMEDS_Tool::RemoveTemporaryFiles(aFullName1, aSeq.in(), true);
00969 
00970   return aResultSO._retn();
00971 }