Salome HOME
f2ce5e79ac0ea67491693165b0f8d01ea85f76fa
[modules/kernel.git] / src / SALOMEDS / SALOMEDS_SimanStudy_i.cxx
1 // Copyright (C) 2007-2014  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, or (at your option) any later version.
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("FactoryServer", actIter.Activity().Module());
118         if (CORBA::is_nil(aComp)) {
119           MESSAGE("Checkout: component "<<actIter.Activity().Module()<<" is nil");
120         } else {
121           SimanIO_Activity::DocumentsIterator aDocIter(actIter.Activity());
122           for(; aDocIter.More(); aDocIter.Next()) {
123             if (_filesId.find(aDocIter.DocId()) == _filesId.end())
124               _filesId[aDocIter.DocId()] = std::map<std::string, int>();
125             SimanIO_Document& aDoc = aDocIter.Document();
126             SimanIO_Document::FilesIterator aFileIter(aDoc);
127             for(; aFileIter.More(); aFileIter.Next()) {
128               if (aFileIter.GetProcessing() == FILE_IMPORT) {
129                 // files provided by SIMAN will be removed later, on study close
130                 Engines::DataContainer_var aData = (new Engines_DataContainer_i(
131                   aFileIter.URL(), aDoc.Name(), "", false))->_this();
132                 Engines::ListOfOptions anEmptyOpts;
133                 Engines::ListOfIdentifiers_var anIds = aComp->importData(_study->StudyId(), aData, anEmptyOpts);
134                 for(int anIdNum = 0; anIdNum < anIds->length(); anIdNum++) {
135                   const char* anId = anIds[anIdNum];
136                   _filesId[aDocIter.DocId()][anId] = aFileIter.Id();
137                 }
138               } else {
139                 MESSAGE("!!! File just downloaded, not imported:"<<aFileIter.Id());
140               }
141             }
142           }
143         }
144       }
145     } else {
146       MESSAGE("There is no connection to SIMAN!");
147     }
148   
149     if (aLocked) _study->GetProperties()->SetLocked(true);
150 #endif
151   }
152 }
153
154 //============================================================================
155 /*! Function : CheckIn
156  *  Purpose  : Get data from SIMAN study and stores to SIMAN
157  */
158 //============================================================================
159 void SALOMEDS_SimanStudy_i::CheckIn(const char* theModuleName)
160 {
161   if (_study) {
162 #ifdef WITH_SIMANIO
163     std::string aModuleName(theModuleName);
164     SimanIO_Link aLink(_studyId.c_str(), _scenarioId.c_str(), _userId.c_str());
165     if (aLink.IsConnected()) {
166       // Set "C" locale temporarily to avoid possible localization problems
167       Kernel_Utils::Localizer loc;
168       SimanIO_Configuration aToStore; // here create and store data in this configuration to check in to SIMAN
169       std::string aTmpDir = SALOMEDS_Tool::GetTmpDir(); // temporary directory for checked in files
170       int aFileIndex = 0; // for unique file name generation
171       std::list<std::string> aTemporaryFileNames;
172       SimanIO_Configuration::ActivitiesIterator actIter(*_checkedOut);
173       for(; actIter.More(); actIter.Next()) {
174         int aDocId = actIter.Activity().DocumentMaxID();
175         //if (aDocId < 0) continue; // no documents => no check in
176         if (!aModuleName.empty() && aModuleName != actIter.Activity().Module()) {
177           continue;
178         }
179         Engines::EngineComponent_var aComp =
180           SALOME_LifeCycleCORBA(_name_service).FindOrLoad_Component("FactoryServer", actIter.Activity().Module());
181         if (CORBA::is_nil(aComp)) {
182           MESSAGE("Checkin: component "<<actIter.Activity().Module()<<" is nil");
183         } else {
184           SimanIO_Document aDoc;
185           if (aDocId != -1) // get document is at least one exists in this action, "-1" is the Id of the new document otherwise
186             aDoc = actIter.Activity().Document(aDocId);
187           Engines::ListOfData_var aList = aComp->getModifiedData(_study->StudyId());
188           int aNumData = aList->length();
189           for(int aDataIndex = 0; aDataIndex < aNumData; aDataIndex++) {
190             Engines::DataContainer_var aData = aList[aDataIndex];
191             // store this in the configuration
192             SimanIO_Activity& aStoreActivity = aToStore.GetOrCreateActivity(actIter.ActivityId());
193             aStoreActivity.SetName(actIter.Activity().Name());
194             aStoreActivity.SetModule(actIter.Activity().Module());
195             SimanIO_Document& aStoreDoc = aStoreActivity.GetOrCreateDocument(aDocId);
196             aStoreDoc.SetName(aDoc.Name());
197             // prepare a file to store
198             SimanIO_File aStoreFile;
199   
200             std::stringstream aNumStore;
201             aNumStore<<"file"<<(++aFileIndex);
202             std::string aFileName(aNumStore.str());
203             std::string anExtension(aData->extension());
204             aFileName += "." + anExtension;
205             std::string aFullPath = aTmpDir + aFileName;
206             Engines::TMPFile* aFileStream = aData->get();
207             const char *aBuffer = (const char*)aFileStream->NP_data();
208 #ifdef WIN32
209             std::ofstream aFile(aFullPath.c_str(), std::ios::binary);
210 #else
211             std::ofstream aFile(aFullPath.c_str());
212 #endif
213             aFile.write(aBuffer, aFileStream->length());
214             aFile.close();
215             aTemporaryFileNames.push_back(aFileName);
216   
217             aStoreFile.url = aFullPath;
218             if (_filesId[aDocId].find(aData->identifier()) != _filesId[aDocId].end()) { // file is already exists
219               aStoreFile.id = _filesId[aDocId][aData->identifier()];
220               aStoreFile.result = aDoc.File(aStoreFile.id).result;
221             } else {
222               aStoreFile.id = -1; // to be created as new
223               aStoreFile.result = true; // new is always result
224             }
225   
226             aStoreDoc.AddFile(aStoreFile);
227           }
228         }
229       }
230       aLink.StoreConf(aToStore);
231       // after files have been stored, remove them from the temporary directory
232       SALOMEDS::ListOfFileNames aTmpFiles;
233       aTmpFiles.length(aTemporaryFileNames.size());
234       std::list<std::string>::const_iterator aFilesIter = aTemporaryFileNames.begin();
235       for(int a = 0; aFilesIter != aTemporaryFileNames.end(); aFilesIter++, a++) {
236         aTmpFiles[a] = aFilesIter->c_str();
237       }
238       SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir, aTmpFiles, true);
239     } else {
240       MESSAGE("There is no connection to SIMAN!")
241     }
242 #endif
243   }
244 }
245
246 //============================================================================
247 /*! Function : getReferencedStudy
248  *  Purpose  : Returns the %Study with checked out data
249  */
250 //============================================================================
251 SALOMEDS::Study_ptr SALOMEDS_SimanStudy_i::getReferencedStudy()
252 {
253   SALOMEDS::Study_var aStudy = (new SALOMEDS_Study_i(_study, _orb))->_this();
254   return aStudy._retn();
255 }
256
257 //============================================================================
258 /*! Function : StudyId
259  *  Purpose  : The ID of the study in SIMAN server
260  */
261 //============================================================================
262 char* SALOMEDS_SimanStudy_i::StudyId()
263 {
264   return CORBA::string_dup(_studyId.c_str());
265 }
266
267 //============================================================================
268 /*! Function : StudyId
269  *  Purpose  : The ID of the study in SIMAN server
270  */
271 //============================================================================
272 void SALOMEDS_SimanStudy_i::StudyId(const char* theId)
273 {
274   _studyId = theId;
275 }
276
277 //============================================================================
278 /*! Function : ScenarioId
279  *  Purpose  : The ID of the scenario in SIMAN server
280  */
281 //============================================================================
282 char* SALOMEDS_SimanStudy_i::ScenarioId()
283 {
284   return CORBA::string_dup(_scenarioId.c_str());
285 }
286
287 //============================================================================
288 /*! Function : ScenarioId
289  *  Purpose  : The ID of the scenario in SIMAN server
290  */
291 //============================================================================
292 void SALOMEDS_SimanStudy_i::ScenarioId(const char* theId)
293 {
294   _scenarioId = theId;
295 }
296
297 //============================================================================
298 /*! Function : UserId
299  *  Purpose  : The ID of the user in SIMAN server
300  */
301 //============================================================================
302 char* SALOMEDS_SimanStudy_i::UserId()
303 {
304   return CORBA::string_dup(_userId.c_str());
305 }
306
307 //============================================================================
308 /*! Function : UserId
309  *  Purpose  : The ID of the user in SIMAN server
310  */
311 //============================================================================
312 void SALOMEDS_SimanStudy_i::UserId(const char* theId)
313 {
314   _userId = theId;
315 }
316
317 SALOMEDS_SimanStudy_i* SALOMEDS_SimanStudy_i::GetSimanServant(CORBA::ORB_ptr orb)
318 {
319   static SALOMEDS_SimanStudy_i* aServant = 0;
320   if (aServant == 0) {
321     aServant = new SALOMEDS_SimanStudy_i(orb);
322   }
323   return aServant;
324 }
325                                   
326 /// PRIVATE FUNCTIONS
327 /*
328 CORBA::LongLong SALOMEDS_SimanStudy_i::GetLocalImpl(const char* theHostname, CORBA::Long thePID, CORBA::Boolean& isLocal)
329 {
330 #ifdef WIN32
331   long pid = (long)_getpid();
332 #else
333   long pid = (long)getpid();
334 #endif
335   isLocal = (strcmp(theHostname, Kernel_Utils::GetHostname().c_str()) == 0 && pid == thePID)?1:0;
336   return reinterpret_cast<CORBA::LongLong>(_impl);
337 }
338 */