Salome HOME
ba6a01593d2857331b7966c63487a1ee4d06bf3a
[tools/eficas.git] / Noyau / N_ENTITE.py
1 # coding=utf-8
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2017  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20
21
22 """
23     Ce module contient la classe ENTITE qui est la classe de base
24     de toutes les classes de definition d'EFICAS.
25 """
26
27 from __future__ import absolute_import
28 from __future__ import print_function
29 try :
30    from builtins import str
31    from builtins import object
32 except :
33    pass
34 import re
35 from . import N_CR
36 from . import N_OPS
37 from . import N_VALIDATOR
38
39 import six
40 stringTypes = (str, six.text_type)
41
42
43 class ENTITE(object):
44
45     """
46        Classe de base pour tous les objets de definition : mots cles et commandes
47        Cette classe ne contient que des methodes utilitaires
48        Elle ne peut être instanciee et doit d abord être specialisee
49     """
50     CR = N_CR.CR
51     factories = {'validator': N_VALIDATOR.validatorFactory}
52
53     def __init__(self, validators=None):
54         """
55            Initialise les deux attributs regles et entites d'une classe dérivée
56            à : pas de règles et pas de sous-entités.
57
58            L'attribut regles doit contenir la liste des regles qui s'appliquent
59            sur ses sous-entités
60
61            L'attribut entités doit contenir le dictionnaires des sous-entités
62            (clé = nom, valeur=objet)
63         """
64         self.regles = ()
65         self.entites = {}
66         if validators:
67             self.validators = self.factories['validator'](validators)
68         else:
69             self.validators = validators
70
71     def affecter_parente(self):
72         """
73             Cette methode a pour fonction de donner un nom et un pere aux
74             sous entités qui n'ont aucun moyen pour atteindre leur parent
75             directement
76             Il s'agit principalement des mots cles
77         """
78         for k, v in list(self.entites.items()):
79             v.pere = self
80             v.nom = k
81
82     def verif_cata(self):
83         """
84             Cette methode sert à valider les attributs de l'objet de définition
85         """
86         raise NotImplementedError("La méthode verif_cata de la classe %s doit être implémentée"
87                                   % self.__class__.__name__)
88
89     def __call__(self):
90         """
91             Cette methode doit retourner un objet dérivé de la classe OBJECT
92         """
93         raise NotImplementedError("La méthode __call__ de la classe %s doit être implémentée"
94                                   % self.__class__.__name__)
95
96     def report(self):
97         """
98            Cette méthode construit pour tous les objets dérivés de ENTITE un
99            rapport de validation de la définition portée par cet objet
100         """
101         self.cr = self.CR()
102         self.verif_cata()
103         for k, v in list(self.entites.items()):
104             try:
105                 cr = v.report()
106                 cr.debut = u"Début " + v.__class__.__name__ + ' : ' + k
107                 cr.fin = u"Fin " + v.__class__.__name__ + ' : ' + k
108                 self.cr.add(cr)
109             except:
110                 self.cr.fatal("Impossible d'obtenir le rapport de %s %s" % (k, repr(v)))
111                 print(("Impossible d'obtenir le rapport de %s %s" % (k, repr(v))))
112                 print(("père =", self))
113         return self.cr
114
115     def verif_cata_regles(self):
116         """
117            Cette méthode vérifie pour tous les objets dérivés de ENTITE que
118            les objets REGLES associés ne portent que sur des sous-entités
119            existantes
120         """
121         for regle in self.regles:
122             l = []
123             for mc in regle.mcs:
124                 if not mc in  self.entites :
125                     l.append(mc)
126             if l != []:
127                 txt = str(regle)
128                 self.cr.fatal(
129                     _(u"Argument(s) non permis : %r pour la règle : %s"), l, txt)
130
131     def check_definition(self, parent):
132         """Verifie la definition d'un objet composite (commande, fact, bloc)."""
133         args = self.entites.copy()
134         mcs = set()
135         for nom, val in list(args.items()):
136             if val.label == 'SIMP':
137                 mcs.add(nom)
138                 # XXX
139                 # if val.max != 1 and val.type == 'TXM':
140                     # print "#CMD", parent, nom
141             elif val.label == 'FACT':
142                 val.check_definition(parent)
143                 # CALC_SPEC !
144                 # assert self.label != 'FACT', \
145                    #'Commande %s : Mot-clef facteur present sous un mot-clef facteur : interdit !' \
146                    #% parent
147             else:
148                 continue
149             del args[nom]
150         # seuls les blocs peuvent entrer en conflit avec les mcs du plus haut
151         # niveau
152         for nom, val in list(args.items()):
153             if val.label == 'BLOC':
154                 mcbloc = val.check_definition(parent)
155                 # XXX
156                 # print "#BLOC", parent, re.sub('\s+', ' ', val.condition)
157                 assert mcs.isdisjoint(mcbloc), "Commande %s : Mot(s)-clef(s) vu(s) plusieurs fois : %s" \
158                     % (parent, tuple(mcs.intersection(mcbloc)))
159         return mcs
160
161     def check_op(self, valmin=-9999, valmax=9999):
162         """Vérifie l'attribut op."""
163         if self.op is not None and \
164            (type(self.op) is not int or self.op < valmin or self.op > valmax):
165             self.cr.fatal(_(u"L'attribut 'op' doit être un entier "
166                             u"compris entre %d et %d : %r"), valmin, valmax, self.op)
167
168     def check_proc(self):
169         """Vérifie l'attribut proc."""
170         if self.proc is not None and not isinstance(self.proc, N_OPS.OPS):
171             self.cr.fatal(
172                 _(u"L'attribut op doit être une instance d'OPS : %r"), self.proc)
173
174     def check_regles(self):
175         """Vérifie l'attribut regles."""
176         if type(self.regles) is not tuple:
177             self.cr.fatal(_(u"L'attribut 'regles' doit être un tuple : %r"),
178                           self.regles)
179
180     def check_fr(self):
181         """Vérifie l'attribut fr."""
182         if type(self.fr) not in stringTypes:
183             self.cr.fatal(
184                 _(u"L'attribut 'fr' doit être une chaine de caractères : %r"),
185                 self.fr)
186
187     def check_docu(self):
188         """Vérifie l'attribut docu."""
189         if type(self.docu) not in stringTypes:
190             self.cr.fatal(
191                 _(u"L'attribut 'docu' doit être une chaine de caractères : %r"),
192                 self.docu)
193
194     def check_nom(self):
195         """Vérifie l'attribut proc."""
196         if type(self.nom) is not str:
197             self.cr.fatal(
198                 _(u"L'attribut 'nom' doit être une chaine de caractères : %r"),
199                 self.nom)
200
201     def check_reentrant(self):
202         """Vérifie l'attribut reentrant."""
203         if self.reentrant not in ('o', 'n', 'f'):
204             self.cr.fatal(
205                 _(u"L'attribut 'reentrant' doit valoir 'o','n' ou 'f' : %r"),
206                 self.reentrant)
207
208     def check_statut(self, into=('o', 'f', 'c', 'd')):
209         """Vérifie l'attribut statut."""
210         if self.statut not in into:
211             self.cr.fatal(_(u"L'attribut 'statut' doit être parmi %s : %r"),
212                           into, self.statut)
213
214     def check_condition(self):
215         """Vérifie l'attribut condition."""
216         if self.condition != None:
217             if type(self.condition) is not str:
218                 self.cr.fatal(
219                     _(u"L'attribut 'condition' doit être une chaine de caractères : %r"),
220                     self.condition)
221         else:
222             self.cr.fatal(_(u"La condition ne doit pas valoir None !"))
223
224     def check_min_max(self):
225         """Vérifie les attributs min/max."""
226         if type(self.min) != int:
227             if self.min != '**'and self.min != float('-inf'):
228                 self.cr.fatal(
229                     _(u"L'attribut 'min' doit être un entier : %r"), self.min)
230         if type(self.max) != int:
231             if self.max != '**' and self.max != float('inf'):
232                 self.cr.fatal(
233                     _(u"L'attribut 'max' doit être un entier : %r"), self.max)
234         if self.min > self.max:
235             self.cr.fatal(
236                 _(u"Nombres d'occurrence min et max invalides : %r %r"),
237                 self.min, self.max)
238
239     def check_validators(self):
240         """Vérifie les validateurs supplémentaires"""
241         if self.validators and not self.validators.verif_cata():
242             self.cr.fatal(_(u"Un des validateurs est incorrect. Raison : %s"),
243                           self.validators.cata_info)
244
245     def check_homo(self):
246         """Vérifie l'attribut homo."""
247         if self.homo != 0 and self.homo != 1:
248             self.cr.fatal(
249                 _(u"L'attribut 'homo' doit valoir 0 ou 1 : %r"), self.homo)
250
251     def check_into(self):
252         """Vérifie l'attribut into."""
253         if self.into != None:
254             if (type(self.into) not in (list, tuple)) and (type(self.into) != types.FunctionType) :
255                 self.cr.fatal(
256                     _(u"L'attribut 'into' doit être un tuple : %r"), self.into)
257
258     def check_position(self):
259         """Vérifie l'attribut position."""
260         if self.position not in ('local', 'global', 'global_jdc'):
261             self.cr.fatal(_(u"L'attribut 'position' doit valoir 'local', 'global' "
262                             u"ou 'global_jdc' : %r"), self.position)