Salome HOME
This commit was generated by cvs2git to track changes on a CVS vendor
[modules/med.git] / src / MED / Med_Gen_i.cxx
1 using namespace std;
2 //=============================================================================
3 // File      : Med_Gen_i.cxx
4 // Created   : mer fév 20 15:47:57 CET 2002
5 // Author    : Paul RASCLE, EDF
6 // Project   : SALOME
7 // Copyright : EDF 2001
8 // $Header$
9 //=============================================================================
10 using namespace std;
11
12 #include "Med_Gen_i.hxx"
13
14 #include "Mesh_i.hxx"
15 #include "Med_i.hxx"
16 #include "FieldInt_i.hxx"
17 #include "FieldDouble_i.hxx"
18 #include "Support_i.hxx"
19
20
21 #include "MEDMEM_Mesh.hxx"
22 #include "MEDMEM_Field.hxx"
23 #include "MEDMEM_Med.hxx"
24 #include "MEDMEM_MedMedDriver.hxx"
25 #include "MEDMEM_MedMeshDriver.hxx"
26 #include "MEDMEM_MedFieldDriver.hxx"
27 #include "MEDMEM_define.hxx"
28 #include "MEDMEM_DriversDef.hxx"
29
30
31 #include "Utils_SINGLETON.hxx"
32 #include "OpUtil.hxx"
33 #include "Utils_CorbaException.hxx"
34 #include "utilities.h"
35
36 #include <string>
37 #include <deque>
38 #include <map>
39
40 #include <TCollection_AsciiString.hxx>
41 #include <TColStd_SequenceOfAsciiString.hxx>
42 #include "SALOMEDS_Tool.hxx"
43
44 // Initialisation des variables statiques
45  map <string, string> Med_Gen_i::_MedCorbaObj;
46  string Med_Gen_i::_myFileName="";
47  string Med_Gen_i::_saveFileName="";
48
49 //=============================================================================
50 /*!
51  *  default constructor: not for use
52  */
53 //=============================================================================
54
55 Med_Gen_i::Med_Gen_i()
56 {
57   MESSAGE("Med_Gen_i::Med_Gen_i");
58 }
59
60 //=============================================================================
61 /*!
62  *  standard constructor
63  */
64 //=============================================================================
65
66 Med_Gen_i:: Med_Gen_i(CORBA::ORB_ptr orb,
67                                 PortableServer::POA_ptr poa,
68                                 PortableServer::ObjectId * contId, 
69                                 const char *instanceName, 
70                                 const char *interfaceName) :
71   Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
72 {
73   MESSAGE("activate object");
74   _thisObj = this ;
75   _id = _poa->activate_object(_thisObj);
76
77   _duringLoad=false;
78   // get an NamingService interface
79   _NS = SINGLETON_<SALOME_NamingService>::Instance() ;
80   ASSERT(SINGLETON_<SALOME_NamingService>::IsAlreadyExisting()) ;
81   _NS->init_orb( _orb ) ;
82 }
83 //=============================================================================
84 /*!
85  *  private method : change a study name in SALOMEDS::Study_var
86  */
87 //=============================================================================
88
89 SALOMEDS::Study_var Med_Gen_i::studyName2Study(const char* studyName)
90   throw(SALOME::SALOME_Exception)
91 {
92   string myStudyName(studyName);
93
94   if (myStudyName.size() == 0)
95     THROW_SALOME_CORBA_EXCEPTION("No Study Name given", \
96                                  SALOME::BAD_PARAM);
97
98   // Get StudyManager Reference, current study,
99   
100   CORBA::Object_var obj = _NS->Resolve("/myStudyManager");
101   SALOMEDS::StudyManager_var myStudyManager =
102     SALOMEDS::StudyManager::_narrow(obj);
103   if(CORBA::is_nil(myStudyManager))
104     THROW_SALOME_CORBA_EXCEPTION("No StudyManager Found in NameService", \
105                                  SALOME::BAD_PARAM);
106   
107   SALOMEDS::Study_var myStudy =
108     myStudyManager->GetStudyByName(myStudyName.c_str());
109   if (CORBA::is_nil(myStudy))
110     THROW_SALOME_CORBA_EXCEPTION("Wrong Study Name", \
111                                  SALOME::BAD_PARAM);
112
113   return SALOMEDS::Study::_duplicate(myStudy) ;
114 }
115
116 //=============================================================================
117 /*!
118  *  private method : add Med component in Study (Not MedGen ???)
119  */
120 //=============================================================================
121
122 void Med_Gen_i::addInStudy(SALOMEDS::Study_var myStudy)
123   throw(SALOME::SALOME_Exception)
124 {
125   SALOMEDS::StudyBuilder_var  myBuilder = myStudy->NewBuilder();
126   
127   myBuilder->NewCommand();
128   
129   // Create SComponent labelled 'Med' if it doesn't already exit
130   SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED");
131   if ( CORBA::is_nil(medfather) )
132     {
133       // mpv: component label must be created in spite of "Locked" study flag state
134       bool aLocked = myStudy->GetProperties()->IsLocked();
135       if (aLocked) myStudy->GetProperties()->SetLocked(false);
136       
137       MESSAGE("Add Component Med");
138       medfather = myBuilder->NewComponent("MED");
139       SALOMEDS::GenericAttribute_var anAttr = myBuilder->FindOrCreateAttribute(medfather, "AttributeName");
140       SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
141       //NRI      aName->SetValue("Med");
142
143       CORBA::Object_var objVarN = _NS->Resolve("/Kernel/ModulCatalog");
144       SALOME_ModuleCatalog::ModuleCatalog_var Catalogue  = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
145       SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "MED" );
146       if ( !Comp->_is_nil() ) {
147         aName->SetValue( Comp->componentusername() );
148       }    
149
150       //            Utilisation de this  deconseillee par Paul ??
151       //            myBuilder->DefineComponentInstance(medfather,POA_Engines::Med_Gen::_this());
152       CORBA::Object_var myO = _poa->id_to_reference(*_id); // this ior...
153       myBuilder->DefineComponentInstance(medfather,myO);
154       
155       if (aLocked) myStudy->GetProperties()->SetLocked(true);
156     } 
157   
158   myBuilder->CommitCommand();
159    
160 }
161
162 //=============================================================================
163 /*!
164  * Lit tous les objets contenus dans un fichier med et les lit en memoire
165  */
166 //=============================================================================
167 SALOME_MED::MED_ptr Med_Gen_i::readStructFile (const char* fileName,
168                                 const char* studyName)
169   throw(SALOME::SALOME_Exception)
170 {
171         SCRUTE(fileName);
172         SALOMEDS::Study_var myStudy = studyName2Study(studyName) ;
173         if (!_duringLoad) addInStudy(myStudy) ;
174
175         SALOME_MED::MED_ptr myMedIOR ;
176         try 
177         {
178           // we create a new MED_i and add in study
179           MED_i * myMedI = new MED_i();
180           myMedIOR = myMedI->_this() ;
181           if (!_duringLoad) myMedI->addInStudy(myStudy,myMedIOR) ;        
182           // create ::MED object, read all and add in study !
183           myMedI->init(myStudy,MED_DRIVER,fileName) ;
184         }
185         catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
186         catch(...)
187         {
188                 MESSAGE("Erreur a la lecture du fichier");
189                 THROW_SALOME_CORBA_EXCEPTION("Unable to open File "\
190                                                 ,SALOME::BAD_PARAM);
191         }
192         return SALOME_MED::MED::_duplicate(myMedIOR) ;
193 }
194
195 //=============================================================================
196 /*!
197  *  Prepare un Maillage sans le lire en memoire avec stokage dans l'etude
198  *  des champs avec leur type
199  */
200 //=============================================================================
201 void Med_Gen_i::readStructFileWithFieldType (const char* fileName,
202                                              const char* studyName)
203 throw (SALOME::SALOME_Exception)
204 {
205   BEGIN_OF("Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)");
206
207         SCRUTE(fileName);
208         SALOMEDS::Study_var myStudy = studyName2Study(studyName) ;
209
210         if (!_duringLoad) addInStudy(myStudy) ;
211
212         try 
213         {
214           // we create a new MED_i and add in study
215           MED_i * myMedI = new MED_i();
216           SALOME_MED::MED_ptr myMedIOR = myMedI->_this() ;
217           if (!_duringLoad) myMedI->addInStudy(myStudy,myMedIOR) ;        
218           // create ::MED object, read all and add in study !
219           myMedI->initWithFieldType(myStudy,MED_DRIVER,fileName) ;
220         }
221         catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
222         catch(...)
223         {
224                 MESSAGE("Erreur a la lecture du fichier");
225                 THROW_SALOME_CORBA_EXCEPTION("Unable to open File "\
226                                                 ,SALOME::BAD_PARAM);
227         }
228
229         END_OF("Med_Gen_i::readStructFileWithFieldType (const char* fileName,const char* studyName)");
230
231
232 }
233
234 //=============================================================================
235 /*!
236  *  Sert un Maillage
237  */
238 //=============================================================================
239 SALOME_MED::MESH_ptr Med_Gen_i::readMeshInFile(const char* fileName,
240                                                const char* studyName,
241                                                const char* meshName)
242 throw (SALOME::SALOME_Exception)
243 {
244         SCRUTE(fileName);
245         SALOMEDS::Study_var myStudy = studyName2Study(studyName) ;
246
247         if (!_duringLoad) addInStudy(myStudy) ;
248
249 // Creation du maillage
250
251         MESH * myMesh= new MESH() ;
252         myMesh->setName(meshName);
253         MED_MESH_RDONLY_DRIVER myMeshDriver(fileName,myMesh);
254         try
255         {
256                 myMeshDriver.setMeshName(meshName);
257                 myMeshDriver.open();
258         }
259         catch (const exception & ex)
260         {
261                 MESSAGE("Exception Interceptee : ");
262                 SCRUTE(ex.what());
263                 THROW_SALOME_CORBA_EXCEPTION("Unable to find this mesh in this file",SALOME::BAD_PARAM);
264         };
265         try
266         {
267                 myMeshDriver.read();
268                 MESSAGE("apres read");
269                 myMeshDriver.close();
270         }
271         catch (const exception & ex)
272         {
273                 MESSAGE("Exception Interceptee : ");
274                 SCRUTE(ex.what());
275                 THROW_SALOME_CORBA_EXCEPTION("Unable to read this mesh in this file",SALOME::BAD_PARAM);
276         };
277
278         MESH_i * meshi = new MESH_i(myMesh);
279         //SALOME_MED::MESH_var mesh = SALOME_MED::MESH::_narrow(meshi->_this());
280         SALOME_MED::MESH_ptr mesh = meshi->_this();
281         try
282         {
283         // add the mesh object in study
284                 if (!_duringLoad) meshi->addInStudy(myStudy,mesh);
285         }
286         catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
287         return SALOME_MED::MESH::_duplicate(mesh);
288 }
289 //=============================================================================
290 /*!
291  *  Sert un Champ
292  */
293 //=============================================================================
294 SALOME_MED::FIELD_ptr Med_Gen_i::readFieldInFile(const char* fileName,
295                                                const char* studyName,
296                                                const char* fieldName,
297                                                CORBA::Long ordre,
298                                                CORBA::Long iter)
299 throw (SALOME::SALOME_Exception)
300 {
301         SCRUTE(fileName);
302         string myStudyName(studyName);
303
304         if (myStudyName.size() == 0)
305                 THROW_SALOME_CORBA_EXCEPTION("No Study Name given", \
306                                  SALOME::BAD_PARAM);
307
308         // Get StudyManager Reference, current study,
309         
310         CORBA::Object_var obj = _NS->Resolve("/myStudyManager");
311         SALOMEDS::StudyManager_var myStudyManager =
312                         SALOMEDS::StudyManager::_narrow(obj);
313         ASSERT(! CORBA::is_nil(myStudyManager));
314         SALOMEDS::Study_var myStudy =
315                 myStudyManager->GetStudyByName(myStudyName.c_str());
316         if (CORBA::is_nil(myStudy))
317         THROW_SALOME_CORBA_EXCEPTION("Wrong Study Name", \
318                                  SALOME::BAD_PARAM);
319
320         SALOMEDS::StudyBuilder_var myBuilder = myStudy->NewBuilder();
321         SALOMEDS::SComponent_var medfather = myStudy->FindComponent("MED");
322         if (CORBA::is_nil(medfather))
323         {
324                 myBuilder->NewCommand();
325                 // mpv: component label must be created in spite of "Locked" study flag state
326                 bool aLocked = myStudy->GetProperties()->IsLocked();
327                 if (aLocked) myStudy->GetProperties()->SetLocked(false);
328
329                 medfather = myBuilder->NewComponent("MED");
330                 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(
331                       myBuilder->FindOrCreateAttribute(medfather, "AttributeName"));
332                 //NRI           aName->SetValue("Med");
333
334                 CORBA::Object_var objVarN = _NS->Resolve("/Kernel/ModulCatalog");
335                 SALOME_ModuleCatalog::ModuleCatalog_var Catalogue  = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
336                 SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "MED" );
337                 if ( !Comp->_is_nil() ) {
338                   aName->SetValue( Comp->componentusername() );
339                 }    
340
341                 CORBA::Object_var myO = _poa->id_to_reference(*_id); // this ior...
342                 myBuilder->DefineComponentInstance(medfather,myO);
343
344                 if (aLocked) myStudy->GetProperties()->SetLocked(true);
345                 myBuilder->CommitCommand();
346
347         }
348         else
349                         MESSAGE("MED dejà dans l étude");
350
351         MESSAGE("Lecture du fichier ")
352         SCRUTE(fileName);
353
354 // Creation du champ
355
356         FIELD_ * myField= new FIELD_() ;
357         MED * mymed = new MED(MED_DRIVER,fileName) ;
358         try
359         {
360                 deque<string> fieldsNames = mymed->getFieldNames() ;
361                 int numberOfFields = fieldsNames.size();
362                 int i;
363                 for (i=0; i<numberOfFields; i++)
364                 {
365                         if (fieldsNames[i]== fieldName) break;
366                 }
367                 if (i == numberOfFields)
368                 {
369                         THROW_SALOME_CORBA_EXCEPTION("Unable to find this field ",SALOME::BAD_PARAM);
370                 }
371                 MESSAGE("trouve");
372 /*
373                 deque<DT_IT_> myIteration = mymed->getFieldIteration (fieldName);
374                 if (myIteration.size() != 1)
375                 {
376                         MESSAGE("WARNING : My iteration size is ")
377                         SCRUTE(myIteration.size());
378                 }
379 */
380                 myField = mymed->getField(fieldName,iter,ordre);
381         }
382         catch (const exception & ex)
383         {
384                 MESSAGE("Exception Interceptee : ");
385                 SCRUTE(ex.what());
386                 THROW_SALOME_CORBA_EXCEPTION("Unable to find this field in this file",SALOME::BAD_PARAM);
387         };
388                         
389         SUPPORT * fieldSupport;
390         SALOME_MED::SUPPORT_ptr mySupportIOR;
391         try
392         {
393                 fieldSupport=(SUPPORT *)myField->getSupport() ;
394                 ASSERT(fieldSupport != NULL);
395                 MESH * myMesh=(MESH *)fieldSupport->getMesh();
396                 ASSERT(myMesh != NULL);
397                 myMesh->read();
398                 SCRUTE(myMesh->getName());
399                 fieldSupport->update();
400                 SUPPORT_i * mySupportI = new SUPPORT_i(fieldSupport);
401                 mySupportIOR=mySupportI->_this();
402         }
403         catch (const exception & ex)
404         {
405                 MESSAGE("Exception Interceptee : ");
406                 SCRUTE(ex.what());
407                 THROW_SALOME_CORBA_EXCEPTION("Unable to find associated support",SALOME::BAD_PARAM);
408         };
409
410         med_type_champ type = myField->getValueType() ;
411         switch (type) 
412         {
413          case MED_FR::MED_INT32:        
414          {
415                 try 
416                 {
417                         ((FIELD<int>*)myField)->read() ;
418                         FIELDINT_i * myFieldIntI = new FIELDINT_i(mySupportIOR,(FIELD<int>*)myField);
419                         POA_SALOME_MED::FIELD_tie<FIELD_i> * myFieldTie = new POA_SALOME_MED::FIELD_tie<FIELD_i>(myFieldIntI);
420                         SALOME_MED::FIELD_ptr myFieldIOR = myFieldTie->_this() ;
421                         if (!_duringLoad) myFieldIntI->addInStudy(myStudy,myFieldIOR) ;
422                         return SALOME_MED::FIELD::_duplicate(myFieldIOR);
423                 }
424                 catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
425                 catch (const exception & ex)
426                 {
427                         MESSAGE("Exception Interceptee : ");
428                         SCRUTE(ex.what());
429                         THROW_SALOME_CORBA_EXCEPTION("Unable to read int field",SALOME::BAD_PARAM);
430                 };
431                 break;
432          }
433          case MED_FR::MED_REEL64: 
434          {
435                 try 
436                 {
437                         ((FIELD<double>*)myField)->read() ;
438                         FIELDDOUBLE_i * myFieldDoubleI = new FIELDDOUBLE_i(mySupportIOR,(FIELD<double>*)myField);
439                         POA_SALOME_MED::FIELD_tie<FIELD_i> * myFieldTie = new POA_SALOME_MED::FIELD_tie<FIELD_i>(myFieldDoubleI);
440                         SALOME_MED::FIELD_ptr myFieldIOR = myFieldTie->_this() ;
441                         if (!_duringLoad) myFieldDoubleI->addInStudy(myStudy,myFieldIOR) ;
442                         return SALOME_MED::FIELD::_duplicate(myFieldIOR);
443                 }
444                 catch (const SALOMEDS::StudyBuilder::LockProtection & lp) {}
445                 catch (const exception & ex)
446                 {
447                         MESSAGE("Exception Interceptee : ");
448                         SCRUTE(ex.what());
449                         THROW_SALOME_CORBA_EXCEPTION("Unable to read double field",SALOME::BAD_PARAM);
450                 };
451                 break;
452          }
453         }
454
455         
456 }
457
458
459 //=============================================================================
460 /*!
461  *  Destructor
462  */
463 //=============================================================================
464
465 Med_Gen_i::~Med_Gen_i()
466 {
467   MESSAGE("Med_Gen_i::~Med_Gen_i");
468 }
469
470 //=============================================================================
471 /*!
472  *  CORBA: Save Mesh objects (called when a study is saved)
473  */
474 //=============================================================================
475 SALOMEDS::TMPFile* Med_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent,
476                                    const char* theURL,
477                                    bool isMultiFile) {
478   const char* LOC = "Med_Gen_i::Save";
479   BEGIN_OF(LOC);
480
481   SALOMEDS::TMPFile_var aStreamFile;
482   // Get a temporary directory to store a file
483   TCollection_AsciiString aTmpDir = (isMultiFile)?TCollection_AsciiString((char*)theURL):SALOMEDS_Tool::GetTmpDir();
484   // Create a list to store names of created files
485   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
486   TColStd_SequenceOfAsciiString aFileNames;
487
488   CORBA::String_var aSaveStudyName = strdup(SALOMEDS_Tool::GetNameFromPath(theComponent->GetStudy()->URL()));
489
490   SALOMEDS::SObject_var aMedMeshFather = theComponent->GetStudy()->FindObject("MEDMESH");
491   if (!CORBA::is_nil(aMedMeshFather)) {
492     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedMeshFather);
493     for(; anIter->More(); anIter->Next()) {
494       SALOMEDS::SObject_var aSO = anIter->Value();
495       SALOMEDS::GenericAttribute_var anAttr;
496       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
497         CORBA::Object_var myIOR = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
498         SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
499         if (! CORBA::is_nil(myMesh)) {
500           TCollection_AsciiString aName(strdup(aSaveStudyName));
501           aName += "_MEDMESH_";
502           aName += myMesh->getName();
503           aName += ".med";
504           MESSAGE("Save mesh with name "<<aName.ToCString());
505           long driverId = myMesh->addDriver(SALOME_MED::MED_DRIVER,(aTmpDir+aName).ToCString(),myMesh->getName());
506           myMesh->write(driverId,"");
507           aFileNames.Append(aName);
508         }
509       }
510     }
511   }
512
513   SALOMEDS::SObject_var aMedFieldFather = theComponent->GetStudy()->FindObject("MEDFIELD");
514   if (!CORBA::is_nil(aMedFieldFather)) {
515     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedFieldFather);
516     for(; anIter->More(); anIter->Next()) {
517       SALOMEDS::SObject_var aSO = anIter->Value();
518       SALOMEDS::GenericAttribute_var anAttr;
519       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
520         CORBA::Object_var myIOR = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
521         SALOME_MED::FIELD_var myField = SALOME_MED::FIELD::_narrow(myIOR);
522         if (! CORBA::is_nil(myField)) {
523           ostringstream a,b;
524           a<< myField->getOrderNumber();
525           b<< myField->getIterationNumber();
526
527           TCollection_AsciiString aName(strdup(aSaveStudyName));
528           aName += "_MEDFIELD_";
529           aName += myField->getName();
530           aName += "_ORDRE_";
531           aName += strdup(a.str().c_str());
532           aName += "_ITER_";
533           aName += strdup(b.str().c_str());
534           aName += ".med";
535           MESSAGE("Save mesh with name "<<aName.ToCString());
536           long driverId = myField->addDriver(SALOME_MED::MED_DRIVER,(aTmpDir+aName).ToCString(),myField->getName());
537           myField->write(driverId,"");
538           aFileNames.Append(aName);
539         }
540       }
541     }
542   }
543
544   int i;
545   aSeq->length(aFileNames.Length());
546   for(i = aFileNames.Length(); i > 0; i--) aSeq[i-1] = CORBA::string_dup(aFileNames.Value(i).ToCString());
547   // Conver a file to the byte stream
548   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir.ToCString(), aSeq.in(), isMultiFile);
549   // Remove the created file and tmp directory
550   if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.ToCString(), aSeq.in(), true);
551   // Return the created byte stream
552   return aStreamFile._retn();
553   
554   END_OF(LOC);
555 }
556
557 //=============================================================================
558 /*!
559  *  CORBA: Load Mesh objects (called when an existing study is opened)
560  */
561 //=============================================================================
562
563 CORBA::Boolean Med_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,
564                                const SALOMEDS::TMPFile& theStream,
565                                const char* theURL,
566                                bool isMultiFile) {
567   const char* LOC = "Med_Gen_i::Load";
568   BEGIN_OF(LOC);
569
570   // Get a temporary directory for a file
571   TCollection_AsciiString aTmpDir =
572     (isMultiFile)?TCollection_AsciiString((char*)theURL):SALOMEDS_Tool::GetTmpDir();
573   _saveFileName = CORBA::string_dup(aTmpDir.ToCString());
574   SALOMEDS::ListOfFileNames_var aSeq =
575     SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir.ToCString(), isMultiFile);
576   return true;
577
578   END_OF(LOC);
579 }
580
581 //=============================================================================
582 /*!
583  *  CORBA: 
584  */
585 //=============================================================================
586
587 void Med_Gen_i::Close(SALOMEDS::SComponent_ptr theComponent)
588 {
589   MESSAGE("Med_Gen_i::Close");
590   SALOMEDS::SObject_var aMedMeshFather = theComponent->GetStudy()->FindObject("MEDMESH");
591   if (!CORBA::is_nil(aMedMeshFather)) {
592     SALOMEDS::ChildIterator_var anIter = theComponent->GetStudy()->NewChildIterator(aMedMeshFather);
593     for(; anIter->More(); anIter->Next()) {
594       SALOMEDS::SObject_var aSO = anIter->Value();
595       SALOMEDS::GenericAttribute_var anAttr;
596       if (aSO->FindAttribute(anAttr,"AttributeIOR")) {
597         CORBA::Object_var myIOR = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
598         SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
599         // here must call method destroy of myMesh, but it not implented yet
600       }
601     }
602   }
603 }
604
605 //=============================================================================
606 /*!
607  *  CORBA:
608  */
609 //=============================================================================
610
611 char* Med_Gen_i::ComponentDataType()
612 {
613   MESSAGE("Med_Gen_i::ComponentDataType");
614   return strdup("MED") ; /* What is this type ? */
615 }
616     
617 //=============================================================================
618 /*!
619  *  CORBA: give a persistent reference of a transient object (for study save) 
620  */
621 //=============================================================================
622
623 char* Med_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject,
624                                         const char* IORString,
625                                         CORBA::Boolean isMultiFile)
626 {
627   const char * LOC = "Med_Gen_i::IORToLocalPersistentID" ;
628   BEGIN_OF(LOC) ;
629   SCRUTE(IORString);
630
631   string aSaveStudyName(strdup(SALOMEDS_Tool::GetNameFromPath(theSObject->GetStudy()->URL())));
632   
633
634   if (string(IORString).size()==0) return strdup((aSaveStudyName+"_MED").c_str());
635   // Well, we know where put object (_saveFilename) and we know object (IORString)
636   // cast object :
637   CORBA::Object_var myIOR = _orb->string_to_object(IORString);
638
639   // MED
640   SALOME_MED::MED_var myMed = SALOME_MED::MED::_narrow(myIOR);
641   if (! CORBA::is_nil(myMed)) 
642   {
643         // nothing to save : Support will be saved inside the mesh
644         string str_MedName=aSaveStudyName + "_MED Objet Med + /OBJ_MED/";
645         return strdup(str_MedName.c_str()) ; 
646   }
647  
648   // MESH
649   SALOME_MED::MESH_var myMesh = SALOME_MED::MESH::_narrow(myIOR);
650   if (! CORBA::is_nil(myMesh)) 
651   {
652     CORBA::String_var aName((aSaveStudyName+"_MEDMESH_"+ myMesh->getName() + ".med").c_str());
653     return strdup(aName._retn()) ;
654   }
655     
656   // SUPPORT
657   SALOME_MED::SUPPORT_var mySupport = SALOME_MED::SUPPORT::_narrow(myIOR);
658   if (! CORBA::is_nil(mySupport)) 
659   {
660         // nothing to save : Support will be saved inside the mesh
661         string str_SupportName;
662         try
663         {
664                 str_SupportName=string("/FAS/")+string(mySupport->getName());
665                 str_SupportName+=string("/ENS_MAA/")+string(mySupport->getMesh()->getName());
666                 SCRUTE(str_SupportName);
667         }
668         catch(...)
669         {
670                 MESSAGE("Unable to save the support");
671                 THROW_SALOME_CORBA_EXCEPTION("Unable to save Field in Med"\
672                                               ,SALOME::INTERNAL_ERROR);
673         }
674     return strdup((aSaveStudyName+"_MED"+str_SupportName).c_str());
675   }
676     
677   SALOME_MED::FIELD_var myField = SALOME_MED::FIELD::_narrow(myIOR);
678   if (! CORBA::is_nil(myField)) 
679   {
680     string str_FieldName;
681     ostringstream a,b;
682     a<< myField->getOrderNumber();
683     b<< myField->getIterationNumber();
684     CORBA::String_var aName((aSaveStudyName+"_MEDFIELD_"+ myField->getName() +
685                              string("_ORDRE_")+a.str()+
686                              string("_ITER_")+b.str() +
687                              ".med").c_str());
688     return strdup(aName._retn());
689   }
690
691   //THROW_SALOME_CORBA_EXCEPTION("Unable to save IOR",SALOME::BAD_PARAM);
692   return strdup((aSaveStudyName+"_MED").c_str());
693
694   END_OF(LOC) ;
695 }
696
697 //=============================================================================
698 /*!
699  *  CORBA: give a transient reference (when loading an object, opening study)
700  */
701 //=============================================================================
702
703 char* Med_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject,
704                                         const char* aLocalPersistentID,
705                                         CORBA::Boolean isMultiFile)
706      throw(SALOME::SALOME_Exception)
707 {
708   const char * LOC = "Med_Gen_i::LocalPersistentIDToIOR" ;
709   BEGIN_OF(LOC) ;
710
711   TCollection_AsciiString aTmpDir(CORBA::string_dup(_saveFileName.c_str()));
712
713   string aSaveStudyName(strdup(SALOMEDS_Tool::GetNameFromPath(theSObject->GetStudy()->URL())));
714   int aStudyNameLen = strlen(aSaveStudyName.c_str());
715
716   if (strlen(aLocalPersistentID) <= aStudyNameLen) return strdup("");
717   if (strcmp(aLocalPersistentID, "Objet Med + /OBJ_MED/") == 0) return strdup(""); // MED
718
719   if (strncmp(&(aLocalPersistentID[aStudyNameLen]), "_MEDMESH_",13) == 0) {// MESH
720     MESH * myMesh= new MESH() ;
721     int aMeshNameLen = strlen(aLocalPersistentID) - 16 - aStudyNameLen;
722     char* aMeshName = new char[aMeshNameLen];
723     strncpy(aMeshName, &(aLocalPersistentID[aStudyNameLen + 13]), aMeshNameLen-1);
724     aMeshName[aMeshNameLen-1] = 0;
725     myMesh->setName(aMeshName);
726     MED_MESH_RDONLY_DRIVER myMeshDriver((aTmpDir + strdup(aLocalPersistentID)).ToCString(),myMesh);
727     try
728       {
729         myMeshDriver.setMeshName(aMeshName);
730         myMeshDriver.open();
731       }
732     catch (const exception & ex)
733       {
734         MESSAGE("Exception Interceptee : ");
735         SCRUTE(ex.what());
736         THROW_SALOME_CORBA_EXCEPTION("Unable to find this mesh in this file",SALOME::BAD_PARAM);
737       };
738     try
739       {
740         myMeshDriver.read();
741         MESSAGE("apres read");
742         myMeshDriver.close();
743       }
744     catch (const exception & ex)
745       {
746         MESSAGE("Exception Interceptee : ");
747         SCRUTE(ex.what());
748         THROW_SALOME_CORBA_EXCEPTION("Unable to read this mesh in this file",SALOME::BAD_PARAM);
749       }
750     MESH_i * meshi = new MESH_i(myMesh);
751     //SALOME_MED::MESH_var mesh = SALOME_MED::MESH::_narrow(meshi->_this());
752     SALOME_MED::MESH_ptr mesh = meshi->_this();
753     SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
754     aSeq->length(1);
755     aSeq[0]=CORBA::string_dup(aLocalPersistentID);
756     if (!isMultiFile) SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.ToCString(), aSeq.in(), true);
757     return(CORBA::string_dup(_orb->object_to_string(mesh)));
758   } else if (strncmp(&(aLocalPersistentID[aStudyNameLen]), "_MEDFIELD_",14) == 0) { // FIELD
759     return(strdup("")); // not implemented yet
760   }
761
762   return strdup("");
763
764   END_OF(LOC) ;
765 }
766
767 //=============================================================================
768 /*!
769  *  returns true, if can publish object
770  */
771 //=============================================================================
772 bool Med_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR) {
773   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(theIOR);
774   return !(aMesh->_is_nil());
775 }
776
777 //=============================================================================
778 /*!
779  *  publish the given object
780  */
781 //=============================================================================
782 SALOMEDS::SObject_ptr Med_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
783                                                 SALOMEDS::SObject_ptr theSObject,
784                                                 CORBA::Object_ptr theObject,
785                                                 const char* theName) throw (SALOME::SALOME_Exception)
786 {
787   SALOMEDS::SObject_var aResultSO;
788
789   if(CORBA::is_nil(theObject)) return aResultSO;
790   if(theStudy->_is_nil()) return aResultSO;
791
792   SALOMEDS::StudyBuilder_var aBuilder = theStudy->NewBuilder();
793   SALOMEDS::GenericAttribute_var anAttr;
794   SALOMEDS::AttributeName_var    aName;
795   SALOMEDS::AttributeIOR_var     anIOR;
796   SALOMEDS::SComponent_var aFather = theStudy->FindComponent("MED");
797
798   if (aFather->_is_nil()) {
799     aFather = aBuilder->NewComponent("MED");
800     if (aFather->_is_nil()) return aResultSO;
801     anAttr = aBuilder->FindOrCreateAttribute(aFather, "AttributeName");
802     aName = SALOMEDS::AttributeName::_narrow(anAttr);
803     //NRI    aName->SetValue("MED");
804
805     CORBA::Object_var objVarN = _NS->Resolve("/Kernel/ModulCatalog");
806     SALOME_ModuleCatalog::ModuleCatalog_var Catalogue  = SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
807     SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "MED" );
808     if ( !Comp->_is_nil() ) {
809       aName->SetValue( Comp->componentusername() );
810     }    
811     aBuilder->DefineComponentInstance(aFather, Med_Gen::_this());
812   }
813
814   if (CORBA::is_nil(theSObject)) {
815     SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(theObject);
816     aMesh->addInStudy(theStudy, aMesh);
817     SALOMEDS::SObject_var aResultSO = theStudy->FindObjectIOR(_orb->object_to_string(theObject));
818   } else {
819     if (!theSObject->ReferencedObject(aResultSO)) 
820       THROW_SALOME_CORBA_EXCEPTION("Publish in study MED object error",SALOME::BAD_PARAM);
821   }
822 //    aBuilder->Addreference(theObject, aResultSO);
823   return aResultSO._retn();
824 }
825
826 //=============================================================================
827 /*!
828  *  returns true, if can copy the object
829  */
830 //=============================================================================
831 CORBA::Boolean Med_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject) {
832   // Try to retrieve known by MED component mesh by given IOR
833   SALOMEDS::GenericAttribute_var anAttr;
834   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return false;
835   CORBA::Object_var anObj = _orb->string_to_object(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
836   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
837   // If the object is null one it can't be copied: return false
838   if (aMesh->_is_nil()) return false;
839   return true;
840 }
841
842 //=============================================================================
843 /*!
844  *  create copy of the object and put it to the stream
845  */
846 //=============================================================================
847 SALOMEDS::TMPFile* Med_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID) {
848     // Declare a sequence of the byte to store the copied object
849   SALOMEDS::TMPFile_var aStreamFile;
850
851   // Try to get GEOM_Shape object by given SObject
852   SALOMEDS::GenericAttribute_var anAttr;
853   if (!theObject->FindAttribute(anAttr, "AttributeIOR")) return new SALOMEDS::TMPFile(0);
854   CORBA::String_var anIOR = strdup(SALOMEDS::AttributeIOR::_narrow(anAttr)->Value());
855   CORBA::Object_var anObj = _orb->string_to_object(anIOR);
856   SALOME_MED::MESH_var aMesh = SALOME_MED::MESH::_narrow(anObj);
857   if (aMesh->_is_nil()) return new SALOMEDS::TMPFile(0);
858
859   // Get a temporary directory to store a temporary file
860   CORBA::String_var aTmpDir = SALOMEDS_Tool::GetTmpDir();
861   // Create a list to store names of created files
862   SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
863   aSeq->length(1);
864   aSeq[0] = strdup(aMesh->getName());
865   char* aFullName = new char[strlen(aTmpDir)+strlen(aSeq[0])+1];
866   strcpy(aFullName, aTmpDir);
867   strcpy(aFullName+strlen(aTmpDir), aSeq[0]);
868   long driverId = aMesh->addDriver(SALOME_MED::MED_DRIVER,strdup(aFullName) , aMesh->getName());
869   aMesh->write(driverId,"");
870   delete(aFullName);
871   
872   aStreamFile = SALOMEDS_Tool::PutFilesToStream(aTmpDir, aSeq.in(), false);
873   SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir, aSeq.in(), true);
874   
875   // Assign an ID = 1 the the type SALOME_MED::MESH
876   theObjectID = 1;
877  
878   return aStreamFile._retn();
879 }
880
881 //=============================================================================
882 /*!
883  *  returns true, if can copy the object
884  */
885 //=============================================================================
886 CORBA::Boolean Med_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID) {
887   // The MED component can paste only objects copied by MED component
888   // and with the object type = 1 (mesh)
889   if (strcmp(theComponentName, ComponentDataType()) != 0 || theObjectID != 1) return false;
890   return true;
891 }
892
893 //=============================================================================
894 /*!
895  *  returns true, if can copy the object
896  */
897 //=============================================================================
898 SALOMEDS::SObject_ptr Med_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
899                                            CORBA::Long theObjectID,
900                                            SALOMEDS::SObject_ptr theObject) {
901   SALOMEDS::SObject_var aResultSO = SALOMEDS::SObject::_duplicate(theObject);
902   if (theStream.length() == 0) return aResultSO._retn();
903   
904   SALOMEDS::Study_var aStudy = theObject->GetStudy();
905
906   CORBA::String_var aTmpDir = strdup(SALOMEDS_Tool::GetTmpDir());
907   SALOMEDS::ListOfFileNames_var aSeq = SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir, false);
908   CORBA::String_var aMeshName = strdup(aSeq[0]);
909   char* aFullName = new char[strlen(aTmpDir)+strlen(aMeshName)+1];
910   strcpy(aFullName, aTmpDir);
911   strcpy(aFullName+strlen(aTmpDir), aMeshName);
912
913   MESH * myMesh= new MESH() ;
914   myMesh->setName((char*)aMeshName);
915   MED_MESH_RDONLY_DRIVER myMeshDriver(aFullName, myMesh);
916   try {
917     myMeshDriver.setMeshName((char*)aMeshName);
918     myMeshDriver.open();
919   } catch (const exception & ex) {
920     MESSAGE("Exception Interceptee : ");
921     SCRUTE(ex.what());
922     delete(aFullName);
923     return aResultSO._retn();
924   };
925   try {
926     myMeshDriver.read();
927     ("apres read");
928     myMeshDriver.close();
929   } catch (const exception & ex) {
930     MESSAGE("Exception Interceptee : ");
931     SCRUTE(ex.what());
932     delete(aFullName);
933     return aResultSO._retn();
934   };
935   // set new mesh name, becouse now there are no possibility to operate meshes with the same names
936 //    srand((unsigned int)time(NULL));
937   int aRND = rand(); //Get a random number to present a name of a copied mesh
938   char aCopiedMeshName[20];
939   sprintf(aCopiedMeshName,"MESH_COPY_%d",aRND);
940   myMesh->setName(aCopiedMeshName);
941   MESH_i * meshi = new MESH_i(myMesh);
942   SALOME_MED::MESH_ptr mesh = meshi->_this();
943   // add the mesh object in study
944   meshi->addInStudy(aStudy,mesh);
945   // get the IOR attribute of just added mesh
946   CORBA::String_var anIORString = _orb->object_to_string(mesh);
947   aResultSO = aStudy->FindObjectIOR(anIORString);
948
949   SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir, aSeq.in(), true);
950   delete(aFullName);
951   return aResultSO._retn();
952 }
953
954
955
956
957
958
959 //=============================================================================
960 /*! 
961  * C factory, accessible with dlsym, after dlopen  
962  */
963 //=============================================================================
964
965 extern "C"
966 {
967   PortableServer::ObjectId * MEDEngine_factory(
968                                CORBA::ORB_ptr orb,
969                                PortableServer::POA_ptr poa, 
970                                PortableServer::ObjectId * contId,
971                                const char *instanceName, 
972                                const char *interfaceName)
973   {
974     MESSAGE("PortableServer::ObjectId * MedEngine_factory()");
975     SCRUTE(interfaceName);
976     Med_Gen_i * myMed_Gen 
977       = new Med_Gen_i(orb, poa, contId, instanceName, interfaceName);
978     return myMed_Gen->getId() ;
979   }
980 }