Salome HOME
version 19 mars
[tools/eficas.git] / Noyau / N_ENTITE.py
1 # coding=utf-8
2 # Copyright (C) 2007-2013   EDF R&D
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19
20
21 """
22     Ce module contient la classe ENTITE qui est la classe de base
23     de toutes les classes de definition d'EFICAS.
24 """
25
26 import re
27 import types
28 import N_CR
29 import N_OPS
30 import N_VALIDATOR
31 from strfunc import ufmt
32
33
34 class ENTITE:
35
36     """
37        Classe de base pour tous les objets de definition : mots cles et commandes
38        Cette classe ne contient que des methodes utilitaires
39        Elle ne peut être instanciee et doit d abord être specialisee
40     """
41     CR = N_CR.CR
42     factories = {'validator': N_VALIDATOR.validatorFactory}
43
44     def __init__(self, validators=None):
45         """
46            Initialise les deux attributs regles et entites d'une classe dérivée
47            à : pas de règles et pas de sous-entités.
48
49            L'attribut regles doit contenir la liste des regles qui s'appliquent
50            sur ses sous-entités
51
52            L'attribut entités doit contenir le dictionnaires des sous-entités
53            (clé = nom, valeur=objet)
54         """
55         self.regles = ()
56         self.entites = {}
57         if validators:
58             self.validators = self.factories['validator'](validators)
59         else:
60             self.validators = validators
61
62     def affecter_parente(self):
63         """
64             Cette methode a pour fonction de donner un nom et un pere aux
65             sous entités qui n'ont aucun moyen pour atteindre leur parent
66             directement
67             Il s'agit principalement des mots cles
68         """
69         for k, v in self.entites.items():
70             v.pere = self
71             v.nom = k
72
73     def verif_cata(self):
74         """
75             Cette methode sert à valider les attributs de l'objet de définition
76         """
77         raise NotImplementedError("La méthode verif_cata de la classe %s doit être implémentée"
78                                   % self.__class__.__name__)
79
80     def __call__(self):
81         """
82             Cette methode doit retourner un objet dérivé de la classe OBJECT
83         """
84         raise NotImplementedError("La méthode __call__ de la classe %s doit être implémentée"
85                                   % self.__class__.__name__)
86
87     def report(self):
88         """
89            Cette méthode construit pour tous les objets dérivés de ENTITE un
90            rapport de validation de la définition portée par cet objet
91         """
92         self.cr = self.CR()
93         self.verif_cata()
94         for k, v in self.entites.items():
95             try:
96                 cr = v.report()
97                 cr.debut = u"Début " + v.__class__.__name__ + ' : ' + k
98                 cr.fin = u"Fin " + v.__class__.__name__ + ' : ' + k
99                 self.cr.add(cr)
100             except:
101                 self.cr.fatal(
102                     _(u"Impossible d'obtenir le rapport de %s %s"), k, `v`)
103                 print "Impossible d'obtenir le rapport de %s %s" % (k, `v`)
104                 print "père =", self
105         return self.cr
106
107     def verif_cata_regles(self):
108         """
109            Cette méthode vérifie pour tous les objets dérivés de ENTITE que
110            les objets REGLES associés ne portent que sur des sous-entités
111            existantes
112         """
113         for regle in self.regles:
114             l = []
115             for mc in regle.mcs:
116                 if not self.entites.has_key(mc):
117                     l.append(mc)
118             if l != []:
119                 txt = str(regle)
120                 self.cr.fatal(
121                     _(u"Argument(s) non permis : %r pour la règle : %s"), l, txt)
122
123     def check_definition(self, parent):
124         """Verifie la definition d'un objet composite (commande, fact, bloc)."""
125         args = self.entites.copy()
126         mcs = set()
127         for nom, val in args.items():
128             if val.label == 'SIMP':
129                 mcs.add(nom)
130                 # XXX
131                 # if val.max != 1 and val.type == 'TXM':
132                     # print "#CMD", parent, nom
133             elif val.label == 'FACT':
134                 val.check_definition(parent)
135                 # CALC_SPEC !
136                 # assert self.label != 'FACT', \
137                    #'Commande %s : Mot-clef facteur present sous un mot-clef facteur : interdit !' \
138                    #% parent
139             else:
140                 continue
141             del args[nom]
142         # seuls les blocs peuvent entrer en conflit avec les mcs du plus haut
143         # niveau
144         for nom, val in args.items():
145             if val.label == 'BLOC':
146                 mcbloc = val.check_definition(parent)
147                 # XXX
148                 # print "#BLOC", parent, re.sub('\s+', ' ', val.condition)
149                 assert mcs.isdisjoint(mcbloc), "Commande %s : Mot(s)-clef(s) vu(s) plusieurs fois : %s" \
150                     % (parent, tuple(mcs.intersection(mcbloc)))
151         return mcs
152
153     def check_op(self, valmin=-9999, valmax=9999):
154         """Vérifie l'attribut op."""
155         if self.op is not None and \
156            (type(self.op) is not int or self.op < valmin or self.op > valmax):
157             self.cr.fatal(_(u"L'attribut 'op' doit être un entier "
158                             u"compris entre %d et %d : %r"), valmin, valmax, self.op)
159
160     def check_proc(self):
161         """Vérifie l'attribut proc."""
162         if self.proc is not None and not isinstance(self.proc, N_OPS.OPS):
163             self.cr.fatal(
164                 _(u"L'attribut op doit être une instance d'OPS : %r"), self.proc)
165
166     def check_regles(self):
167         """Vérifie l'attribut regles."""
168         if type(self.regles) is not tuple:
169             self.cr.fatal(_(u"L'attribut 'regles' doit être un tuple : %r"),
170                           self.regles)
171
172     def check_fr(self):
173         """Vérifie l'attribut fr."""
174         if type(self.fr) not in (str, unicode):
175             self.cr.fatal(
176                 _(u"L'attribut 'fr' doit être une chaine de caractères : %r"),
177                 self.fr)
178
179     def check_docu(self):
180         """Vérifie l'attribut docu."""
181         if type(self.docu) not in (str, unicode):
182             self.cr.fatal(
183                 _(u"L'attribut 'docu' doit être une chaine de caractères : %r"),
184                 self.docu)
185
186     def check_nom(self):
187         """Vérifie l'attribut proc."""
188         if type(self.nom) != types.StringType:
189             self.cr.fatal(
190                 _(u"L'attribut 'nom' doit être une chaine de caractères : %r"),
191                 self.nom)
192
193     def check_reentrant(self):
194         """Vérifie l'attribut reentrant."""
195         if self.reentrant not in ('o', 'n', 'f'):
196             self.cr.fatal(
197                 _(u"L'attribut 'reentrant' doit valoir 'o','n' ou 'f' : %r"),
198                 self.reentrant)
199
200     def check_statut(self, into=('o', 'f', 'c', 'd')):
201         """Vérifie l'attribut statut."""
202         if self.statut not in into:
203             self.cr.fatal(_(u"L'attribut 'statut' doit être parmi %s : %r"),
204                           into, self.statut)
205
206     def check_condition(self):
207         """Vérifie l'attribut condition."""
208         if self.condition != None:
209             if type(self.condition) != types.StringType:
210                 self.cr.fatal(
211                     _(u"L'attribut 'condition' doit être une chaine de caractères : %r"),
212                     self.condition)
213         else:
214             self.cr.fatal(_(u"La condition ne doit pas valoir None !"))
215
216     def check_min_max(self):
217         """Vérifie les attributs min/max."""
218         if type(self.min) != types.IntType:
219             if self.min != '**':
220                 self.cr.fatal(
221                     _(u"L'attribut 'min' doit être un entier : %r"), self.min)
222         if type(self.max) != types.IntType:
223             if self.max != '**':
224                 self.cr.fatal(
225                     _(u"L'attribut 'max' doit être un entier : %r"), self.max)
226         if self.min > self.max:
227             self.cr.fatal(
228                 _(u"Nombres d'occurrence min et max invalides : %r %r"),
229                 self.min, self.max)
230
231     def check_validators(self):
232         """Vérifie les validateurs supplémentaires"""
233         if self.validators and not self.validators.verif_cata():
234             self.cr.fatal(_(u"Un des validateurs est incorrect. Raison : %s"),
235                           self.validators.cata_info)
236
237     def check_homo(self):
238         """Vérifie l'attribut homo."""
239         if self.homo != 0 and self.homo != 1:
240             self.cr.fatal(
241                 _(u"L'attribut 'homo' doit valoir 0 ou 1 : %r"), self.homo)
242
243     def check_into(self):
244         """Vérifie l'attribut into."""
245         if self.into != None:
246             if type(self.into) != types.TupleType:
247                 self.cr.fatal(
248                     _(u"L'attribut 'into' doit être un tuple : %r"), self.into)
249
250     def check_position(self):
251         """Vérifie l'attribut position."""
252         if self.position not in ('local', 'global', 'global_jdc'):
253             self.cr.fatal(_(u"L'attribut 'position' doit valoir 'local', 'global' "
254                             u"ou 'global_jdc' : %r"), self.position)