Salome HOME
merge from branch BR_V5_DEV
[modules/kernel.git] / src / LifeCycleCORBA / SALOME_FileTransferCORBA.cxx
1 //  Copyright (C) 2007-2008  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 //  File   : SALOME_FileTransferCORBA.cxx
23 //  Author : Paul RASCLE, EDF
24 //  Module : SALOME
25 //  $Header$
26 //
27 #include "SALOME_FileTransferCORBA.hxx"
28 #include "SALOME_LifeCycleCORBA.hxx"
29 #include "utilities.h"
30 #include "Basics_Utils.hxx"
31
32 using namespace std;
33
34 //=============================================================================
35 /*! 
36  *  Default constructor, not for use.
37  */
38 //=============================================================================
39
40 SALOME_FileTransferCORBA::SALOME_FileTransferCORBA()
41 {
42   ASSERT(0);
43 }
44
45 //=============================================================================
46 /*! 
47  *  Constructor to use when we get a fileRef CORBA object from a component.
48  *  \param aFileRef file reference CORBA object
49  */
50 //=============================================================================
51
52 SALOME_FileTransferCORBA::SALOME_FileTransferCORBA(Engines::fileRef_ptr
53                                                    aFileRef)
54 {
55   MESSAGE("SALOME_FileTransferCORBA::SALOME_FileTransferCORBA(aFileRef)");
56   _theFileRef = aFileRef;
57 }
58
59 //=============================================================================
60 /*! 
61  *  Constructor to use when we have the file name and machine from which to
62  *  copy, plus an optional Container name on the machine.
63  *  \param refMachine    the machine on which is the file to transfer
64  *  \param origFileName  abolute file path on refMachine
65  *  \param containerName default container name used (FactoryServer) if empty
66  */
67 //=============================================================================
68
69 SALOME_FileTransferCORBA::SALOME_FileTransferCORBA(string refMachine,
70                                                    string origFileName,
71                                                    string containerName)
72 {
73   MESSAGE("SALOME_FileTransferCORBA::SALOME_FileTransferCORBA"
74           << refMachine << " " << origFileName  << " " << containerName);
75   _refMachine = refMachine;
76   _origFileName = origFileName;
77   _containerName = containerName;
78   if (_refMachine.empty() || _origFileName.empty())
79     {
80       INFOS("bad parameters: machine and file name must be given");
81     } 
82 }
83
84 //=============================================================================
85 /*! 
86  *  Destructor
87  */
88 //=============================================================================
89
90 SALOME_FileTransferCORBA::~SALOME_FileTransferCORBA()
91 {
92   MESSAGE("SALOME_FileTransferCORBA::~SALOME_FileTransferCORBA");
93 }
94
95 //=============================================================================
96 /*! 
97  *  CORBA method: get a local copy of the reference file.
98  *  \param  localFile optional absolute path to store the copy
99  *  \return the file name (absolute path) of the copy, may be different from
100  *          localFile parameter if the copy was already done before the call
101  */
102 //=============================================================================
103
104 string SALOME_FileTransferCORBA::getLocalFile(string localFile)
105 {
106   MESSAGE("SALOME_FileTransferCORBA::getLocalFile " << localFile);
107
108   Engines::Container_var container;
109
110   if (CORBA::is_nil(_theFileRef))
111     {
112       if (_refMachine.empty() || _origFileName.empty())
113         {
114           INFOS("not enough parameters: machine and file name must be given");
115           return "";
116         }
117
118       SALOME_LifeCycleCORBA LCC;
119       Engines::ContainerManager_var contManager = LCC.getContainerManager();
120       Engines::ResourcesManager_var resManager = LCC.getResourcesManager();
121
122       Engines::MachineParameters params;
123       LCC.preSet(params);
124       params.container_name = _containerName.c_str();
125       params.hostname = _refMachine.c_str();
126
127       Engines::CompoList clist;
128       Engines::MachineList_var listOfMachines =
129         resManager->GetFittingResources(params, clist);
130
131       container = contManager->FindOrStartContainer(params,
132                                                     listOfMachines);
133       if (CORBA::is_nil(container))
134         {
135           INFOS("machine " << _refMachine << " unreachable");
136           return "";
137         }
138
139       _theFileRef = container->createFileRef(_origFileName.c_str());
140       if (CORBA::is_nil(_theFileRef))
141         {
142           INFOS("imposssible to create fileRef on " << _refMachine);
143           return "";
144         }
145     }
146
147   container = _theFileRef->getContainer();
148   ASSERT(! CORBA::is_nil(container));
149
150   string myMachine = Kernel_Utils::GetHostname();
151   string localCopy = _theFileRef->getRef(myMachine.c_str());
152
153   if (localCopy.empty()) // no existing copy available
154     {
155       if (localFile.empty()) // no name provided for local copy
156         {
157           char bufName[256];
158           localCopy = tmpnam(bufName);
159           localFile = bufName;
160           SCRUTE(localFile);
161         }
162
163       FILE* fp;
164       if ((fp = fopen(localFile.c_str(),"wb")) == NULL)
165         {
166           INFOS("file " << localFile << " cannot be open for writing");
167           return "";
168         }
169
170       Engines::fileTransfer_var fileTransfer = container->getFileTransfer();
171       ASSERT(! CORBA::is_nil(fileTransfer));
172
173       CORBA::Long fileId = fileTransfer->open(_origFileName.c_str());
174       if (fileId > 0)
175         {
176           Engines::fileBlock* aBlock;
177           int toFollow = 1;
178           int ctr=0;
179           while (toFollow)
180             {
181               ctr++;
182               SCRUTE(ctr);
183               aBlock = fileTransfer->getBlock(fileId);
184               toFollow = aBlock->length();
185               SCRUTE(toFollow);
186               CORBA::Octet *buf = aBlock->get_buffer();
187 #if defined(_DEBUG_) || defined(_DEBUG)
188               int nbWri = fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
189               ASSERT(nbWri == toFollow);
190 #else
191               fwrite(buf, sizeof(CORBA::Octet), toFollow, fp);
192 #endif
193               delete aBlock;
194             }
195           fclose(fp);
196           MESSAGE("end of transfer");
197           fileTransfer->close(fileId);
198           _theFileRef->addRef(myMachine.c_str(), localFile.c_str());
199           localCopy = localFile;
200         }
201       else
202         {
203           INFOS("open reference file for copy impossible");
204           return "";
205         }
206       
207     }
208   SCRUTE(localCopy);
209   return localCopy;
210 }