IConfigurator.py 7.87 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#MDANSE : Molecular Dynamics Analysis for Neutron Scattering Experiments
#------------------------------------------------------------------------------------------
#Copyright (C)
#2015- Eric C. Pellegrini Institut Laue-Langevin
#BP 156
#6, rue Jules Horowitz
#38042 Grenoble Cedex 9
#France
#pellegrini[at]ill.fr
#goret[at]ill.fr
#aoun[at]ill.fr
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#Lesser General Public License for more details.
#
#You should have received a copy of the GNU Lesser General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

''' 
Created on Mar 30, 2015

30
:author: Eric C. Pellegrini
31
32
33
34
35
36
37
38
'''

import abc

from MDANSE import REGISTRY
from MDANSE.Core.Error import Error

class ConfiguratorError(Error):
39
40
41
    '''
    This class handles any exception related to Configurator-derived object
    '''
42
43
    
    def __init__(self, message, configurator=None):
44
45
46
47
48
49
50
51
        '''
        Initializes the the object.
        
        :param message: the exception message
        :type message: str
        :param configurator: the configurator in which the exception was raised
        :type configurator: an instance or derived instance of a MDANSE.Framework.Configurators.Configurator object
        '''
52
53
54
55
56

        self._message = message
        self._configurator = configurator
                
    def __str__(self):
57
58
59
60
61
62
        '''
        Returns the informal string representation of this object.
        
        :return: the informal string representation of this object
        :rtype: str
        '''
63
64
65
66
67
68
69
70
        
        if self._configurator is not None:
            self._message = "Configurator: %r --> %s" % (self._configurator.name,self._message)
        
        return self._message
    
    @property
    def configurator(self):
71
72
73
74
75
76
        '''
        Returns the configurator in which the exception was raised

        :return: the configurator in which the exception was raised
        :rtype: an instance or derived instance of a MDANSE.Framework.Configurators.Configurator object
        '''
77
78
79
        return self._configurator
                                                
class IConfigurator(dict):
80
81
    '''
    This class implements the base class for configurator objects. A configurator object is a dictionary-derived object that is used 
82
83
    to configure one item of a given configuration. Once the input value given for that item is configured, the dictionary is updated 
    with keys/values providing information about this item.
84
85
86
87
88
89
90
    
    A configurator is not designed to be used as a stand-alone object. It should be used within the scope of a Configurable object that 
    will store a complete configuration for a given task (e.g. job, Q vectors, instrument resolution ...).
    
    Usually, configurator objects are self-consistent but for complex ones, it can happen that they depends on other configurators of the 
    configuration.
    '''
91
92
93
94
95
96
97
98
99
    
    __metaclass__ = REGISTRY

    type = "configurator"
    
    _default = None
    
    _doc_ = "undocumented"
                            
100
    def __init__(self, name, **kwargs):
101
102
103
104
105
        '''
        Initializes a configurator object.
        
        :param name: the name of this configurator.
        :type name: str
106
107
108
        :param dependencies: the other configurators on which this configurator depends on to be configured. \
        This has to be input as a dictionary that maps the name under which the dependency will be used within \
        the configurator implementation to the actual name of the configurator on which this configurator is depending on.  
109
110
111
112
113
114
115
116
        :type dependencies: (str,str)-dict
        :param default: the default value of this configurator.
        :type default: any python object
        :param label: the label of the panel in which this configurator will be inserted in the MDANSE GUI.
        :type label: str
        :param widget: the configurator widget that corresponds to this configurator.
        :type widget: str
        '''
117
118

        self._name = name
119
        
120
        self._configurable = kwargs.get('configurable',None)
121
                
122
        self._dependencies = kwargs.get('dependencies',{})
123

124
        self._default = kwargs.get('default',self.__class__._default) 
125

126
        self._label = kwargs.get('label'," ".join(name.split('_')).strip())
127

128
        self._widget = kwargs.get('widget',self.type)
129
130
        
        self._configured = False
131
132
133
            
    @property
    def default(self):
134
135
136
137
138
139
        '''
        Returns the default value of this configurator.
        
        :return: the default value of this configurator.
        :rtype: any Python object
        '''
140
141
142
143
144
        
        return self._default
    
    @property
    def dependencies(self):
145
146
147
148
149
150
        '''
        Returns the dependencies maps of this configurator.
        
        :return: the dependencies maps of this configurator.
        :rtype: (str,str)-dict
        '''
151
152
153
154
155
        
        return self._dependencies
        
    @property
    def label(self):
156
157
158
159
160
161
        '''
        Returns the label of this configurator that will be used when inserting its corresponding widget in a configuration panel.
        
        :return: the label of this configurator.
        :rtype: str 
        '''
162
163
164
165
166
        
        return self._label

    @property
    def name(self):
167
168
169
170
171
172
        '''
        Returns the name of this configurator. That name will be used as a key of a Configurable object.
        
        :return: the name of this configurator.
        :rtype: str
        '''
173
174
175
176
177
        
        return self._name

    @property
    def widget(self):
178
179
180
181
182
183
        '''
        Returns the name of the widget that will be associated to this configurator.
        
        :return: the name of the configurator-widget.
        :rtype: str
        '''
184
185
186
187
        
        return self._widget
    
    @abc.abstractmethod
188
    def configure(self, value):
189
190
        '''
        Configures this configurator with a given value.
191
        
192
193
194
195
196
        :param value: the input value to be configured.
        :type value: depends on the configurator

        :note: this is an abstract method.
        '''
197

198
199
200
201
202
203
204
205
    def set_configured(self,configured):
        
        self._configured = configured
        
    def is_configured(self):
        
        return self._configured

206
207
208
    def set_configurable(self,configurable):
        
        self._configurable = configurable
209
                                                
210
    def check_dependencies(self, configured):
211
212
213
214
215
216
217
218
219
        '''
        Check that the configurators on which this configurator depends on have already been configured.
        
        :param configured: the names of the configurators that have already been configured when configuring this configurator.
        :type: list of str
        
        :return: True if the configurators on which this configurator depends on have already been configured. False otherwise.
        :rtype: bool
        '''
220
221
222
223
224
225
226
227
        
        for c in self._dependencies.values():
            if c not in configured:
                return False

        return True
    
    def get_information(self):
228
229
230
231
232
233
234
235
236
        '''
        Returns some informations about this configurator.
        
        :return: the information about this configurator
        :rtype: str
        
        :note: this is an abstract method.
        '''

237
        return ""