Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
CaseOptionBase.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/* CaseOptionBase.cc (C) 2000-2025 */
9/* */
10/* Data set option management. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/CaseOptionBase.h"
15
16#include "arcane/utils/FatalErrorException.h"
17#include "arcane/utils/StringBuilder.h"
18
19#include "arcane/core/CaseOptionBuildInfo.h"
20#include "arcane/core/StringDictionary.h"
21#include "arcane/core/CaseOptions.h"
22#include "arcane/core/ICaseMng.h"
23#include "arcane/core/ICaseDocument.h"
24#include "arcane/core/CaseOptionException.h"
25#include "arcane/core/internal/ICaseOptionListInternal.h"
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane
31{
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36/*!
37 * \internal
38 * \brief Implementation of the base class for a data set option.
39 */
40class CaseOptionBasePrivate
41{
42 public:
43
44 explicit CaseOptionBasePrivate(const CaseOptionBuildInfo& cob);
45
46 public:
47
48 ICaseMng* m_case_mng = nullptr; //!< Sub-domain manager
49 ICaseOptionList* m_parent_option_list = nullptr; //!< Parent
50 ICaseDocumentFragment* m_case_document_fragment = nullptr; //!< Associated document
51 XmlNode m_root_element; //!< Option's DOM element
52 String m_true_name; //!< Option name
53 String m_name; //!< Translated option name
54 const String m_axl_default_value; //!< Initial default value
55 String m_default_value; //!< Default value
56 Integer m_min_occurs; //!< Minimum number of occurrences
57 Integer m_max_occurs; //!< Maximum number of occurrences (-1 == unbounded)
58 bool m_is_optional;
59 bool m_is_initialized; //!< \a true if initialized
60 bool m_is_override_default; //!< \a true if the default value is overridden
61 //! List of option names by language.
63 //! List of default values by category.
65};
66
67/*---------------------------------------------------------------------------*/
68/*---------------------------------------------------------------------------*/
69
70CaseOptionBasePrivate::
71CaseOptionBasePrivate(const CaseOptionBuildInfo& cob)
72: m_case_mng(cob.caseMng())
73, m_parent_option_list(cob.caseOptionList())
74, m_case_document_fragment(m_parent_option_list->caseDocumentFragment())
75, m_root_element()
76, m_true_name(cob.name())
77, m_name(m_true_name)
78, m_axl_default_value(cob.defaultValue())
79, m_default_value(m_axl_default_value)
80, m_min_occurs(cob.minOccurs())
81, m_max_occurs(cob.maxOccurs())
82, m_is_optional(cob.isOptional())
83, m_is_initialized(false)
84, m_is_override_default(false)
85{
86}
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94CaseOptionBase::
95CaseOptionBase(const CaseOptionBuildInfo& cob)
96: m_p(new CaseOptionBasePrivate(cob))
97{
98 cob.caseOptionList()->_internalApi()->addConfig(this, cob.element());
99}
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
104CaseOptionBase::
105~CaseOptionBase()
106{
107 delete m_p;
108}
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
114caseMng() const
115{
116 return m_p->m_case_mng;
117}
118
119/*---------------------------------------------------------------------------*/
120/*---------------------------------------------------------------------------*/
121
123parentOptionList() const
124{
125 return m_p->m_parent_option_list;
126}
127
128/*---------------------------------------------------------------------------*/
129/*---------------------------------------------------------------------------*/
130
132traceMng() const
133{
134 return m_p->m_case_mng->traceMng();
135}
136
137/*---------------------------------------------------------------------------*/
138/*---------------------------------------------------------------------------*/
139
141subDomain() const
142{
143 return m_p->m_case_mng->subDomain();
144}
145
146/*---------------------------------------------------------------------------*/
147/*---------------------------------------------------------------------------*/
148
150caseDocument() const
151{
152 return caseMng()->caseDocument();
153}
154
155/*---------------------------------------------------------------------------*/
156/*---------------------------------------------------------------------------*/
157
160{
161 return m_p->m_case_document_fragment;
162}
163
164/*---------------------------------------------------------------------------*/
165/*---------------------------------------------------------------------------*/
166
168_defaultValue() const
169{
170 return m_p->m_default_value;
171}
172
173/*---------------------------------------------------------------------------*/
174/*---------------------------------------------------------------------------*/
175
176void CaseOptionBase::
177_setDefaultValue(const String& def_value)
178{
179 m_p->m_default_value = def_value;
180 m_p->m_is_override_default = true;
181}
182
183/*---------------------------------------------------------------------------*/
184/*---------------------------------------------------------------------------*/
185
187search(bool is_phase1)
188{
189 _setCategoryDefaultValue();
190 _setTranslatedName();
191 _search(is_phase1);
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
198trueName() const
199{
200 return m_p->m_true_name;
201}
202
203/*---------------------------------------------------------------------------*/
204/*---------------------------------------------------------------------------*/
205
207name() const
208{
209 return m_p->m_name;
210}
211
212/*---------------------------------------------------------------------------*/
213/*---------------------------------------------------------------------------*/
214
216minOccurs() const
217{
218 return m_p->m_min_occurs;
219}
220
221/*---------------------------------------------------------------------------*/
222/*---------------------------------------------------------------------------*/
223
225maxOccurs() const
226{
227 return m_p->m_max_occurs;
228}
229
230/*---------------------------------------------------------------------------*/
231/*---------------------------------------------------------------------------*/
232
234isOptional() const
235{
236 return m_p->m_is_optional;
237}
238
239/*---------------------------------------------------------------------------*/
240/*---------------------------------------------------------------------------*/
241
242void CaseOptionBase::
243_setTranslatedName()
244{
246 if (lang.null())
247 m_p->m_name = m_p->m_true_name;
248 else {
249 String tr = m_p->m_name_translations.find(lang);
250 if (!tr.null()) {
251 //cerr << "** TRANSLATION FOR " << m_p->m_true_name << " is " << tr << " in " << lang << '\n';
252 m_p->m_name = tr;
253 }
254 }
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
260void CaseOptionBase::
261_setCategoryDefaultValue()
262{
263 // If the developer has overridden the option, do nothing
264 if (m_p->m_is_override_default)
265 return;
266 String category = caseDocumentFragment()->defaultCategory();
267 if (category.null())
268 m_p->m_default_value = m_p->m_axl_default_value;
269 else {
270 String v = m_p->m_default_values.find(category);
271 if (!v.null()) {
272 m_p->m_default_value = v;
273 }
274 }
275}
276
277/*---------------------------------------------------------------------------*/
278/*---------------------------------------------------------------------------*/
279
281translatedName(const String& lang) const
282{
283 if (!lang.null()) {
284 String tr = m_p->m_name_translations.find(lang);
285 if (!tr.null())
286 return tr;
287 }
288 return m_p->m_name;
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
295setRootElement(const XmlNode& root_element)
296{
297 m_p->m_root_element = root_element;
298}
299
300/*---------------------------------------------------------------------------*/
301/*---------------------------------------------------------------------------*/
302
304rootElement() const
305{
306 return m_p->m_root_element;
307}
308
309/*---------------------------------------------------------------------------*/
310/*---------------------------------------------------------------------------*/
311
313addAlternativeNodeName(const String& lang, const String& name)
314{
315 m_p->m_name_translations.add(lang, name);
316}
317
318/*---------------------------------------------------------------------------*/
319/*---------------------------------------------------------------------------*/
320
322addDefaultValue(const String& category, const String& value)
323{
324 m_p->m_default_values.add(category, value);
325}
326
327/*---------------------------------------------------------------------------*/
328/*---------------------------------------------------------------------------*/
329
330void CaseOptionBase::
331_setIsInitialized()
332{
333 m_p->m_is_initialized = true;
334}
335
336/*---------------------------------------------------------------------------*/
337/*---------------------------------------------------------------------------*/
338
339bool CaseOptionBase::
340_isInitialized() const
341{
342 return m_p->m_is_initialized;
343}
344
345/*---------------------------------------------------------------------------*/
346/*---------------------------------------------------------------------------*/
347
348void CaseOptionBase::
349_checkIsInitialized() const
350{
351 if (!_isInitialized()) {
352 ARCANE_THROW(CaseOptionException, "option non initialisée '{0}'", name());
353 }
354}
355
356/*---------------------------------------------------------------------------*/
357/*---------------------------------------------------------------------------*/
358
359void CaseOptionBase::
360_checkMinMaxOccurs(Integer nb_occur)
361{
362 Integer min_occurs = m_p->m_min_occurs;
363 Integer max_occurs = m_p->m_max_occurs;
364 bool is_optional = m_p->m_is_optional;
365
366 if (nb_occur == 0 && is_optional) {
367 return;
368 }
369
370 if (nb_occur < min_occurs) {
371 StringBuilder msg = "Bad number of occurences (less than min)";
372 msg += " nb_occur=";
373 msg += nb_occur;
374 msg += " min_occur=";
375 msg += min_occurs;
376 msg += " option=";
377 msg += m_p->m_root_element.xpathFullName();
378 msg += "/";
379 msg += name();
380 throw CaseOptionException(A_FUNCINFO, msg.toString(), true);
381 }
382 if (max_occurs >= 0)
383 if (nb_occur > max_occurs) {
384 StringBuilder msg = "Bad number of occurences (greater than max)";
385 msg += " nb_occur=";
386 msg += nb_occur;
387 msg += " max_occur=";
388 msg += max_occurs;
389 msg += " option=";
390 msg += m_p->m_root_element.xpathFullName();
391 msg += "/";
392 msg += name();
393 throw CaseOptionException(A_FUNCINFO, msg.toString(), true);
394 }
395}
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400String CaseOptionBase::
401_xpathFullName() const
402{
403 return m_p->m_root_element.xpathFullName();
404}
405
406/*---------------------------------------------------------------------------*/
407/*---------------------------------------------------------------------------*/
408
409} // namespace Arcane
410
411/*---------------------------------------------------------------------------*/
412/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
const String m_axl_default_value
Initial default value.
Integer m_min_occurs
Minimum number of occurrences.
String m_name
Translated option name.
ICaseMng * m_case_mng
Sub-domain manager.
XmlNode m_root_element
Option's DOM element.
Integer m_max_occurs
Maximum number of occurrences (-1 == unbounded).
StringDictionary m_default_values
List of default values by category.
bool m_is_initialized
true if initialized
ICaseDocumentFragment * m_case_document_fragment
Associated document.
String m_default_value
Default value.
StringDictionary m_name_translations
List of option names by language.
ICaseOptionList * m_parent_option_list
Parent.
String name() const
Returns the option name corresponding to the data set language.
String translatedName(const String &lang) const
Name of the option in the language lang. Returns name() if no translation exists.
void addDefaultValue(const String &category, const String &value)
Adds the default value value to the category category.
String _defaultValue() const
Returns the default value of the option or 0 if none exists.
ICaseDocument * caseDocument() const
Returns the document manager.
void search(bool is_phase1)
Retrieves the value from the configuration file for the variable.
ICaseMng * caseMng() const
Case manager.
ICaseDocumentFragment * caseDocumentFragment() const
Returns the document associated with this option.
void addAlternativeNodeName(const String &lang, const String &name)
Adds a translation for the option name.
void setRootElement(const XmlNode &root_element)
Positions the root element at root_element.
bool isOptional() const
Allows knowing if an option is optional.
Integer maxOccurs() const
Maximum number of occurrences (for a multiple option) (-1 == unbounded).
XmlNode rootElement() const
Returns the root element of the DOM.
ITraceMng * traceMng() const
Trace manager.
ISubDomain * subDomain() const
Sub-domain manager.
String trueName() const
Returns the true name (untranslated) of the option.
ICaseOptionList * parentOptionList() const
Parent OptionList.
Integer minOccurs() const
Minimum number of occurrences (for a multiple option).
virtual String defaultCategory() const =0
Category used for default values.
virtual String language() const =0
Language used in the dataset.
Case manager interface.
Definition ICaseMng.h:57
virtual ICaseDocument * caseDocument()=0
XML document of the dataset (can be null if no dataset).
Interface of the subdomain manager.
Definition ISubDomain.h:75
String find(const String &key, bool throw_exception=false) const
Returns the value associated with key.
bool null() const
Returns true if the string is null.
Definition String.cc:306
Node of a DOM tree.
Definition XmlNode.h:51
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.