Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CaseOptionList.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CaseOptionList.cc (C) 2000-2025 */
9/* */
10/* Liste d'options de configuration d'un service ou module. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/TraceAccessor.h"
15#include "arcane/utils/FatalErrorException.h"
16#include "arcane/utils/Iterator.h"
17#include "arcane/utils/StringBuilder.h"
18
19#include "arcane/core/CaseOptions.h"
20#include "arcane/core/ICaseMng.h"
21#include "arcane/core/XmlNodeList.h"
22#include "arcane/core/XmlNodeIterator.h"
23#include "arcane/core/CaseOptionError.h"
24#include "arcane/core/ICaseDocumentVisitor.h"
25#include "arcane/core/CaseOptionException.h"
26#include "arcane/core/ICaseDocument.h"
27#include "arcane/core/MeshHandle.h"
28#include "arcane/core/internal/ICaseOptionListInternal.h"
29
30// TODO: a supprimer
31#include "arcane/IServiceInfo.h"
32#include "arcane/ICaseFunction.h"
33
34#include <vector>
35#include <algorithm>
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane
41{
42
43
44/*---------------------------------------------------------------------------*/
45/*---------------------------------------------------------------------------*/
46/*!
47 * \brief Vérifie la validité du contenu entre éléments.
48 *
49 * Cette classe permet de vérifier qu'il n'y a pas de chaînes de caractères
50 * entre les éléments.
51 *
52 * Par exemple, le texte suivant est invalide: pour une option complexe 'toto'
53 * contenant deux options 'x' et 'y', le texte suivant est considéré invalide:
54 * <toto>ABCD<x>A</x><y></y></toto>
55 * car 'ABCD' ne sera pas utilisé ce qui peut être trompeur pour l'utilisateur.
56 * On ne tolére entre les éléments que les noeuds texte contenant des
57 * caractères blancs.
58 */
59class XmlElementContentChecker
60{
61 public:
62 XmlElementContentChecker(ICaseDocumentFragment* cd,ITraceMng* tm)
63 : m_case_document(cd), m_space_string(" ")
64 {
65 ARCANE_UNUSED(tm);
66 }
67
68 //! Vérifie la validité des éléments fils de \a element
69 void check(XmlNode element)
70 {
71 //ITraceMng* tm = m_trace_mng;
72 XmlNode last_element = element;
73 for( XmlNode::const_iterator i = element.begin(), end = element.end(); i != end; ++i ){
74 XmlNode n = *i;
75 //tm->info() << "CHECK SUB_ELEMENT: " << n.name();
76 if (n.type()==XmlNode::ELEMENT){
77 last_element = n;
78 }
79 if (n.type()==XmlNode::TEXT){
80 StringBuilder sb = n.value();
81 //tm->info() << "VALUE1: '" << n.value() << "'";
83 String ns = sb.toString();
84 //tm->info() << "VALUE2: '" << ns << "'";
85 if (ns!=m_space_string)
86 CaseOptionError::addWarning(m_case_document,A_FUNCINFO,last_element.xpathFullName(),
87 String::format("Invalid text node between elements (value='{0}')",
88 n.value()),true);
89
90 }
91 }
92 }
93
94 private:
95 ICaseDocumentFragment* m_case_document;
96 String m_space_string;
97};
98
99/*---------------------------------------------------------------------------*/
100/*---------------------------------------------------------------------------*/
101/*!
102 * \internal
103 * \brief Liste d'options de configuration d'un service ou module.
104 */
105class CaseOptionList
106: public TraceAccessor
108, public ICaseOptionList
109{
110 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
111
112 public:
113
114 class InternalApi
115 : public ICaseOptionListInternal
116 {
117 public:
118
119 InternalApi(CaseOptionList* opt_list)
120 : m_opt_list(opt_list)
121 {
122 }
123
124 public:
125
126 void addConfig(CaseOptionBase* o, const XmlNode& parent) override
127 {
128 m_opt_list->addConfig(o,parent);
129 }
130 void setRootElementWithParent(const XmlNode& parent_element) override
131 {
132 m_opt_list->setRootElementWithParent(parent_element);
133 }
134 void setRootElement(const XmlNode& root_element) override
135 {
136 m_opt_list->setRootElement(root_element);
137 }
138 void addInvalidChildren(XmlNodeList& nlist) override
139 {
140 m_opt_list->addInvalidChildren(nlist);
141 }
142
143 private:
144
145 CaseOptionList* m_opt_list;
146 };
147
148 public:
149
150 typedef std::pair<CaseOptionBase*,XmlNode> CaseOptionBasePair;
151 typedef std::vector<CaseOptionBasePair> CaseOptionBasePairList;
152
153 CaseOptionList(ICaseMng* m,ICaseOptions* ref_opt,XmlNode parent_element)
154 : TraceAccessor(m->traceMng()), m_case_mng(m), m_root_element(), m_parent(nullptr), m_ref_opt(ref_opt),
155 m_parent_element(parent_element), m_is_present(false), m_is_multi(false),
156 m_is_optional(false), m_internal_api(this) {}
157 CaseOptionList(ICaseOptionList* parent,ICaseOptions* ref_opt,XmlNode parent_element)
158 : TraceAccessor(parent->caseMng()->traceMng()), m_case_mng(parent->caseMng()),
159 m_root_element(), m_parent(parent),
160 m_ref_opt(ref_opt), m_parent_element(parent_element), m_is_present(false),
161 m_is_multi(false), m_is_optional(false), m_internal_api(this)
162 {
163 }
164 ~CaseOptionList()
165 {
166 // Détache les options filles qui existent encore pour ne pas qu'elles le
167 // fassent lors de leur destruction. Il faut utiliser une copie de la liste
168 // car cette dernière sera modifiée lors du detach().
169 std::vector<ICaseOptions*> copy_list(m_case_options);
170 for( ICaseOptions* co : copy_list )
171 co->detach();
172 }
173
174 public:
175
176 XmlNode rootElement() const override { return m_root_element; }
177 XmlNode parentElement() const override { return m_parent_element; }
178 ICaseMng* caseMng() const override { return m_case_mng; }
179 void addConfig(CaseOptionBase* cbi,XmlNode parent) override
180 {
181 //TODO: Vérifier la suppression et pas déjà présent
182 m_config_list.push_back(CaseOptionBasePair(cbi,parent));
183 }
184 void addChild(ICaseOptions* c) override
185 {
186 info(5) << " ADD_CHILD " << c->rootTagName() << " instance=" << c
187 << " this=" << this << " n=" << m_case_options.size();
188 m_case_options.push_back(c);
189 }
190 void removeChild(ICaseOptions* c) override
191 {
192 info(5) << " REMOVE_CHILD " << c->rootTagName() << " instance=" << c << " this=" << this;
193 auto i = std::find(m_case_options.begin(),m_case_options.end(),c);
194 if (i==m_case_options.end())
195 ARCANE_FATAL("Internal: option not in list");
196 m_case_options.erase(i);
197 }
198
199 void readChildren(bool is_phase1) override;
200 void printChildren(const String& lang,int indent) override;
201 void visit(ICaseDocumentVisitor* visitor) override;
202 void addInvalidChildren(XmlNodeList& nlist) override;
203
204 public:
205
207 {
209 col.add(i->first);
210 for( ICaseOptions* co : m_case_options )
211 co->deepGetChildren(col);
212 }
213
214 String rootTagName() const override { return m_ref_opt->rootTagName(); }
215
216 bool isOptional() const override { return m_is_optional; }
217 void setOptional(bool v) { m_is_optional = v; }
218
219 Integer minOccurs() const override { return m_is_optional ? 0 : 1; }
220 Integer maxOccurs() const override { return 1; }
221
222 void setRootElementWithParent(XmlNode parent_element) override
223 {
224 _setRootElement(false,parent_element);
225 }
226
227 void setRootElement(XmlNode root_element) override
228 {
229 if (!m_root_element.null())
230 throw CaseOptionException("CaseOptionsList::setRootElement()","root_element already set",true);
231 m_root_element = root_element;
232 _setRootElement(true,XmlNode());
233 }
234
235 bool isPresent() const override
236 {
237 return m_is_present;
238 }
239
240 /*!
241 * \brief Indique si l'option peut-être présente plusieurs fois.
242 *
243 * Cela sert à vérifier que l'élément correspondant de l'option n'est
244 * présent qu'une seule fois si \a v est faux. Si \a v est vrai,
245 * la vérification a lieu ailleurs. Cette fonction doit être appelée
246 * avant readChildren() pour être pris en compte.
247 */
248 void setIsMulti(bool v)
249 {
250 m_is_multi = v;
251 }
252
253 String xpathFullName() const override { return m_root_element.xpathFullName(); }
254
255 MeshHandle meshHandle() const override { return m_ref_opt->meshHandle(); }
256
257 public:
258
260 {
261 return m_ref_opt->caseDocumentFragment();
262 }
263
264 public:
265
266 void disable() override
267 {
268 info(5) << "INTERNAL REMOVE CHILDREN root=" << m_root_element.xpathFullName() << " this=" << this;
269 // TODO regarder éventuelles fuites mémoire
270 m_case_options.clear();
271 m_is_disabled = true;
272 }
273
274 public:
275
276 virtual ICaseOptionListInternal* _internalApi() override { return &m_internal_api; }
277
278 protected:
279
280 void _addInvalidChildren(XmlNode parent,XmlNodeList& nlist);
281 void _searchChildren(bool is_phase1);
282 void _setRootElement(bool force_init,XmlNode parent_element);
283 void _strIndent(char* buf,int indent,int max_indent);
284 void _printOption(const String& lang,int indent,CaseOptionBase* co,std::ostream& o);
285 bool _isValidChildTagName(const String& name);
286
287 protected:
288
289 ICaseMng* m_case_mng;
290 XmlNode m_root_element; //!< Elément racine pour cette liste d'options
291 ICaseOptionList* m_parent;
292 ICaseOptions* m_ref_opt;
293 CaseOptionBasePairList m_config_list; //!< Liste des valeurs de configuration
294 std::vector<ICaseOptions*> m_case_options;
295 XmlNode m_parent_element; //!< Elément parent.
296 bool m_is_present;
297 bool m_is_multi;
298 bool m_is_optional;
299 bool m_is_disabled = false;
300 InternalApi m_internal_api;
301};
302
303/*---------------------------------------------------------------------------*/
304/*---------------------------------------------------------------------------*/
305
306/*---------------------------------------------------------------------------*/
307/*---------------------------------------------------------------------------*/
308
310readChildren(bool is_phase1)
311{
312 info(5) << "READ CHILDREN root=" << m_root_element.xpathFullName()
313 << " parent=" << m_parent_element.xpathFullName()
314 << " id=" << typeid(*this).name()
315 << " phase1?=" << is_phase1
316 << " this=" << this;
317
318 if (!m_is_multi && !m_parent_element.null()){
319 // Vérifie que l'élément n'est présent qu'une fois.
320 XmlNodeList all_children = m_parent_element.children(rootTagName());
321 if (all_children.size()>1){
322 String node_name = m_parent_element.xpathFullName()+"/"+rootTagName();
324 String::format("Only one token of the element is allowed (nb_occur={0})",
325 all_children.size()),true);
326 }
327 }
328 _setRootElement(false,XmlNode());
329 for( ConstIterT< std::vector<CaseOptionBasePair> > i(m_config_list); i(); ++i )
330 i->first->setRootElement(m_root_element);
331 _searchChildren(is_phase1);
332}
333
334/*---------------------------------------------------------------------------*/
335/*---------------------------------------------------------------------------*/
336
338printChildren(const String& lang,int indent)
339{
340 if (!m_is_present && isOptional())
341 return;
342
343 char str_indent[128];
344 _strIndent(str_indent,indent,127);
345
346 String service_name = "";
347 String mesh_name = "";
348 IServiceInfo* service = m_ref_opt->caseServiceInfo();
349 if (service){
350 service_name = " name=\""+ service->localName() + "\"";
351 String mesh_handle_name = m_ref_opt->meshHandle().meshName();
352 if (mesh_handle_name!="Mesh0")
353 mesh_name = " mesh=\"" + m_ref_opt->meshHandle().meshName() + "\"";
354 }
355 info() << str_indent << "<" << rootTagName() << service_name << mesh_name << ">";
357 _printOption(lang,indent,i->first,info().file());
358 }
359 for( ICaseOptions* co : m_case_options ){
360 co->printChildren(lang,indent+1);
361 }
362 info() << str_indent << "</" << rootTagName() << ">";
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
370{
371 if (!m_is_present && isOptional())
372 return;
373
374 visitor->beginVisit(m_ref_opt);
376 i->first->visit(visitor);
377 }
378 for( ICaseOptions* co : m_case_options ){
379 co->visit(visitor);
380 }
381 visitor->endVisit(m_ref_opt);
382}
383
384/*---------------------------------------------------------------------------*/
385/*---------------------------------------------------------------------------*/
386
389{
390 info(5) << "CHECK INVALID CHILDREN root=" << m_root_element.xpathFullName()
391 << " parent=" << m_parent_element.xpathFullName()
392 << " this=" << this;
393 if (m_is_disabled)
394 return;
395
396 if (!m_root_element.null())
397 _addInvalidChildren(m_root_element,nlist);
398
399 // Récursion sur les fils
400 for( ICaseOptions* co : m_case_options )
401 co->addInvalidChildren(nlist);
402}
403
404/*---------------------------------------------------------------------------*/
405/*---------------------------------------------------------------------------*/
406
407void CaseOptionList::
408_searchChildren(bool is_phase1)
409{
410 // Si je suis absent et que je suis optionel, ne fait rien.
411 if (!m_is_present && isOptional())
412 return;
414 i->first->search(is_phase1);
415 auto read_phase = (is_phase1) ? eCaseOptionReadPhase::Phase1 : eCaseOptionReadPhase::Phase2;
416 for( ICaseOptions* co : m_case_options )
417 co->read(read_phase);
418}
419
420/*---------------------------------------------------------------------------*/
421/*---------------------------------------------------------------------------*/
422
423void CaseOptionList::
424_setRootElement(bool force_init,XmlNode parent_element)
425{
426 // Ne fait rien si déjà positionné
427 if (!m_root_element.null() && !force_init)
428 return;
429 if (force_init){
430 if (m_root_element.null())
431 throw CaseOptionException("CaseOptionsList::_setRootElement()","root_element not set",true);
433 }
434 else{
435 if (!parent_element.null())
436 m_parent_element = parent_element;
437 if (m_parent_element.null())
438 m_parent_element = (m_parent) ? m_parent->rootElement() : caseDocumentFragment()->rootElement();
440 }
441 // L'élément recherché n'existe pas. Il y a alors trois possibitités:
442 // 1- Il s'agit d'un bloc d'option (cet élément est directement fils
443 // de l'élément racine du document). Dans ce cas, on créé l'élément
444 // correspondant ce qui permet d'avoir des modules optionnels.
445 // 2- L'option n'est pas obligatoire. Dans ce cas on ne fait rien.
446 // 3- L'option est obligatoire. On créé tout de même l'élément correspondant
447 // car s'il ne comporte que des options par défaut, il n'est pas
448 // nécessaire qu'il soit présent.
449 if (m_root_element.null()){
450 m_is_present = false;
451 if (!m_parent){
452 XmlNode case_root = caseDocumentFragment()->rootElement();
453 m_root_element = case_root.createAndAppendElement(rootTagName());
454 }
455 else if (!isOptional()){
456 m_root_element = m_parent_element.createAndAppendElement(rootTagName());
457 //throw ExConfigNotFound(msgMng(),"_setRootElement",rootTagName(),m_parent_element);
458 }
459 }
460 else
461 m_is_present = true;
462}
463
464/*---------------------------------------------------------------------------*/
465/*---------------------------------------------------------------------------*/
466
467void CaseOptionList::
468_strIndent(char* buf,int indent,int max_indent)
469{
470 ++indent;
471
472 if (indent>max_indent)
473 indent = max_indent;
474
475 for( int i=0; i<indent; ++i )
476 buf[i] = ' ';
477 buf[indent] = '\0';
478}
479
480/*---------------------------------------------------------------------------*/
481/*---------------------------------------------------------------------------*/
482
483void CaseOptionList::
484_printOption(const String& lang,int indent,CaseOptionBase* co,std::ostream& o)
485{
486 std::ios_base::fmtflags f = o.flags(std::ios::left);
487 o << " ";
488 for( int i=0; i<indent; ++i )
489 o << ' ';
490 o.width(40-indent);
491 o << co->name();
492 co->print(lang,o);
493 ICaseFunction* func = co->function();
494 if (func){
495 o << " (fonction: " << func->name() << ")";
496 }
497 o.flags(f);
498}
499
500/*---------------------------------------------------------------------------*/
501/*---------------------------------------------------------------------------*/
502
503bool CaseOptionList::
504_isValidChildTagName(const String& name)
505{
506 for( ConstIterT<CaseOptionBasePairList> i(m_config_list); i(); ++i ){
507 CaseOptionBase* co = i->first;
508 if (co->name()==name)
509 return true;
510 }
511 for( ICaseOptions* co : m_case_options ){
512 info(5) << " CHECK CHILDREN this=" << this << " instance=" << co << " tag=" << co->rootTagName();
513 if (co->rootTagName()==name)
514 return true;
515 }
516 return false;
517}
518
519/*---------------------------------------------------------------------------*/
520/*---------------------------------------------------------------------------*/
521
522void CaseOptionList::
523_addInvalidChildren(XmlNode parent,XmlNodeList& nlist)
524{
525 for( auto i = parent.begin(), end = parent.end(); i != end; ++i ){
526 if (i->type()!=XmlNode::ELEMENT)
527 continue;
528 const String& name = i->name();
529 bool is_valid = _isValidChildTagName(name);
530 info(5) << " CHECK Valid tag_name=" << name << " is_valid=" << is_valid;
531 if (!is_valid)
532 nlist.add(*i);
533 }
534 XmlElementContentChecker xecc(caseDocumentFragment(),traceMng());
535 xecc.check(parent);
536}
537
538/*---------------------------------------------------------------------------*/
539/*---------------------------------------------------------------------------*/
540
541/*---------------------------------------------------------------------------*/
542/*---------------------------------------------------------------------------*/
543/*!
544 * \internal
545 * \brief Liste d'options du jeu de données contenant plusieurs fils identiques.
546 */
547class CaseOptionListMulti
548: public CaseOptionList
549{
550 public:
551
552 typedef std::pair<CaseOptionBase*,XmlNode> CaseOptionBasePair;
553 typedef std::vector<CaseOptionBasePair> CaseOptionBasePairList;
554
555 public:
556
557 CaseOptionListMulti(ICaseOptionsMulti* com,ICaseOptions* co,ICaseMng* m,
558 const XmlNode& element,Integer min_occurs,Integer max_occurs)
559 : CaseOptionList(m,co,element), m_case_option_multi(com),
560 m_min_occurs(min_occurs), m_max_occurs(max_occurs) {}
561 CaseOptionListMulti(ICaseOptionsMulti* com,ICaseOptions* co,
562 ICaseOptionList* parent,const XmlNode& element,
563 Integer min_occurs,Integer max_occurs)
564 : CaseOptionList(parent,co,element), m_case_option_multi(com),
565 m_min_occurs(min_occurs), m_max_occurs(max_occurs) {}
566
567 public:
568
569 bool isOptional() const override { return true; }
570 Integer minOccurs() const override { return m_min_occurs; }
571 Integer maxOccurs() const override { return m_max_occurs; }
572 void readChildren(bool is_phase1) override;
573 void addInvalidChildren(XmlNodeList& nlist) override;
574 void printChildren(const String& lang,int indent) override;
575 void deepGetChildren(Array<CaseOptionBase*>& col) override;
576 void visit(ICaseDocumentVisitor* visitor) override;
577 void _checkMinMaxOccurs(Integer nb_occur);
578
579 protected:
580
581 XmlNode _rootElement(Integer position) const
582 {
583 return m_root_element_list[position];
584 }
585
586 private:
587
588 ICaseOptionsMulti* m_case_option_multi;
589 UniqueArray<ICaseOptionList*> m_case_config_list;
590 XmlNodeList m_root_element_list;
591 Integer m_min_occurs;
592 Integer m_max_occurs;
593
594 private:
595};
596
597/*---------------------------------------------------------------------------*/
598/*---------------------------------------------------------------------------*/
599
601readChildren(bool is_phase1)
602{
603 if (is_phase1){
604 _setRootElement(false,XmlNode());
605
606 info(5) << "ListMulti: readChildren root=" << m_root_element.xpathFullName()
607 << " parent=" << m_parent_element.xpathFullName()
608 << " id=" << typeid(*this).name()
609 << " phase1?=" << is_phase1
610 << " this=" << this;
611
612 //debug() << "ReadConfig " << rootTagName();
613
614 m_root_element_list = m_parent_element.children(rootTagName());
615 m_case_config_list.clear();
616 // Ces vérifications sont faites dans multiAllocate().
617 //Integer s = m_root_element_list.size();
618 //_checkMinMaxOccurs(s);
619 //if (s!=0)
620 m_case_option_multi->multiAllocate(m_root_element_list);
621 // Récupère les options créées lors de l'appel à 'multiAllocate' et
622 // les ajoute à la liste.
623 Integer nb_children = m_case_option_multi->nbChildren();
624 for( Integer i=0; i<nb_children; ++i ){
625 ICaseOptionList* co_value = m_case_option_multi->child(i);
626 co_value->_internalApi()->setRootElement(m_root_element_list[i]);
627 m_case_config_list.add(co_value);
628 }
629 }
630 for( ICaseOptionList* opt : m_case_config_list ){
631 opt->readChildren(is_phase1);
632 }
633 _searchChildren(is_phase1);
634 // Normalement on ne doit pas avoir d'éléments dans 'm_config_list'.
635 if (m_config_list.size()!=0)
636 ARCANE_FATAL("Invalid 'm_config_list' size ({1}) for option '{0}'",rootTagName(),m_config_list.size());
637}
638
639/*---------------------------------------------------------------------------*/
640/*---------------------------------------------------------------------------*/
641
644{
645 for( ICaseOptions* co : m_case_options )
646 co->addInvalidChildren(nlist);
647 for( ICaseOptionList* opt : m_case_config_list ){
648 opt->_internalApi()->addInvalidChildren(nlist);
649 }
650}
651
652/*---------------------------------------------------------------------------*/
653/*---------------------------------------------------------------------------*/
654
656printChildren(const String& lang,int indent)
657{
658 for( ICaseOptions* co : m_case_options )
659 co->printChildren(lang,indent);
660 for( ICaseOptionList* opt : m_case_config_list )
661 opt->printChildren(lang,indent);
662}
663
664/*---------------------------------------------------------------------------*/
665/*---------------------------------------------------------------------------*/
666
669{
670 for( ICaseOptions* co : m_case_options )
671 co->deepGetChildren(col);
672 for( ICaseOptionList* opt : m_case_config_list )
673 opt->deepGetChildren(col);
674}
675
676/*---------------------------------------------------------------------------*/
677/*---------------------------------------------------------------------------*/
678
681{
682 for( ICaseOptions* co : m_case_options )
683 co->visit(visitor);
684 for( ICaseOptionList* opt_list : m_case_config_list )
685 opt_list->visit(visitor);
686}
687
688/*---------------------------------------------------------------------------*/
689/*---------------------------------------------------------------------------*/
690
691void CaseOptionListMulti::
692_checkMinMaxOccurs(Integer nb_occur)
693{
694 if (nb_occur<m_min_occurs){
696 CaseOptionError::addError(caseDocumentFragment(),A_FUNCINFO,node_name,
697 String::format("Bad number of occurences (less than min)"
698 " nb_occur={0}"
699 " min_occur={1}",
700 nb_occur,m_min_occurs),true);
701 }
702 if (m_max_occurs>=0)
703 if (nb_occur>m_max_occurs){
704 String node_name = m_parent_element.xpathFullName()+"/"+rootTagName();
705 CaseOptionError::addError(caseDocumentFragment(),A_FUNCINFO,node_name,
706 String::format("Bad number of occurences (greater than max)"
707 " nb_occur={0}"
708 " max_occur={1}",
709 nb_occur,m_max_occurs),true);
710 }
711}
712
713/*---------------------------------------------------------------------------*/
714/*---------------------------------------------------------------------------*/
715
716/*---------------------------------------------------------------------------*/
717/*---------------------------------------------------------------------------*/
718
719ICaseOptionList* ICaseOptionListInternal::
720create(ICaseMng* m,ICaseOptions* ref_opt,const XmlNode& parent_element)
721{
722 return new CaseOptionList(m,ref_opt,parent_element);
723}
724
725ICaseOptionList* ICaseOptionListInternal::
726create(ICaseOptionList* parent,ICaseOptions* ref_opt,const XmlNode& parent_element)
727{
728 return new CaseOptionList(parent,ref_opt,parent_element);
729}
730
731ICaseOptionList* ICaseOptionListInternal::
732create(ICaseOptionList* parent,ICaseOptions* ref_opt,const XmlNode& parent_element,
733 bool is_optional,bool is_multi)
734{
735 auto x = new CaseOptionList(parent,ref_opt,parent_element);
736 if (is_optional)
737 x->setOptional(true);
738 if (is_multi)
739 x->setIsMulti(true);
740 return x;
741}
742
743ICaseOptionList* ICaseOptionListInternal::
744create(ICaseOptionsMulti* com,ICaseOptions* co,ICaseMng* m,
745 const XmlNode& element,Integer min_occurs,Integer max_occurs)
746{
747 return new CaseOptionListMulti(com,co,m,element,min_occurs,max_occurs);
748}
749
750ICaseOptionList* ICaseOptionListInternal::
751create(ICaseOptionsMulti* com,ICaseOptions* co,
752 ICaseOptionList* parent,const XmlNode& element,
753 Integer min_occurs,Integer max_occurs)
754{
755 return new CaseOptionListMulti(com,co,parent,element,min_occurs,max_occurs);
756}
757
758/*---------------------------------------------------------------------------*/
759/*---------------------------------------------------------------------------*/
760
761} // End namespace Arcane
762
767
768/*---------------------------------------------------------------------------*/
769/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name)
Macro pour définir les méthodes et types une classe qui utilise un compteur de référence.
Classe de base des vecteurs 1D de données.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Classe de base d'une option du jeu de donnée.
static void addWarning(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const String &message, bool is_collective=false)
Erreur générique.
static void addError(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const String &message, bool is_collective=false)
Erreur générique.
Exception en rapport avec le jeu de données.
void readChildren(bool is_phase1) override
Lis les valeurs des options à partir des éléments du DOM.
Integer minOccurs() const override
Nombre minimum d'occurences.
void visit(ICaseDocumentVisitor *visitor) override
Applique le visiteur visitor.
Integer maxOccurs() const override
Nombre maximum d'occurences.
void deepGetChildren(Array< CaseOptionBase * > &col) override
Ajoute à la liste col tous les options filles.
void addInvalidChildren(XmlNodeList &nlist) override
Ajoute les éléments fils ne correspondants par à de options dans nlist.
void printChildren(const String &lang, int indent) override
Affiche la liste des options filles dans le langage lang et leur valeur.
bool isOptional() const override
Indique si l'option est optionnelle.
XmlNode parentElement() const override
Retourne l'élément parent.
String xpathFullName() const override
Nom complet au format XPath correspondant à rootElement()
MeshHandle meshHandle() const override
Handle du maillage associé
XmlNode m_root_element
Elément racine pour cette liste d'options.
void removeChild(ICaseOptions *c) override
Supprime co de la liste des fils.
void visit(ICaseDocumentVisitor *visitor) override
Applique le visiteur visitor.
XmlNode m_parent_element
Elément parent.
void setRootElement(XmlNode root_element) override
Positionne l'élément racine de la liste. Si déjà positionné, lance une exception.
bool isOptional() const override
Indique si l'option est optionnelle.
void readChildren(bool is_phase1) override
Lis les valeurs des options à partir des éléments du DOM.
Integer minOccurs() const override
Nombre minimum d'occurences.
Integer maxOccurs() const override
Nombre maximum d'occurences.
void addInvalidChildren(XmlNodeList &nlist) override
Ajoute les éléments fils ne correspondants par à de options dans nlist.
void deepGetChildren(Array< CaseOptionBase * > &col) override
Ajoute à la liste col tous les options filles.
CaseOptionBasePairList m_config_list
Liste des valeurs de configuration.
void addChild(ICaseOptions *c) override
Ajoute la liste co à la liste des fils.
bool isPresent() const override
Indique si l'option est présente dans le jeu de données.
XmlNode rootElement() const override
Retourne l'élément lié à cette liste d'option.
ICaseDocumentFragment * caseDocumentFragment() const override
Document associé.
virtual ICaseOptionListInternal * _internalApi() override
API interne à Arcane.
void printChildren(const String &lang, int indent) override
Affiche la liste des options filles dans le langage lang et leur valeur.
void setRootElementWithParent(XmlNode parent_element) override
Positionne l'élément racine de la liste, avec parent_element comme parent. Si déjà positionné,...
ICaseMng * caseMng() const override
Retourne le gestionnaire du cas.
void setIsMulti(bool v)
Indique si l'option peut-être présente plusieurs fois.
void addConfig(CaseOptionBase *cbi, XmlNode parent) override
Ajoute l'option o avec le parent parent.
void disable() override
Désactive l'option comme si elle était absente.
String rootTagName() const override
Retourne le nom de l'élément de cette liste.
virtual XmlNode rootElement()=0
Retourne l'élément racine.
Interface du visiteur pour une option du jeu de données.
Interface du gestionnaire de cas.
Definition ICaseMng.h:56
virtual ICaseOptionListInternal * _internalApi()=0
API interne à Arcane.
virtual String rootTagName() const =0
Nom de l'élément dans le langage du jeu de données.
Interface des informations d'un service ou d'un module.
virtual String localName() const =0
Partie locale du nom du service.
Interface du gestionnaire de traces.
Handle sur un maillage.
Definition MeshHandle.h:47
Implémentation thread-safe d'un compteur de référence.
Constructeur de chaîne de caractère unicode.
StringBuilder & collapseWhiteSpace()
Effectue une normalisation des caractères espaces. Le comportement est identique à replaceWhiteSpace(...
String toString() const
Retourne la chaîne de caractères construite.
Chaîne de caractères unicode.
TraceAccessor(ITraceMng *m)
Construit un accesseur via le gestionnaire de trace m.
TraceMessage info() const
Flot pour un message d'information.
ITraceMng * traceMng() const
Gestionnaire de trace.
void check(XmlNode element)
Vérifie la validité des éléments fils de element.
Liste de noeuds d'un arbre DOM.
Definition XmlNodeList.h:33
Noeud d'un arbre DOM.
Definition XmlNode.h:51
String xpathFullName() const
Nom XPath du noeud avec ces ancêtres.
Definition XmlNode.cc:143
eType type() const
Type du noeud.
Definition XmlNode.cc:123
iterator end()
Retourne un iterateur sur le premier élément après la fin du tableau.
XmlNodeConstIterator const_iterator
Type de l'itérateur constant sur un élément du tableau.
Definition XmlNode.h:59
String value() const
Valeur du noeud.
Definition XmlNode.cc:199
bool null() const
Vrai si le noeud est nul.
Definition XmlNode.h:294
@ TEXT
The node is a Text node.
Definition XmlNode.h:91
@ ELEMENT
The node is an Element.
Definition XmlNode.h:87
XmlNode parent() const
Parent de ce noeud (null si aucun)
Definition XmlNode.h:261
iterator begin()
Retourne un iterateur sur le premier élément du tableau.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
eCaseOptionReadPhase
Phases de la lecture.
Int32 Integer
Type représentant un entier.
Espace de nom de Arccore.