configurationengine/source/plugins/symbian/ConeProjectConverterPlugin/projectconvertplugin/convertproject.py
changeset 3 e7e0ae78773e
parent 0 2e8eeb919028
child 4 0951727b8815
equal deleted inserted replaced
2:87cfa131b535 3:e7e0ae78773e
    22 import sys
    22 import sys
    23 import logging
    23 import logging
    24 import xml.parsers.expat
    24 import xml.parsers.expat
    25 import shutil
    25 import shutil
    26 import fnmatch
    26 import fnmatch
       
    27 import pkg_resources
       
    28 import types
    27 
    29 
    28 try:
    30 try:
    29     from cElementTree import ElementTree
    31     from cElementTree import ElementTree
    30 except ImportError:
    32 except ImportError:
    31     try:    
    33     try:    
    69         """
    71         """
    70         Generate the given implementation.
    72         Generate the given implementation.
    71         """
    73         """
    72         
    74         
    73         #Generating content
    75         #Generating content
    74         fullOutputPath = self.output
    76         fullOutputPath = os.path.join(context.output, self.output)
    75         if self.project_data.has_key("path"): 
    77         if self.project_data.has_key("path"): 
    76             targetPath = utils.resourceref.norm(self.project_data["path"])
    78             targetPath = utils.resourceref.norm(self.project_data["path"])
    77             if targetPath and targetPath != "":
    79             if targetPath and targetPath != "":
    78                 fullOutputPath = os.path.join(fullOutputPath, targetPath)             
    80                 fullOutputPath = os.path.join(context.output, fullOutputPath, targetPath)             
    79         
    81         
    80         fs = filestorage.FileStorage(fullOutputPath, "w")
    82         fs = filestorage.FileStorage(fullOutputPath, "w")
    81         newProject = api.Project(fs)        
    83         newProject = api.Project(fs)        
    82         for layer in self.layers:
    84         for layer in self.layers:
    83             layer.generate(newProject, self.configuration.get_storage().get_path())        
    85             layer.generate(newProject, self.configuration.get_storage().get_path())        
   114 class ConvertProjectLayer(object):
   116 class ConvertProjectLayer(object):
   115     """
   117     """
   116     Object presenting layer in convertprojectml file.
   118     Object presenting layer in convertprojectml file.
   117     """
   119     """
   118     
   120     
   119     def __init__(self, path):
   121     def __init__(self, path, configuration):
   120         if path != None:
   122         if path != None:
   121             self.path = path
   123             self.path = path
   122         else:
   124         else:
   123             self.path = ""
   125             self.path = ""
   124         self.folders = []
   126         self.folders = []
   125         self.files = []        
   127         self.files = []
       
   128         self.source_configuration = configuration        
   126 
   129 
   127     def __str__(self):
   130     def __str__(self):
   128         retStr = ""
   131         retStr = ""
   129         retStr += "\nPath: %s\n" % self.path
   132         retStr += "\nPath: %s\n" % self.path
   130         retStr +="Folders:\n"        
   133         retStr +="Folders:\n"        
   157 
   160 
   158     def addFile(self, file):
   161     def addFile(self, file):
   159         self.files.append(file)
   162         self.files.append(file)
   160 
   163 
   161     def getProjectPath(self):
   164     def getProjectPath(self):
   162         return self.path
   165         return self.path    
   163 
   166 
       
   167     def solve_ref(self, inputdata):
       
   168         """
       
   169         Internal function to solve whether input is ref or just normal input string. 
       
   170         For refs actual ConfML value is resolved and returned. Non-refs are returned 
       
   171         as such.
       
   172         """                        
       
   173         dview = self.source_configuration.get_default_view()
       
   174         if inputdata and isinstance(inputdata, types.StringType):            
       
   175             return utils.expand_refs_by_default_view(inputdata, dview)
       
   176         elif inputdata and isinstance(inputdata, types.DictType):
       
   177             retDict = {}
       
   178             for key in inputdata:
       
   179                 retDict[self.solve_ref(key)] = self.solve_ref(inputdata[key])            
       
   180             return retDict
       
   181         else:
       
   182             return inputdata
   164                 
   183                 
   165 class ConvertProjectFolder(object):
   184 class ConvertProjectFolder(object):
   166     """
   185     """
   167     Object presenting folder in convertprojectml file.
   186     Object presenting folder in convertprojectml file.
   168     """
   187     """
   196     def addFilter(self, filter):
   215     def addFilter(self, filter):
   197         self.filters.append(filter)
   216         self.filters.append(filter)
   198 
   217 
   199     def getProjectPath(self):
   218     def getProjectPath(self):
   200         return os.path.join(self.parent.getProjectPath(), self.path)
   219         return os.path.join(self.parent.getProjectPath(), self.path)
   201     
   220 
       
   221     def solve_ref(self, inputdata):
       
   222         return self.parent.solve_ref(inputdata)
       
   223 
       
   224             
   202 class ConvertProjectFile(object):
   225 class ConvertProjectFile(object):
   203     """
   226     """
   204     Object presenting file in convertprojectml file.
   227     Object presenting file in convertprojectml file.
   205     """
   228     """
   206         
   229         
   207     def __init__(self, path, type, parent=None):
   230     def __init__(self, path, type, parent=None):
   208         if path != None:
   231         if path != None:
   209             self.path = path
   232             self.path = path
   210         else:
   233         else:
   211             self.path = ""
   234             self.path = ""
   212         if type != None:
   235         if type != None and type != "none":
   213             self.type = type
   236             self.type = type
   214         else:
   237         else:
   215             self.type = ""        
   238             self.type = ""        
   216             
   239             
   217         self.filters = []
   240         self.filters = []
   218         self.parent = parent
   241         self.parent = parent
   219         self.meta = []
   242         self.meta = []
   220         self.desc = ""
   243         self.desc = ""
       
   244         self.configuration_name = ""
   221         
   245         
   222     def __str__(self):
   246     def __str__(self):
   223         retStr = ""
   247         retStr = ""
   224         retStr += "\tPath: %s\n" % self.path
   248         retStr += "\tPath: %s\n" % self.path
   225         retStr += "\tType: %s\n" % self.type
   249         retStr += "\tType: %s\n" % self.type
   230 
   254 
   231     def generate(self, project, old_structure_root):
   255     def generate(self, project, old_structure_root):
   232         for filter in self.filters:            
   256         for filter in self.filters:            
   233             filter.generate(project, old_structure_root, self.type)                        
   257             filter.generate(project, old_structure_root, self.type)                        
   234 
   258 
   235         if self.type == "configuration_root":
   259         if self.type:
   236             #Adding metadata                
   260             config = project.get_configuration(utils.resourceref.norm(self.getProjectPath()))
   237             config = project.get_configuration(utils.resourceref.norm(self.path))
       
   238             if self.meta:                
   261             if self.meta:                
   239                 if not config.meta:
   262                 if not config.meta:
   240                     config.meta = []
   263                     config.meta = []
   241                 for meta in self.meta:
   264                 for meta in self.meta:
   242                     config.meta.add(meta[0], meta[1], meta[2], meta[3])                        
   265                     config.meta.set_property_by_tag(self.solve_ref(meta[0]), \
       
   266                                                     self.solve_ref(meta[1]), \
       
   267                                                     self.solve_ref(meta[2]), \
       
   268                                                     self.solve_ref(meta[3]))                   
   243             if self.desc:
   269             if self.desc:
   244                 config.desc = self.desc
   270                 config.desc = self.desc
   245                 
   271                 
   246             config.save()                    
   272             if self.configuration_name:
       
   273                 config.set_name(self.configuration_name)
       
   274             config.save()
       
   275                     
   247         return
   276         return
   248 
   277 
   249     def addFilter(self, filter):
   278     def addFilter(self, filter):
   250         self.filters.append(filter)
   279         self.filters.append(filter)
   251 
   280 
   252     def addMeta(self, meta):
   281     def addMeta(self, meta):
   253         self.meta = meta
   282         self.meta = meta
   254 
   283 
   255     def addDescription(self, desc):
   284     def addDescription(self, desc):
   256         self.desc = desc
   285         self.desc = desc
       
   286     
       
   287     def addConfigurationName(self, configuration_name):
       
   288         self.configuration_name = configuration_name
   257 
   289 
   258     def getProjectPath(self):
   290     def getProjectPath(self):
   259         return os.path.join(self.parent.getProjectPath(), self.path)
   291         if self.type == "configuration_root":
       
   292             return self.path
       
   293         else:
       
   294             return os.path.join(self.parent.getProjectPath(), self.path)
       
   295 
       
   296     def solve_ref(self, inputdata):
       
   297         return self.parent.solve_ref(inputdata)
   260 
   298 
   261 class ConvertProjectFilter(object):
   299 class ConvertProjectFilter(object):
   262     """
   300     """
   263     Object presenting filter in convertprojectml file.
   301     Object presenting filter in convertprojectml file.
   264     """
   302     """
   272         else:
   310         else:
   273             self.remove_includes = "false"
   311             self.remove_includes = "false"
   274         if recursive:
   312         if recursive:
   275             self.recursive = recursive
   313             self.recursive = recursive
   276         else:
   314         else:
   277              self.recursive = "false"
   315             self.recursive = "false"
   278 
   316 
   279     def __str__(self):
   317     def __str__(self):
   280         retStr = ""
   318         retStr = ""
   281         retStr += "\t\tAction: %s\n" % self.action
   319         retStr += "\t\tAction: %s\n" % self.action
   282         retStr += "\t\tData: %s\n" % self.data
   320         retStr += "\t\tData: %s\n" % self.data
   365             return os.path.join(project.get_storage().get_path(), self.getProjectPath())
   403             return os.path.join(project.get_storage().get_path(), self.getProjectPath())
   366         else:            
   404         else:            
   367             retPath = os.path.join(project.get_storage().get_path(), self.getProjectPath())            
   405             retPath = os.path.join(project.get_storage().get_path(), self.getProjectPath())            
   368             startFound = 0
   406             startFound = 0
   369             
   407             
   370             for item in os.path.normpath(filepath).split("\\"):
   408             parts = filter(lambda p: p != '',
       
   409                            os.path.normpath(filepath).replace('\\', '/').split('/'))
       
   410             for item in parts:
   371                 if self.data.find(item) != -1:
   411                 if self.data.find(item) != -1:
   372                     startFound = 1
   412                     startFound = 1
   373                 if startFound and self.data.find(item) == -1:
   413                 if startFound and self.data.find(item) == -1:
   374                     retPath = os.path.join(retPath, item)                
   414                     retPath = os.path.join(retPath, item)                
   375             return os.path.split(retPath)[0]
   415             return os.path.split(retPath)[0]
   400             #Need to handle wildcard part
   440             #Need to handle wildcard part
   401             fullSearchPath = os.path.join(project.get_storage().get_path(), self.getProjectPath(), pathPart)
   441             fullSearchPath = os.path.join(project.get_storage().get_path(), self.getProjectPath(), pathPart)
   402             filesToProcess = self.getFilesByWildcard(fullSearchPath, wildCardPart, project)
   442             filesToProcess = self.getFilesByWildcard(fullSearchPath, wildCardPart, project)
   403         
   443         
   404         #Creating rootfile.        
   444         #Creating rootfile.        
   405         rootFilePath = os.path.join(self.getProjectPath(), self.parent.path)        
   445         rootFilePath = os.path.join(self.getProjectPath(), self.parent.path)
   406         config = project.create_configuration(utils.resourceref.norm(rootFilePath))
   446         if project.is_configuration(utils.resourceref.norm(rootFilePath)):
       
   447             config = project.get_configuration(utils.resourceref.norm(rootFilePath))
       
   448         else:
       
   449             config = project.create_configuration(utils.resourceref.norm(rootFilePath))
   407         
   450         
   408         #Adding defined includes.
   451         #Adding defined includes.
   409         for f in filesToProcess:
   452         for f in filesToProcess:
   410             source = f["source"]
   453             source = f["source"]
   411             #Getting path in configuration project and adding it as include.
   454             #Getting path in configuration project and adding it as include.
   433     def handleConfigurationRoot(self, project):
   476     def handleConfigurationRoot(self, project):
   434         """
   477         """
   435         """        
   478         """        
   436         #Always in the root of the project
   479         #Always in the root of the project
   437         configname = utils.resourceref.norm(self.parent.path)
   480         configname = utils.resourceref.norm(self.parent.path)
   438         if configname in project.list_configurations():
   481         if project.is_configuration(utils.resourceref.norm(self.parent.path)):
   439             config = project.get_configuration(configname)
   482             config = project.get_configuration(configname)
   440         else:
   483         else:
   441             config = project.create_configuration(utils.resourceref.norm(self.parent.path))
   484             config = project.create_configuration(utils.resourceref.norm(self.parent.path))
   442         config.include_configuration(utils.resourceref.norm(self.data))                
   485         config.include_configuration(utils.resourceref.norm(self.data))                
   443         config.save()
   486         config.save()
   467                 if self.recursive == "false" and os.path.normpath(root) != os.path.normpath(folder):
   510                 if self.recursive == "false" and os.path.normpath(root) != os.path.normpath(folder):
   468                 #No recursive search used and therefore only topmost directory is handled.
   511                 #No recursive search used and therefore only topmost directory is handled.
   469                     continue
   512                     continue
   470                 else:
   513                 else:
   471                     for f in files:
   514                     for f in files:
       
   515                         if wildcard and wildcard[0] != "*":
       
   516                             #Matches path part.
       
   517                             wildcard = "*%s" % wildcard
       
   518                         
   472                         if fnmatch.fnmatch(os.path.join(root, f), wildcard):
   519                         if fnmatch.fnmatch(os.path.join(root, f), wildcard):
   473                             source = os.path.join(root, f)
   520                             source = os.path.join(root, f)
   474                             targetDir = self.resolveTargetDir(project, source)                
   521                             targetDir = self.resolveTargetDir(project, source)                
   475                             retArray.append({"source": source, "targetDir": targetDir})
   522                             retArray.append({"source": source, "targetDir": targetDir})
   476 
   523 
   500         #Some wildcards found. Wildcards are supported only in the last segment.
   547         #Some wildcards found. Wildcards are supported only in the last segment.
   501             pathPart, wildCardPart = os.path.split(data)
   548             pathPart, wildCardPart = os.path.split(data)
   502 
   549 
   503         return pathPart, wildCardPart
   550         return pathPart, wildCardPart
   504 
   551 
   505 
   552     def solve_ref(self, inputdata):
       
   553         return self.parent.solve_ref(inputdata)   
       
   554      
   506 #=================================================================
   555 #=================================================================
   507     
   556     
   508 class ConvertProjectReader(plugin.ReaderBase):
   557 class ConvertProjectReader(plugin.ReaderBase):
   509     """
   558     """
   510     Parses a single convertprojectml  file
   559     Parses a single convertprojectml  file
   511     """ 
   560     """ 
   512     
   561     
   513     NAMESPACE = 'http://www.s60.com/xml/convertprojectml/1'
   562     NAMESPACE = 'http://www.s60.com/xml/convertprojectml/1'
       
   563     NAMESPACE_ID = 'convertprojectml'
       
   564     ROOT_ELEMENT_NAME = 'convertprojectml'
   514     FILE_EXTENSIONS = ['convertprojectml']
   565     FILE_EXTENSIONS = ['convertprojectml']
   515     
   566     
   516     def __init__(self):
   567     def __init__(self):
   517         self.desc = None
   568         self.desc = None
   518         self.output_dir = None
   569         self.output_dir = None
   522         self.layers = []
   573         self.layers = []
   523     
   574     
   524     @classmethod
   575     @classmethod
   525     def read_impl(cls, resource_ref, configuration, etree):
   576     def read_impl(cls, resource_ref, configuration, etree):
   526         reader = ConvertProjectReader()
   577         reader = ConvertProjectReader()
   527         reader.from_etree(etree, configuration.get_storage().get_path())
   578         reader.from_etree(etree, configuration, configuration.get_storage().get_path())
   528         
   579         
   529         impl = ConvertProjectImpl(resource_ref, configuration)
   580         impl = ConvertProjectImpl(resource_ref, configuration)
   530         impl.project_data   = reader.project_data
   581         impl.project_data   = reader.project_data
   531         impl.layers         = reader.layers
   582         impl.layers         = reader.layers
   532         return impl
   583         return impl
   533     
   584     
   534     def from_etree(self, etree, old_structure_root = ""):
   585     @classmethod
   535         self.project_data = self.parse_attributes(etree, "targetProject")        
   586     def get_schema_data(cls):
   536         self.layers = self.parse_layers(etree) 
   587         return pkg_resources.resource_string('projectconvertplugin', 'xsd/convertprojectml.xsd')
   537         for fe in self.parse_foreach(etree, old_structure_root):
   588     
   538             self.layers.append(fe)
   589     def from_etree(self, etree, configuration, old_structure_root = ""):
   539         
   590         self.configuration = configuration
   540         #for l in self.layers:
   591                 
   541             #print l
   592         for element in etree:
   542         return    
   593             if element.tag == "{http://www.s60.com/xml/convertprojectml/1}targetProject":
       
   594                 self.project_data = self.parse_attributes(etree, "targetProject")
       
   595             elif element.tag == "{http://www.s60.com/xml/convertprojectml/1}layer":
       
   596                 self.layers.append(self.parse_layer(element))
       
   597             elif element.tag == "{http://www.s60.com/xml/convertprojectml/1}foreach":
       
   598                 for fe in self.parse_foreach(element, old_structure_root):
       
   599                     self.layers.append(fe)                
       
   600         return
   543     
   601     
   544     def parse_foreach(self, etree, old_structure_root):
   602     def parse_foreach(self, etree, old_structure_root):
   545         layersTmp = []
   603         layersTmp = []        
   546         for fe in etree.findall("{%s}foreach" % self.namespaces[0]):
   604         variable = etree.get("variable")
   547             variable = fe.get("variable")
   605         data = self.handleMapping(etree.get("data"), {})
   548             data = fe.get("data")
   606         folders = [] 
   549             folders = [] 
   607         for item in os.listdir(os.path.join(old_structure_root, data)):
   550             for item in os.listdir(os.path.join(old_structure_root, data)):
   608             if os.path.isdir(os.path.join(old_structure_root, data, item)) and item != '.svn':
   551                 if os.path.isdir(os.path.join(old_structure_root, data, item)) and item != '.svn':
   609                 folders.append(item)
   552                     folders.append(item)
   610         
   553             
   611         for folder in folders:
   554             for folder in folders:
   612             mapping_data = {variable: folder}                                             
   555                 mapping_data = {variable: folder}                                             
   613             for layer in etree.findall("{%s}layer" % self.namespaces[0]):            
   556                 for layer in fe.findall("{%s}layer" % self.namespaces[0]):            
   614                 layersTmp.append(self.parse_layer(layer, mapping_data))
   557                     layersTmp.append(self.parse_layer(layer, mapping_data))
       
   558                                 
   615                                 
   559         return layersTmp
   616         return layersTmp
   560     
   617         
   561     def parse_layers(self,etree):
       
   562         layersTmp = []
       
   563         for layer in etree.findall("{%s}layer" % self.namespaces[0]):            
       
   564             layersTmp.append(self.parse_layer(layer))
       
   565             
       
   566         return layersTmp
       
   567     
       
   568     def parse_layer(self, etree, mapping_data=None):        
   618     def parse_layer(self, etree, mapping_data=None):        
   569         path = self.handleMapping(etree.get("path"), mapping_data)
   619         path = self.handleMapping(etree.get("path"), mapping_data)
   570         
   620         
   571         layerObject = ConvertProjectLayer(path)        
   621         layerObject = ConvertProjectLayer(path, self.configuration)        
   572         for folder in etree.findall("{%s}folder" % self.namespaces[0]):
   622         for folder in etree.findall("{%s}folder" % self.namespaces[0]):
   573             layerObject.addFolder(self.parse_folder(folder, layerObject, mapping_data))
   623             layerObject.addFolder(self.parse_folder(folder, layerObject, mapping_data))
   574 
   624 
   575         for f in etree.findall("{%s}file" % self.namespaces[0]):
   625         for f in etree.findall("{%s}file" % self.namespaces[0]):
   576             layerObject.addFile(self.parse_file(f, layerObject, mapping_data))
   626             layerObject.addFile(self.parse_file(f, layerObject, mapping_data))
   587         return folderObject
   637         return folderObject
   588 
   638 
   589     def parse_file(self, etree, parent, mapping_data=None):
   639     def parse_file(self, etree, parent, mapping_data=None):
   590         path = self.handleMapping(etree.get("path"), mapping_data)
   640         path = self.handleMapping(etree.get("path"), mapping_data)
   591         type = self.handleMapping(etree.get("type"), mapping_data)
   641         type = self.handleMapping(etree.get("type"), mapping_data)
       
   642         configuration_name = self.handleMapping(etree.get("configuration_name"), mapping_data)
   592         
   643         
   593         fileObject = ConvertProjectFile(path, type, parent)        
   644         fileObject = ConvertProjectFile(path, type, parent)        
   594         for filter in etree.findall("{%s}filter" % self.namespaces[0]):
   645         for filter in etree.findall("{%s}filter" % self.namespaces[0]):
   595             fileObject.addFilter(self.parse_filter(filter, fileObject, mapping_data))
   646             fileObject.addFilter(self.parse_filter(filter, fileObject, mapping_data))
   596         
   647         
   616         description = ""
   667         description = ""
   617         if descElement != None:
   668         if descElement != None:
   618             description = descElement.text                
   669             description = descElement.text                
   619                          
   670                          
   620         fileObject.addMeta(metaArray)
   671         fileObject.addMeta(metaArray)
   621         fileObject.addDescription(description)                
   672         fileObject.addDescription(description)
       
   673         fileObject.addConfigurationName(configuration_name)
   622         return fileObject
   674         return fileObject
   623 
   675 
   624     def parse_filter(self, etree, parent, mapping_data=None):
   676     def parse_filter(self, etree, parent, mapping_data=None):
   625         """
   677         """
   626         """
   678         """
   642             tmpDict[attribute] = tmpElement.get(attribute)
   694             tmpDict[attribute] = tmpElement.get(attribute)
   643         return tmpDict
   695         return tmpDict
   644     
   696     
   645     def handleMapping(self, data, mapping):
   697     def handleMapping(self, data, mapping):
   646         """
   698         """
   647         """
   699         """ 
   648         
       
   649         retStr = data
   700         retStr = data
   650         
   701         if not mapping: mapping = {}        
   651         if mapping != None and data != None:                        
   702         if data != None:
   652             for key in mapping.keys():
   703             merged = dict(mapping.items() + self._get_env_variables().items())                                    
   653                 retStr = retStr.replace(key, mapping[key])
   704             for key in merged.keys():
       
   705                 retStr = retStr.replace(key, merged[key])
       
   706          
   654         return retStr
   707         return retStr
   655         
   708         
   656         
   709     def _get_env_variables(self):
   657         
   710         if not hasattr(self, '_env_dict'):
   658         
   711         #Making dictionary only once because of performance.
   659         
   712             self._env_dict = {}
   660         
   713             for var in os.environ:
   661 
   714                 self._env_dict["%%%s%%" % var] = os.environ[var]
   662 
   715             
   663     
   716         return self._env_dict 
   664     
   717         
   665     
   718         
       
   719 
       
   720 
       
   721     
       
   722     
       
   723