--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/action/configroot2flat.py Tue Aug 10 14:29:28 2010 +0300
@@ -0,0 +1,169 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+#!/usr/bin/env python
+##
+# @author Teemu Rytkonen
+
+import os, re, fnmatch, logging
+from cone.public import api, utils, exceptions
+from cone.confml import model as confml_model
+
+logger = logging.getLogger('cone')
+
+def get_config_list_from_project(project, configs, config_wildcards, config_regexes):
+ """
+ Return a list of configuration root names based on the given parameters.
+ @param project: The project from which to get the configuration list.
+ @param configs: List of configuration names to add. All of these should exist
+ in the project, or a ConfigurationNotFoundError is raised.
+ @param config_wildcards: List of wildcard patterns for including configurations.
+ @param config_regexs: List of regular expression patters for including configurations.
+ @return: A distinct list of configuration names matched by the given parameters. The
+ list contains matched configurations in the following order:
+ 1. Configurations specified in configs
+ 2. Configurations matched by wildcard patterns
+ 3. Configurations matched by regular expressions
+ If a configuration is matched by more than one of these, the first match determines
+ its placement in the list.
+ @raise Exception: A configuration specified in configs is not
+ actually found in the project.
+ """
+ config_list = []
+
+ # Handle configurations specified with --configuration first
+ for config in configs:
+ if not project.get_storage().is_resource(utils.resourceref.norm(config)):
+ raise Exception("No such configuration: %s" % config)
+ if config not in config_list:
+ config_list.append(config)
+
+ # Then handle wildcards
+ #print "wilds %s" % config_wildcards
+ if config_wildcards:
+ for path in project.get_storage().list_resources('.', recurse=True):
+ for wildcard in config_wildcards:
+ if fnmatch.fnmatch(path, wildcard):
+ if path not in config_list:
+ config_list.append(path)
+
+ # Lastly handle regexes
+ #print "regexes %s" % config_regexes
+ if config_regexes:
+ for path in project.get_storage().list_resources('.', recurse=True):
+ for pattern in config_regexes:
+ if re.search(pattern, path) is not None:
+ if path not in config_list:
+ config_list.append(path)
+
+ return config_list
+
+def get_flat_includes(config):
+ """
+ get a flat list of configuration in which each include of configuration root is expanded.
+ The mechanism assumes all includes that end with /root.confml to be layer includes that
+ are layers that are not expanded
+ @param config: the configuration object to process.
+ """
+ includes = []
+ for include in config.list_configurations():
+ if include.endswith('/root.confml'):
+ includes.append(utils.resourceref.remove_begin_slash(include))
+ else:
+ subconfig = config.get_configuration(include)
+ includes += get_flat_includes(subconfig)
+ return includes
+
+def get_nested_meta(config, recursion_depth=-1):
+ """
+ Get the nested meta data for the given configuration constructed from metadata of all sub configuration meta.
+ @param config: the configuration object to fetch the metadata for
+ @param recursion_depth: the depth of the recursive nested metadata calls. default value -1 will go through
+ all configurations.
+ @return: a ConfmlMeta object
+ """
+
+ meta = confml_model.ConfmlMeta()
+ if recursion_depth != 0:
+ # First recurse through all subconfigurations to get their meta
+ for subconfig_name in config.list_configurations():
+ subconfig = config.get_configuration(subconfig_name)
+ submeta = get_nested_meta(subconfig, recursion_depth-1)
+
+ meta.update( submeta )
+
+ # lastly, update the meta data of the root configuration
+ if config.meta:
+ meta.update(config.meta)
+ return meta
+
+
+class Configroot2FlatFailed(exceptions.ConeException):
+ pass
+
+class ConeConfigroot2FlatAction(object):
+ def __init__(self, **kwargs):
+ self.project = kwargs.get('project')
+ self.configs = kwargs.get('configs')
+ self.config_wildcards = kwargs.get('config_wildcards')
+ self.config_regexes = kwargs.get('config_regexes')
+ self._project = None
+
+ def run(self):
+ self._project = api.Project(api.Storage.open(self.project, 'a'))
+ prj = self._project
+
+ configs = []
+ if self.configs or self.config_wildcards or self.config_regexes:
+ configs = get_config_list_from_project(
+ project = prj,
+ configs = self.configs,
+ config_wildcards = self.config_wildcards,
+ config_regexes = self.config_regexes)
+
+ if not configs:
+ raise Configroot2FlatFailed("At least one configuration must be given!")
+
+ print "Processing configurations %s" % configs
+ for source_config in configs:
+ target_config= os.path.basename(source_config)
+ if source_config == target_config:
+ print "Cannot flatten configuration because the source path is the same as target!"
+ config = prj.get_configuration(source_config)
+
+ print "opened %s for flattening" % source_config
+
+ print "Creating a new configuration root '%s' for flattening" % target_config
+ tconf = prj.create_configuration(target_config, True)
+ # add the includes
+ for config_include in get_flat_includes(config):
+ tconf.include_configuration(config_include)
+ # add the metadata with hardcoded recursion depth count
+ newmeta = get_nested_meta(config, 2)
+ tconf.meta = newmeta
+ tconf.name = config.name
+ tconf.save()
+
+ return True
+
+ def save(self):
+ if self._project: self._project.save()
+
+ def close(self):
+ if self._project: self._project.close()
+
+
+def get_class():
+ return ConeConfigroot2FlatAction