2
# This file is part of Checkbox.
4
# Copyright 2008 Canonical Ltd.
6
# Checkbox is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
11
# Checkbox is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
21
from checkbox.lib.cache import cache
23
from checkbox.component import ComponentManager
24
from checkbox.frontend import FrontendException
25
from checkbox.properties import String
28
class Registry(object):
30
Registry base class which should be inherited by each registry
31
implementation. This class basically provides methods to represent
32
the items in the registry as attributes. If some items cannot
33
be represented as attributes, if there are spaces in the name
34
for example, this class also provides methods to reprent them as
40
user = String(required=False)
43
super(Registry, self).__init__()
44
self.id = Registry._id
48
raise NotImplementedError, "this function must be overridden by subclasses"
50
def __getattr__(self, name):
53
def split(self, *args, **kwargs):
54
return str(self).split(*args, **kwargs)
57
raise NotImplementedError, "this function must be overridden by subclasses"
59
def get(self, key, default=None):
61
return self.__getitem__(key)
64
from checkbox.registries.none import NoneRegistry
69
def has_key(self, key):
70
return key in self.keys()
73
for k, v in self.items():
77
from checkbox.registries.link import LinkRegistry
79
for k, v in self.items():
80
# Prevent returning links in a dict() context
81
if not isinstance(v, LinkRegistry):
85
return list(self.iterkeys())
88
from checkbox.registries.link import LinkRegistry
90
for k, v in self.items():
91
# Prevent returning links in a values() context
92
if not isinstance(v, LinkRegistry):
96
return list(self.itervalues())
99
raise Exception, "Cannot call clear on registry."
101
def setdefault(self, key, default=None):
102
raise Exception, "Cannot call setdefault on registry."
104
def __cmp__(self, foreign):
105
local = set(self.items())
106
foreign = set(foreign.items())
109
elif local < foreign:
113
def __contains__(self, key):
114
return key in self.keys()
117
return len(self.keys())
119
def __getitem__(self, key):
120
for k, v in self.items():
126
def __setitem__(self, key, value):
127
raise Exception, "Cannot set setitem on registry."
129
def __delitem__(self, key):
130
raise Exception, "Cannot call delitem on registry."
132
def update(self, foreign):
133
raise Exception, "Cannot call update on registry."
136
class RegistryManager(ComponentManager, Registry):
138
Registry manager which is essentially the root of the registry
139
tree. The first level in this tree consists of the module names
140
which have been loaded from the registries configuration parameter.
146
registries = self._config.get_defaults().registries
147
section_names = re.split(r"\s+", registries)
148
for section_name in section_names:
149
section = self.load_section(section_name)
150
for name in section.get_names():
151
module = section.load_module(name)
152
items.append((name, module))
157
def registry_eval(registry, source):
159
return eval(source, {}, registry)
163
def registry_eval_recursive(registry, source, mask=[False]):
166
value = registry_eval(registry, source)
167
if type(value) in (bool, int) and value:
168
values.append(registry)
170
elif type(value) is tuple and True in value:
171
for i in range(len(value)):
172
if value[i] is True or i >= len(mask):
173
mask[i:i+1] = [value[i]]
175
values.append(registry)
178
for key, value in registry.items():
179
if isinstance(value, Registry):
180
values.extend(registry_eval_recursive(value, source, mask))
181
except FrontendException:
182
# Failing to call the backend should result in a failed eval