1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 '''
20 Set of functions to parse stuff.
21
22 Created on Jun 28, 2011
23
24 @author: tmetsch
25 '''
26
27
28
29
30
31 from occi.core_model import Category, Link, Mixin, Kind
32
33
34
35
36
37
38 -def get_category(category_string, registry, extras, is_mixin=False):
39 '''
40 Create a Category from a string rendering.
41
42 If found it will return the object from the registry.
43
44 If is_mixin is set to true it will not match with the registry and just
45 return a Mixin.
46
47 category_string -- A string rendering of a category.
48 registry -- To generate a list of registered categories.
49 extras -- The passed on extras argument
50 is_mixin -- Mixin will be created and no matching will be done.
51 '''
52 categories = registry.get_categories(extras)
53
54 term = category_string[:category_string.find(';')].strip()
55
56
57 scheme = find_in_string(category_string, 'scheme')
58
59 if is_mixin:
60 location = find_in_string(category_string, 'location')
61 if not location[-1] == '/':
62 raise AttributeError('Illegal location; must end with /')
63 if location[0] != '/' and location.find('http') != 0:
64 raise AttributeError('Illegal location; Either provide full URL'
65 ' or just a path starting with /.')
66 mixin = Mixin(scheme, term, location=location)
67 mixin.extras = registry.get_extras(extras)
68
69 try:
70 related = find_in_string(category_string, 'rel')
71 except AttributeError:
72 return mixin
73 else:
74 for item in categories:
75 if str(item) == related:
76 mixin.related = [item]
77 return mixin
78 raise AttributeError('Related category cannot be found.')
79
80
81 tmp = Category(scheme, term, '', {}, '')
82 if extras is not None:
83 tmp.extras = registry.get_extras(extras)
84 for item in categories:
85 if item.extras is None:
86 tmp.extras = None
87 if tmp == item:
88 del tmp
89 return item
90 tmp.extras = registry.get_extras(extras)
91 elif item.extras is not None:
92 if tmp == item:
93 del tmp
94 return item
95 raise AttributeError('The following category is not registered within'
96 + ' this service (See Query interfaces): '
97 + str(scheme) + str(term))
98
99
101 '''
102 Create a string rendering for a Category.
103
104 category -- A category.
105 registry -- registry to retrieve hostname.
106 '''
107
108 tmp = ''
109 tmp += category.term
110 tmp += '; scheme="' + category.scheme + '"'
111 tmp += '; class="' + repr(category) + '"'
112 if hasattr(category, 'title') and category.title is not '':
113 tmp += '; title="' + category.title + '"'
114 if hasattr(category, 'related') and len(category.related) > 0:
115 rel_list = []
116 for item in category.related:
117 rel_list.append(str(item))
118 tmp += '; rel="' + ' '.join(rel_list) + '"'
119 if hasattr(category, 'location') and category.location is not None:
120 tmp += '; location="'
121 if category.location.find('http') == -1:
122 tmp += registry.get_hostname()
123 tmp += category.location + '"'
124 if hasattr(category, 'attributes') and len(category.attributes) > 0:
125 attr_list = []
126 for item in category.attributes:
127 if category.attributes[item] == 'required':
128 attr_list.append(item + '{required}')
129 elif category.attributes[item] == 'immutable':
130 attr_list.append(item + '{immutable}')
131 else:
132 attr_list.append(item)
133 tmp += '; attributes="' + ' '.join(attr_list) + '"'
134 if hasattr(category, 'actions') and len(category.actions) > 0:
135 action_list = []
136 for item in category.actions:
137 action_list.append(str(item))
138 tmp += '; actions="' + ' '.join(action_list) + '"'
139 return tmp
140
141
143 '''
144 Determine the kind ans mixins for inline link creation.
145
146 categories -- String with a set of category string definitions.
147 registry -- Registry used for this call.
148 extras -- Passed on extra object.
149 '''
150 tmp_kind = None
151 tmp_mixins = []
152 for tmp_cat in categories.split(' '):
153 tempus = tmp_cat.split('#')
154 link_category = get_category(tempus[1].strip() + ';scheme="'
155 + tempus[0].strip() + '#"', registry,
156 extras)
157 if isinstance(link_category, Kind):
158 tmp_kind = link_category
159 else:
160 tmp_mixins.append(link_category)
161
162 return tmp_kind, tmp_mixins
163
164
165 -def get_link(link_string, source, registry, extras):
166 '''
167 Create a Link from a string rendering.
168
169 Also note that the link_id is set but is not yet registered as resource.
170
171 link_string -- A string rendering of a link.
172 source -- The source entity.
173 registry -- Registry used for this call.
174 extras -- Passed on extra object.
175 '''
176 tmp = link_string.find('<') + 1
177 target_id = link_string[tmp:link_string.rfind('>', tmp)].strip()
178
179 try:
180 link_id = find_in_string(link_string, 'self')
181 except AttributeError:
182 link_id = None
183
184 try:
185 tmp_category = find_in_string(link_string, 'category')
186 except AttributeError:
187 raise AttributeError('Could not determine the Category of the Link.')
188
189 tmp_kind, tmp_mixins = _get_link_categories(tmp_category, registry, extras)
190
191 if tmp_kind is None:
192 raise AttributeError('Unable to find the Kind of the Link.')
193
194 attributes = {}
195 attr_begin = link_string.find('category="') + 12 + len(tmp_category)
196 attributes_str = link_string[attr_begin:]
197 for attribute in attributes_str.split(';'):
198 tmp = attribute.strip().split('=')
199 if len(tmp) == 2:
200 attributes[tmp[0].strip()] = tmp[1].rstrip('"').lstrip('"').strip()
201
202 try:
203 if not target_id.find(registry.get_hostname()):
204 target_id = target_id.replace(registry.get_hostname(), '')
205 target = registry.get_resource(target_id, extras)
206 except KeyError:
207
208 raise AttributeError('The target for the link cannot be found: '
209 + target_id)
210
211 link = Link(link_id, tmp_kind, tmp_mixins, source, target)
212 link.attributes = attributes
213 return link
214
215
217 '''
218 Create a string rendering for a Link.
219
220 link -- A link.
221 '''
222 tmp = '<' + link.target.identifier + '>'
223 tmp += '; rel="' + str(link.target.kind) + '"'
224 tmp += '; self="' + str(link.identifier) + '"'
225 tmp += '; category="' + str(link.kind)
226
227 if len(link.mixins) > 0:
228 for mixin in link.mixins:
229 tmp = tmp + ' ' + str(mixin)
230
231 tmp += '"'
232
233 link.attributes['occi.core.id'] = link.identifier
234 link.attributes['occi.core.source'] = link.source.identifier
235
236 link.attributes['occi.core.target'] = link.target.identifier
237
238 if len(link.attributes) > 0:
239 attr_str_list = []
240 for item in link.attributes:
241 attr_str_list.append(item + '="' + link.attributes[item] + '"')
242 tmp += '; ' + '; '.join(attr_str_list)
243 return tmp
244
245
247 '''
248 Retrieve the attributes from the HTTP X-OCCI-Attribute rendering.
249 '''
250 tmp = _strip_all(attribute_string)
251 if tmp.find('=') == -1:
252 raise AttributeError('Mailformed Attribute description!')
253 key = _strip_all(tmp[:tmp.find('=')])
254 value = tmp[tmp.find('=') + 1:]
255 if value.find('"') is not -1:
256 value = _strip_all(value)
257
258 return key, value
259
260
261
262
263
264
266 '''
267 Removes beginning / ending quotes and whitespaces.
268 '''
269 return string.lstrip().lstrip('"').rstrip().rstrip('"')
270
271
273 '''
274 Search for string which is surrounded by '<name>=' and ';'. Raises
275 AttributeError if value cannot be found.
276
277 string -- The string to look into.
278 name -- The name of the value to look for.
279 '''
280 begin = string.find(name + '=')
281 end = string.find(';', begin)
282 result = string[begin + len(name) + 1:end].rstrip('"').lstrip('"').strip()
283 if begin == -1:
284 raise AttributeError('Could not determine the value for: ' + name)
285 return result
286