Salome HOME
[MEDCalc] fix missing return status
[modules/med.git] / src / MEDCalc / cmp / MED.cxx
1 // Copyright (C) 2015-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "MED.hxx"
21 #include "MEDFactoryClient.hxx"
22 #include <MEDCalcConstants.hxx>
23
24 #include <SALOMEconfig.h>
25 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
26
27 #include <SALOMEDS_SObject.hxx>
28 #include <Utils_ExceptHandlers.hxx>
29 #include <SALOME_LifeCycleCORBA.hxx>
30 #include <SALOME_NamingService.hxx>
31
32 #include <string>
33 #include <sstream>
34
35 /*!
36   \brief Constructor
37
38   Creates an instance of the MED component engine
39
40   \param orb reference to the ORB
41   \param poa reference to the POA
42   \param contId CORBA object ID, pointing to the owner SALOME container
43   \param instanceName SALOME component instance name
44   \param interfaceName SALOME component interface name
45 */
46 MED::MED(CORBA::ORB_ptr orb,
47          PortableServer::POA_ptr poa,
48          PortableServer::ObjectId* contId,
49          const char* instanceName,
50          const char* interfaceName)
51   : Engines_Component_i(orb, poa, contId, instanceName, interfaceName),
52     _fieldSeriesEntries()
53 {
54   _thisObj = this;
55   _id = _poa->activate_object(_thisObj); // register and activate this servant object
56 }
57
58 MED::~MED()
59 {
60   // nothing to do
61 }
62
63 MED_ORB::status
64 MED::addDatasourceToStudy(SALOMEDS::Study_ptr study,
65                           const MEDCALC::DatasourceHandler& datasourceHandler)
66 {
67   // set exception handler to catch unexpected CORBA exceptions
68   Unexpect aCatch(SALOME_SalomeException);
69
70   // check if reference to study is valid
71   if (!CORBA::is_nil(study)) {
72     // get full object path
73     std::string fullName = CORBA::string_dup(datasourceHandler.name);
74     // check if the object with the same name is already registered in the study
75     SALOMEDS::SObject_var sobj = study->FindObjectByPath(fullName.c_str());
76     if (CORBA::is_nil(sobj)) {
77       // object is not registered yet -> register
78       SALOMEDS::GenericAttribute_var anAttr;
79       SALOMEDS::AttributeParameter_var aParam;
80       SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
81       SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
82
83       // find MED component; create it if not found
84       SALOMEDS::SComponent_var father = study->FindComponent("MED");
85       if (CORBA::is_nil(father)) {
86         // create component
87         father = studyBuilder->NewComponent("MED");
88         // set name attribute
89         father->SetAttrString("AttributeName", "MEDCalc");
90         // set icon attribute
91         father->SetAttrString("AttributePixMap", "ICO_MED");
92         // register component in the study
93         studyBuilder->DefineComponentInstance(father, MED_Gen::_this());
94         // add component to the use case tree
95         // (to support tree representation customization and drag-n-drop)
96         useCaseBuilder->SetRootCurrent();
97         useCaseBuilder->Append(father); // component object is added as the top level item
98       }
99
100       // create new sub-object, as a child of the component object
101       SALOMEDS::SObject_var soDatasource = studyBuilder->NewObject(father);
102       soDatasource->SetAttrString("AttributeName", fullName.c_str());
103       soDatasource->SetAttrString("AttributePixMap", "ICO_DATASOURCE");
104       anAttr = studyBuilder->FindOrCreateAttribute(soDatasource, "AttributeParameter");
105       aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
106       aParam->SetInt(SOURCE_ID, datasourceHandler.id);
107       useCaseBuilder->AppendTo(soDatasource->GetFather(), soDatasource);
108
109       // We can add the meshes as children of the datasource
110       MEDCALC::MeshHandlerList* meshHandlerList =
111         MEDFactoryClient::getDataManager()->getMeshList(datasourceHandler.id);
112
113       for(CORBA::ULong iMesh=0; iMesh<meshHandlerList->length(); iMesh++) {
114         MEDCALC::MeshHandler meshHandler = (*meshHandlerList)[iMesh];
115         SALOMEDS::SObject_var soMesh = studyBuilder->NewObject(soDatasource);
116         soMesh->SetAttrString("AttributeName", meshHandler.name);
117         soMesh->SetAttrString("AttributePixMap", "ICO_DATASOURCE_MESH");
118         anAttr = studyBuilder->FindOrCreateAttribute(soMesh, "AttributeParameter");
119         aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
120         aParam->SetInt(MESH_ID, meshHandler.id);
121         aParam->SetBool(IS_IN_WORKSPACE, false);
122         useCaseBuilder->AppendTo(soMesh->GetFather(), soMesh);
123
124         // We add the field timeseries defined on this mesh, as children of the mesh SObject
125         MEDCALC::FieldseriesHandlerList * fieldseriesHandlerList =
126           MEDFactoryClient::getDataManager()->getFieldseriesListOnMesh(meshHandler.id);
127
128         for(CORBA::ULong iFieldseries=0; iFieldseries<fieldseriesHandlerList->length(); iFieldseries++) {
129           MEDCALC::FieldseriesHandler fieldseriesHandler = (*fieldseriesHandlerList)[iFieldseries];
130           SALOMEDS::SObject_var soFieldseries = studyBuilder->NewObject(soMesh);
131           _fieldSeriesEntries[fieldseriesHandler.id] = soFieldseries->GetID();
132
133           std::string label(fieldseriesHandler.name);
134           label +=" ("+std::string(mapTypeOfFieldLabel[fieldseriesHandler.type])+")";
135           soFieldseries->SetAttrString("AttributeName", label.c_str());
136           soFieldseries->SetAttrString("AttributePixMap", "ICO_DATASOURCE_FIELD");
137           anAttr = studyBuilder->FindOrCreateAttribute(soFieldseries, "AttributeParameter");
138           aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
139           //aParam->SetInt(FIELD_SERIES_ID, fieldseriesHandler.id);
140           aParam->SetInt(FIELD_ID, fieldseriesHandler.id);
141           aParam->SetBool(IS_IN_WORKSPACE, false);
142
143           useCaseBuilder->AppendTo(soFieldseries->GetFather(), soFieldseries);
144           soFieldseries->UnRegister();
145         }
146         soMesh->UnRegister();
147       }
148
149       // cleanup
150       father->UnRegister();
151       soDatasource->UnRegister();
152     }
153   }
154
155   return MED_ORB::OP_OK;
156 }
157
158 MED_ORB::status
159 MED::registerPresentation(SALOMEDS::Study_ptr study,
160                           CORBA::Long fieldId,
161                           const char* name,
162                           const char* label,
163                           CORBA::Long presentationId)
164 {
165   // set exception handler to catch unexpected CORBA exceptions
166   Unexpect aCatch(SALOME_SalomeException);
167
168   if (_fieldSeriesEntries.find(fieldId) == _fieldSeriesEntries.end()) {
169     std::cerr << "Field not found\n";
170     return MED_ORB::OP_ERROR ;
171   }
172   std::string entry = _fieldSeriesEntries[fieldId];
173   SALOMEDS::SObject_var sobject = study->FindObjectID(entry.c_str());
174   SALOMEDS::SObject_ptr soFieldseries = sobject._retn();
175
176   if (soFieldseries->IsNull()) {
177     std::cerr << "Entry not found\n";
178     return MED_ORB::OP_ERROR;
179   }
180
181   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
182   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
183   SALOMEDS::SObject_var soPresentation = studyBuilder->NewObject(soFieldseries);
184   useCaseBuilder->AppendTo(soPresentation->GetFather(), soPresentation);
185
186   soPresentation->SetAttrString("AttributeName", name);
187   soPresentation->SetAttrString("AttributePixMap", label);
188
189   SALOMEDS::GenericAttribute_var anAttr;
190   SALOMEDS::AttributeParameter_var aParam;
191   anAttr = studyBuilder->FindOrCreateAttribute(soPresentation, "AttributeParameter");
192   aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
193   aParam->SetInt(FIELD_ID, fieldId);
194   aParam->SetBool(IS_PRESENTATION, true);
195   aParam->SetInt(PRESENTATION_ID, presentationId);
196
197   return MED_ORB::OP_OK;
198 }
199
200 MED_ORB::status
201 MED::unregisterPresentation(SALOMEDS::Study_ptr study,
202                             CORBA::Long presentationId)
203 {
204   // set exception handler to catch unexpected CORBA exceptions
205   Unexpect aCatch(SALOME_SalomeException);
206
207   SALOMEDS::StudyBuilder_var studyBuilder = study->NewBuilder();
208   SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
209
210   SALOMEDS::GenericAttribute_var anAttribute;
211   SALOMEDS::SComponent_var father = study->FindComponent("MED");
212   SALOMEDS::ChildIterator_var it = study->NewChildIterator(father);
213   for (it->InitEx(true); it->More(); it->Next()) {
214     SALOMEDS::SObject_var child(it->Value());
215
216     if (child->FindAttribute(anAttribute, "AttributeParameter")) {
217       SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
218       if (!attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN) || !attrParam->GetBool(IS_PRESENTATION) || !attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
219         continue;
220
221       if (presentationId == attrParam->GetInt(PRESENTATION_ID)) {
222         // remove object from study
223         studyBuilder->RemoveObjectWithChildren(child);
224         // remove object from use case tree
225         useCaseBuilder->Remove(child);
226       }
227     }
228   }
229
230   return MED_ORB::OP_OK;
231 }
232
233 Engines::TMPFile*
234 MED::DumpPython(CORBA::Object_ptr theStudy,
235                 CORBA::Boolean isPublished,
236                 CORBA::Boolean isMultiFile,
237                 CORBA::Boolean& isValidScript)
238 {
239   std::cout << "In MED::DumpPython\n";
240
241   SALOMEDS::Study_var aStudy = SALOMEDS::Study::_narrow(theStudy);
242   if(CORBA::is_nil(aStudy)) {
243     std::cerr << "Error: Cannot find the study\n";
244     return new Engines::TMPFile(0);
245   }
246
247   SALOMEDS::SObject_var aSO = aStudy->FindComponent("MED");
248   if(CORBA::is_nil(aSO)) {
249     std::cerr << "Error: Cannot find component MED\n";
250     return new Engines::TMPFile(0);
251   }
252
253   std::string aScript;
254
255   MEDCALC::CommandsList* history = MEDFactoryClient::getCommandsHistoryManager()->getCommandsHistory();
256   for (CORBA::ULong i = 0; i < history->length(); ++i) {
257     aScript += (*history)[i];
258     aScript += "\n";
259   }
260
261   int aLen = aScript.size();
262   unsigned char* aBuffer = new unsigned char[aLen+1];
263   strcpy((char*)aBuffer, aScript.c_str());
264
265   CORBA::Octet* anOctetBuf =  (CORBA::Octet*)aBuffer;
266   Engines::TMPFile_var aStreamFile = new Engines::TMPFile(aLen+1, aLen+1, anOctetBuf, 1);
267
268   isValidScript = true;
269   return aStreamFile._retn();
270 }
271
272 CORBA::Boolean
273 MED::hasObjectInfo()
274 {
275   return true;
276 }
277
278 char*
279 MED::getObjectInfo(CORBA::Long studyId, const char* entry)
280 {
281   SALOME_LifeCycleCORBA lcc;
282   CORBA::Object_var aSMObject = lcc.namingService()->Resolve( "/myStudyManager" );
283   SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow( aSMObject );
284   SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID( studyId );
285   SALOMEDS::SObject_var aSObj = aStudy->FindObjectID( entry );
286   SALOMEDS::SObject_var aResultSObj;
287   if (aSObj->ReferencedObject(aResultSObj))
288     aSObj = aResultSObj;
289
290   if (aSObj->_is_nil())
291     return CORBA::string_dup("unknown");
292
293   SALOMEDS::GenericAttribute_var anAttribute;
294
295   std::string name("unknown");
296   if (aSObj->FindAttribute(anAttribute, "AttributeName")) {
297     SALOMEDS::AttributeName_var attrName = SALOMEDS::AttributeName::_narrow(anAttribute);
298     name = std::string(attrName->Value());
299   }
300
301   bool isInWorkspace = false;
302   //bool isPresentation = false;
303   int sourceId = -1;
304   int meshId = -1;
305   //int fieldSeriesId = -1;
306   int fieldId = -1;
307   int presentationId = -1;
308   if (aSObj->FindAttribute(anAttribute, "AttributeParameter")) {
309     SALOMEDS::AttributeParameter_var attrParam = SALOMEDS::AttributeParameter::_narrow(anAttribute);
310     if (attrParam->IsSet(IS_IN_WORKSPACE, PT_BOOLEAN))
311       isInWorkspace = attrParam->GetBool(IS_IN_WORKSPACE);
312     //if (attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN))
313     //  isPresentation = attrParam->GetBool(IS_PRESENTATION);
314     if (attrParam->IsSet(SOURCE_ID, PT_INTEGER))
315       sourceId = attrParam->GetInt(SOURCE_ID);
316     if (attrParam->IsSet(MESH_ID, PT_INTEGER))
317       meshId = attrParam->GetInt(MESH_ID);
318     //if (attrParam->IsSet(FIELD_SERIES_ID, PT_INTEGER))
319     //  fieldSeriesId = attrParam->GetInt(FIELD_SERIES_ID);
320     if (attrParam->IsSet(FIELD_ID, PT_INTEGER))
321       fieldId = attrParam->GetInt(FIELD_ID);
322     if (attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
323       presentationId = attrParam->GetInt(PRESENTATION_ID);
324   }
325
326   if (!aSObj->_is_nil() )
327     aSObj->UnRegister();
328
329   std::ostringstream oss;
330   if (sourceId > -1)
331     oss << "Source id: " << sourceId << std::endl;
332   if (meshId > -1)
333     oss << "Mesh id: " << meshId << std::endl;
334   //if (fieldSeriesId > -1)
335   //  oss << "Field series id: " << fieldSeriesId << std::endl;
336   if (fieldId > -1)
337     oss << "Field id: " << fieldId << std::endl;
338   //oss << "Is presentation: " << isPresentation << std::endl;
339   if (presentationId > -1)
340     oss << "Presentation id: " << presentationId << std::endl;
341   oss << "Is in workspace: " << isInWorkspace << std::endl;
342
343   return CORBA::string_dup(oss.str().c_str());
344 }
345
346 extern "C"
347 {
348   /*!
349     \brief Exportable factory function: create an instance of the MED component engine
350     \param orb reference to the ORB
351     \param poa reference to the POA
352     \param contId CORBA object ID, pointing to the owner SALOME container
353     \param instanceName SALOME component instance name
354     \param interfaceName SALOME component interface name
355     \return CORBA object identifier of the registered servant
356   */
357   PortableServer::ObjectId* MEDEngine_factory(CORBA::ORB_ptr orb,
358                                               PortableServer::POA_ptr poa,
359                                               PortableServer::ObjectId* contId,
360                                               const char* instanceName,
361                                               const char* interfaceName)
362   {
363     MED* component = new MED(orb, poa, contId, instanceName, interfaceName);
364     return component->getId();
365   }
366 }