Salome HOME
Merge from V7_siman 11/10/2013
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_SimanStudy_i.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : SALOMEDS_SimanStudy_i.cxx
24 //  Author : Mikhail PONIKAROV
25 //  Module : SALOME
26 //
27 #include "SALOMEDS_SimanStudy_i.hxx"
28 #include "SALOMEDS_Study_i.hxx"
29 #include "SALOMEDS_Study.hxx"
30 #include "SALOMEDS_Tool.hxx"
31 #include "SALOME_DataContainer_i.hxx"
32 #include "SALOME_NamingService.hxx"
33 #include "SALOME_LifeCycleCORBA.hxx"
34 #include "Basics_Utils.hxx"
35 #include "Basics_DirUtils.hxx"
36 #include "utilities.h"
37
38 #ifdef WITH_SIMANIO
39 #include <SimanIO_Link.hxx>
40 #include <SimanIO_Activity.hxx>
41 #endif
42
43 #include <SALOMEconfig.h>
44 #include CORBA_SERVER_HEADER(SALOME_Component)
45
46 //============================================================================
47 /*! Function : SALOMEDS_SimanStudy_i
48  *  Purpose  : standard constructor
49  */
50 //============================================================================
51 SALOMEDS_SimanStudy_i::SALOMEDS_SimanStudy_i(/*SALOMEDSImpl_SimanStudy* theImpl,*/ CORBA::ORB_ptr orb)
52 {
53   _orb = CORBA::ORB::_duplicate(orb);
54   _name_service = new SALOME_NamingService(_orb);
55 #ifdef WITH_SIMANIO
56   _checkedOut = new SimanIO_Configuration;
57 #endif
58 }
59
60 //============================================================================
61 /*! Function : ~SALOMEDS_SimanStudy_i
62  *  Purpose  : standard destructor
63  */
64 //============================================================================
65 SALOMEDS_SimanStudy_i::~SALOMEDS_SimanStudy_i()
66 {
67 #ifdef WITH_SIMANIO
68   if (_checkedOut) {
69     SimanIO_Configuration::ActivitiesIterator actIter(*_checkedOut);
70     for(; actIter.More(); actIter.Next()) {
71       SimanIO_Activity::DocumentsIterator aDocIter(actIter.Activity());
72       for(; aDocIter.More(); aDocIter.Next()) {
73         SimanIO_Document& aDoc = aDocIter.Document();
74         SimanIO_Document::FilesIterator aFileIter(aDoc);
75         for(; aFileIter.More(); aFileIter.Next()) {
76           std::string aURL = aFileIter.URL();
77           std::string aDir = Kernel_Utils::GetDirName(aURL);
78           aDir += "/";
79           std::string aFileName = aURL.substr(aDir.size());
80           SALOMEDS::ListOfFileNames aTmpFiles;
81           aTmpFiles.length(1);
82           aTmpFiles[0] = aFileName.c_str();
83           // try to remove temporary directory that contains this file if directory becomes empty
84           SALOMEDS_Tool::RemoveTemporaryFiles(aDir, aTmpFiles, true);
85         }
86       }
87     }
88     delete _checkedOut;
89   }
90 #endif
91   delete _name_service;
92 }
93
94 //============================================================================
95 /*! Function : CheckOut
96  *  Purpose  : Get data from SIMAN and put it to the given study
97  */
98 //============================================================================
99 void SALOMEDS_SimanStudy_i::CheckOut(SALOMEDS::Study_ptr theTarget)
100 {
101   // SimanStudy and Study must be located at the same place anyway
102   SALOMEDS_Study aStudy(theTarget);
103   _study = aStudy.GetLocalImpl();
104   if (_study) {
105 #ifdef WITH_SIMANIO
106     int aLocked = _study->GetProperties()->IsLocked();
107     if (aLocked) _study->GetProperties()->SetLocked(false);
108   
109     SimanIO_Link aLink(_studyId.c_str(), _scenarioId.c_str(), _userId.c_str());
110     if (aLink.IsConnected()) {
111       // Set "C" locale temporarily to avoid possible localization problems
112       Kernel_Utils::Localizer loc;
113       *_checkedOut = aLink.RetrieveConf();
114       SimanIO_Configuration::ActivitiesIterator actIter(*_checkedOut);
115       for(; actIter.More(); actIter.Next()) {
116         Engines::EngineComponent_var aComp =
117           SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServerPy", actIter.Activity().Module());
118         if (CORBA::is_nil(aComp)) // it is not python container, try to find in C++ container
119           SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServer", actIter.Activity().Module());
120         if (CORBA::is_nil(aComp)) {
121           MESSAGE("Checkout: component "<<actIter.Activity().Module()<<" is nil");
122         } else {
123           SimanIO_Activity::DocumentsIterator aDocIter(actIter.Activity());
124           for(; aDocIter.More(); aDocIter.Next()) {
125             if (_filesId.find(aDocIter.DocId()) == _filesId.end())
126               _filesId[aDocIter.DocId()] = std::map<std::string, int>();
127             SimanIO_Document& aDoc = aDocIter.Document();
128             SimanIO_Document::FilesIterator aFileIter(aDoc);
129             for(; aFileIter.More(); aFileIter.Next()) {
130               if (aFileIter.GetProcessing() == FILE_IMPORT) {
131                 // files provided by SIMAN will be removed later, on study close
132                 Engines::DataContainer_var aData = (new Engines_DataContainer_i(
133                   aFileIter.URL(), aDoc.Name(), "", false))->_this();
134                 Engines::ListOfOptions anEmptyOpts;
135                 Engines::ListOfIdentifiers_var anIds = aComp->importData(_study->StudyId(), aData, anEmptyOpts);
136                 for(int anIdNum = 0; anIdNum < anIds->length(); anIdNum++) {
137                   const char* anId = anIds[anIdNum];
138                   _filesId[aDocIter.DocId()][anId] = aFileIter.Id();
139                 }
140               } else {
141                 MESSAGE("!!! File just downloaded, not imported:"<<aFileIter.Id());
142               }
143             }
144           }
145         }
146       }
147     } else {
148       MESSAGE("There is no connection to SIMAN!");
149     }
150   
151     if (aLocked) _study->GetProperties()->SetLocked(true);
152 #endif
153   }
154 }
155
156 //============================================================================
157 /*! Function : CheckIn
158  *  Purpose  : Get data from SIMAN study and stores to SIMAN
159  */
160 //============================================================================
161 void SALOMEDS_SimanStudy_i::CheckIn(const char* theModuleName)
162 {
163   if (_study) {
164 #ifdef WITH_SIMANIO
165     std::string aModuleName(theModuleName);
166     SimanIO_Link aLink(_studyId.c_str(), _scenarioId.c_str(), _userId.c_str());
167     if (aLink.IsConnected()) {
168       // Set "C" locale temporarily to avoid possible localization problems
169       Kernel_Utils::Localizer loc;
170       SimanIO_Configuration aToStore; // here create and store data in this configuration to check in to SIMAN
171       std::string aTmpDir = SALOMEDS_Tool::GetTmpDir(); // temporary directory for checked in files
172       int aFileIndex = 0; // for unique file name generation
173       std::list<std::string> aTemporaryFileNames;
174       SimanIO_Configuration::ActivitiesIterator actIter(*_checkedOut);
175       for(; actIter.More(); actIter.Next()) {
176         int aDocId = actIter.Activity().DocumentMaxID();
177         //if (aDocId < 0) continue; // no documents => no check in
178         if (!aModuleName.empty() && aModuleName != actIter.Activity().Module()) {
179           continue;
180         }
181         Engines::EngineComponent_var aComp =
182           SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServerPy", actIter.Activity().Module());
183         if (CORBA::is_nil(aComp)) // it is not python container, try to find in C++ container
184           SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServer", actIter.Activity().Module());
185         if (CORBA::is_nil(aComp)) {
186           MESSAGE("Checkin: component "<<actIter.Activity().Module()<<" is nil");
187         } else {
188           SimanIO_Document aDoc;
189           if (aDocId != -1) // get document is at least one exists in this action, "-1" is the Id of the new document otherwise
190             aDoc = actIter.Activity().Document(aDocId);
191           Engines::ListOfData_var aList = aComp->getModifiedData(_study->StudyId());
192           int aNumData = aList->length();
193           for(int aDataIndex = 0; aDataIndex < aNumData; aDataIndex++) {
194             Engines::DataContainer_var aData = aList[aDataIndex];
195             // store this in the configuration
196             SimanIO_Activity& aStoreActivity = aToStore.GetOrCreateActivity(actIter.ActivityId());
197             aStoreActivity.SetName(actIter.Activity().Name());
198             aStoreActivity.SetModule(actIter.Activity().Module());
199             SimanIO_Document& aStoreDoc = aStoreActivity.GetOrCreateDocument(aDocId);
200             aStoreDoc.SetName(aDoc.Name());
201             // prepare a file to store
202             SimanIO_File aStoreFile;
203   
204             std::stringstream aNumStore;
205             aNumStore<<"file"<<(++aFileIndex);
206             std::string aFileName(aNumStore.str());
207             std::string anExtension(aData->extension());
208             aFileName += "." + anExtension;
209             std::string aFullPath = aTmpDir + aFileName;
210             Engines::TMPFile* aFileStream = aData->get();
211             const char *aBuffer = (const char*)aFileStream->NP_data();
212 #ifdef WIN32
213             std::ofstream aFile(aFullPath.c_str(), std::ios::binary);
214 #else
215             std::ofstream aFile(aFullPath.c_str());
216 #endif
217             aFile.write(aBuffer, aFileStream->length());
218             aFile.close();
219             aTemporaryFileNames.push_back(aFileName);
220   
221             aStoreFile.url = aFullPath;
222             if (_filesId[aDocId].find(aData->identifier()) != _filesId[aDocId].end()) { // file is already exists
223               aStoreFile.id = _filesId[aDocId][aData->identifier()];
224               aStoreFile.result = aDoc.File(aStoreFile.id).result;
225             } else {
226               aStoreFile.id = -1; // to be created as new
227               aStoreFile.result = true; // new is always result
228             }
229   
230             aStoreDoc.AddFile(aStoreFile);
231           }
232         }
233       }
234       aLink.StoreConf(aToStore);
235       // after files have been stored, remove them from the temporary directory
236       SALOMEDS::ListOfFileNames aTmpFiles;
237       aTmpFiles.length(aTemporaryFileNames.size());
238       std::list<std::string>::const_iterator aFilesIter = aTemporaryFileNames.begin();
239       for(int a = 0; aFilesIter != aTemporaryFileNames.end(); aFilesIter++, a++) {
240         aTmpFiles[a] = aFilesIter->c_str();
241       }
242       SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir, aTmpFiles, true);
243     } else {
244       MESSAGE("There is no connection to SIMAN!")
245     }
246 #endif
247   }
248 }
249
250 //============================================================================
251 /*! Function : getReferencedStudy
252  *  Purpose  : Returns the %Study with checked out data
253  */
254 //============================================================================
255 SALOMEDS::Study_ptr SALOMEDS_SimanStudy_i::getReferencedStudy()
256 {
257   SALOMEDS::Study_var aStudy = (new SALOMEDS_Study_i(_study, _orb))->_this();
258   return aStudy._retn();
259 }
260
261 //============================================================================
262 /*! Function : StudyId
263  *  Purpose  : The ID of the study in SIMAN server
264  */
265 //============================================================================
266 char* SALOMEDS_SimanStudy_i::StudyId()
267 {
268   return CORBA::string_dup(_studyId.c_str());
269 }
270
271 //============================================================================
272 /*! Function : StudyId
273  *  Purpose  : The ID of the study in SIMAN server
274  */
275 //============================================================================
276 void SALOMEDS_SimanStudy_i::StudyId(const char* theId)
277 {
278   _studyId = theId;
279 }
280
281 //============================================================================
282 /*! Function : ScenarioId
283  *  Purpose  : The ID of the scenario in SIMAN server
284  */
285 //============================================================================
286 char* SALOMEDS_SimanStudy_i::ScenarioId()
287 {
288   return CORBA::string_dup(_scenarioId.c_str());
289 }
290
291 //============================================================================
292 /*! Function : ScenarioId
293  *  Purpose  : The ID of the scenario in SIMAN server
294  */
295 //============================================================================
296 void SALOMEDS_SimanStudy_i::ScenarioId(const char* theId)
297 {
298   _scenarioId = theId;
299 }
300
301 //============================================================================
302 /*! Function : UserId
303  *  Purpose  : The ID of the user in SIMAN server
304  */
305 //============================================================================
306 char* SALOMEDS_SimanStudy_i::UserId()
307 {
308   return CORBA::string_dup(_userId.c_str());
309 }
310
311 //============================================================================
312 /*! Function : UserId
313  *  Purpose  : The ID of the user in SIMAN server
314  */
315 //============================================================================
316 void SALOMEDS_SimanStudy_i::UserId(const char* theId)
317 {
318   _userId = theId;
319 }
320
321 SALOMEDS_SimanStudy_i* SALOMEDS_SimanStudy_i::GetSimanServant(CORBA::ORB_ptr orb)
322 {
323   static SALOMEDS_SimanStudy_i* aServant = 0;
324   if (aServant == 0) {
325     aServant = new SALOMEDS_SimanStudy_i(orb);
326   }
327   return aServant;
328 }
329                                   
330 /// PRIVATE FUNCTIONS
331 /*
332 CORBA::LongLong SALOMEDS_SimanStudy_i::GetLocalImpl(const char* theHostname, CORBA::Long thePID, CORBA::Boolean& isLocal)
333 {
334 #ifdef WIN32
335   long pid = (long)_getpid();
336 #else
337   long pid = (long)getpid();
338 #endif
339   isLocal = (strcmp(theHostname, Kernel_Utils::GetHostname().c_str()) == 0 && pid == thePID)?1:0;
340   return reinterpret_cast<CORBA::LongLong>(_impl);
341 }
342 */