diff -r 87cfa131b535 -r e7e0ae78773e configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py --- a/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py Fri Mar 12 08:30:17 2010 +0200 +++ b/configurationengine/source/plugins/symbian/ConeGenconfmlPlugin/genconfmlplugin/genconfmlplugin.py Tue Aug 10 14:29:28 2010 +0300 @@ -26,6 +26,7 @@ import xslttransformer import codecs import tempfile +import pkg_resources import tempfile try: @@ -39,7 +40,6 @@ except ImportError: from xml.etree import ElementTree -import __init__ from cone.public import exceptions,plugin,utils,api from cone.confml import persistentconfml @@ -52,7 +52,7 @@ IMPL_TYPE_ID = "gcfml" - def __init__(self,ref,configuration, output='output', linesep=os.linesep, reader=None): + def __init__(self,ref,configuration, output='', linesep=os.linesep, reader=None): """ Overloading the default constructor """ @@ -63,7 +63,7 @@ self.xslt_temp_file_name = os.path.join(tempfile.gettempdir(), "genconfml_temp_%i.xslt" % os.getpid()) self.set_output_root(output) self.linesep = linesep - self._flatconfig = None + self.flatconfig = None self.temp_confml_file = os.path.join(tempfile.gettempdir(),'temp_flatted_%i.confml' % os.getpid()) self.reader = reader @@ -71,19 +71,28 @@ """ Generate the given implementation. """ + self.context = context self.create_output() return def get_refs(self): + """ + Get the list of references used inside this gcfml object. + """ result = [] + refs = [] for ref in self.reader.settings: # Process the reference, so that it will work with has_ref(). # E.g. 'MyFeature/MySetting' -> 'MyFeature.MySetting' # 'MyFeature/* -> 'MyFeature' ref = ref.replace('/', '.') - if ref.endswith('.*'): - ref = ref[:-2] - result.append(ref) + refs.append(ref) + + # Traverse through actual features in the default view, to get a full list + # of refs in case of wildcard usage + dview = self.configuration.get_default_view() + for fea in dview.get_features(refs): + result.append(fea.fqr) return result def list_output_files(self): @@ -113,7 +122,7 @@ """ Generate all output """ resource = self.configuration.get_resource(self.ref) write_element_enc(self.reader.stylesheet_elem, self.xslt_temp_file_name, self.reader.stylesheet_output_enc) - gen = Generator() + gen = Generator(self) target = self.reader.target if target == None: target = "" @@ -126,10 +135,12 @@ self.logger.info('Generating %s' % output_file) - flatted_conf_as_element = persistentconfml.ConfmlWriter().dumps(self.flatconfig) + flatted_conf_as_element = persistentconfml.ConfmlWriter().dumps(self.get_flatconfig()) postprocessed_element = self.post_process_flattening(flatted_conf_as_element) write_element_enc(postprocessed_element, self.temp_confml_file, self.reader.stylesheet_output_enc) - gen.generate(self.configuration, resource, output_file, self.xslt_temp_file_name, self.reader.settings, self.reader.stylesheet_output_enc) + gen.generate(self.context, resource, output_file, self.xslt_temp_file_name, self.reader.settings, self.reader.stylesheet_output_enc, + line_ending_style = self.reader.line_ending_style) + def post_process_flattening(self, element): """ @@ -144,21 +155,20 @@ new_doc = "" + ElementTree.tostring(data_element) + "" return ElementTree.fromstring(new_doc) - @property - def flatconfig(self): - """ - Create a flat configuration from the current configuration with the given setting refs. - Take the last configuration element, which will contain the data elements - """ - if not self._flatconfig: - try: - cf = confflattener.ConfigurationFlattener() - self._flatconfig = api.Configuration() - cf.flat(self.configuration, self.reader.settings, self._flatconfig) - except (exceptions.ConeException, TypeError, Exception), e: - utils.log_exception(self.logger, 'Failed to flat configuration with settings %s. Exception: %s' % (self.reader.settings, e)) - raise exceptions.ConeException('Failed to flat configuration. Exception: %s' % e) - return self._flatconfig + def get_flatconfig(self): + """ + Create a flat configuration from the current configuration with the given setting refs. + Take the last configuration element, which will contain the data elements + """ + if not self.flatconfig: + try: + cf = confflattener.ConfigurationFlattener() + self.flatconfig = api.Configuration() + cf.flat(self.configuration, self.reader.settings, self.flatconfig) + except (exceptions.ConeException, TypeError, Exception), e: + utils.log_exception(self.logger, 'Failed to flat configuration with settings %s. Exception: %s' % (self.reader.settings, e)) + raise exceptions.ConeException('Failed to flat configuration. Exception: %s' % e) + return self.flatconfig def write_element(element, output, linesep=os.linesep): @@ -221,7 +231,7 @@ try: tempfile.write(ElementTree.tostring(element)) except Exception, e: - raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e)) + raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (tempfile, e)) else: raise exceptions.ConeException('Cannot write element to file, because None element passed or not Element passed.') @@ -230,6 +240,8 @@ Parses a single gcfml file """ NAMESPACE = 'http://www.s60.com/xml/genconfml/1' + NAMESPACE_ID = 'gcfml' + ROOT_ELEMENT_NAME = 'file' IGNORED_NAMESPACES = ['http://www.w3.org/1999/XSL/Transform', 'http://www.w3.org/2001/xinclude'] FILE_EXTENSIONS = ['gcfml'] @@ -251,17 +263,27 @@ reader = GenconfmlImplReader() reader.from_etree(etree) return GenconfmlImpl(resource_ref, configuration, reader=reader) - + + @classmethod + def get_schema_data(cls): + return pkg_resources.resource_string('genconfmlplugin', 'xsd/gcfml.xsd') + def from_etree(self, etree): self.stylesheet = self.parse_stylesheet(etree) self.settings = self.parse_settings(etree) - self.name = self.parse_name(etree) - self.subdir = self.parse_subdir(etree) - self.target = self.parse_target(etree) + self.target = etree.get('target', '') + self.name = etree.get('name', '') + self.subdir = etree.get('subdir', '') + self.line_ending_style = etree.get('lineEndingStyle') self.stylesheet_elem = self.parse_stylesheet_elem(etree) self.stylesheet_output_enc = self.parse_stylesheet_output_enc(etree) self.nss = self.parse_stylesheet_nss(etree) + if self.line_ending_style not in (None, 'CRLF', 'LF'): + raise exceptions.ImplmlParseError( + "Invalid line ending style '%s' (should be omitted or one " + "of ['CRLF', 'LF'])" % self.line_ending_style) + return def parse_target(self, etree): @@ -271,8 +293,8 @@ target = "" for elem in etree.getiterator("{%s}file" % self.namespaces[2]): - if elem != None: - target = elem.get('target') + if elem != None: + target = elem.get('target') return target @@ -283,8 +305,8 @@ name = "" for elem in etree.getiterator("{%s}file" % self.namespaces[2]): - if elem != None: - name = elem.get('name') + if elem != None: + name = elem.get('name') return name @@ -295,8 +317,8 @@ subdir = "" for elem in etree.getiterator("{%s}file" % self.namespaces[2]): - if elem != None: - subdir = elem.get('subdir') + if elem != None: + subdir = elem.get('subdir') if subdir == None: subdir = "" @@ -350,21 +372,21 @@ settings = [] for elem in etree.getiterator("{%s}file" % self.namespaces[2]): - if elem != None: - setting_elems = elem.findall("{%s}setting" % self.namespaces[2]) - for setting_elem in setting_elems: - if setting_elem != None: - settings.append(setting_elem.get('ref')) - + if elem != None: + setting_elems = elem.findall("{%s}setting" % self.namespaces[2]) + for setting_elem in setting_elems: + if setting_elem != None: + settings.append(setting_elem.get('ref')) return settings class Generator(object): """ Genconfml generator """ - def __init__(self): + def __init__(self, implml): self.temp_confml_file = os.path.join(tempfile.gettempdir(),'temp_flatted_%i.confml' % os.getpid()) - pass + self.context = None + self.implml = implml def post_process_flattening(self, element): """ @@ -380,17 +402,25 @@ return ElementTree.fromstring(new_doc) - def generate(self, configuration, input, output, xslt, settings, enc=sys.getdefaultencoding()): + def generate(self, context, input, output, xslt, settings, enc=sys.getdefaultencoding(), + line_ending_style=None): """ Generates output """ + self.context = context self.logger = logging.getLogger('cone.gcfml{%s}' % input.path) + if line_ending_style == 'LF': + linesep = '\n' + else: + linesep = '\r\n' try: tf = xslttransformer.XsltTransformer() - tf.transform_lxml(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), output, enc) - #tf.transform_4s(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), output, enc) + result = tf.transform_lxml(os.path.abspath(self.temp_confml_file), os.path.abspath(xslt), enc, linesep) + if not self.filter_file_writing(result): + self.write_string_to_file(result, output, enc) + except (exceptions.ConeException, TypeError, Exception), e: logging.getLogger('cone.gcfml').warning('Failed to do XSLT tranformation. Exception: %s' % e) raise exceptions.ConeException('Failed to do XSLT tranformation. Exception: %s' % e) @@ -399,3 +429,32 @@ if not logging.getLogger('cone').getEffectiveLevel() != 10: os.remove(os.path.abspath(self.temp_confml_file)) os.remove(os.path.abspath(xslt)) + + def filter_file_writing(self, string): + """ + Returns True if writing result file should be ignored. + """ + string = string.rstrip('\n\r') + if string == '' or string == '' or \ + string == '': + return True + + return False + + def write_string_to_file(self, string, output, enc): + """ + Writes string to file + """ + try: + + #fl = codecs.open(outfile, 'w', enc) + fl = self.context.create_file(output, + implementation=self.implml, + mode='w', + encoding=enc) + fl.write(string) + fl.close() + + except Exception, e: + logging.getLogger('cone.gcfml').error('Cannot write Element to file (%s). Exception: %s' % (output, e)) + raise exceptions.ConeException('Cannot write Element to file (%s). Exception: %s' % (output, e))