Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
CaseOptionList.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* List of configuration options for a service or 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: to be removed
31#include "arcane/core/IServiceInfo.h"
32#include "arcane/core/ICaseFunction.h"
33
34#include <vector>
35#include <algorithm>
36
37/*---------------------------------------------------------------------------*/
38/*---------------------------------------------------------------------------*/
39
40namespace Arcane
41{
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
58class XmlElementContentChecker
59{
60 public:
61
62 XmlElementContentChecker(ICaseDocumentFragment* cd, ITraceMng* tm)
63 : m_case_document(cd)
64 , m_space_string(" ")
65 {
66 ARCANE_UNUSED(tm);
67 }
68
70 void check(XmlNode element)
71 {
72 //ITraceMng* tm = m_trace_mng;
73 XmlNode last_element = element;
74 for (XmlNode::const_iterator i = element.begin(), end = element.end(); i != end; ++i) {
75 XmlNode n = *i;
76 //tm->info() << "CHECK SUB_ELEMENT: " << n.name();
77 if (n.type() == XmlNode::ELEMENT) {
78 last_element = n;
79 }
80 if (n.type() == XmlNode::TEXT) {
81 StringBuilder sb = n.value();
82 //tm->info() << "VALUE1: '" << n.value() << "'";
84 String ns = sb.toString();
85 //tm->info() << "VALUE2: '" << ns << "'";
86 if (ns != m_space_string)
87 CaseOptionError::addWarning(m_case_document, A_FUNCINFO, last_element.xpathFullName(),
88 String::format("Invalid text node between elements (value='{0}')",
89 n.value()),
90 true);
91 }
92 }
93 }
94
95 private:
96
97 ICaseDocumentFragment* m_case_document;
98 String m_space_string;
99};
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
108class CaseOptionList
109: public TraceAccessor
111, public ICaseOptionList
112{
114
115 public:
116
117 class InternalApi
119 {
120 public:
121
122 InternalApi(CaseOptionList* opt_list)
123 : m_opt_list(opt_list)
124 {
125 }
126
127 public:
128
129 void addConfig(CaseOptionBase* o, const XmlNode& parent) override
130 {
131 m_opt_list->addConfig(o, parent);
132 }
133 void setRootElementWithParent(const XmlNode& parent_element) override
134 {
135 m_opt_list->setRootElementWithParent(parent_element);
136 }
137 void setRootElement(const XmlNode& root_element) override
138 {
139 m_opt_list->setRootElement(root_element);
140 }
141 void addInvalidChildren(XmlNodeList& nlist) override
142 {
143 m_opt_list->addInvalidChildren(nlist);
144 }
145
146 private:
147
148 CaseOptionList* m_opt_list;
149 };
150
151 public:
152
153 typedef std::pair<CaseOptionBase*, XmlNode> CaseOptionBasePair;
154 typedef std::vector<CaseOptionBasePair> CaseOptionBasePairList;
155
156 CaseOptionList(ICaseMng* m, ICaseOptions* ref_opt, XmlNode parent_element)
157 : TraceAccessor(m->traceMng())
158 , m_case_mng(m)
160 , m_parent(nullptr)
161 , m_ref_opt(ref_opt)
162 , m_parent_element(parent_element)
163 , m_is_present(false)
164 , m_is_multi(false)
165 , m_is_optional(false)
166 , m_internal_api(this)
167 {}
168 CaseOptionList(ICaseOptionList* parent, ICaseOptions* ref_opt, XmlNode parent_element)
169 : TraceAccessor(parent->caseMng()->traceMng())
170 , m_case_mng(parent->caseMng())
172 , m_parent(parent)
173 , m_ref_opt(ref_opt)
174 , m_parent_element(parent_element)
175 , m_is_present(false)
176 , m_is_multi(false)
177 , m_is_optional(false)
178 , m_internal_api(this)
179 {
180 }
181 ~CaseOptionList()
182 {
183 // Detach the child options that still exist so they don't do so
184 // upon their destruction. A copy of the list must be used
185 // because it will be modified during the detach().
186 std::vector<ICaseOptions*> copy_list(m_case_options);
187 for (ICaseOptions* co : copy_list)
188 co->detach();
189 }
190
191 public:
192
193 XmlNode rootElement() const override { return m_root_element; }
194 XmlNode parentElement() const override { return m_parent_element; }
195 ICaseMng* caseMng() const override { return m_case_mng; }
196 void addConfig(CaseOptionBase* cbi, XmlNode parent) override
197 {
198 //TODO: Check for deletion and if already present
199 m_config_list.push_back(CaseOptionBasePair(cbi, parent));
200 }
201 void addChild(ICaseOptions* c) override
202 {
203 info(5) << " ADD_CHILD " << c->rootTagName() << " instance=" << c
204 << " this=" << this << " n=" << m_case_options.size();
205 m_case_options.push_back(c);
206 }
207 void removeChild(ICaseOptions* c) override
208 {
209 info(5) << " REMOVE_CHILD " << c->rootTagName() << " instance=" << c << " this=" << this;
210 auto i = std::find(m_case_options.begin(), m_case_options.end(), c);
211 if (i == m_case_options.end())
212 ARCANE_FATAL("Internal: option not in list");
213 m_case_options.erase(i);
214 }
215
216 void readChildren(bool is_phase1) override;
217 void printChildren(const String& lang, int indent) override;
218 void visit(ICaseDocumentVisitor* visitor) override;
219 void addInvalidChildren(XmlNodeList& nlist) override;
220
221 public:
222
224 {
226 col.add(i->first);
227 for (ICaseOptions* co : m_case_options)
228 co->deepGetChildren(col);
229 }
230
231 String rootTagName() const override { return m_ref_opt->rootTagName(); }
232
233 bool isOptional() const override { return m_is_optional; }
234 void setOptional(bool v) { m_is_optional = v; }
235
236 Integer minOccurs() const override { return m_is_optional ? 0 : 1; }
237 Integer maxOccurs() const override { return 1; }
238
239 void setRootElementWithParent(XmlNode parent_element) override
240 {
241 _setRootElement(false, parent_element);
242 }
243
244 void setRootElement(XmlNode root_element) override
245 {
246 if (!m_root_element.null())
247 throw CaseOptionException("CaseOptionsList::setRootElement()", "root_element already set", true);
248 m_root_element = root_element;
249 _setRootElement(true, XmlNode());
250 }
251
252 bool isPresent() const override
253 {
254 return m_is_present;
255 }
256
265 void setIsMulti(bool v)
266 {
267 m_is_multi = v;
268 }
269
270 String xpathFullName() const override { return m_root_element.xpathFullName(); }
271
272 MeshHandle meshHandle() const override { return m_ref_opt->meshHandle(); }
273
274 public:
275
277 {
278 return m_ref_opt->caseDocumentFragment();
279 }
280
281 public:
282
283 void disable() override
284 {
285 info(5) << "INTERNAL REMOVE CHILDREN root=" << m_root_element.xpathFullName() << " this=" << this;
286 // TODO check for possible memory leaks
287 m_case_options.clear();
288 m_is_disabled = true;
289 }
290
291 public:
292
293 virtual ICaseOptionListInternal* _internalApi() override { return &m_internal_api; }
294
295 protected:
296
297 void _addInvalidChildren(XmlNode parent, XmlNodeList& nlist);
298 void _searchChildren(bool is_phase1);
299 void _setRootElement(bool force_init, XmlNode parent_element);
300 void _strIndent(char* buf, int indent, int max_indent);
301 void _printOption(const String& lang, int indent, CaseOptionBase* co, std::ostream& o);
302 bool _isValidChildTagName(const String& name);
303
304 protected:
305
306 ICaseMng* m_case_mng;
308 ICaseOptionList* m_parent;
309 ICaseOptions* m_ref_opt;
310 CaseOptionBasePairList m_config_list;
311 std::vector<ICaseOptions*> m_case_options;
313 bool m_is_present;
314 bool m_is_multi;
315 bool m_is_optional;
316 bool m_is_disabled = false;
317 InternalApi m_internal_api;
318};
319
320/*---------------------------------------------------------------------------*/
321/*---------------------------------------------------------------------------*/
322
323/*---------------------------------------------------------------------------*/
324/*---------------------------------------------------------------------------*/
325
327readChildren(bool is_phase1)
328{
329 info(5) << "READ CHILDREN root=" << m_root_element.xpathFullName()
330 << " parent=" << m_parent_element.xpathFullName()
331 << " id=" << typeid(*this).name()
332 << " phase1?=" << is_phase1
333 << " this=" << this;
334
335 if (!m_is_multi && !m_parent_element.null()) {
336 // Checks that the element is present only once.
337 XmlNodeList all_children = m_parent_element.children(rootTagName());
338 if (all_children.size() > 1) {
339 String node_name = m_parent_element.xpathFullName() + "/" + rootTagName();
340 CaseOptionError::addWarning(caseDocumentFragment(), A_FUNCINFO, node_name,
341 String::format("Only one token of the element is allowed (nb_occur={0})",
342 all_children.size()),
343 true);
344 }
345 }
346 _setRootElement(false, XmlNode());
347 for (ConstIterT<std::vector<CaseOptionBasePair>> i(m_config_list); i(); ++i)
348 i->first->setRootElement(m_root_element);
349 _searchChildren(is_phase1);
350}
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
356printChildren(const String& lang, int indent)
357{
358 if (!m_is_present && isOptional())
359 return;
360
361 char str_indent[128];
362 _strIndent(str_indent, indent, 127);
363
364 String service_name = "";
365 String mesh_name = "";
366 IServiceInfo* service = m_ref_opt->caseServiceInfo();
367 if (service) {
368 service_name = " name=\"" + service->localName() + "\"";
369 String mesh_handle_name = m_ref_opt->meshHandle().meshName();
370 if (mesh_handle_name != "Mesh0")
371 mesh_name = " mesh=\"" + m_ref_opt->meshHandle().meshName() + "\"";
372 }
373 info() << str_indent << "<" << rootTagName() << service_name << mesh_name << ">";
375 _printOption(lang, indent, i->first, info().file());
376 }
377 for (ICaseOptions* co : m_case_options) {
378 co->printChildren(lang, indent + 1);
379 }
380 info() << str_indent << "</" << rootTagName() << ">";
381}
382
383/*---------------------------------------------------------------------------*/
384/*---------------------------------------------------------------------------*/
385
388{
389 if (!m_is_present && isOptional())
390 return;
391
392 visitor->beginVisit(m_ref_opt);
394 i->first->visit(visitor);
395 }
396 for (ICaseOptions* co : m_case_options) {
397 co->visit(visitor);
398 }
399 visitor->endVisit(m_ref_opt);
400}
401
402/*---------------------------------------------------------------------------*/
403/*---------------------------------------------------------------------------*/
404
407{
408 info(5) << "CHECK INVALID CHILDREN root=" << m_root_element.xpathFullName()
409 << " parent=" << m_parent_element.xpathFullName()
410 << " this=" << this;
411 if (m_is_disabled)
412 return;
413
414 if (!m_root_element.null())
415 _addInvalidChildren(m_root_element, nlist);
416
417 // Recursion over children
418 for (ICaseOptions* co : m_case_options)
419 co->addInvalidChildren(nlist);
420}
421
422/*---------------------------------------------------------------------------*/
423/*---------------------------------------------------------------------------*/
424
425void CaseOptionList::
426_searchChildren(bool is_phase1)
427{
428 // If I am absent and I am optional, do nothing.
429 if (!m_is_present && isOptional())
430 return;
432 i->first->search(is_phase1);
433 auto read_phase = (is_phase1) ? eCaseOptionReadPhase::Phase1 : eCaseOptionReadPhase::Phase2;
434 for (ICaseOptions* co : m_case_options)
435 co->read(read_phase);
436}
437
438/*---------------------------------------------------------------------------*/
439/*---------------------------------------------------------------------------*/
440
441void CaseOptionList::
442_setRootElement(bool force_init, XmlNode parent_element)
443{
444 // Do nothing if already positioned
445 if (!m_root_element.null() && !force_init)
446 return;
447 if (force_init) {
448 if (m_root_element.null())
449 throw CaseOptionException("CaseOptionsList::_setRootElement()", "root_element not set", true);
451 }
452 else {
453 if (!parent_element.null())
454 m_parent_element = parent_element;
455 if (m_parent_element.null())
456 m_parent_element = (m_parent) ? m_parent->rootElement() : caseDocumentFragment()->rootElement();
458 }
459 // The searched element does not exist. There are then three possibilities:
460 // 1- It is an option block (this element is a direct child
461 // of the document root element). In this case, we create the element
462 // corresponding, which allows for optional modules.
463 // 2- The option is not mandatory. In this case, we do nothing.
464 // 3- The option is mandatory. We still create the corresponding element
465 // because if it only contains default options, it is not
466 // necessary for it to be present.
467 if (m_root_element.null()) {
468 m_is_present = false;
469 if (!m_parent) {
470 XmlNode case_root = caseDocumentFragment()->rootElement();
471 m_root_element = case_root.createAndAppendElement(rootTagName());
472 }
473 else if (!isOptional()) {
474 m_root_element = m_parent_element.createAndAppendElement(rootTagName());
475 //throw ExConfigNotFound(msgMng(),"_setRootElement",rootTagName(),m_parent_element);
476 }
477 }
478 else
479 m_is_present = true;
480}
481
482/*---------------------------------------------------------------------------*/
483/*---------------------------------------------------------------------------*/
484
485void CaseOptionList::
486_strIndent(char* buf, int indent, int max_indent)
487{
488 ++indent;
489
490 if (indent > max_indent)
491 indent = max_indent;
492
493 for (int i = 0; i < indent; ++i)
494 buf[i] = ' ';
495 buf[indent] = '\0';
496}
497
498/*---------------------------------------------------------------------------*/
499/*---------------------------------------------------------------------------*/
500
501void CaseOptionList::
502_printOption(const String& lang, int indent, CaseOptionBase* co, std::ostream& o)
503{
504 std::ios_base::fmtflags f = o.flags(std::ios::left);
505 o << " ";
506 for (int i = 0; i < indent; ++i)
507 o << ' ';
508 o.width(40 - indent);
509 o << co->name();
510 co->print(lang, o);
511 ICaseFunction* func = co->function();
512 if (func) {
513 o << " (fonction: " << func->name() << ")";
514 }
515 o.flags(f);
516}
517
518/*---------------------------------------------------------------------------*/
519/*---------------------------------------------------------------------------*/
520
521bool CaseOptionList::
522_isValidChildTagName(const String& name)
523{
524 for (ConstIterT<CaseOptionBasePairList> i(m_config_list); i(); ++i) {
525 CaseOptionBase* co = i->first;
526 if (co->name() == name)
527 return true;
528 }
529 for (ICaseOptions* co : m_case_options) {
530 info(5) << " CHECK CHILDREN this=" << this << " instance=" << co << " tag=" << co->rootTagName();
531 if (co->rootTagName() == name)
532 return true;
533 }
534 return false;
535}
536
537/*---------------------------------------------------------------------------*/
538/*---------------------------------------------------------------------------*/
539
540void CaseOptionList::
541_addInvalidChildren(XmlNode parent, XmlNodeList& nlist)
542{
543 for (auto i = parent.begin(), end = parent.end(); i != end; ++i) {
544 if (i->type() != XmlNode::ELEMENT)
545 continue;
546 const String& name = i->name();
547 bool is_valid = _isValidChildTagName(name);
548 info(5) << " CHECK Valid tag_name=" << name << " is_valid=" << is_valid;
549 if (!is_valid)
550 nlist.add(*i);
551 }
552 XmlElementContentChecker xecc(caseDocumentFragment(), traceMng());
553 xecc.check(parent);
554}
555
556/*---------------------------------------------------------------------------*/
557/*---------------------------------------------------------------------------*/
558
559/*---------------------------------------------------------------------------*/
560/*---------------------------------------------------------------------------*/
561
566class CaseOptionListMulti
567: public CaseOptionList
568{
569 public:
570
571 typedef std::pair<CaseOptionBase*, XmlNode> CaseOptionBasePair;
572 typedef std::vector<CaseOptionBasePair> CaseOptionBasePairList;
573
574 public:
575
576 CaseOptionListMulti(ICaseOptionsMulti* com, ICaseOptions* co, ICaseMng* m,
577 const XmlNode& element, Integer min_occurs, Integer max_occurs)
578 : CaseOptionList(m, co, element)
579 , m_case_option_multi(com)
580 , m_min_occurs(min_occurs)
581 , m_max_occurs(max_occurs)
582 {}
583 CaseOptionListMulti(ICaseOptionsMulti* com, ICaseOptions* co,
584 ICaseOptionList* parent, const XmlNode& element,
585 Integer min_occurs, Integer max_occurs)
586 : CaseOptionList(parent, co, element)
587 , m_case_option_multi(com)
588 , m_min_occurs(min_occurs)
589 , m_max_occurs(max_occurs)
590 {}
591
592 public:
593
594 bool isOptional() const override { return true; }
595 Integer minOccurs() const override { return m_min_occurs; }
596 Integer maxOccurs() const override { return m_max_occurs; }
597 void readChildren(bool is_phase1) override;
598 void addInvalidChildren(XmlNodeList& nlist) override;
599 void printChildren(const String& lang, int indent) override;
600 void deepGetChildren(Array<CaseOptionBase*>& col) override;
601 void visit(ICaseDocumentVisitor* visitor) override;
602 void _checkMinMaxOccurs(Integer nb_occur);
603
604 protected:
605
606 XmlNode _rootElement(Integer position) const
607 {
608 return m_root_element_list[position];
609 }
610
611 private:
612
613 ICaseOptionsMulti* m_case_option_multi;
614 UniqueArray<ICaseOptionList*> m_case_config_list;
615 XmlNodeList m_root_element_list;
616 Integer m_min_occurs;
617 Integer m_max_occurs;
618
619 private:
620};
621
622/*---------------------------------------------------------------------------*/
623/*---------------------------------------------------------------------------*/
624
626readChildren(bool is_phase1)
627{
628 if (is_phase1) {
629 _setRootElement(false, XmlNode());
630
631 info(5) << "ListMulti: readChildren root=" << m_root_element.xpathFullName()
632 << " parent=" << m_parent_element.xpathFullName()
633 << " id=" << typeid(*this).name()
634 << " phase1?=" << is_phase1
635 << " this=" << this;
636
637 //debug() << "ReadConfig " << rootTagName();
638
639 m_root_element_list = m_parent_element.children(rootTagName());
640 m_case_config_list.clear();
641 // These checks are done in multiAllocate().
642 //Integer s = m_root_element_list.size();
643 //_checkMinMaxOccurs(s);
644 //if (s!=0)
645 m_case_option_multi->multiAllocate(m_root_element_list);
646 // Retrieves the options created during the call to 'multiAllocate' and
647 // adds them to the list.
648 Integer nb_children = m_case_option_multi->nbChildren();
649 for (Integer i = 0; i < nb_children; ++i) {
650 ICaseOptionList* co_value = m_case_option_multi->child(i);
651 co_value->_internalApi()->setRootElement(m_root_element_list[i]);
652 m_case_config_list.add(co_value);
653 }
654 }
655 for (ICaseOptionList* opt : m_case_config_list) {
656 opt->readChildren(is_phase1);
657 }
658 _searchChildren(is_phase1);
659 // Normally, there should be no elements in 'm_config_list'.
660 if (m_config_list.size() != 0)
661 ARCANE_FATAL("Invalid 'm_config_list' size ({1}) for option '{0}'", rootTagName(), m_config_list.size());
662}
663
664/*---------------------------------------------------------------------------*/
665/*---------------------------------------------------------------------------*/
666
669{
670 for (ICaseOptions* co : m_case_options)
671 co->addInvalidChildren(nlist);
672 for (ICaseOptionList* opt : m_case_config_list) {
673 opt->_internalApi()->addInvalidChildren(nlist);
674 }
675}
676
677/*---------------------------------------------------------------------------*/
678/*---------------------------------------------------------------------------*/
679
681printChildren(const String& lang, int indent)
682{
683 for (ICaseOptions* co : m_case_options)
684 co->printChildren(lang, indent);
685 for (ICaseOptionList* opt : m_case_config_list)
686 opt->printChildren(lang, indent);
687}
688
689/*---------------------------------------------------------------------------*/
690/*---------------------------------------------------------------------------*/
691
694{
695 for (ICaseOptions* co : m_case_options)
696 co->deepGetChildren(col);
697 for (ICaseOptionList* opt : m_case_config_list)
698 opt->deepGetChildren(col);
699}
700
701/*---------------------------------------------------------------------------*/
702/*---------------------------------------------------------------------------*/
703
706{
707 for (ICaseOptions* co : m_case_options)
708 co->visit(visitor);
709 for (ICaseOptionList* opt_list : m_case_config_list)
710 opt_list->visit(visitor);
711}
712
713/*---------------------------------------------------------------------------*/
714/*---------------------------------------------------------------------------*/
715
716void CaseOptionListMulti::
717_checkMinMaxOccurs(Integer nb_occur)
718{
719 if (nb_occur < m_min_occurs) {
720 String node_name = m_parent_element.xpathFullName() + "/" + rootTagName();
721 CaseOptionError::addError(caseDocumentFragment(), A_FUNCINFO, node_name,
722 String::format("Bad number of occurences (less than min)"
723 " nb_occur={0}"
724 " min_occur={1}",
725 nb_occur, m_min_occurs),
726 true);
727 }
728 if (m_max_occurs >= 0)
729 if (nb_occur > m_max_occurs) {
730 String node_name = m_parent_element.xpathFullName() + "/" + rootTagName();
731 CaseOptionError::addError(caseDocumentFragment(), A_FUNCINFO, node_name,
732 String::format("Bad number of occurences (greater than max)"
733 " nb_occur={0}"
734 " max_occur={1}",
735 nb_occur, m_max_occurs),
736 true);
737 }
738}
739
740/*---------------------------------------------------------------------------*/
741/*---------------------------------------------------------------------------*/
742
743/*---------------------------------------------------------------------------*/
744/*---------------------------------------------------------------------------*/
745
746ICaseOptionList* ICaseOptionListInternal::
747create(ICaseMng* m, ICaseOptions* ref_opt, const XmlNode& parent_element)
748{
749 return new CaseOptionList(m, ref_opt, parent_element);
750}
751
752ICaseOptionList* ICaseOptionListInternal::
753create(ICaseOptionList* parent, ICaseOptions* ref_opt, const XmlNode& parent_element)
754{
755 return new CaseOptionList(parent, ref_opt, parent_element);
756}
757
758ICaseOptionList* ICaseOptionListInternal::
759create(ICaseOptionList* parent, ICaseOptions* ref_opt, const XmlNode& parent_element,
760 bool is_optional, bool is_multi)
761{
762 auto x = new CaseOptionList(parent, ref_opt, parent_element);
763 if (is_optional)
764 x->setOptional(true);
765 if (is_multi)
766 x->setIsMulti(true);
767 return x;
768}
769
770ICaseOptionList* ICaseOptionListInternal::
771create(ICaseOptionsMulti* com, ICaseOptions* co, ICaseMng* m,
772 const XmlNode& element, Integer min_occurs, Integer max_occurs)
773{
774 return new CaseOptionListMulti(com, co, m, element, min_occurs, max_occurs);
775}
776
777ICaseOptionList* ICaseOptionListInternal::
778create(ICaseOptionsMulti* com, ICaseOptions* co,
779 ICaseOptionList* parent, const XmlNode& element,
780 Integer min_occurs, Integer max_occurs)
781{
782 return new CaseOptionListMulti(com, co, parent, element, min_occurs, max_occurs);
783}
784
785/*---------------------------------------------------------------------------*/
786/*---------------------------------------------------------------------------*/
787
788} // End namespace Arcane
789
790/*---------------------------------------------------------------------------*/
791/*---------------------------------------------------------------------------*/
792
797
798/*---------------------------------------------------------------------------*/
799/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCCORE_DEFINE_REFERENCE_COUNTED_CLASS(class_name)
Macro to define methods and types for a class that uses a reference counter.
#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS()
Macro to define methods managing counters of references.
Base class for 1D data vectors.
void add(ConstReferenceType val)
Adds element val to the end of the array.
Base class for a data set option.
static void addWarning(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const String &message, bool is_collective=false)
Generic error.
static void addError(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const String &message, bool is_collective=false)
Generic error.
Exception related to the dataset.
void readChildren(bool is_phase1) override
Reads the option values from the DOM elements.
Integer minOccurs() const override
Minimum number of occurrences.
void visit(ICaseDocumentVisitor *visitor) override
Applies the visitor visitor.
Integer maxOccurs() const override
Maximum number of occurrences.
void deepGetChildren(Array< CaseOptionBase * > &col) override
Adds all child options to the list col.
void addInvalidChildren(XmlNodeList &nlist) override
Adds child elements that do not correspond to options in nlist.
void printChildren(const String &lang, int indent) override
Displays the list of child options in language lang and their value.
bool isOptional() const override
Indicates if the option is optional.
void setRootElement(const XmlNode &root_element) override
Positions the root element of the list. If already positioned, throws an exception.
void addInvalidChildren(XmlNodeList &nlist) override
Adds child elements that do not correspond to options in nlist.
void setRootElementWithParent(const XmlNode &parent_element) override
Positions the root element of the list, with parent_element as parent. If already positioned,...
List of configuration options for a service or module.
XmlNode parentElement() const override
Returns the parent element.
String xpathFullName() const override
Full name in XPath format corresponding to rootElement().
MeshHandle meshHandle() const override
Handle of the associated mesh.
XmlNode m_root_element
Root element for this option list.
void removeChild(ICaseOptions *c) override
Removes co from the list of children.
void visit(ICaseDocumentVisitor *visitor) override
Applies the visitor visitor.
XmlNode m_parent_element
Parent element.
void setRootElement(XmlNode root_element) override
Positions the root element of the list. If already positioned, throws an exception.
bool isOptional() const override
Indicates if the option is optional.
void readChildren(bool is_phase1) override
Reads the option values from the DOM elements.
Integer minOccurs() const override
Minimum number of occurrences.
Integer maxOccurs() const override
Maximum number of occurrences.
void addInvalidChildren(XmlNodeList &nlist) override
Adds child elements that do not correspond to options in nlist.
void deepGetChildren(Array< CaseOptionBase * > &col) override
Adds all child options to the list col.
CaseOptionBasePairList m_config_list
List of configuration values.
void addChild(ICaseOptions *c) override
Adds the list co to the list of children.
bool isPresent() const override
Indicates if the option is present in the data set.
XmlNode rootElement() const override
Returns the element associated with this options list.
ICaseDocumentFragment * caseDocumentFragment() const override
Associated document.
virtual ICaseOptionListInternal * _internalApi() override
Internal Arcane API.
void printChildren(const String &lang, int indent) override
Displays the list of child options in language lang and their value.
void setRootElementWithParent(XmlNode parent_element) override
Positions the root element of the list, with parent_element as parent. If already positioned,...
ICaseMng * caseMng() const override
Returns the case manager.
void setIsMulti(bool v)
Indicates if the option can be present multiple times.
void addConfig(CaseOptionBase *cbi, XmlNode parent) override
Adds option o with parent parent.
void disable() override
Disables the option as if it were absent.
String rootTagName() const override
Returns the name of the element of this list.
Interface of a part of a dataset.
virtual XmlNode rootElement()=0
Returns the root element.
Visitor interface for a dataset option.
Case manager interface.
Definition ICaseMng.h:57
Internal API of the data set options list interface.
virtual void setRootElement(const XmlNode &root_element)=0
Positions the root element of the list. If already positioned, throws an exception.
Interface for a data set options list.
virtual ICaseOptionListInternal * _internalApi()=0
Internal Arcane API.
Interface for a list of options that appears multiple times.
Interface for a list of data set options.
virtual String rootTagName() const =0
Name of the element in the data set language.
Interface for service or module information.
virtual String localName() const =0
Local part of the service name.
Handle on a mesh.
Definition MeshHandle.h:48
Thread-safe implementation of a reference counter.
Unicode character string constructor.
StringBuilder & collapseWhiteSpace()
Performs whitespace character normalization. The behavior is identical to replaceWhiteSpace() plus:
String toString() const
Returns the constructed character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
ITraceMng * traceMng() const
Trace manager.
void check(XmlNode element)
Checks the validity of child elements of element.
List of nodes of a DOM tree.
Definition XmlNodeList.h:36
Node of a DOM tree.
Definition XmlNode.h:51
String xpathFullName() const
XPath name of the node with its ancestors.
Definition XmlNode.cc:152
eType type() const
Node type.
Definition XmlNode.cc:132
iterator end()
Returns an iterator over the first element after the end of the array.
XmlNodeConstIterator const_iterator
Type of the constant iterator over an element in the array.
Definition XmlNode.h:59
String value() const
Node value.
Definition XmlNode.cc:208
bool null() const
True if the node is null.
Definition XmlNode.h:303
@ 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 of this node (null if none).
Definition XmlNode.h:270
iterator begin()
Returns an iterator over the first element of the array.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
eCaseOptionReadPhase
Reading phases.
Int32 Integer
Type representing an integer.
Namespace of Arccore.