0
|
1 |
#
|
|
2 |
# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
# All rights reserved.
|
|
4 |
# This component and the accompanying materials are made available
|
|
5 |
# under the terms of "Eclipse Public License v1.0"
|
|
6 |
# which accompanies this distribution, and is available
|
|
7 |
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
#
|
|
9 |
# Initial Contributors:
|
|
10 |
# Nokia Corporation - initial contribution.
|
|
11 |
#
|
|
12 |
# Contributors:
|
|
13 |
#
|
|
14 |
# Description:
|
|
15 |
#
|
|
16 |
'''
|
|
17 |
Generator classes
|
|
18 |
'''
|
|
19 |
|
|
20 |
|
|
21 |
import re
|
|
22 |
import os
|
|
23 |
import logging
|
|
24 |
import subprocess
|
|
25 |
import shutil
|
|
26 |
|
|
27 |
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
|
3
|
28 |
from cone.public import utils
|
0
|
29 |
|
|
30 |
class InvalidInputFileException(RuntimeError):
|
|
31 |
"""
|
|
32 |
Exception thrown in case of an invalid input file list.
|
|
33 |
"""
|
|
34 |
pass
|
|
35 |
|
|
36 |
class OutputGenerator(object):
|
|
37 |
def __init__(self,outputpath,**kwargs):
|
|
38 |
self._configuration = None
|
|
39 |
self._subpath = ''
|
|
40 |
self._contentpath = ''
|
|
41 |
self._command = ''
|
|
42 |
self._inputs = []
|
|
43 |
for arg in kwargs.keys():
|
|
44 |
setattr(self, arg, kwargs[arg])
|
|
45 |
self._outputpath = outputpath
|
|
46 |
|
|
47 |
def __str__(self):
|
|
48 |
return "Generator for output %s: %s" % (self.path,self.get_command())
|
|
49 |
|
|
50 |
def generate(self, context=None):
|
|
51 |
command = self.get_command()
|
|
52 |
if command:
|
|
53 |
return command.execute()
|
|
54 |
else:
|
|
55 |
return 0
|
|
56 |
|
|
57 |
def get_outputpath(self):
|
|
58 |
"""
|
|
59 |
Get the confml ref value from configuration if the outputpath is actually a ref
|
|
60 |
"""
|
|
61 |
if self._outputpath and ConfmlRefs.is_confml_ref(self._outputpath):
|
3
|
62 |
oref = ConfmlRefs.get_confml_ref(self._outputpath)
|
|
63 |
opath = self.configuration.get_default_view().get_feature(oref).get_value()
|
|
64 |
if opath == None:
|
|
65 |
logging.getLogger('cone.imageml').warning('Output path not set.')
|
|
66 |
return self._outputpath
|
|
67 |
#raise exceptions.NotBound("Output path reference has no value %s" % oref)
|
|
68 |
(drive,opath) = os.path.splitdrive(opath)
|
|
69 |
opath = utils.resourceref.norm(opath)
|
|
70 |
opath = utils.resourceref.remove_begin_slash(opath)
|
|
71 |
return opath
|
0
|
72 |
else:
|
3
|
73 |
return self._outputpath
|
0
|
74 |
|
|
75 |
def set_outputpath(self, value):
|
|
76 |
self._outputpath = value
|
|
77 |
|
|
78 |
def del_outputpath(self):
|
|
79 |
self._outputpath = None
|
|
80 |
|
|
81 |
def get_subpath(self):
|
|
82 |
return self._subpath
|
|
83 |
|
|
84 |
def set_subpath(self, value):
|
|
85 |
self._subpath = value
|
|
86 |
|
|
87 |
def del_subpath(self):
|
|
88 |
self._subpath = None
|
|
89 |
|
|
90 |
def get_inputs(self):
|
|
91 |
return self._inputs
|
|
92 |
|
|
93 |
def set_inputs(self, value):
|
|
94 |
self._inputs = value
|
|
95 |
|
|
96 |
def del_inputs(self):
|
|
97 |
self._inputs = []
|
|
98 |
|
|
99 |
def get_configuration(self):
|
|
100 |
return self._configuration
|
|
101 |
|
|
102 |
def set_configuration(self, value):
|
|
103 |
self._configuration= value
|
|
104 |
for input in self.inputs:
|
|
105 |
input.configuration = self.configuration
|
|
106 |
|
|
107 |
def del_configuration(self):
|
|
108 |
self._configuration= None
|
|
109 |
|
|
110 |
@property
|
|
111 |
def path(self):
|
|
112 |
return utils.resourceref.join_refs([self.subpath, self.outputpath])
|
|
113 |
|
|
114 |
def get_command(self):
|
|
115 |
(_,ext) = os.path.splitext(self.path)
|
|
116 |
if ext == '.mbm':
|
|
117 |
return BmconvCommand(self)
|
|
118 |
elif ext == '.mif':
|
|
119 |
return MifconvCommand(self)
|
|
120 |
elif ext == '.gif':
|
|
121 |
return CopyCommand(self)
|
|
122 |
else:
|
|
123 |
return None
|
|
124 |
|
|
125 |
def get_refs(self):
|
|
126 |
refs = []
|
|
127 |
for input in self.inputs:
|
|
128 |
refs.extend(input.get_refs())
|
|
129 |
return refs
|
|
130 |
|
|
131 |
configuration = property(get_configuration, set_configuration, del_configuration)
|
|
132 |
inputs = property(get_inputs, set_inputs, del_inputs)
|
|
133 |
outputpath = property(get_outputpath, set_outputpath, del_outputpath)
|
|
134 |
subpath = property(get_subpath, set_subpath, del_subpath)
|
|
135 |
|
|
136 |
class Command(object):
|
|
137 |
def __init__(self,generator):
|
|
138 |
self._generator = generator
|
|
139 |
self._workdir = 'conversion_workdir'
|
3
|
140 |
self._extraparams = ""
|
|
141 |
|
0
|
142 |
|
|
143 |
def execute(self):
|
|
144 |
""" Execute this command """
|
|
145 |
pass
|
|
146 |
|
|
147 |
def get_command(self, input_files):
|
|
148 |
""" return the command as an array """
|
|
149 |
return []
|
|
150 |
|
|
151 |
def create_workdir(self, input_files):
|
|
152 |
"""
|
|
153 |
Extract the necessary input files from storage to a working directory
|
|
154 |
@param input_files: The input files (a list of InputFile objects)
|
|
155 |
"""
|
|
156 |
if not os.path.exists(self._workdir):
|
|
157 |
os.makedirs(self._workdir)
|
|
158 |
|
|
159 |
for file in input_files:
|
|
160 |
self.import_to_work(file.filename)
|
|
161 |
|
|
162 |
def clean_workdir(self):
|
|
163 |
"""
|
|
164 |
Clean up working directory
|
|
165 |
"""
|
|
166 |
if os.path.exists(self._workdir):
|
|
167 |
shutil.rmtree(self._workdir)
|
|
168 |
|
|
169 |
def import_to_work(self,storage_filename):
|
|
170 |
"""
|
|
171 |
Convert a storage filename to a work filename
|
|
172 |
"""
|
|
173 |
workfile = self.workfilename(storage_filename)
|
|
174 |
res = self._generator.configuration.get_resource(storage_filename,"rb")
|
|
175 |
workfile = open(workfile,"wb")
|
|
176 |
workfile.write(res.read())
|
|
177 |
res.close()
|
|
178 |
workfile.close()
|
|
179 |
|
|
180 |
def workfilename(self,filename):
|
|
181 |
"""
|
|
182 |
Convert a storage filename to a work filename
|
|
183 |
"""
|
|
184 |
(_,workname) = os.path.split(filename)
|
|
185 |
return os.path.join(self.workdir,workname)
|
|
186 |
|
|
187 |
def quote_needed(self,str):
|
|
188 |
"""
|
|
189 |
Add quotes around str if it has spaces
|
|
190 |
"""
|
|
191 |
if str.split(' ',1) > 1:
|
|
192 |
return '"%s"' % str
|
|
193 |
else:
|
|
194 |
return str
|
|
195 |
|
|
196 |
@property
|
|
197 |
def tool(self):
|
|
198 |
return ''
|
|
199 |
|
|
200 |
@property
|
|
201 |
def generator(self):
|
|
202 |
return self._generator
|
|
203 |
|
|
204 |
@property
|
|
205 |
def workdir(self):
|
|
206 |
return self._workdir
|
3
|
207 |
|
|
208 |
@property
|
|
209 |
def extraparams(self):
|
|
210 |
if self._generator.extraparams and self._generator.configuration:
|
|
211 |
dview = self._generator.configuration.get_default_view()
|
|
212 |
return utils.expand_refs_by_default_view(self._generator.extraparams, dview)
|
|
213 |
else:
|
|
214 |
return self._generator.extraparams or ''
|
0
|
215 |
|
|
216 |
def _get_filtered_input_files(self):
|
|
217 |
"""
|
|
218 |
Get the list of InputFile objects and with ignored
|
|
219 |
(optional empty or invalid files) entries filtered out.
|
|
220 |
|
|
221 |
Raise InvalidInputFileException if the input file list is invalid.
|
|
222 |
"""
|
|
223 |
# Get all input files
|
|
224 |
input_files = []
|
|
225 |
for input in self.generator.inputs:
|
|
226 |
input_files.extend(input.files)
|
|
227 |
|
|
228 |
# Check if all are empty
|
|
229 |
all_empty = True
|
|
230 |
for file in input_files:
|
|
231 |
if not file.is_empty():
|
|
232 |
all_empty = False
|
|
233 |
break
|
|
234 |
if all_empty:
|
|
235 |
return []
|
|
236 |
|
|
237 |
# Create the filtered list
|
|
238 |
result = []
|
|
239 |
for file in input_files:
|
|
240 |
if file.is_empty():
|
|
241 |
if file.is_optional():
|
|
242 |
# Optional file is empty: no error
|
|
243 |
pass
|
|
244 |
else:
|
|
245 |
raise InvalidInputFileException("Input file empty but not optional")
|
|
246 |
else:
|
|
247 |
if not file.is_valid():
|
|
248 |
raise InvalidInputFileException("Invalid input file: '%s'" % file.path)
|
|
249 |
else:
|
|
250 |
result.append(file)
|
|
251 |
return result
|
|
252 |
|
|
253 |
class BmconvCommand(Command):
|
|
254 |
def __init__(self,generator):
|
|
255 |
super(BmconvCommand, self).__init__(generator)
|
|
256 |
|
|
257 |
def execute(self):
|
|
258 |
"""
|
|
259 |
Execute the command in the current working directory
|
|
260 |
"""
|
|
261 |
input_files = self._get_filtered_input_files()
|
|
262 |
if len(input_files) == 0: return 0
|
|
263 |
self.create_workdir(input_files)
|
|
264 |
|
3
|
265 |
opath = self.generator.path
|
|
266 |
odir = os.path.dirname(opath)
|
|
267 |
if odir and not os.path.exists(odir):
|
|
268 |
os.makedirs(odir)
|
0
|
269 |
|
|
270 |
command = self.get_command(input_files)
|
|
271 |
p = subprocess.Popen(command,
|
|
272 |
stdout=subprocess.PIPE,
|
|
273 |
stderr=subprocess.PIPE)
|
|
274 |
|
|
275 |
# Wait for the process to return
|
|
276 |
out, err = [ e.splitlines() for e in p.communicate() ]
|
|
277 |
for outl in out:
|
|
278 |
if outl not in err:
|
|
279 |
logging.getLogger('cone.bmconv').info(outl)
|
|
280 |
for outl in err:
|
|
281 |
logging.getLogger('cone.bmconv').error(outl)
|
|
282 |
if p.returncode != 0:
|
|
283 |
logging.getLogger('cone.bmconv').error("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
|
|
284 |
else:
|
|
285 |
logging.getLogger('cone.bmconv').info("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
|
|
286 |
if p.returncode == 0:
|
3
|
287 |
self.clean_workdir()
|
0
|
288 |
return p.returncode
|
|
289 |
|
|
290 |
def get_command(self, input_files):
|
|
291 |
command = [self.tool]
|
3
|
292 |
|
|
293 |
""" Add extraparams """
|
|
294 |
if hasattr(self._generator,'extraparams'):
|
|
295 |
command.append(self.extraparams)
|
|
296 |
|
0
|
297 |
""" Add palette file """
|
|
298 |
if hasattr(self._generator,'palette'):
|
|
299 |
command.append('/p%s' % os.path.abspath(self.generator.palette))
|
3
|
300 |
|
0
|
301 |
""" Add output file """
|
|
302 |
""" Add output file as compressed if needed """
|
|
303 |
if self.rom:
|
|
304 |
if self.compress:
|
|
305 |
command.append('/s')
|
|
306 |
else:
|
|
307 |
command.append('/r')
|
|
308 |
else:
|
|
309 |
pass
|
|
310 |
command.append(os.path.normpath(self.generator.path))
|
|
311 |
|
|
312 |
|
|
313 |
for inputfile in input_files:
|
|
314 |
depth = ''
|
|
315 |
if inputfile.depth:
|
|
316 |
depth = '/%s' % inputfile.depth
|
|
317 |
command.append('%s%s' % (depth,self.workfilename(inputfile.filename)))
|
|
318 |
return command
|
|
319 |
|
|
320 |
@property
|
|
321 |
def tool(self):
|
|
322 |
if hasattr(self._generator,'tool'):
|
|
323 |
return os.path.abspath(self._generator.tool)
|
|
324 |
elif hasattr(self._generator, 'tooldir'):
|
|
325 |
return os.path.abspath(os.path.join(self._generator.tooldir, 'bmconv'))
|
|
326 |
else:
|
|
327 |
return 'bmconv'
|
|
328 |
|
|
329 |
@property
|
|
330 |
def rom(self):
|
|
331 |
if hasattr(self._generator,'rom') and self._generator.rom.lower() == 'true':
|
|
332 |
return True
|
|
333 |
else:
|
|
334 |
return False
|
|
335 |
|
|
336 |
@property
|
|
337 |
def compress(self):
|
|
338 |
if hasattr(self._generator,'compress') and self._generator.compress.lower() == 'true':
|
|
339 |
return True
|
|
340 |
else:
|
|
341 |
return False
|
|
342 |
|
|
343 |
class MifconvCommand(Command):
|
|
344 |
def __init__(self,generator):
|
|
345 |
super(MifconvCommand, self).__init__(generator)
|
|
346 |
|
|
347 |
def execute(self):
|
|
348 |
"""
|
|
349 |
Execute the command in the current working directory
|
|
350 |
"""
|
|
351 |
input_files = self._get_filtered_input_files()
|
|
352 |
if len(input_files) == 0: return 0
|
|
353 |
self.create_workdir(input_files)
|
|
354 |
|
|
355 |
runenv = None
|
|
356 |
runshell = True
|
|
357 |
if os.path.dirname(self.tool):
|
|
358 |
runenv = {}
|
|
359 |
runenv['path'] = os.path.dirname(self.tool)
|
|
360 |
runshell = True
|
|
361 |
if not os.path.exists(os.path.dirname(self.generator.path)):
|
|
362 |
os.makedirs(os.path.dirname(self.generator.path))
|
|
363 |
|
|
364 |
command = self.get_command(input_files)
|
|
365 |
p = subprocess.Popen(command,
|
|
366 |
stdout=subprocess.PIPE,
|
|
367 |
stderr=subprocess.PIPE,
|
|
368 |
env=runenv,
|
|
369 |
shell=runshell)
|
|
370 |
|
|
371 |
# Wait for the process to return
|
|
372 |
out, err = [ e.splitlines() for e in p.communicate() ]
|
|
373 |
for outl in out:
|
|
374 |
if outl not in err:
|
|
375 |
logging.getLogger('cone.mifconv').info(outl)
|
|
376 |
for outl in err:
|
|
377 |
logging.getLogger('cone.mifconv').error(outl)
|
|
378 |
if p.returncode != 0:
|
|
379 |
logging.getLogger('cone.mifconv').error("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
|
|
380 |
else:
|
|
381 |
logging.getLogger('cone.mifconv').info("Command returned with returncode %s: %s" % (p.returncode, ' '.join(command)))
|
|
382 |
if p.returncode == 0:
|
3
|
383 |
self.clean_workdir()
|
0
|
384 |
return p.returncode
|
|
385 |
|
|
386 |
def get_command(self, input_files):
|
|
387 |
command = [self.tool]
|
|
388 |
|
|
389 |
""" Add output file """
|
|
390 |
command.append(os.path.normpath(self.generator.path))
|
|
391 |
|
3
|
392 |
""" Add extraparams """
|
|
393 |
if hasattr(self._generator,'extraparams'):
|
|
394 |
command.append(self.extraparams)
|
|
395 |
|
0
|
396 |
""" Add temp_path """
|
|
397 |
command.append("/t%s" % self.temppath)
|
|
398 |
|
|
399 |
# Add tool directory if given
|
|
400 |
if hasattr(self._generator,'tooldir'):
|
|
401 |
command.append('/S%s' % os.path.abspath(self.generator.tooldir))
|
|
402 |
|
|
403 |
""" Get input files """
|
|
404 |
for inputfile in input_files:
|
|
405 |
depth = 'c8'
|
|
406 |
if inputfile.depth:
|
|
407 |
depth = inputfile.depth
|
|
408 |
command.append('/%s' % depth)
|
|
409 |
command.append( '%s' % self.workfilename(inputfile.filename))
|
|
410 |
return command
|
|
411 |
|
|
412 |
@property
|
|
413 |
def tool(self):
|
|
414 |
if hasattr(self._generator,'tool'):
|
|
415 |
return os.path.abspath(self._generator.tool)
|
|
416 |
elif hasattr(self._generator, 'tooldir'):
|
|
417 |
return os.path.abspath(os.path.join(self._generator.tooldir, 'mifconv'))
|
|
418 |
else:
|
|
419 |
return 'mifconv'
|
|
420 |
|
|
421 |
@property
|
|
422 |
def temppath(self):
|
|
423 |
if hasattr(self._generator,'temp'):
|
|
424 |
return os.path.abspath(self._generator.temp)
|
|
425 |
else:
|
|
426 |
return self.workdir
|
|
427 |
|
|
428 |
class CopyCommand(object):
|
|
429 |
def __init__(self,generator):
|
|
430 |
self._generator = generator
|
|
431 |
|
|
432 |
def execute(self):
|
|
433 |
pass
|
|
434 |
|
|
435 |
@property
|
|
436 |
def tool(self):
|
|
437 |
return 'copy'
|
|
438 |
|
|
439 |
class InputFile(object):
|
|
440 |
def __init__(self,path,**kwargs):
|
|
441 |
self.configuration = None
|
|
442 |
self._depth = None
|
|
443 |
for arg in kwargs.keys():
|
|
444 |
if arg == 'depth':
|
|
445 |
# Special handling for depth ('depth' is a property that
|
|
446 |
# expands refs using '_depth' as the base)
|
|
447 |
self._depth = kwargs[arg]
|
|
448 |
else:
|
|
449 |
setattr(self, arg, kwargs[arg])
|
|
450 |
self._path= path
|
|
451 |
|
|
452 |
def get_input(self):
|
|
453 |
"""
|
|
454 |
Get the confml ref value from configuration if the outputpath is actually a ref
|
|
455 |
"""
|
|
456 |
if self._path and self.configuration is not None:
|
|
457 |
dview = self.configuration.get_default_view()
|
|
458 |
def expand(ref, index):
|
|
459 |
value = dview.get_feature(ref).get_original_value()
|
|
460 |
if value is None: return ''
|
|
461 |
else: return value
|
|
462 |
return utils.expand_delimited_tokens(self._path, expand)
|
|
463 |
else:
|
|
464 |
return self._path
|
|
465 |
|
|
466 |
def set_input(self, value): self._path = value
|
|
467 |
|
|
468 |
def del_input(self): self._path = None
|
|
469 |
|
|
470 |
@property
|
|
471 |
def type(self):
|
|
472 |
return 'file'
|
|
473 |
|
|
474 |
@property
|
|
475 |
def depth(self):
|
|
476 |
if self._depth and self.configuration:
|
|
477 |
dview = self.configuration.get_default_view()
|
|
478 |
return utils.expand_refs_by_default_view(self._depth, dview)
|
|
479 |
else:
|
|
480 |
return self._depth or ''
|
|
481 |
|
|
482 |
@property
|
|
483 |
def files(self):
|
|
484 |
"""
|
|
485 |
Return a list of file names
|
|
486 |
"""
|
|
487 |
return [self]
|
|
488 |
|
|
489 |
@property
|
|
490 |
def filename(self):
|
|
491 |
"""
|
|
492 |
Return a the path to the layer specific filename
|
|
493 |
"""
|
|
494 |
if self.configuration and self.path:
|
|
495 |
content = self.configuration.layered_content().flatten()
|
|
496 |
inputpath = self.path
|
|
497 |
return content.get(inputpath)
|
|
498 |
else:
|
|
499 |
return self.path
|
|
500 |
|
|
501 |
path = property(get_input, set_input, del_input, "The input 'path'.")
|
|
502 |
|
|
503 |
def is_valid(self):
|
|
504 |
"""
|
|
505 |
Return whether the input file is valid (not empty
|
|
506 |
and exists in project content).
|
|
507 |
"""
|
|
508 |
return not self.is_empty() and self.filename
|
|
509 |
|
|
510 |
def is_empty(self):
|
|
511 |
"""
|
|
512 |
Return whether the input file is empty.
|
|
513 |
"""
|
|
514 |
return self.path in ('', None)
|
|
515 |
|
|
516 |
def is_optional(self):
|
|
517 |
"""
|
|
518 |
Return whether the input file is optional.
|
|
519 |
"""
|
|
520 |
return hasattr(self, 'optional') \
|
|
521 |
and self.optional.lower() in ('1', 't', 'true', 'yes', 'y')
|
|
522 |
|
|
523 |
def get_refs(self):
|
|
524 |
return utils.extract_delimited_tokens(self._path)
|
|
525 |
|
|
526 |
def __repr__(self):
|
|
527 |
return "InputFile(path=%r, optional=%r)" % (self._path, self.is_optional())
|
|
528 |
|
|
529 |
class InputDir(InputFile):
|
|
530 |
def __init__(self,path,**kwargs):
|
|
531 |
super(InputDir,self).__init__(path,**kwargs)
|
|
532 |
self._files = []
|
|
533 |
self._include = None
|
|
534 |
self._exclude = None
|
|
535 |
|
|
536 |
def get_include(self):
|
|
537 |
return self._include.get('pattern',[])
|
|
538 |
|
|
539 |
def set_include(self, value):
|
|
540 |
self._include = value
|
|
541 |
|
|
542 |
def del_include(self):
|
|
543 |
self._include = None
|
|
544 |
|
|
545 |
def get_exclude(self):
|
|
546 |
return self._exclude.get('pattern',[])
|
|
547 |
|
|
548 |
def set_exclude(self, value):
|
|
549 |
self._exclude = value
|
|
550 |
|
|
551 |
def del_exclude(self):
|
|
552 |
self._exclude = None
|
|
553 |
|
|
554 |
@property
|
|
555 |
def type(self):
|
|
556 |
return 'dir'
|
|
557 |
|
|
558 |
@property
|
|
559 |
def files(self):
|
|
560 |
"""
|
|
561 |
Return a list of file names under this directory definition
|
|
562 |
"""
|
|
563 |
if self.configuration:
|
|
564 |
inputlist = []
|
|
565 |
content = self.configuration.layered_content().flatten()
|
|
566 |
contentfiles = content.keys()
|
|
567 |
|
|
568 |
folderfiles = utils.resourceref.filter_resources(contentfiles, "^%s" % self.path)
|
|
569 |
for inputfilter in self.include:
|
|
570 |
folderfiles = utils.resourceref.filter_resources(folderfiles, inputfilter)
|
|
571 |
for excludefilter in self.exclude:
|
|
572 |
folderfiles = utils.resourceref.neg_filter_resources(folderfiles, excludefilter)
|
|
573 |
folderfiles.sort()
|
|
574 |
for filename in folderfiles:
|
|
575 |
inputlist.append(InputFile(filename, **self.__dict__))
|
|
576 |
return inputlist
|
|
577 |
else:
|
|
578 |
return []
|
|
579 |
|
|
580 |
include = property(get_include, set_include, del_include)
|
|
581 |
exclude = property(get_exclude, set_exclude, del_exclude)
|
|
582 |
|
|
583 |
|
|
584 |
|
|
585 |
class ConfmlRefs(object):
|
|
586 |
|
|
587 |
ref_pattern = re.compile('^\$\{(.*)\}$')
|
|
588 |
|
|
589 |
@classmethod
|
|
590 |
def is_confml_ref(cls, variableref):
|
|
591 |
"""
|
|
592 |
|
|
593 |
Returns true if the given variable ref is a confml reference
|
|
594 |
"""
|
|
595 |
return cls.ref_pattern.match(variableref) != None
|
|
596 |
|
|
597 |
@classmethod
|
|
598 |
def get_confml_ref(cls, variableref):
|
|
599 |
"""
|
|
600 |
|
|
601 |
Returns true if the given variable ref is a confml reference
|
|
602 |
"""
|
|
603 |
matchref = cls.ref_pattern.match(variableref)
|
|
604 |
if matchref:
|
|
605 |
return matchref.group(1)
|
|
606 |
else:
|
|
607 |
return None
|