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