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