Salome HOME
chgt noyau pour aster
[tools/eficas.git] / Noyau / N_SENSIBILITE.py
1 # -*- coding: iso-8859-1 -*-
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    Ce module contient les règles nécessaires aux commandes sensibles
22    pour renseigner l'attribut etape.sd.sensi, gérer le caractère réentrant
23    sur présence de la sensibilité.
24 """
25
26 from types import TupleType, ListType
27 EnumTypes = (TupleType, ListType)
28
29 from N_REGLE import REGLE
30
31 # -----------------------------------------------------------------------------
32 class CONCEPT_SENSIBLE(REGLE):
33    """Règle permettant de renseigner au niveau du catalogue comment sera
34    rempli le concept (valeur nominale ou dérivée(s) ou les deux...).
35    """
36    def __init__(self, mode, mocle='SENSIBILITE'):
37       """Constructeur.
38
39          mode : manière dont la commande rempli le concept
40             - 'ENSEMBLE' : concept nominal ET dérivées en une seule passe
41             - 'SEPARE'   : concept nominal OU dérivée (une ou plusieurs)
42             
43          mocle : mot-clé contenant les paramètres sensibles.
44       """
45       REGLE.__init__(self)
46       self.mocle = mocle
47       self._modes = { 'ENSEMBLE' : 0, 'SEPARE' : 1 }
48       self.mode = self._modes.get(mode, self._modes['ENSEMBLE'])
49
50    def gettext(self):
51       """Pour EFICAS
52       """
53       return ''
54
55    def verif(self, args):
56       """Retourne texte + 1 si ok, 0 si nook.
57       On stocke dans sd.sensi l'étape courante, c'est-à-dire celle qui
58       renseigne le concept si cela n'a pas déjà été fait (car verif est
59       appelé à chaque validation).
60       """
61       obj = args["self"]
62       etape = obj.etape
63       id_etape = '%s_%s' % (etape.id, id(etape))
64       if etape.sd == None:
65           return '',1
66       if not hasattr(etape.sd,"sensi"):
67          etape.sd.sensi = {}
68       # si ENSEMBLE, la sd nominale est forcément produite
69       if self.mode == self._modes['ENSEMBLE'] and not etape.sd.sensi.has_key('nominal'):
70          etape.sd.sensi['nominal'] = id_etape
71       # liste des paramètres sensibles
72       valeur = obj[self.mocle]
73       if valeur == None:
74          # pas de sensibilité, la sd nominale est produite
75          if not etape.sd.sensi.has_key('nominal'):
76             etape.sd.sensi['nominal'] = id_etape
77          return '', 1
78       if not type(valeur) in EnumTypes:
79          valeur = [valeur,]
80       for v in valeur:
81          if not etape.sd.sensi.has_key(v.get_name()):
82             etape.sd.sensi[v.get_name()] = id_etape
83       return '', 1
84
85
86 # -----------------------------------------------------------------------------
87 class REUSE_SENSIBLE(REGLE):
88    """Limite le caractère réentrant de la commande.
89    On autorisera reuse seulement si le concept (au sens fortran) n'a pas déjà
90    été calculé (d'après sd.sensi). Ce sera interdit dans les cas suivants :
91       - sd nominale calculée et SENSIBILITE absent
92       - PS1 dans SENSIBILITE et sd dérivée par rapport à PS1 calculée
93    """
94    def __init__(self, mocle='SENSIBILITE'):
95       """Constructeur.
96          mocle : mot-clé SENSIBILITE.
97       """
98       REGLE.__init__(self)
99       self.mocle = mocle
100
101    def gettext(self):
102       """Pour EFICAS
103       """
104       return ''
105
106    def verif(self,args):
107       """Retourne texte + 1 si ok, 0 si nook = reuse interdit.
108       Comme CONCEPT_SENSIBLE est appelé avant (et à chaque validation),
109       on regarde si sd.sensi[ps] a été renseigné par une étape précédente.
110       """
111       obj = args["self"]
112       etape = obj.etape
113       id_etape = '%s_%s' % (etape.id, id(etape))
114       sd = etape.sd
115       # si la commande n'est pas réentrante, rien à faire
116       if etape.reuse is not None:
117          valeur = obj[self.mocle]
118          if valeur is None:
119             if not hasattr(sd, 'sensi') or sd.sensi.get('nominal', id_etape) != id_etape:
120                # pas de sensibilite et concept nominal déjà calculé : reuse interdit
121                text = "Commande non réentrante en l'absence de sensibilité."
122                return text, 0
123          else:
124             if not type(valeur) in EnumTypes:
125                valeur = [valeur,]
126             for ps in valeur:
127                if hasattr(sd, 'sensi') and sd.sensi.get(ps.nom, id_etape) != id_etape:
128                   # concept dérivé par rapport à ps déjà calculé : reuse interdit
129                   text = "Commande non réentrante : dérivée par rapport à %s déjà calculée" % ps.nom
130                   return text, 0
131       return '', 1
132
133
134 # -----------------------------------------------------------------------------
135 class DERIVABLE(REGLE):
136    """Déclare que le concept fourni derrière un mot-clé est dérivable.
137    Sa présence ne suffit pas à le valider, il faut encore que son attribut
138    '.sensi' soit cohérent avec le contenu du mot-clé SENSIBILITE (ou l'absence
139    de celui-ci).
140    """
141    def __init__(self, mocle):
142       """Constructeur.
143          mocle : mot-clé dérivable.
144       """
145       REGLE.__init__(self)
146       self.mocle = mocle
147
148    def gettext(self):
149       """Pour EFICAS
150       """
151       return ''
152
153    def verif(self,args):
154       """
155       """
156       obj = args["self"]
157       try:
158          concept = obj[self.mocle]
159       except IndexError:
160          return '', 1
161       if not type(concept) in EnumTypes:
162          concept = [concept,]
163       l_ps = obj["SENSIBILITE"]
164       for co in concept:
165          if co is None:
166             text = "Concept non défini (None) sous le mot-clé %s" % self.mocle
167             return text, 0
168          if not l_ps:
169             # pas de sensibilité
170             if hasattr(co,"sensi") and not co.sensi.get('nominal'):
171                text = "%s ne contient que des valeurs dérivées, utilisez le mot cle SENSIBILITE" %\
172                      co.nom
173                return text, 0
174          else:
175             # sensibilité spécifiée
176             if not type(l_ps) in EnumTypes:
177                l_ps = [l_ps,]
178             for ps in l_ps:
179                if not hasattr(co,"sensi") or not co.sensi.get(ps.nom):
180                   text = "La dérivée de %s par rapport à %s n'est pas disponible." %\
181                         (co.nom, ps.nom)
182                   return text, 0
183       return '', 1
184