Salome HOME
d4faed75c3df3f66f1b2161962a5e65cd6940075
[modules/kernel.git] / src / ResourcesManager / SALOME_ResourcesCatalog_Handler.cxx
1 // Copyright (C) 2007-2011  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 //  SALOME ResourcesCatalog : implementation of catalog resources parsing (SALOME_ModuleCatalog.idl)
24 //  File   : SALOME_ResourcesCatalog_Handler.cxx
25 //  Author : Estelle Deville
26 //  Module : SALOME
27 //$Header$
28 //
29 #include "SALOME_ResourcesCatalog_Handler.hxx"
30 #include "Basics_Utils.hxx"
31 #include "Utils_SALOME_Exception.hxx"
32 #include <iostream>
33 #include <sstream>
34 #include <map>
35
36 //=============================================================================
37 /*!
38  *  Constructor
39  *  \param listOfResources: map of ParserResourcesType to fill when parsing
40  */ 
41 //=============================================================================
42
43 SALOME_ResourcesCatalog_Handler::
44 SALOME_ResourcesCatalog_Handler(MapOfParserResourcesType& resources_list): _resources_list(resources_list)
45 {
46   //XML tags initialisation
47   test_machine = "machine";
48   test_cluster = "cluster";
49   test_name = "name";
50   test_hostname = "hostname";
51   test_protocol = "protocol";
52   test_cluster_internal_protocol = "iprotocol";
53   test_mode = "mode";
54   test_batch = "batch";
55   test_mpi = "mpi";
56   test_user_name = "userName";
57   test_appli_path = "appliPath";
58   test_modules = "modules";
59   test_module_name = "moduleName";
60   test_components = "component";
61   test_component_name = "name";
62   test_os = "OS";
63   test_mem_in_mb = "memInMB";
64   test_cpu_freq_mhz = "CPUFreqMHz";
65   test_nb_of_nodes = "nbOfNodes";
66   test_nb_of_proc = "nbOfProc";
67   test_nb_of_proc_per_node = "nbOfProcPerNode";
68   test_batch_queue = "batchQueue";
69   test_user_commands = "userCommands";
70   test_use = "use";
71   test_members = "members";
72 }
73
74 //=============================================================================
75 /*!
76  *  Destructor
77  */ 
78 //=============================================================================
79
80 SALOME_ResourcesCatalog_Handler::~SALOME_ResourcesCatalog_Handler()
81 {
82   //  cout << "SALOME_ResourcesCatalog_Handler destruction") << endl;
83 }
84
85 //=============================================================================
86 /*!
87  *  Retrieves DS after the file parse.
88  */ 
89 //=============================================================================
90
91 const MapOfParserResourcesType&
92 SALOME_ResourcesCatalog_Handler::GetResourcesAfterParsing() const
93 {
94   return _resources_list;
95 }
96
97 //=============================================================================
98 /*!
99  *  Processes XML document and fills the list of resources
100  */ 
101 //=============================================================================
102
103 void SALOME_ResourcesCatalog_Handler::ProcessXmlDocument(xmlDocPtr theDoc)
104 {
105   // Empty private elements
106   _resources_list.clear();
107
108   //default resources
109   _resource.Clear();
110   _resource.HostName = Kernel_Utils::GetHostname();
111   _resource.Name = Kernel_Utils::GetHostname();
112   _resource.DataForSort._Name = Kernel_Utils::GetHostname();
113   _resources_list[Kernel_Utils::GetHostname()] = _resource;
114
115   // Get the document root node
116   xmlNodePtr aCurNode = xmlDocGetRootElement(theDoc);
117
118   aCurNode = aCurNode->xmlChildrenNode;
119  
120   // Processing the document nodes
121   while(aCurNode != NULL)
122   {
123     // Cas d'une machine ou d'une machine batch
124     if (!xmlStrcmp(aCurNode->name,(const xmlChar*)test_machine))
125     {
126       _resource.Clear();
127       bool Ok = ProcessMachine(aCurNode, _resource);
128       if (Ok)
129       {
130         // Adding a resource
131         if(_resource.HostName == "localhost")
132         {
133           _resource.HostName = Kernel_Utils::GetHostname();
134         }
135         std::map<std::string, ParserResourcesType>::const_iterator iter = _resources_list.find(_resource.Name);
136         if (iter != _resources_list.end())
137           RES_INFOS("Warning resource " << _resource.Name << " already added, keep last resource found !");
138         _resources_list[_resource.Name] = _resource;
139       }
140     }
141     // Cas de la déclaration d'un cluster
142     if (!xmlStrcmp(aCurNode->name,(const xmlChar*)test_cluster))
143     {
144       _resource.Clear();
145       if(ProcessCluster(aCurNode, _resource))
146       {
147         std::map<std::string, ParserResourcesType>::const_iterator iter = _resources_list.find(_resource.Name);
148         if (iter != _resources_list.end())
149           RES_INFOS("Warning resource " << _resource.Name << " already added, keep last resource found !");
150         _resources_list[_resource.Name] = _resource;
151       }
152     }
153     aCurNode = aCurNode->next;
154   }
155
156 #ifdef _DEBUG_
157   for (std::map<std::string, ParserResourcesType>::const_iterator iter = _resources_list.begin();
158        iter != _resources_list.end();
159        iter++)
160   {
161     std::cerr << "************************************************" << std::endl;
162     std::cerr << "Resource " << (*iter).first << " found:" << std::endl;
163     std::cerr << " Name: " << (*iter).second.Name << std::endl;
164     std::cerr << " Hostname: " << (*iter).second.HostName << std::endl;
165     std::cerr << " Username: " << (*iter).second.UserName << std::endl;
166     std::cerr << " Appli path: " <<(*iter).second.AppliPath << std::endl;
167     std::cerr << " OS: " << (*iter).second.OS << std::endl;
168     std::cerr << " Protocol: " << (*iter).second.PrintAccessProtocolType() << std::endl;
169     std::cerr << " Internal Protocol: " <<(*iter).second.PrintClusterInternalProtocol() << std::endl;
170     std::cerr << " Mode: " << (*iter).second.PrintAccessModeType() << std::endl;
171     std::cerr << " Batch Type: " << (*iter).second.PrintBatchType() << std::endl;
172     std::cerr << " MPI Impl: " << (*iter).second.PrintMpiImplType() << std::endl;
173     std::cerr << "************************************************" << std::endl;
174   }
175 #endif
176 }
177
178 bool
179 SALOME_ResourcesCatalog_Handler::ProcessCluster(xmlNodePtr cluster_descr, ParserResourcesType & resource)
180 {
181   // Ajout d'un cluster
182   // hostname, use et nbOfProc sont obligatoires
183   if (xmlHasProp(cluster_descr, (const xmlChar*)test_hostname))
184   {
185     xmlChar* hostname = xmlGetProp(cluster_descr, (const xmlChar*)test_hostname);
186     resource.HostName = (const char*)hostname;
187     xmlFree(hostname);
188   }
189   else
190   {
191     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a hostname" << std::endl;
192     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" << std::endl;
193     return false;
194   }
195
196   if (xmlHasProp(cluster_descr, (const xmlChar*)test_name))
197   {
198     xmlChar* name = xmlGetProp(cluster_descr, (const xmlChar*)test_name);
199     resource.Name = (const char*)name;
200     resource.DataForSort._Name = (const char*)name;
201     xmlFree(name);
202   }
203   else
204   {
205     resource.Name = resource.HostName;
206     resource.DataForSort._Name = resource.HostName;
207     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! No Name found use Hostname for resource: " << _resource.Name << std::endl;
208   }
209
210   if (xmlHasProp(cluster_descr, (const xmlChar*)test_use))
211   {
212     xmlChar* use = xmlGetProp(cluster_descr, (const xmlChar*)test_use);
213     resource.use = (const char*)use;
214     xmlFree(use);
215   }
216   else
217   {
218     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a use" << std::endl;
219     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" << std::endl;
220     return false;
221   }
222
223   if (xmlHasProp(cluster_descr, (const xmlChar*)test_nb_of_proc))
224   {
225     xmlChar* nb_of_proc = xmlGetProp(cluster_descr, (const xmlChar*)test_nb_of_proc);
226     resource.nbOfProc = atoi((const char*)nb_of_proc);
227     xmlFree(nb_of_proc);
228   }
229   else
230   {
231     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a nbOfProc" << std::endl;
232     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" << std::endl;
233     return false;
234   }
235
236   if (xmlHasProp(cluster_descr, (const xmlChar*)test_mpi))
237   {
238     xmlChar* mpi = xmlGetProp(cluster_descr, (const xmlChar*)test_mpi);
239     std::string anMpi = (const char*)mpi;
240     xmlFree(mpi);
241     if (anMpi == "lam")
242       resource.mpi = lam;
243     else if (anMpi == "mpich1")
244       resource.mpi = mpich1;
245     else if (anMpi == "mpich2")
246       resource.mpi = mpich2;
247     else if (anMpi == "openmpi")
248       resource.mpi = openmpi;
249     else if  (anMpi == "slurmmpi")
250       resource.mpi = slurmmpi;
251     else if  (anMpi == "prun")
252       resource.mpi = prun;
253     else
254       resource.mpi = nompi;
255   }
256
257   // Parsing des membres du cluster 
258   xmlNodePtr aCurSubNode = cluster_descr->xmlChildrenNode;
259   while(aCurSubNode != NULL)
260   {
261     if (!xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_members))
262     {
263        xmlNodePtr members = aCurSubNode->xmlChildrenNode;
264        while (members != NULL)
265        {
266          // Process members
267          if (!xmlStrcmp(members->name, (const xmlChar*)test_machine))
268          {
269            ParserResourcesClusterMembersType new_member;
270            if (ProcessMember(members, new_member))
271              resource.ClusterMembersList.push_back(new_member);
272          }
273          members = members->next;
274        }
275     }
276     aCurSubNode = aCurSubNode->next;
277   }
278
279   // Test: Il faut au moins un membre pour que le cluster soit correct !
280   if (resource.ClusterMembersList.empty())
281   {
282     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! found a cluster without a member" << std::endl;
283     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessCluster : !!! Warning !!! this cluster will not be added" << std::endl;
284     return false;
285   }
286   return true;
287 }
288
289 bool
290 SALOME_ResourcesCatalog_Handler::ProcessMember(xmlNodePtr member_descr, ParserResourcesClusterMembersType & resource)
291 {
292   if (xmlHasProp(member_descr, (const xmlChar*)test_hostname))
293   {
294     xmlChar* hostname = xmlGetProp(member_descr, (const xmlChar*)test_hostname);
295     resource.HostName = (const char*)hostname;
296     xmlFree(hostname);
297   }
298   else
299   {
300     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a hostname" << std::endl;
301     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
302     return false;
303   }
304
305   if (xmlHasProp(member_descr, (const xmlChar*)test_protocol))
306   {
307     xmlChar* protocol= xmlGetProp(member_descr, (const xmlChar*)test_protocol);
308     try
309     {
310       resource.Protocol = ParserResourcesType::stringToProtocol((const char *)protocol);
311     }
312     catch (SALOME_Exception e)
313     {
314       std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine with a bad protocol" << std::endl;
315       std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
316       return false;
317     }
318     xmlFree(protocol);
319   }
320   else
321   {
322     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a protocol" << std::endl;
323     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
324     return false;
325   }
326
327   if (xmlHasProp(member_descr, (const xmlChar*)test_cluster_internal_protocol))
328   {
329     xmlChar* iprotocol= xmlGetProp(member_descr, (const xmlChar*)test_cluster_internal_protocol);
330     try
331     {
332       resource.ClusterInternalProtocol = ParserResourcesType::stringToProtocol((const char *)iprotocol);
333     }
334     catch (SALOME_Exception e)
335     {
336       std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine with a bad protocol" << std::endl;
337       std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
338       return false;
339     }
340     xmlFree(iprotocol);
341   }
342   else
343   {
344     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a protocol" << std::endl;
345     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
346     return false;
347   }
348
349   if (xmlHasProp(member_descr, (const xmlChar*)test_user_name))
350   {
351     xmlChar* user_name= xmlGetProp(member_descr, (const xmlChar*)test_user_name);
352     resource.UserName = (const char*)user_name;
353     xmlFree(user_name);
354   }
355   else
356   {
357     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a user name" << std::endl;
358     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
359     return false;
360   }
361
362   if (xmlHasProp(member_descr, (const xmlChar*)test_nb_of_nodes))
363   {
364     xmlChar* nb_of_nodes = xmlGetProp(member_descr, (const xmlChar*)test_nb_of_nodes);
365     resource.DataForSort._nbOfNodes = atoi((const char*)nb_of_nodes);
366     xmlFree(nb_of_nodes);
367   }
368   else
369   {
370     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a nbOfNodes" << std::endl;
371     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
372     return false;
373   }
374
375   if (xmlHasProp(member_descr, (const xmlChar*)test_nb_of_proc_per_node))
376   {
377     xmlChar* nb_of_proc_per_node = xmlGetProp(member_descr, (const xmlChar*)test_nb_of_proc_per_node);
378     resource.DataForSort._nbOfProcPerNode = atoi((const char*)nb_of_proc_per_node);
379     xmlFree(nb_of_proc_per_node);
380   }
381   else
382   {
383     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a nbOfProcPerNode" << std::endl;
384     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
385     return false;
386   }
387
388   if (xmlHasProp(member_descr, (const xmlChar*)test_appli_path))
389   {
390     xmlChar* appli_path = xmlGetProp(member_descr, (const xmlChar*)test_appli_path);
391     resource.AppliPath = (const char*)appli_path;
392     xmlFree(appli_path);
393   }
394   else
395   {
396     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning found a machine without a AppliPath" << std::endl;
397     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMember : Warning this machine will not be added" << std::endl;
398     return false;
399   }
400   return true;
401 }
402
403 bool
404 SALOME_ResourcesCatalog_Handler::ProcessMachine(xmlNodePtr machine_descr, ParserResourcesType & resource)
405 {
406   if (xmlHasProp(machine_descr, (const xmlChar*)test_hostname))
407   {
408     xmlChar* hostname = xmlGetProp(machine_descr, (const xmlChar*)test_hostname);
409     resource.HostName = (const char*)hostname;
410     xmlFree(hostname);
411   }
412   else
413   {
414     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMachine : Warning found a machine without a hostname" << std::endl;
415     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMachine : Warning this machine will not be added" << std::endl;
416     return false;
417   }
418
419   if (xmlHasProp(machine_descr, (const xmlChar*)test_name))
420   {
421     xmlChar* name = xmlGetProp(machine_descr, (const xmlChar*)test_name);
422     resource.Name = (const char*)name;
423     resource.DataForSort._Name = (const char*)name;
424     xmlFree(name);
425   }
426   else
427   {
428     resource.Name = resource.HostName;
429     resource.DataForSort._Name = resource.HostName;
430     std::cerr << "SALOME_ResourcesCatalog_Handler::ProcessMachine : !!! Warning !!! No Name found use Hostname for resource: " << _resource.Name << std::endl;
431   }
432
433   if (xmlHasProp(machine_descr, (const xmlChar*)test_batch_queue))
434   {
435     xmlChar* batch_queue = xmlGetProp(machine_descr, (const xmlChar*)test_batch_queue);
436     resource.batchQueue = (const char*)batch_queue;
437     xmlFree(batch_queue);
438   }
439   else
440     resource.batchQueue = "";
441
442   if (xmlHasProp(machine_descr, (const xmlChar*)test_user_commands))
443   {
444     xmlChar* user_commands= xmlGetProp(machine_descr, (const xmlChar*)test_user_commands);
445     resource.userCommands = (const char*)user_commands;
446     xmlFree(user_commands);
447   }
448   else
449     resource.userCommands = "";
450
451   if (xmlHasProp(machine_descr, (const xmlChar*)test_protocol))
452   {
453     xmlChar* protocol= xmlGetProp(machine_descr, (const xmlChar*)test_protocol);
454     try
455     {
456       resource.Protocol = ParserResourcesType::stringToProtocol((const char *)protocol);
457     }
458     catch (SALOME_Exception e)
459     {
460       // If it'not in all theses cases, the protocol is affected to rsh
461       resource.Protocol = rsh;
462     }
463     xmlFree(protocol);
464   }
465   else
466     resource.Protocol = rsh;
467
468   if (xmlHasProp(machine_descr, (const xmlChar*)test_cluster_internal_protocol))
469   {
470     xmlChar* iprotocol= xmlGetProp(machine_descr, (const xmlChar*)test_cluster_internal_protocol);
471     try
472     {
473       resource.ClusterInternalProtocol = ParserResourcesType::stringToProtocol((const char *)iprotocol);
474     }
475     catch (SALOME_Exception e)
476     {
477       // If it'not in all theses cases, the protocol is affected to rsh
478       resource.ClusterInternalProtocol = rsh;
479     }
480     xmlFree(iprotocol);
481   }
482   else
483     resource.ClusterInternalProtocol = resource.Protocol;
484
485   if (xmlHasProp(machine_descr, (const xmlChar*)test_mode))
486   {
487     xmlChar* mode=xmlGetProp(machine_descr, (const xmlChar*)test_mode);
488     switch ( mode[0] )
489     {
490       case 'i':
491         resource.Mode = interactive;
492         break;
493       case 'b':
494         resource.Mode = batch;
495         break;
496       default:
497         // If it'not in all theses cases, the mode is affected to interactive
498         resource.Mode = interactive;
499         break;
500     }
501     xmlFree(mode);
502   }
503   else
504     resource.Mode = interactive;
505
506   if (xmlHasProp(machine_descr, (const xmlChar*)test_batch))
507   {
508     xmlChar* batch = xmlGetProp(machine_descr, (const xmlChar*)test_batch);
509     std::string aBatch = (const char*)batch;
510     xmlFree(batch);
511     if (aBatch == "pbs")
512       resource.Batch = pbs;
513     else if  (aBatch == "lsf")
514       resource.Batch = lsf;
515     else if  (aBatch == "sge")
516       resource.Batch = sge;
517     else if  (aBatch == "ssh_batch")
518       resource.Batch = ssh_batch;
519     else if  (aBatch == "ccc")
520       resource.Batch = ccc;
521     else if  (aBatch == "slurm")
522       resource.Batch = slurm;
523     else if  (aBatch == "ll")
524       resource.Batch = ll;
525     else
526       resource.Batch = none;
527   }
528
529   if (xmlHasProp(machine_descr, (const xmlChar*)test_mpi))
530   {
531     xmlChar* mpi = xmlGetProp(machine_descr, (const xmlChar*)test_mpi);
532     std::string anMpi = (const char*)mpi;
533     xmlFree(mpi);
534     if (anMpi == "lam")
535       resource.mpi = lam;
536     else if (anMpi == "mpich1")
537       resource.mpi = mpich1;
538     else if (anMpi == "mpich2")
539       resource.mpi = mpich2;
540     else if (anMpi == "openmpi")
541       resource.mpi = openmpi;
542     else if  (anMpi == "slurmmpi")
543       resource.mpi = slurmmpi;
544     else if  (anMpi == "prun")
545       resource.mpi = prun;
546     else
547       resource.mpi = nompi;
548   }
549
550   if (xmlHasProp(machine_descr, (const xmlChar*)test_user_name))
551   {
552     xmlChar* user_name= xmlGetProp(machine_descr, (const xmlChar*)test_user_name);
553     resource.UserName = (const char*)user_name;
554     xmlFree(user_name);
555   }
556
557   if (xmlHasProp(machine_descr, (const xmlChar*)test_appli_path))
558   {
559     xmlChar* appli_path = xmlGetProp(machine_descr, (const xmlChar*)test_appli_path);
560     resource.AppliPath = (const char*)appli_path;
561     xmlFree(appli_path);
562   }
563
564   if (xmlHasProp(machine_descr, (const xmlChar*)test_os))
565   {
566     xmlChar* os = xmlGetProp(machine_descr, (const xmlChar*)test_os);
567     resource.OS = (const char*)os;
568     xmlFree(os);
569   }
570
571   if (xmlHasProp(machine_descr, (const xmlChar*)test_mem_in_mb))
572   {
573     xmlChar* mem_in_mb = xmlGetProp(machine_descr, (const xmlChar*)test_mem_in_mb);
574     resource.DataForSort._memInMB = atoi((const char*)mem_in_mb);
575     xmlFree(mem_in_mb);
576   }
577
578   if (xmlHasProp(machine_descr, (const xmlChar*)test_cpu_freq_mhz))
579   {
580     xmlChar* cpu_freq_mhz = xmlGetProp(machine_descr, (const xmlChar*)test_cpu_freq_mhz);
581     resource.DataForSort._CPUFreqMHz = atoi((const char*)cpu_freq_mhz);
582     xmlFree(cpu_freq_mhz);
583   }
584
585   if (xmlHasProp(machine_descr, (const xmlChar*)test_nb_of_nodes))
586   {
587     xmlChar* nb_of_nodes = xmlGetProp(machine_descr, (const xmlChar*)test_nb_of_nodes);
588     resource.DataForSort._nbOfNodes = atoi((const char*)nb_of_nodes);
589     xmlFree(nb_of_nodes);
590   }
591
592   if (xmlHasProp(machine_descr, (const xmlChar*)test_nb_of_proc_per_node))
593   {
594     xmlChar* nb_of_proc_per_node = xmlGetProp(machine_descr, (const xmlChar*)test_nb_of_proc_per_node);
595     resource.DataForSort._nbOfProcPerNode = atoi((const char*)nb_of_proc_per_node);
596     xmlFree(nb_of_proc_per_node);
597   }
598
599   // Process children nodes
600   xmlNodePtr aCurSubNode = machine_descr->xmlChildrenNode;
601   while(aCurSubNode != NULL)
602   {
603     // Process components
604     if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_components) )
605     {
606       //If a component is given, it is in a module with the same name
607       //except if the module name is given
608       if (xmlHasProp(aCurSubNode, (const xmlChar*)test_component_name)) 
609       {
610         xmlChar* component_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_component_name);
611         std::string aComponentName = (const char*)component_name;
612         _resource.ComponentsList.push_back(aComponentName);
613         if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
614         {
615           xmlChar* module_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
616           std::string aModuleName = (const char*)module_name;
617           _resource.ModulesList.push_back(aModuleName);
618           xmlFree(module_name);
619         }
620         else
621           _resource.ModulesList.push_back(aComponentName);
622         xmlFree(component_name);
623       }
624     }
625     // Process modules
626     else if ( !xmlStrcmp(aCurSubNode->name, (const xmlChar*)test_modules) )
627     {
628       // If a module is given, we create an entry in componentsList and modulesList
629       // with the same name (module == component)
630       if (xmlHasProp(aCurSubNode, (const xmlChar*)test_module_name)) 
631       {
632         xmlChar* component_name = xmlGetProp(aCurSubNode, (const xmlChar*)test_module_name);
633         std::string aComponentName = (const char*)component_name;
634         _resource.ComponentsList.push_back(aComponentName);
635         _resource.ModulesList.push_back(aComponentName);
636         xmlFree(component_name);
637       }
638     }
639     aCurSubNode = aCurSubNode->next;
640   }
641   return true;
642 }
643
644 //=============================================================================
645 /*!
646  *  Fill the document tree in xml file, used to write in an xml file.
647  *  \param theDoc document to fill.
648  */ 
649 //=============================================================================
650
651 void SALOME_ResourcesCatalog_Handler::PrepareDocToXmlFile(xmlDocPtr theDoc)
652 {
653   // Node pointers
654   xmlNodePtr root_node = NULL, node = NULL, node1 = NULL;
655
656   root_node = xmlNewNode(NULL, BAD_CAST "resources");
657   xmlDocSetRootElement(theDoc, root_node);
658     
659   std::map<std::string, ParserResourcesType>::iterator iter = _resources_list.begin();
660   for (; iter != _resources_list.end(); iter++)
661   {
662     node = xmlNewChild(root_node, NULL, BAD_CAST test_machine, NULL);
663     RES_MESSAGE("Add resource name = " << (*iter).second.Name.c_str());
664     xmlNewProp(node, BAD_CAST test_name, BAD_CAST (*iter).second.Name.c_str());
665     xmlNewProp(node, BAD_CAST test_hostname, BAD_CAST (*iter).second.HostName.c_str());
666     xmlNewProp(node, BAD_CAST test_appli_path, BAD_CAST (*iter).second.AppliPath.c_str());
667     xmlNewProp(node, BAD_CAST test_batch_queue, BAD_CAST (*iter).second.batchQueue.c_str());
668     xmlNewProp(node, BAD_CAST test_user_commands, BAD_CAST (*iter).second.userCommands.c_str());
669     xmlNewProp(node,
670                BAD_CAST test_protocol,
671                BAD_CAST ParserResourcesType::protocolToString((*iter).second.Protocol).c_str());
672     xmlNewProp(node,
673                BAD_CAST test_cluster_internal_protocol,
674                BAD_CAST ParserResourcesType::protocolToString((*iter).second.ClusterInternalProtocol).c_str());
675
676     switch ((*iter).second.Mode)
677     {
678       case interactive:
679         xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
680         break;
681       case batch:
682         xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "batch");
683         break;
684       default:
685         xmlNewProp(node, BAD_CAST test_mode, BAD_CAST "interactive");
686     }
687
688     switch ((*iter).second.Batch)
689     {
690       case pbs:
691         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "pbs");
692         break;
693       case lsf:
694         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "lsf");
695         break;
696       case sge:
697         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "sge");
698         break;
699       case ccc:
700         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "ccc");
701         break;
702       case slurm:
703         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "slurm");
704         break;
705       case ssh_batch:
706         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "ssh_batch");
707         break;
708       case ll:
709         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "ll");
710         break;
711       default:
712         xmlNewProp(node, BAD_CAST test_batch, BAD_CAST "");
713     }
714
715     switch ((*iter).second.mpi)
716     {
717       case lam:
718         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "lam");
719         break;
720       case mpich1:
721         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich1");
722         break;
723       case mpich2:
724         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "mpich2");
725         break;
726       case openmpi:
727         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "openmpi");
728         break;
729       case slurmmpi:
730         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "slurmmpi");
731         break;
732       case prun:
733         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "prun");
734         break;
735       default:
736         xmlNewProp(node, BAD_CAST test_mpi, BAD_CAST "");
737     }
738
739     xmlNewProp(node, BAD_CAST test_user_name, BAD_CAST (*iter).second.UserName.c_str());
740
741     std::vector<std::string>::const_iterator iter2 = (*iter).second.ComponentsList.begin();
742     for(;iter2 != (*iter).second.ComponentsList.end(); iter2++)
743     {
744       node1 = xmlNewChild(node, NULL, BAD_CAST test_components, NULL);
745       xmlNewProp(node1, BAD_CAST test_component_name, BAD_CAST (*iter2).c_str());
746     }
747
748     xmlNewProp(node, BAD_CAST test_os, BAD_CAST (*iter).second.OS.c_str());
749     std::ostringstream mem_stream;
750     mem_stream << (*iter).second.DataForSort._memInMB;
751     xmlNewProp(node, BAD_CAST test_mem_in_mb, BAD_CAST mem_stream.str().c_str());
752     std::ostringstream cpu_stream;
753     cpu_stream << (*iter).second.DataForSort._CPUFreqMHz;
754     xmlNewProp(node, BAD_CAST test_cpu_freq_mhz, BAD_CAST cpu_stream.str().c_str());
755     std::ostringstream nb_nodes_stream;
756     nb_nodes_stream << (*iter).second.DataForSort._nbOfNodes;
757     xmlNewProp(node, BAD_CAST test_nb_of_nodes, BAD_CAST nb_nodes_stream.str().c_str());
758     std::ostringstream nb_proc_per_nodes_stream;
759     nb_proc_per_nodes_stream << (*iter).second.DataForSort._nbOfProcPerNode;
760     xmlNewProp(node, BAD_CAST test_nb_of_proc_per_node, BAD_CAST nb_proc_per_nodes_stream.str().c_str());
761   }
762 }