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