Arcane  v4.1.2.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
CaseOptionExtended.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/* CaseOptionExtended.cc (C) 2000-2025 */
9/* */
10/* Option du jeu de données de type 'Extended'. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/core/CaseOptionExtended.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/FatalErrorException.h"
18#include "arcane/utils/StringBuilder.h"
19#include "arcane/utils/internal/ParameterCaseOption.h"
20
21#include "arcane/core/ICaseMng.h"
22#include "arcane/core/CaseOptionError.h"
23#include "arcane/core/ICaseDocumentVisitor.h"
24#include "arcane/core/XmlNodeList.h"
25#include "arcane/core/ICaseOptionList.h"
26#include "arcane/core/MeshHandle.h"
27#include "arcane/core/ICaseDocument.h"
28#include "arcane/core/CaseOptionException.h"
29#include "arcane/core/internal/StringVariableReplace.h"
30#include "arcane/core/internal/ICaseMngInternal.h"
31
32/*---------------------------------------------------------------------------*/
33/*---------------------------------------------------------------------------*/
34
35namespace Arcane
36{
37
38/*---------------------------------------------------------------------------*/
39/*---------------------------------------------------------------------------*/
49_search(bool is_phase1)
50{
51 ITraceMng* tm = traceMng();
53 const ParameterCaseOption pco{ params.getParameterCaseOption(caseDocumentFragment()->language()) };
54 String full_xpath = String::format("{0}/{1}", rootElement().xpathFullName(), name());
55
56 // !!! En XML, on commence par 1 et non 0.
57 UniqueArray<Integer> option_in_param;
58
59 pco.indexesInParam(full_xpath, option_in_param, false);
60
61 XmlNodeList elem_list = rootElement().children(name());
62 Integer size = elem_list.size();
63 bool is_optional = isOptional();
64
65 if (size == 0 && option_in_param.empty() && is_optional) {
66 return;
67 }
68
69 Integer min_occurs = minOccurs();
70 Integer max_occurs = maxOccurs();
71
72 Integer max_in_param = 0;
73
74 // On regarde si l'utilisateur n'a pas mis un indice trop élevé pour l'option dans la ligne de commande.
75 if (!option_in_param.empty()) {
76 max_in_param = option_in_param[0];
77 for (Integer index : option_in_param) {
78 if (index > max_in_param)
79 max_in_param = index;
80 }
81 if (max_occurs >= 0) {
82 if (max_in_param > max_occurs) {
83 StringBuilder msg = "Bad number of occurences in command line (greater than max)";
84 msg += " index_max_in_param=";
85 msg += max_in_param;
86 msg += " max_occur=";
87 msg += max_occurs;
88 msg += " option=";
89 msg += full_xpath;
90 throw CaseOptionException(A_FUNCINFO, msg.toString(), true);
91 }
92 }
93 }
94
95 if (max_occurs >= 0) {
96 if (size > max_occurs) {
97 StringBuilder msg = "Bad number of occurences (greater than max)";
98 msg += " nb_occur=";
99 msg += size;
100 msg += " max_occur=";
101 msg += max_occurs;
102 msg += " option=";
103 msg += full_xpath;
104 throw CaseOptionException(A_FUNCINFO, msg.toString(), true);
105 }
106 }
107
108 // Il y aura toujours au moins min_occurs options.
109 // S'il n'y a pas assez l'options dans le jeu de données et dans les paramètres de la
110 // ligne de commande, on ajoute des services par défaut (si pas de défaut, il y aura un plantage).
111 Integer final_size = std::max(size, std::max(min_occurs, max_in_param));
112
113 if (is_phase1) {
114 _allocate(final_size);
115 m_values.resize(final_size);
116 }
117 else {
118 // D'abord, on aura les options du jeu de données : comme on ne peut pas définir un indice
119 // pour les options dans le jeu de données, elles seront forcément au début et seront contigües.
120 // Puis, s'il manque des options pour atteindre le min_occurs, on ajoute des options par défaut.
121 // S'il n'y a pas d'option par défaut, il y aura une exception.
122 // Enfin, l'utilisateur peut avoir ajouté des options à partir de la ligne de commande. On les ajoute alors.
123 // Si l'utilisateur souhaite modifier des valeurs du jeu de données à partir de la ligne de commande, on
124 // remplace les options au fur et à mesure de la lecture.
125 for (Integer i = 0; i < final_size; ++i) {
126 String str_val;
127
128 // Partie paramètres de la ligne de commande.
129 if (option_in_param.contains(i + 1)) {
130 str_val = pco.getParameterOrNull(full_xpath, i + 1, false);
131 }
132
133 // Partie jeu de données.
134 else if (i < size) {
135 XmlNode velem = elem_list[i];
136 if (!velem.null()) {
137 str_val = velem.value();
138 }
139 }
140
141 // Valeur par défaut.
142 if (str_val.null()) {
143 str_val = _defaultValue();
144 }
145 else {
146 // Dans un else : Le remplacement de symboles ne s'applique pas pour les valeurs par défault du .axl.
147 str_val = StringVariableReplace::replaceWithCmdLineArgs(params, str_val, true);
148 }
149
150 // Maintenant, ce plantage concerne aussi le cas où il n'y a pas de valeurs par défaut et qu'il n'y a
151 // pas assez d'options pour atteindre le min_occurs.
152 if (str_val.null()) {
154 name(),rootElement());
155 continue;
156 }
157 tm->info(5) << "TryConvert opt=" << _xpathFullName() << " i=" << i
158 << " mesh_name=" << parentOptionList()->meshHandle().meshName()
159 << " value=" << str_val;
160 bool is_bad = _tryToConvert(str_val,i);
161 if (is_bad){
162 m_values[i] = String();
164 name(),rootElement(),str_val,_typeName());
165 continue;
166 }
167 m_values[i] = str_val;
168 //ptr_value[i] = val;
169 //cerr << "** FOUND " << val << endl;
170 }
171 }
172}
173
174/*---------------------------------------------------------------------------*/
175/*---------------------------------------------------------------------------*/
176
178print(const String& lang,std::ostream& o) const
179{
180 ARCANE_UNUSED(lang);
181 for( Integer i=0, s=_nbElem(); i<s; ++i )
182 o << m_values[i] << " ";
183}
184
185/*---------------------------------------------------------------------------*/
186/*---------------------------------------------------------------------------*/
187
189visit(ICaseDocumentVisitor* visitor) const
190{
191 visitor->applyVisitor(this);
192}
193
194/*---------------------------------------------------------------------------*/
195/*---------------------------------------------------------------------------*/
196
198setDefaultValue(const String& def_value)
199{
200 // Si on a une valeur donnée par l'utilisateur, on ne fait rien.
201 if (isPresent())
202 return;
203
204 // Valeur déjà initialisée. Dans ce cas on remplace aussi la valeur
205 // actuelle.
206 if (_isInitialized()){
207 bool is_bad = _tryToConvert(def_value);
208 if (is_bad){
209 m_value = String();
210 ARCANE_FATAL("Can not convert '{0}' to type '{1}' (option='{2}')",
211 def_value,_typeName(),xpathFullName());
212 }
213 m_value = def_value;
214 }
215
216 // La valeur par défaut n'a pas de langue associée.
217 _setDefaultValue(def_value);
218}
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
231_search(bool is_phase1)
232{
233 CaseOptionSimple::_search(is_phase1);
234 if (is_phase1)
235 return;
236 ITraceMng* tm = traceMng();
237 // Si l'option n'est pas présente dans le jeu de donnée, on prend
238 // l'option par défaut.
239 String str_val = (_element().null()) ? _defaultValue() : _element().value();
240 bool has_valid_value = true;
241 if (str_val.null()) {
242 m_value = String();
243 if (!isOptional()){
245 name(),rootElement());
246 return;
247 }
248 else
249 has_valid_value = false;
250 }
251 _setHasValidValue(has_valid_value);
252 if (has_valid_value){
253 tm->info(5) << "TryConvert opt=" << xpathFullName()
254 << " mesh_name=" << parentOptionList()->meshHandle().meshName()
255 << " value=" << str_val;
256 bool is_bad = _tryToConvert(str_val);
257 if (is_bad){
258 m_value = String();
260 name(),rootElement(),str_val,_typeName());
261 return;
262 }
263 m_value = str_val;
264 }
265 _setIsInitialized();
266}
267
268/*---------------------------------------------------------------------------*/
269/*---------------------------------------------------------------------------*/
270
272print(const String& lang,std::ostream& o) const
273{
274 ARCANE_UNUSED(lang);
275 _checkIsInitialized();
276 if (hasValidValue())
277 o << m_value;
278 else
279 o << "undefined";
280}
281
282/*---------------------------------------------------------------------------*/
283/*---------------------------------------------------------------------------*/
284
286visit(ICaseDocumentVisitor* visitor) const
287{
288 visitor->applyVisitor(this);
289}
290
291/*---------------------------------------------------------------------------*/
292/*---------------------------------------------------------------------------*/
293
294} // End namespace Arcane
295
296/*---------------------------------------------------------------------------*/
297/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
bool empty() const
Capacité (nombre d'éléments alloués) du vecteur.
bool contains(ConstReferenceType v) const
Vrai si le tableau contient l'élément de valeur v.
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.
bool isOptional() const
Permet de savoir si une option est optionnelle.
Integer maxOccurs() const
Nombre maximum d'occurences (pour une option multiple) (-1 == unbounded)
XmlNode rootElement() const
Retourne l'élément racine du DOM.
ITraceMng * traceMng() const
Gestionnaire de traces.
ICaseOptionList * parentOptionList() const
OptionList parent.
Integer minOccurs() const
Nombre minimum d'occurences (pour une option multiple)
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.
Exception en rapport avec le jeu de données.
void _search(bool is_phase1) override
Cherche la valeur de l'option dans le jeu de donnée.
void setDefaultValue(const String &def_value)
Positionne la valeur par défaut de l'option.
String m_value
Valeur de l'option sous forme de chaîne unicode.
void print(const String &lang, std::ostream &o) const override
Imprime la valeur de l'option dans le langage lang,sur le flot o.
void visit(ICaseDocumentVisitor *visitor) const override
Applique le visiteur sur cette option.
UniqueArray< String > m_values
Valeurs sous forme de chaînes unicodes.
void print(const String &lang, std::ostream &o) const override
Imprime la valeur de l'option dans le langage lang,sur le flot o.
void _search(bool is_phase1) override
Cherche la valeur de l'option dans le jeu de données.
void visit(ICaseDocumentVisitor *visitor) const override
Applique le visiteur sur cette option.
String xpathFullName() const
Nom complet au format donné par la norme XPath.
bool hasValidValue() const
Indique si l'option a une valeur invalide.
bool isOptional() const
Indique si l'option est facultative.
bool isPresent() const
Retourne true si l'option est présente.
Interface du visiteur pour une option du jeu de données.
virtual const ParameterListWithCaseOption & parameters() const =0
Liste des paramètres pouvant surcharger le jeu de données.
virtual ICaseMngInternal * _internalImpl()=0
Implémentation interne.
virtual MeshHandle meshHandle() const =0
Handle du maillage associé
Interface du gestionnaire de traces.
virtual TraceMessage info()=0
Flot pour un message d'information.
Classe représentant l'ensemble des paramètres pouvant modifier les options du jeu de données.
Liste de paramètres avec informations pour surcharger les options du jeu de données.
ParameterCaseOption getParameterCaseOption(const String &language) const
Méthode permettant de récupérer un objet de type ParameterCaseOption.
Constructeur de chaîne de caractère unicode.
String toString() const
Retourne la chaîne de caractères construite.
Chaîne de caractères unicode.
bool null() const
Retourne true si la chaîne est nulle.
Definition String.cc:305
Vecteur 1D de données avec sémantique par valeur (style STL).
Liste de noeuds d'un arbre DOM.
Definition XmlNodeList.h:35
Noeud d'un arbre DOM.
Definition XmlNode.h:51
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
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.