Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CaseOptionEnum.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* CaseOptionEnum.cc (C) 2000-2023 */
9/* */
10/* Option du jeu de données de type énuméré. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/CaseOptionEnum.h"
15
16#include "arcane/utils/Array.h"
17#include "arcane/utils/ITraceMng.h"
18
19#include "arcane/core/ICaseFunction.h"
20#include "arcane/core/ICaseMng.h"
21#include "arcane/core/ICaseDocument.h"
22#include "arcane/core/StringDictionary.h"
23#include "arcane/core/CaseOptionError.h"
24#include "arcane/core/ICaseDocumentVisitor.h"
25
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
28
29namespace Arcane
30{
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
36CaseOptionName(const String& aname)
37: m_true_name(aname)
38, m_translations(0)
39{
40}
41
42/*---------------------------------------------------------------------------*/
43/*---------------------------------------------------------------------------*/
44
47: m_true_name(rhs.m_true_name)
48, m_translations(0)
49{
50 if (rhs.m_translations)
51 m_translations = new StringDictionary(*rhs.m_translations);
52}
53
54/*---------------------------------------------------------------------------*/
55/*---------------------------------------------------------------------------*/
56
59{
60 delete m_translations;
61}
62
63/*---------------------------------------------------------------------------*/
64/*---------------------------------------------------------------------------*/
65
67addAlternativeNodeName(const String& lang,const String& name)
68{
69 if (!m_translations)
70 m_translations = new StringDictionary();
71 m_translations->add(lang,name);
72}
73
74/*---------------------------------------------------------------------------*/
75/*---------------------------------------------------------------------------*/
76
78name(const String& lang) const
79{
80 if (!m_translations || lang.null())
81 return m_true_name;
82 String s = m_translations->find(lang);
83 if (s.null())
84 return m_true_name;
85 return s;
86}
87
88/*---------------------------------------------------------------------------*/
89/*---------------------------------------------------------------------------*/
90
91/*---------------------------------------------------------------------------*/
92/*---------------------------------------------------------------------------*/
93
94CaseOptionEnumValue::
95CaseOptionEnumValue(const String& name,int value)
96: CaseOptionName(name)
97, m_value(value)
98{
99}
100
101CaseOptionEnumValue::
102CaseOptionEnumValue(const CaseOptionEnumValue& rhs)
103: CaseOptionName(rhs)
104, m_value(rhs.m_value)
105{
106}
107
108CaseOptionEnumValue::
109~CaseOptionEnumValue()
110{
111}
112
113/*---------------------------------------------------------------------------*/
114/*---------------------------------------------------------------------------*/
115
116/*---------------------------------------------------------------------------*/
117/*---------------------------------------------------------------------------*/
118
121: m_enum_values(new EnumValueList())
122{
123}
124
127{
128 for( auto i : (*m_enum_values) ){
129 delete i;
130 }
131 delete m_enum_values;
132}
133
134
135/*---------------------------------------------------------------------------*/
136/*---------------------------------------------------------------------------*/
137
139enumValue(Integer index) const
140{
141 return (*m_enum_values)[index];
142}
143
144/*---------------------------------------------------------------------------*/
145/*---------------------------------------------------------------------------*/
146
148addEnumValue(CaseOptionEnumValue* value,bool do_clone)
149{
150 CaseOptionEnumValue* svalue = value;
151 if (do_clone)
152 svalue = new CaseOptionEnumValue(*value);
153 m_enum_values->add(svalue);
154}
155
157nbEnumValue() const
158{
159 return m_enum_values->size();
160}
161
162/*---------------------------------------------------------------------------*/
163/*---------------------------------------------------------------------------*/
164
166valueOfName(const String& name,const String& lang,int& value) const
167{
168 for( auto ev : (*m_enum_values) ){
169 const String& n = ev->name(lang);
170 if (n==name){
171 value = ev->value();
172 return false;
173 }
174 }
175 return true;
176}
177
178/*---------------------------------------------------------------------------*/
179/*---------------------------------------------------------------------------*/
180
182nameOfValue(int value,const String& lang) const
183{
184 String s;
185 for( auto ev : (*m_enum_values) ){
186 if (ev->value()==value){
187 s = ev->name(lang);
188 break;
189 }
190 }
191 return s;
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
198getValidNames(const String& lang,StringArray& names) const
199{
200 for( auto ev : (*m_enum_values) ){
201 names.add(ev->name(lang));
202 }
203}
204
205/*---------------------------------------------------------------------------*/
206/*---------------------------------------------------------------------------*/
207
208/*---------------------------------------------------------------------------*/
209/*---------------------------------------------------------------------------*/
210
211CaseOptionEnum::
212CaseOptionEnum(const CaseOptionBuildInfo& cob,const String& type_name)
213: CaseOptionSimple(cob)
214, m_type_name(type_name)
215, m_enum_values(new CaseOptionEnumValues())
216{
217}
218
219/*---------------------------------------------------------------------------*/
220/*---------------------------------------------------------------------------*/
221
222CaseOptionEnum::
223~CaseOptionEnum()
224{
225 delete m_enum_values;
226}
227
228/*---------------------------------------------------------------------------*/
229/*---------------------------------------------------------------------------*/
230
231void CaseOptionEnum::
232_search(bool is_phase1)
233{
234 CaseOptionSimple::_search(is_phase1);
235 if (!is_phase1)
236 return;
237 bool is_default = _element().null();
238 String str_val = (is_default) ? _defaultValue() : _element().value();
239 bool has_valid_value = true;
240 if (str_val.null()) {
241 if (!isOptional()){
243 name(),rootElement());
244
245 return;
246 }
247 else
248 has_valid_value = false;
249
250 }
251 _setHasValidValue(has_valid_value);
252
253 if (has_valid_value){
254 String lang;
255 // La valeur par défaut n'a pas de langage associé. Il ne faut donc
256 // pas essayer de la convertir.
257 if (!is_default)
258 lang = caseDocumentFragment()->language();
259 int value = 0;
260 bool is_bad = m_enum_values->valueOfName(str_val,lang,value);
261
262 if (is_bad) {
263 StringUniqueArray valid_values;
264 m_enum_values->getValidNames(lang,valid_values);
266 name(),rootElement(),str_val,m_type_name,valid_values);
267 return;
268 }
269 _setOptionValue(value);
270 }
271
272 _setIsInitialized();
273}
274
275/*---------------------------------------------------------------------------*/
276/*---------------------------------------------------------------------------*/
277
278void CaseOptionEnum::
279_setEnumDefaultValue(int def_value)
280{
281 // Si on a une valeur donnée par l'utilisateur, on ne fait rien.
282 if (isPresent())
283 return;
284
285 // Valeur déjà initialisée. Dans ce cas on remplace aussi la valeur actuelle
286 if (_isInitialized())
287 _setOptionValue(def_value);
288
289 // La valeur par défaut n'a pas de langue associée.
290 _setDefaultValue(m_enum_values->nameOfValue(def_value,String()));
291}
292
293/*---------------------------------------------------------------------------*/
294/*---------------------------------------------------------------------------*/
295
297print(const String& lang,std::ostream& o) const
298{
299 _checkIsInitialized();
300 int v = _optionValue();
301 o << "'" << m_enum_values->nameOfValue(v,lang) << "' (" << v << ")";
302}
303
304/*---------------------------------------------------------------------------*/
305/*---------------------------------------------------------------------------*/
306
308visit(ICaseDocumentVisitor* visitor) const
309{
310 visitor->applyVisitor(this);
311}
312
313/*---------------------------------------------------------------------------*/
314/*---------------------------------------------------------------------------*/
315
316void CaseOptionEnum::
317_updateFromFunction(Real current_time,Integer current_iteration)
318{
319 _checkIsInitialized();
320 ICaseFunction* func = function();
321 ITraceMng* msg = caseMng()->traceMng();
323 int current_value = _optionValue();
324 String new_str = m_enum_values->nameOfValue(current_value,lang);
325 switch(func->paramType()){
327 new_str = _convertFunctionRealToString(func,current_time);
328 break;
330 new_str = _convertFunctionIntegerToString(func,current_iteration);
331 break;
333 break;
334 }
335 int new_value = 0;
336 bool is_bad = m_enum_values->valueOfName(new_str,lang,new_value);
337 if (is_bad) {
338 StringUniqueArray valid_values;
339 m_enum_values->getValidNames(lang,valid_values);
341 name(),rootElement(),new_str,m_type_name,valid_values);
342 return;
343 //throw CaseOptionException("get_value",name(),rootElement(),new_str,m_type_name);
344 }
345 msg->debug() << "New value for enum option <" << name() << "> " << new_value;
346 bool has_changed = new_value!=current_value;
347 _setChangedSinceLastIteration(has_changed);
348 if (has_changed)
349 _setOptionValue(new_value);
350}
351
352/*---------------------------------------------------------------------------*/
353/*---------------------------------------------------------------------------*/
354
355/*---------------------------------------------------------------------------*/
356/*---------------------------------------------------------------------------*/
357
358CaseOptionMultiEnum::
359CaseOptionMultiEnum(const CaseOptionBuildInfo& cob,const String& type_name)
360: CaseOptionBase(cob)
361, m_type_name(type_name)
362, m_enum_values(new CaseOptionEnumValues())
363{
364}
365
366/*---------------------------------------------------------------------------*/
367/*---------------------------------------------------------------------------*/
368
369CaseOptionMultiEnum::
370~CaseOptionMultiEnum()
371{
372 delete m_enum_values;
373}
374
375/*---------------------------------------------------------------------------*/
376/*---------------------------------------------------------------------------*/
377
378void CaseOptionMultiEnum::
379_search(bool is_phase1)
380{
381 XmlNodeList elem_list = rootElement().children(name());
382
383 Integer size = elem_list.size();
384 _checkMinMaxOccurs(size);
385 if (size==0)
386 return;
387
388 if (is_phase1){
389 _allocate(size);
390
391 const String& lang = caseDocumentFragment()->language();
392
393 for( Integer index=0; index<size; ++index ){
394 XmlNode velem = elem_list[index];
395 // Si l'option n'est pas présente dans le jeu de donnée, on prend
396 // l'option par défaut.
397 String str_val = (velem.null()) ? _defaultValue() : velem.value();
398 if (str_val.null()) {
400 name(),rootElement());
401 continue;
402 //throw CaseOptionException("get_value",name(),rootElement());
403 }
404
405 int value = 0;
406 bool is_bad = m_enum_values->valueOfName(str_val,lang,value);
407
408 if (is_bad) {
409 StringUniqueArray valid_values;
410 m_enum_values->getValidNames(lang,valid_values);
412 name(),rootElement(),str_val,m_type_name,valid_values);
413 continue;
414 //throw CaseOptionException("get_value",name(),rootElement(),str_val,m_type_name);
415 }
416 else
417 _setOptionValue(index,value);
418 }
419 }
420}
421
422/*---------------------------------------------------------------------------*/
423/*---------------------------------------------------------------------------*/
424
426print(const String& lang,std::ostream& o) const
427{
428 for( Integer i=0, s=_nbElem(); i<s; ++i ){
429 int v = _optionValue(i);
430 o << "'" << m_enum_values->nameOfValue(v,lang) << "' (" << v << ")";
431 }
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
438visit(ICaseDocumentVisitor* visitor) const
439{
440 visitor->applyVisitor(this);
441}
442
443/*---------------------------------------------------------------------------*/
444/*---------------------------------------------------------------------------*/
445
446} // End namespace Arcane
447
448/*---------------------------------------------------------------------------*/
449/*---------------------------------------------------------------------------*/
String name() const
Retourne le nom de l'option correspondant au langage du jeu de données.
String _defaultValue() const
Retourne la valeur par défaut de l'option ou 0 s'il n'y en a pas.
ICaseMng * caseMng() const
Gestionnaire de cas.
ICaseDocumentFragment * caseDocumentFragment() const
Retourne le document associé à cette option.
XmlNode rootElement() const
Retourne l'élément racine du DOM.
String nameOfValue(int value, const String &lang) const
Retourne le nom de correspondant à la valeur value pour le langage lang.
CaseOptionEnumValues()
Contruit l'instance.
UniqueArray< CaseOptionEnumValue * > EnumValueList
Type de la liste des valeurs.
void getValidNames(const String &lang, StringArray &names) const
Remplit names avec les noms valides pour la langue lang.
~CaseOptionEnumValues()
Libère les ressources.
bool valueOfName(const String &name, const String &lang, int &value) const
Retourne la valeur de l'énumération ayant le nom name.
Integer nbEnumValue() const
Retourne le nombre de valeurs de l'énumération.
CaseOptionEnumValue * enumValue(Integer index) const
Retourne la ième valeur.
void addEnumValue(CaseOptionEnumValue *value, bool do_clone)
Ajoute la valeur d'énumération value. L'instance devient propriétaire de value qui est détruite lorsq...
virtual void print(const String &lang, std::ostream &o) const
Imprime la valeur de l'option dans le langage lang,sur le flot o.
virtual void _setOptionValue(int v)=0
Positionne à v la valeur de l'option.
virtual int _optionValue() const =0
Retourne la valeur de l'option.
virtual void visit(ICaseDocumentVisitor *visitor) const
Applique le visiteur sur cette option.
static void addInvalidTypeError(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const XmlNode &parent, const String &value, const String &expected_type)
Erreur lorsqu'une valeur d'une jeu de données n'est pas du bon type. Cette erreur est collective.
static void addOptionNotFoundError(ICaseDocumentFragment *document, const TraceInfo &where, const String &node_name, const XmlNode &parent)
Erreur lorsqu'une option du jeu de données n'est pas trouvée. Cette erreur est collective.
virtual void visit(ICaseDocumentVisitor *visitor) const
Applique le visiteur sur cette option.
virtual Integer _nbElem() const =0
Retourne le nombre d'éléments du tableau.
virtual void print(const String &lang, std::ostream &o) const
Imprime la valeur de l'option dans le langage lang,sur le flot o.
virtual void _allocate(Integer size)=0
Alloue un tableau pour size éléments.
virtual int _optionValue(Integer index) const =0
Retourne la valeur de l'énumération pour l'indice index.
virtual void _setOptionValue(Integer index, int v)=0
String name(const String &lang) const
retourne le nom de l'option dans le langage lang. Si aucune traduction n'est disponible dans le langa...
virtual ~CaseOptionName()
Libère les ressources.
CaseOptionName(const String &true_name)
Construit une option de nom true_name.
void addAlternativeNodeName(const String &lang, const String &tname)
Ajoute une traduction pour le nom de l'option. Ajoute le nom tname correspondant au langage lang....
Classe de base des options simples (uniquement une valeur).
ICaseFunction * function() const override
Fonction associée à cette option (0 si aucune).
bool isOptional() const
Indique si l'option est facultative.
bool isPresent() const
Retourne true si l'option est présente.
virtual String language() const =0
Langage utilisé dans le jeu de données.
Interface du visiteur pour une option du jeu de données.
@ ParamUnknown
Type de paramètre inconnu.
@ ParamReal
Paramètre de type Real.
@ ParamInteger
Paramètre de type Integer.
virtual eParamType paramType() const =0
Type du paramètre de la fonction.
virtual ITraceMng * traceMng()=0
Gestionnaire de traces.
void add(const String &key, const String &value)
Ajoute le couple (key,value) au dictionnaire.
String find(const String &key, bool throw_exception=false) const
Retourne la valeur associée à key.
String value() const
Valeur du noeud.
Definition XmlNode.cc:199
XmlNodeList children(const String &name) const
Ensemble des noeuds fils de ce noeud ayant pour nom name.
Definition XmlNode.cc:93
bool null() const
Vrai si le noeud est nul.
Definition XmlNode.h:294
Classe de base des vecteurs 1D de données.
void add(ConstReferenceType val)
Ajoute l'élément val à la fin du tableau.
Interface du gestionnaire de traces.
virtual TraceMessageDbg debug(Trace::eDebugLevel=Trace::Medium)=0
Flot pour un message de debug.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:304
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
UniqueArray< String > StringUniqueArray
Tableau dynamique à une dimension de chaînes de caractères.
Definition UtilsTypes.h:525
Int32 Integer
Type représentant un entier.