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