--- 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 = "<?xml version=\"1.0\"?><configuration>" + ElementTree.tostring(data_element) + "</configuration>"
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 == '<?xml version="1.0" encoding="UTF-16"?>' or \
+ string == '<?xml version="1.0" encoding="UTF-8"?>':
+ 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))