17d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner#!/usr/bin/python2 27d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# -*-coding:utf-8 -* 37d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 47d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# Copyright (c) 2011-2014, Intel Corporation 57d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# All rights reserved. 67d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 77d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# Redistribution and use in source and binary forms, with or without modification, 87d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# are permitted provided that the following conditions are met: 97d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 1. Redistributions of source code must retain the above copyright notice, this 117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# list of conditions and the following disclaimer. 127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 2. Redistributions in binary form must reproduce the above copyright notice, 147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# this list of conditions and the following disclaimer in the documentation and/or 157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# other materials provided with the distribution. 167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 3. Neither the name of the copyright holder nor the names of its contributors 187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# may be used to endorse or promote products derived from this software without 197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# specific prior written permission. 207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# 217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerimport re 357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerimport sys 367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerimport copy 377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerfrom itertools import izip 387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerfrom itertools import imap 397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ===================================================================== 417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner""" Context classes, used during propagation and the "to PFW script" step """ 427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ===================================================================== 437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass PropagationContextItem(list) : 457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Handle an item during the propagation step""" 467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __copy__(self): 477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """C.__copy__() -> a shallow copy of C""" 487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.__class__(self) 497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass PropagationContextElement(PropagationContextItem) : 517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Handle an Element during the propagation step""" 527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getElementsFromName(self, name): 537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner matchingElements = [] 547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for element in self : 557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if element.getName() == name : 567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner matchingElements.append(element) 577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return matchingElements 587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass PropagationContextOption(PropagationContextItem) : 617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Handle an Option during the propagation step""" 627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getOptionItems (self, itemName): 637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner items = [] 647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for options in self : 657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner items.append(options.getOption(itemName)) 667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return items 677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass PropagationContext() : 707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Handle the context during the propagation step""" 717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__(self, propagationContext=None) : 727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if propagationContext == None : 747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self._context = { 757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner "DomainOptions" : PropagationContextOption() , 767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner "Configurations" : PropagationContextElement() , 777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner "ConfigurationOptions" : PropagationContextOption() , 787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner "Rules" : PropagationContextElement() , 797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner "PathOptions" : PropagationContextOption() , 807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner } 817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else : 827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self._context = propagationContext 837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def copy(self): 857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return a copy of the context""" 867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner contextCopy = self._context.copy() 877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for key in iter(self._context) : 897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner contextCopy[key] = contextCopy[key].__copy__() 907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.__class__(contextCopy) 927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getDomainOptions (self): 947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self._context["DomainOptions"] 957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getConfigurations (self): 977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self._context["Configurations"] 987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getConfigurationOptions (self): 1007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self._context["ConfigurationOptions"] 1017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getRules (self): 1037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self._context["Rules"] 1047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getPathOptions (self): 1067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self._context["PathOptions"] 1077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ===================================================== 1107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner"""Element option container""" 1117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ===================================================== 1127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Options () : 1147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """handle element options""" 1157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__(self, options=[], optionNames=[]) : 1167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.options = dict(izip(optionNames, options)) 1177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # print(options,optionNames,self.options) 1187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __str__(self) : 1217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ops2str = [] 1227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for name, argument in self.options.items() : 1237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ops2str.append(str(name) + "=\"" + str(argument) + "\"") 1247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return " ".join(ops2str) 1267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getOption(self, name): 1287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """get option by its name, if it does not exist return empty string""" 1297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.options.get(name, "") 1307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def setOption(self, name, newOption): 1327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """set option by its name""" 1337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.options[name] = newOption 1347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def copy (self): 1367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """D.copy() -> a shallow copy of D""" 1377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner copy = Options() 1387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner copy.options = self.options.copy() 1397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return copy 1407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ==================================================== 1427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner"""Definition of all element class""" 1437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ==================================================== 1447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Element(object): 1467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ implement a basic element 1477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner It is the class base for all other elements as Domain, Configuration...""" 1497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "unknown" 1507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name"] 1517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = [] 1527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionDelimiter = " " 1537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__(self, line=None) : 1557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if line == None : 1577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option = Options([], self.optionNames) 1587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else : 1597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option = self.optionFromLine(line) 1607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.children = [] 1627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def optionFromLine(self, line) : 1647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # get ride of spaces 1657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner line = line.strip() 1667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options = self.extractOptions(line) 1687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return Options(options, self.optionNames) 1707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def extractOptions(self, line) : 1727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return the line splited by the optionDelimiter atribute 1737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Option list length is less or equal to the optionNames list length 1757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 1767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options = line.split(self.optionDelimiter, len(self.optionNames) - 1) 1777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # get ride of leftover spaces 1797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionsStrip = list(imap(str.strip, options)) 1807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return optionsStrip 1827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def addChild(self, child, append=True) : 1847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ A.addChid(B) -> add B to A child list if B class name is in A white List""" 1857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner try: 1867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # Will raise an exception if this child is not in the white list 1877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.childWhiteList.index(child.__class__.__name__) 1887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # If no exception was raised, add child to child list 1897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if append : 1917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.children.append(child) 1927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else : 1937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.children.insert(0, child) 1947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner except ValueError: 1967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # the child class is not in the white list 1977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise ChildNotPermitedError("", self, child) 1987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 1997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def addChildren(self, children, append=True) : 2007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Add a list of child""" 2017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if append: 2027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # Add children at the end of the child list 2037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.children.extend(children) 2047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else: 2057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # Add children at the begining of the child list 2067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.children = children + self.children 2077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def childrenToString(self, prefix=""): 2097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return raw printed children """ 2107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner body = "" 2117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.children : 2127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner body = body + child.__str__(prefix) 2137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return body 2157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __str__(self, prefix="") : 2177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return raw printed element""" 2187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner selfToString = prefix + " " + self.tag + " " + str(self.option) 2197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return selfToString + "\n" + self.childrenToString(prefix + "\t") 2207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def extractChildrenByClass(self, classTypeList) : 2227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return all children whose class is in the list argument 2237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return a list of all children whose class in the list "classTypeList" (second arguments)""" 2257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner selectedChildren = [] 2267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.children : 2287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for classtype in classTypeList : 2297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if child.__class__ == classtype : 2307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner selectedChildren.append(child) 2317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner break 2327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return selectedChildren 2337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def propagate (self, context=PropagationContext()): 2357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """call the propagate method of all children""" 2367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.children : 2377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner child.propagate(context) 2387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getName(self): 2407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return name option value. If none return "" """ 2417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.option.getOption("Name") 2427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def setName(self, name): 2447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option.setOption("Name", name) 2457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 2477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.children: 2487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner child.translate(translator) 2497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 2517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass ElementWithTag (Element): 2537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Element of this class are declared with a tag => line == "tag: .*" """ 2547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def extractOptions(self, line) : 2557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner lineWithoutTag = line.split(":", 1)[-1].strip() 2567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options = super(ElementWithTag, self).extractOptions(lineWithoutTag) 2577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return options 2587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 2607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass ElementWithInheritance(Element): 2627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def propagate (self, context=PropagationContext) : 2637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """propagate some proprieties to children""" 2647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # copy the context so that everything that hapend next will only affect 2667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # children 2677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner contextCopy = context.copy() 2687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for inheritance 2707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.Inheritance(contextCopy) 2717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # call the propagate method of all children 2737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner super(ElementWithInheritance, self).propagate(contextCopy) 2747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass ElementWithRuleInheritance(ElementWithInheritance): 2777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """class that will give to its children its rules""" 2787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def ruleInheritance(self, context): 2797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Add its rules to the context and get context rules""" 2807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # extract all children rule and operator 2827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childRules = self.extractChildrenByClass([Operator, Rule]) 2837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # get context rules 2857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner contextRules = context.getRules() 2867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # adopt rules of the beginning of the context 2887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.addChildren(contextRules, append=False) 2897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add previously extract rules to the context 2917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner contextRules += childRules 2927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 2957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass EmptyLine (Element) : 2977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """This class represents an empty line. 2987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 2997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Will raise "EmptyLineWarning" exception at instanciation.""" 3007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "emptyLine" 3027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"[ \t]*\n?$").match 3037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__ (self, line): 3047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise EmptyLineWarning(line) 3057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 3077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Commentary(Element): 3097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """This class represents a commentary. 3107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Will raise "CommentWarning" exception at instanciation.""" 3127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "commentary" 3147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["comment"] 3157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"#").match 3167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__ (self, line): 3177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise CommentWarning(line) 3187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 3207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Path (ElementWithInheritance) : 3227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """class implementing the "path = value" concept""" 3237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "path" 3247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name", "value"] 3257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r".+=").match 3267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionDelimiter = "=" 3277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 3297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner translator.setParameter(self.getName(), self.option.getOption("value")) 3307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def Inheritance (self, context) : 3327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """check for path name inheritance""" 3337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.OptionsInheritance(context) 3347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def OptionsInheritance (self, context) : 3367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """make configuration name inheritance """ 3377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context.getPathOptions().append(self.option.copy()) 3397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.setName("/".join(context.getPathOptions().getOptionItems("Name"))) 3407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass GroupPath (Path, ElementWithTag) : 3437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "component" 3447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(tag + r" *:").match 3457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name"] 3467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["Path", "GroupPath"] 3477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getPathNames (self) : 3497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Return the list of all path child name""" 3507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner pathNames = [] 3527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner paths = self.extractChildrenByClass([Path]) 3547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for path in paths : 3557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner pathNames.append(path.getName()) 3567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner groupPaths = self.extractChildrenByClass([GroupPath]) 3587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for groupPath in groupPaths : 3597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner pathNames += groupPath.getPathNames() 3607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return pathNames 3627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 3647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.extractChildrenByClass([Path, GroupPath]): 3657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner child.translate(translator) 3667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 3687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Rule (Element) : 3707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """class implementing the rule concept 3717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner A rule is composed of a criterion, a rule type and an criterion state. 3737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner It should not have any child and is propagated to all configuration in parent descendants. 3747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 3757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "rule" 3777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["criterion", "type", "element"] 3787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"[a-zA-Z0-9_.]+ +(Is|IsNot|Includes|Excludes) +[a-zA-Z0-9_.]+").match 3797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = [] 3807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def PFWSyntax (self, prefix=""): 3827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner script = prefix + \ 3847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option.getOption("criterion") + " " + \ 3857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option.getOption("type") + " " + \ 3867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option.getOption("element") 3877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return script 3897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Operator (Rule) : 3927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """class implementing the operator concept 3937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner An operator contains rules and other operators 3957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner It is as rules propagated to all configuration children in parent descendants. 3967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner It should only have the name ANY or ALL to be understood by PFW. 3977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 3987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 3997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "operator" 4007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name"] 4017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"ANY|ALL").match 4027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["Rule", "Operator"] 4037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner syntax = { "ANY" : "Any" , "ALL" : "All"} 4057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def PFWSyntax (self, prefix=""): 4077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ return a pfw rule (ex : "Any{criterion1 is state1}") generated from "self" and its children options""" 4087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner script = "" 4097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner script += prefix + \ 4117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.syntax[self.getName()] + "{ " 4127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rules = self.extractChildrenByClass([Rule, Operator]) 4147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner PFWRules = [] 4167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for rule in rules : 4177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner PFWRules.append(rule.PFWSyntax(prefix + " ")) 4187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner script += (" , ").join(PFWRules) 4207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner script += prefix + " }" 4227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return script 4247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 4267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Configuration (ElementWithRuleInheritance, ElementWithTag) : 4287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "configuration" 4297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name"] 4307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"conf *:").match 4317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["Rule", "Operator", "Path", "GroupPath"] 4327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def composition (self, context): 4347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """make all needed composition 4357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Composition is the fact that group configuration with the same name defined 4377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner in a parent will give their rule children to this configuration 4387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 4397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner name = self.getName() 4417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sameNameConf = context.getConfigurations().getElementsFromName(name) 4427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sameNameConf.reverse() 4447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for configuration in sameNameConf : 4467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add same name configuration rule children to self child list 4477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.addChildren(configuration.extractChildrenByClass([Operator, Rule]), append=False) 4487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def propagate (self, context=PropagationContext) : 4517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """propagate proprieties to children 4527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner make needed compositions, join ancestor name to its name, 4547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner and add rules previously defined rules""" 4557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # make all needed composition 4577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.composition(context) 4587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner super(Configuration, self).propagate(context) 4607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def Inheritance (self, context) : 4627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """make configuration name and rule inheritance""" 4637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for configuration name inheritance 4647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.OptionsInheritance(context) 4657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for rule inheritance 4677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.ruleInheritance(context) 4687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def OptionsInheritance (self, context) : 4707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """make configuration name inheritance """ 4717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context.getConfigurationOptions().append(self.option.copy()) 4737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.setName(".".join(context.getConfigurationOptions().getOptionItems("Name"))) 4747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getRootPath (self) : 4777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner paths = self.extractChildrenByClass([Path, GroupPath]) 4797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rootPath = GroupPath() 4817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rootPath.addChildren(paths) 4827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return rootPath 4847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getConfigurableElements (self) : 4867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return all path name defined in this configuration""" 4877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.getRootPath().getPathNames() 4897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getRuleString(self): 4917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Output this configuration's rule as a string""" 4927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # Create a rootRule 4947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ruleChildren = self.extractChildrenByClass([Rule, Operator]) 4957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 4967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # Do not create a root rule if there is only one fist level Operator rule 4977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if len(ruleChildren) == 1 and ruleChildren[0].__class__ == Operator : 4987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ruleroot = ruleChildren[0] 4997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else : 5017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ruleroot = Operator() 5027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ruleroot.setName("ALL") 5037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ruleroot.addChildren(ruleChildren) 5047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return ruleroot.PFWSyntax() 5067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 5087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner translator.createConfiguration(self.getName()) 5097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner translator.setRule(self.getRuleString()) 5107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner paths = self.extractChildrenByClass([Path, GroupPath]) 5127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner translator.setElementSequence(self.getConfigurableElements()) 5137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for path in paths: 5147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner path.translate(translator) 5157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def copy (self) : 5177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return a shallow copy of the configuration""" 5187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # create configuration or subclass copy 5207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner confCopy = self.__class__() 5217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add children 5237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner confCopy.children = list(self.children) 5247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add option 5267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner confCopy.option = self.option.copy() 5277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return confCopy 5297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass GroupConfiguration (Configuration) : 5317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "GroupConfiguration" 5327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name"] 5337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"(supConf|confGroup|confType) *:").match 5347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["Rule", "Operator", "GroupConfiguration", "Configuration", "GroupPath"] 5357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def composition (self, context) : 5377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """add itself in context for configuration composition 5387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Composition is the fact that group configuration with the same name defined 5407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner in a parent will give their rule children to this configuration 5417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 5427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # copyItself 5447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner selfCopy = self.copy() 5457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # make all needed composition 5477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner super(GroupConfiguration, self).composition(context) 5487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add the copy in context for futur configuration composition 5507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context.getConfigurations().append(selfCopy) 5517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getConfigurableElements (self) : 5547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return a list. Each elements consist of a list of configurable element of a configuration 5557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return a list consisting of all configurable elements for each configuration. 5577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner These configurable elements are organized in a list""" 5587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElements = [] 5597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurations = self.extractChildrenByClass([Configuration]) 5617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for configuration in configurations : 5627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElements.append(configuration.getConfigurableElements()) 5637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner groudeConfigurations = self.extractChildrenByClass([GroupConfiguration]) 5657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for groudeConfiguration in groudeConfigurations : 5667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElements += groudeConfiguration.getConfigurableElements() 5677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return configurableElements 5697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 5717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.extractChildrenByClass([Configuration, GroupConfiguration]): 5727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner child.translate(translator) 5737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 5757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Domain (ElementWithRuleInheritance, ElementWithTag) : 5777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "domain" 5787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sequenceAwareKeyword = "sequenceAware" 5797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"domain *:").match 5817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner optionNames = ["Name", sequenceAwareKeyword] 5827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["Configuration", "GroupConfiguration", "Rule", "Operator"] 5837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def propagate (self, context=PropagationContext) : 5857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ propagate name, sequenceAwareness and rule to children""" 5867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # call the propagate method of all children 5887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner super(Domain, self).propagate(context) 5897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.checkConfigurableElementUnicity() 5917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def Inheritance (self, context) : 5937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """check for domain name, sequence awarness and rules inheritance""" 5947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for domain name and sequence awarness inheritance 5957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.OptionsInheritance(context) 5967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 5977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for rule inheritance 5987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.ruleInheritance(context) 5997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def OptionsInheritance(self, context) : 6017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ make domain name and sequence awareness inheritance 6027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner join to the domain name all domain names defined in context and 6047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if any domain in context is sequence aware, set sequenceAwareness to True""" 6057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add domain options to context 6077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context.getDomainOptions().append(self.option.copy()) 6087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # set name to the junction of all domain name in context 6107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.setName(".".join(context.getDomainOptions().getOptionItems("Name"))) 6117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # get sequenceAwareness of all domains in context 6137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sequenceAwareList = context.getDomainOptions().getOptionItems(self.sequenceAwareKeyword) 6147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # or operation on all booleans in sequenceAwareList 6157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sequenceAwareness = False 6167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for sequenceAware in sequenceAwareList : 6177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sequenceAwareness = sequenceAwareness or sequenceAware 6187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # current domain sequenceAwareness = sequenceAwareness 6197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.option.setOption(self.sequenceAwareKeyword, sequenceAwareness) 6207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def extractOptions(self, line) : 6237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Extract options from the definition line""" 6247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options = super(Domain, self).extractOptions(line) 6257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sequenceAwareIndex = self.optionNames.index(self.sequenceAwareKeyword) 6277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # translate the keyword self.sequenceAwareKeyword if specified to boolean True, 6297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # to False otherwise 6307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner try : 6317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if options[sequenceAwareIndex] == self.sequenceAwareKeyword : 6327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options[sequenceAwareIndex] = True 6337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else: 6347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options[sequenceAwareIndex] = False 6357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner except IndexError : 6367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner options = options + [None] * (sequenceAwareIndex - len(options)) + [False] 6377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return options 6387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def getRootConfiguration (self) : 6407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return the root configuration group""" 6417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurations = self.extractChildrenByClass([Configuration, GroupConfiguration]) 6427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurationRoot = GroupConfiguration() 6447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurationRoot.addChildren(configurations) 6467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return configurationRoot 6487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # TODO: don't do that in the parser, let the PFW tell you that 6507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def checkConfigurableElementUnicity (self): 6517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ check that all configurable elements defined in child configuration are the sames""" 6527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # get a list. Each elements of is the configurable element list of a configuration 6547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElementsList = self.getRootConfiguration().getConfigurableElements() 6557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # if at least two configurations in the domain 6577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if len(configurableElementsList) > 1 : 6587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # get first configuration configurable element list sort 6607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElementsList0 = list(configurableElementsList[0]) 6617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElementsList0.sort() 6627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for configurableElements in configurableElementsList : 6647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # sort current configurable element list 6657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner auxConfigurableElements = list(configurableElements) 6667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner auxConfigurableElements.sort() 6677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if auxConfigurableElements != configurableElementsList0 : 6697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # if different, 2 configurations those not have the same configurable element list 6707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # => one or more configurable element is missing in one of the 2 configuration 6717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise UndefinedParameter(self.getName()) 6727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 6757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner sequence_aware = self.option.getOption(self.sequenceAwareKeyword) 6767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner translator.createDomain(self.getName(), sequence_aware) 6777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurations = self.getRootConfiguration() 6797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurableElementsList = configurations.getConfigurableElements() 6807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # add configurable elements 6827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if len(configurableElementsList) != 0 : 6837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for configurableElement in configurableElementsList[0] : 6847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner translator.addElement(configurableElement) 6857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner configurations.translate(translator) 6877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass GroupDomain (Domain) : 6897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "groupDomain" 6907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner match = re.compile(r"(supDomain|domainGroup) *:").match 6917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["GroupDomain", "Domain", "GroupConfiguration", "Rule", "Operator"] 6927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def translate(self, translator): 6947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for child in self.extractChildrenByClass([Domain, GroupDomain]): 6957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner child.translate(translator) 6967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ---------------------------------------------------------- 6987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 6997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Root(Element): 7007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner tag = "root" 7017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner childWhiteList = ["Domain", "GroupDomain"] 7027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# =========================================== 7057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner""" Syntax error Exceptions""" 7067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# =========================================== 7077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass MySyntaxProblems(SyntaxError) : 7097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = "syntax error in %(line)s " 7107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__(self, line=None, num=None): 7127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.setLine(line, num) 7137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __str__(self): 7157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if self.line : 7177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.comment = self.comment % {"line" : repr(self.line)} 7187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if self.num : 7197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.comment = "Line " + str(self.num) + ", " + self.comment 7207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.comment 7217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def setLine (self, line, num): 7237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.line = str(line) 7247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.num = num 7257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# --------------------------------------------------------- 7287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass MyPropagationError(MySyntaxProblems) : 7307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ Syntax error Exceptions used in the propagation step""" 7317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner pass 7327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass UndefinedParameter(MyPropagationError) : 7347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = "Configurations in domain '%(domainName)s' do not all set the same parameters " 7357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__ (self, domainName): 7367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.domainName = domainName 7377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __str__ (self): 7387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return self.comment % { "domainName" : self.domainName } 7397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ----------------------------------------------------- 7427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner""" Syntax error Exceptions used by parser""" 7437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass MySyntaxError(MySyntaxProblems) : 7457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ Syntax error Exceptions used by parser""" 7467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner pass 7477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass MySyntaxWarning(MySyntaxProblems) : 7497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ Syntax warning Exceptions used by parser""" 7507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner pass 7517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass IndentationSyntaxError(MySyntaxError) : 7537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = """syntax error in %(line)s has no father element. 7547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner You can only increment indentation by one tabutation per line")""" 7557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass EmptyLineWarning(MySyntaxWarning): 7577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = "warning : %(line)s is an empty line and has been ommited" 7587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass CommentWarning(MySyntaxWarning): 7607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = "warning : %(line)s is a commentary and has been ommited" 7617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass ChildNotPermitedError(MySyntaxError): 7637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__(self, line, fatherElement, childElement): 7647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.comment = "syntax error in %(line)s, " + fatherElement.tag + " should not have a " + childElement.tag + " child." 7657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner super(ChildNotPermitedError, self).__init__(line) 7667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass UnknownElementTypeError(MySyntaxError): 7697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = " error in line %(line)s , not known element type were matched " 7707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass SpaceInIndentationError(MySyntaxError): 7727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner comment = " error in ,%(line)s space is not permited in indentation" 7737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ============================================ 7767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner"""Class creating the DOM elements from a stream""" 7777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner# ============================================ 7787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass ElementsFactory(object) : 7807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Element factory, return an instance of the first matching element 7817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Test each element list in elementClass and instanciate it if it's methode match returns True 7837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner The method match is called with input line as argument 7847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 7857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__ (self): 7867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.elementClass = [ 7877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner EmptyLine , 7887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Commentary, 7897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner GroupDomain, 7907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Domain, 7917d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Path, 7927d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner GroupConfiguration, 7937d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Configuration, 7947d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Operator, 7957d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Rule, 7967d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner GroupPath 7977d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ] 7987d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 7997d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def createElementFromLine (self, line) : 8007d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return an instance of the first matching element 8017d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8027d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Test each element list in elementClass and instanciate it if it's methode match returns True 8037d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner The method match is called with the argument line. 8047d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner Raise UnknownElementTypeError if no element matched. 8057d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """ 8067d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for element in self.elementClass : 8077d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if element.match(line) : 8087d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # print (line + element.__class__.__name__) 8097d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return element(line) 8107d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # if we have not find any 8117d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise UnknownElementTypeError(line) 8127d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8137d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner#------------------------------------------------------ 8147d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8157d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerclass Parser(object) : 8167d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """Class implementing the parser""" 8177d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __init__(self): 8187d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.rankPattern = re.compile(r"^([\t ]*)(.*)") 8197d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.elementFactory = ElementsFactory() 8207d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.previousRank = 0 8217d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8227d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __parseLine__(self, line): 8237d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8247d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rank, rest = self.__getRank__(line) 8257d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8267d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # instanciate the coresponding element 8277d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner element = self.elementFactory.createElementFromLine(rest) 8287d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8297d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.__checkIndentation__(rank) 8307d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8317d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return rank, element 8327d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8337d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __getRank__(self, line): 8347d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """return the rank, the name and the option of the input line 8357d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8367d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerthe rank is the number of tabulation (\t) at the line beginning. 8377d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagnerthe rest is the rest of the line.""" 8387d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # split line in rank and rest 8397d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rank = self.rankPattern.match(line) 8407d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if rank : 8417d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rank, rest = rank.group(1, 2) 8427d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner else : 8437d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise MySyntaxError(line) 8447d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8457d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for empty line 8467d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if rest == "" : 8477d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise EmptyLineWarning(line) 8487d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8497d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner # check for space in indentation 8507d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if rank.find(" ") > -1 : 8517d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise SpaceInIndentationError(line) 8527d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8537d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rank = len (rank) + 1 # rank starts at 1 8547d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8557d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8567d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return rank, rest 8577d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8587d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8597d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def __checkIndentation__(self, rank): 8607d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """check if indentation > previous indentation + 1. If so, raise IndentationSyntaxError""" 8617d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if (rank > self.previousRank + 1) : 8627d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise IndentationSyntaxError() 8637d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner self.previousRank = rank 8647d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8657d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner def parse(self, stream, verbose=False): 8667d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner """parse a stream, usually a opened file""" 8677d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner myroot = Root("root") 8687d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context = [myroot] # root is element of rank 0 8697d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner warnings = "" 8707d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8717d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner for num, line in enumerate(stream): 8727d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner try: 8737d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner rank, myelement = self.__parseLine__(line) 8747d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8757d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner while len(context) > rank : 8767d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context.pop() 8777d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context.append(myelement) 8787d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner context[-2].addChild(myelement) 8797d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8807d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner except MySyntaxWarning, ex: 8817d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ex.setLine(line, num + 1) 8827d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner if verbose : 8837d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner print >>sys.stderr, ex 8847d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8857d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner except MySyntaxError, ex : 8867d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner ex.setLine(line, num + 1) 8877d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner raise 8887d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 8897d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner return myroot 8907d996811c0e80b30a40a5add1f01f0314f2ebef4David Wagner 891